diff --git a/.gitignore b/.gitignore
index 5e33b5a1..ac08113 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,7 +43,6 @@
 v8.log
 /_out
 /android_emulator_sdk
-/arm-sysroot
 /ash/ash_unittests_run.xml
 /base/base_unittests_run.xml
 /breakpad/src/
@@ -93,8 +92,7 @@
 /chrome/common/extensions/api/api.xml
 /chrome/common/extensions/api/ledger/
 /chrome/Hammer
-/chrome/installer/linux/debian_wheezy_amd64-sysroot/
-/chrome/installer/linux/debian_wheezy_i386-sysroot/
+/chrome/installer/linux/debian_wheezy_*-sysroot/
 /chrome/installer/linux/internal
 /chrome/installer/mac/internal
 /chrome/installer/mac/third_party/xz/xz
diff --git a/AUTHORS b/AUTHORS
index a61c7a6..1265abc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,6 +19,7 @@
 Aditya Bhargava <heuristicist@gmail.com>
 Ajay Berwal <ajay.berwal@samsung.com>
 Ajith Kumar V <ajith.v@samsung.com>
+Aku Kotkavuo <a.kotkavuo@partner.samsung.com>
 Alex Gartrell <agartrell@cmu.edu>
 Alex Henrie <alexhenrie24@gmail.com>
 Alex Scheele <alexscheele@gmail.com>
@@ -86,6 +87,7 @@
 Chansik Yun <chansik.yun@gmail.com>
 Chaobin Zhang <zhchbin@gmail.com>
 Chris Harrelson <chrishtr@gmail.com>
+Chris Nardi <hichris123@gmail.com>
 Christophe Dumez <ch.dumez@samsung.com>
 Christopher Dale <chrelad@gmail.com>
 Clemens Fruhwirth <clemens@endorphin.org>
@@ -105,6 +107,7 @@
 David Benjamin <davidben@mit.edu>
 David Erceg <erceg.david@gmail.com>
 David Futcher <david.mike.futcher@gmail.com>
+David McAllister <mcdavid@amazon.com>
 Deepak Dilip Borade <deepak.db@samsung.com>
 Deepak Mittal <deepak.m1@samsung.com>
 Deepak Singla <deepak.sa@samsung.com>
@@ -120,6 +123,7 @@
 Dongseong Hwang <dongseong.hwang@intel.com>
 Dongwoo Joshua Im <dw.im@samsung.com>
 Douglas F. Turner <doug.turner@gmail.com>
+Ebrahim Byagowi <ebraminio@gmail.com>
 Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
 Edward Crossman <tedoc2000@gmail.com>
 Eero Häkkinen <e.hakkinen@samsung.com>
@@ -247,6 +251,7 @@
 Kingshuk Jana <kingshuk.j@samsung.com>
 Klemen Forstnerič <klemen.forstneric@gmail.com>
 Krishna Chaitanya <krish.botta@samsung.com>
+Kristof Kosztyo <kkosztyo.u-szeged@partner.samsung.com>
 Krzysztof Wolanski <k.wolanski@samsung.com>
 Kunal Thakar <kunalt@gmail.com>
 Kushal Pisavadia <kushi.p@gmail.com>
@@ -412,6 +417,7 @@
 Shez Baig <sbaig1@bloomberg.net>
 Shiliu Wang <aofdwsl@gmail.com>
 Shiliu Wang <shiliu.wang@intel.com>
+Shilpa Shri <shilpa.shri@samsung.com>
 Shouqun Liu <shouqun.liu@intel.com>
 Shreeram Kushwaha <shreeram.k@samsung.com>
 Shreyas Gopal <shreyas.g@samsung.com>
@@ -491,6 +497,7 @@
 Zhenyu Liang <zhenyu.liang@intel.com>
 Zhenyu Shan <zhenyu.shan@intel.com>
 Ziran Sun <ziran.sun@samsung.com>
+Zsolt Borbely <zsborbely.u-szeged@partner.samsung.com>
 Yongha Lee <yongha78.lee@samsung.com>
 方觉 (Fang Jue) <fangjue23303@gmail.com>
 Yupei Wang <perryuwang@tencent.com>
diff --git a/BUILD.gn b/BUILD.gn
index 6a041d0c..e3bf258 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -9,6 +9,16 @@
 # file to your new one or GN won't know about it.
 
 import("//build/config/ui.gni")
+if (is_android) {
+  import("//build/config/android/config.gni")
+}
+
+declare_args() {
+  # A list of extra dependencies to add to the root target. This allows a
+  # checkout to add additional targets without explicitly changing any checked-
+  # in files.
+  root_extra_deps = []
+}
 
 # In GN, a "group" is a dummy target that just lists other targets.
 group("root") {
@@ -124,7 +134,7 @@
     "//ui/web_dialogs",
     "//url",
     "//v8:v8",
-  ]
+  ] + root_extra_deps
 
   if (!is_win) {
     deps += [ "//breakpad:symupload" ]
@@ -166,7 +176,8 @@
 
   if (is_android) {
     deps += [
-      "//base/android:chromium_android_linker",
+      "//base/android/linker:chromium_android_linker",
+      "//build/android/rezip",
       "//third_party/openmax_dl/dl",
       "//content/shell/android:content_shell_apk",
       "//chrome/android:chrome_shell_apk",
@@ -180,6 +191,12 @@
       "//third_party/eyesfree:eyesfree_java",
     ]
 
+    if (has_chrome_android_internal) {
+      deps += [
+        "//clank",
+      ]
+    }
+
     deps -= [
       "//apps",  # Needs testing.
       "//chrome/browser",
diff --git a/DEPS b/DEPS
index b0a794e..f2835d0 100644
--- a/DEPS
+++ b/DEPS
@@ -36,31 +36,31 @@
   'libcxx_revision': '48198f9110397fff47fe7c37cbfa296be7d44d3d',
   'libcxxabi_revision': '4ad1009ab3a59fa7a6896d74d5e4de5885697f95',
   'webkit_trunk': 'http://src.chromium.org/blink/trunk',
-  'webkit_revision': '95c55abf8cd1a9b91f09f4a32c7b2bb2646dbfe6', # from svn revision 184068
+  'webkit_revision': '28d0729ed0731e5bf216ce716e7248036942aed8', # from svn revision 184365
   'chromium_git': 'https://chromium.googlesource.com',
   'chromiumos_git': 'https://chromium.googlesource.com/chromiumos',
   'pdfium_git': 'https://pdfium.googlesource.com',
   'skia_git': 'https://skia.googlesource.com',
   'boringssl_git': 'https://boringssl.googlesource.com',
-  'libvpx_revision': 'efe9712d52c2d216fb3d1ceb508b8148847a7e4b',
+  'libvpx_revision': '2e5ced5fd62a73f4f5687ab19520b3aad1c53f6f',
   'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
-  'skia_revision': 'b0e89dcc1d8c1c2f9f7ffb45e8609cdb4a68104b',
+  'skia_revision': 'c6f3e2c17b3a7ccfd1ca473652ee9e34e89fad0a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and V8 without interference from each other.
   'v8_branch': 'trunk',
-  'v8_revision': '2f51c28a975ceaa07ce8f8b2e42ac0f0c5a57802', # from svn revision 24723
+  'v8_revision': 'fb0f6c03710de36d4f11b8164a76c8a66008f5d9', # from svn revision 24879
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling WebRTC
   # and V8 without interference from each other.
   # 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.
-  'swarming_revision': 'a57d7db4026bca8e0fab9aadd4953503e8d74e74',
+  'swarming_revision': 'bcb3bc30328c38441d3f7656cb649b123803726c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  "angle_revision": "8e92923010c568a445c0f22e1a36f462fcabc8f3",
+  "angle_revision": "d2f756be4fd198d630b64dc6c3568184363e6d14",
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -68,7 +68,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'cbd8e1a584e2c0ffcb7aaf49d89a7696f5ebc916',
+  'pdfium_revision': '767aebbef641a89498deebc29369a078207b4dcc',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -76,7 +76,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': '7ea848165b89577c6e9a1ef12a2cdff9d1beb71f',
+  'boringssl_revision': '751e889b1d791d2b91c1437248454fa1d4e101a5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nss
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': '2a8cf9cfd9a14e9e721d5e514434cec1d82bf294', # from svn revision r13947
+  'nacl_revision': 'c4102cf8b31a545d4fba47108a45affdf92f6fa1', # from svn revision r13974
 }
 
 # Only these hosts are allowed for dependencies in this DEPS file.
@@ -109,7 +109,7 @@
 
 deps = {
   'src/breakpad/src':
-   Var('chromium_git') + '/external/google-breakpad/src.git' + '@' + 'e15ba2c4d7d3b10c8c2818aa14ab66ad9a383ff6', # from svn revision 1388
+   Var('chromium_git') + '/external/google-breakpad/src.git' + '@' + 'f37b59821ecbd69c54f3388026d2e98cd8b2fba2', # from svn revision 1397
 
   'src/buildtools':
    Var('chromium_git') + '/chromium/buildtools.git' + '@' +  Var('buildtools_revision'),
@@ -130,13 +130,13 @@
    Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',
 
   'src/third_party/trace-viewer':
-   Var('chromium_git') + '/external/trace-viewer.git' + '@' + '3bf3f6d734fc2ff47a756450c5d69dfbaf7d917a',
+   Var('chromium_git') + '/external/trace-viewer.git' + '@' + 'c3e5dde9384d641ddec8a5dcf4081fd520f0e096',
 
   'src/third_party/WebKit':
    Var('chromium_git') + '/chromium/blink.git' + '@' +  Var('webkit_revision'),
 
   'src/third_party/icu':
-   Var('chromium_git') + '/chromium/deps/icu52.git' + '@' + '8ac906faf7b66180f2208380c35ae1e07136c5cc', # from svn revision 292317
+   Var('chromium_git') + '/chromium/deps/icu52.git' + '@' + 'd8b2a9d7b0039a4950ee008c5b1d998902c44c60', # from svn revision 292476
 
   'src/third_party/libexif/sources':
    Var('chromium_git') + '/chromium/deps/libexif/sources.git' + '@' + 'ed98343daabd7b4497f97fda972e132e6877c48a',
@@ -169,7 +169,7 @@
     Var('chromium_git') + '/external/grit-i18n.git' + '@' + '740badd5e3e44434a9a47b5d16749daac1e8ea80', # from svn revision 176
 
   'src/tools/gyp':
-    Var('chromium_git') + '/external/gyp.git' + '@' + '9202573e476f9f61341aec21b585cdc984141916', # from svn revision 1990
+    Var('chromium_git') + '/external/gyp.git' + '@' + 'a61e860884929dd46cb55de7916a7ba067a8a655', # from svn revision 1991
 
   'src/tools/swarming_client':
    Var('chromium_git') + '/external/swarming.client.git' + '@' +  Var('swarming_revision'),
@@ -453,7 +453,7 @@
      Var('chromium_git') + '/external/android_webview_glue.git' + '@' + '7d62eab4ca242beacac4471c002e998ef5c218b8',
 
     'src/third_party/android_tools':
-     Var('chromium_git') + '/android_tools.git' + '@' + '36bf7ac9a608f95f642ec64a743feea3b2e5a8d5',
+     Var('chromium_git') + '/android_tools.git' + '@' + 'ea50cccc11657404ce22cf928062ed1a3927eb39',
 
     'src/third_party/apache-mime4j':
      Var('chromium_git') + '/chromium/deps/apache-mime4j.git' + '@' + '28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',
@@ -547,16 +547,6 @@
     ],
   },
   {
-    # Downloads an ARM sysroot image to src/arm-sysroot. This image updates
-    # at about the same rate that the chrome build deps change.
-    # This script is a no-op except for linux users who have
-    # target_arch=arm in their GYP_DEFINES.
-    'name': 'sysroot',
-    'pattern': '.',
-    'action': ['python', 'src/build/linux/install-arm-sysroot.py',
-               '--linux-only'],
-  },
-  {
     # Downloads the Debian Wheezy sysroot to chrome/installer/linux if needed.
     # This sysroot updates at about the same rate that the chrome build deps
     # change. This script is a no-op except for linux users who are doing
@@ -580,6 +570,16 @@
         '--arch=i386'],
   },
   {
+    # Same as above, but for ARM Linux.
+    'name': 'sysroot',
+    'pattern': '.',
+    'action': [
+        'python',
+        'src/chrome/installer/linux/sysroot_scripts/install-debian.wheezy.sysroot.py',
+        '--linux-only',
+        '--arch=arm'],
+  },
+  {
     # Update the Windows toolchain if necessary.
     'name': 'win_toolchain',
     'pattern': '.',
@@ -729,7 +729,7 @@
     'action': ['python',
                'src/build/get_syzygy_binaries.py',
                '--output-dir=src/third_party/syzygy/binaries',
-               '--revision=363bc02a09c380b6f5f397606cc0744d85d54a51',
+               '--revision=6a46c83649012c692b940218a4a2a8f560d4df77',
                '--overwrite',
     ],
   },
diff --git a/OWNERS b/OWNERS
index 587377cb..28f143e4 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,8 @@
-darin@chromium.org
 ben@chromium.org
+brettw@chromium.org
+cpu@chromium.org
+darin@chromium.org
+jam@chromium.org
 per-file .gitignore=*
 per-file DEPS=*
 per-file AUTHORS=*
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index eafc8fe3..8ec7f532 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1239,7 +1239,7 @@
       documentation is ignored by the hooks as it
       needs to be consumed by WebKit. """
   results = []
-  file_inclusion_pattern = (r".+\.css$")
+  file_inclusion_pattern = (r".+\.css$",)
   black_list = (_EXCLUDED_PATHS +
                 _TEST_CODE_EXCLUDED_PATHS +
                 input_api.DEFAULT_BLACK_LIST +
@@ -1251,27 +1251,35 @@
   for fpath in input_api.AffectedFiles(file_filter=file_filter):
     for line_num, line in fpath.ChangedContents():
       for (deprecated_value, value) in _DEPRECATED_CSS:
-        if input_api.re.search(deprecated_value, line):
+        if deprecated_value in line:
           results.append(output_api.PresubmitError(
               "%s:%d: Use of deprecated CSS %s, use %s instead" %
               (fpath.LocalPath(), line_num, deprecated_value, value)))
   return results
 
 
-def _CheckForOverrideAndFinalRules(input_api, output_api):
-  """Checks for final and override used as per C++11"""
-  problems = []
-  for f in input_api.AffectedFiles():
-    if (f.LocalPath().endswith(('.cc', '.cpp', '.h', '.mm'))):
-      for line_num, line in f.ChangedContents():
-        if (input_api.re.search(r'\b(FINAL|OVERRIDE)\b', line)):
-          problems.append('    %s:%d' % (f.LocalPath(), line_num))
+_DEPRECATED_JS = [
+  ( "__lookupGetter__", "Object.getOwnPropertyDescriptor" ),
+  ( "__defineGetter__", "Object.defineProperty" ),
+  ( "__defineSetter__", "Object.defineProperty" ),
+]
 
-  if not problems:
-    return []
-  return [output_api.PresubmitError('Use C++11\'s |final| and |override| '
-                                    'rather than FINAL and OVERRIDE.',
-                                    problems)]
+def _CheckNoDeprecatedJS(input_api, output_api):
+  """Make sure that we don't use deprecated JS in Chrome code."""
+  results = []
+  file_inclusion_pattern = (r".+\.js$",)  # TODO(dbeam): .html?
+  black_list = (_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
+                input_api.DEFAULT_BLACK_LIST)
+  file_filter = lambda f: input_api.FilterSourceFile(
+      f, white_list=file_inclusion_pattern, black_list=black_list)
+  for fpath in input_api.AffectedFiles(file_filter=file_filter):
+    for lnum, line in fpath.ChangedContents():
+      for (deprecated, replacement) in _DEPRECATED_JS:
+        if deprecated in line:
+          results.append(output_api.PresubmitError(
+              "%s:%d: Use of deprecated JS %s, use %s instead" %
+              (fpath.LocalPath(), lnum, deprecated, replacement)))
+  return results
 
 
 def _CommonChecks(input_api, output_api):
@@ -1313,9 +1321,9 @@
   results.extend(_CheckCygwinShell(input_api, output_api))
   results.extend(_CheckUserActionUpdate(input_api, output_api))
   results.extend(_CheckNoDeprecatedCSS(input_api, output_api))
+  results.extend(_CheckNoDeprecatedJS(input_api, output_api))
   results.extend(_CheckParseErrors(input_api, output_api))
   results.extend(_CheckForIPCRules(input_api, output_api))
-  results.extend(_CheckForOverrideAndFinalRules(input_api, output_api))
 
   if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
     results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
@@ -1606,22 +1614,22 @@
       'linux_gtk': standard_tests,
       'linux_chromeos_asan': ['compile'],
       'linux_chromium_chromeos_clang_dbg': ['defaulttests'],
-      'linux_chromium_chromeos_rel_swarming': ['defaulttests'],
+      'linux_chromium_chromeos_rel': ['defaulttests'],
       'linux_chromium_compile_dbg': ['defaulttests'],
       'linux_chromium_gn_dbg': ['compile'],
       'linux_chromium_gn_rel': ['defaulttests'],
-      'linux_chromium_rel_swarming': ['defaulttests'],
+      'linux_chromium_rel': ['defaulttests'],
       'linux_chromium_clang_dbg': ['defaulttests'],
       'linux_gpu': ['defaulttests'],
       'linux_nacl_sdk_build': ['compile'],
       'mac_chromium_compile_dbg': ['defaulttests'],
-      'mac_chromium_rel_swarming': ['defaulttests'],
+      'mac_chromium_rel': ['defaulttests'],
       'mac_gpu': ['defaulttests'],
       'mac_nacl_sdk_build': ['compile'],
       'win_chromium_compile_dbg': ['defaulttests'],
       'win_chromium_dbg': ['defaulttests'],
-      'win_chromium_rel_swarming': ['defaulttests'],
-      'win_chromium_x64_rel_swarming': ['defaulttests'],
+      'win_chromium_rel': ['defaulttests'],
+      'win_chromium_x64_rel': ['defaulttests'],
       'win_gpu': ['defaulttests'],
       'win_nacl_sdk_build': ['compile'],
       'win8_chromium_rel': ['defaulttests'],
@@ -1671,12 +1679,12 @@
   if all(re.search(r'\.(m|mm)$|(^|[\\\/_])mac[\\\/_.]', f) for f in files):
     return GetDefaultTryConfigs([
         'mac_chromium_compile_dbg',
-        'mac_chromium_rel_swarming',
+        'mac_chromium_rel',
     ])
   if all(re.search('(^|[/_])win[/_.]', f) for f in files):
     return GetDefaultTryConfigs([
         'win_chromium_dbg',
-        'win_chromium_rel_swarming',
+        'win_chromium_rel',
         'win8_chromium_rel',
     ])
   if all(re.search(r'(^|[\\\/_])android[\\\/_.]', f) for f in files):
@@ -1698,18 +1706,18 @@
       'ios_dbg_simulator',
       'ios_rel_device',
       'ios_rel_device_ninja',
-      'linux_chromium_chromeos_rel_swarming',
+      'linux_chromium_chromeos_rel',
       'linux_chromium_clang_dbg',
       'linux_chromium_gn_dbg',
       'linux_chromium_gn_rel',
-      'linux_chromium_rel_swarming',
+      'linux_chromium_rel',
       'linux_gpu',
       'mac_chromium_compile_dbg',
-      'mac_chromium_rel_swarming',
+      'mac_chromium_rel',
       'mac_gpu',
       'win_chromium_compile_dbg',
-      'win_chromium_rel_swarming',
-      'win_chromium_x64_rel_swarming',
+      'win_chromium_rel',
+      'win_chromium_x64_rel',
       'win_gpu',
       'win8_chromium_rel',
   ]
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
index 02a10c6..a3eef95 100755
--- a/PRESUBMIT_test.py
+++ b/PRESUBMIT_test.py
@@ -413,66 +413,6 @@
     self.assertEqual(0, len(errors))
 
 
-class InvalidOverideAndFinalTest(unittest.TestCase):
-  def testValidOverrideConstructs(self):
-    mock_input_api = MockInputApi()
-    lines = ['foo1() override;',
-             'foo2() final;',
-             '#DEFINE OVERRIDE_METHOD_OVERLOAD',
-             '#DEFINE FINAL_METHOD',
-             '#DEFINE OVERRIDE_OVERRIDE_SOMETHING',
-             '#DEFINE SOMETHING_OVERRIDE_SOMETHING',
-             '#DEFINE SOMETHING_SOMETHING_OVERRIDE',
-             '#DEFINE FINAL_OVERRIDE_FINAL',
-             '#DEFINE SOMETHING_OVERRIDE_FINAL',
-             '#DEFINE OVERRIDE_OVERRIDE_OVERRIDE',
-             '#endif  // FINAL_METHOD',
-             '#endif  // OVERRIDE_METHOD_OVERLOAD']
-    mock_file_h = MockFile('something.h', lines)
-    mock_input_api.files = [mock_file_h]
-    errors = PRESUBMIT._CheckForOverrideAndFinalRules(mock_input_api,
-                                                      MockOutputApi())
-    self.assertEqual(0, len(errors))
-
-  def testInvalidOverrideConstructsInHeaders(self):
-    mock_input_api = MockInputApi()
-    lines_cpp = ['foo2() FINAL;']
-    lines_h = ['foo1() OVERRIDE;']
-    mock_file_cpp = MockFile('something.cpp', lines_cpp)
-    mock_file_h = MockFile('something.h', lines_h)
-    mock_input_api.files = [mock_file_cpp, mock_file_h]
-    errors = PRESUBMIT._CheckForOverrideAndFinalRules(mock_input_api,
-                                                      MockOutputApi())
-    self.assertEqual(1, len(errors))
-
-  def testInvalidOverrideConstructsInCpp(self):
-    mock_input_api = MockInputApi()
-    lines_cpp = ['foo2() FINAL;']
-    mock_file_cpp = MockFile('something.cpp', lines_cpp)
-    mock_input_api.files = [mock_file_cpp]
-    errors = PRESUBMIT._CheckForOverrideAndFinalRules(mock_input_api,
-                                                      MockOutputApi())
-    self.assertEqual(1, len(errors))
-
-  def testInvalidOverrideConstructsInCc(self):
-    mock_input_api = MockInputApi()
-    lines_cc = ['foo3() override FINAL;']
-    mock_file_cc = MockFile('something.cc', lines_cc)
-    mock_input_api.files = [mock_file_cc]
-    errors = PRESUBMIT._CheckForOverrideAndFinalRules(mock_input_api,
-                                                      MockOutputApi())
-    self.assertEqual(1, len(errors))
-
-  def testInvalidOverrideConstructsInMm(self):
-    mock_input_api = MockInputApi()
-    lines_mm = ['foo4() OVERRIDE final;']
-    mock_file_mm = MockFile('something.mm', lines_mm)
-    mock_input_api.files = [mock_file_mm]
-    errors = PRESUBMIT._CheckForOverrideAndFinalRules(mock_input_api,
-                                                      MockOutputApi())
-    self.assertEqual(1, len(errors))
-
-
 class InvalidIfDefinedMacroNamesTest(unittest.TestCase):
   def testInvalidIfDefinedMacroNames(self):
     lines = ['#if defined(TARGET_IPHONE_SIMULATOR)',
@@ -751,7 +691,6 @@
             'mac_chromium_compile_rel',
             'mac_chromium_dbg',
             'mac_chromium_rel',
-            'mac_chromium_rel_swarming',
             'mac_nacl_sdk',
             'mac_nacl_sdk_build',
             'mac_rel_naclmore',
@@ -794,7 +733,6 @@
             'linux_chromium_gn_dbg',
             'linux_chromium_gn_rel',
             'linux_chromium_rel',
-            'linux_chromium_rel_swarming',
             'linux_chromium_trusty32_dbg',
             'linux_chromium_trusty32_rel',
             'linux_chromium_trusty_dbg',
@@ -824,8 +762,6 @@
             'win_chromium_dbg',
             'win_chromium_rel',
             'win_chromium_rel',
-            'win_chromium_rel_swarming',
-            'win_chromium_rel_swarming',
             'win_chromium_x64_dbg',
             'win_chromium_x64_rel',
             'win_drmemory',
diff --git a/WATCHLISTS b/WATCHLISTS
index 7ba389d..e9b76a42 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -896,7 +896,6 @@
                 'kmadhusu+watch@chromium.org', 'dhollowa+watch@chromium.org',
                 'jfweitz+watch@chromium.org', 'skanuj+watch@chromium.org'],
     'ipc': ['jam@chromium.org', 'darin-cc@chromium.org'],
-    'ipc_messages': [ 'mkwst+moarreviews-ipc@chromium.org' ],
     'libwebp': ['urvang@google.com', 'jzern@chromium.org',
                 'skal@google.com', 'vikasa@google.com'],
     'linux_fonts': ['derat+watch@chromium.org'],
@@ -937,7 +936,7 @@
     'ozone': ['kalyan.kondapally@intel.com', 'ozone-reviews@chromium.org'],
     'panels': ['dimich@chromium.org', 'jennb@chromium.org',
                'dcheng@chromium.org', 'jianli@chromium.org'],
-    'password_manager': ['mkwst+watchlist@chromium.org',
+    'password_manager': ['mkwst+watchlist-passwords@chromium.org',
                          'gcasto+watchlist@chromium.org'],
     'pepper_api': ['piman+watch@chromium.org', 'ihf+watch@chromium.org',
                    'yusukes+watch@chromium.org', 'raymes+watch@chromium.org',
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index 31e9da88..79d7b17c 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -20,6 +20,7 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_params.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h"
 #include "components/user_prefs/user_prefs.h"
 #include "components/visitedlink/browser/visitedlink_master.h"
 #include "content/public/browser/browser_thread.h"
@@ -94,6 +95,10 @@
       context->GetDataReductionProxySettings();
   if (proxy_settings == NULL)
     return;
+
+  context->CreateDataReductionProxyStatisticsIfNecessary();
+  proxy_settings->SetDataReductionProxyStatisticsPrefs(
+      context->data_reduction_proxy_statistics_.get());
   proxy_settings->SetDataReductionProxyEnabled(data_reduction_proxy_enabled_);
 }
 
@@ -211,9 +216,9 @@
     data_reduction_proxy_settings_->InitDataReductionProxySettings(
         user_pref_service_.get(),
         GetRequestContext());
+    data_reduction_proxy_settings_->MaybeActivateDataReductionProxy(true);
 
-    data_reduction_proxy_settings_->SetDataReductionProxyEnabled(
-        data_reduction_proxy_enabled_);
+    SetDataReductionProxyEnabled(data_reduction_proxy_enabled_);
   }
 }
 
@@ -293,4 +298,19 @@
   enumerator->OnComplete(true);
 }
 
+void AwBrowserContext::CreateDataReductionProxyStatisticsIfNecessary() {
+  DCHECK(user_pref_service_.get());
+
+  if (!data_reduction_proxy_statistics_.get()) {
+    // We don't care about commit_delay for now. It is just a dummy value.
+    base::TimeDelta commit_delay = base::TimeDelta::FromMinutes(60);
+    data_reduction_proxy_statistics_ =
+        scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>(
+            new data_reduction_proxy::DataReductionProxyStatisticsPrefs(
+                user_pref_service_.get(),
+                base::MessageLoopProxy::current(),
+                commit_delay));
+  }
+}
+
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index d6c1b37..3f49765 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -30,6 +30,7 @@
 namespace data_reduction_proxy {
 class DataReductionProxyConfigurator;
 class DataReductionProxySettings;
+class DataReductionProxyStatisticsPrefs;
 }
 
 namespace net {
@@ -116,6 +117,7 @@
       const scoped_refptr<URLEnumerator>& enumerator) override;
 
  private:
+  void CreateDataReductionProxyStatisticsIfNecessary();
   static bool data_reduction_proxy_enabled_;
 
   // The file path where data for this context is persisted.
@@ -136,6 +138,8 @@
 
   scoped_ptr<data_reduction_proxy::DataReductionProxyConfigurator>
       data_reduction_proxy_configurator_;
+  scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
+      data_reduction_proxy_statistics_;
   scoped_ptr<data_reduction_proxy::DataReductionProxySettings>
       data_reduction_proxy_settings_;
 
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index be3e162e..59c3038 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -21,7 +21,7 @@
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPicture.h"
 #include "third_party/skia/include/core/SkPictureRecorder.h"
-#include "ui/gfx/vector2d_conversions.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 
 using content::SynchronousCompositorMemoryPolicy;
 
@@ -61,8 +61,9 @@
     g_memory_override_in_bytes *= 1024 * 1024;
   }
 
-  // Also use a high tile limit since there are no file descriptor issues.
-  GlobalTileManager::GetInstance()->SetTileLimit(1000);
+  // There is no need to limit number of tiles, so use an effectively unlimited
+  // value as the limit.
+  GlobalTileManager::GetInstance()->SetTileLimit(10 * 1000 * 1000);
 }
 
 BrowserViewRenderer::BrowserViewRenderer(
@@ -85,6 +86,7 @@
       on_new_picture_enable_(false),
       clear_view_(false),
       compositor_needs_continuous_invalidate_(false),
+      invalidate_after_composite_(false),
       block_invalidates_(false),
       fallback_tick_pending_(false),
       width_(0),
@@ -211,13 +213,6 @@
     return false;
 
   shared_renderer_state_->SetScrollOffset(last_on_draw_scroll_offset_);
-  if (last_on_draw_global_visible_rect_.IsEmpty()) {
-    TRACE_EVENT_INSTANT0("android_webview",
-                         "EarlyOut_EmptyVisibleRect",
-                         TRACE_EVENT_SCOPE_THREAD);
-    shared_renderer_state_->SetForceInvalidateOnNextDrawGL(true);
-    return client_->RequestDrawGL(java_canvas, false);
-  }
 
   if (!hardware_enabled_) {
     hardware_enabled_ = compositor_->InitializeHwDraw();
@@ -228,12 +223,21 @@
   if (!hardware_enabled_)
     return false;
 
+  if (last_on_draw_global_visible_rect_.IsEmpty() &&
+      parent_draw_constraints_.surface_rect.IsEmpty()) {
+    TRACE_EVENT_INSTANT0("android_webview",
+                         "EarlyOut_EmptyVisibleRect",
+                         TRACE_EVENT_SCOPE_THREAD);
+    shared_renderer_state_->SetForceInvalidateOnNextDrawGL(true);
+    return client_->RequestDrawGL(java_canvas, false);
+  }
+
   ReturnResourceFromParent();
   if (shared_renderer_state_->HasCompositorFrame()) {
     TRACE_EVENT_INSTANT0("android_webview",
                          "EarlyOut_PreviousFrameUnconsumed",
                          TRACE_EVENT_SCOPE_THREAD);
-    SkippedCompositeInDraw();
+    DidSkipCompositeInDraw();
     return client_->RequestDrawGL(java_canvas, false);
   }
 
@@ -262,10 +266,12 @@
   // applied onto the layer so global visible rect does not make sense here.
   // In this case, just use the surface rect for tiling.
   gfx::Rect viewport_rect_for_tile_priority;
-  if (parent_draw_constraints_.is_layer)
+  if (parent_draw_constraints_.is_layer ||
+      last_on_draw_global_visible_rect_.IsEmpty()) {
     viewport_rect_for_tile_priority = parent_draw_constraints_.surface_rect;
-  else
+  } else {
     viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_;
+  }
 
   scoped_ptr<cc::CompositorFrame> frame =
       compositor_->DemandDrawHw(surface_size,
@@ -282,11 +288,13 @@
 void BrowserViewRenderer::UpdateParentDrawConstraints() {
   // Post an invalidate if the parent draw constraints are stale and there is
   // no pending invalidate.
-  if (shared_renderer_state_->NeedsForceInvalidateOnNextDrawGL() ||
+  bool needs_force_invalidate =
+      shared_renderer_state_->NeedsForceInvalidateOnNextDrawGL();
+  if (needs_force_invalidate ||
       !parent_draw_constraints_.Equals(
-        shared_renderer_state_->ParentDrawConstraints())) {
+          shared_renderer_state_->ParentDrawConstraints())) {
     shared_renderer_state_->SetForceInvalidateOnNextDrawGL(false);
-    EnsureContinuousInvalidation(true, false);
+    EnsureContinuousInvalidation(true, needs_force_invalidate);
   }
 }
 
@@ -310,6 +318,11 @@
   }
 }
 
+void BrowserViewRenderer::DidSkipCommitFrame() {
+  // Treat it the same way as skipping onDraw.
+  DidSkipCompositeInDraw();
+}
+
 bool BrowserViewRenderer::OnDrawSoftware(jobject java_canvas) {
   if (!compositor_) {
     TRACE_EVENT_INSTANT0(
@@ -656,12 +669,18 @@
 void BrowserViewRenderer::EnsureContinuousInvalidation(
     bool force_invalidate,
     bool skip_reschedule_tick) {
+  if (force_invalidate)
+    invalidate_after_composite_ = true;
+
   // This method should be called again when any of these conditions change.
   bool need_invalidate =
-      compositor_needs_continuous_invalidate_ || force_invalidate;
+      compositor_needs_continuous_invalidate_ || invalidate_after_composite_;
   if (!need_invalidate || block_invalidates_)
     return;
 
+  if (!compositor_needs_continuous_invalidate_ && invalidate_after_composite_)
+    invalidate_after_composite_ = false;
+
   // Always call view invalidate. We rely the Android framework to ignore the
   // invalidate when it's not needed such as when view is not visible.
   client_->PostInvalidate();
@@ -764,9 +783,9 @@
   EnsureContinuousInvalidation(false, false);
 }
 
-void BrowserViewRenderer::SkippedCompositeInDraw() {
+void BrowserViewRenderer::DidSkipCompositeInDraw() {
   block_invalidates_ = false;
-  EnsureContinuousInvalidation(false, true);
+  EnsureContinuousInvalidation(true, true);
 }
 
 std::string BrowserViewRenderer::ToString() const {
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h
index 61fadc1..1fc5650 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/browser_view_renderer.h
@@ -141,6 +141,7 @@
       bool effective_immediately) override;
 
   void UpdateParentDrawConstraints();
+  void DidSkipCommitFrame();
 
  private:
   void SetTotalRootLayerScrollOffset(gfx::Vector2dF new_value_dip);
@@ -154,7 +155,7 @@
   bool OnDrawSoftware(jobject java_canvas);
   bool CompositeSW(SkCanvas* canvas);
   void DidComposite();
-  void SkippedCompositeInDraw();
+  void DidSkipCompositeInDraw();
   scoped_refptr<base::debug::ConvertableToTraceFormat> RootLayerStateAsValue(
       const gfx::Vector2dF& total_scroll_offset_dip,
       const gfx::SizeF& scrollable_size_dip);
@@ -216,6 +217,8 @@
   // states.
   bool compositor_needs_continuous_invalidate_;
 
+  bool invalidate_after_composite_;
+
   // Used to block additional invalidates while one is already pending.
   bool block_invalidates_;
 
diff --git a/android_webview/browser/browser_view_renderer_client.h b/android_webview/browser/browser_view_renderer_client.h
index 2fba4d2..ebf5b7b 100644
--- a/android_webview/browser/browser_view_renderer_client.h
+++ b/android_webview/browser/browser_view_renderer_client.h
@@ -31,6 +31,9 @@
   // Called to update the parent draw constraints in browser view renderer.
   virtual void UpdateParentDrawConstraints() = 0;
 
+  // Called if commit is skipped due to pipeline stall.
+  virtual void DidSkipCommitFrame() = 0;
+
   // Called to get view's absolute location on the screen.
   virtual gfx::Point GetLocationOnScreen() = 0;
 
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index 49679a9f..3511bb8d 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -144,6 +144,7 @@
     TRACE_EVENT_INSTANT0("android_webview",
                          "EarlyOut_PreviousFrameUnconsumed",
                          TRACE_EVENT_SCOPE_THREAD);
+    shared_renderer_state_->DidSkipCommitFrame();
     return;
   }
 
diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc
index 5450da6..0de8371 100644
--- a/android_webview/browser/shared_renderer_state.cc
+++ b/android_webview/browser/shared_renderer_state.cc
@@ -186,6 +186,18 @@
   }
 }
 
+void SharedRendererState::DidSkipCommitFrame() {
+  ui_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&SharedRendererState::DidSkipCommitFrameOnUIThread,
+                 ui_thread_weak_ptr_));
+}
+
+void SharedRendererState::DidSkipCommitFrameOnUIThread() {
+  DCHECK(ui_loop_->BelongsToCurrentThread());
+  client_on_ui_->DidSkipCommitFrame();
+}
+
 const ParentCompositorDrawConstraints
 SharedRendererState::ParentDrawConstraints() const {
   base::AutoLock lock(lock_);
diff --git a/android_webview/browser/shared_renderer_state.h b/android_webview/browser/shared_renderer_state.h
index 9b60cf1..29d05c2 100644
--- a/android_webview/browser/shared_renderer_state.h
+++ b/android_webview/browser/shared_renderer_state.h
@@ -49,6 +49,7 @@
       const ParentCompositorDrawConstraints& parent_draw_constraints);
   void PostExternalDrawConstraintsToChildCompositor(
       const ParentCompositorDrawConstraints& parent_draw_constraints);
+  void DidSkipCommitFrame();
 
   const ParentCompositorDrawConstraints ParentDrawConstraints() const;
 
@@ -67,6 +68,7 @@
   void ResetRequestDrawGLCallback();
   void ClientRequestDrawGLOnUIThread();
   void UpdateParentDrawConstraintsOnUIThread();
+  void DidSkipCommitFrameOnUIThread();
   void SetInsideHardwareRelease(bool inside);
 
   scoped_refptr<base::MessageLoopProxy> ui_loop_;
diff --git a/android_webview/buildbot/aosp_manifest.xml b/android_webview/buildbot/aosp_manifest.xml
index 3b6755b..15c56a5 100644
--- a/android_webview/buildbot/aosp_manifest.xml
+++ b/android_webview/buildbot/aosp_manifest.xml
@@ -11,14 +11,14 @@
   <project name="platform/frameworks/webview" path="frameworks/webview" revision="7d62eab4ca242beacac4471c002e998ef5c218b8"/>
 
   <project groups="device,flo" name="device/asus/deb" revision="0ce3a783d549d023ddc553a04fed717ffb2ff533"/>
-  <project groups="device,flo" name="device/asus/flo" revision="55ea79b11f9f82b2aa03f44a3429112fc5c06d07"/>
+  <project groups="device,flo" name="device/asus/flo" revision="13b0b88382596da2833a7907dd3c9012b5fe07c4"/>
   <project groups="device,flo" name="device/asus/flo-kernel" revision="6d74123947016999ae62d9c3067ae97782fdba21"/>
-  <project groups="device,grouper" name="device/asus/grouper" revision="78fe48f44e90ef3a7eceab5465dbad63cd16ce88"/>
-  <project groups="device,grouper" name="device/asus/tilapia" revision="e5033bc80764067cbb1c9dc3970f0718e35ae8c7"/>
+  <project groups="device,grouper" name="device/asus/grouper" revision="105946dfceb0e40edd26b438109f0bacc70285b1"/>
+  <project groups="device,grouper" name="device/asus/tilapia" revision="dbcd8921423228a57c95b640f6675ada687d301a"/>
   <project name="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
   <project groups="pdk" name="device/generic/armv7-a-neon" revision="8bcf4b7a6380b26c2b42dae00dd8443de2a8e12c"/>
   <project groups="pdk" name="device/generic/common" revision="11c092a6cbfcf6207f07a9a8e3398e747e7f5461"/>
-  <project groups="pdk" name="device/generic/goldfish" revision="7d3d0c99d2c82319e001289d1b9e091e5ff8f7aa"/>
+  <project groups="pdk" name="device/generic/goldfish" revision="dc69376bd3d1c65ad19abfc036a85266b2199136"/>
   <project groups="pdk" name="device/generic/mini-emulator-armv7-a-neon" revision="2a7ade61377b7906187ab46b5859c896baa0ab0e"/>
   <project groups="pdk" name="device/generic/mini-emulator-mips" revision="2ff06dda649ba43507a911057f7854a3373ef7d6"/>
   <project groups="pdk" name="device/generic/mini-emulator-x86" revision="a2f05b8c5259c232be5b029b2d5e721ba3f70917"/>
@@ -27,75 +27,71 @@
   <project groups="pdk" name="device/generic/x86" revision="f111878fb41e2bdf4eb092d1edf0eb53cc5d0153"/>
   <project groups="device" name="device/google/accessory/arduino" revision="abc5159a3ca9dbb5c7e364a1eab99901a4440ac5"/>
   <project groups="device" name="device/google/accessory/demokit" revision="7dfe7f89a3b174709c773fe319531006e46440d9"/>
-  <project groups="device,hammerhead" name="device/lge/hammerhead" revision="c24a30da3c3da741dc830d287ad4ec6054dd3a83"/>
+  <project groups="device,hammerhead" name="device/lge/hammerhead" revision="592ef0a5477f2d946b806a5e33136553c3969735"/>
   <project groups="device,hammerhead" name="device/lge/hammerhead-kernel" revision="a1dc58be96e7a71496e3e89079ac704930f982f2"/>
-  <project groups="device,mako" name="device/lge/mako" revision="7e5f0f313819ffa3b45cd4208ab552f446c33936"/>
+  <project groups="device,mako" name="device/lge/mako" revision="fa8fcca4de6019bb46d25dcef554154701781c37"/>
   <project groups="device,mako" name="device/lge/mako-kernel" revision="b7de901b8cb86036e9b92b3b6f188b45a524b125"/>
-  <project groups="pdk" name="device/sample" revision="096f9eb5763fd2766fcbbe4f6b9da51c87f61797"/>
-  <project groups="device,manta" name="device/samsung/manta" revision="10149f87f34ba720be946e0b1a696ce135e1f58f"/>
-  <project groups="pdk" name="platform/abi/cpp" path="abi/cpp" revision="a0f99286d0909f7a30b0bee742bec2a0b62c4dd0"/>
-  <project name="platform/art" path="art" revision="dcea56f4132bc19abf867ee9ef01244d5283c2cf"/>
-  <project groups="pdk" name="platform/bionic" path="bionic" revision="5120bcf9f11951bffd8ac595c2b70252ed4a4958"/>
+  <project groups="pdk" name="device/sample" revision="b547634be491c688cc313b6d10e9a6ad1ccc7f16"/>
+  <project groups="device,manta" name="device/samsung/manta" revision="6893bedca60b3fca06755399d05c96be37992d4d"/>
+  <project groups="pdk" name="platform/abi/cpp" path="abi/cpp" revision="1c7cf0400b5fd28491d2d670ac4482120542ce4b"/>
+  <project name="platform/art" path="art" revision="37a7188810e865a1ee0a7bdc2d01d62c1f1ea49e"/>
+  <project groups="pdk" name="platform/bionic" path="bionic" revision="cf8ea37fc91e23d37b3c5873b5e152ccae293f03"/>
   <project name="platform/bootable/bootloader/legacy" path="bootable/bootloader/legacy" revision="3c491d6efb8ff2534a6934702760a6273f197918"/>
-  <project name="platform/bootable/diskinstaller" path="bootable/diskinstaller" revision="ca40959a8caafa0df6a5c3d845e2afe6b252093f"/>
-  <project groups="pdk" name="platform/bootable/recovery" path="bootable/recovery" revision="974fe112ae6df95ca6d49688d6e3e459d87e16de"/>
-  <project groups="pdk" name="platform/build" path="build" revision="7852b80c05e33c873819b1bf22bcaa54bb583c99">
+  <project groups="pdk" name="platform/bootable/recovery" path="bootable/recovery" revision="4f66469b29a34811b69518a266be31fe42cc111b"/>
+  <project groups="pdk" name="platform/build" path="build" revision="4dfda1fa4201e41022396b77054168ffc73b590c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project groups="cts" name="platform/cts" path="cts" revision="b344a4ac011ff284f8c3dc82aca5c82a34e2dee5"/>
-  <project name="platform/dalvik" path="dalvik" revision="51deeeae0f8616d45414aa916bf961e053634eb0"/>
+  <project groups="cts" name="platform/cts" path="cts" revision="ab3c59d0e7a07ccf4a51c63cdf77802bdbcedd3f"/>
+  <project name="platform/dalvik" path="dalvik" revision="0bfe5322bdb29a3d4bb520073893dffa16dd17b3"/>
   <project name="platform/developers/build" path="developers/build" revision="75c5c41b06f045c3304b1b19d8250f04a8da8f10"/>
   <project name="platform/developers/demos" path="developers/demos" revision="64526120cd8da89bcb9a48acf95307d2c172a6e8"/>
   <project name="platform/developers/docs" path="developers/docs" revision="c0b835ddd9acc27176dc9a0f7d1aa2faf5d51806"/>
   <project name="platform/developers/samples/android" path="developers/samples/android" revision="dea82fa23f038d66bd9cfdff2afb8ef22add1c4f"/>
-  <project name="platform/development" path="development" revision="72bd04795b38b8dbbbf5d4b6e8c5cac2a4322702"/>
-  <project name="platform/docs/source.android.com" path="docs/source.android.com" revision="e2caa98f86abc325a11ecff6980d703ffd673ab1"/>
-  <project groups="pdk" name="platform/external/aac" path="external/aac" revision="2decc77814e729df47464a504123f9b398ac7077"/>
-  <project name="platform/external/android-clat" path="external/android-clat" revision="05ff508a793c2113ca2a06942f0cec1aec220799"/>
-  <project name="platform/external/android-mock" path="external/android-mock" revision="4fe497660c2e939300dc5b743d662aef458b1726"/>
+  <project name="platform/development" path="development" revision="c13cf09c4cab0babd7dda0f7884ae7367a40b4e9"/>
+  <project name="platform/docs/source.android.com" path="docs/source.android.com" revision="8515e62ee6831dc1feae298be3ccebcd0950f615"/>
+  <project groups="pdk" name="platform/external/aac" path="external/aac" revision="7e46495606bd66973a10565f932acee7bddcc003"/>
+  <project name="platform/external/android-clat" path="external/android-clat" revision="89f49ae6d7ddde7a765cce7ecd5006ecf97e8754"/>
   <project name="platform/external/ant-glob" path="external/ant-glob" revision="0f189400fd2a36bf11bfb058e7f3917eb7ed163a"/>
   <project name="platform/external/antlr" path="external/antlr" revision="47997265eeb7d954a32ece693bbe6dab740872dd"/>
-  <project name="platform/external/apache-harmony" path="external/apache-harmony" revision="0260dd36e8057a8469325042508fd53f952e3835"/>
+  <project name="platform/external/apache-harmony" path="external/apache-harmony" revision="a56966f5f8c66f861d69f4bd90c985e44501766e"/>
   <project name="platform/external/apache-http" path="external/apache-http" revision="85ed0e10781c3c57343300a02556dd5131c450aa"/>
   <project name="platform/external/apache-qp" path="external/apache-qp" revision="64ea622b23e6612eb8e7dcae6bfd4314beb022a8"/>
   <project name="platform/external/apache-xml" path="external/apache-xml" revision="00ee83ff1bd827a852065986ed0da7a3ded57a55"/>
-  <project name="platform/external/arduino" path="external/arduino" revision="d06daf9bbc46838400461eb8e15842974e38d82a"/>
+  <project name="platform/external/arduino" path="external/arduino" revision="60f21b2e195defce0d56fa789ece5cb04a34e37b"/>
   <project groups="pdk" name="platform/external/bison" path="external/bison" revision="c2418b886165add7f5a31fc5609f0ce2d004a90e"/>
   <project name="platform/external/blktrace" path="external/blktrace" revision="d345431f16b8f76f30a58193ff2b26d5853e1109"/>
-  <project groups="pdk" name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="3b4040093ddf0e0025d0dd034aa65078bb695514"/>
-  <project name="platform/external/bouncycastle" path="external/bouncycastle" revision="e46fd72598d3efe6d22c689da50ec30e433cbb19"/>
+  <project groups="pdk" name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="8b52f5f2f0eb1e3748a19af4438147872cba1cd2"/>
+  <project name="platform/external/bouncycastle" path="external/bouncycastle" revision="9454cc5f373b734695c29d079d62003b7de763df"/>
   <project groups="pdk" name="platform/external/bsdiff" path="external/bsdiff" revision="6f503758fad2cbcf8359e8f0af32e4d79a2a48ae"/>
   <project groups="pdk" name="platform/external/bzip2" path="external/bzip2" revision="1cb636bd8e9e5cdfd5d5b2909a122f6e80db62de"/>
   <project name="platform/external/ceres-solver" path="external/ceres-solver" revision="399f7d09e0c45af54b77b4ab9508d6f23759b927"/>
-  <project groups="pdk" name="platform/external/checkpolicy" path="external/checkpolicy" revision="c66ac590eebc731f6021f267ebea208e87d8f04f"/>
-  <project name="platform/external/chromium" path="external/chromium" revision="3b8ac3320cf35b5701a1e01d7ff72f450de2b184"/>
-  <project name="platform/external/chromium-libpac" path="external/chromium-libpac" revision="6bf4dfa9e7dc61b40316c0f8cfab335dbe53dd52"/>
+  <project groups="pdk" name="platform/external/checkpolicy" path="external/checkpolicy" revision="9961167f9690f31021be00ae2123128179125da5"/>
+  <project name="platform/external/chromium" path="external/chromium" revision="619b74c791c0fd5c106f679c425a58aca5bec1b1"/>
+  <project name="platform/external/chromium-libpac" path="external/chromium-libpac" revision="536e6cd684a10e16817cecb044ac2f0a46dfb6e4"/>
   <project groups="pdk" name="platform/external/chromium-trace" path="external/chromium-trace" revision="8252ae6b83ea65cf871e7981e981da07379f5a0f"/>
-  <project groups="pdk" name="platform/external/clang" path="external/clang" revision="123b2924ba712a33160a578e22fc3ab4318d9492"/>
-  <project groups="pdk" name="platform/external/compiler-rt" path="external/compiler-rt" revision="c185902e393cd71823258016ead1b315ed062b24"/>
-  <project name="platform/external/conscrypt" path="external/conscrypt" revision="04b3500f06f18dd4d2613004e22543d14ff3cf91"/>
+  <project groups="pdk" name="platform/external/clang" path="external/clang" revision="9e3e0e73011baba4988e958144fcc7ca3ae1261e"/>
+  <project groups="pdk" name="platform/external/compiler-rt" path="external/compiler-rt" revision="e6767d43983dfc8c878eec50859e3ed0e10d8685"/>
+  <project name="platform/external/conscrypt" path="external/conscrypt" revision="78b425a3489268653d32fda8edfca643fb645702"/>
   <project name="platform/external/dexmaker" path="external/dexmaker" revision="2b528c4b156f2de5c641875b98e59e0b09ebaccd"/>
-  <project name="platform/external/dhcpcd" path="external/dhcpcd" revision="03baf5eab896198b5060d287af3fd60d360bf48f"/>
+  <project name="platform/external/dhcpcd" path="external/dhcpcd" revision="e8960dc707b76d83fbf8a650314b93d8c28b1a38"/>
   <project groups="pdk" name="platform/external/dnsmasq" path="external/dnsmasq" revision="7674911bc9d10adf57c2c2d15d0c641b48e4afe6"/>
   <project name="platform/external/doclava" path="external/doclava" revision="b9d279d8f9c29a3044d13482846efb21f27b5df4"/>
-  <project groups="pdk" name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="721f3bc56989b5f4101e646a02d598ddb4a7ff6e"/>
+  <project groups="pdk" name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="e64b83185148d359b9b6cc1310172a3c213a61fb"/>
   <project name="platform/external/easymock" path="external/easymock" revision="c9a234086537e5fd820b110bbd99e3cdc695004c"/>
   <project name="platform/external/eclipse-basebuilder" path="external/eclipse-basebuilder" revision="6134da6347cc997e0cf2921aaadfb46f21c05d85"/>
   <project name="platform/external/eclipse-windowbuilder" path="external/eclipse-windowbuilder" revision="a5f3ee137e94737538ec3bdf9b3716765d178c17"/>
   <project name="platform/external/eigen" path="external/eigen" revision="b015e75e8c7ba1ab4ddb91e9372a57e76f3fd159"/>
-  <project name="platform/external/elfutils" path="external/elfutils" revision="6441455e365064bdeba3c8154430a068881d4a63"/>
-  <project name="platform/external/embunit" path="external/embunit" revision="336b7c65098af0d1be69f2db55f4e75342d73b3f"/>
+  <project name="platform/external/elfutils" path="external/elfutils" revision="a74b2e16a257455b25322913f6cd4899eca69179"/>
   <project name="platform/external/emma" path="external/emma" revision="daacd02a6b9f7a3e82bdf1cc5b84db85ed59edb1"/>
   <project name="platform/external/esd" path="external/esd" revision="224a67f2683a7ee997179fc5dd16115e39987b0f"/>
   <project groups="pdk" name="platform/external/expat" path="external/expat" revision="907ec055718996baf36961e7f47f8447e49b3865"/>
   <project name="platform/external/eyes-free" path="external/eyes-free" revision="16bd4c7a4d1bfe229068b637614dad7c48dd2ceb"/>
-  <project name="platform/external/f2fs-tools" path="external/f2fs-tools" revision="00dc8a1c6c87acf687e64e66cfc2fd7ca28e646e"/>
-  <project name="platform/external/fdlibm" path="external/fdlibm" revision="c831c726067e0d8a05362e710e2405f0eff81e07"/>
-  <project name="platform/external/fio" path="external/fio" revision="6f4e805b805f1ab3025482e471147bb51efa99bd"/>
+  <project name="platform/external/f2fs-tools" path="external/f2fs-tools" revision="73b6e3eb4e944338edd80b4f27c29b7aa31c76f2"/>
+  <project name="platform/external/fdlibm" path="external/fdlibm" revision="8b08bde15b80b40d3cbb731f5415434fc843d800"/>
+  <project name="platform/external/fio" path="external/fio" revision="b287c3293081dd98182a026a15e63536148b3287"/>
   <project groups="pdk" name="platform/external/flac" path="external/flac" revision="7f32dd57579bdff88e46e1e403154be0b99165da"/>
   <project groups="pdk" name="platform/external/freetype" path="external/freetype" revision="899c67b6cfcd2010784fbf08c5415af16c526e0c"/>
   <project name="platform/external/fsck_msdos" path="external/fsck_msdos" revision="17a1471db8c528cd9d44ec4385d2eb3614138856"/>
-  <project name="platform/external/ganymed-ssh2" path="external/ganymed-ssh2" revision="d3724dabc1cfbacd105fe6c422b4dcba80e4fb2d"/>
   <project groups="pdk" name="platform/external/gcc-demangle" path="external/gcc-demangle" revision="9241386b62c353302c2f9eccda0672685b252b4d"/>
   <project name="platform/external/genext2fs" path="external/genext2fs" revision="e11a9c7fe6f1cef99aad2f25afaea37b72fe9f93"/>
   <project name="platform/external/giflib" path="external/giflib" revision="621696a283c0ce34956417f760f1005fadcd12ae"/>
@@ -103,119 +99,108 @@
   <project name="platform/external/google-fonts/carrois-gothic-sc" path="external/google-fonts/carrois-gothic-sc" revision="0062a10458d4c357f3082d66bcb129d11913aaae"/>
   <project name="platform/external/google-fonts/coming-soon" path="external/google-fonts/coming-soon" revision="2c5cb418c690815545bbb0316eae5fd33b9fc859"/>
   <project name="platform/external/google-fonts/dancing-script" path="external/google-fonts/dancing-script" revision="7b6623bd54cee3e48ae8a4f477f616366643cc78"/>
-  <project name="platform/external/grub" path="external/grub" revision="33a4e7e4cfa81dc21d37091515891859ef3ab934"/>
-  <project groups="pdk" name="platform/external/gtest" path="external/gtest" revision="fa3c26b862ca17c0d2db67606226b49d1648b4bf"/>
+  <project groups="pdk" name="platform/external/gtest" path="external/gtest" revision="be0656e745b4c8e5bfd7efaa44d5dc4367375d72"/>
   <project name="platform/external/guava" path="external/guava" revision="5e6db342fc75b1945298142530f2d1d1861bce73"/>
   <project name="platform/external/hamcrest" path="external/hamcrest" revision="ba28ac1e0386f26d9a45be5ed16fc9c598b27e70"/>
   <project name="platform/external/harfbuzz" path="external/harfbuzz" revision="2300ee50159d8b40a634855c523c6063b2975c0f"/>
   <project name="platform/external/harfbuzz_ng" path="external/harfbuzz_ng" revision="3e537b48a7b56c742ecf3c2ed24ff15fcb73f575"/>
-  <project name="platform/external/hyphenation" path="external/hyphenation" revision="bfa84834dfeb7fe8d058c2e7e07b5981451ddf82"/>
-  <project groups="pdk" name="platform/external/icu" path="external/icu" revision="44b0a574cbc3a54e421f5c79020cc59fbd4f34b9"/>
-  <project groups="pdk" name="platform/external/iproute2" path="external/iproute2" revision="5d4c86892885ae1bc12e0e157b35ef44e8ba81bd"/>
-  <project name="platform/external/ipsec-tools" path="external/ipsec-tools" revision="f4cb1ee4b00abbfb6f968dc25818c23b4b47e584"/>
-  <project name="platform/external/iptables" path="external/iptables" revision="e3928b77f18db0fdc615693017c6c15eb71bf4e0"/>
+  <project groups="pdk" name="platform/external/icu" path="external/icu" revision="6c6993c9ef811e486c4468172004539002cad6c2"/>
+  <project groups="pdk" name="platform/external/iproute2" path="external/iproute2" revision="cb80ba50b89e3e039481a988626ea8e419ed762c"/>
+  <project name="platform/external/ipsec-tools" path="external/ipsec-tools" revision="822abcd2d60cc753d53785ce5c34b57f6ca5b5d3"/>
+  <project name="platform/external/iptables" path="external/iptables" revision="94ccd7362d9e5f8f422ee54215af9952ed41a274"/>
   <project name="platform/external/iputils" path="external/iputils" revision="1c7c426ab377c3a005a36d612ebbb16de86fb7d4"/>
   <project name="platform/external/jack" path="external/jack" revision="5ceb2025ac5d25ed48183ac2d3dac4691fe761fb"/>
   <project name="platform/external/javasqlite" path="external/javasqlite" revision="b8501bdeb0b7e39a0d82f2a96ad382c05a763b22"/>
   <project name="platform/external/javassist" path="external/javassist" revision="9566207cff5871c672fac1f0d4332d93292036d7"/>
   <project name="platform/external/jdiff" path="external/jdiff" revision="e4694302d6a3786c64d954e0b3cf42786283bd3c"/>
-  <project name="platform/external/jemalloc" path="external/jemalloc" revision="e5d3dcfe0dbd2515afaa88f1b77c1eb0b88a40c0"/>
+  <project name="platform/external/jemalloc" path="external/jemalloc" revision="19e1d8dacf21affac338fbe784990f081c806da7"/>
   <project groups="pdk" name="platform/external/jhead" path="external/jhead" revision="871af5c305ce1d3087e58fae091c60c359f5fa45"/>
   <project name="platform/external/jmdns" path="external/jmdns" revision="f4eb7466d5c09098f9dc54137ed3235e3c43fc9f"/>
-  <project name="platform/external/jmonkeyengine" path="external/jmonkeyengine" revision="a6b44658eb1c55295f132a36233a11aa2bd8f9cf"/>
-  <project groups="pdk" name="platform/external/jpeg" path="external/jpeg" revision="ef1b83013e7814622a9d11579878d342e84580b7"/>
+  <project groups="pdk" name="platform/external/jpeg" path="external/jpeg" revision="a66efb5d9a21e2666099dffb234b774d796cefbd"/>
   <project name="platform/external/jsilver" path="external/jsilver" revision="739060b01245f1dc5f1800949b3c30c291253cff"/>
   <project name="platform/external/jsr305" path="external/jsr305" revision="a82868820d6350811b9ddfde4bf8ed5016084269"/>
   <project name="platform/external/junit" path="external/junit" revision="8f312e0c3d6dff30d015d2c85fdaae0a39220fd6"/>
-  <project name="platform/external/kernel-headers" path="external/kernel-headers" revision="8b663ef01dcaadfe1dec7ba826e5cd1cf0bb2c91"/>
+  <project name="platform/external/kernel-headers" path="external/kernel-headers" revision="0de034a4ab74ecf1cab41e58f0e8aa92551141bf"/>
   <project name="platform/external/libcap-ng" path="external/libcap-ng" revision="52447887e50b49f33f959077c31232edff6659d8"/>
-  <project name="platform/external/libcxx" path="external/libcxx" revision="246124b60c15f201071275dc05f3cf498fa97dd4"/>
-  <project name="platform/external/libcxxabi" path="external/libcxxabi" revision="71c03f185750080a99cfce6ff0cc4684624fe454"/>
-  <project name="platform/external/libcxxrt" path="external/libcxxrt" revision="d1ee2b2a4946a073596514462d7629373d22fb27"/>
+  <project name="platform/external/libcxx" path="external/libcxx" revision="48dfa099ea8b6043c67eb3fdc9aa3d0b4fe56e2a"/>
+  <project name="platform/external/libcxxabi" path="external/libcxxabi" revision="e3e9a2a4f28eecf404101d137cb98e4e7d002cae"/>
   <project name="platform/external/libexif" path="external/libexif" revision="25d371312cee1452a2adcf8b7f6cad6267bda32d"/>
-  <project name="platform/external/libffi" path="external/libffi" revision="385ba8b006b9995456d3c9283fd20dded90809cc"/>
   <project groups="pdk" name="platform/external/libgsm" path="external/libgsm" revision="50761abed8f4734970874165b386cfd4d9599db4"/>
   <project groups="pdk" name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
   <project name="platform/external/libmtp" path="external/libmtp" revision="7075348937f6a8c9d9211942fcb6c376f4227776"/>
-  <project groups="pdk" name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="46abb3dcf960058e48d1444b6a11cc7e84912339"/>
+  <project groups="pdk" name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="901861912ee63d9a0208ea9ecfc07931945d4743"/>
   <project groups="pdk" name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="15d81f71a668b3092549c6b7f83694bf680d9c49"/>
   <project name="platform/external/libnl" path="external/libnl" revision="99debfa4c01b49c9b470884cc56f81fcdee0fa1f"/>
   <project groups="pdk" name="platform/external/libnl-headers" path="external/libnl-headers" revision="52c926a9de955fa2d987bf8c5d4a1304b5a2a611"/>
   <project name="platform/external/libogg" path="external/libogg" revision="ec0b24fb1468abe37be4164a6feb16568e036bde"/>
   <project name="platform/external/libpcap" path="external/libpcap" revision="9dab0cd7430a4d23e0a7752fb13b941692171c3d"/>
   <project name="platform/external/libphonenumber" path="external/libphonenumber" revision="485e6d5c6e48a1fc43cc0a090e687c723dac056c"/>
-  <project groups="pdk" name="platform/external/libpng" path="external/libpng" revision="48b7ba25a15a9eae83d366c02475539725d035d0"/>
+  <project groups="pdk" name="platform/external/libpng" path="external/libpng" revision="9039c1a1dafbd5508aac8cb5af4268577a4bddd1"/>
   <project name="platform/external/libseccomp-helper" path="external/libseccomp-helper" revision="e87019943a8b5a7cd0880910f671c37b240d5754"/>
-  <project groups="pdk" name="platform/external/libselinux" path="external/libselinux" revision="da4208c8808e6a62fcfe848343abd3e2f3b339cc"/>
-  <project groups="pdk" name="platform/external/libsepol" path="external/libsepol" revision="d26204e7d0a3be178a97d4920b82007e05a2a632"/>
+  <project groups="pdk" name="platform/external/libselinux" path="external/libselinux" revision="d0b768abcd2b4adb1853ac38e59aa80f09872ac3"/>
+  <project groups="pdk" name="platform/external/libsepol" path="external/libsepol" revision="6b7fc04c339b9926ede48426e99b2621428a0d3d"/>
   <project name="platform/external/libssh2" path="external/libssh2" revision="2bb40f2445cab3ba588efb29e1835cdba2b27248"/>
-  <project name="platform/external/libunwind" path="external/libunwind" revision="b3436a3feed4dcb22dafc8f7818b742cacaddd1d"/>
-  <project name="platform/external/libusb" path="external/libusb" revision="2801917fe150393d4f4a354165fe89550ae22613"/>
-  <project name="platform/external/libusb-compat" path="external/libusb-compat" revision="94867ba54eb7faa8efca81cf2214d00bb9143d27"/>
+  <project name="platform/external/libunwind" path="external/libunwind" revision="f760bf5b2c822d21442aa9f765da0e62284e4f48"/>
+  <project name="platform/external/libusb" path="external/libusb" revision="3a36cef7ef847d3839090a7c98eb961a602af55b"/>
+  <project name="platform/external/libusb-compat" path="external/libusb-compat" revision="6d4ab8939e4784b2b6eb63d992cc4d44f953bb41"/>
   <project name="platform/external/libvorbis" path="external/libvorbis" revision="de559619fd4dd0d2d9608436696fd44bdf74eba8"/>
-  <project groups="pdk" name="platform/external/libvpx" path="external/libvpx" revision="9921efda82d7b1f6410ad01c2cb4549b3bc1bb5c"/>
+  <project groups="pdk" name="platform/external/libvpx" path="external/libvpx" revision="7fb54bb13de3ee9c7d769f7599bc157aebb178ff"/>
   <project name="platform/external/libxml2" path="external/libxml2" revision="399e808f940777d18efe377bd34f738dc84729e0"/>
-  <project name="platform/external/libxslt" path="external/libxslt" revision="98f5140c33273d3bd67ca03566f8417406001016"/>
   <project groups="libyuv" name="platform/external/libyuv" path="external/libyuv" revision="482a582884351288fb701532359652970b1ba7c0"/>
-  <project name="platform/external/linux-tools-perf" path="external/linux-tools-perf" revision="823f2555fc4d3520db79268334ddf3e431ade2a0"/>
+  <project name="platform/external/linux-tools-perf" path="external/linux-tools-perf" revision="f63954197ea5e1fa300fa6c561e2f5b0a67d2d1f"/>
   <project name="platform/external/littlemock" path="external/littlemock" revision="328b01eada8965cd38feea884d4080c31e3763b0"/>
-  <project groups="pdk" name="platform/external/llvm" path="external/llvm" revision="c4fa175f2865ac9046c1396fd4f1d3eddd73b31b"/>
-  <project name="platform/external/ltrace" path="external/ltrace" revision="82ae18484c7b6a8af05354caf6de3a7f1ac5fcf9"/>
+  <project groups="pdk" name="platform/external/llvm" path="external/llvm" revision="281cc67b6ac794b1eb8232e6efca366d870dad43"/>
+  <project name="platform/external/ltrace" path="external/ltrace" revision="10ffb54609942b390bb9a65964f62425b04df53f"/>
   <project name="platform/external/lzma" path="external/lzma" revision="19cf4f773361c09e47a2ffe1613d66cbf632227f"/>
-  <project name="platform/external/marisa-trie" path="external/marisa-trie" revision="629ed059b1e85cd8e4de363d8b3dc53c15c3e08a"/>
   <project name="platform/external/markdown" path="external/markdown" revision="6f2e3554ae38cc90518d32e02cb57d05988270a6"/>
   <project groups="pdk" name="platform/external/mdnsresponder" path="external/mdnsresponder" revision="b25c2507ecc3f674e3b4f0a770acf9ad8fd874d0"/>
-  <project name="platform/external/mesa3d" path="external/mesa3d" revision="97d3f36a59ea448fa77e47a90bf04f1254670542"/>
-  <project name="platform/external/messageformat" path="external/messageformat" revision="a5e918984692c683ec42bfc9cd33de96f3c6460b"/>
-  <project groups="pdk" name="platform/external/mksh" path="external/mksh" revision="d2b5c0ede63db6e5390c680884ca65f612173da0"/>
+  <project name="platform/external/mesa3d" path="external/mesa3d" revision="cfa14c46594a66e3f1b6b50b65b5e9f4fa6302a5"/>
+  <project name="platform/external/messageformat" path="external/messageformat" revision="fb716cce89ee080907bb5d43dfc84a657e4e5282"/>
+  <project groups="pdk" name="platform/external/mksh" path="external/mksh" revision="319a679f02fd6ac5f7cbde03c3e64935b2c9af82"/>
   <project name="platform/external/mockito" path="external/mockito" revision="4d0dcd53b27a243baf72ee0b127b188a058b318d"/>
-  <project name="platform/external/mockwebserver" path="external/mockwebserver" revision="2f7659c426de53122ee7922b0981058a900124a7"/>
+  <project name="platform/external/mockwebserver" path="external/mockwebserver" revision="a09bacce76b6ece0de2ca71c397dd4b96d101904"/>
   <project name="platform/external/mp4parser" path="external/mp4parser" revision="16051e950485c6b62127c0446a760111de1a0cb9"/>
   <project name="platform/external/mtpd" path="external/mtpd" revision="5ea8006691664b7e6d46d6a6dc889eac91b7fe37"/>
   <project name="platform/external/naver-fonts" path="external/naver-fonts" revision="3bba7d2430bc3ec8105678a27f03fb080f0f8384"/>
   <project name="platform/external/netcat" path="external/netcat" revision="444644cfa9a2f3002863caa168fb2d6b34dfd1e8"/>
   <project name="platform/external/netperf" path="external/netperf" revision="38e47cd883738cb84bdb47a7d263f14f14062d7b"/>
-  <project name="platform/external/neven" path="external/neven" revision="504ee5ccaabd8bce4da3430b0f4e9714ac2a8e6c"/>
+  <project name="platform/external/neven" path="external/neven" revision="0037214648ffc810cd54c232b2026096e834a93a"/>
   <project name="platform/external/nfacct" path="external/nfacct" revision="6f7aae0264821b44e9fe80fb5596c525d3e2f475"/>
-  <project name="platform/external/nist-pkits" path="external/nist-pkits" revision="b7a53ad5a587926cb880d9bb6f3d51657596474c"/>
+  <project name="platform/external/nist-pkits" path="external/nist-pkits" revision="2c243d61d94b93eaef6fd5e0f727c9a2be838338"/>
   <project name="platform/external/nist-sip" path="external/nist-sip" revision="b23dbfce7ea84c39cea75b612868a5832cb9af2b"/>
   <project name="platform/external/noto-fonts" path="external/noto-fonts" revision="90372d894b5d9c9f2a111315d2eb3b8de1979ee4"/>
   <project name="platform/external/oauth" path="external/oauth" revision="bc170f58de82000ed6460f111686a850a1890c07"/>
   <project name="platform/external/objenesis" path="external/objenesis" revision="2a7655c0d503fcf5989098f65bf89eae78c32e5a"/>
-  <project name="platform/external/okhttp" path="external/okhttp" revision="bd5b1a78b0559b7cd7fae5a06235714b244cfe55"/>
-  <project name="platform/external/open-vcdiff" path="external/open-vcdiff" revision="6d29f2f083baf8250db94ed0b4807e513a84163d"/>
+  <project name="platform/external/okhttp" path="external/okhttp" revision="cfa2143be012b18239a0574aed72ebe843293b3f"/>
   <project name="platform/external/opencv" path="external/opencv" revision="4a99e243b42afcb885d036bb451eb3c2739275b6"/>
-  <project name="platform/external/openfst" path="external/openfst" revision="b7434caa51427a0f5ab5c807e1a92d6ca2af8884"/>
-  <project name="platform/external/openssh" path="external/openssh" revision="3c335c9fb9c12375ad62748fa1d1e5ebe4710c94"/>
-  <project groups="pdk" name="platform/external/openssl" path="external/openssl" revision="fec161200bd965269f524ab6364dc530976e4f61"/>
+  <project groups="pdk" name="platform/external/openssl" path="external/openssl" revision="54efc1885c3a4fd0f436518431577e8e7760b18c"/>
   <project name="platform/external/oprofile" path="external/oprofile" revision="3722f1053f4cab90c4daf61451713a2d61d79c71"/>
   <project name="platform/external/owasp/sanitizer" path="external/owasp/sanitizer" revision="6a304233f9f2010821a5a1dd40e2832b68353a3c"/>
-  <project name="platform/external/pcre" path="external/pcre" revision="993a14b71c8e7af03eb929d44a444137393a5324"/>
+  <project name="platform/external/pcre" path="external/pcre" revision="1dceafb0c217395f704290bc3f176d5f008b791c"/>
   <project name="platform/external/pixman" path="external/pixman" revision="afd5bbd8074cedec8544d07920fa06786d5a4f08"/>
   <project name="platform/external/ppp" path="external/ppp" revision="8b58d9bd02e2c55f547fafbe9ba55b1160665761"/>
   <project groups="pdk-java" name="platform/external/proguard" path="external/proguard" revision="3fd19dba2bdc0c4b64afda4d75836e1dcf7abf97"/>
-  <project groups="pdk" name="platform/external/protobuf" path="external/protobuf" revision="0068978c364173b15a9cb8ab65fb2d2eac17f136"/>
-  <project name="platform/external/qemu" path="external/qemu" revision="89fcf67c0e039d733c1e63fc6fe65079024bd99c"/>
+  <project groups="pdk" name="platform/external/protobuf" path="external/protobuf" revision="9be7e7401174d75e87e21fdc5f43549594a714bb"/>
+  <project name="platform/external/qemu" path="external/qemu" revision="9ffcfd8d0c59145f26de96fd096dabb0690de213"/>
   <project name="platform/external/qemu-pc-bios" path="external/qemu-pc-bios" revision="20349dae98d7de09a7e390d4a706c64f1db6edc2"/>
-  <project name="platform/external/regex-re2" path="external/regex-re2" revision="0d4c52358a1af421705c54bd8a9fdd8a30558a2e"/>
+  <project name="platform/external/regex-re2" path="external/regex-re2" revision="a1eaef0f4fce3c358b850dabd724ca66c5ec2d81"/>
   <project name="platform/external/replicaisland" path="external/replicaisland" revision="99e2e54c5d036048caf09bb05eea0969de093104"/>
   <project name="platform/external/robolectric" path="external/robolectric" revision="6bf395c984ed3f69711663b006aeffbb0f7e8a90"/>
   <project groups="pdk" name="platform/external/safe-iop" path="external/safe-iop" revision="aa0725fb1da35e47676b6da30009322eb5ed59be"/>
-  <project groups="pdk" name="platform/external/scrypt" path="external/scrypt" revision="dde037b82e5cd6215244e3240dbaad417928eafa"/>
-  <project groups="pdk" name="platform/external/sepolicy" path="external/sepolicy" revision="60f0be84c0cf3a895c6b95ee8387b71e1b0c6d83"/>
-  <project name="platform/external/sfntly" path="external/sfntly" revision="6723e5241a45c6de224c96384a595a1bf5bc5449"/>
-  <project name="platform/external/sil-fonts" path="external/sil-fonts" revision="795a2f4339f8a82d6cff187e2a77bb01d5911aac"/>
-  <project name="platform/external/skia" path="external/skia" revision="d6f2c76fdb9b0469261fa2db0b29ed48c7ac38b5"/>
+  <project groups="pdk" name="platform/external/scrypt" path="external/scrypt" revision="789860d0e09a2d98976e028179afe0446f2172cc"/>
+  <project groups="pdk" name="platform/external/sepolicy" path="external/sepolicy" revision="46f3ce87d9a130924c763a245639331c6e1a5b28"/>
+  <project name="platform/external/sfntly" path="external/sfntly" revision="8372b6c4430169593c20082e209fd7e5ed777655"/>
+  <project name="platform/external/skia" path="external/skia" revision="eae531fdfcf03e266a18f6a313d002aad58e0692"/>
   <project name="platform/external/smack" path="external/smack" revision="d7955ce24d294fb2014c59d11fca184471056f44"/>
   <project name="platform/external/smali" path="external/smali" revision="5fd395796e215a80c722815bf180728948868f18"/>
-  <project groups="pdk" name="platform/external/sonivox" path="external/sonivox" revision="c0723d864b10fbd6c5cbbfa65e886c5e9eb3aafd"/>
+  <project groups="pdk" name="platform/external/sonivox" path="external/sonivox" revision="399080e8ae3ebee97a5a57f1072452c4c77b5c5a"/>
   <project groups="pdk" name="platform/external/speex" path="external/speex" revision="eaa4765b8cc6a6dd5ee0d26dc1b61a1044817f32"/>
   <project groups="pdk" name="platform/external/sqlite" path="external/sqlite" revision="50af37d784661b2d54c8e043de52ffc4f02a1a50"/>
   <project name="platform/external/srec" path="external/srec" revision="540e7ee8dbf1d7ee72ef45c92efbebcb89bf6d1a"/>
   <project name="platform/external/srtp" path="external/srtp" revision="98bd63b48a31b4633cdfdc8138577dfa6d8dd2a6"/>
-  <project groups="pdk" name="platform/external/stlport" path="external/stlport" revision="dc05ca5be2319f74b41cb429ea50f30fceff4ace"/>
-  <project name="platform/external/strace" path="external/strace" revision="133fd4c5949d3b8c837f569270e1bff626251cc0"/>
-  <project name="platform/external/stressapptest" path="external/stressapptest" revision="0956427aa995561acb4471764158ae057a36dad5"/>
+  <project groups="pdk" name="platform/external/stlport" path="external/stlport" revision="27757ed969c75ac5d6ec2eb6bbea0a12b2d1b700"/>
+  <project name="platform/external/strace" path="external/strace" revision="72dd4a20531043c88f1ae7c3f608f5e6fe57155a"/>
+  <project name="platform/external/stressapptest" path="external/stressapptest" revision="c5e4b50511dcc560623d4e0292a694739394f2b9"/>
   <project name="platform/external/svox" path="external/svox" revision="ad0a55bd0e13a27ed11034346eee9c47e3684ef2"/>
   <project name="platform/external/tagsoup" path="external/tagsoup" revision="a97828cb3f8f3a1af8470e55d3c5cd62d6a7cb4c"/>
   <project name="platform/external/tcpdump" path="external/tcpdump" revision="de49cdcfddf36f2b41ef3278e98a8a550a189952"/>
@@ -224,56 +209,56 @@
   <project groups="pdk" name="platform/external/tinycompress" path="external/tinycompress" revision="aeee2c6a19b9d3765f72bc79555005786a424233"/>
   <project groups="pdk" name="platform/external/tinyxml" path="external/tinyxml" revision="143125ff631c481d590cae0d7cc9ccfaaca269c7"/>
   <project groups="pdk" name="platform/external/tinyxml2" path="external/tinyxml2" revision="7974ba13a557b3352b0fd4b2a8c377cb530e886e"/>
-  <project groups="pdk" name="platform/external/tremolo" path="external/tremolo" revision="ee8e2a29b072186828656c2bb1e813acab36779a"/>
-  <project groups="pdk" name="platform/external/valgrind" path="external/valgrind" revision="893257d6c86a18cc5cf6c92528b7027f327dca70"/>
-  <project name="platform/external/vixl" path="external/vixl" revision="e1ab25cde167109efb28fa6a86d5c2c80b762d58"/>
+  <project groups="pdk" name="platform/external/tremolo" path="external/tremolo" revision="a4d929e3adc82981f7378933e9343a82d99fd867"/>
+  <project groups="pdk" name="platform/external/valgrind" path="external/valgrind" revision="c45c083313755a58b73943fae0c66aac92185ad5"/>
+  <project name="platform/external/vixl" path="external/vixl" revision="39ee1f4b336c7e6b25be0df6375c18dcbd577c09"/>
   <project name="platform/external/webp" path="external/webp" revision="0db01fc3411621bec473d50db0071fd2a225962e"/>
-  <project groups="pdk" name="platform/external/webrtc" path="external/webrtc" revision="d62aeac391d16d4953a12120c0ff614ccde02a30"/>
+  <project groups="pdk" name="platform/external/webrtc" path="external/webrtc" revision="8fd3f61c995481e581d45719458ddc237fe35f83"/>
   <project groups="pdk" name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="88ef20ce4facae68a3e6b05429bb9f3f73a93996"/>
   <project name="platform/external/xmlwriter" path="external/xmlwriter" revision="e95d92246ee35273dde2bee8b00485cc14c12be5"/>
   <project name="platform/external/xmp_toolkit" path="external/xmp_toolkit" revision="42ea4dc6d1fc2206a7778029070ed9213e3b0fbf"/>
   <project groups="pdk" name="platform/external/yaffs2" path="external/yaffs2" revision="a2cff2275e1b501ff478b03757d6e4f05fddc2db"/>
   <project groups="pdk" name="platform/external/zlib" path="external/zlib" revision="8d977782c1cfe9d75cc9a464439c2ff1e27e1665"/>
   <project name="platform/external/zxing" path="external/zxing" revision="7620644768ffc235607b3a94671e49518c18686f"/>
-  <project groups="pdk" name="platform/frameworks/av" path="frameworks/av" revision="45d2c7e1809e41e3d022f037aeec7e38646f6072"/>
-  <project name="platform/frameworks/base" path="frameworks/base" revision="25d928f687408058f007051878574ea66691d9dc"/>
-  <project groups="pdk" name="platform/frameworks/compile/libbcc" path="frameworks/compile/libbcc" revision="ea6b1c5af978698f266f352c8a6f00ec3677e7e5"/>
-  <project groups="pdk" name="platform/frameworks/compile/mclinker" path="frameworks/compile/mclinker" revision="e673be8f0526f9cbc83093fb579c0f76de9e4e3c"/>
-  <project groups="pdk" name="platform/frameworks/compile/slang" path="frameworks/compile/slang" revision="4f5fc88dd854dfa10c19f109b7a7a1a4a0c6d791"/>
-  <project name="platform/frameworks/ex" path="frameworks/ex" revision="1870c0718729ef8968b2264c329c0351f6ba5de6"/>
+  <project groups="pdk" name="platform/frameworks/av" path="frameworks/av" revision="589a89f5a2a9aa08bdd9b78727f608f2f178f107"/>
+  <project name="platform/frameworks/base" path="frameworks/base" revision="2bf3800b10e1cc9a291527fc83efc986ba83aa37"/>
+  <project groups="pdk" name="platform/frameworks/compile/libbcc" path="frameworks/compile/libbcc" revision="40990623cd268dfcf5503abcd58465d14453d2f4"/>
+  <project groups="pdk" name="platform/frameworks/compile/mclinker" path="frameworks/compile/mclinker" revision="7488ffd672ad1146d8a615f03a96a79794cd0d73"/>
+  <project groups="pdk" name="platform/frameworks/compile/slang" path="frameworks/compile/slang" revision="1a3db4a5943e662eea542dc58398a4c7ab656cc4"/>
+  <project name="platform/frameworks/ex" path="frameworks/ex" revision="c8e9c0148525d853588f606fe8315368ea134615"/>
   <project name="platform/frameworks/mff" path="frameworks/mff" revision="b9669b8540a1e5c953374d53b115514335e23c27"/>
-  <project name="platform/frameworks/ml" path="frameworks/ml" revision="b020ad88ca28ada76a596b5dcc7e6c2854fcc132"/>
-  <project name="platform/frameworks/multidex" path="frameworks/multidex" revision="590a07e63868f0a1da311ff22b4a9f35eb48a865"/>
-  <project groups="pdk" name="platform/frameworks/native" path="frameworks/native" revision="8c1642ad4ea8fbeb7d03f30e5f50e03c28d40065"/>
+  <project name="platform/frameworks/ml" path="frameworks/ml" revision="264f08d8b8a152a9ea2445b05602ea50d90d1f1c"/>
+  <project name="platform/frameworks/multidex" path="frameworks/multidex" revision="f50beca07827921e005ce6825bbc874a843f91e1"/>
+  <project groups="pdk" name="platform/frameworks/native" path="frameworks/native" revision="cb8a9fcc56288378d05d80c55396db7981e3828d"/>
   <project name="platform/frameworks/opt/calendar" path="frameworks/opt/calendar" revision="03b18577f8f8f799e87a62b8e03889ddacf6daa2"/>
   <project name="platform/frameworks/opt/carddav" path="frameworks/opt/carddav" revision="f08aa2df132dd8dc32a0013d3750137d9dd9280a"/>
   <project name="platform/frameworks/opt/colorpicker" path="frameworks/opt/colorpicker" revision="720a40ae24d526268b3c0f2dd8497b5df2cc6f23"/>
   <project name="platform/frameworks/opt/datetimepicker" path="frameworks/opt/datetimepicker" revision="8a1c55baaf5ced7a98b196c689ccdd59238f6e58"/>
   <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="709f713ebcd62c61defc270d945810efca179621"/>
+  <project name="platform/frameworks/opt/inputconnectioncommon" path="frameworks/opt/inputconnectioncommon" revision="6a11cdd827d64b98ca82a9c1565a317c0ecd2b0f"/>
   <project name="platform/frameworks/opt/inputmethodcommon" path="frameworks/opt/inputmethodcommon" revision="df9dd39c2047992a43b64e13bb0fc348a1630f3b"/>
-  <project name="platform/frameworks/opt/mailcommon" path="frameworks/opt/mailcommon" revision="1537812900e59f875cfea0483f0ae261b16d3e4b"/>
   <project name="platform/frameworks/opt/mms" path="frameworks/opt/mms" revision="64817e848552fd0a429a3e026b7b1562103c56bb"/>
   <project name="platform/frameworks/opt/net/voip" path="frameworks/opt/net/voip" revision="0f722c7f09ce67e058eb1cfaabf1d85f1abdf797"/>
-  <project name="platform/frameworks/opt/photoviewer" path="frameworks/opt/photoviewer" revision="4258372a2745f4139f25dc14413f9a08125802e3"/>
+  <project name="platform/frameworks/opt/photoviewer" path="frameworks/opt/photoviewer" revision="bcbd114452a8d672077e406304ebbba317509252"/>
   <project groups="pdk" name="platform/frameworks/opt/telephony" path="frameworks/opt/telephony" revision="93faaed9056491c551ef7046e9e1de7d6397e95c"/>
   <project name="platform/frameworks/opt/timezonepicker" path="frameworks/opt/timezonepicker" revision="3820b87bfbc86d066e9093e78254e1f3728ad77d"/>
   <project name="platform/frameworks/opt/vcard" path="frameworks/opt/vcard" revision="5907243e6cf0603adf266ebfa7ee5ee465b9c596"/>
   <project name="platform/frameworks/opt/widget" path="frameworks/opt/widget" revision="466e0e0307b3f6aa4f4be3d9419b5996bd389da5"/>
-  <project groups="pdk" name="platform/frameworks/rs" path="frameworks/rs" revision="4fd5d37ce45a4ad0708ad5ffbd68e73696838d05"/>
-  <project name="platform/frameworks/support" path="frameworks/support" revision="bfec5af0e2237e44f4a3ac0383fa02b6c82693ca"/>
+  <project groups="pdk" name="platform/frameworks/rs" path="frameworks/rs" revision="aee3e3c852d01770ed56968986b288484f37aec1"/>
+  <project name="platform/frameworks/support" path="frameworks/support" revision="e4ecf4ad3dd5a1c229e30db56a224eacc72a7fd2"/>
   <project name="platform/frameworks/testing" path="frameworks/testing" revision="5c8e0271db889518f5969b142a37faa01a4ee54d"/>
-  <project name="platform/frameworks/volley" path="frameworks/volley" revision="71d91b4ea41c3ec2324343541f6626c35b316f05"/>
-  <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="15bb40eaebf1e1d0445fb9bcfc9c2b6eb57dff5f"/>
+  <project name="platform/frameworks/volley" path="frameworks/volley" revision="1b4858087f25a8033c5136a96b750752b87e128c"/>
+  <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="5a55e234fc79b0da96a2e158d90cd5ba2f12d9ef"/>
   <project name="platform/hardware/akm" path="hardware/akm" revision="32838ef838d1341aa8b77022869b801fb0bbb26c"/>
   <project groups="pdk" name="platform/hardware/broadcom/libbt" path="hardware/broadcom/libbt" revision="55ddd0cce019e88829f92b2fe4e17d5869daa9b9"/>
   <project groups="broadcom_wlan" name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="47a3b8f496e6d2a836ac6b7268e5626c969542ec"/>
   <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="0f5bc7cd710fac85377621a8b9a4c364af80605f"/>
-  <project groups="pdk" name="platform/hardware/libhardware" path="hardware/libhardware" revision="3e618a6aa10c783d1536f20edfc3347939cfa18e"/>
+  <project groups="pdk" name="platform/hardware/libhardware" path="hardware/libhardware" revision="9f4978701783942e836aeab526727458e9cb1492"/>
   <project groups="pdk" name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="4c20a09e8684657448f0bc97a2da4e56c94d484e"/>
-  <project groups="qcom" name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="d47ff224c7b24933c701acae8d5e4c98a1bc80af"/>
+  <project groups="qcom" name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="6430d90d63db8b8af4c76cb063badf7b1ef43834"/>
   <project groups="qcom" name="platform/hardware/qcom/bt" path="hardware/qcom/bt" revision="d2b071c3683bace40c9ed666107367dac5a5bb45"/>
   <project groups="qcom" name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="fbf72e519ec5fe2f2720b1a3d119e2d69e172e34"/>
-  <project groups="qcom" name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="c2ec890152c23c23187c3d8b78ac6103b7d0c856"/>
+  <project groups="qcom" name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="fb37b11703cb95bef058b29715f879c5afd7b908"/>
   <project groups="qcom" name="platform/hardware/qcom/keymaster" path="hardware/qcom/keymaster" revision="70d36107318e1d3f7abf62a56279b3f9da3ff000"/>
   <project groups="qcom" name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="1208a868bcb0ffaa650a7e68b51031254c775d39"/>
   <project groups="qcom_msm8960" name="platform/hardware/qcom/msm8960" path="hardware/qcom/msm8960" revision="ca38ed098b05a79d20e852348f27d7c40a53f801"/>
@@ -282,39 +267,39 @@
   <project groups="qcom" name="platform/hardware/qcom/sensors" path="hardware/qcom/sensors" revision="07c5bcdb36158e22d33bac02eecd83d4ff1fb2f8"/>
   <project groups="qcom_wlan" name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="daa321b0ad8c10b454dc28d7e6dadc72196a8c7a"/>
   <project groups="pdk" name="platform/hardware/ril" path="hardware/ril" revision="eb2a93458204a928edfe36f043ddb48cf5575143"/>
-  <project groups="exynos5" name="platform/hardware/samsung_slsi/exynos5" path="hardware/samsung_slsi/exynos5" revision="d7bd354358ecfb1e52afb3da4fc586c0822c696a"/>
+  <project groups="exynos5" name="platform/hardware/samsung_slsi/exynos5" path="hardware/samsung_slsi/exynos5" revision="2113fb14d60becb6d419513f3752d4efa2f6a4cc"/>
   <project name="platform/hardware/ti/omap3" path="hardware/ti/omap3" revision="949aad363a9cc794f9ac8fd42338ae1678e50bc1"/>
   <project groups="omap4" name="platform/hardware/ti/omap4xxx" path="hardware/ti/omap4xxx" revision="c32caab84ff9edc1489ed6c8079c7d252caafc4d"/>
-  <project name="platform/libcore" path="libcore" revision="8d1a96527f86493c56022f64bf38752ff0dc1fa5"/>
-  <project groups="pdk-java" name="platform/libnativehelper" path="libnativehelper" revision="e2564566790ab2689c102dc46eea89f06caa0b86"/>
-  <project name="platform/ndk" path="ndk" revision="be9ba71abf2b898fa62a169659ab0b6f8baaa5ca"/>
+  <project name="platform/libcore" path="libcore" revision="96e130ce423be02e08b471a9eba80c1ed51d4a7a"/>
+  <project groups="pdk-java" name="platform/libnativehelper" path="libnativehelper" revision="221e49a1ca260781ecdabdfa106d2e47d444e6de"/>
+  <project name="platform/ndk" path="ndk" revision="1723135d8d23ce7fdea0709432f70c3eb2b36dab"/>
   <project name="platform/packages/apps/BasicSmsReceiver" path="packages/apps/BasicSmsReceiver" revision="80327793c4b4ebf4a6a53b72e46c477afe18f135"/>
-  <project name="platform/packages/apps/Bluetooth" path="packages/apps/Bluetooth" revision="7efa9db2129c99475684a2e44c4fb89cce3134bc"/>
+  <project name="platform/packages/apps/Bluetooth" path="packages/apps/Bluetooth" revision="3e0289f54abff3a9ad6c0b11ff828a5ad3c05271"/>
   <project name="platform/packages/apps/Browser" path="packages/apps/Browser" revision="fe4083510dc773911651456f150bf5432f81a6c0"/>
   <project name="platform/packages/apps/Calculator" path="packages/apps/Calculator" revision="6c7521bb685c9b7b7c36f2077612d4b1a0e808d4"/>
   <project name="platform/packages/apps/Calendar" path="packages/apps/Calendar" revision="2d72f6bed6a0eeaddbda08393063fe873c1c7922"/>
-  <project name="platform/packages/apps/Camera" path="packages/apps/Camera" revision="b0e357d548fb8d10896200add2b932199a96a2ea"/>
-  <project name="platform/packages/apps/Camera2" path="packages/apps/Camera2" revision="ece4866dc575b956801f6dab2d6c4923e272c5fa"/>
+  <project name="platform/packages/apps/Camera" path="packages/apps/Camera" revision="597fe13805d12821126a1a1772f2fdcc9d93f1d6"/>
+  <project name="platform/packages/apps/Camera2" path="packages/apps/Camera2" revision="c0dd3adffa1eb2fdeb281ea08ce9a085b463ff04"/>
   <project name="platform/packages/apps/CellBroadcastReceiver" path="packages/apps/CellBroadcastReceiver" revision="21d8baf492007cc01545905de33ecefe5d947843"/>
-  <project name="platform/packages/apps/CertInstaller" path="packages/apps/CertInstaller" revision="483a188feda6e9d311aef437d28f30e1fb6afeb0"/>
+  <project name="platform/packages/apps/CertInstaller" path="packages/apps/CertInstaller" revision="d9ececef2ffe2b86354a069b2fd34422dbb79b07"/>
   <project name="platform/packages/apps/Contacts" path="packages/apps/Contacts" revision="24a4f48dc5c768188143648e267889477e4185e8"/>
   <project name="platform/packages/apps/ContactsCommon" path="packages/apps/ContactsCommon" revision="6ce4a3bc083a7dbcc7ffa2bebff242638d7f8e61"/>
-  <project name="platform/packages/apps/DeskClock" path="packages/apps/DeskClock" revision="d3bfe9223f3e70271813f48b8ef5500c3a90c0b3"/>
+  <project name="platform/packages/apps/DeskClock" path="packages/apps/DeskClock" revision="b29c331083c7782a78a2053a809f1fcebe233b9d"/>
   <project name="platform/packages/apps/Dialer" path="packages/apps/Dialer" revision="5cb300ef50e9942eef746319dd1b1b6e7c2c05e2"/>
   <project name="platform/packages/apps/Email" path="packages/apps/Email" revision="22766dcf6a44416b2972c053739472317017257d"/>
   <project name="platform/packages/apps/Exchange" path="packages/apps/Exchange" revision="ab03a7f9b197b6ffcc390dd5fb589067a5161148"/>
   <project name="platform/packages/apps/Gallery" path="packages/apps/Gallery" revision="9595006a3347c08e6b8e31d679903bb8f77a343d"/>
-  <project name="platform/packages/apps/Gallery2" path="packages/apps/Gallery2" revision="9cde04ed08f3a5201a007d78b3c89f43fb3003e0"/>
+  <project name="platform/packages/apps/Gallery2" path="packages/apps/Gallery2" revision="3ffc28897d40524e0b8869aebccc8b04551ba5cf"/>
   <project name="platform/packages/apps/HTMLViewer" path="packages/apps/HTMLViewer" revision="7498890092c388dc59ca932e09ec79dd568b1a19"/>
-  <project name="platform/packages/apps/InCallUI" path="packages/apps/InCallUI" revision="d968d1a28dae45229b1be9f05bef8df13821e94d"/>
+  <project name="platform/packages/apps/InCallUI" path="packages/apps/InCallUI" revision="6676f4e282b0c1166a4fd92c8f0a3c78ac8b37b5"/>
   <project name="platform/packages/apps/KeyChain" path="packages/apps/KeyChain" revision="73170a7386c3587f8baaea9ccb0ddd3bec468021"/>
   <project name="platform/packages/apps/Launcher2" path="packages/apps/Launcher2" revision="31569f6dbd44d443ff54c460b733e62fc37d2319"/>
-  <project name="platform/packages/apps/Launcher3" path="packages/apps/Launcher3" revision="3a9f3a7806a0153865415d6207c6812915d3f6b1"/>
+  <project name="platform/packages/apps/Launcher3" path="packages/apps/Launcher3" revision="f1340f1810464ec656262141326c87b3896a3550"/>
   <project name="platform/packages/apps/LegacyCamera" path="packages/apps/LegacyCamera" revision="d9b5d8941d1ec47ff391da2b8cc8ec90f902062f"/>
   <project name="platform/packages/apps/Mms" path="packages/apps/Mms" revision="e770738ea4389afddb0b4e6c69749f9456ed0f48"/>
   <project name="platform/packages/apps/Music" path="packages/apps/Music" revision="bfca689bb6605cfcd1e0c1781c707735efb7444e"/>
   <project name="platform/packages/apps/MusicFX" path="packages/apps/MusicFX" revision="aaa2f99caac6f088b23de55fe2eb1e8ee305b1fb"/>
-  <project name="platform/packages/apps/Nfc" path="packages/apps/Nfc" revision="f62a9a00a13ba333e88cb9e8ce2553d6acf708ad"/>
+  <project name="platform/packages/apps/Nfc" path="packages/apps/Nfc" revision="f3d9d8a9f8fe33ec9ea120b528adf6d2dfc14dd4"/>
   <project name="platform/packages/apps/OneTimeInitializer" path="packages/apps/OneTimeInitializer" revision="01e429c08e51291315890de9677151a7e0b6ad35"/>
   <project name="platform/packages/apps/PackageInstaller" path="packages/apps/PackageInstaller" revision="212398024b4491276ef00cf7fcd829c89200b6ba"/>
   <project name="platform/packages/apps/Phone" path="packages/apps/Phone" revision="bf4ec5b1258628bfa6a82aa0d80f348a77bbf194"/>
@@ -336,7 +321,6 @@
   <project name="platform/packages/experimental" path="packages/experimental" revision="4b57239083bb61d9b4a253bb55cef8e00b149c30"/>
   <project name="platform/packages/inputmethods/LatinIME" path="packages/inputmethods/LatinIME" revision="159474f2ae5d13308ca1b92b8a5ccd809ec6a450"/>
   <project name="platform/packages/inputmethods/OpenWnn" path="packages/inputmethods/OpenWnn" revision="59aefa242169b7a51c2381daee58ff22fd1834ce"/>
-  <project name="platform/packages/inputmethods/PinyinIME" path="packages/inputmethods/PinyinIME" revision="49aebad1c1cfbbcaa9288ffed5161e79e57c3679"/>
   <project name="platform/packages/providers/ApplicationsProvider" path="packages/providers/ApplicationsProvider" revision="3347f31bd268ca3153abe5def9361f625bd73efd"/>
   <project name="platform/packages/providers/CalendarProvider" path="packages/providers/CalendarProvider" revision="20360f2fdd7ad2de1234b7ed61e3ea120f0dc635"/>
   <project name="platform/packages/providers/ContactsProvider" path="packages/providers/ContactsProvider" revision="6ac2395324c0e7539434b7c68ec738f867d7ed37"/>
@@ -358,19 +342,19 @@
   <project name="platform/packages/wallpapers/NoiseField" path="packages/wallpapers/NoiseField" revision="7c3213da68e4551a7563545da1be9d2acc10c684"/>
   <project name="platform/packages/wallpapers/PhaseBeam" path="packages/wallpapers/PhaseBeam" revision="771f86c1c99bcf9a62d990d0d0e5e0c4dfb8bd5d"/>
   <project groups="pdk" name="platform/pdk" path="pdk" revision="19a31ae94fb7e7d16c74d93ff0a736689c4f09c1"/>
-  <project name="platform/prebuilts/android-emulator" path="prebuilts/android-emulator" revision="971827cc3d21684f537ba7ef7630db1f46df2c86"/>
+  <project name="platform/prebuilts/android-emulator" path="prebuilts/android-emulator" revision="f287663a0bee1f08fcb11878d71af96e31e1efba"/>
   <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/3.1" path="prebuilts/clang/darwin-x86/3.1" revision="426233405bef3c7c825095ab14256c3773894b9b"/>
   <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/3.2" path="prebuilts/clang/darwin-x86/3.2" revision="af856d77b3cbb1f6afccdc531bee991403c28907"/>
   <project groups="darwin,arm" name="platform/prebuilts/clang/darwin-x86/arm/3.3" path="prebuilts/clang/darwin-x86/arm/3.3" revision="54acc51e28850485e380b55916868a4e1ff17998"/>
   <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/host/3.4" path="prebuilts/clang/darwin-x86/host/3.4" revision="a798fe00dbd92ad4e5f7123a2e2bc1d805db04f6"/>
-  <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/host/3.5" path="prebuilts/clang/darwin-x86/host/3.5" revision="e377e8bf82e5cc180f4c609bc3ace91554e407f2"/>
+  <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/host/3.5" path="prebuilts/clang/darwin-x86/host/3.5" revision="56610421fd0f182e835717aff569b1ad0c9ca4b9"/>
   <project groups="darwin,mips" name="platform/prebuilts/clang/darwin-x86/mips/3.3" path="prebuilts/clang/darwin-x86/mips/3.3" revision="da3dad928542362835082b2eda44e4dc315d65bb"/>
   <project groups="darwin,x86" name="platform/prebuilts/clang/darwin-x86/x86/3.3" path="prebuilts/clang/darwin-x86/x86/3.3" revision="f67a83f35e30f92b312fbee852184c3f6dc38f34"/>
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
   <project groups="linux,arm" name="platform/prebuilts/clang/linux-x86/arm/3.3" path="prebuilts/clang/linux-x86/arm/3.3" revision="2f6d2db9e2af3507d132cf5d286a42fe1d47f7bc"/>
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.4" path="prebuilts/clang/linux-x86/host/3.4" revision="fae26a039f79d780ddedcad07f164d9e6c05fc87"/>
-  <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="6e6c6b66815d2fcadf22885b839c49adae6807af"/>
+  <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="fda4dc6a29d5a0f37430a8d7ae3f713f80b6cd15"/>
   <project groups="linux,mips" name="platform/prebuilts/clang/linux-x86/mips/3.3" path="prebuilts/clang/linux-x86/mips/3.3" revision="51f8e2760628588fe268438d612d942c30d13fb2"/>
   <project groups="linux,x86" name="platform/prebuilts/clang/linux-x86/x86/3.3" path="prebuilts/clang/linux-x86/x86/3.3" revision="017a8a67f92a66b29ab17772e50642a7b9d0f8e6"/>
   <project name="platform/prebuilts/devtools" path="prebuilts/devtools" revision="be724be535ea50585d8c625b768ccb63aacd2926"/>
@@ -378,54 +362,55 @@
   <project groups="notdefault,eclipse" name="platform/prebuilts/eclipse-build-deps" path="prebuilts/eclipse-build-deps" revision="ceb739d6a7c10f5fb5a6cf6e1f702453b1361ad3"/>
   <project groups="notdefault,eclipse" name="platform/prebuilts/eclipse-build-deps-sources" path="prebuilts/eclipse-build-deps-sources" revision="8b7d8f6033ffe2d22905d10cf6d57d5bdcbe519b"/>
   <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.8" revision="a261d38eaebb7ff406a6bb60237b36fc61714d46"/>
-  <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" path="prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" revision="32d722d66d7a935a8b6f8e6ab2d5d8bf0e9e0986"/>
+  <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" path="prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" revision="7b14592e42cfe89c4a7ed86818e17d4672b62334"/>
   <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8" revision="6d08ca9f45ff685648fd13c75bf5cac4b11c19bb"/>
   <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.8" revision="264394c23b2686ce52cd4ffb116ced127aa7f8fc"/>
+  <project name="platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9" path="prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9" revision="d95eebb0bb7600ffe9e56b6a478a3384e18bf9bc"/>
   <project groups="pdk,darwin" name="platform/prebuilts/gcc/darwin-x86/host/headers" path="prebuilts/gcc/darwin-x86/host/headers" revision="4ac4f7cc41cf3c9e36fc3d6cf37fd1cfa9587a68"/>
   <project groups="pdk,darwin" name="platform/prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1" path="prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1" revision="8834958755acc291d126ba7ee38ac731d04f9c9e"/>
   <project groups="pdk,darwin,mips" name="platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.8" path="prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.8" revision="3b5bef47de8017ff39ef5bfbe801e3fa6b272fab"/>
-  <project name="platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" path="prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" revision="367a6529b0cc9f5ac5ca69226f583420563fd473"/>
+  <project name="platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" path="prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" revision="5b0ffd9d7bd5e9bf0802bcdc4cf22f336d2ab8fe"/>
   <project groups="pdk,darwin,mips" name="platform/prebuilts/gcc/darwin-x86/mips/mipsel-linux-android-4.8" path="prebuilts/gcc/darwin-x86/mips/mipsel-linux-android-4.8" revision="ba97180acd4251d3acf08530faa4a724af74abd3"/>
   <project groups="pdk,darwin,x86" name="platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.8" revision="c3c37a54f07d51a50e17d63dbf1d92da343f45ce"/>
   <project name="platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9" revision="a7c5a1df753fd3a24494d5e1fe00211048be5c1d"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="7334f0a7a872700d0aaf00bea75917c077c45530"/>
-  <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" revision="a3f0180676c6b6cd9c664704f86855d3404ae4dd"/>
+  <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" revision="cee064f3285bd568fde278a5a3a15837ccd5d11b"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="26e93f6af47f7bd3a9beb5c102a5f45e19bfa38a"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="d9735fc81434f2af2c44d86ca57740c673c8d9bc"/>
-  <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="fe610b19e10b4db855c69f42480b58f0ff7f2d9a"/>
+  <project name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9" revision="e22e34fbd9f173a44f9aa541edd2fe992dbba283"/>
+  <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="fdd759c108d1ad27b9b6e134ee346c3b52d52125"/>
   <project name="platform/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" revision="2725a175a32032fb9a63e247c176ecc3d448ea27"/>
   <project groups="pdk,linux,mips" name="platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.8" path="prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.8" revision="38586de6b44714b4adcf21119fe6b267e33f3ca6"/>
-  <project name="platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" path="prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" revision="eabc7ae8ed527ee3d4517196732fa3f3e8939a28"/>
+  <project name="platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" path="prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" revision="03c23e514e09633c5eb6609d2ad59d3d86ab6901"/>
   <project groups="pdk,linux,mips" name="platform/prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.8" path="prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.8" revision="c06b9b305c365163c99d4ffba49ac37ce2716024"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="e08fa7e57a573a9baa5ccd8d4b8d73cc871f9b48"/>
-  <project name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" revision="e99278016e6285363bc20d1b35d4b9b5c4e8b0a0"/>
+  <project name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" revision="3ca5439a94b378feba31a3b4c228845decebd7d3"/>
   <project name="platform/prebuilts/gradle-plugin" path="prebuilts/gradle-plugin" revision="e7814a3cbb96742ff74505a1fc152cb534fbf2f9"/>
   <project name="platform/prebuilts/maven_repo/android" path="prebuilts/maven_repo/android" revision="0dbe3df0f057de9e83e599b9be2ca866c673130d"/>
-  <project groups="pdk" name="platform/prebuilts/misc" path="prebuilts/misc" revision="3cc2e316acf9da501479bbfd85159407239994d2"/>
-  <project groups="pdk" name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="71a04678bcea092e7d56697b46076da88ccff89e"/>
+  <project groups="pdk" name="platform/prebuilts/misc" path="prebuilts/misc" revision="1963ffb263bc80ea157ccbf323e59dea658b7f7a"/>
+  <project groups="pdk" name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="74db65e4eb138d90293b80dd274203462f8387bf"/>
   <project groups="darwin" name="platform/prebuilts/python/darwin-x86/2.7.5" path="prebuilts/python/darwin-x86/2.7.5" revision="2bdd4fd418614c7c0101147d02199d0e47c4980e"/>
   <project groups="linux" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="5de4f653a1cff7d7acbbb933711537ef47e2723c"/>
-  <project groups="pdk" name="platform/prebuilts/qemu-kernel" path="prebuilts/qemu-kernel" revision="5f91f38eac40a8465f3a7e4aa298a75afcf2936a"/>
-  <project name="platform/prebuilts/runtime" path="prebuilts/runtime" revision="56e663b8ec9cd0df9ce5afdc7b7d56460faf44c8"/>
-  <project groups="pdk" name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="249746cf1f69767f47b93c04c346b00aa504f871"/>
-  <project groups="pdk,tools" name="platform/prebuilts/tools" path="prebuilts/tools" revision="d311580c1bc212ba1a9a45880d1619ddfd7a2a92"/>
-  <project name="platform/sdk" path="sdk" revision="972e1c6d399e81b59fc07d7b7bdc77069ebac1c7"/>
-  <project groups="pdk" name="platform/system/core" path="system/core" revision="7a1973ece3f3f5e1870f7b169281b48b0ca1cd3c"/>
-  <project groups="pdk" name="platform/system/extras" path="system/extras" revision="a64e3c55546f4d94c55f35e341a886c1dfab9e47"/>
-  <project name="platform/system/keymaster" path="system/keymaster" revision="51a11345dfd1acc57d5739640b166caadde0903f"/>
-  <project groups="pdk" name="platform/system/media" path="system/media" revision="77f0f32b32adc5ba1134e7a68e4d907c4f695eb6"/>
-  <project groups="pdk" name="platform/system/netd" path="system/netd" revision="f5d949ef0991737af9daa7ba702cc2ec638e435b"/>
-  <project groups="pdk" name="platform/system/security" path="system/security" revision="4a16cd72102c5b0aeb2690edb5aac1c4d0e1b7fa"/>
-  <project groups="pdk" name="platform/system/vold" path="system/vold" revision="52f5425ff53216e3d7e2410bffd05e0df2b13c9c"/>
+  <project groups="pdk" name="platform/prebuilts/qemu-kernel" path="prebuilts/qemu-kernel" revision="1dffc580d656397f0ffca65820aac524a7ba6f77"/>
+  <project groups="pdk" name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="a57a682a74a9136ec3b8b51b6c4accbca9efafa4"/>
+  <project groups="pdk,tools" name="platform/prebuilts/tools" path="prebuilts/tools" revision="9aad5665728e47d15a9ade341a0efc7b928039a7"/>
+  <project name="platform/sdk" path="sdk" revision="eafacf27fc36109fb9ad92606754aa761696f429"/>
+  <project groups="pdk" name="platform/system/core" path="system/core" revision="c0b4b8b0f17efd4381a828bfbed232fb10b27300"/>
+  <project groups="pdk" name="platform/system/extras" path="system/extras" revision="acc6dfd95f6a2f660f318284db0fa7f01f99231b"/>
+  <project name="platform/system/keymaster" path="system/keymaster" revision="675257e83c8a92ae7d58e321c3800d55a1a3698d"/>
+  <project groups="pdk" name="platform/system/media" path="system/media" revision="89a2450a407ef237e5e35fb21a682758cc6b5f5a"/>
+  <project groups="pdk" name="platform/system/netd" path="system/netd" revision="388cd671ff5237aabcd728794af49d33e18fda8b"/>
+  <project groups="pdk" name="platform/system/security" path="system/security" revision="b570de568adbc2a8ffcb356a56373c10be03b650"/>
+  <project groups="pdk" name="platform/system/vold" path="system/vold" revision="460a93a6d4d01bf0efa83acea0c84b4d43ab23c9"/>
   <project groups="notdefault,tools" name="platform/tools/adt/eclipse" path="tools/adt/eclipse" revision="ede2ed86419bb4c78428f1ac09825b1a247d8e24"/>
-  <project groups="notdefault,tools" name="platform/tools/adt/idea" path="tools/adt/idea" revision="057fd6953b6b8fe4e8868c2cba412651f2429329"/>
-  <project groups="notdefault,tools" name="platform/tools/base" path="tools/base" revision="393bf495dc7279a33ee37f78b812994072ee9e41"/>
+  <project groups="notdefault,tools" name="platform/tools/adt/idea" path="tools/adt/idea" revision="22841dee2cc52f10789b246efe9243c5277a5b51"/>
+  <project groups="notdefault,tools" name="platform/tools/base" path="tools/base" revision="7ae4782932dac53f949cb1766aa5b09d8132cf25"/>
   <project groups="notdefault,tools" name="platform/tools/build" path="tools/build" revision="69c4b95102b4b9862bfba68b3eaf5b7537a705ee"/>
   <project groups="notdefault,tools" name="platform/tools/emulator" path="tools/emulator" revision="c427e5d5227ba9413307670a5d758d9ced394a7e"/>
   <project groups="tools" name="platform/tools/external/fat32lib" path="tools/external/fat32lib" revision="3880776e41ff7def06e351720f2d162f88b58a03"/>
-  <project groups="tools" name="platform/tools/external/gradle" path="tools/external/gradle" revision="842b7a27df8606faa29b0875a13270701eb78dd8"/>
-  <project groups="notdefault,tools" name="platform/tools/idea" path="tools/idea" revision="9cde0e3c015174898df8b8f3672185941fad4786"/>
+  <project groups="tools" name="platform/tools/external/gradle" path="tools/external/gradle" revision="1bde8d4a215dc3efc54d755591b46e329437cc05"/>
+  <project groups="notdefault,tools" name="platform/tools/idea" path="tools/idea" revision="9b5d02ac8c92b1e71523cc15cb3d168d57fbd898"/>
   <project groups="notdefault,motodev" name="platform/tools/motodev" path="tools/motodev" revision="69989786cefbde82527960a1e100ec9afba46a98"/>
   <project groups="notdefault,tools" name="platform/tools/studio/cloud" path="tools/studio/cloud" revision="58f06e77e051fff3903adabca7acdaa9dd12ec2d"/>
-  <project groups="notdefault,tools" name="platform/tools/swt" path="tools/swt" revision="b52fabf54dc10032ae989aecd1b1c0383f877007"/>
+  <project groups="notdefault,tools" name="platform/tools/swt" path="tools/swt" revision="3288c33c591d8b607c42a1e362fb68c0f3909260"/>
 </manifest>
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 6d9325a..6455234 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -58,7 +58,7 @@
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.common.Referrer;
 import org.chromium.ui.base.ActivityWindowAndroid;
-import org.chromium.ui.base.PageTransitionTypes;
+import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.gfx.DeviceDisplayInfo;
 
@@ -1122,11 +1122,11 @@
         // If we are reloading the same url, then set transition type as reload.
         if (params.getUrl() != null &&
                 params.getUrl().equals(mWebContents.getUrl()) &&
-                params.getTransitionType() == PageTransitionTypes.PAGE_TRANSITION_LINK) {
-            params.setTransitionType(PageTransitionTypes.PAGE_TRANSITION_RELOAD);
+                params.getTransitionType() == PageTransition.LINK) {
+            params.setTransitionType(PageTransition.RELOAD);
         }
         params.setTransitionType(
-                params.getTransitionType() | PageTransitionTypes.PAGE_TRANSITION_FROM_API);
+                params.getTransitionType() | PageTransition.FROM_API);
 
         // For WebView, always use the user agent override, which is set
         // every time the user agent in AwSettings is modified.
@@ -1288,11 +1288,7 @@
      * @see View#onScrollChanged(int,int)
      */
     public void onContainerViewScrollChanged(int l, int t, int oldl, int oldt) {
-        // A side-effect of View.onScrollChanged is that the scroll accessibility event being sent
-        // by the base class implementation. This is completely hidden from the base classes and
-        // cannot be prevented, which is why we need the code below.
-        mScrollAccessibilityHelper.removePostedViewScrolledAccessibilityEventCallback();
-        mScrollOffsetManager.onContainerViewScrollChanged(l, t);
+        mAwViewMethods.onContainerViewScrollChanged(l, t, oldl, oldt);
     }
 
     /**
@@ -1301,17 +1297,7 @@
      */
     public void onContainerViewOverScrolled(int scrollX, int scrollY, boolean clampedX,
             boolean clampedY) {
-        int oldX = mContainerView.getScrollX();
-        int oldY = mContainerView.getScrollY();
-
-        mScrollOffsetManager.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
-
-        if (mOverScrollGlow != null) {
-            mOverScrollGlow.pullGlow(mContainerView.getScrollX(), mContainerView.getScrollY(),
-                    oldX, oldY,
-                    mScrollOffsetManager.computeMaximumHorizontalScrollOffset(),
-                    mScrollOffsetManager.computeMaximumVerticalScrollOffset());
-        }
+        mAwViewMethods.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
     }
 
     /**
@@ -1324,45 +1310,45 @@
     }
 
     /**
-     * @see View.computeScroll()
-     */
-    public void computeScroll() {
-        mScrollOffsetManager.computeScrollAndAbsorbGlow(mOverScrollGlow);
-    }
-
-    /**
      * @see View#computeHorizontalScrollRange()
      */
     public int computeHorizontalScrollRange() {
-        return mScrollOffsetManager.computeHorizontalScrollRange();
+        return mAwViewMethods.computeHorizontalScrollRange();
     }
 
     /**
      * @see View#computeHorizontalScrollOffset()
      */
     public int computeHorizontalScrollOffset() {
-        return mScrollOffsetManager.computeHorizontalScrollOffset();
+        return mAwViewMethods.computeHorizontalScrollOffset();
     }
 
     /**
      * @see View#computeVerticalScrollRange()
      */
     public int computeVerticalScrollRange() {
-        return mScrollOffsetManager.computeVerticalScrollRange();
+        return mAwViewMethods.computeVerticalScrollRange();
     }
 
     /**
      * @see View#computeVerticalScrollOffset()
      */
     public int computeVerticalScrollOffset() {
-        return mScrollOffsetManager.computeVerticalScrollOffset();
+        return mAwViewMethods.computeVerticalScrollOffset();
     }
 
     /**
      * @see View#computeVerticalScrollExtent()
      */
     public int computeVerticalScrollExtent() {
-        return mScrollOffsetManager.computeVerticalScrollExtent();
+        return mAwViewMethods.computeVerticalScrollExtent();
+    }
+
+    /**
+     * @see View.computeScroll()
+     */
+    public void computeScroll() {
+        mAwViewMethods.computeScroll();
     }
 
     /**
@@ -2476,6 +2462,61 @@
             if (mIsWindowVisible == windowVisible) return;
             setWindowVisibilityInternal(windowVisible);
         }
+
+        @Override
+        public void onContainerViewScrollChanged(int l, int t, int oldl, int oldt) {
+            // A side-effect of View.onScrollChanged is that the scroll accessibility event being
+            // sent by the base class implementation. This is completely hidden from the base
+            // classes and cannot be prevented, which is why we need the code below.
+            mScrollAccessibilityHelper.removePostedViewScrolledAccessibilityEventCallback();
+            mScrollOffsetManager.onContainerViewScrollChanged(l, t);
+        }
+
+        @Override
+        public void onContainerViewOverScrolled(int scrollX, int scrollY, boolean clampedX,
+                boolean clampedY) {
+            int oldX = mContainerView.getScrollX();
+            int oldY = mContainerView.getScrollY();
+
+            mScrollOffsetManager.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
+
+            if (mOverScrollGlow != null) {
+                mOverScrollGlow.pullGlow(mContainerView.getScrollX(), mContainerView.getScrollY(),
+                        oldX, oldY,
+                        mScrollOffsetManager.computeMaximumHorizontalScrollOffset(),
+                        mScrollOffsetManager.computeMaximumVerticalScrollOffset());
+            }
+        }
+
+        @Override
+        public int computeHorizontalScrollRange() {
+            return mScrollOffsetManager.computeHorizontalScrollRange();
+        }
+
+        @Override
+        public int computeHorizontalScrollOffset() {
+            return mScrollOffsetManager.computeHorizontalScrollOffset();
+        }
+
+        @Override
+        public int computeVerticalScrollRange() {
+            return mScrollOffsetManager.computeVerticalScrollRange();
+        }
+
+        @Override
+        public int computeVerticalScrollOffset() {
+            return mScrollOffsetManager.computeVerticalScrollOffset();
+        }
+
+        @Override
+        public int computeVerticalScrollExtent() {
+            return mScrollOffsetManager.computeVerticalScrollExtent();
+        }
+
+        @Override
+        public void computeScroll() {
+            mScrollOffsetManager.computeScrollAndAbsorbGlow(mOverScrollGlow);
+        }
     }
 
     // Return true if the GeolocationPermissionAPI should be used.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwViewMethods.java b/android_webview/java/src/org/chromium/android_webview/AwViewMethods.java
index e5031ad1..02b360d 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwViewMethods.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwViewMethods.java
@@ -112,4 +112,45 @@
      * @see android.view.View#onWindowVisibilityChanged
      */
     void onWindowVisibilityChanged(int visibility);
+
+    /**
+     * @see android.view.View#onScrollChanged
+     */
+    void onContainerViewScrollChanged(int l, int t, int oldl, int oldt);
+
+    /**
+     * @see android.view.View#onOverScrolled
+     */
+    void onContainerViewOverScrolled(
+            int scrollX, int scrollY, boolean clampedX, boolean clampedY);
+
+    /**
+     * @see android.view.View#computeHorizontalScrollRange
+     */
+    int computeHorizontalScrollRange();
+
+    /**
+     * @see android.view.View#computeHorizontalScrollOffset
+     */
+    int computeHorizontalScrollOffset();
+
+    /**
+     * @see android.view.View#computeVerticalScrollRange
+     */
+    int computeVerticalScrollRange();
+
+    /**
+     * @see android.view.View#computeVerticalScrollOffset
+     */
+    int computeVerticalScrollOffset();
+
+    /**
+     * @see android.view.View#computeVerticalScrollExtent
+     */
+    int computeVerticalScrollExtent();
+
+    /**
+     * @see android.view.View#computeScroll
+     */
+    void computeScroll();
 }
diff --git a/android_webview/java/src/org/chromium/android_webview/FullScreenView.java b/android_webview/java/src/org/chromium/android_webview/FullScreenView.java
index 6b944a1..3dd0f3d 100644
--- a/android_webview/java/src/org/chromium/android_webview/FullScreenView.java
+++ b/android_webview/java/src/org/chromium/android_webview/FullScreenView.java
@@ -140,6 +140,47 @@
         mAwViewMethods.onWindowVisibilityChanged(visibility);
     }
 
+    @Override
+    public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
+        mAwViewMethods.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
+    }
+
+    @Override
+    public void onScrollChanged(int l, int t, int oldl, int oldt) {
+        super.onScrollChanged(l, t, oldl, oldt);
+        mAwViewMethods.onContainerViewScrollChanged(l, t, oldl, oldt);
+    }
+
+    @Override
+    public int computeHorizontalScrollRange() {
+        return mAwViewMethods.computeHorizontalScrollRange();
+    }
+
+    @Override
+    public int computeHorizontalScrollOffset() {
+        return mAwViewMethods.computeHorizontalScrollOffset();
+    }
+
+    @Override
+    public int computeVerticalScrollRange() {
+        return mAwViewMethods.computeVerticalScrollRange();
+    }
+
+    @Override
+    public int computeVerticalScrollOffset() {
+        return mAwViewMethods.computeVerticalScrollOffset();
+    }
+
+    @Override
+    public int computeVerticalScrollExtent() {
+        return mAwViewMethods.computeVerticalScrollExtent();
+    }
+
+    @Override
+    public void computeScroll() {
+        mAwViewMethods.computeScroll();
+    }
+
     // AwContents.InternalAccessDelegate implementation --------------------------------------
     private class InternalAccessAdapter implements AwContents.InternalAccessDelegate {
 
@@ -181,29 +222,30 @@
 
         @Override
         public boolean awakenScrollBars() {
-            return false;
+            return FullScreenView.this.awakenScrollBars(0);
         }
 
         @Override
         public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
-            return false;
+            return FullScreenView.super.awakenScrollBars(startDelay, invalidate);
         }
 
         @Override
         public void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix) {
-            // Intentional no-op.
+            FullScreenView.this.onScrollChanged(lPix, tPix, oldlPix, oldtPix);
         }
 
         @Override
         public void overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,
                 int scrollRangeX, int scrollRangeY, int maxOverScrollX,
                 int maxOverScrollY, boolean isTouchEvent) {
-            // Intentional no-op.
+            FullScreenView.this.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
+                    scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
         }
 
         @Override
         public void super_scrollTo(int scrollX, int scrollY) {
-            // Intentional no-op.
+            FullScreenView.super.scrollTo(scrollX, scrollY);
         }
 
         @Override
diff --git a/android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java b/android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java
index 2a94e60..aea2c09f 100644
--- a/android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java
+++ b/android_webview/java/src/org/chromium/android_webview/NullAwViewMethods.java
@@ -127,4 +127,45 @@
     public void onWindowVisibilityChanged(int visibility) {
         // Intentional no-op.
     }
+
+    @Override
+    public void onContainerViewScrollChanged(int l, int t, int oldl, int oldt) {
+        // Intentional no-op.
+    }
+
+    @Override
+    public void onContainerViewOverScrolled(int scrollX, int scrollY, boolean clampedX,
+            boolean clampedY) {
+        // Intentional no-op.
+    }
+
+    @Override
+    public int computeHorizontalScrollRange() {
+        return 0;
+    }
+
+    @Override
+    public int computeHorizontalScrollOffset() {
+        return 0;
+    }
+
+    @Override
+    public int computeVerticalScrollRange() {
+        return 0;
+    }
+
+    @Override
+    public int computeVerticalScrollOffset() {
+        return 0;
+    }
+
+    @Override
+    public int computeVerticalScrollExtent() {
+        return 0;
+    }
+
+    @Override
+    public void computeScroll() {
+        // Intentional no-op.
+    }
 }
diff --git a/android_webview/java_library_common.mk b/android_webview/java_library_common.mk
index ec9ad693..d4cebdd 100644
--- a/android_webview/java_library_common.mk
+++ b/android_webview/java_library_common.mk
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+LOCAL_SDK_VERSION := 21
+
 LOCAL_SRC_FILES := $(call all-java-files-under, java/src)
 
 # contentview and its dependencies
@@ -56,11 +58,11 @@
 $(call intermediates-dir-for,GYP,shared)/enums/speech_recognition_error_java/org/chromium/content_public/common/SpeechRecognitionErrorCode.java \
 $(call intermediates-dir-for,GYP,shared)/enums/top_controls_state_java/org/chromium/content_public/common/TopControlsState.java \
 $(call intermediates-dir-for,GYP,shared)/enums/window_open_disposition_java/org/chromium/ui/WindowOpenDisposition.java \
-$(call intermediates-dir-for,GYP,shared)/templates/base_java_application_state/org/chromium/base/ApplicationState.java \
-$(call intermediates-dir-for,GYP,shared)/templates/base_java_memory_pressure_level_list/org/chromium/base/MemoryPressureLevelList.java \
-$(call intermediates-dir-for,GYP,shared)/templates/media_android_imageformat_list/org/chromium/media/AndroidImageFormat.java \
+$(call intermediates-dir-for,GYP,shared)/enums/base_java_application_state/org/chromium/base/ApplicationState.java \
+$(call intermediates-dir-for,GYP,shared)/enums/base_java_memory_pressure_level/org/chromium/base/MemoryPressureLevel.java \
+$(call intermediates-dir-for,GYP,shared)/enums/media_android_imageformat/org/chromium/media/AndroidImageFormat.java \
+$(call intermediates-dir-for,GYP,shared)/enums/page_transition_types_java/org/chromium/ui/base/PageTransition.java \
 $(call intermediates-dir-for,GYP,shared)/templates/net_errors_java/org/chromium/net/NetError.java \
-$(call intermediates-dir-for,GYP,shared)/templates/page_transition_types_java/org/chromium/ui/base/PageTransitionTypes.java \
 
 # content dependencies on java components that are provided by the system on
 # android
diff --git a/android_webview/javatests/AndroidManifest.xml b/android_webview/javatests/AndroidManifest.xml
index a681e25..8005cd1 100644
--- a/android_webview/javatests/AndroidManifest.xml
+++ b/android_webview/javatests/AndroidManifest.xml
@@ -11,7 +11,7 @@
         <uses-library android:name="android.test.runner" />
     </application>
     <!-- TODO(joth): Change minSdkVersion to 16 when crbug/161864 lands. -->
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.android_webview.shell"
         android:label="Tests for org.chromium.android_webview"/>
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index d43870fc..c59d7ca 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -288,8 +288,8 @@
         }
 
         private String getData() {
-            return "<html><body onload=\"document.title = " +
-                    "getComputedStyle(document.body).getPropertyValue('font-family');\">"
+            return "<html><body onload=\"document.title = "
+                    + "getComputedStyle(document.body).getPropertyValue('font-family');\">"
                     + "</body></html>";
         }
     }
@@ -328,8 +328,8 @@
         }
 
         private String getData() {
-            return "<html><body onload=\"document.title = " +
-                    "getComputedStyle(document.body).getPropertyValue('font-size');\">"
+            return "<html><body onload=\"document.title = "
+                    + "getComputedStyle(document.body).getPropertyValue('font-size');\">"
                     + "</body></html>";
         }
     }
@@ -368,10 +368,10 @@
         @Override
         protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
             loadDataSync(mGenerator.getPageSource());
-            assertEquals(value == ENABLED ?
-                         ImagePageGenerator.IMAGE_LOADED_STRING :
-                         ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
-                         getTitleOnUiThread());
+            assertEquals(value == ENABLED
+                    ? ImagePageGenerator.IMAGE_LOADED_STRING
+                    : ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
+                    getTitleOnUiThread());
         }
     }
 
@@ -415,10 +415,10 @@
                     mAwContents,
                     mContentViewClient.getOnPageFinishedHelper(),
                     httpImageUrl);
-            assertEquals(value == ENABLED ?
-                         ImagePageGenerator.IMAGE_LOADED_STRING :
-                         ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
-                         getTitleOnUiThread());
+            assertEquals(value == ENABLED
+                    ? ImagePageGenerator.IMAGE_LOADED_STRING
+                    : ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
+                    getTitleOnUiThread());
         }
 
         private TestWebServer mWebServer;
@@ -888,11 +888,11 @@
             try {
                 TestFileUtil.createNewHtmlFile(fileName,
                         TARGET,
-                        "<img src=\"" +
+                        "<img src=\""
                         // Adding a query avoids hitting a cached image, and also verifies
                         // that content URL query parameters are ignored when accessing
                         // a content provider.
-                        AwSettingsTest.this.createContentUrl(TARGET + "?id=" + mIndex) + "\">");
+                        + AwSettingsTest.this.createContentUrl(TARGET + "?id=" + mIndex) + "\">");
                 mIndex += 2;
                 loadUrlSync("file://" + fileName);
                 if (value == ENABLED) {
@@ -954,20 +954,20 @@
             int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
             int layoutWidth = (int) (displayWidth * 2.5f); // Use 2.5 as autosizing layout tests do.
             StringBuilder sb = new StringBuilder();
-            sb.append("<html>" +
-                    "<head>" +
-                    "<meta name=\"viewport\" content=\"width=" + layoutWidth + "\">" +
-                    "<style>" +
-                    "body { width: " + layoutWidth + "px; margin: 0; overflow-y: hidden; }" +
-                    "</style>" +
-                    "<script>" +
-                    "function setTitleToActualFontSize() {" +
+            sb.append("<html>"
+                    + "<head>"
+                    + "<meta name=\"viewport\" content=\"width=" + layoutWidth + "\">"
+                    + "<style>"
+                    + "body { width: " + layoutWidth + "px; margin: 0; overflow-y: hidden; }"
+                    + "</style>"
+                    + "<script>"
+                    + "function setTitleToActualFontSize() {"
                     // parseFloat is used to trim out the "px" suffix.
-                    "  document.title = parseFloat(getComputedStyle(" +
-                    "    document.getElementById('par')).getPropertyValue('font-size'));" +
-                    "}</script></head>" +
-                    "<body>" +
-                    "<p id=\"par\" style=\"font-size:");
+                    + "  document.title = parseFloat(getComputedStyle("
+                    + "    document.getElementById('par')).getPropertyValue('font-size'));"
+                    + "}</script></head>"
+                    + "<body>"
+                    + "<p id=\"par\" style=\"font-size:");
             sb.append(PARAGRAPH_FONT_SIZE);
             sb.append("px;\">");
             // Make the paragraph wide enough for being processed by the font autosizer.
@@ -1065,11 +1065,11 @@
             // Ensure that actual vs. initial font size ratio is similar to actual vs. initial
             // text zoom values ratio.
             final float ratiosDelta = Math.abs(
-                    (actualFontSize / mInitialActualFontSize) -
-                    (value / (float) INITIAL_TEXT_ZOOM));
+                    (actualFontSize / mInitialActualFontSize)
+                    - (value / (float) INITIAL_TEXT_ZOOM));
             assertTrue(
-                    "|(" + actualFontSize + " / " + mInitialActualFontSize + ") - (" +
-                    value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta,
+                    "|(" + actualFontSize + " / " + mInitialActualFontSize + ") - ("
+                    + value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta,
                     ratiosDelta <= 0.2f);
         }
     }
@@ -1116,11 +1116,11 @@
             // Ensure that actual vs. initial font size ratio is similar to actual vs. initial
             // text zoom values ratio.
             final float ratiosDelta = Math.abs(
-                    (actualFontSize / mInitialActualFontSize) -
-                    (value / (float) INITIAL_TEXT_ZOOM));
+                    (actualFontSize / mInitialActualFontSize)
+                    - (value / (float) INITIAL_TEXT_ZOOM));
             assertTrue(
-                    "|(" + actualFontSize + " / " + mInitialActualFontSize + ") - (" +
-                    value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta,
+                    "|(" + actualFontSize + " / " + mInitialActualFontSize + ") - ("
+                    + value + " / " + INITIAL_TEXT_ZOOM + ")| = " + ratiosDelta,
                     ratiosDelta <= 0.2f);
         }
     }
@@ -1171,16 +1171,16 @@
         }
 
         private String getData() {
-            return "<html><head>" +
-                    "<script>" +
-                    "    function tryOpenWindow() {" +
-                    "        var newWindow = window.open(" +
-                    "           'data:text/html;charset=utf-8," +
-                    "           <html><head><title>" + POPUP_ENABLED + "</title></head></html>');" +
-                    "        if (!newWindow) document.title = '" + POPUP_BLOCKED + "';" +
-                    "    }" +
-                    "</script></head>" +
-                    "<body onload='tryOpenWindow()'></body></html>";
+            return "<html><head>"
+                    + "<script>"
+                    + "    function tryOpenWindow() {"
+                    + "        var newWindow = window.open("
+                    + "           'data:text/html;charset=utf-8,"
+                    + "           <html><head><title>" + POPUP_ENABLED + "</title></head></html>');"
+                    + "        if (!newWindow) document.title = '" + POPUP_BLOCKED + "';"
+                    + "    }"
+                    + "</script></head>"
+                    + "<body onload='tryOpenWindow()'></body></html>";
         }
     }
 
@@ -1282,10 +1282,10 @@
         }
 
         private String getData() {
-            return "<html><head>" +
-                    "<meta name='viewport' content='width=" + VIEWPORT_TAG_LAYOUT_WIDTH + "' />" +
-                    "</head>" +
-                    "<body onload='document.title=document.body.clientWidth'></body></html>";
+            return "<html><head>"
+                    + "<meta name='viewport' content='width=" + VIEWPORT_TAG_LAYOUT_WIDTH + "' />"
+                    + "</head>"
+                    + "<body onload='document.title=document.body.clientWidth'></body></html>";
         }
     }
 
@@ -1330,8 +1330,8 @@
         protected void doEnsureSettingHasValue(Boolean value) throws Throwable {
             loadDataSync(getData());
             if (mExpectScaleChange) {
-                mContentViewClient.getOnScaleChangedHelper().
-                        waitForCallback(mOnScaleChangedCallCount);
+                mContentViewClient.getOnScaleChangedHelper()
+                        .waitForCallback(mOnScaleChangedCallCount);
                 mExpectScaleChange = false;
             }
             float currentScale = AwSettingsTest.this.getScaleOnUiThread(mAwContents);
@@ -1344,10 +1344,10 @@
         }
 
         private String getData() {
-            return "<html><head>" +
-                    (mWithViewPortTag ? "<meta name='viewport' content='width=3000' />" : "") +
-                    "</head>" +
-                    "<body></body></html>";
+            return "<html><head>"
+                    + (mWithViewPortTag ? "<meta name='viewport' content='width=3000' />" : "")
+                    + "</head>"
+                    + "<body></body></html>";
         }
 
         private final boolean mWithViewPortTag;
@@ -1398,18 +1398,18 @@
         }
 
         private String getData() {
-            return "<html><head>" +
-                    (mWithViewPortTag ? "<meta name='viewport' content='height=3000' />" : "") +
-                    "  <script type='text/javascript'> " +
-                    "    window.addEventListener('load', function(event) { " +
-                    "       document.title = document.getElementById('testDiv').clientHeight; " +
-                    "    }); " +
-                    "  </script> " +
-                    "</head>" +
-                    "<body> " +
-                    "  <div style='height:50px;'>test</div> " +
-                    "  <div id='testDiv' style='height:100%;'></div> " +
-                    "</body></html>";
+            return "<html><head>"
+                    + (mWithViewPortTag ? "<meta name='viewport' content='height=3000' />" : "")
+                    + "  <script type='text/javascript'> "
+                    + "    window.addEventListener('load', function(event) { "
+                    + "       document.title = document.getElementById('testDiv').clientHeight; "
+                    + "    }); "
+                    + "  </script> "
+                    + "</head>"
+                    + "<body> "
+                    + "  <div style='height:50px;'>test</div> "
+                    + "  <div id='testDiv' style='height:100%;'></div> "
+                    + "</body></html>";
         }
 
         private final boolean mWithViewPortTag;
@@ -1461,18 +1461,18 @@
         }
 
         private String getData() {
-            return "<html><head>" +
-                    "<meta name='viewport' content='width=3000' />" +
-                    "  <script type='text/javascript'> " +
-                    "    window.addEventListener('load', function(event) { " +
-                    "       document.title = document.documentElement.clientWidth; " +
-                    "    }); " +
-                    "  </script> " +
-                    "</head>" +
-                    "<body> " +
-                    "  <div style='height:50px;'>test</div> " +
-                    "  <div id='testDiv' style='height:100%;'></div> " +
-                    "</body></html>";
+            return "<html><head>"
+                    + "<meta name='viewport' content='width=3000' />"
+                    + "  <script type='text/javascript'> "
+                    + "    window.addEventListener('load', function(event) { "
+                    + "       document.title = document.documentElement.clientWidth; "
+                    + "    }); "
+                    + "  </script> "
+                    + "</head>"
+                    + "<body> "
+                    + "  <div style='height:50px;'>test</div> "
+                    + "  <div id='testDiv' style='height:100%;'></div> "
+                    + "</body></html>";
         }
     }
 
@@ -1626,15 +1626,15 @@
         final String actualUserAgentString = settings.getUserAgentString();
         assertEquals(actualUserAgentString, AwSettings.getDefaultUserAgent());
         final String patternString =
-                "Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?" +
-                "\\s?(.*)\\sBuild/(.+)\\) AppleWebKit/(\\d+)\\.(\\d+) \\(KHTML, like Gecko\\) " +
-                "Version/\\d+\\.\\d Chrome/\\d+\\.\\d+\\.\\d+\\.\\d+" +
-                "( Mobile)? Safari/(\\d+)\\.(\\d+)";
+                "Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?"
+                + "\\s?(.*)\\sBuild/(.+)\\) AppleWebKit/(\\d+)\\.(\\d+) \\(KHTML, like Gecko\\) "
+                + "Version/\\d+\\.\\d Chrome/\\d+\\.\\d+\\.\\d+\\.\\d+"
+                + "( Mobile)? Safari/(\\d+)\\.(\\d+)";
         final Pattern userAgentExpr = Pattern.compile(patternString);
         Matcher patternMatcher = userAgentExpr.matcher(actualUserAgentString);
-        assertTrue(String.format("User agent string did not match expected pattern. %nExpected " +
-                        "pattern:%n%s%nActual:%n%s", patternString, actualUserAgentString),
-                        patternMatcher.find());
+        assertTrue(String.format("User agent string did not match expected pattern. %nExpected "
+                        + "pattern:%n%s%nActual:%n%s", patternString, actualUserAgentString),
+                    patternMatcher.find());
         // No country-language code token.
         assertEquals(null, patternMatcher.group(3));
         if ("REL".equals(Build.VERSION.CODENAME)) {
@@ -1692,9 +1692,9 @@
         // We are using different page titles to make sure that we are really
         // going back and forward between them.
         final String pageTemplate =
-                "<html><head><title>%s</title></head>" +
-                "<body onload='document.title+=navigator.userAgent'></body>" +
-                "</html>";
+                "<html><head><title>%s</title></head>"
+                + "<body onload='document.title+=navigator.userAgent'></body>"
+                + "</html>";
         final String page1Title = "Page1";
         final String page2Title = "Page2";
         final String page1 = String.format(pageTemplate, page1Title);
@@ -1892,10 +1892,10 @@
                 createAwTestContainerViewOnMainSync(contentClient);
         final AwContents awContents = testContainerView.getAwContents();
         final String target = "content_from_data";
-        final String page = "<html><body>" +
-                "<img src=\"" +
-                createContentUrl(target) + "\">" +
-                "</body></html>";
+        final String page = "<html><body>"
+                + "<img src=\""
+                + createContentUrl(target) + "\">"
+                + "</body></html>";
         resetResourceRequestCountInContentProvider(target);
         loadDataSync(
                 awContents,
@@ -2013,9 +2013,9 @@
                     CommonResources.getImagePngHeaders(true));
 
             // Set up file html that loads http iframe.
-            String pageHtml = "<img src='" + imageUrl + "' " +
-                      "onload=\"document.title='img_onload_fired';\" " +
-                      "onerror=\"document.title='img_onerror_fired';\" />";
+            String pageHtml = "<img src='" + imageUrl + "' "
+                      + "onload=\"document.title='img_onload_fired';\" "
+                      + "onerror=\"document.title='img_onerror_fired';\" />";
             Context context = getInstrumentation().getTargetContext();
             fileName = context.getCacheDir() + "/block_network_loads_test.html";
             TestFileUtil.deleteFile(fileName);  // Remove leftover file if any.
@@ -2079,9 +2079,9 @@
             // to know whether Url is accessed.
             final String audioUrl = webServer.setResponse(httpPath, "1", null);
 
-            String pageHtml = "<html><body><audio controls src='" + audioUrl + "' " +
-                    "oncanplay=\"AudioEvent.onCanPlay();\" " +
-                    "onerror=\"AudioEvent.onError();\" /> </body></html>";
+            String pageHtml = "<html><body><audio controls src='" + audioUrl + "' "
+                    + "oncanplay=\"AudioEvent.onCanPlay();\" "
+                    + "onerror=\"AudioEvent.onError();\" /> </body></html>";
             // Actual test. Blocking should trigger onerror handler.
             awSettings.setBlockNetworkLoads(true);
             runTestOnUiThread(new Runnable() {
@@ -2503,8 +2503,8 @@
         final AwContents awContents = testContainer.getAwContents();
         AwSettings settings = getAwSettingsOnUiThread(awContents);
 
-        final String pageTemplate = "<html><head>%s</head>" +
-                "<body onload='document.title=document.body.clientWidth'></body></html>";
+        final String pageTemplate = "<html><head>%s</head>"
+                + "<body onload='document.title=document.body.clientWidth'></body></html>";
         final String pageNoViewport = String.format(pageTemplate, "");
         final String pageViewportDeviceWidth = String.format(
                 pageTemplate,
@@ -2586,10 +2586,10 @@
                 DeviceDisplayInfo.create(testContainerView.getContext());
         int displayWidth = (int) (deviceInfo.getDisplayWidth() / deviceInfo.getDIPScale());
         int layoutWidth = displayWidth * 2;
-        final String page = "<html>" +
-                "<head><meta name='viewport' content='width=" + layoutWidth + "'>" +
-                "<style> body { width: " + layoutWidth + "px; }</style></head>" +
-                "<body>Page Text</body></html>";
+        final String page = "<html>"
+                + "<head><meta name='viewport' content='width=" + layoutWidth + "'>"
+                + "<style> body { width: " + layoutWidth + "px; }</style></head>"
+                + "<body>Page Text</body></html>";
 
         assertFalse(settings.getUseWideViewPort());
         // Without wide viewport the <meta viewport> tag will be ignored by WebView,
@@ -2682,9 +2682,9 @@
         // Make sure after 50% scale, page width still larger than screen.
         int height = screenSize.y * 2 + 1;
         int width = screenSize.x * 2 + 1;
-        final String page = "<html><body>" +
-                "<p style='height:" + height + "px;width:" + width + "px'>" +
-                "testSetInitialScale</p></body></html>";
+        final String page = "<html><body>"
+                + "<p style='height:" + height + "px;width:" + width + "px'>"
+                + "testSetInitialScale</p></body></html>";
         final float defaultScale =
                 getInstrumentation().getTargetContext().getResources().getDisplayMetrics().density;
 
@@ -2756,9 +2756,9 @@
         VideoTestWebServer webServer = new VideoTestWebServer(
                 getInstrumentation().getTargetContext());
         try {
-            String data = "<html><head><body>" +
-                    "<video id='video' control src='" +
-                    webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
+            String data = "<html><head><body>"
+                    + "<video id='video' control src='"
+                    + webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
             loadDataAsync(awContents, data, "text/html", false);
             videoPosterAccessedCallbackHelper.waitForCallback(0, 1, 20, TimeUnit.SECONDS);
         } finally {
@@ -2796,8 +2796,8 @@
             httpServer.setResponse(jsUrl, "window.loaded_js = 42;", null);
             httpServer.setResponseBase64(imageUrl, CommonResources.FAVICON_DATA_BASE64, null);
 
-            final String jsHtml = "<script src=\"" + httpServer.getResponseUrl(jsUrl) +
-                    "\"></script>";
+            final String jsHtml = "<script src=\"" + httpServer.getResponseUrl(jsUrl)
+                    + "\"></script>";
             final String imageHtml = "<img src=\"" + httpServer.getResponseUrl(imageUrl) + "\" />";
             final String secureHtml = "<body>" + imageHtml + " " + jsHtml + "</body>";
 
@@ -2936,9 +2936,9 @@
     static void assertFileIsReadable(String filePath) {
         File file = new File(filePath);
         try {
-            assertTrue("Test file \"" + filePath + "\" is not readable." +
-                    "Please make sure that files from android_webview/test/data/device_files/ " +
-                    "has been pushed to the device before testing",
+            assertTrue("Test file \"" + filePath + "\" is not readable."
+                    + "Please make sure that files from android_webview/test/data/device_files/ "
+                    + "has been pushed to the device before testing",
                     file.canRead());
         } catch (SecurityException e) {
             fail("Got a SecurityException for \"" + filePath + "\": " + e.toString());
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java
index 4dee1cf..2c72619 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java
@@ -116,10 +116,10 @@
         JSUtils.executeJavaScriptAndWaitForResult(
                 this, mAwContents,
                 mContentsClient.getOnEvaluateJavaScriptResultHelper(),
-                "var expirationDate = new Date();" +
-                "expirationDate.setDate(expirationDate.getDate() + 5);" +
-                "document.cookie='" + name + "=" + value +
-                        "; expires=' + expirationDate.toUTCString();");
+                "var expirationDate = new Date();"
+                + "expirationDate.setDate(expirationDate.getDate() + 5);"
+                + "document.cookie='" + name + "=" + value
+                + "; expires=' + expirationDate.toUTCString();");
     }
 
     @MediumTest
@@ -425,8 +425,8 @@
      * @return  the url which gets the response
      */
     private String makeScriptLinkUrl(TestWebServer webServer, String path, String url) {
-        String responseStr = "<html><head><title>Content!</title></head>" +
-                    "<body><script src=" + url + "></script></body></html>";
+        String responseStr = "<html><head><title>Content!</title></head>"
+                + "<body><script src=" + url + "></script></body></html>";
         return webServer.setResponse(path, responseStr, null);
     }
 
@@ -436,8 +436,8 @@
         TestWebServer webServer = TestWebServer.start();
         try {
             // This test again uses 127.0.0.1/localhost trick to simulate a third party.
-            ThirdPartyCookiesTestHelper thirdParty
-                    = new ThirdPartyCookiesTestHelper(webServer);
+            ThirdPartyCookiesTestHelper thirdParty =
+                    new ThirdPartyCookiesTestHelper(webServer);
 
             mCookieManager.setAcceptCookie(true);
             assertTrue(mCookieManager.acceptCookie());
@@ -597,8 +597,8 @@
      * @return  the url which gets the response
      */
     private String makeIframeUrl(TestWebServer webServer, String path, String url) {
-        String responseStr = "<html><head><title>Content!</title></head>" +
-                    "<body><iframe src=" + url + "></iframe></body></html>";
+        String responseStr = "<html><head><title>Content!</title></head>"
+                + "<body><iframe src=" + url + "></iframe></body></html>";
         return webServer.setResponse(path, responseStr, null);
     }
 
@@ -612,8 +612,8 @@
      */
     private String makeCookieScriptUrl(TestWebServer webServer, String path, String key,
             String value) {
-        String response = "<html><head></head><body>" +
-                "<script>document.cookie = \"" + key + "=" + value + "\";</script></body></html>";
+        String response = "<html><head></head><body>"
+                + "<script>document.cookie = \"" + key + "=" + value + "\";</script></body></html>";
         return webServer.setResponse(path, response, null);
     }
 
diff --git a/android_webview/libwebviewchromium.gypi b/android_webview/libwebviewchromium.gypi
index 3d87388d..50ff746 100644
--- a/android_webview/libwebviewchromium.gypi
+++ b/android_webview/libwebviewchromium.gypi
@@ -14,7 +14,7 @@
       # android_webview_java in android_webview/java_library_common.mk.
       'dependencies': [
         '../base/base.gyp:base_java_application_state',
-        '../base/base.gyp:base_java_memory_pressure_level_list',
+        '../base/base.gyp:base_java_memory_pressure_level',
         '../content/content.gyp:content_gamepad_mapping',
         '../content/content.gyp:gesture_event_type_java',
         '../content/content.gyp:popup_item_type_java',
@@ -23,7 +23,7 @@
         '../content/content.gyp:selection_event_type_java',
         '../content/content.gyp:speech_recognition_error_java',
         '../content/content.gyp:top_controls_state_java',
-        '../media/media.gyp:media_android_imageformat_list',
+        '../media/media.gyp:media_android_imageformat',
         '../net/net.gyp:cert_verify_status_android_java',
         '../net/net.gyp:certificate_mime_types_java',
         '../net/net.gyp:net_errors_java',
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index c0da9257..fb7b2e4 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -279,7 +279,7 @@
   // without ever using another WebView.
   if (base::subtle::NoBarrier_Load(&g_instance_count) == 0) {
     base::MemoryPressureListener::NotifyMemoryPressure(
-        base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
+        base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
   }
 }
 
@@ -774,6 +774,11 @@
   browser_view_renderer_.UpdateParentDrawConstraints();
 }
 
+void AwContents::DidSkipCommitFrame() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  browser_view_renderer_.DidSkipCommitFrame();
+}
+
 void AwContents::OnNewPicture() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   JNIEnv* env = AttachCurrentThread();
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index e49d842..f350b73 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -192,6 +192,7 @@
   virtual bool RequestDrawGL(jobject canvas, bool wait_for_completion) override;
   virtual void PostInvalidate() override;
   virtual void UpdateParentDrawConstraints() override;
+  virtual void DidSkipCommitFrame() override;
   virtual void OnNewPicture() override;
   virtual gfx::Point GetLocationOnScreen() override;
   virtual void ScrollContainerViewTo(gfx::Vector2d new_value) override;
diff --git a/android_webview/renderer/DEPS b/android_webview/renderer/DEPS
index b5cbb48..055b5e0 100644
--- a/android_webview/renderer/DEPS
+++ b/android_webview/renderer/DEPS
@@ -9,6 +9,8 @@
 
   "+content/public/renderer",
 
+  "+media/base",
+
   "+printing",
 
   "+third_party/WebKit/public/platform",
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc
index 7ba28d9..5114d0f 100644
--- a/android_webview/renderer/aw_content_renderer_client.cc
+++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -193,7 +193,7 @@
 }
 
 void AwContentRendererClient::AddKeySystems(
-    std::vector<content::KeySystemInfo>* key_systems) {
+    std::vector<media::KeySystemInfo>* key_systems) {
   AwAddKeySystems(key_systems);
 }
 
diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h
index ac6e67b..f6ffcbff 100644
--- a/android_webview/renderer/aw_content_renderer_client.h
+++ b/android_webview/renderer/aw_content_renderer_client.h
@@ -38,7 +38,7 @@
                                              size_t length) override;
   virtual bool IsLinkVisited(unsigned long long link_hash) override;
   virtual void AddKeySystems(
-      std::vector<content::KeySystemInfo>* key_systems) override;
+      std::vector<media::KeySystemInfo>* key_systems) override;
 
   virtual bool HandleNavigation(content::RenderFrame* render_frame,
                                 content::DocumentState* document_state,
diff --git a/android_webview/renderer/aw_key_systems.cc b/android_webview/renderer/aw_key_systems.cc
index 2076c92..cc3059e 100644
--- a/android_webview/renderer/aw_key_systems.cc
+++ b/android_webview/renderer/aw_key_systems.cc
@@ -8,7 +8,7 @@
 namespace android_webview {
 
 void AwAddKeySystems(
-    std::vector<content::KeySystemInfo>* key_systems_info) {
+    std::vector<media::KeySystemInfo>* key_systems_info) {
   cdm::AddAndroidWidevine(key_systems_info);
   cdm::AddAndroidPlatformKeySystems(key_systems_info);
 }
diff --git a/android_webview/renderer/aw_key_systems.h b/android_webview/renderer/aw_key_systems.h
index 96823b5..4bed8b61 100644
--- a/android_webview/renderer/aw_key_systems.h
+++ b/android_webview/renderer/aw_key_systems.h
@@ -5,11 +5,13 @@
 #ifndef ANDROID_WEBVIEW_RENDERER_AW_KEY_SYSTEMS_H_
 #define ANDROID_WEBVIEW_RENDERER_AW_KEY_SYSTEMS_H_
 
-#include "content/public/renderer/key_system_info.h"
+#include <vector>
+
+#include "media/base/key_system_info.h"
 
 namespace android_webview {
 
-void AwAddKeySystems(std::vector<content::KeySystemInfo>* key_systems_info);
+void AwAddKeySystems(std::vector<media::KeySystemInfo>* key_systems_info);
 
 }  // namespace android_webview
 
diff --git a/android_webview/test/shell/AndroidManifest.xml b/android_webview/test/shell/AndroidManifest.xml
index 749efaa2..6529f36 100644
--- a/android_webview/test/shell/AndroidManifest.xml
+++ b/android_webview/test/shell/AndroidManifest.xml
@@ -32,7 +32,7 @@
   </application>
 
   <!-- TODO(joth): Change minSdkVersion to 16 when crbug/161864 lands. -->
-  <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
+  <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.WAKE_LOCK"/>
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
index 5095127..adc43fe8 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
@@ -32,10 +32,12 @@
 import org.chromium.android_webview.AwBrowserProcess;
 import org.chromium.android_webview.AwContents;
 import org.chromium.android_webview.AwContentsClient;
+import org.chromium.android_webview.AwContentsStatics;
 import org.chromium.android_webview.AwDevToolsServer;
 import org.chromium.android_webview.AwSettings;
 import org.chromium.android_webview.test.AwTestContainerView;
 import org.chromium.android_webview.test.NullContentsClient;
+import org.chromium.base.CommandLine;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.NavigationController;
 import org.chromium.content_public.browser.WebContents;
@@ -55,6 +57,11 @@
     private ImageButton mPrevButton;
     private ImageButton mNextButton;
 
+    // This is the same as data_reduction_proxy::switches::kEnableDataReductionProxy.
+    private static final String ENABLE_DATA_REDUCTION_PROXY = "enable-spdy-proxy-auth";
+    // This is the same as data_reduction_proxy::switches::kDataReductionProxyKey.
+    private static final String DATA_REDUCTION_PROXY_KEY = "spdy-proxy-auth-value";
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -82,6 +89,14 @@
         mAwTestContainerView.getAwContents().loadUrl(new LoadUrlParams(startupUrl));
         AwContents.setShouldDownloadFavicons();
         mUrlTextView.setText(startupUrl);
+
+        if (CommandLine.getInstance().hasSwitch(ENABLE_DATA_REDUCTION_PROXY)) {
+            String key = CommandLine.getInstance().getSwitchValue(DATA_REDUCTION_PROXY_KEY);
+            if (key != null && !key.isEmpty()) {
+                AwContentsStatics.setDataReductionProxyKey(key);
+                AwContentsStatics.setDataReductionProxyEnabled(true);
+            }
+        }
     }
 
     private AwTestContainerView createAwTestContainerView() {
diff --git a/android_webview/tools/PRESUBMIT.py b/android_webview/tools/PRESUBMIT.py
new file mode 100644
index 0000000..455701ec
--- /dev/null
+++ b/android_webview/tools/PRESUBMIT.py
@@ -0,0 +1,29 @@
+# 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.
+
+def CheckChangeOnUpload(input_api, output_api):
+  return _CommonChecks(input_api, output_api)
+
+def CheckChangeOnCommit(input_api, output_api):
+  return _CommonChecks(input_api, output_api)
+
+def _CommonChecks(input_api, output_api):
+  """Checks common to both upload and commit."""
+  results = []
+
+  would_affect_tests = [
+    'PRESUBMIT.py',
+    'copyright_scanner.py',
+    'copyright_scanner_unittest.py'
+  ]
+  need_to_run_unittests = False
+  for f in input_api.AffectedFiles():
+    if any(t for t in would_affect_tests if f.LocalPath().endswith(t)):
+      need_to_run_unittests = True
+      break
+  tests = [input_api.os_path.join(
+    input_api.PresubmitLocalPath(), 'copyright_scanner_unittest.py')]
+  results.extend(
+    input_api.canned_checks.RunUnitTests(input_api, output_api, tests))
+  return results
diff --git a/android_webview/tools/copyright_scanner.py b/android_webview/tools/copyright_scanner.py
index 90da30de..7e4ef0c 100644
--- a/android_webview/tools/copyright_scanner.py
+++ b/android_webview/tools/copyright_scanner.py
@@ -6,14 +6,13 @@
 """
 
 import itertools
-import os
-import re
 
 
-def FindFiles(root_dir, start_paths_list, excluded_dirs_list):
+def FindFiles(input_api, root_dir, start_paths_list, excluded_dirs_list):
   """Similar to UNIX utility find(1), searches for files in the directories.
   Automatically leaves out only source code files.
   Args:
+    input_api: InputAPI, as in presubmit scripts.
     root_dir: The root directory, to which all other paths are relative.
     start_paths_list: The list of paths to start search from. Each path can
       be a file or a directory.
@@ -28,7 +27,7 @@
         return True
     return False
 
-  files_whitelist_re = re.compile(
+  files_whitelist_re = input_api.re.compile(
     r'\.(asm|c(c|pp|xx)?|h(h|pp|xx)?|p(l|m)|xs|sh|php|py(|x)'
     '|rb|idl|java|el|sc(i|e)|cs|pas|inc|js|pac|html|dtd|xsl|mod|mm?'
     '|tex|mli?)$')
@@ -36,66 +35,75 @@
 
   base_path_len = len(root_dir)
   for path in start_paths_list:
-    full_path = os.path.join(root_dir, path)
-    if os.path.isfile(full_path):
+    full_path = input_api.os_path.join(root_dir, path)
+    if input_api.os_path.isfile(full_path):
       if files_whitelist_re.search(path):
         files.append(path)
     else:
-      for dirpath, dirnames, filenames in os.walk(full_path):
+      for dirpath, dirnames, filenames in input_api.os_walk(full_path):
         # Remove excluded subdirs for faster scanning.
         for item in dirnames[:]:
-          if IsBlacklistedDir(os.path.join(dirpath, item)[base_path_len + 1:]):
+          if IsBlacklistedDir(
+              input_api.os_path.join(dirpath, item)[base_path_len + 1:]):
             dirnames.remove(item)
         for filename in filenames:
-          filepath = os.path.join(dirpath, filename)[base_path_len + 1:]
+          filepath = \
+              input_api.os_path.join(dirpath, filename)[base_path_len + 1:]
           if files_whitelist_re.search(filepath) and \
               not IsBlacklistedDir(filepath):
             files.append(filepath)
   return files
 
 
-python_multiline_string_double_re = re.compile(
-  r'"""[^"]*(?:"""|$)', flags=re.MULTILINE)
-python_multiline_string_single_re = re.compile(
-  r"'''[^']*(?:'''|$)", flags=re.MULTILINE)
-automatically_generated_re = re.compile(
-  r'(All changes made in this file will be lost'
-  '|DO NOT (EDIT|delete this file)'
-  '|Generated (at|automatically|data)'
-  '|Automatically generated'
-  '|\Wgenerated\s+(?:\w+\s+)*file\W)', flags=re.IGNORECASE)
+class _GeneratedFilesDetector(object):
+  GENERATED_FILE = 'GENERATED FILE'
+  NO_COPYRIGHT = '*No copyright*'
 
-def _IsGeneratedFile(header):
-  header = header.upper()
-  if '"""' in header:
-    header = python_multiline_string_double_re.sub('', header)
-  if "'''" in header:
-    header = python_multiline_string_single_re.sub('', header)
-  # First do simple strings lookup to save time.
-  if 'ALL CHANGES MADE IN THIS FILE WILL BE LOST' in header:
-    return True
-  if 'DO NOT EDIT' in header or 'DO NOT DELETE' in header or \
-      'GENERATED' in header:
-    return automatically_generated_re.search(header)
-  return False
+  def __init__(self, input_api):
+    self.python_multiline_string_double_re = \
+      input_api.re.compile(r'"""[^"]*(?:"""|$)', flags=input_api.re.MULTILINE)
+    self.python_multiline_string_single_re = \
+      input_api.re.compile(r"'''[^']*(?:'''|$)", flags=input_api.re.MULTILINE)
+    self.automatically_generated_re = input_api.re.compile(
+      r'(All changes made in this file will be lost'
+      '|DO NOT (EDIT|delete this file)'
+      '|Generated (at|automatically|data)'
+      '|Automatically generated'
+      '|\Wgenerated\s+(?:\w+\s+)*file\W)', flags=input_api.re.IGNORECASE)
 
+  def IsGeneratedFile(self, header):
+    header = header.upper()
+    if '"""' in header:
+      header = self.python_multiline_string_double_re.sub('', header)
+    if "'''" in header:
+      header = self.python_multiline_string_single_re.sub('', header)
+    # First do simple strings lookup to save time.
+    if 'ALL CHANGES MADE IN THIS FILE WILL BE LOST' in header:
+      return True
+    if 'DO NOT EDIT' in header or 'DO NOT DELETE' in header or \
+        'GENERATED' in header:
+      return self.automatically_generated_re.search(header)
+    return False
 
-GENERATED_FILE = 'GENERATED FILE'
-NO_COPYRIGHT = '*No copyright*'
 
 class _CopyrightsScanner(object):
-  _c_comment_re = re.compile(r'''"[^"\\]*(?:\\.[^"\\]*)*"''')
-  _copyright_indicator = r'(?:copyright|copr\.|\xc2\xa9|\(c\))'
-  _full_copyright_indicator_re = \
-    re.compile(r'(?:\W|^)' + _copyright_indicator + r'(?::\s*|\s+)(\w.*)$', \
-                 re.IGNORECASE)
-  _copyright_disindicator_re = \
-    re.compile(r'\s*\b(?:info(?:rmation)?|notice|and|or)\b', re.IGNORECASE)
+  @staticmethod
+  def StaticInit(input_api):
+    _CopyrightsScanner._c_comment_re = \
+      input_api.re.compile(r'''"[^"\\]*(?:\\.[^"\\]*)*"''')
+    _CopyrightsScanner._copyright_indicator = \
+      r'(?:copyright|copr\.|\xc2\xa9|\(c\))'
+    _CopyrightsScanner._full_copyright_indicator_re = input_api.re.compile(
+      r'(?:\W|^)' + _CopyrightsScanner._copyright_indicator + \
+      r'(?::\s*|\s+)(\w.*)$', input_api.re.IGNORECASE)
+    _CopyrightsScanner._copyright_disindicator_re = input_api.re.compile(
+      r'\s*\b(?:info(?:rmation)?|notice|and|or)\b', input_api.re.IGNORECASE)
 
-  def __init__(self):
+  def __init__(self, input_api):
     self.max_line_numbers_proximity = 3
     self.last_a_item_line_number = -200
     self.last_b_item_line_number = -100
+    self.re = input_api.re
 
   def _CloseLineNumbers(self, a, b):
     return 0 <= a - b <= self.max_line_numbers_proximity
@@ -131,17 +139,20 @@
         not _CopyrightsScanner._copyright_disindicator_re.match(m.group(1)):
       copyr = m.group(0)
       # Prettify the authorship string.
-      copyr = re.sub(r'([,.])?\s*$/', '', copyr)
-      copyr = re.sub(self._copyright_indicator, '', copyr, flags=re.IGNORECASE)
-      copyr = re.sub(r'^\s+', '', copyr)
-      copyr = re.sub(r'\s{2,}', ' ', copyr)
-      copyr = re.sub(r'\\@', '@', copyr)
+      copyr = self.re.sub(r'([,.])?\s*$/', '', copyr)
+      copyr = self.re.sub(
+        _CopyrightsScanner._copyright_indicator, '', copyr, \
+        flags=self.re.IGNORECASE)
+      copyr = self.re.sub(r'^\s+', '', copyr)
+      copyr = self.re.sub(r'\s{2,}', ' ', copyr)
+      copyr = self.re.sub(r'\\@', '@', copyr)
     return copyr
 
 
-def FindCopyrights(root_dir, files_to_scan):
+def FindCopyrights(input_api, root_dir, files_to_scan):
   """Determines code autorship, and finds generated files.
   Args:
+    input_api: InputAPI, as in presubmit scripts.
     root_dir: The root directory, to which all other paths are relative.
     files_to_scan: The list of file names to scan.
   Returns:
@@ -150,47 +161,52 @@
     entry -- 'GENERATED_FILE' string. If the file has no copyright info,
     the corresponding list contains 'NO_COPYRIGHT' string.
   """
+  generated_files_detector = _GeneratedFilesDetector(input_api)
+  _CopyrightsScanner.StaticInit(input_api)
   copyrights = []
   for file_name in files_to_scan:
     linenum = 0
-    header = ''
+    header = []
     file_copyrights = []
-    scanner = _CopyrightsScanner()
-    with open(os.path.join(root_dir, file_name), 'r') as f:
-      for l in f.readlines():
-        linenum += 1
-        if linenum <= 25:
-          header += l
-        c = scanner.MatchLine(linenum, l)
-        if c:
-          file_copyrights.append(c)
-      if _IsGeneratedFile(header):
-        copyrights.append([GENERATED_FILE])
-      elif file_copyrights:
-        copyrights.append(file_copyrights)
-      else:
-        copyrights.append([NO_COPYRIGHT])
+    scanner = _CopyrightsScanner(input_api)
+    contents = input_api.ReadFile(
+      input_api.os_path.join(root_dir, file_name), 'r')
+    for l in contents.split('\n'):
+      linenum += 1
+      if linenum <= 25:
+        header.append(l)
+      c = scanner.MatchLine(linenum, l)
+      if c:
+        file_copyrights.append(c)
+    if generated_files_detector.IsGeneratedFile('\n'.join(header)):
+      copyrights.append([_GeneratedFilesDetector.GENERATED_FILE])
+    elif file_copyrights:
+      copyrights.append(file_copyrights)
+    else:
+      copyrights.append([_GeneratedFilesDetector.NO_COPYRIGHT])
   return copyrights
 
 
-def FindCopyrightViolations(root_dir, files_to_scan):
+def FindCopyrightViolations(input_api, root_dir, files_to_scan):
   """Looks for files that are not belong exlusively to the Chromium Authors.
   Args:
+    input_api: InputAPI, as in presubmit scripts.
     root_dir: The root directory, to which all other paths are relative.
     files_to_scan: The list of file names to scan.
   Returns:
     The list of file names that contain non-Chromium copyrights.
   """
-  copyrights = FindCopyrights(root_dir, files_to_scan)
+  copyrights = FindCopyrights(input_api, root_dir, files_to_scan)
   offending_files = []
-  allowed_copyrights_re = re.compile(
+  allowed_copyrights_re = input_api.re.compile(
     r'^(?:20[0-9][0-9](?:-20[0-9][0-9])? The Chromium Authors\. '
     'All rights reserved.*)$')
   for f, cs in itertools.izip(files_to_scan, copyrights):
-    if cs[0] == GENERATED_FILE or cs[0] == NO_COPYRIGHT:
+    if cs[0] == _GeneratedFilesDetector.GENERATED_FILE or \
+       cs[0] == _GeneratedFilesDetector.NO_COPYRIGHT:
       continue
     for c in cs:
       if not allowed_copyrights_re.match(c):
-        offending_files.append(os.path.normpath(f))
+        offending_files.append(input_api.os_path.normpath(f))
         break
   return offending_files
diff --git a/android_webview/tools/copyright_scanner_unittest.py b/android_webview/tools/copyright_scanner_unittest.py
new file mode 100755
index 0000000..df406d09
--- /dev/null
+++ b/android_webview/tools/copyright_scanner_unittest.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+# 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.
+
+"""Unit tests for Copyright Scanner utilities."""
+
+import os
+import re
+import sys
+import unittest
+
+test_dir = os.path.dirname(os.path.abspath(__file__))
+sys.path.extend([
+    os.path.normpath(os.path.join(test_dir, '..', '..', 'tools')),
+    os.path.join(test_dir),
+])
+
+import find_depot_tools
+from testing_support.super_mox import SuperMoxTestBase
+
+import copyright_scanner
+
+class FindCopyrightsTest(SuperMoxTestBase):
+  def setUp(self):
+    SuperMoxTestBase.setUp(self)
+    self.input_api = self.mox.CreateMockAnything()
+    self.input_api.re = re
+    self.input_api.os_path = os.path
+    self.input_api.os_walk = os.walk
+
+  def ShouldMatchReferenceOutput(self, test_data, expected_output):
+    for data in test_data:
+      self.input_api.ReadFile = lambda _1, _2: data
+      actual_output = copyright_scanner.FindCopyrights(self.input_api, '', [''])
+      self.assertEqual(
+        expected_output,
+        actual_output,
+        'Input """\n%s""", expected output: "%s", actual: "%s"' % \
+            (data, expected_output, actual_output));
+
+  def testCopyrightedFiles(self):
+    test_data = [
+      '// (c) 2014 Google Inc.\n//\n//  (a) One\n//\n//  (b) Two\n//\n',
+      'Copyright 2014 Google Inc.\n',
+      'Copr. 2014 Google Inc.',
+      '\xc2\xa9 2014 Google Inc.',
+      'Copyright 2014    Google  Inc.'
+    ]
+    self.ShouldMatchReferenceOutput(test_data, [['2014 Google Inc.']])
+
+  def testGeneratedFiles(self):
+    test_data = [
+      'ALL CHANGES MADE IN THIS FILE WILL BE LOST\nCopyright 2014 Google\n',
+      'GENERATED FILE. DO NOT EDIT\nCopyright 2014 Google\n',
+      'GENERATED. DO NOT DELETE THIS FILE.\nCopyright 2014 Google\n',
+      'DO NOT EDIT\nCopyright 2014 Google\n',
+      'DO NOT DELETE THIS FILE\nCopyright 2014 Google\n',
+      'All changes made in this file will be lost\nCopyright 2014 Google\n',
+      'Automatically generated file\nCopyright 2014 Google\n',
+      'Synthetically generated dummy file\nCopyright 2014 Google\n',
+      'Generated data (by gnugnu)\nCopyright 2014 Google\n'
+    ]
+    self.ShouldMatchReferenceOutput(test_data, [['GENERATED FILE']])
+
+  def testNonCopyrightedFiles(self):
+    test_data = [
+      'std::cout << "Copyright 2014 Google"\n',
+      '// Several points can be made:\n//\n//  (a) One\n//\n//  (b) Two\n'
+      '//\n//  (c) Three\n//\n',
+      'See \'foo\' for copyright information.\n',
+      'See \'foo\' for the copyright notice.\n',
+      'See \'foo\' for the copyright and other things.\n'
+    ]
+    self.ShouldMatchReferenceOutput(test_data, [['*No copyright*']])
+
+  def testNonGeneratedFiles(self):
+    test_data = [
+      'This file was prohibited from being generated.\n',
+      'Please do not delete our files! They are valuable to us.\n',
+      'Manually generated from dice rolls.\n',
+      '"""This Python script produces generated data\n"""\n',
+      '\'\'\'This Python script produces generated data\n\'\'\'\n'
+    ]
+    self.ShouldMatchReferenceOutput(test_data, [['*No copyright*']])
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/android_webview/tools/gyp_webview b/android_webview/tools/gyp_webview
index 6de0250..0d00283 100755
--- a/android_webview/tools/gyp_webview
+++ b/android_webview/tools/gyp_webview
@@ -54,6 +54,7 @@
 export GYP_DEFINES="${GYP_DEFINES} ${DEFINES}"
 
 FLAGS="-f android -Gdefault_target=libwebviewchromium -Glimit_to_target_all=1 "\
+"-Gaosp_sdk_version=21 "\
 "--depth=${CHROME_SRC} ${CHROME_SRC}/android_webview/android_webview.gyp"
 
 for host_os in linux mac; do
diff --git a/android_webview/tools/run_find_copyrights_manual_tests.sh b/android_webview/tools/run_find_copyrights_manual_tests.sh
deleted file mode 100755
index 88ef193..0000000
--- a/android_webview/tools/run_find_copyrights_manual_tests.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-# 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.
-find android_webview/tools/tests -type f | sort \
-    | android_webview/tools/webview_licenses.py display_copyrights
diff --git a/android_webview/tools/tests/copyright-01 b/android_webview/tools/tests/copyright-01
deleted file mode 100644
index 414f52c..0000000
--- a/android_webview/tools/tests/copyright-01
+++ /dev/null
@@ -1,6 +0,0 @@
-// (c) 2014 Google Inc.
-//
-//  (a) One
-//
-//  (b) Two
-//
diff --git a/android_webview/tools/tests/copyright-02 b/android_webview/tools/tests/copyright-02
deleted file mode 100644
index 2fb88252e..0000000
--- a/android_webview/tools/tests/copyright-02
+++ /dev/null
@@ -1 +0,0 @@
-Copyright 2014 Google Inc.
diff --git a/android_webview/tools/tests/copyright-03 b/android_webview/tools/tests/copyright-03
deleted file mode 100644
index 05d7d352..0000000
--- a/android_webview/tools/tests/copyright-03
+++ /dev/null
@@ -1 +0,0 @@
-Copr. 2014 Google Inc.
diff --git a/android_webview/tools/tests/copyright-04 b/android_webview/tools/tests/copyright-04
deleted file mode 100644
index cb0e164..0000000
--- a/android_webview/tools/tests/copyright-04
+++ /dev/null
@@ -1 +0,0 @@
-© 2014 Google Inc.
diff --git a/android_webview/tools/tests/copyright-05 b/android_webview/tools/tests/copyright-05
deleted file mode 100644
index c47eb57..0000000
--- a/android_webview/tools/tests/copyright-05
+++ /dev/null
@@ -1 +0,0 @@
-Copyright 2014    Google  Inc.
diff --git a/android_webview/tools/tests/generated-01 b/android_webview/tools/tests/generated-01
deleted file mode 100644
index bfc2944d..0000000
--- a/android_webview/tools/tests/generated-01
+++ /dev/null
@@ -1,2 +0,0 @@
-ALL CHANGES MADE IN THIS FILE WILL BE LOST
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/generated-02 b/android_webview/tools/tests/generated-02
deleted file mode 100644
index a5a3c1a..0000000
--- a/android_webview/tools/tests/generated-02
+++ /dev/null
@@ -1,2 +0,0 @@
-GENERATED FILE. DO NOT EDIT
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/generated-03 b/android_webview/tools/tests/generated-03
deleted file mode 100644
index be609a7..0000000
--- a/android_webview/tools/tests/generated-03
+++ /dev/null
@@ -1,2 +0,0 @@
-GENERATED. DO NOT DELETE THIS FILE.
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/generated-04 b/android_webview/tools/tests/generated-04
deleted file mode 100644
index f14a94e..0000000
--- a/android_webview/tools/tests/generated-04
+++ /dev/null
@@ -1,2 +0,0 @@
-DO NOT EDIT
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/generated-05 b/android_webview/tools/tests/generated-05
deleted file mode 100644
index 66bf448..0000000
--- a/android_webview/tools/tests/generated-05
+++ /dev/null
@@ -1,2 +0,0 @@
-DO NOT DELETE THIS FILE
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/generated-06 b/android_webview/tools/tests/generated-06
deleted file mode 100644
index 02932e38..0000000
--- a/android_webview/tools/tests/generated-06
+++ /dev/null
@@ -1,2 +0,0 @@
-All changes made in this file will be lost
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/generated-07 b/android_webview/tools/tests/generated-07
deleted file mode 100644
index 0b1ffab..0000000
--- a/android_webview/tools/tests/generated-07
+++ /dev/null
@@ -1,2 +0,0 @@
-Automatically generated file
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/generated-08 b/android_webview/tools/tests/generated-08
deleted file mode 100644
index a9d23dd..0000000
--- a/android_webview/tools/tests/generated-08
+++ /dev/null
@@ -1,2 +0,0 @@
-Synthetically generated dummy file
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/generated-09 b/android_webview/tools/tests/generated-09
deleted file mode 100644
index f79ef340..0000000
--- a/android_webview/tools/tests/generated-09
+++ /dev/null
@@ -1,2 +0,0 @@
-Generated data (by gnugnu)
-Copyright 2014 Google
diff --git a/android_webview/tools/tests/no-copyright-01 b/android_webview/tools/tests/no-copyright-01
deleted file mode 100644
index ac4787e..0000000
--- a/android_webview/tools/tests/no-copyright-01
+++ /dev/null
@@ -1 +0,0 @@
-std::cout << "Copyright 2014 Google"
diff --git a/android_webview/tools/tests/no-copyright-02 b/android_webview/tools/tests/no-copyright-02
deleted file mode 100644
index 6257f7d..0000000
--- a/android_webview/tools/tests/no-copyright-02
+++ /dev/null
@@ -1,9 +0,0 @@
-// Several points can be made:
-//
-//  (a) One
-//
-//  (b) Two
-//
-//  (c) Three
-//
-
diff --git a/android_webview/tools/tests/no-copyright-03 b/android_webview/tools/tests/no-copyright-03
deleted file mode 100644
index 289d451..0000000
--- a/android_webview/tools/tests/no-copyright-03
+++ /dev/null
@@ -1 +0,0 @@
-See 'foo' for copyright information.
diff --git a/android_webview/tools/tests/no-copyright-04 b/android_webview/tools/tests/no-copyright-04
deleted file mode 100644
index 390a71b..0000000
--- a/android_webview/tools/tests/no-copyright-04
+++ /dev/null
@@ -1 +0,0 @@
-See 'foo' for the copyright notice.
diff --git a/android_webview/tools/tests/no-copyright-05 b/android_webview/tools/tests/no-copyright-05
deleted file mode 100644
index 654d261..0000000
--- a/android_webview/tools/tests/no-copyright-05
+++ /dev/null
@@ -1 +0,0 @@
-See 'foo' for the copyright and other things.
diff --git a/android_webview/tools/tests/non-generated-01 b/android_webview/tools/tests/non-generated-01
deleted file mode 100644
index b0be44d6..0000000
--- a/android_webview/tools/tests/non-generated-01
+++ /dev/null
@@ -1 +0,0 @@
-This file was prohibited from being generated.
diff --git a/android_webview/tools/tests/non-generated-02 b/android_webview/tools/tests/non-generated-02
deleted file mode 100644
index 758b570e..0000000
--- a/android_webview/tools/tests/non-generated-02
+++ /dev/null
@@ -1 +0,0 @@
-Please do not delete our files! They are valuable to us.
diff --git a/android_webview/tools/tests/non-generated-03 b/android_webview/tools/tests/non-generated-03
deleted file mode 100644
index e93fcd4..0000000
--- a/android_webview/tools/tests/non-generated-03
+++ /dev/null
@@ -1 +0,0 @@
-Manually generated from dice rolls.
diff --git a/android_webview/tools/tests/non-generated-04 b/android_webview/tools/tests/non-generated-04
deleted file mode 100644
index 20634ec..0000000
--- a/android_webview/tools/tests/non-generated-04
+++ /dev/null
@@ -1,2 +0,0 @@
-"""This Python script produces generated data
-"""
diff --git a/android_webview/tools/tests/non-generated-05 b/android_webview/tools/tests/non-generated-05
deleted file mode 100644
index 5d00845a..0000000
--- a/android_webview/tools/tests/non-generated-05
+++ /dev/null
@@ -1,2 +0,0 @@
-'''This Python script produces generated data
-'''
diff --git a/android_webview/tools/third_party_files_whitelist.txt b/android_webview/tools/third_party_files_whitelist.txt
index 986467f3..c789230 100644
--- a/android_webview/tools/third_party_files_whitelist.txt
+++ b/android_webview/tools/third_party_files_whitelist.txt
@@ -9,6 +9,8 @@
 # so additions to this file should be rare. See
 # http://www.chromium.org/developers/adding-3rd-party-libraries.
 
+# Contains test strings that look like copyrights.
+android_webview/tools/copyright_scanner_unittest.py
 # Copyright IBM; MIT license. This third-party code is taken from ICU, the
 # license for which we already pick up from third_party/icu/.
 base/i18n/icu_string_conversions.cc
diff --git a/android_webview/tools/webview_licenses.py b/android_webview/tools/webview_licenses.py
index 8d09630..01b2715 100755
--- a/android_webview/tools/webview_licenses.py
+++ b/android_webview/tools/webview_licenses.py
@@ -44,7 +44,10 @@
 
 class InputApi(object):
   def __init__(self):
+    self.os_path = os.path
+    self.os_walk = os.walk
     self.re = re
+    self.ReadFile = _ReadFile
 
 def GetIncompatibleDirectories():
   """Gets a list of third-party directories which use licenses incompatible
@@ -99,7 +102,7 @@
 # Needs to be a top-level function for multiprocessing
 def _FindCopyrightViolations(files_to_scan_as_string):
   return copyright_scanner.FindCopyrightViolations(
-    REPOSITORY_ROOT, files_to_scan_as_string)
+    InputApi(), REPOSITORY_ROOT, files_to_scan_as_string)
 
 def _ShardList(l, shard_len):
   return [l[i:i + shard_len] for i in range(0, len(l), shard_len)]
@@ -149,7 +152,9 @@
   excluded_dirs_list.append('tools/histograms')
   # Swarming tools, doesn't exist in the snapshot
   excluded_dirs_list.append('tools/swarming_client')
-  # Arm sysroot tools, doesn't exist in the snapshot
+  # ARM sysroot, doesn't exist in the snapshot
+  excluded_dirs_list.append('chrome/installer/linux/debian_wheezy_arm-sysroot')
+  # Old location (TODO(sbc): Remove this once it no longer exists on any bots)
   excluded_dirs_list.append('arm-sysroot')
   # Data is not part of open source chromium, but are included on some bots.
   excluded_dirs_list.append('data')
@@ -157,7 +162,7 @@
   excluded_dirs_list.append('skia/tools/clusterfuzz-data')
 
   files_to_scan = copyright_scanner.FindFiles(
-    REPOSITORY_ROOT, ['.'], excluded_dirs_list)
+    InputApi(), REPOSITORY_ROOT, ['.'], excluded_dirs_list)
   sharded_files_to_scan = _ShardList(files_to_scan, 2000)
   pool = multiprocessing.Pool()
   offending_files_chunks = pool.map_async(
@@ -193,7 +198,19 @@
     return ScanResult.Ok
 
 
-def _ReadFile(path):
+def _ReadFile(full_path, mode='rU'):
+  """Reads a file from disk. This emulates presubmit InputApi.ReadFile func.
+  Args:
+    full_path: The path of the file to read.
+  Returns:
+    The contents of the file as a string.
+  """
+
+  with open(full_path, mode) as f:
+    return f.read()
+
+
+def _ReadLocalFile(path, mode='rb'):
   """Reads a file from disk.
   Args:
     path: The path of the file to read, relative to the root of the repository.
@@ -201,8 +218,7 @@
     The contents of the file as a string.
   """
 
-  with open(os.path.join(REPOSITORY_ROOT, path), 'rb') as f:
-    return f.read()
+  return _ReadFile(os.path.join(REPOSITORY_ROOT, path), mode)
 
 
 def _FindThirdPartyDirs():
@@ -262,8 +278,8 @@
         all_licenses_valid = False
 
   # Second, check for non-standard license text.
-  files_data = _ReadFile(os.path.join('android_webview', 'tools',
-                                      'third_party_files_whitelist.txt'))
+  files_data = _ReadLocalFile(os.path.join('android_webview', 'tools',
+                                           'third_party_files_whitelist.txt'))
   whitelisted_files = []
   for line in files_data.splitlines():
     match = re.match(r'([^#\s]+)', line)
@@ -284,7 +300,7 @@
   third_party_dirs = _FindThirdPartyDirs()
 
   # Don't forget Chromium's LICENSE file
-  content = [_ReadFile('LICENSE')]
+  content = [_ReadLocalFile('LICENSE')]
 
   # We provide attribution for all third-party directories.
   # TODO(steveblock): Limit this to only code used by the WebView binary.
@@ -293,7 +309,7 @@
                                  require_license_file=False)
     license_file = metadata['License File']
     if license_file and license_file != licenses.NOT_SHIPPED:
-      content.append(_ReadFile(license_file))
+      content.append(_ReadLocalFile(license_file))
 
   return '\n'.join(content)
 
@@ -344,7 +360,8 @@
     return _ProcessIncompatibleResult(GetIncompatibleDirectories())
   elif args[0] == 'display_copyrights':
     files = sys.stdin.read().splitlines()
-    for f, c in zip(files, copyright_scanner.FindCopyrights('.', files)):
+    for f, c in \
+        zip(files, copyright_scanner.FindCopyrights(InputApi(), '.', files)):
       print f, '\t', ' / '.join(sorted(c))
     return ScanResult.Ok
   parser.print_help()
diff --git a/apps/app_lifetime_monitor.h b/apps/app_lifetime_monitor.h
index dfaebef..8f079fe 100644
--- a/apps/app_lifetime_monitor.h
+++ b/apps/app_lifetime_monitor.h
@@ -49,24 +49,24 @@
   };
 
   explicit AppLifetimeMonitor(Profile* profile);
-  virtual ~AppLifetimeMonitor();
+  ~AppLifetimeMonitor() override;
 
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
  private:
   // content::NotificationObserver overrides:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // extensions::AppWindowRegistry::Observer overrides:
-  virtual void OnAppWindowRemoved(extensions::AppWindow* app_window) override;
-  virtual void OnAppWindowHidden(extensions::AppWindow* app_window) override;
-  virtual void OnAppWindowShown(extensions::AppWindow* app_window) override;
+  void OnAppWindowRemoved(extensions::AppWindow* app_window) override;
+  void OnAppWindowHidden(extensions::AppWindow* app_window) override;
+  void OnAppWindowShown(extensions::AppWindow* app_window) override;
 
   // KeyedService overrides:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   bool HasVisibleAppWindows(extensions::AppWindow* app_window) const;
 
diff --git a/apps/app_lifetime_monitor_factory.h b/apps/app_lifetime_monitor_factory.h
index 466c8ed..1df284b 100644
--- a/apps/app_lifetime_monitor_factory.h
+++ b/apps/app_lifetime_monitor_factory.h
@@ -27,14 +27,14 @@
   friend struct DefaultSingletonTraits<AppLifetimeMonitorFactory>;
 
   AppLifetimeMonitorFactory();
-  virtual ~AppLifetimeMonitorFactory();
+  ~AppLifetimeMonitorFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
-    content::BrowserContext* context) const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
+  content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
 };
 
 }  // namespace apps
diff --git a/apps/app_load_service.h b/apps/app_load_service.h
index 566672e..aa9cc98 100644
--- a/apps/app_load_service.h
+++ b/apps/app_load_service.h
@@ -44,7 +44,7 @@
   };
 
   explicit AppLoadService(Profile* profile);
-  virtual ~AppLoadService();
+  ~AppLoadService() override;
 
   // Reload the application with the given id and then send it the OnRestarted
   // event.
@@ -65,12 +65,12 @@
 
  private:
   // content::NotificationObserver.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // extensions::ExtensionRegistryObserver.
-  virtual void OnExtensionUnloaded(
+  void OnExtensionUnloaded(
       content::BrowserContext* browser_context,
       const extensions::Extension* extension,
       extensions::UnloadedExtensionInfo::Reason reason) override;
diff --git a/apps/app_load_service_factory.h b/apps/app_load_service_factory.h
index fec014cc..68fa7db8 100644
--- a/apps/app_load_service_factory.h
+++ b/apps/app_load_service_factory.h
@@ -24,14 +24,14 @@
   friend struct DefaultSingletonTraits<AppLoadServiceFactory>;
 
   AppLoadServiceFactory();
-  virtual ~AppLoadServiceFactory();
+  ~AppLoadServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  bool ServiceIsCreatedWithBrowserContext() const override;
+  bool ServiceIsNULLWhileTesting() const override;
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
 };
 
diff --git a/apps/app_restore_service.h b/apps/app_restore_service.h
index 5738b05..fec9ed7 100644
--- a/apps/app_restore_service.h
+++ b/apps/app_restore_service.h
@@ -42,16 +42,14 @@
 
  private:
   // AppLifetimeMonitor::Observer.
-  virtual void OnAppStart(Profile* profile, const std::string& app_id) override;
-  virtual void OnAppActivated(Profile* profile,
-                              const std::string& app_id) override;
-  virtual void OnAppDeactivated(Profile* profile,
-                                const std::string& app_id) override;
-  virtual void OnAppStop(Profile* profile, const std::string& app_id) override;
-  virtual void OnChromeTerminating() override;
+  void OnAppStart(Profile* profile, const std::string& app_id) override;
+  void OnAppActivated(Profile* profile, const std::string& app_id) override;
+  void OnAppDeactivated(Profile* profile, const std::string& app_id) override;
+  void OnAppStop(Profile* profile, const std::string& app_id) override;
+  void OnChromeTerminating() override;
 
   // KeyedService.
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   void RecordAppStart(const std::string& extension_id);
   void RecordAppStop(const std::string& extension_id);
diff --git a/apps/app_restore_service_factory.h b/apps/app_restore_service_factory.h
index 676d4c2c..0c5189b 100644
--- a/apps/app_restore_service_factory.h
+++ b/apps/app_restore_service_factory.h
@@ -27,12 +27,12 @@
   friend struct DefaultSingletonTraits<AppRestoreServiceFactory>;
 
   AppRestoreServiceFactory();
-  virtual ~AppRestoreServiceFactory();
+  ~AppRestoreServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
 };
 
 }  // namespace apps
diff --git a/apps/custom_launcher_page_contents.h b/apps/custom_launcher_page_contents.h
index 8465a05f..d3140e6 100644
--- a/apps/custom_launcher_page_contents.h
+++ b/apps/custom_launcher_page_contents.h
@@ -34,7 +34,7 @@
  public:
   CustomLauncherPageContents(scoped_ptr<extensions::AppDelegate> app_delegate,
                              const std::string& extension_id);
-  virtual ~CustomLauncherPageContents();
+  ~CustomLauncherPageContents() override;
 
   // Called to initialize and load the WebContents.
   void Initialize(content::BrowserContext* context, const GURL& url);
@@ -42,48 +42,43 @@
   content::WebContents* web_contents() const { return web_contents_.get(); }
 
   // content::WebContentsDelegate overrides:
-  virtual content::WebContents* OpenURLFromTab(
+  content::WebContents* OpenURLFromTab(
       content::WebContents* source,
       const content::OpenURLParams& params) override;
-  virtual void AddNewContents(content::WebContents* source,
-                              content::WebContents* new_contents,
-                              WindowOpenDisposition disposition,
-                              const gfx::Rect& initial_pos,
-                              bool user_gesture,
-                              bool* was_blocked) override;
-  virtual bool IsPopupOrPanel(
-      const content::WebContents* source) const override;
-  virtual bool ShouldSuppressDialogs() override;
-  virtual bool PreHandleGestureEvent(
-      content::WebContents* source,
-      const blink::WebGestureEvent& event) override;
-  virtual content::ColorChooser* OpenColorChooser(
+  void AddNewContents(content::WebContents* source,
+                      content::WebContents* new_contents,
+                      WindowOpenDisposition disposition,
+                      const gfx::Rect& initial_pos,
+                      bool user_gesture,
+                      bool* was_blocked) override;
+  bool IsPopupOrPanel(const content::WebContents* source) const override;
+  bool ShouldSuppressDialogs() override;
+  bool PreHandleGestureEvent(content::WebContents* source,
+                             const blink::WebGestureEvent& event) override;
+  content::ColorChooser* OpenColorChooser(
       content::WebContents* web_contents,
       SkColor color,
       const std::vector<content::ColorSuggestion>& suggestions) override;
-  virtual void RunFileChooser(
-      content::WebContents* tab,
-      const content::FileChooserParams& params) override;
-  virtual void RequestToLockMouse(content::WebContents* web_contents,
-                                  bool user_gesture,
-                                  bool last_unlocked_by_target) override;
-  virtual void RequestMediaAccessPermission(
+  void RunFileChooser(content::WebContents* tab,
+                      const content::FileChooserParams& params) override;
+  void RequestToLockMouse(content::WebContents* web_contents,
+                          bool user_gesture,
+                          bool last_unlocked_by_target) override;
+  void RequestMediaAccessPermission(
       content::WebContents* web_contents,
       const content::MediaStreamRequest& request,
       const content::MediaResponseCallback& callback) override;
-  virtual bool CheckMediaAccessPermission(
-      content::WebContents* web_contents,
-      const GURL& security_origin,
-      content::MediaStreamType type) override;
+  bool CheckMediaAccessPermission(content::WebContents* web_contents,
+                                  const GURL& security_origin,
+                                  content::MediaStreamType type) override;
 
  private:
   // content::WebContentsObserver overrides:
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // extensions::ExtensionFunctionDispatcher::Delegate overrides:
-  virtual extensions::WindowController* GetExtensionWindowController()
-      const override;
-  virtual content::WebContents* GetAssociatedWebContents() const override;
+  extensions::WindowController* GetExtensionWindowController() const override;
+  content::WebContents* GetAssociatedWebContents() const override;
 
   void OnRequest(const ExtensionHostMsg_Request_Params& params);
 
diff --git a/apps/load_and_launch_browsertest.cc b/apps/load_and_launch_browsertest.cc
index ced6564..f3573b81 100644
--- a/apps/load_and_launch_browsertest.cc
+++ b/apps/load_and_launch_browsertest.cc
@@ -109,7 +109,7 @@
  protected:
   PlatformAppLoadAndLaunchBrowserTest() {}
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     PlatformAppBrowserTest::SetUpCommandLine(command_line);
     app_path_ = test_data_dir_
         .AppendASCII("platform_apps")
diff --git a/apps/saved_files_service.h b/apps/saved_files_service.h
index d696c79..de1b1a26 100644
--- a/apps/saved_files_service.h
+++ b/apps/saved_files_service.h
@@ -60,7 +60,7 @@
                           public content::NotificationObserver {
  public:
   explicit SavedFilesService(Profile* profile);
-  virtual ~SavedFilesService();
+  ~SavedFilesService() override;
 
   static SavedFilesService* Get(Profile* profile);
 
@@ -109,9 +109,9 @@
   class SavedFiles;
 
   // content::NotificationObserver.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Returns the SavedFiles for |extension_id| or NULL if one does not exist.
   SavedFiles* Get(const std::string& extension_id) const;
diff --git a/apps/saved_files_service_factory.h b/apps/saved_files_service_factory.h
index 7d4c15c..b7f47154 100644
--- a/apps/saved_files_service_factory.h
+++ b/apps/saved_files_service_factory.h
@@ -23,10 +23,10 @@
 
  private:
   SavedFilesServiceFactory();
-  virtual ~SavedFilesServiceFactory();
+  ~SavedFilesServiceFactory() override;
   friend struct DefaultSingletonTraits<SavedFilesServiceFactory>;
 
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
 };
 
diff --git a/ash/accelerators/DEPS b/ash/accelerators/DEPS
index c34af3f7..c9f58d3 100644
--- a/ash/accelerators/DEPS
+++ b/ash/accelerators/DEPS
@@ -1,5 +1,5 @@
 specific_include_rules = {
-  "accelerator_controller\.cc": [
+  "debug_commands\.cc": [
     "+ash/host"
   ],
 }
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index dcbb39a..a5b5c6a 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -17,7 +17,6 @@
 #include "ash/display/display_manager.h"
 #include "ash/focus_cycler.h"
 #include "ash/gpu_support.h"
-#include "ash/host/ash_window_tree_host.h"
 #include "ash/ime_control_delegate.h"
 #include "ash/magnifier/magnification_controller.h"
 #include "ash/magnifier/partial_magnification_controller.h"
@@ -57,10 +56,8 @@
 #include "base/command_line.h"
 #include "base/metrics/user_metrics.h"
 #include "ui/aura/env.h"
-#include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/base/accelerators/accelerator_manager.h"
-#include "ui/compositor/debug_utils.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_sequence.h"
 #include "ui/compositor/layer_animator.h"
@@ -68,8 +65,6 @@
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/gfx/screen.h"
 #include "ui/views/controls/webview/webview.h"
-#include "ui/views/debug_utils.h"
-#include "ui/views/widget/widget.h"
 
 #if defined(OS_CHROMEOS)
 #include "ash/system/chromeos/keyboard_brightness_controller.h"
@@ -83,15 +78,6 @@
 
 using base::UserMetricsAction;
 
-bool DebugShortcutsEnabled() {
-#if defined(NDEBUG)
-  return CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kAshDebugShortcuts);
-#else
-  return true;
-#endif
-}
-
 bool HandleAccessibleFocusCycle(bool reverse) {
   if (reverse) {
     base::RecordAction(UserMetricsAction("Accel_Accessible_Focus_Previous"));
@@ -506,11 +492,6 @@
   return true;
 }
 
-bool HandleToggleRootWindowFullScreen() {
-  Shell::GetPrimaryRootWindowController()->ash_host()->ToggleFullScreen();
-  return true;
-}
-
 bool HandleWindowSnapOrDock(int action) {
   wm::WindowState* window_state = wm::GetActiveWindowState();
   // Disable window snapping shortcut key for full screen window due to
@@ -541,12 +522,6 @@
 }
 
 #if defined(OS_CHROMEOS)
-bool HandleAddRemoveDisplay() {
-  base::RecordAction(UserMetricsAction("Accel_Add_Remove_Display"));
-  Shell::GetInstance()->display_manager()->AddRemoveDisplay();
-  return true;
-}
-
 bool HandleCrosh() {
   base::RecordAction(UserMetricsAction("Accel_Open_Crosh"));
 
@@ -682,71 +657,6 @@
 
 #endif  // defined(OS_CHROMEOS)
 
-// Debug print methods.
-
-bool HandlePrintLayerHierarchy() {
-  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
-  for (size_t i = 0; i < root_windows.size(); ++i) {
-    ui::PrintLayerHierarchy(
-        root_windows[i]->layer(),
-        root_windows[i]->GetHost()->dispatcher()->GetLastMouseLocationInRoot());
-  }
-  return true;
-}
-
-bool HandlePrintViewHierarchy() {
-  aura::Window* active_window = ash::wm::GetActiveWindow();
-  if (!active_window)
-    return true;
-  views::Widget* browser_widget =
-      views::Widget::GetWidgetForNativeWindow(active_window);
-  if (!browser_widget)
-    return true;
-  views::PrintViewHierarchy(browser_widget->GetRootView());
-  return true;
-}
-
-void PrintWindowHierarchy(aura::Window* window,
-                          int indent,
-                          std::ostringstream* out) {
-  std::string indent_str(indent, ' ');
-  std::string name(window->name());
-  if (name.empty())
-    name = "\"\"";
-  *out << indent_str << name << " (" << window << ")"
-       << " type=" << window->type()
-       << (wm::IsActiveWindow(window) ? " [active] " : " ")
-       << (window->IsVisible() ? " visible " : " ")
-       << window->bounds().ToString()
-       << '\n';
-
-  for (size_t i = 0; i < window->children().size(); ++i)
-    PrintWindowHierarchy(window->children()[i], indent + 3, out);
-}
-
-bool HandlePrintWindowHierarchy() {
-  Shell::RootWindowControllerList controllers =
-      Shell::GetAllRootWindowControllers();
-  for (size_t i = 0; i < controllers.size(); ++i) {
-    std::ostringstream out;
-    out << "RootWindow " << i << ":\n";
-    PrintWindowHierarchy(controllers[i]->GetRootWindow(), 0, &out);
-    // Error so logs can be collected from end-users.
-    LOG(ERROR) << out.str();
-  }
-  return true;
-}
-
-bool HandlePrintUIHierarchies() {
-  // This is a separate command so the user only has to hit one key to generate
-  // all the logs. Developers use the individual dumps repeatedly, so keep
-  // those as separate commands to avoid spamming their logs.
-  HandlePrintLayerHierarchy();
-  HandlePrintWindowHierarchy();
-  HandlePrintViewHierarchy();
-  return true;
-}
-
 class AutoSet {
  public:
   AutoSet(ui::Accelerator* scoped, ui::Accelerator new_value)
@@ -798,14 +708,11 @@
 
   RegisterAccelerators(kAcceleratorData, kAcceleratorDataLength);
 
-#if !defined(NDEBUG)
-  RegisterAccelerators(kDesktopAcceleratorData, kDesktopAcceleratorDataLength);
-#endif
-
-  if (DebugShortcutsEnabled()) {
+  if (debug::DebugAcceleratorsEnabled()) {
     RegisterAccelerators(kDebugAcceleratorData, kDebugAcceleratorDataLength);
-    for (size_t i = 0; i < kReservedDebugActionsLength; ++i)
-      reserved_actions_.insert(kReservedDebugActions[i]);
+    // All debug accelerators are reserved.
+    for (size_t i = 0; i < kDebugAcceleratorDataLength; ++i)
+      reserved_actions_.insert(kDebugAcceleratorData[i].action);
   }
 
 #if defined(OS_CHROMEOS)
@@ -913,8 +820,6 @@
     case TOGGLE_OVERVIEW:
       return ToggleOverview(accelerator);
 #if defined(OS_CHROMEOS)
-    case ADD_REMOVE_DISPLAY:
-      return HandleAddRemoveDisplay();
     case TOGGLE_MIRROR_MODE:
       return HandleToggleMirrorMode();
     case LOCK_SCREEN:
@@ -925,7 +830,7 @@
       return HandleCrosh();
     case SILENCE_SPOKEN_FEEDBACK:
       HandleSilenceSpokenFeedback();
-      break;
+      return false;
     case SWAP_PRIMARY_DISPLAY:
       return HandleSwapPrimaryDisplay();
     case SWITCH_TO_NEXT_USER:
@@ -980,21 +885,21 @@
     case BRIGHTNESS_DOWN:
       if (brightness_control_delegate_)
         return brightness_control_delegate_->HandleBrightnessDown(accelerator);
-      break;
+      return false;
     case BRIGHTNESS_UP:
       if (brightness_control_delegate_)
         return brightness_control_delegate_->HandleBrightnessUp(accelerator);
-      break;
+      return false;
     case KEYBOARD_BRIGHTNESS_DOWN:
       if (keyboard_brightness_control_delegate_)
         return keyboard_brightness_control_delegate_->
             HandleKeyboardBrightnessDown(accelerator);
-      break;
+      return false;
     case KEYBOARD_BRIGHTNESS_UP:
       if (keyboard_brightness_control_delegate_)
         return keyboard_brightness_control_delegate_->
             HandleKeyboardBrightnessUp(accelerator);
-      break;
+      return false;
     case VOLUME_MUTE: {
       ash::VolumeControlDelegate* volume_delegate =
           shell->system_tray_delegate()->GetVolumeControlDelegate();
@@ -1033,7 +938,8 @@
     case PREVIOUS_IME:
       return HandlePreviousIme(ime_control_delegate_.get(), accelerator);
     case PRINT_UI_HIERARCHIES:
-      return HandlePrintUIHierarchies();
+      debug::PrintUIHierarchies();
+      return true;
     case SWITCH_IME:
       return HandleSwitchIme(ime_control_delegate_.get(), accelerator);
     case LAUNCH_APP_0:
@@ -1076,22 +982,6 @@
       return HandleRotateActiveWindow();
     case ROTATE_SCREEN:
       return HandleRotateScreen();
-    case TOGGLE_DESKTOP_BACKGROUND_MODE:
-      return debug::CycleDesktopBackgroundMode();
-    case TOGGLE_ROOT_WINDOW_FULL_SCREEN:
-      return HandleToggleRootWindowFullScreen();
-    case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
-      Shell::GetInstance()->display_manager()->ToggleDisplayScaleFactor();
-      return true;
-    case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
-      ash::debug::ToggleShowDebugBorders();
-      return true;
-    case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
-      ash::debug::ToggleShowFpsCounter();
-      return true;
-    case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
-      ash::debug::ToggleShowPaintRects();
-      return true;
     case MAGNIFY_SCREEN_ZOOM_IN:
       return HandleMagnifyScreen(1);
     case MAGNIFY_SCREEN_ZOOM_OUT:
@@ -1122,15 +1012,14 @@
       Shell::GetInstance()->power_button_controller()->
           OnLockButtonEvent(action == LOCK_PRESSED, base::TimeTicks());
       return true;
-    case PRINT_LAYER_HIERARCHY:
-      return HandlePrintLayerHierarchy();
-    case PRINT_VIEW_HIERARCHY:
-      return HandlePrintViewHierarchy();
-    case PRINT_WINDOW_HIERARCHY:
-      return HandlePrintWindowHierarchy();
     default:
-      NOTREACHED() << "Unhandled action " << action;
+      DCHECK(debug::DebugAcceleratorsEnabled())
+          << "Unhandled action " << action;
   }
+
+  // If |action| is a debug action, run it.
+  debug::PerformDebugAction(action);
+
   return false;
 }
 
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc
index a3e5f641..338c15f 100644
--- a/ash/accelerators/accelerator_controller_unittest.cc
+++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -977,17 +977,6 @@
   }
 #endif
 
-#if !defined(NDEBUG)
-  // ToggleDesktopBackgroundMode
-  EXPECT_TRUE(GetController()->Process(
-      ui::Accelerator(ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)));
-#if !defined(OS_LINUX)
-  // ToggleDesktopFullScreen (not implemented yet on Linux)
-  EXPECT_TRUE(GetController()->Process(
-      ui::Accelerator(ui::VKEY_F11, ui::EF_CONTROL_DOWN)));
-#endif  // OS_LINUX
-#endif  // !NDEBUG
-
 #if !defined(OS_WIN)
   // Exit
   ExitWarningHandler* ewh = GetController()->GetExitWarningHandlerForTest();
@@ -1326,11 +1315,9 @@
   std::set<AcceleratorAction> all_actions;
   for (size_t i = 0 ; i < kAcceleratorDataLength; ++i)
     all_actions.insert(kAcceleratorData[i].action);
-#if !defined(NDEBUG)
-  std::set<AcceleratorAction> all_desktop_actions;
-  for (size_t i = 0 ; i < kDesktopAcceleratorDataLength; ++i)
-    all_desktop_actions.insert(kDesktopAcceleratorData[i].action);
-#endif
+  std::set<AcceleratorAction> all_debug_actions;
+  for (size_t i = 0 ; i < kDebugAcceleratorDataLength; ++i)
+    all_debug_actions.insert(kDebugAcceleratorData[i].action);
 
   std::set<AcceleratorAction> actionsAllowedAtModalWindow;
   for (size_t k = 0 ; k < kActionsAllowedAtModalWindowLength; ++k)
@@ -1338,14 +1325,10 @@
   for (std::set<AcceleratorAction>::const_iterator it =
            actionsAllowedAtModalWindow.begin();
        it != actionsAllowedAtModalWindow.end(); ++it) {
-    EXPECT_TRUE(all_actions.find(*it) != all_actions.end()
-
-#if !defined(NDEBUG)
-                || all_desktop_actions.find(*it) != all_desktop_actions.end()
-#endif
-                )
+    EXPECT_TRUE(all_actions.find(*it) != all_actions.end() ||
+                all_debug_actions.find(*it) != all_debug_actions.end())
         << " action from kActionsAllowedAtModalWindow"
-        << " not found in kAcceleratorData or kDesktopAcceleratorData. "
+        << " not found in kAcceleratorData or kDebugAcceleratorData. "
         << "action: " << *it;
   }
   scoped_ptr<aura::Window> window(
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index 82dfc63..0bd5bea 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -179,8 +179,7 @@
 
 const size_t kAcceleratorDataLength = arraysize(kAcceleratorData);
 
-#if !defined(NDEBUG)
-const AcceleratorData kDesktopAcceleratorData[] = {
+const AcceleratorData kDebugAcceleratorData[] = {
 #if defined(OS_CHROMEOS)
   // Extra shortcut for debug build to control magnifier on linux desktop.
   { true, ui::VKEY_BRIGHTNESS_DOWN, ui::EF_CONTROL_DOWN,
@@ -191,11 +190,11 @@
   { true, ui::VKEY_POWER, ui::EF_SHIFT_DOWN, LOCK_PRESSED },
   { false, ui::VKEY_POWER, ui::EF_SHIFT_DOWN, LOCK_RELEASED },
   { true, ui::VKEY_D, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
-    ADD_REMOVE_DISPLAY },
+    DEBUG_ADD_REMOVE_DISPLAY },
   { true, ui::VKEY_M, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
     TOGGLE_MIRROR_MODE },
   { true, ui::VKEY_W, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, TOGGLE_WIFI },
-  // Extra shortcut for display swaping as alt-f4 is taken on linux desktop.
+  // Extra shortcut for display swapping as alt-f4 is taken on linux desktop.
   { true, ui::VKEY_S, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
     SWAP_PRIMARY_DISPLAY },
 #endif
@@ -204,26 +203,20 @@
     ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, ROTATE_SCREEN },
   // For testing on systems where Alt-Tab is already mapped.
   { true, ui::VKEY_W, ui::EF_ALT_DOWN, CYCLE_FORWARD_MRU },
-
-  { true, ui::VKEY_F11, ui::EF_CONTROL_DOWN, TOGGLE_ROOT_WINDOW_FULL_SCREEN },
+  { true, ui::VKEY_F11, ui::EF_CONTROL_DOWN,
+    DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN },
   { true, ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
       CYCLE_BACKWARD_MRU },
   { true, ui::VKEY_B, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-    TOGGLE_DESKTOP_BACKGROUND_MODE },
+    DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE },
   { true, ui::VKEY_F, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
     TOGGLE_FULLSCREEN },
-};
-
-const size_t kDesktopAcceleratorDataLength = arraysize(kDesktopAcceleratorData);
-#endif
-
-const AcceleratorData kDebugAcceleratorData[] = {
   { true, ui::VKEY_L, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-    PRINT_LAYER_HIERARCHY },
+    DEBUG_PRINT_LAYER_HIERARCHY },
   { true, ui::VKEY_V, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-    PRINT_VIEW_HIERARCHY },
+    DEBUG_PRINT_VIEW_HIERARCHY },
   { true, ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
-    PRINT_WINDOW_HIERARCHY },
+    DEBUG_PRINT_WINDOW_HIERARCHY },
   { true, ui::VKEY_S, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
     DEBUG_TOGGLE_DEVICE_SCALE_FACTOR },
   { true, ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
@@ -255,21 +248,12 @@
 
 const size_t kReservedActionsLength = arraysize(kReservedActions);
 
-const AcceleratorAction kReservedDebugActions[] = {
-  PRINT_LAYER_HIERARCHY,
-  PRINT_VIEW_HIERARCHY,
-  PRINT_WINDOW_HIERARCHY,
-  DEBUG_TOGGLE_DEVICE_SCALE_FACTOR,
-  DEBUG_TOGGLE_SHOW_DEBUG_BORDERS,
-  DEBUG_TOGGLE_SHOW_FPS_COUNTER,
-  DEBUG_TOGGLE_SHOW_PAINT_RECTS,
-};
-
-const size_t kReservedDebugActionsLength = arraysize(kReservedDebugActions);
-
 const AcceleratorAction kActionsAllowedAtLoginOrLockScreen[] = {
   BRIGHTNESS_DOWN,
   BRIGHTNESS_UP,
+  DEBUG_PRINT_LAYER_HIERARCHY,
+  DEBUG_PRINT_VIEW_HIERARCHY,
+  DEBUG_PRINT_WINDOW_HIERARCHY,
   DISABLE_CAPS_LOCK,
   KEYBOARD_BRIGHTNESS_DOWN,
   KEYBOARD_BRIGHTNESS_UP,
@@ -277,10 +261,7 @@
   MAGNIFY_SCREEN_ZOOM_OUT,  // Control+F6
   NEXT_IME,
   PREVIOUS_IME,
-  PRINT_LAYER_HIERARCHY,
   PRINT_UI_HIERARCHIES,
-  PRINT_VIEW_HIERARCHY,
-  PRINT_WINDOW_HIERARCHY,
   ROTATE_WINDOW,
   SHOW_SYSTEM_TRAY_BUBBLE,
   SWITCH_IME,  // Switch to another IME depending on the accelerator.
@@ -293,10 +274,10 @@
   VOLUME_MUTE,
   VOLUME_UP,
 #if defined(OS_CHROMEOS)
-  TOGGLE_TOUCH_VIEW_TESTING,
-  TOGGLE_SPOKEN_FEEDBACK,
-  ADD_REMOVE_DISPLAY,
+  DEBUG_ADD_REMOVE_DISPLAY,
   DISABLE_GPU_WATCHDOG,
+  TOGGLE_SPOKEN_FEEDBACK,
+  TOGGLE_TOUCH_VIEW_TESTING,
   TOGGLE_MIRROR_MODE,
 #endif
 #if defined(OS_CHROMEOS) && !defined(NDEBUG)
@@ -347,13 +328,11 @@
   VOLUME_MUTE,
   VOLUME_UP,
 #if defined(OS_CHROMEOS)
-  SWAP_PRIMARY_DISPLAY,
-  TOGGLE_SPOKEN_FEEDBACK,
-#if !defined(NDEBUG)
-  ADD_REMOVE_DISPLAY,
-#endif
+  DEBUG_ADD_REMOVE_DISPLAY,
   LOCK_SCREEN,
+  SWAP_PRIMARY_DISPLAY,
   TOGGLE_MIRROR_MODE,
+  TOGGLE_SPOKEN_FEEDBACK,
 #endif
 };
 
@@ -383,6 +362,9 @@
 const AcceleratorAction kActionsAllowedInAppMode[] = {
   BRIGHTNESS_DOWN,
   BRIGHTNESS_UP,
+  DEBUG_PRINT_LAYER_HIERARCHY,
+  DEBUG_PRINT_VIEW_HIERARCHY,
+  DEBUG_PRINT_WINDOW_HIERARCHY,
   DISABLE_CAPS_LOCK,
   KEYBOARD_BRIGHTNESS_DOWN,
   KEYBOARD_BRIGHTNESS_UP,
@@ -395,10 +377,7 @@
   POWER_PRESSED,
   POWER_RELEASED,
   PREVIOUS_IME,
-  PRINT_LAYER_HIERARCHY,
   PRINT_UI_HIERARCHIES,
-  PRINT_VIEW_HIERARCHY,
-  PRINT_WINDOW_HIERARCHY,
   ROTATE_SCREEN,
   SCALE_UI_DOWN,
   SCALE_UI_RESET,
@@ -411,11 +390,11 @@
   VOLUME_MUTE,
   VOLUME_UP,
 #if defined(OS_CHROMEOS)
-  SWAP_PRIMARY_DISPLAY,
-  TOGGLE_SPOKEN_FEEDBACK,
-  ADD_REMOVE_DISPLAY,
+  DEBUG_ADD_REMOVE_DISPLAY,
   DISABLE_GPU_WATCHDOG,
+  SWAP_PRIMARY_DISPLAY,
   TOGGLE_MIRROR_MODE,
+  TOGGLE_SPOKEN_FEEDBACK,
 #endif  // defined(OS_CHROMEOS)
 };
 
diff --git a/ash/accelerators/accelerator_table.h b/ash/accelerators/accelerator_table.h
index 96b31101..af30c5d 100644
--- a/ash/accelerators/accelerator_table.h
+++ b/ash/accelerators/accelerator_table.h
@@ -57,6 +57,11 @@
   BRIGHTNESS_UP,
   CYCLE_BACKWARD_MRU,
   CYCLE_FORWARD_MRU,
+  DEBUG_PRINT_LAYER_HIERARCHY,
+  DEBUG_PRINT_VIEW_HIERARCHY,
+  DEBUG_PRINT_WINDOW_HIERARCHY,
+  DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN,
+  DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE,
   DEBUG_TOGGLE_DEVICE_SCALE_FACTOR,
   DEBUG_TOGGLE_SHOW_DEBUG_BORDERS,
   DEBUG_TOGGLE_SHOW_FPS_COUNTER,
@@ -92,10 +97,7 @@
   POWER_PRESSED,
   POWER_RELEASED,
   PREVIOUS_IME,
-  PRINT_LAYER_HIERARCHY,
   PRINT_UI_HIERARCHIES,
-  PRINT_VIEW_HIERARCHY,
-  PRINT_WINDOW_HIERARCHY,
   RESTORE_TAB,
   ROTATE_SCREEN,
   ROTATE_WINDOW,
@@ -114,11 +116,9 @@
   TOGGLE_APP_LIST,
   TOGGLE_CAPS_LOCK,
   TOGGLE_CAPS_LOCK_BY_ALT_LWIN,
-  TOGGLE_DESKTOP_BACKGROUND_MODE,
   TOGGLE_FULLSCREEN,
   TOGGLE_MAXIMIZED,
   TOGGLE_OVERVIEW,
-  TOGGLE_ROOT_WINDOW_FULL_SCREEN,
   TOGGLE_SPOKEN_FEEDBACK,
   TOGGLE_TOUCH_VIEW_TESTING,
   TOGGLE_WIFI,
@@ -133,14 +133,14 @@
   WINDOW_CYCLE_SNAP_DOCK_LEFT,
   WINDOW_CYCLE_SNAP_DOCK_RIGHT,
 #if defined(OS_CHROMEOS)
-  ADD_REMOVE_DISPLAY,
-  TOGGLE_MIRROR_MODE,
+  DEBUG_ADD_REMOVE_DISPLAY,
   DISABLE_GPU_WATCHDOG,
   LOCK_SCREEN,
   OPEN_CROSH,
   OPEN_FILE_MANAGER,
   SWITCH_TO_NEXT_USER,
   SWITCH_TO_PREVIOUS_USER,
+  TOGGLE_MIRROR_MODE,
 #else
   DUMMY_FOR_RESERVED,
 #endif
@@ -157,14 +157,9 @@
 ASH_EXPORT extern const AcceleratorData kAcceleratorData[];
 ASH_EXPORT extern const size_t kAcceleratorDataLength;
 
-#if !defined(NDEBUG)
-// Accelerators useful when running on desktop. Debug build only.
-ASH_EXPORT extern const AcceleratorData kDesktopAcceleratorData[];
-ASH_EXPORT extern const size_t kDesktopAcceleratorDataLength;
-#endif
-
-// Debug accelerators enabled only when "Debugging keyboard shortcuts" flag
-// (--ash-debug-shortcuts) is enabled.
+// Debug accelerators. Debug accelerators are only enabled when the "Debugging
+// keyboard shortcuts" flag (--ash-debug-shortcuts) is enabled. Debug actions
+// are always run (similar to reserved actions).
 ASH_EXPORT extern const AcceleratorData kDebugAcceleratorData[];
 ASH_EXPORT extern const size_t kDebugAcceleratorDataLength;
 
@@ -177,12 +172,6 @@
 ASH_EXPORT extern const AcceleratorAction kReservedActions[];
 ASH_EXPORT extern const size_t kReservedActionsLength;
 
-// Actions that should be handled very early in Ash unless the current target
-// window is full-screen, these actions are only handled if
-// DebugShortcutsEnabled is true (command line switch 'ash-debug-shortcuts').
-ASH_EXPORT extern const AcceleratorAction kReservedDebugActions[];
-ASH_EXPORT extern const size_t kReservedDebugActionsLength;
-
 // Actions allowed while user is not signed in or screen is locked.
 ASH_EXPORT extern const AcceleratorAction kActionsAllowedAtLoginOrLockScreen[];
 ASH_EXPORT extern const size_t kActionsAllowedAtLoginOrLockScreenLength;
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
index beca39fc..7bd4e71 100644
--- a/ash/accelerators/debug_commands.cc
+++ b/ash/accelerators/debug_commands.cc
@@ -4,18 +4,82 @@
 
 #include "ash/accelerators/accelerator_commands.h"
 
+#include "ash/accelerators/accelerator_table.h"
+#include "ash/ash_switches.h"
+#include "ash/debug.h"
 #include "ash/desktop_background/desktop_background_controller.h"
 #include "ash/desktop_background/user_wallpaper_delegate.h"
+#include "ash/display/display_manager.h"
+#include "ash/host/ash_window_tree_host.h"
+#include "ash/root_window_controller.h"
 #include "ash/shell.h"
+#include "ash/wm/window_util.h"
+#include "base/command_line.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkPaint.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/compositor/debug_utils.h"
+#include "ui/compositor/layer.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/image/image_skia.h"
+#include "ui/views/debug_utils.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 namespace debug {
 namespace {
 
+void HandlePrintLayerHierarchy() {
+  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
+  for (size_t i = 0; i < root_windows.size(); ++i) {
+    ui::PrintLayerHierarchy(
+        root_windows[i]->layer(),
+        root_windows[i]->GetHost()->dispatcher()->GetLastMouseLocationInRoot());
+  }
+}
+
+void HandlePrintViewHierarchy() {
+  aura::Window* active_window = ash::wm::GetActiveWindow();
+  if (!active_window)
+    return;
+  views::Widget* browser_widget =
+      views::Widget::GetWidgetForNativeWindow(active_window);
+  if (!browser_widget)
+    return;
+  views::PrintViewHierarchy(browser_widget->GetRootView());
+}
+
+void PrintWindowHierarchy(aura::Window* window,
+                          int indent,
+                          std::ostringstream* out) {
+  std::string indent_str(indent, ' ');
+  std::string name(window->name());
+  if (name.empty())
+    name = "\"\"";
+  *out << indent_str << name << " (" << window << ")"
+       << " type=" << window->type()
+       << (wm::IsActiveWindow(window) ? " [active] " : " ")
+       << (window->IsVisible() ? " visible " : " ")
+       << window->bounds().ToString()
+       << '\n';
+
+  for (size_t i = 0; i < window->children().size(); ++i)
+    PrintWindowHierarchy(window->children()[i], indent + 3, out);
+}
+
+void HandlePrintWindowHierarchy() {
+  Shell::RootWindowControllerList controllers =
+      Shell::GetAllRootWindowControllers();
+  for (size_t i = 0; i < controllers.size(); ++i) {
+    std::ostringstream out;
+    out << "RootWindow " << i << ":\n";
+    PrintWindowHierarchy(controllers[i]->GetRootWindow(), 0, &out);
+    // Error so logs can be collected from end-users.
+    LOG(ERROR) << out.str();
+  }
+}
+
 gfx::ImageSkia CreateWallpaperImage(SkColor fill, SkColor rect) {
   // TODO(oshima): Consider adding a command line option to control
   // wallpaper images for testing.
@@ -32,9 +96,7 @@
   return gfx::ImageSkia(canvas.ExtractImageRep());
 }
 
-}  // namespace
-
-bool CycleDesktopBackgroundMode() {
+void HandleToggleDesktopBackgroundMode() {
   static int index = 0;
   DesktopBackgroundController* desktop_background_controller =
       Shell::GetInstance()->desktop_background_controller();
@@ -59,7 +121,64 @@
           WALLPAPER_LAYOUT_CENTER_CROPPED);
       break;
   }
-  return true;
+}
+
+}  // namespace
+
+void PrintUIHierarchies() {
+  // This is a separate command so the user only has to hit one key to generate
+  // all the logs. Developers use the individual dumps repeatedly, so keep
+  // those as separate commands to avoid spamming their logs.
+  HandlePrintLayerHierarchy();
+  HandlePrintWindowHierarchy();
+  HandlePrintViewHierarchy();
+}
+
+bool DebugAcceleratorsEnabled() {
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kAshDebugShortcuts);
+}
+
+void PerformDebugAction(int action) {
+  if (!DebugAcceleratorsEnabled())
+    return;
+
+  switch (action) {
+#if defined(OS_CHROMEOS)
+    case DEBUG_ADD_REMOVE_DISPLAY:
+      Shell::GetInstance()->display_manager()->AddRemoveDisplay();
+      break;
+#endif
+    case DEBUG_PRINT_LAYER_HIERARCHY:
+      HandlePrintLayerHierarchy();
+      break;
+    case DEBUG_PRINT_VIEW_HIERARCHY:
+      HandlePrintViewHierarchy();
+      break;
+    case DEBUG_PRINT_WINDOW_HIERARCHY:
+      HandlePrintWindowHierarchy();
+      break;
+    case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE:
+      HandleToggleDesktopBackgroundMode();
+      break;
+    case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR:
+      Shell::GetInstance()->display_manager()->ToggleDisplayScaleFactor();
+      break;
+    case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
+      Shell::GetPrimaryRootWindowController()->ash_host()->ToggleFullScreen();
+      break;
+    case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
+      ToggleShowDebugBorders();
+      break;
+    case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
+      ToggleShowFpsCounter();
+      break;
+    case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
+      ToggleShowPaintRects();
+      break;
+    default:
+      break;
+  }
 }
 
 }  // namespace debug
diff --git a/ash/accelerators/debug_commands.h b/ash/accelerators/debug_commands.h
index a064d4f5..190249c 100644
--- a/ash/accelerators/debug_commands.h
+++ b/ash/accelerators/debug_commands.h
@@ -12,9 +12,16 @@
 namespace ash {
 namespace debug {
 
-// Cycle through different wallpaper modes. This is used when running
-// on desktop for testing.
-ASH_EXPORT bool CycleDesktopBackgroundMode();
+// Print the views::View, ui::Layer and aura::Window hierarchies. This may be
+// useful in debugging user reported bugs.
+ASH_EXPORT void PrintUIHierarchies();
+
+// Returns true if debug accelerators are enabled.
+ASH_EXPORT bool DebugAcceleratorsEnabled();
+
+// Performs |action| if |action| belongs to a debug-only accelerator and
+// debug accelerators are enabled.
+ASH_EXPORT void PerformDebugAction(int action);
 
 }  // namespace debug
 }  // namespace ash
diff --git a/ash/display/display_change_observer_chromeos.cc b/ash/display/display_change_observer_chromeos.cc
index 047d903..752e2b7 100644
--- a/ash/display/display_change_observer_chromeos.cc
+++ b/ash/display/display_change_observer_chromeos.cc
@@ -7,6 +7,8 @@
 #include <algorithm>
 #include <map>
 #include <set>
+#include <string>
+#include <utility>
 #include <vector>
 
 #include "ash/ash_switches.h"
@@ -287,9 +289,12 @@
   return 1.0f;
 }
 
-void DisplayChangeObserver::OnInputDeviceConfigurationChanged() {
+void DisplayChangeObserver::OnTouchscreenDeviceConfigurationChanged() {
   OnDisplayModeChanged(
       Shell::GetInstance()->display_configurator()->cached_displays());
 }
 
+void DisplayChangeObserver::OnKeyboardDeviceConfigurationChanged() {
+}
+
 }  // namespace ash
diff --git a/ash/display/display_change_observer_chromeos.h b/ash/display/display_change_observer_chromeos.h
index 905db78..8e18256 100644
--- a/ash/display/display_change_observer_chromeos.h
+++ b/ash/display/display_change_observer_chromeos.h
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_DISPLAY_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H
-#define ASH_DISPLAY_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H
+#ifndef ASH_DISPLAY_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H_
+#define ASH_DISPLAY_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H_
+
+#include <vector>
 
 #include "ash/ash_export.h"
 #include "ash/shell_observer.h"
@@ -46,7 +48,8 @@
       const ui::DisplayConfigurator::DisplayStateList& outputs) override;
 
   // Overriden from ui::InputDeviceEventObserver:
-  virtual void OnInputDeviceConfigurationChanged() override;
+  virtual void OnTouchscreenDeviceConfigurationChanged() override;
+  virtual void OnKeyboardDeviceConfigurationChanged() override;
 
   // Overriden from ShellObserver:
   virtual void OnAppTerminating() override;
@@ -60,4 +63,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_DISPLAY_AURA_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H
+#endif  // ASH_DISPLAY_DISPLAY_CHANGE_OBSERVER_CHROMEOS_H_
diff --git a/ash/display/display_info.cc b/ash/display/display_info.cc
index 16a31f24..866f49d 100644
--- a/ash/display/display_info.cc
+++ b/ash/display/display_info.cc
@@ -149,9 +149,7 @@
   float device_scale_factor = 1.0f;
   if (!GetDisplayBounds(main_spec, &bounds_in_native, &device_scale_factor)) {
 #if defined(OS_WIN)
-    if (gfx::IsHighDPIEnabled()) {
-      device_scale_factor = gfx::GetDPIScale();
-    }
+    device_scale_factor = gfx::GetDPIScale();
 #endif
   }
 
diff --git a/ash/display/display_info.h b/ash/display/display_info.h
index 5598273d..6071a9d 100644
--- a/ash/display/display_info.h
+++ b/ash/display/display_info.h
@@ -111,8 +111,8 @@
   }
   gfx::Display::TouchSupport touch_support() const { return touch_support_; }
 
-  void set_touch_device_id(int id) { touch_device_id_ = id; }
-  int touch_device_id() const { return touch_device_id_; }
+  void set_touch_device_id(unsigned int id) { touch_device_id_ = id; }
+  unsigned int touch_device_id() const { return touch_device_id_; }
 
   // Gets/Sets the device scale factor of the display.
   float device_scale_factor() const { return device_scale_factor_; }
@@ -228,7 +228,7 @@
 
   // If the display is also a touch device, it will have a positive
   // |touch_device_id_|. Otherwise |touch_device_id_| is 0.
-  int touch_device_id_;
+  unsigned int touch_device_id_;
 
   // This specifies the device's pixel density. (For example, a
   // display whose DPI is higher than the threshold is considered to have
diff --git a/ash/display/screen_ash.cc b/ash/display/screen_ash.cc
index 125ef82..8c72e1d 100644
--- a/ash/display/screen_ash.cc
+++ b/ash/display/screen_ash.cc
@@ -71,9 +71,6 @@
   }
 
   // gfx::Screen overrides:
-  virtual bool IsDIPEnabled() override {
-    return true;
-  }
   virtual gfx::Point GetCursorScreenPoint() override {
     return gfx::Point();
   }
@@ -204,10 +201,6 @@
       gfx::DisplayObserver, observers_, OnDisplayRemoved(display));
 }
 
-bool ScreenAsh::IsDIPEnabled() {
-  return true;
-}
-
 gfx::Point ScreenAsh::GetCursorScreenPoint() {
   return aura::Env::GetInstance()->last_mouse_location();
 }
diff --git a/ash/display/screen_ash.h b/ash/display/screen_ash.h
index 8b0cb2c..22af08f 100644
--- a/ash/display/screen_ash.h
+++ b/ash/display/screen_ash.h
@@ -61,7 +61,6 @@
   static const gfx::Display& GetDisplayForId(int64 display_id);
 
   // gfx::Screen overrides:
-  virtual bool IsDIPEnabled() override;
   virtual gfx::Point GetCursorScreenPoint() override;
   virtual gfx::NativeWindow GetWindowUnderCursor() override;
   virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point)
diff --git a/ash/ime/OWNERS b/ash/ime/OWNERS
index cb42d0b..931e51cd 100644
--- a/ash/ime/OWNERS
+++ b/ash/ime/OWNERS
@@ -2,6 +2,7 @@
 mukai@chromium.org
 
 # backup reviewers
+shuchen@chromium.org
 komatsu@chromium.org
 nona@chromium.org
 yukishiino@chromium.org
diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc
index a649f30..144b605 100644
--- a/ash/magnifier/magnification_controller.cc
+++ b/ash/magnifier/magnification_controller.cc
@@ -15,10 +15,13 @@
 #include "ash/system/tray/system_tray_delegate.h"
 #include "base/command_line.h"
 #include "base/synchronization/waitable_event.h"
+#include "ui/aura/client/aura_constants.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/aura/window.h"
-#include "ui/aura/window_property.h"
 #include "ui/aura/window_tree_host.h"
+#include "ui/base/ime/input_method.h"
+#include "ui/base/ime/input_method_observer.h"
+#include "ui/base/ime/text_input_client.h"
 #include "ui/compositor/dip_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_observer.h"
@@ -31,6 +34,7 @@
 #include "ui/gfx/rect_conversions.h"
 #include "ui/gfx/screen.h"
 #include "ui/wm/core/compound_event_filter.h"
+#include "ui/wm/core/coordinate_conversion.h"
 
 namespace {
 
@@ -46,6 +50,10 @@
 // |kPanningMergin| from the edge, the view-port moves.
 const int kPanningMergin = 100;
 
+// Gives a little panning margin for following caret, so that we will move the
+// view-port before the caret is completely out of sight.
+const int kCaretPanningMargin = 10;
+
 void MoveCursorTo(aura::WindowTreeHost* host, const gfx::Point& root_location) {
   gfx::Point3F host_location_3f(root_location);
   host->GetRootTransform().TransformPoint(&host_location_3f);
@@ -63,7 +71,8 @@
 class MagnificationControllerImpl : virtual public MagnificationController,
                                     public ui::EventHandler,
                                     public ui::ImplicitAnimationObserver,
-                                    public aura::WindowObserver {
+                                    public aura::WindowObserver,
+                                    public ui::InputMethodObserver {
  public:
   MagnificationControllerImpl();
   virtual ~MagnificationControllerImpl();
@@ -144,6 +153,29 @@
   virtual void OnScrollEvent(ui::ScrollEvent* event) override;
   virtual void OnTouchEvent(ui::TouchEvent* event) override;
 
+  // Moves the view port when |point| is located within
+  // |x_panning_margin| and |y_pannin_margin| to the edge of the visible
+  // window region. The view port will be moved so that the |point| will be
+  // moved to the point where it has |x_target_margin| and |y_target_margin|
+  // to the edge of the visible region.
+  void MoveMagnifierWindow(const gfx::Point& point,
+                           int x_panning_margin,
+                           int y_panning_margin,
+                           int x_target_margin,
+                           int y_target_margin);
+
+  // ui::InputMethodObserver:
+  virtual void OnTextInputTypeChanged(
+      const ui::TextInputClient* client) override {}
+  virtual void OnFocus() override {}
+  virtual void OnBlur() override {}
+  virtual void OnTextInputStateChanged(
+      const ui::TextInputClient* client) override {}
+  virtual void OnInputMethodDestroyed(
+      const ui::InputMethod* input_method) override {}
+  virtual void OnShowImeIfNeeded() override {}
+  virtual void OnCaretBoundsChanged(const ui::TextInputClient* client) override;
+
   // Target root window. This must not be NULL.
   aura::Window* root_window_;
 
@@ -169,6 +201,8 @@
 
   ScrollDirection scroll_direction_;
 
+  ui::InputMethod* input_method_;  // Not owned.
+
   DISALLOW_COPY_AND_ASSIGN(MagnificationControllerImpl);
 };
 
@@ -181,13 +215,17 @@
       is_enabled_(false),
       move_cursor_after_animation_(false),
       scale_(kNonMagnifiedScale),
-      scroll_direction_(SCROLL_NONE) {
+      scroll_direction_(SCROLL_NONE),
+      input_method_(NULL) {
   Shell::GetInstance()->AddPreTargetHandler(this);
   root_window_->AddObserver(this);
   point_of_interest_ = root_window_->bounds().CenterPoint();
 }
 
 MagnificationControllerImpl::~MagnificationControllerImpl() {
+  if (input_method_)
+    input_method_->RemoveObserver(this);
+
   root_window_->RemoveObserver(this);
 
   Shell::GetInstance()->RemovePreTargetHandler(this);
@@ -317,55 +355,8 @@
   DCHECK(root_window_);
 
   gfx::Point mouse(location);
-
-  int x = origin_.x();
-  int y = origin_.y();
-  bool start_zoom = false;
-
-  const gfx::Rect window_rect = gfx::ToEnclosingRect(GetWindowRectDIP(scale_));
-  const int left = window_rect.x();
-  const int right = window_rect.right();
   int margin = kPanningMergin / scale_;  // No need to consider DPI.
-
-  int x_diff = 0;
-
-  if (mouse.x() < left + margin) {
-    // Panning left.
-    x_diff = mouse.x() - (left + margin);
-    start_zoom = true;
-  } else if (right - margin < mouse.x()) {
-    // Panning right.
-    x_diff = mouse.x() - (right - margin);
-    start_zoom = true;
-  }
-  x = left + x_diff;
-
-  const int top = window_rect.y();
-  const int bottom = window_rect.bottom();
-
-  int y_diff = 0;
-  if (mouse.y() < top + margin) {
-    // Panning up.
-    y_diff = mouse.y() - (top + margin);
-    start_zoom = true;
-  } else if (bottom - margin < mouse.y()) {
-    // Panning down.
-    y_diff = mouse.y() - (bottom - margin);
-    start_zoom = true;
-  }
-  y = top + y_diff;
-
-  if (start_zoom && !is_on_animation_) {
-    // No animation on panning.
-    bool animate = false;
-    bool ret = RedrawDIP(gfx::Point(x, y), scale_, animate);
-
-    if (ret) {
-      // If the magnified region is moved, hides the mouse cursor and moves it.
-      if (x_diff != 0 || y_diff != 0)
-        MoveCursorTo(root_window_->GetHost(), mouse);
-    }
-  }
+  MoveMagnifierWindow(mouse, margin, margin, margin, margin);
 }
 
 void MagnificationControllerImpl::AfterAnimationMoveCursorTo(
@@ -517,6 +508,13 @@
 void MagnificationControllerImpl::SetEnabled(bool enabled) {
   Shell* shell = Shell::GetInstance();
   if (enabled) {
+    if (!input_method_) {
+      input_method_ =
+          root_window_->GetProperty(aura::client::kRootWindowInputMethodKey);
+      if (input_method_)
+        input_method_->AddObserver(this);
+    }
+
     float scale =
         Shell::GetInstance()->accessibility_delegate()->
         GetSavedScreenMagnifierScale();
@@ -536,6 +534,11 @@
     if (!is_enabled_)
       return;
 
+    if (input_method_) {
+      input_method_->RemoveObserver(this);
+      input_method_ = NULL;
+    }
+
     RedrawKeepingMousePosition(kNonMagnifiedScale, true);
     is_enabled_ = enabled;
   }
@@ -597,6 +600,87 @@
   }
 }
 
+void MagnificationControllerImpl::MoveMagnifierWindow(const gfx::Point& point,
+                                                      int x_panning_margin,
+                                                      int y_panning_margin,
+                                                      int x_target_margin,
+                                                      int y_target_margin) {
+  DCHECK(root_window_);
+  int x = origin_.x();
+  int y = origin_.y();
+  bool start_zoom = false;
+
+  const gfx::Rect window_rect = gfx::ToEnclosingRect(GetWindowRectDIP(scale_));
+  const int left = window_rect.x();
+  const int right = window_rect.right();
+
+  int x_diff = 0;
+  if (point.x() < left + x_panning_margin) {
+    // Panning left.
+    x_diff = point.x() - (left + x_target_margin);
+    start_zoom = true;
+  } else if (right - x_panning_margin < point.x()) {
+    // Panning right.
+    x_diff = point.x() - (right - x_target_margin);
+    start_zoom = true;
+  }
+  x = left + x_diff;
+
+  const int top = window_rect.y();
+  const int bottom = window_rect.bottom();
+
+  int y_diff = 0;
+  if (point.y() < top + y_panning_margin) {
+    // Panning up.
+    y_diff = point.y() - (top + y_target_margin);
+    start_zoom = true;
+  } else if (bottom - y_panning_margin < point.y()) {
+    // Panning down.
+    y_diff = point.y() - (bottom - y_target_margin);
+    start_zoom = true;
+  }
+  y = top + y_diff;
+  if (start_zoom && !is_on_animation_) {
+    // No animation on panning.
+    bool animate = false;
+    bool ret = RedrawDIP(gfx::Point(x, y), scale_, animate);
+
+    if (ret) {
+      // If the magnified region is moved, hides the mouse cursor and moves it.
+      if (x_diff != 0 || y_diff != 0)
+        MoveCursorTo(root_window_->GetHost(), point);
+    }
+  }
+}
+
+void MagnificationControllerImpl::OnCaretBoundsChanged(
+    const ui::TextInputClient* client) {
+  // caret bounds in screen coordinates.
+  const gfx::Rect caret_bounds = client->GetCaretBounds();
+  // Note: OnCaretBoundsChanged could be fired OnTextInputTypeChanged during
+  // which the caret position is not set a meaning position, and we do not
+  // need to adjust the view port position based on the bogus caret position.
+  // This is only a transition period, the caret position will be fixed upon
+  // focusing right after.
+  if (caret_bounds.width() == 0 && caret_bounds.height() == 0)
+    return;
+
+  gfx::Point caret_origin = caret_bounds.origin();
+  // caret_origin in |root_window_| coordinates.
+  wm::ConvertPointFromScreen(root_window_, &caret_origin);
+
+  // Visible window_rect in |root_window_| coordinates.
+  const gfx::Rect visible_window_rect =
+      gfx::ToEnclosingRect(GetWindowRectDIP(scale_));
+
+  const int panning_margin = kCaretPanningMargin / scale_;
+  MoveMagnifierWindow(caret_origin,
+                      panning_margin,
+                      panning_margin,
+                      visible_window_rect.width() / 2,
+                      visible_window_rect.height() / 2);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // MagnificationController:
 
diff --git a/ash/magnifier/magnification_controller_unittest.cc b/ash/magnifier/magnification_controller_unittest.cc
index ca63aeb..7aad7973 100644
--- a/ash/magnifier/magnification_controller_unittest.cc
+++ b/ash/magnifier/magnification_controller_unittest.cc
@@ -12,9 +12,15 @@
 #include "ui/aura/env.h"
 #include "ui/aura/test/aura_test_utils.h"
 #include "ui/aura/window_tree_host.h"
+#include "ui/base/ime/input_method.h"
 #include "ui/events/test/event_generator.h"
 #include "ui/gfx/rect_conversions.h"
 #include "ui/gfx/screen.h"
+#include "ui/views/controls/textfield/textfield.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_delegate.h"
+#include "ui/wm/core/coordinate_conversion.h"
 
 namespace ash {
 namespace {
@@ -22,11 +28,39 @@
 const int kRootHeight = 600;
 const int kRootWidth = 800;
 
+const int kTextInputWindowWidth = 50;
+const int kTextInputWindowHeight = 50;
+
+class TextInputView : public views::WidgetDelegateView {
+ public:
+  TextInputView() : text_field_(new views::Textfield) {
+    text_field_->SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT);
+    AddChildView(text_field_);
+    SetLayoutManager(new views::FillLayout);
+  }
+
+  virtual ~TextInputView() {}
+
+  virtual gfx::Size GetPreferredSize() const override {
+    return gfx::Size(kTextInputWindowWidth, kTextInputWindowHeight);
+  }
+
+  // Overridden from views::WidgetDelegate:
+  virtual views::View* GetContentsView() override { return this; }
+
+  void FocusOnTextInput() { GetFocusManager()->SetFocusedView(text_field_); }
+
+ private:
+  views::Textfield* text_field_;  // owned by views hierarchy
+
+  DISALLOW_COPY_AND_ASSIGN(TextInputView);
+};
+
 }  // namespace
 
 class MagnificationControllerTest: public test::AshTestBase {
  public:
-  MagnificationControllerTest() {}
+  MagnificationControllerTest() : text_input_view_(NULL) {}
   virtual ~MagnificationControllerTest() {}
 
   virtual void SetUp() override {
@@ -75,7 +109,51 @@
         GetPointOfInterestForTesting().ToString();
   }
 
+  void CreateAndShowTextInputView(const gfx::Rect& bounds) {
+    text_input_view_ = new TextInputView;
+    views::Widget* widget = views::Widget::CreateWindowWithContextAndBounds(
+        text_input_view_, GetRootWindow(), bounds);
+    widget->Show();
+  }
+
+  // Returns the text input view's bounds in root window coordinates.
+  gfx::Rect GetTextInputViewBounds() {
+    DCHECK(text_input_view_);
+    gfx::Rect bounds = text_input_view_->bounds();
+    gfx::Point origin = bounds.origin();
+    // Convert origin to screen coordinates.
+    views::View::ConvertPointToScreen(text_input_view_, &origin);
+    // Convert origin to root_window_ coordinates.
+    wm::ConvertPointFromScreen(GetRootWindow(), &origin);
+    return gfx::Rect(origin.x(), origin.y(), bounds.width(), bounds.height());
+  }
+
+  // Returns the caret bounds in root window coordinates.
+  gfx::Rect GetCaretBounds() {
+    gfx::Rect caret_bounds =
+        GetInputMethod()->GetTextInputClient()->GetCaretBounds();
+    gfx::Point origin = caret_bounds.origin();
+    wm::ConvertPointFromScreen(GetRootWindow(), &origin);
+    return gfx::Rect(
+        origin.x(), origin.y(), caret_bounds.width(), caret_bounds.height());
+  }
+
+  void FocusOnTextInputView() {
+    DCHECK(text_input_view_);
+    text_input_view_->FocusOnTextInput();
+  }
+
  private:
+  TextInputView* text_input_view_;
+
+  ui::InputMethod* GetInputMethod() {
+    DCHECK(text_input_view_);
+    return text_input_view_->GetWidget()
+        ->GetNativeWindow()
+        ->GetRootWindow()
+        ->GetProperty(aura::client::kRootWindowInputMethodKey);
+  }
+
   DISALLOW_COPY_AND_ASSIGN(MagnificationControllerTest);
 };
 
@@ -440,4 +518,70 @@
   EXPECT_EQ("100,300", GetHostMouseLocation());
 }
 
+TEST_F(MagnificationControllerTest, FollowTextInputFieldFocus) {
+  CreateAndShowTextInputView(gfx::Rect(500, 300, 80, 80));
+  gfx::Rect text_input_bounds = GetTextInputViewBounds();
+
+  // Enables magnifier and confirm the viewport is at center.
+  GetMagnificationController()->SetEnabled(true);
+  EXPECT_EQ(2.0f, GetMagnificationController()->GetScale());
+  EXPECT_EQ("200,150 400x300", GetViewport().ToString());
+
+  // Move the viewport to (0, 0), so that text input field will be out of
+  // the viewport region.
+  GetMagnificationController()->MoveWindow(0, 0, false);
+  EXPECT_EQ("0,0 400x300", GetViewport().ToString());
+  EXPECT_FALSE(GetViewport().Intersects(text_input_bounds));
+
+  // Focus on the text input field.
+  FocusOnTextInputView();
+
+  // Verify the view port has been moved to the place where the text field is
+  // contained in the view port and the caret is at the center of the view port.
+  gfx::Rect view_port = GetViewport();
+  EXPECT_TRUE(view_port.Contains(text_input_bounds));
+  gfx::Rect caret_bounds = GetCaretBounds();
+  EXPECT_TRUE(text_input_bounds.Contains(caret_bounds));
+  EXPECT_EQ(caret_bounds.origin(), view_port.CenterPoint());
+}
+
+TEST_F(MagnificationControllerTest, FollowTextInputFieldKeyPress) {
+  CreateAndShowTextInputView(gfx::Rect(385, 200, 80, 80));
+  gfx::Rect text_input_bounds = GetTextInputViewBounds();
+
+  // Enables magnifier and confirm the viewport is at center.
+  GetMagnificationController()->SetEnabled(true);
+  EXPECT_EQ(2.0f, GetMagnificationController()->GetScale());
+  EXPECT_EQ("200,150 400x300", GetViewport().ToString());
+
+  // Move the viewport to (0, 0), so that text input field intersects the
+  // view port at the right edge.
+  GetMagnificationController()->MoveWindow(0, 0, false);
+  EXPECT_EQ("0,0 400x300", GetViewport().ToString());
+  EXPECT_TRUE(GetViewport().Intersects(text_input_bounds));
+
+  // Focus on the text input field.
+  FocusOnTextInputView();
+
+  // Verify the view port is not moved, and the caret is inside the view port.
+  gfx::Rect view_port = GetViewport();
+  EXPECT_EQ("0,0 400x300", view_port.ToString());
+  EXPECT_TRUE(view_port.Intersects(text_input_bounds));
+  EXPECT_TRUE(text_input_bounds.Contains(GetCaretBounds()));
+
+  // Press keys on text input simulate typing on text field and the caret
+  // moves out of the old view port region. The view port is moved to the place
+  // where caret's x coordinate is centered at the new view port.
+  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+  generator.PressKey(ui::VKEY_A, 0);
+  generator.ReleaseKey(ui::VKEY_A, 0);
+  gfx::Rect caret_bounds = GetCaretBounds();
+  EXPECT_FALSE(view_port.Intersects(caret_bounds));
+
+  gfx::Rect new_view_port = GetViewport();
+  EXPECT_TRUE(new_view_port.Contains(caret_bounds));
+  EXPECT_EQ(caret_bounds.x(), new_view_port.CenterPoint().x());
+  EXPECT_EQ(view_port.y(), new_view_port.y());
+}
+
 }  // namespace ash
diff --git a/ash/system/chromeos/network/network_connect.cc b/ash/system/chromeos/network/network_connect.cc
index f8ad6719..1647546 100644
--- a/ash/system/chromeos/network/network_connect.cc
+++ b/ash/system/chromeos/network/network_connect.cc
@@ -205,10 +205,11 @@
 // networks or repeat connect attempts).
 void CallConnectToNetwork(const std::string& service_path,
                           bool check_error_state) {
-  if (!ash::Shell::HasInstance())
-    return;
-  message_center::MessageCenter::Get()->RemoveNotification(
-      network_connect::kNetworkConnectNotificationId, false /* not by user */);
+  if (message_center::MessageCenter::Get()) {
+    message_center::MessageCenter::Get()->RemoveNotification(
+        network_connect::kNetworkConnectNotificationId,
+        false /* not by user */);
+  }
 
   NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
       service_path,
diff --git a/ash/touch/touch_transformer_controller.cc b/ash/touch/touch_transformer_controller.cc
index 8ff8ad5c3..0cf36f3b 100644
--- a/ash/touch/touch_transformer_controller.cc
+++ b/ash/touch/touch_transformer_controller.cc
@@ -35,7 +35,7 @@
 // sqrt of (display_area / touchscreen_area)
 double TouchTransformerController::GetTouchResolutionScale(
     const DisplayInfo& touch_display) const {
-  if (touch_display.touch_device_id() == 0)
+  if (touch_display.touch_device_id() == 0u)
     return 1.0;
 
   double min_x, max_x;
@@ -77,8 +77,7 @@
 TouchTransformerController::GetExtendedModeTouchTransformer(
     const DisplayInfo& touch_display, const gfx::Size& fb_size) const {
   gfx::Transform ctm;
-  if (touch_display.touch_device_id() == 0 ||
-      fb_size.width() == 0.0 ||
+  if (touch_display.touch_device_id() == 0u || fb_size.width() == 0.0 ||
       fb_size.height() == 0.0)
     return ctm;
   float width = touch_display.bounds_in_native().width();
@@ -92,7 +91,7 @@
   if (force_compute_mirror_mode_touch_transformer_)
     return true;
 
-  if (touch_display.touch_device_id() == 0)
+  if (touch_display.touch_device_id() == 0u)
     return false;
 
   if (touch_display.size_in_pixel() == touch_display.GetNativeModeSize() ||
diff --git a/ash/touch/touch_transformer_controller_unittest.cc b/ash/touch/touch_transformer_controller_unittest.cc
index cff2c53..bd8f4548 100644
--- a/ash/touch/touch_transformer_controller_unittest.cc
+++ b/ash/touch/touch_transformer_controller_unittest.cc
@@ -15,7 +15,7 @@
 
 namespace {
 DisplayInfo CreateDisplayInfo(int64 id,
-                              int touch_device_id,
+                              unsigned int touch_device_id,
                               const gfx::Rect& bounds) {
   DisplayInfo info(id, std::string(), false);
   info.SetBounds(bounds);
@@ -31,7 +31,7 @@
   // mirror mode it is configured as 1920x1200. This is in letterboxing
   // mode.
   DisplayInfo internal_display_info =
-      CreateDisplayInfo(1, 10, gfx::Rect(0, 0, 1920, 1200));
+      CreateDisplayInfo(1, 10u, gfx::Rect(0, 0, 1920, 1200));
   std::vector<DisplayMode> internal_modes;
   internal_modes.push_back(
       DisplayMode(gfx::Size(2560, 1700), 60, false, true));
@@ -40,7 +40,7 @@
   internal_display_info.set_display_modes(internal_modes);
 
   DisplayInfo external_display_info =
-      CreateDisplayInfo(2, 11, gfx::Rect(0, 0, 1920, 1200));
+      CreateDisplayInfo(2, 11u, gfx::Rect(0, 0, 1920, 1200));
 
   TouchTransformerController* tt_controller =
       Shell::GetInstance()->touch_transformer_controller();
@@ -154,8 +154,9 @@
   // where 2428 = 768 + 60 (hidden gap) + 1600
   // and the sceond monitor is translated to Point (0, 828) in the
   // framebuffer.
-  DisplayInfo display1 = CreateDisplayInfo(1, 5, gfx::Rect(0, 0, 1366, 768));
-  DisplayInfo display2 = CreateDisplayInfo(2, 6, gfx::Rect(0, 828, 2560, 1600));
+  DisplayInfo display1 = CreateDisplayInfo(1, 5u, gfx::Rect(0, 0, 1366, 768));
+  DisplayInfo display2 =
+      CreateDisplayInfo(2, 6u, gfx::Rect(0, 828, 2560, 1600));
   gfx::Size fb_size(2560, 2428);
 
   TouchTransformerController* tt_controller =
@@ -205,7 +206,7 @@
 }
 
 TEST_F(TouchTransformerControllerTest, TouchRadiusScale) {
-  DisplayInfo display = CreateDisplayInfo(1, 5, gfx::Rect(0, 0, 2560, 1600));
+  DisplayInfo display = CreateDisplayInfo(1, 5u, gfx::Rect(0, 0, 2560, 1600));
   std::vector<unsigned int> devices;
   devices.push_back(5);
   ui::SetUpTouchDevicesForTest(devices);
diff --git a/ash/touch/touchscreen_util.cc b/ash/touch/touchscreen_util.cc
index b7f0b99..898c924 100644
--- a/ash/touch/touchscreen_util.cc
+++ b/ash/touch/touchscreen_util.cc
@@ -7,6 +7,7 @@
 #include <set>
 
 #include "base/logging.h"
+#include "ui/events/input_device.h"
 
 namespace ash {
 
@@ -15,7 +16,7 @@
   std::set<int> no_match_touchscreen;
   int internal_touchscreen = -1;
   for (size_t i = 0; i < devices.size(); ++i) {
-    if (devices[i].is_internal) {
+    if (devices[i].type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL) {
       internal_touchscreen = i;
       break;
     }
diff --git a/ash/touch/touchscreen_util_unittest.cc b/ash/touch/touchscreen_util_unittest.cc
index fd88fc1a..3ac903f 100644
--- a/ash/touch/touchscreen_util_unittest.cc
+++ b/ash/touch/touchscreen_util_unittest.cc
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string>
 #include <vector>
 
 #include "ash/display/display_info.h"
 #include "ash/touch/touchscreen_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/input_device.h"
 
 namespace ash {
 
@@ -76,65 +78,77 @@
 
 TEST_F(TouchscreenUtilTest, OneToOneMapping) {
   std::vector<ui::TouchscreenDevice> devices;
-  devices.push_back(ui::TouchscreenDevice(1, gfx::Size(800, 600), false));
-  devices.push_back(ui::TouchscreenDevice(2, gfx::Size(1024, 768), false));
+  devices.push_back(ui::TouchscreenDevice(
+      1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", gfx::Size(800, 600)));
+  devices.push_back(ui::TouchscreenDevice(
+      2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", gfx::Size(1024, 768)));
 
   AssociateTouchscreens(&displays_, devices);
 
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[0].touch_device_id());
-  EXPECT_EQ(1, displays_[1].touch_device_id());
+  EXPECT_EQ(1u, displays_[1].touch_device_id());
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id());
-  EXPECT_EQ(2, displays_[3].touch_device_id());
+  EXPECT_EQ(2u, displays_[3].touch_device_id());
 }
 
 TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) {
   std::vector<ui::TouchscreenDevice> devices;
-  devices.push_back(ui::TouchscreenDevice(2, gfx::Size(1024, 768), false));
+  devices.push_back(ui::TouchscreenDevice(
+      2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", gfx::Size(1024, 768)));
 
   AssociateTouchscreens(&displays_, devices);
 
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[0].touch_device_id());
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[1].touch_device_id());
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id());
-  EXPECT_EQ(2, displays_[3].touch_device_id());
+  EXPECT_EQ(2u, displays_[3].touch_device_id());
 }
 
 TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) {
   std::vector<ui::TouchscreenDevice> devices;
-  devices.push_back(ui::TouchscreenDevice(1, gfx::Size(801, 600), false));
-  devices.push_back(ui::TouchscreenDevice(2, gfx::Size(1023, 768), false));
+  devices.push_back(ui::TouchscreenDevice(
+      1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", gfx::Size(801, 600)));
+  devices.push_back(ui::TouchscreenDevice(
+      2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", gfx::Size(1023, 768)));
 
   AssociateTouchscreens(&displays_, devices);
 
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[0].touch_device_id());
-  EXPECT_EQ(1, displays_[1].touch_device_id());
+  EXPECT_EQ(1u, displays_[1].touch_device_id());
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id());
-  EXPECT_EQ(2, displays_[3].touch_device_id());
+  EXPECT_EQ(2u, displays_[3].touch_device_id());
 }
 
 TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) {
   std::vector<ui::TouchscreenDevice> devices;
-  devices.push_back(ui::TouchscreenDevice(1, gfx::Size(1022, 768), false));
-  devices.push_back(ui::TouchscreenDevice(2, gfx::Size(802, 600), false));
+  devices.push_back(ui::TouchscreenDevice(
+      1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", gfx::Size(1022, 768)));
+  devices.push_back(ui::TouchscreenDevice(
+      2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", gfx::Size(802, 600)));
 
   AssociateTouchscreens(&displays_, devices);
 
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[0].touch_device_id());
-  EXPECT_EQ(1, displays_[1].touch_device_id());
+  EXPECT_EQ(1u, displays_[1].touch_device_id());
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id());
-  EXPECT_EQ(2, displays_[3].touch_device_id());
+  EXPECT_EQ(2u, displays_[3].touch_device_id());
 }
 
 TEST_F(TouchscreenUtilTest, MapInternalTouchscreen) {
   std::vector<ui::TouchscreenDevice> devices;
-  devices.push_back(ui::TouchscreenDevice(1, gfx::Size(1920, 1080), false));
-  devices.push_back(ui::TouchscreenDevice(2, gfx::Size(9999, 888), true));
+  devices.push_back(
+      ui::TouchscreenDevice(1,
+                            ui::InputDeviceType::INPUT_DEVICE_EXTERNAL,
+                            "",
+                            gfx::Size(1920, 1080)));
+  devices.push_back(ui::TouchscreenDevice(
+      2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "", gfx::Size(9999, 888)));
 
   AssociateTouchscreens(&displays_, devices);
 
   // Internal touchscreen is always mapped to internal display.
-  EXPECT_EQ(2, displays_[0].touch_device_id());
-  EXPECT_EQ(1, displays_[1].touch_device_id());
+  EXPECT_EQ(2u, displays_[0].touch_device_id());
+  EXPECT_EQ(1u, displays_[1].touch_device_id());
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id());
   EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[3].touch_device_id());
 }
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc
index dc78d28..3f784d4 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller.cc
@@ -20,7 +20,7 @@
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/events/event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
-#include "ui/gfx/vector3d_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 
 #if defined(USE_X11)
 #include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.h"
@@ -118,6 +118,7 @@
     : rotation_locked_(false),
       have_seen_accelerometer_data_(false),
       ignore_display_configuration_updates_(false),
+      lid_open_past_180_(false),
       shutting_down_(false),
       user_rotation_(gfx::Display::ROTATE_0),
       last_touchview_transition_time_(base::Time::Now()),
@@ -274,7 +275,6 @@
 void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base,
                                                  const gfx::Vector3dF& lid) {
   static const gfx::Vector3dF hinge_vector(1.0f, 0.0f, 0.0f);
-  bool maximize_mode_engaged = IsMaximizeModeWindowManagerEnabled();
   // Ignore the component of acceleration parallel to the hinge for the purposes
   // of hinge angle calculation.
   gfx::Vector3dF base_flattened(base);
@@ -306,16 +306,25 @@
     last_lid_open_time_ = base::TimeTicks();
 
   // Toggle maximize mode on or off when corresponding thresholds are passed.
-  // TODO(flackr): Make MaximizeModeController own the MaximizeModeWindowManager
-  // such that observations of state changes occur after the change and shell
-  // has fewer states to track.
-  if (maximize_mode_engaged && is_angle_stable &&
+  if (lid_open_past_180_ && is_angle_stable &&
       lid_angle <= kExitMaximizeModeAngle) {
-    LeaveMaximizeMode();
-  } else if (!lid_is_closed_ && !maximize_mode_engaged &&
+    lid_open_past_180_ = false;
+    if (!CommandLine::ForCurrentProcess()->
+            HasSwitch(switches::kAshEnableTouchViewTesting)) {
+      LeaveMaximizeMode();
+    }
+    event_blocker_.reset();
+  } else if (!lid_open_past_180_ && !lid_is_closed_ &&
              lid_angle >= kEnterMaximizeModeAngle &&
              (is_angle_stable || !WasLidOpenedRecently())) {
-    EnterMaximizeMode();
+    lid_open_past_180_ = true;
+    if (!CommandLine::ForCurrentProcess()->
+            HasSwitch(switches::kAshEnableTouchViewTesting)) {
+      EnterMaximizeMode();
+    }
+#if defined(USE_X11)
+    event_blocker_.reset(new ScopedDisableInternalMouseAndKeyboardX11);
+#endif
   }
 }
 
@@ -402,9 +411,6 @@
     LoadDisplayRotationProperties();
   }
   EnableMaximizeModeWindowManager(true);
-#if defined(USE_X11)
-  event_blocker_.reset(new ScopedDisableInternalMouseAndKeyboardX11);
-#endif
   Shell::GetInstance()->display_controller()->AddObserver(this);
 }
 
@@ -421,7 +427,6 @@
   if (!shutting_down_)
     SetRotationLocked(false);
   EnableMaximizeModeWindowManager(false);
-  event_blocker_.reset();
   Shell::GetInstance()->display_controller()->RemoveObserver(this);
 }
 
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.h b/ash/wm/maximize_mode/maximize_mode_controller.h
index f96cfd2c..a06a785e 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller.h
+++ b/ash/wm/maximize_mode/maximize_mode_controller.h
@@ -185,6 +185,9 @@
   // called, and for which these changes should be ignored.
   bool ignore_display_configuration_updates_;
 
+  // True when the hinge angle has been detected past 180 degrees.
+  bool lid_open_past_180_;
+
   // True when Shutdown has been called. When shutting down the non maximize
   // mode state should be restored, however user preferences should not be
   // altered.
diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
index faa8f591..de90d4f 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc
@@ -7,6 +7,7 @@
 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
 
 #include "ash/accelerometer/accelerometer_controller.h"
+#include "ash/ash_switches.h"
 #include "ash/display/display_manager.h"
 #include "ash/shell.h"
 #include "ash/system/tray/system_tray_delegate.h"
@@ -14,11 +15,12 @@
 #include "ash/test/display_manager_test_api.h"
 #include "ash/test/test_system_tray_delegate.h"
 #include "ash/test/test_volume_control_delegate.h"
+#include "base/command_line.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "ui/accelerometer/accelerometer_types.h"
 #include "ui/events/event_handler.h"
 #include "ui/events/test/event_generator.h"
-#include "ui/gfx/vector3d_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/message_center/message_center.h"
 
 #if defined(USE_X11)
@@ -614,4 +616,33 @@
   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
 }
 
+class MaximizeModeControllerSwitchesTest : public MaximizeModeControllerTest {
+ public:
+  MaximizeModeControllerSwitchesTest() {}
+  virtual ~MaximizeModeControllerSwitchesTest(){}
+
+  virtual void SetUp() override {
+    CommandLine::ForCurrentProcess()->AppendSwitch(
+        switches::kAshEnableTouchViewTesting);
+    MaximizeModeControllerTest::SetUp();
+  }
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MaximizeModeControllerSwitchesTest);
+};
+
+// Tests that when the command line switch for testing maximize mode is on, that
+// accelerometer updates which would normally cause it to exit do not, and that
+// screen rotations still occur.
+TEST_F(MaximizeModeControllerSwitchesTest, IgnoreHingeAngles) {
+  maximize_mode_controller()->EnableMaximizeModeWindowManager(true);
+
+  // Would normally trigger an exit from maximize mode.
+  OpenLidToAngle(90.0f);
+  EXPECT_TRUE(IsMaximizeModeStarted());
+
+  TriggerAccelerometerUpdate(gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f),
+                             gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f));
+  EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
+}
+
 }  // namespace ash
diff --git a/ash/wm/overview/transparent_activate_window_button.cc b/ash/wm/overview/transparent_activate_window_button.cc
index a92e8bb..1cb3c4f1 100644
--- a/ash/wm/overview/transparent_activate_window_button.cc
+++ b/ash/wm/overview/transparent_activate_window_button.cc
@@ -13,6 +13,7 @@
 namespace ash {
 
 namespace {
+const char kTransparentButtonName[] = "TransparentButton";
 
 // Transparent button that handles events which activate windows in overview
 // mode.
@@ -23,6 +24,28 @@
   }
   virtual ~TransparentButton() {}
 
+  // views::CustomButton:
+  void OnGestureEvent(ui::GestureEvent* event) override {
+    // TODO(tdanderson): Re-evaluate whether we want to set capture once
+    //                   the a fix has landed to avoid crashing when a window
+    //                   having an active gesture sequence is destroyed as a
+    //                   result of a gesture in a separate window.
+    if (event->type() == ui::ET_GESTURE_TAP_DOWN)
+      GetWidget()->SetCapture(this);
+
+    if (event->type() == ui::ET_GESTURE_TAP ||
+        event->type() == ui::ET_GESTURE_END) {
+      GetWidget()->ReleaseCapture();
+    }
+
+    CustomButton::OnGestureEvent(event);
+    event->StopPropagation();
+  }
+
+  virtual const char* GetClassName() const override {
+    return kTransparentButtonName;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(TransparentButton);
 };
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc
index a892c45..729239a 100644
--- a/ash/wm/overview/window_selector_unittest.cc
+++ b/ash/wm/overview/window_selector_unittest.cc
@@ -329,6 +329,39 @@
   EXPECT_EQ(window2.get(), GetFocusedWindow());
 }
 
+// Tests that we do not crash and overview mode remains engaged if the desktop
+// is tapped while a finger is already down over a window.
+TEST_F(WindowSelectorTest, NoCrashWithDesktopTap) {
+  scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(200, 300, 250, 450)));
+
+  // We need a widget for the close button to work, a bare window will crash.
+  scoped_ptr<views::Widget> widget(new views::Widget);
+  views::Widget::InitParams params;
+  params.bounds = gfx::Rect(0, 0, 400, 400);
+  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  params.parent = window->parent();
+  widget->Init(params);
+  widget->Show();
+
+  ToggleOverview();
+
+  gfx::Rect bounds =
+      gfx::ToEnclosingRect(GetTransformedBoundsInRootWindow(window.get()));
+  ui::test::EventGenerator event_generator(window->GetRootWindow(),
+                                           bounds.CenterPoint());
+
+  // Press down on the window.
+  const int kTouchId = 19;
+  event_generator.PressTouchId(kTouchId);
+
+  // Tap on the desktop, which should not cause a crash. Overview mode should
+  // remain engaged because the transparent widget over the window has capture.
+  event_generator.GestureTapAt(gfx::Point(0, 0));
+  EXPECT_TRUE(IsSelecting());
+
+  event_generator.ReleaseTouchId(kTouchId);
+}
+
 // Tests that a window does not receive located events when in overview mode.
 TEST_F(WindowSelectorTest, WindowDoesNotReceiveEvents) {
   gfx::Rect window_bounds(20, 10, 200, 300);
@@ -365,7 +398,7 @@
 TEST_F(WindowSelectorTest, CloseButton) {
   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(200, 300, 250, 450)));
 
-  // We need a widget for the close button the work, a bare window will crash.
+  // We need a widget for the close button to work, a bare window will crash.
   scoped_ptr<views::Widget> widget(new views::Widget);
   views::Widget::InitParams params;
   params.bounds = gfx::Rect(0, 0, 400, 400);
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc
index d4e05b2a..5bc71cd8 100644
--- a/ash/wm/window_animations.cc
+++ b/ash/wm/window_animations.cc
@@ -33,9 +33,9 @@
 #include "ui/compositor/layer_animator.h"
 #include "ui/compositor/layer_tree_owner.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/interpolated_transform.h"
 #include "ui/gfx/screen.h"
-#include "ui/gfx/vector3d_f.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 #include "ui/wm/core/window_util.h"
diff --git a/athena/activity/activity_factory.cc b/athena/activity/activity_factory.cc
index 2507281e..dbaa77d 100644
--- a/athena/activity/activity_factory.cc
+++ b/athena/activity/activity_factory.cc
@@ -10,8 +10,7 @@
 
 namespace {
 
-ActivityFactory* instance = NULL;
-
+ActivityFactory* instance = nullptr;
 }
 
 // static
@@ -30,7 +29,7 @@
 void ActivityFactory::Shutdown() {
   DCHECK(instance);
   delete instance;
-  instance = NULL;
+  instance = nullptr;
 }
 
 }  // namespace athena
diff --git a/athena/activity/activity_manager_impl.cc b/athena/activity/activity_manager_impl.cc
index bf85721..71216df 100644
--- a/athena/activity/activity_manager_impl.cc
+++ b/athena/activity/activity_manager_impl.cc
@@ -18,7 +18,7 @@
 
 namespace {
 
-ActivityManager* instance = NULL;
+ActivityManager* instance = nullptr;
 
 views::Widget* CreateWidget(Activity* activity) {
   ActivityViewModel* view_model = activity->GetActivityViewModel();
@@ -51,7 +51,7 @@
     Activity::Delete(activities_.front());
 
   CHECK_EQ(this, instance);
-  instance = NULL;
+  instance = nullptr;
 }
 
 void ActivityManagerImpl::AddActivity(Activity* activity) {
@@ -95,7 +95,7 @@
   };
   std::vector<Activity*>::iterator iter =
       std::find_if(activities_.begin(), activities_.end(), Matcher(window));
-  return iter != activities_.end() ? *iter : NULL;
+  return iter != activities_.end() ? *iter : nullptr;
 }
 
 void ActivityManagerImpl::AddObserver(ActivityManagerObserver* observer) {
diff --git a/athena/activity/activity_manager_unittest.cc b/athena/activity/activity_manager_unittest.cc
index 37f73f6..92e721d 100644
--- a/athena/activity/activity_manager_unittest.cc
+++ b/athena/activity/activity_manager_unittest.cc
@@ -20,7 +20,7 @@
   ActivityFactory* factory = ActivityFactory::Get();
 
   Activity* activity1 =
-      factory->CreateWebActivity(NULL, base::string16(), GURL());
+      factory->CreateWebActivity(nullptr, base::string16(), GURL());
   EXPECT_EQ(1, activity_manager->num_activities());
 
   // Activity is not visible when created.
@@ -29,7 +29,7 @@
   EXPECT_TRUE(activity1->GetWindow()->TargetVisibility());
 
   Activity* activity2 =
-      factory->CreateWebActivity(NULL, base::string16(), GURL());
+      factory->CreateWebActivity(nullptr, base::string16(), GURL());
   EXPECT_EQ(2, activity_manager->num_activities());
 
   Activity::Delete(activity1);
@@ -45,17 +45,17 @@
   ActivityFactory* factory = ActivityFactory::Get();
 
   Activity* activity1 =
-      factory->CreateWebActivity(NULL, base::string16(), GURL());
+      factory->CreateWebActivity(nullptr, base::string16(), GURL());
   Activity* activity2 =
-      factory->CreateWebActivity(NULL, base::string16(), GURL());
+      factory->CreateWebActivity(nullptr, base::string16(), GURL());
 
   EXPECT_EQ(activity1, manager->GetActivityForWindow(activity1->GetWindow()));
   EXPECT_EQ(activity2, manager->GetActivityForWindow(activity2->GetWindow()));
 
-  EXPECT_EQ(NULL, manager->GetActivityForWindow(NULL));
+  EXPECT_EQ(nullptr, manager->GetActivityForWindow(nullptr));
 
-  scoped_ptr<aura::Window> window = test::CreateNormalWindow(NULL, NULL);
-  EXPECT_EQ(NULL, manager->GetActivityForWindow(window.get()));
+  scoped_ptr<aura::Window> window = test::CreateNormalWindow(nullptr, nullptr);
+  EXPECT_EQ(nullptr, manager->GetActivityForWindow(window.get()));
 }
 
 }  // namespace athena
diff --git a/athena/activity/public/activity.h b/athena/activity/public/activity.h
index 54ed832..b5513bc3 100644
--- a/athena/activity/public/activity.h
+++ b/athena/activity/public/activity.h
@@ -94,7 +94,7 @@
   virtual aura::Window* GetWindow() = 0;
 
   // Returns the web contents used to draw the content of the activity.
-  // This may return NULL if the web content is not available.
+  // This may return nullptr if the web content is not available.
   virtual content::WebContents* GetWebContents() = 0;
 
  protected:
diff --git a/athena/activity/public/activity_manager.h b/athena/activity/public/activity_manager.h
index 946f2ee..99d8e75 100644
--- a/athena/activity/public/activity_manager.h
+++ b/athena/activity/public/activity_manager.h
@@ -30,7 +30,7 @@
   virtual void RemoveActivity(Activity* activity) = 0;
 
   // Returns the activity that has a |window| as toplevel window, or
-  // NULL if such activity does not exist.
+  // nullptr if such activity does not exist.
   virtual Activity* GetActivityForWindow(aura::Window* window) = 0;
 
   // Updates the UI when the task color/title changes.
diff --git a/athena/activity/public/activity_view_model.h b/athena/activity/public/activity_view_model.h
index 24590218..69b98f1 100644
--- a/athena/activity/public/activity_view_model.h
+++ b/athena/activity/public/activity_view_model.h
@@ -45,12 +45,12 @@
   // draws its own frame.
   virtual bool UsesFrame() const = 0;
 
-  // Returns the contents view which might be NULL if the activity is not
+  // Returns the contents view which might be nullptr if the activity is not
   // loaded. Note that the caller should not hold on to the view since it can
   // be deleted by the resource manager.
   virtual views::View* GetContentsView() = 0;
 
-  // Creates a custom widget for the activity. Returns NULL to use default
+  // Creates a custom widget for the activity. Returns nullptr to use default
   // implementation.
   virtual views::Widget* CreateWidget() = 0;
 
diff --git a/athena/content/app_activity.cc b/athena/content/app_activity.cc
index 42f6a0e..503e564 100644
--- a/athena/content/app_activity.cc
+++ b/athena/content/app_activity.cc
@@ -20,12 +20,11 @@
 namespace athena {
 
 // TODO(mukai): specifies the same accelerators of WebActivity.
-AppActivity::AppActivity(const std::string& app_id,
-                         views::WebView* web_view)
+AppActivity::AppActivity(const std::string& app_id, views::WebView* web_view)
     : app_id_(app_id),
       web_view_(web_view),
       current_state_(ACTIVITY_UNLOADED),
-      app_activity_registry_(NULL) {
+      app_activity_registry_(nullptr) {
   Observe(web_view->GetWebContents());
 }
 
@@ -94,11 +93,11 @@
 }
 
 aura::Window* AppActivity::GetWindow() {
-  return !web_view_ ? NULL : web_view_->GetWidget()->GetNativeWindow();
+  return !web_view_ ? nullptr : web_view_->GetWidget()->GetNativeWindow();
 }
 
 content::WebContents* AppActivity::GetWebContents() {
-  return !web_view_ ? NULL : web_view_->GetWebContents();
+  return !web_view_ ? nullptr : web_view_->GetWebContents();
 }
 
 void AppActivity::Init() {
@@ -198,9 +197,9 @@
 
 AppActivity::AppActivity(const std::string& app_id)
     : app_id_(app_id),
-      web_view_(NULL),
+      web_view_(nullptr),
       current_state_(ACTIVITY_UNLOADED),
-      app_activity_registry_(NULL) {
+      app_activity_registry_(nullptr) {
 }
 
 AppActivity::~AppActivity() {
diff --git a/athena/content/app_activity_browsertest.cc b/athena/content/app_activity_browsertest.cc
index 114c5640..22a4c1ab 100644
--- a/athena/content/app_activity_browsertest.cc
+++ b/athena/content/app_activity_browsertest.cc
@@ -41,8 +41,8 @@
   // until the application got restarted returning the new application activity.
   Activity* WaitForProxyDestruction(Activity* proxy_activity) {
     ActivityLifetimeTracker tracker;
-    void* deleted_activity = NULL;
-    Activity* app_activity = NULL;
+    void* deleted_activity = nullptr;
+    Activity* app_activity = nullptr;
     while (!app_activity && !deleted_activity) {
       deleted_activity = tracker_->GetDeletedActivityAndReset();
       app_activity = tracker_->GetNewActivityAndReset();
@@ -68,7 +68,7 @@
     Activity* app_activity = CreateTestAppActivity(GetTestAppID());
     ASSERT_TRUE(app_activity);
     EXPECT_EQ(app_activity, tracker_->GetNewActivityAndReset());
-    EXPECT_EQ(NULL, tracker_->GetDeletedActivityAndReset());
+    EXPECT_EQ(nullptr, tracker_->GetDeletedActivityAndReset());
 
     // Then a web activity (which will then be in front of the app).
     *web_activity = test_util::CreateTestWebActivity(
@@ -77,7 +77,7 @@
         GURL(kTestUrl));
     ASSERT_TRUE(*web_activity);
     EXPECT_EQ(*web_activity, tracker_->GetNewActivityAndReset());
-    EXPECT_EQ(NULL, tracker_->GetDeletedActivityAndReset());
+    EXPECT_EQ(nullptr, tracker_->GetDeletedActivityAndReset());
 
     const aura::Window::Windows& windows =
         WindowManager::Get()->GetWindowListProvider()->GetWindowList();
@@ -138,13 +138,13 @@
 // upon changing it to invisible it gets reloaded it its current list location.
 IN_PROC_BROWSER_TEST_F(AppActivityBrowserTest, UnloadReloadApplicationInPlace) {
   // Set up the experiment.
-  Activity* proxy_activity = NULL;
-  Activity* web_activity = NULL;
+  Activity* proxy_activity = nullptr;
+  Activity* web_activity = nullptr;
   SetUpWebAndProxyActivity(&web_activity, &proxy_activity);
   // By returning to a low memory pressure the application should start again.
   test_util::SendTestMemoryPressureEvent(ResourceManager::MEMORY_PRESSURE_LOW);
   Activity* app_activity = WaitForProxyDestruction(proxy_activity);
-  proxy_activity = NULL;  // The proxy is gone now.
+  proxy_activity = nullptr;  // The proxy is gone now.
 
   // After this, the application should remain at its current location in the
   // stack and the current window should stay active.
@@ -159,8 +159,8 @@
 // front of the stack (and activate it).
 IN_PROC_BROWSER_TEST_F(AppActivityBrowserTest, ReloadActivatedApplication) {
   // Set up the experiment.
-  Activity* proxy_activity = NULL;
-  Activity* web_activity = NULL;
+  Activity* proxy_activity = nullptr;
+  Activity* web_activity = nullptr;
   SetUpWebAndProxyActivity(&web_activity, &proxy_activity);
 
   // Activating the proxy should push back the web app, lauch the application,
@@ -172,7 +172,7 @@
   EXPECT_EQ(web_activity->GetWindow(), windows[0]);
 
   Activity* app_activity = WaitForProxyDestruction(proxy_activity);
-  proxy_activity = NULL;  // The proxy is gone now.
+  proxy_activity = nullptr;  // The proxy is gone now.
 
   // After this, the application should remain at its current location in the
   // stack and the activation focus should remain on the current window as well.
@@ -185,8 +185,8 @@
 // and activate it.
 IN_PROC_BROWSER_TEST_F(AppActivityBrowserTest, ReloadMovedApplication) {
   // Set up the experiment.
-  Activity* proxy_activity = NULL;
-  Activity* web_activity = NULL;
+  Activity* proxy_activity = nullptr;
+  Activity* web_activity = nullptr;
   SetUpWebAndProxyActivity(&web_activity, &proxy_activity);
   // Moving the window to the front will restart the app.
   WindowManager::Get()->GetWindowListProvider()->StackWindowFrontOf(
@@ -197,7 +197,7 @@
   EXPECT_EQ(web_activity->GetWindow(), windows[0]);
 
   Activity* app_activity = WaitForProxyDestruction(proxy_activity);
-  proxy_activity = NULL;  // The proxy is gone now.
+  proxy_activity = nullptr;  // The proxy is gone now.
 
   // After this, the application should remain at its current location in the
   // stack and the activation focus should remain on the current window as well.
diff --git a/athena/content/app_activity_proxy.cc b/athena/content/app_activity_proxy.cc
index f3a0581..80e9938a 100644
--- a/athena/content/app_activity_proxy.cc
+++ b/athena/content/app_activity_proxy.cc
@@ -60,7 +60,7 @@
 }
 
 content::WebContents* AppActivityProxy::GetWebContents() {
-  return NULL;
+  return nullptr;
 }
 
 void AppActivityProxy::Init() {
@@ -73,7 +73,7 @@
                                             replaced_activity_->GetWindow());
   // After the Init() function returns, the passed |replaced_activity_| might
   // get destroyed. Since we do not need it anymore we reset it.
-  replaced_activity_ = NULL;
+  replaced_activity_ = nullptr;
 }
 
 SkColor AppActivityProxy::GetRepresentativeColor() const {
@@ -97,7 +97,7 @@
 }
 
 views::Widget* AppActivityProxy::CreateWidget() {
-  return NULL;
+  return nullptr;
 }
 
 gfx::ImageSkia AppActivityProxy::GetOverviewModeImage() {
diff --git a/athena/content/app_activity_registry.cc b/athena/content/app_activity_registry.cc
index 9981437..4284346 100644
--- a/athena/content/app_activity_registry.cc
+++ b/athena/content/app_activity_registry.cc
@@ -24,10 +24,11 @@
 
 AppActivityRegistry::AppActivityRegistry(
     const std::string& app_id,
-    content::BrowserContext* browser_context) :
-      app_id_(app_id),
+    content::BrowserContext* browser_context)
+    : app_id_(app_id),
       browser_context_(browser_context),
-      unloaded_activity_proxy_(NULL) {}
+      unloaded_activity_proxy_(nullptr) {
+}
 
 AppActivityRegistry::~AppActivityRegistry() {
   CHECK(activity_list_.empty());
@@ -62,7 +63,7 @@
 
 AppActivity* AppActivityRegistry::GetAppActivityAt(size_t index) {
   if (index >= activity_list_.size())
-    return NULL;
+    return nullptr;
   return activity_list_[index];
 }
 
@@ -94,7 +95,7 @@
 
 void AppActivityRegistry::ProxyDestroyed(AppActivityProxy* proxy) {
   DCHECK_EQ(unloaded_activity_proxy_, proxy);
-  unloaded_activity_proxy_ = NULL;
+  unloaded_activity_proxy_ = nullptr;
   if (activity_list_.empty()) {
     AppRegistry::Get()->RemoveAppActivityRegistry(this);
     // |This| is gone now.
@@ -133,7 +134,7 @@
     }
   }
   NOTREACHED() << "The application does not get tracked by the mru list";
-  return NULL;
+  return nullptr;
 }
 
 }  // namespace athena
diff --git a/athena/content/app_activity_registry.h b/athena/content/app_activity_registry.h
index cce8071..da8255c 100644
--- a/athena/content/app_activity_registry.h
+++ b/athena/content/app_activity_registry.h
@@ -45,7 +45,7 @@
   // Returns the number of activities/windows with this application.
   int NumberOfActivities() const { return activity_list_.size(); }
 
-  // Returns the |AppActivity| at |index|. It will return NULL if an invalid
+  // Returns the |AppActivity| at |index|. It will return nullptr if an invalid
   // index was specified.
   AppActivity* GetAppActivityAt(size_t index);
 
@@ -53,7 +53,7 @@
   void Unload();
 
   // Returns true if the application is in the unloaded state.
-  bool IsUnloaded() { return unloaded_activity_proxy_ != NULL; }
+  bool IsUnloaded() { return unloaded_activity_proxy_ != nullptr; }
 
   content::BrowserContext* browser_context() const { return browser_context_; }
   const std::string& app_id() const { return app_id_; }
diff --git a/athena/content/app_activity_unittest.cc b/athena/content/app_activity_unittest.cc
index f09444d..8f164d1 100644
--- a/athena/content/app_activity_unittest.cc
+++ b/athena/content/app_activity_unittest.cc
@@ -37,7 +37,7 @@
         view_(new views::View()),
         current_state_(ACTIVITY_VISIBLE) {
     app_activity_registry_ =
-        AppRegistry::Get()->GetAppActivityRegistry(app_id, NULL);
+        AppRegistry::Get()->GetAppActivityRegistry(app_id, nullptr);
     app_activity_registry_->RegisterAppActivity(this);
   }
   virtual ~TestAppActivity() {
@@ -76,7 +76,7 @@
   virtual base::string16 GetTitle() const override { return title_; }
   virtual bool UsesFrame() const override { return true; }
   virtual views::View* GetContentsView() override { return view_; }
-  virtual views::Widget* CreateWidget() override { return NULL; }
+  virtual views::Widget* CreateWidget() override { return nullptr; }
   virtual gfx::ImageSkia GetOverviewModeImage() override {
     return gfx::ImageSkia();
   }
@@ -108,7 +108,7 @@
 
   // ExtensionsDelegate:
   virtual content::BrowserContext* GetBrowserContext() const override {
-    return NULL;
+    return nullptr;
   }
   virtual const extensions::ExtensionSet& GetInstalledExtensions() override {
     return extension_set_;
@@ -143,7 +143,7 @@
 // Our testing base.
 class AppActivityTest : public AthenaTestBase {
  public:
-  AppActivityTest() : test_extensions_delegate_(NULL) {}
+  AppActivityTest() : test_extensions_delegate_(nullptr) {}
   virtual ~AppActivityTest() {}
 
   // AthenaTestBase:
@@ -204,7 +204,7 @@
     TestAppActivity* app_activity = CreateAppActivity(kDummyApp1);
     EXPECT_EQ(1, AppRegistry::Get()->NumberOfApplications());
     EXPECT_EQ(1, app_activity->app_activity_registry()->NumberOfActivities());
-    EXPECT_EQ(AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL),
+    EXPECT_EQ(AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, nullptr),
               app_activity->app_activity_registry());
     DeleteActivity(app_activity);
   }
@@ -297,7 +297,7 @@
   // created.
   ASSERT_EQ(1, AppRegistry::Get()->NumberOfApplications());
   ASSERT_EQ(app_activity_registry,
-            AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL));
+            AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, nullptr));
   EXPECT_EQ(0, app_activity_registry->NumberOfActivities());
   Activity* activity_proxy = app_activity_registry->unloaded_activity_proxy();
   ASSERT_TRUE(activity_proxy);
@@ -387,7 +387,7 @@
   // Now there should only be the proxy activity left.
   ASSERT_EQ(1, AppRegistry::Get()->NumberOfApplications());
   ASSERT_EQ(app_activity_registry,
-            AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, NULL));
+            AppRegistry::Get()->GetAppActivityRegistry(kDummyApp1, nullptr));
   EXPECT_EQ(0, app_activity_registry->NumberOfActivities());
   Activity* activity_proxy = app_activity_registry->unloaded_activity_proxy();
   ASSERT_TRUE(activity_proxy);
diff --git a/athena/content/app_registry_impl.cc b/athena/content/app_registry_impl.cc
index 0e750f3..599934d 100644
--- a/athena/content/app_registry_impl.cc
+++ b/athena/content/app_registry_impl.cc
@@ -31,7 +31,7 @@
 
 namespace {
 
-AppRegistryImpl* instance = NULL;
+AppRegistryImpl* instance = nullptr;
 
 }  // namespace
 
@@ -88,7 +88,7 @@
 AppRegistry::AppRegistry() {}
 
 AppRegistry::~AppRegistry() {
-  instance = NULL;
+  instance = nullptr;
 }
 
 }  // namespace athena
diff --git a/athena/content/chrome/web_activity_helpers_browsertest.cc b/athena/content/chrome/web_activity_helpers_browsertest.cc
index 12c79d2..1c633e92 100644
--- a/athena/content/chrome/web_activity_helpers_browsertest.cc
+++ b/athena/content/chrome/web_activity_helpers_browsertest.cc
@@ -50,7 +50,7 @@
     content::WebContents* web_contents =
         content::Source<content::WebContents>(source).ptr();
     helpers_created_prior_to_render_view_ &=
-        (extensions::TabHelper::FromWebContents(web_contents) != NULL);
+        (extensions::TabHelper::FromWebContents(web_contents) != nullptr);
   }
 
   bool helpers_created_prior_to_render_view_;
diff --git a/athena/content/content_proxy.cc b/athena/content/content_proxy.cc
index f2a2f137..42369e4 100644
--- a/athena/content/content_proxy.cc
+++ b/athena/content/content_proxy.cc
@@ -101,7 +101,7 @@
   // make the web content visible if the window gets destroyed shortly after.
   ShowOriginalContent();
 
-  web_view_ = NULL;
+  web_view_ = nullptr;
 }
 
 void ContentProxy::ShowOriginalContent() {
diff --git a/athena/content/content_proxy.h b/athena/content/content_proxy.h
index 9d1dca5..e39d1bb8 100644
--- a/athena/content/content_proxy.h
+++ b/athena/content/content_proxy.h
@@ -77,7 +77,7 @@
 
   // The web view which was passed on creation and is associated with this
   // object. It will be shown when OnPreContentDestroyed() gets called and then
-  // set to NULL. The ownership remains with the creator.
+  // set to nullptr. The ownership remains with the creator.
   views::WebView* web_view_;
 
   // While we are doing our PNG encode, we keep the read back image to have
diff --git a/athena/content/shell/dialogs.cc b/athena/content/shell/dialogs.cc
index 63b09e01..ce5db0a 100644
--- a/athena/content/shell/dialogs.cc
+++ b/athena/content/shell/dialogs.cc
@@ -12,7 +12,7 @@
     SkColor initial_color,
     const std::vector<content::ColorSuggestion>& suggestions) {
   NOTIMPLEMENTED();
-  return NULL;
+  return nullptr;
 }
 
 void OpenFileChooser(content::WebContents* web_contents,
diff --git a/athena/content/web_activity.cc b/athena/content/web_activity.cc
index 2baba3d..8041915b 100644
--- a/athena/content/web_activity.cc
+++ b/athena/content/web_activity.cc
@@ -265,8 +265,8 @@
       default:
         break;
     }
-    // NULL is returned if the URL wasn't opened immediately.
-    return NULL;
+    // nullptr is returned if the URL wasn't opened immediately.
+    return nullptr;
   }
 
   virtual bool CanOverscrollContent() const override {
@@ -338,7 +338,7 @@
 
   virtual void LoadingStateChanged(content::WebContents* source,
                                    bool to_different_document) override {
-    bool has_stopped = source == NULL || !source->IsLoading();
+    bool has_stopped = source == nullptr || !source->IsLoading();
     LoadProgressChanged(source, has_stopped ? 1 : 0);
   }
 
@@ -367,7 +367,7 @@
   virtual content::JavaScriptDialogManager* GetJavaScriptDialogManager()
       override {
     NOTIMPLEMENTED();
-    return NULL;
+    return nullptr;
   }
 
   virtual content::ColorChooser* OpenColorChooser(
@@ -505,7 +505,7 @@
       DCHECK_NE(ACTIVITY_UNLOADED, current_state_);
       if (content_proxy_)
         content_proxy_->ContentWillUnload();
-      Observe(NULL);
+      Observe(nullptr);
       web_view_->EvictContent();
       break;
   }
@@ -568,7 +568,7 @@
 }
 
 views::Widget* WebActivity::CreateWidget() {
-  return NULL;  // Use default widget.
+  return nullptr;  // Use default widget.
 }
 
 gfx::ImageSkia WebActivity::GetOverviewModeImage() {
@@ -634,7 +634,7 @@
     const std::vector<SkBitmap>& bitmaps,
     const std::vector<gfx::Size>& original_bitmap_sizes) {
   icon_ = CreateFaviconImageSkia(
-      bitmaps, original_bitmap_sizes, kIconSize, NULL);
+      bitmaps, original_bitmap_sizes, kIconSize, nullptr);
   ActivityManager::Get()->UpdateActivity(this);
 }
 
@@ -645,7 +645,7 @@
 
 void WebActivity::HideContentProxy() {
   if (content_proxy_.get())
-    content_proxy_.reset(NULL);
+    content_proxy_.reset(nullptr);
 }
 
 void WebActivity::ShowContentProxy() {
diff --git a/athena/content/web_contents_view_delegate_factory_impl.cc b/athena/content/web_contents_view_delegate_factory_impl.cc
index 4aa304e3..410a39e3 100644
--- a/athena/content/web_contents_view_delegate_factory_impl.cc
+++ b/athena/content/web_contents_view_delegate_factory_impl.cc
@@ -29,7 +29,7 @@
   virtual content::WebDragDestDelegate* GetDragDestDelegate() override {
     // TODO(oshima): crbug.com/401610
     NOTIMPLEMENTED();
-    return NULL;
+    return nullptr;
   }
 
   virtual bool Focus() override {
@@ -128,7 +128,7 @@
 
   views::FocusManager* GetFocusManager() {
     views::Widget* toplevel_widget = GetTopLevelWidget();
-    return toplevel_widget ? toplevel_widget->GetFocusManager() : NULL;
+    return toplevel_widget ? toplevel_widget->GetFocusManager() : nullptr;
   }
 
   void SetInitialFocus() {
diff --git a/athena/env/athena_env_impl.cc b/athena/env/athena_env_impl.cc
index 1a22632..2d50c5e 100644
--- a/athena/env/athena_env_impl.cc
+++ b/athena/env/athena_env_impl.cc
@@ -34,10 +34,10 @@
 
 namespace {
 
-AthenaEnv* instance = NULL;
+AthenaEnv* instance = nullptr;
 
 // Screen object used during shutdown.
-gfx::Screen* screen_for_shutdown = NULL;
+gfx::Screen* screen_for_shutdown = nullptr;
 
 // TODO(flackr:oshima): Remove this once athena switches to share
 // ash::DisplayManager.
@@ -56,12 +56,11 @@
       : primary_display_(primary_display) {}
 
   // gfx::Screen overrides:
-  virtual bool IsDIPEnabled() override { return true; }
   virtual gfx::Point GetCursorScreenPoint() override { return gfx::Point(); }
-  virtual gfx::NativeWindow GetWindowUnderCursor() override { return NULL; }
+  virtual gfx::NativeWindow GetWindowUnderCursor() override { return nullptr; }
   virtual gfx::NativeWindow GetWindowAtScreenPoint(
       const gfx::Point& point) override {
-    return NULL;
+    return nullptr;
   }
   virtual int GetNumDisplays() const override { return 1; }
   virtual std::vector<gfx::Display> GetAllDisplays() const override {
@@ -220,7 +219,7 @@
   }
 
   virtual ~AthenaEnvImpl() {
-    instance = NULL;
+    instance = nullptr;
 
     host_->RemoveObserver(this);
     if (input_method_filter_)
diff --git a/athena/extensions/athena_app_delegate_base.cc b/athena/extensions/athena_app_delegate_base.cc
index 3c4a1e4..49b8e6d 100644
--- a/athena/extensions/athena_app_delegate_base.cc
+++ b/athena/extensions/athena_app_delegate_base.cc
@@ -25,7 +25,7 @@
       context, base::string16(), params.url);
   Activity::Show(activity);
   // TODO(oshima): Get the web cotnents from activity.
-  return NULL;
+  return nullptr;
 }
 
 }  // namespace
@@ -43,7 +43,7 @@
       content::WebContents* source,
       const content::OpenURLParams& params) override {
     if (!source)
-      return NULL;
+      return nullptr;
     return OpenURLInActivity(source->GetBrowserContext(), params);
   }
 
diff --git a/athena/extensions/chrome/app_list_controller_delegate_athena.cc b/athena/extensions/chrome/app_list_controller_delegate_athena.cc
index 5dcef059..a731c8b 100644
--- a/athena/extensions/chrome/app_list_controller_delegate_athena.cc
+++ b/athena/extensions/chrome/app_list_controller_delegate_athena.cc
@@ -23,7 +23,7 @@
 
 gfx::NativeWindow AppListControllerDelegateAthena::GetAppListWindow() {
   NOTIMPLEMENTED();
-  return NULL;
+  return nullptr;
 }
 
 gfx::Rect AppListControllerDelegateAthena::GetAppListBounds() {
diff --git a/athena/extensions/chrome/athena_chrome_app_delegate.cc b/athena/extensions/chrome/athena_chrome_app_delegate.cc
index 9040ca3..90f9520f 100644
--- a/athena/extensions/chrome/athena_chrome_app_delegate.cc
+++ b/athena/extensions/chrome/athena_chrome_app_delegate.cc
@@ -81,7 +81,7 @@
 void AthenaChromeAppDelegate::SetWebContentsBlocked(
     content::WebContents* web_contents,
     bool blocked) {
-  // RenderViewHost may be NULL during shutdown.
+  // RenderViewHost may be nullptr during shutdown.
   content::RenderViewHost* host = web_contents->GetRenderViewHost();
   if (host) {
     host->Send(new ChromeViewMsg_SetVisuallyDeemphasized(host->GetRoutingID(),
diff --git a/athena/extensions/chrome/athena_extension_install_ui.cc b/athena/extensions/chrome/athena_extension_install_ui.cc
index a4bfaa3..a23807c 100644
--- a/athena/extensions/chrome/athena_extension_install_ui.cc
+++ b/athena/extensions/chrome/athena_extension_install_ui.cc
@@ -58,7 +58,7 @@
   base::string16 message = l10n_util::GetStringFUTF16(
       IDS_EXTENSION_INSTALLED_HEADING, extension_name);
   views::Widget* widget = views::DialogDelegate::CreateDialogWidget(
-      new MessageDialogDelegate(message), NULL, NULL);
+      new MessageDialogDelegate(message), nullptr, nullptr);
   widget->Show();
 }
 
@@ -68,7 +68,7 @@
     return;
 
   views::Widget* widget = views::DialogDelegate::CreateDialogWidget(
-      new MessageDialogDelegate(error.message()), NULL, NULL);
+      new MessageDialogDelegate(error.message()), nullptr, nullptr);
   widget->Show();
 }
 
@@ -84,7 +84,7 @@
 }
 
 gfx::NativeWindow AthenaExtensionInstallUI::GetDefaultInstallDialogParent() {
-  return NULL;
+  return nullptr;
 }
 
 }  // namespace athena
diff --git a/athena/extensions/chrome/extensions_delegate_impl.cc b/athena/extensions/chrome/extensions_delegate_impl.cc
index 0235fd94..587a6f83 100644
--- a/athena/extensions/chrome/extensions_delegate_impl.cc
+++ b/athena/extensions/chrome/extensions_delegate_impl.cc
@@ -4,7 +4,6 @@
 
 #include "athena/extensions/public/extensions_delegate.h"
 
-#include "athena/activity/public/activity_factory.h"
 #include "athena/extensions/chrome/athena_chrome_app_window_client.h"
 #include "athena/extensions/chrome/athena_extension_install_ui.h"
 #include "base/macros.h"
@@ -33,7 +32,7 @@
   }
 
   virtual ~ChromeExtensionsDelegate() {
-    extensions::AppWindowClient::Set(NULL);
+    extensions::AppWindowClient::Set(nullptr);
   }
 
  private:
@@ -76,12 +75,7 @@
     }
     params.container = extensions::LAUNCH_CONTAINER_WINDOW;
 
-    // V2 apps
-    if (CanLaunchViaEvent(extension)) {
-      OpenApplication(params);
-      return true;
-    }
-    LaunchV1App(params, extension);
+    OpenApplication(params);
     return true;
   }
 
@@ -96,17 +90,6 @@
         new AthenaExtensionInstallUI());
   }
 
-  void LaunchV1App(const AppLaunchParams& params,
-                   const extensions::Extension* extension) {
-    // TODO(oshima): Just activate if the app is already running.
-    const GURL url_input = params.override_url;
-
-    DCHECK(!url_input.is_empty() || extension);
-    GURL url = UrlForExtension(extension, url_input);
-    athena::ActivityFactory::Get()->CreateWebActivity(
-        GetBrowserContext(), base::UTF8ToUTF16(extension->name()), url);
-  }
-
   // ExtensionService for the browser context this is created for.
   ExtensionService* extension_service_;
 
diff --git a/athena/extensions/extension_app_model_builder.cc b/athena/extensions/extension_app_model_builder.cc
index 92ee81f..88d89f1c 100644
--- a/athena/extensions/extension_app_model_builder.cc
+++ b/athena/extensions/extension_app_model_builder.cc
@@ -8,6 +8,8 @@
 #include "athena/activity/public/activity_manager.h"
 #include "athena/extensions/public/extensions_delegate.h"
 #include "extensions/browser/extension_icon_image.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_registry_factory.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension_set.h"
 #include "extensions/common/manifest_handlers/icons_handler.h"
@@ -29,17 +31,22 @@
   AppItem(scoped_refptr<const extensions::Extension> extension,
           content::BrowserContext* browser_context)
       : app_list::AppListItem(extension->id()),
-        extension_(extension),
-        browser_context_(browser_context),
-        icon_image_(browser_context_,
-                    extension.get(),
-                    extensions::IconsInfo::GetIcons(extension.get()),
-                    extension_misc::EXTENSION_ICON_MEDIUM,
-                    *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-                        IDR_APP_DEFAULT_ICON),
-                    NULL) {
-    icon_image_.image_skia().EnsureRepsForSupportedScales();
-    SetIcon(icon_image_.image_skia(), false);
+        browser_context_(browser_context) {
+    Reload(extension);
+  }
+
+  void Reload(scoped_refptr<const extensions::Extension> extension) {
+    extension_ = extension;
+    icon_image_.reset(new extensions::IconImage(
+        browser_context_,
+        extension.get(),
+        extensions::IconsInfo::GetIcons(extension.get()),
+        extension_misc::EXTENSION_ICON_MEDIUM,
+        *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+            IDR_APP_DEFAULT_ICON),
+        nullptr));
+    icon_image_->image_skia().EnsureRepsForSupportedScales();
+    SetIcon(icon_image_->image_skia(), false);
     SetName(extension->name());
   }
 
@@ -51,7 +58,7 @@
 
   scoped_refptr<const extensions::Extension> extension_;
   content::BrowserContext* browser_context_;
-  extensions::IconImage icon_image_;
+  scoped_ptr<extensions::IconImage> icon_image_;
 
   DISALLOW_COPY_AND_ASSIGN(AppItem);
 };
@@ -60,27 +67,57 @@
 
 ExtensionAppModelBuilder::ExtensionAppModelBuilder(
     content::BrowserContext* browser_context)
-    : browser_context_(browser_context) {
+    : browser_context_(browser_context), model_(nullptr) {
+  extensions::ExtensionRegistryFactory::GetForBrowserContext(browser_context_)
+      ->AddObserver(this);
 }
 
 ExtensionAppModelBuilder::~ExtensionAppModelBuilder() {
+  extensions::ExtensionRegistryFactory::GetForBrowserContext(browser_context_)
+      ->RemoveObserver(this);
 }
 
-void ExtensionAppModelBuilder::PopulateApps(app_list::AppListModel* model) {
+void ExtensionAppModelBuilder::RegisterAppListModel(
+    app_list::AppListModel* model) {
+  DCHECK(!model_);
+  model_ = model;
+
   ExtensionsDelegate* bridge = ExtensionsDelegate::Get(browser_context_);
   const extensions::ExtensionSet& extensions = bridge->GetInstalledExtensions();
   for (extensions::ExtensionSet::const_iterator iter = extensions.begin();
        iter != extensions.end();
        ++iter) {
-    // Chrome icon is currently disabled for homecard since it's not meaningful.
-    // http://crbug.com/421677
-    // TODO(mukai): use chrome/browser/extension_ui_util.
-    if ((*iter)->ShouldDisplayInAppLauncher() &&
-        (*iter)->id() != kChromeAppId) {
-      model->AddItem(scoped_ptr<app_list::AppListItem>(
-          new AppItem(*iter, browser_context_)));
-    }
+    AddItem(*iter);
   }
 }
 
+void ExtensionAppModelBuilder::AddItem(
+    scoped_refptr<const extensions::Extension> extension) {
+  // Chrome icon is currently disabled for homecard since it's not meaningful.
+  // http://crbug.com/421677
+  // TODO(mukai): use chrome/browser/extension_ui_util.
+  if (extension->ShouldDisplayInAppLauncher() &&
+      extension->id() != kChromeAppId) {
+    model_->AddItem(make_scoped_ptr(new AppItem(extension, browser_context_)));
+  }
+}
+
+void ExtensionAppModelBuilder::OnExtensionInstalled(
+    content::BrowserContext* browser_context,
+    const extensions::Extension* extension,
+    bool is_update) {
+  app_list::AppListItem* item = model_->FindItem(extension->id());
+  if (item)
+    static_cast<AppItem*>(item)->Reload(make_scoped_refptr(extension));
+  else
+    AddItem(make_scoped_refptr(extension));
+}
+
+void ExtensionAppModelBuilder::OnExtensionUninstalled(
+    content::BrowserContext* browser_context,
+    const extensions::Extension* extension,
+    extensions::UninstallReason reason) {
+  model_->DeleteItem(extension->id());
+}
+
 }  // namespace athena
diff --git a/athena/extensions/extensions_delegate.cc b/athena/extensions/extensions_delegate.cc
index 97bd0dda..a5c39b9 100644
--- a/athena/extensions/extensions_delegate.cc
+++ b/athena/extensions/extensions_delegate.cc
@@ -9,7 +9,7 @@
 namespace athena {
 namespace {
 
-ExtensionsDelegate* instance = NULL;
+ExtensionsDelegate* instance = nullptr;
 
 }  // namespace
 
@@ -20,7 +20,7 @@
 
 ExtensionsDelegate::~ExtensionsDelegate() {
   DCHECK(instance);
-  instance = NULL;
+  instance = nullptr;
 }
 
 // static
diff --git a/athena/extensions/public/extension_app_model_builder.h b/athena/extensions/public/extension_app_model_builder.h
index 0906add..abd89728 100644
--- a/athena/extensions/public/extension_app_model_builder.h
+++ b/athena/extensions/public/extension_app_model_builder.h
@@ -7,23 +7,45 @@
 
 #include "athena/home/public/app_model_builder.h"
 #include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "extensions/browser/extension_registry_observer.h"
 
 namespace content {
 class BrowserContext;
 }
 
+namespace extensions {
+class Extension;
+}
+
 namespace athena {
 
-class ATHENA_EXPORT ExtensionAppModelBuilder : public AppModelBuilder {
+class ATHENA_EXPORT ExtensionAppModelBuilder
+    : public AppModelBuilder,
+      public extensions::ExtensionRegistryObserver {
  public:
   explicit ExtensionAppModelBuilder(content::BrowserContext* browser_context);
   virtual ~ExtensionAppModelBuilder();
 
-  virtual void PopulateApps(app_list::AppListModel* model) override;
+  virtual void RegisterAppListModel(app_list::AppListModel* model) override;
 
  private:
+  void AddItem(scoped_refptr<const extensions::Extension> extension);
+
+  // extensions::ExtensionRegistryObserver:
+  virtual void OnExtensionInstalled(content::BrowserContext* browser_context,
+                                    const extensions::Extension* extension,
+                                    bool is_update) override;
+  virtual void OnExtensionUninstalled(
+      content::BrowserContext* browser_context,
+      const extensions::Extension* extension,
+      extensions::UninstallReason reason) override;
+
   content::BrowserContext* browser_context_;
 
+  // Unowned pointer to the app list model.
+  app_list::AppListModel* model_;
+
   DISALLOW_COPY_AND_ASSIGN(ExtensionAppModelBuilder);
 };
 
diff --git a/athena/extensions/shell/athena_shell_app_delegate.cc b/athena/extensions/shell/athena_shell_app_delegate.cc
index 5761166..28043011 100644
--- a/athena/extensions/shell/athena_shell_app_delegate.cc
+++ b/athena/extensions/shell/athena_shell_app_delegate.cc
@@ -26,7 +26,7 @@
     content::WebContents* web_contents,
     SkColor initial_color) {
   NOTIMPLEMENTED();
-  return NULL;
+  return nullptr;
 }
 
 void AthenaShellAppDelegate::RunFileChooser(
diff --git a/athena/extensions/shell/extensions_delegate_impl.cc b/athena/extensions/shell/extensions_delegate_impl.cc
index bd797f88..00af9cc 100644
--- a/athena/extensions/shell/extensions_delegate_impl.cc
+++ b/athena/extensions/shell/extensions_delegate_impl.cc
@@ -6,6 +6,7 @@
 
 #include "athena/extensions/shell/athena_shell_app_window_client.h"
 #include "base/macros.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/browser/install/extension_install_ui.h"
 #include "extensions/common/extension_set.h"
 #include "extensions/shell/browser/shell_extension_system.h"
@@ -22,7 +23,9 @@
     extensions::AppWindowClient::Set(&app_window_client_);
   }
 
-  virtual ~ShellExtensionsDelegate() { extensions::AppWindowClient::Set(NULL); }
+  virtual ~ShellExtensionsDelegate() {
+    extensions::AppWindowClient::Set(nullptr);
+  }
 
  private:
   // ExtensionsDelegate:
@@ -30,13 +33,10 @@
     return context_;
   }
   virtual const extensions::ExtensionSet& GetInstalledExtensions() override {
-    shell_extensions_.Clear();
-    if (extension_system_->extension().get())
-      shell_extensions_.Insert(extension_system_->extension());
-    return shell_extensions_;
+    return extensions::ExtensionRegistry::Get(context_)->enabled_extensions();
   }
   virtual bool LaunchApp(const std::string& app_id) override {
-    extension_system_->LaunchApp();
+    extension_system_->LaunchApp(app_id);
     return true;
   }
 
@@ -49,7 +49,6 @@
 
   content::BrowserContext* context_;
   extensions::ShellExtensionSystem* extension_system_;
-  extensions::ExtensionSet shell_extensions_;
 
   AthenaShellAppWindowClient app_window_client_;
 
diff --git a/athena/extensions/shell/shell_search_controller_factory.cc b/athena/extensions/shell/shell_search_controller_factory.cc
index d8df1ec..5b9422d 100644
--- a/athena/extensions/shell/shell_search_controller_factory.cc
+++ b/athena/extensions/shell/shell_search_controller_factory.cc
@@ -22,7 +22,7 @@
     app_list::AppListModel::SearchResults* results) {
   scoped_ptr<app_list::SearchController> controller(
       new app_list::SearchController(
-          search_box, results, NULL /* no history */));
+          search_box, results, nullptr /* no history */));
   controller->AddProvider(app_list::Mixer::MAIN_GROUP,
                           scoped_ptr<app_list::SearchProvider>(
                               new UrlSearchProvider(browser_context_)));
diff --git a/athena/extensions/shell/url_search_provider.cc b/athena/extensions/shell/url_search_provider.cc
index b3f0f9ee..8ff3b33b 100644
--- a/athena/extensions/shell/url_search_provider.cc
+++ b/athena/extensions/shell/url_search_provider.cc
@@ -91,7 +91,7 @@
       metrics::OmniboxEventProto::PageClassification page_classification,
       AutocompleteMatch* match,
       GURL* alternate_nav_url) override {}
-  virtual history::URLDatabase* InMemoryDatabase() override { return NULL; }
+  virtual history::URLDatabase* InMemoryDatabase() override { return nullptr; }
   virtual void DeleteMatchingURLsForKeywordFromHistory(
       history::KeywordID keyword_id,
       const base::string16& term) override {}
@@ -208,13 +208,13 @@
     : browser_context_(browser_context),
       // TODO(mukai): introduce the real parameters when it's necessary.
       template_url_service_(new TemplateURLService(
-          NULL /* prefs */,
+          nullptr /* prefs */,
           scoped_ptr<SearchTermsData>(new AthenaSearchTermsData()),
-          NULL /* KeywordWebDataService */,
+          nullptr /* KeywordWebDataService */,
           scoped_ptr<TemplateURLServiceClient>(
               new AthenaTemplateURLServiceClient()),
-          NULL /*GoogleURLTracker */,
-          NULL /* RapporService */,
+          nullptr /*GoogleURLTracker */,
+          nullptr /* RapporService */,
           base::Closure() /* dsp_change_callback */)),
       provider_(new ::SearchProvider(
           this,
@@ -248,7 +248,7 @@
   if (input_.type() == metrics::OmniboxInputType::URL) {
     // TODO(hashimoto): Componentize HistoryURLProvider and remove this code.
     AutocompleteMatch what_you_typed_match(
-        NULL, 0, false, AutocompleteMatchType::URL_WHAT_YOU_TYPED);
+        nullptr, 0, false, AutocompleteMatchType::URL_WHAT_YOU_TYPED);
     what_you_typed_match.destination_url = input_.canonicalized_url();
     what_you_typed_match.contents = input_.text();
     what_you_typed_match.relevance = kScoreForWhatYouTypedResult;
diff --git a/athena/extensions/test/test_extensions_delegate.cc b/athena/extensions/test/test_extensions_delegate.cc
index 95dd1a0..540a78ba7 100644
--- a/athena/extensions/test/test_extensions_delegate.cc
+++ b/athena/extensions/test/test_extensions_delegate.cc
@@ -19,7 +19,7 @@
  private:
   // ExtensionsDelegate:
   virtual content::BrowserContext* GetBrowserContext() const override {
-    return NULL;
+    return nullptr;
   }
   virtual const extensions::ExtensionSet& GetInstalledExtensions() override {
     return shell_extensions_;
diff --git a/athena/home/app_list_view_delegate.cc b/athena/home/app_list_view_delegate.cc
index bb1e0be..eead245f 100644
--- a/athena/home/app_list_view_delegate.cc
+++ b/athena/home/app_list_view_delegate.cc
@@ -34,7 +34,7 @@
     SearchControllerFactory* search_factory)
     : model_(new app_list::AppListModel),
       speech_ui_(new app_list::SpeechUIModel) {
-  model_builder->PopulateApps(model_.get());
+  model_builder->RegisterAppListModel(model_.get());
   model_->search_box()->SetHintText(
       l10n_util::GetStringUTF16(IDS_ATHENA_SEARCH_BOX_HINT));
   if (search_factory) {
diff --git a/athena/home/athena_start_page_view.cc b/athena/home/athena_start_page_view.cc
index 0891487f..381f2c9 100644
--- a/athena/home/athena_start_page_view.cc
+++ b/athena/home/athena_start_page_view.cc
@@ -84,8 +84,12 @@
                       public views::ButtonListener {
  public:
   explicit AppIconButton(app_list::AppListItem* item)
-      : ImageButton(this),
-        item_(item) {
+      : ImageButton(this), item_(nullptr) {
+    SetItem(item);
+  }
+
+  void SetItem(app_list::AppListItem* item) {
+    item_ = item;
     // TODO(mukai): icon should be resized.
     SetImage(STATE_NORMAL, &item->icon());
   }
@@ -191,8 +195,8 @@
   logo_->SetSize(gfx::Size(kWebViewWidth, kWebViewHeight));
   AddChildView(logo_);
 
-  search_results_view_ = new app_list::SearchResultListView(
-      NULL, view_delegate);
+  search_results_view_ =
+      new app_list::SearchResultListView(nullptr, view_delegate);
   // search_results_view_'s size will shrink after settings results.
   search_results_height_ = static_cast<views::View*>(
       search_results_view_)->GetHeightForWidth(kSearchBoxWidth);
@@ -209,11 +213,9 @@
   app_icon_container_->layer()->SetFillsBoundsOpaquely(false);
   app_icon_container_->SetLayoutManager(new views::BoxLayout(
       views::BoxLayout::kHorizontal, 0, 0, kIconMargin));
-  app_list::AppListItemList* top_level =
-      view_delegate->GetModel()->top_level_item_list();
-  for (size_t i = 0; i < std::min(top_level->item_count(), kMaxIconNum); ++i)
-    app_icon_container_->AddChildView(new AppIconButton(top_level->item_at(i)));
   app_icon_container_->SetSize(GetIconContainerSize());
+  UpdateAppIcons();
+  view_delegate->GetModel()->top_level_item_list()->AddObserver(this);
 
   control_icon_container_ = new views::View();
   control_icon_container_->SetPaintToLayer(true);
@@ -235,7 +237,9 @@
   AddChildView(search_box_container_);
 }
 
-AthenaStartPageView::~AthenaStartPageView() {}
+AthenaStartPageView::~AthenaStartPageView() {
+  delegate_->GetModel()->top_level_item_list()->RemoveObserver(this);
+}
 
 void AthenaStartPageView::RequestFocusOnSearchBox() {
   search_box_view_->search_box()->RequestFocus();
@@ -324,6 +328,28 @@
   return state;
 }
 
+void AthenaStartPageView::UpdateAppIcons() {
+  app_list::AppListItemList* top_level =
+      delegate_->GetModel()->top_level_item_list();
+  size_t max_items = std::min(top_level->item_count(), kMaxIconNum);
+  for (size_t i = 0; i < max_items; ++i) {
+    if (i < static_cast<size_t>(app_icon_container_->child_count())) {
+      AppIconButton* button =
+          static_cast<AppIconButton*>(app_icon_container_->child_at(i));
+      button->SetItem(top_level->item_at(i));
+    } else {
+      app_icon_container_->AddChildView(
+          new AppIconButton(top_level->item_at(i)));
+    }
+  }
+
+  while (max_items < static_cast<size_t>(app_icon_container_->child_count())) {
+    scoped_ptr<views::View> remover(
+        app_icon_container_->child_at(app_icon_container_->child_count() - 1));
+    app_icon_container_->RemoveChildView(remover.get());
+  }
+}
+
 void AthenaStartPageView::LayoutSearchResults(bool should_show_search_results) {
   if (should_show_search_results ==
       search_results_view_->layer()->GetTargetVisibility()) {
@@ -445,4 +471,25 @@
   LayoutSearchResults(!query.empty());
 }
 
+void AthenaStartPageView::OnListItemAdded(size_t index,
+                                          app_list::AppListItem* item) {
+  UpdateAppIcons();
+}
+
+void AthenaStartPageView::OnListItemRemoved(size_t index,
+                                            app_list::AppListItem* item) {
+  UpdateAppIcons();
+}
+
+void AthenaStartPageView::OnListItemMoved(size_t from_index,
+                                          size_t to_index,
+                                          app_list::AppListItem* item) {
+  UpdateAppIcons();
+}
+
+// static
+size_t AthenaStartPageView::GetMaxIconNumForTest() {
+  return kMaxIconNum;
+}
+
 }  // namespace athena
diff --git a/athena/home/athena_start_page_view.h b/athena/home/athena_start_page_view.h
index f92a73f..4e0f19d4 100644
--- a/athena/home/athena_start_page_view.h
+++ b/athena/home/athena_start_page_view.h
@@ -8,11 +8,13 @@
 #include "athena/athena_export.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "ui/app_list/app_list_item_list_observer.h"
 #include "ui/app_list/views/search_box_view_delegate.h"
 #include "ui/gfx/animation/tween.h"
 #include "ui/views/view.h"
 
 namespace app_list {
+class AppListModelObserver;
 class AppListViewDelegate;
 class SearchBoxView;
 class SearchResultListView;
@@ -22,7 +24,8 @@
 
 class ATHENA_EXPORT AthenaStartPageView
     : public views::View,
-      public app_list::SearchBoxViewDelegate {
+      public app_list::SearchBoxViewDelegate,
+      public app_list::AppListItemListObserver {
  public:
   class Observer {
    public:
@@ -51,6 +54,8 @@
 
   static const char kViewClassName[];
 
+  static size_t GetMaxIconNumForTest();
+
   // A struct which bundles the layout data of subviews.
   struct LayoutData {
     gfx::Rect search_box;
@@ -69,6 +74,8 @@
   // Returns the bounds for |VISIBLE_CENTERED|.
   LayoutData CreateCenteredBounds(int width);
 
+  void UpdateAppIcons();
+
   // Schedules the animation for the layout the search box and the search
   // results.
   void LayoutSearchResults(bool should_show_search_results);
@@ -84,6 +91,15 @@
   // app_list::SearchBoxViewDelegate:
   virtual void QueryChanged(app_list::SearchBoxView* sender) override;
 
+  // app_list::AppListItemListObserver:
+  virtual void OnListItemAdded(size_t index,
+                               app_list::AppListItem* item) override;
+  virtual void OnListItemRemoved(size_t index,
+                                 app_list::AppListItem* item) override;
+  virtual void OnListItemMoved(size_t from_index,
+                               size_t to_index,
+                               app_list::AppListItem* item) override;
+
   // Not owned.
   app_list::AppListViewDelegate* delegate_;
 
diff --git a/athena/home/athena_start_page_view_unittest.cc b/athena/home/athena_start_page_view_unittest.cc
index c91177e..d611c3b 100644
--- a/athena/home/athena_start_page_view_unittest.cc
+++ b/athena/home/athena_start_page_view_unittest.cc
@@ -19,13 +19,6 @@
 
 namespace athena {
 
-namespace {
-
-// The number of dummy applications in this tetst.
-const size_t kNumApps = 10;
-
-}
-
 class AthenaTestViewDelegate : public app_list::test::AppListTestViewDelegate {
  public:
   AthenaTestViewDelegate() {}
@@ -48,11 +41,8 @@
   // testing::Test:
   virtual void SetUp() override {
     test::AthenaTestBase::SetUp();
-    app_list::test::AppListTestModel* model = view_delegate_.GetTestModel();
-    for (size_t i = 0; i < kNumApps; ++i) {
-      model->AddItem(new app_list::test::AppListTestModel::AppListTestItem(
-          base::StringPrintf("id-%" PRIuS, i), model));
-    }
+    for (size_t i = 0; i < GetMaxIconNum(); ++i)
+      AddTestItem(i);
 
     view_.reset(new AthenaStartPageView(&view_delegate_));
     SetSize(gfx::Size(1280, 800));
@@ -68,6 +58,24 @@
     view_->Layout();
   }
 
+  void AddTestItem(size_t index) {
+    app_list::test::AppListTestModel* model = view_delegate_.GetTestModel();
+    model->AddItem(new app_list::test::AppListTestModel::AppListTestItem(
+        GetAppIdFor(index), model));
+  }
+
+  static size_t GetMaxIconNum() {
+    return AthenaStartPageView::GetMaxIconNumForTest();
+  }
+
+  static std::string GetAppIdFor(size_t index) {
+    return base::StringPrintf("id-%" PRIuS, index);
+  }
+
+  app_list::AppListModel* GetModel() { return view_delegate_.GetTestModel(); }
+
+  views::View* GetIconsContainer() { return view_->app_icon_container_; }
+
   gfx::Rect GetIconsBounds() const {
     return view_->app_icon_container_->layer()->GetTargetBounds();
   }
@@ -244,4 +252,28 @@
   EXPECT_EQ(1.0f, layout_state());
 }
 
+TEST_F(AthenaStartPageViewTest, AppAddRemove) {
+  gfx::Rect icons_bounds = GetIconsBounds();
+  EXPECT_EQ(GetMaxIconNum(),
+            static_cast<size_t>(GetIconsContainer()->child_count()));
+
+  GetModel()->DeleteItem(GetAppIdFor(1));
+
+  // The removed icon disappear, however its bound should not change.
+  EXPECT_EQ(GetMaxIconNum() - 1,
+            static_cast<size_t>(GetIconsContainer()->child_count()));
+  EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString());
+
+  AddTestItem(GetMaxIconNum() + 1);
+  EXPECT_EQ(GetMaxIconNum(),
+            static_cast<size_t>(GetIconsContainer()->child_count()));
+  EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString());
+
+  // Adding more doesn't cause any effects.
+  AddTestItem(GetMaxIconNum() + 2);
+  EXPECT_EQ(GetMaxIconNum(),
+            static_cast<size_t>(GetIconsContainer()->child_count()));
+  EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString());
+}
+
 }  // namespace athena
diff --git a/athena/home/home_card_impl.cc b/athena/home/home_card_impl.cc
index 9b2e49f..d092ec06 100644
--- a/athena/home/home_card_impl.cc
+++ b/athena/home/home_card_impl.cc
@@ -32,7 +32,7 @@
 namespace athena {
 namespace {
 
-HomeCard* instance = NULL;
+HomeCard* instance = nullptr;
 
 gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds,
                             HomeCard::State state) {
@@ -67,9 +67,7 @@
 // vertically.
 class HomeCardLayoutManager : public aura::LayoutManager {
  public:
-  HomeCardLayoutManager()
-      : home_card_(NULL),
-        minimized_layer_(NULL) {}
+  HomeCardLayoutManager() : home_card_(nullptr), minimized_layer_(nullptr) {}
 
   virtual ~HomeCardLayoutManager() {}
 
@@ -116,7 +114,7 @@
   }
   virtual void OnWillRemoveWindowFromLayout(aura::Window* child) override {
     if (home_card_ == child)
-      home_card_ = NULL;
+      home_card_ = nullptr;
   }
   virtual void OnWindowRemovedFromLayout(aura::Window* child) override {
   }
@@ -236,9 +234,9 @@
       search_factory_(search_factory.Pass()),
       state_(HIDDEN),
       original_state_(VISIBLE_MINIMIZED),
-      home_card_widget_(NULL),
-      home_card_view_(NULL),
-      layout_manager_(NULL) {
+      home_card_widget_(nullptr),
+      home_card_view_(nullptr),
+      layout_manager_(nullptr) {
   DCHECK(!instance);
   instance = this;
   WindowManager::Get()->AddObserver(this);
@@ -252,7 +250,7 @@
   // Reset the view delegate first as it access search provider during
   // shutdown.
   view_delegate_.reset();
-  instance = NULL;
+  instance = nullptr;
 }
 
 void HomeCardImpl::Init() {
@@ -290,7 +288,7 @@
 }
 
 aura::Window* HomeCardImpl::GetHomeCardWindowForTest() const {
-  return home_card_widget_ ? home_card_widget_->GetNativeWindow() : NULL;
+  return home_card_widget_ ? home_card_widget_->GetNativeWindow() : nullptr;
 }
 
 void HomeCardImpl::InstallAccelerators() {
@@ -439,7 +437,7 @@
 void HomeCard::Shutdown() {
   DCHECK(instance);
   delete instance;
-  instance = NULL;
+  instance = nullptr;
 }
 
 // static
diff --git a/athena/home/home_card_unittest.cc b/athena/home/home_card_unittest.cc
index b0467d8..963fec1 100644
--- a/athena/home/home_card_unittest.cc
+++ b/athena/home/home_card_unittest.cc
@@ -109,7 +109,7 @@
   EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState());
 
   athena::ActivityFactory::Get()->CreateWebActivity(
-      NULL, base::string16(), GURL("http://www.google.com/"));
+      nullptr, base::string16(), GURL("http://www.google.com/"));
   EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
 }
 
@@ -309,7 +309,7 @@
 
   aura::test::TestWindowDelegate delegate;
   scoped_ptr<aura::Window> modal(test::CreateTransientWindow(
-      &delegate, NULL, ui::MODAL_TYPE_SYSTEM, false));
+      &delegate, nullptr, ui::MODAL_TYPE_SYSTEM, false));
   modal->Show();
   wm::ActivateWindow(modal.get());
   EXPECT_TRUE(wm::IsActiveWindow(modal.get()));
diff --git a/athena/home/public/app_model_builder.h b/athena/home/public/app_model_builder.h
index 5cfa890..50c38bf 100644
--- a/athena/home/public/app_model_builder.h
+++ b/athena/home/public/app_model_builder.h
@@ -20,8 +20,9 @@
  public:
   virtual ~AppModelBuilder() {}
 
-  // Fills |model| with the currently available app_list::AppListItems.
-  virtual void PopulateApps(app_list::AppListModel* model) = 0;
+  // Registers |model| to the builder so that the builder can fill the currently
+  // available app_list::AppListItems.
+  virtual void RegisterAppListModel(app_list::AppListModel* model) = 0;
 };
 
 }  // namespace athena
diff --git a/athena/input/accelerator_manager_impl.cc b/athena/input/accelerator_manager_impl.cc
index bd6fbe63..3bb7e62a 100644
--- a/athena/input/accelerator_manager_impl.cc
+++ b/athena/input/accelerator_manager_impl.cc
@@ -102,7 +102,7 @@
       const ui::Accelerator& accelerator) const override {
     return accelerator_manager_->IsRegistered(accelerator, AF_NONE)
                ? accelerator_manager_
-               : NULL;
+               : nullptr;
   }
 
  private:
@@ -126,7 +126,8 @@
       bool desktop_widget) override {
     return new views::FocusManager(
         widget,
-        desktop_widget ? NULL : new FocusManagerDelegate(accelerator_manager_));
+        desktop_widget ? nullptr
+                       : new FocusManagerDelegate(accelerator_manager_));
   }
 
  private:
@@ -246,7 +247,7 @@
   accelerator_filter_.reset();
   // Reset to use the default focus manager because the athena's
   // FocusManager has the reference to this object.
-  views::FocusManagerFactory::Install(NULL);
+  views::FocusManagerFactory::Install(nullptr);
 }
 
 void AcceleratorManagerImpl::Init() {
diff --git a/athena/input/input_manager_impl.cc b/athena/input/input_manager_impl.cc
index 0815a7a..bd901b86 100644
--- a/athena/input/input_manager_impl.cc
+++ b/athena/input/input_manager_impl.cc
@@ -12,7 +12,7 @@
 namespace athena {
 namespace {
 
-InputManager* instance = NULL;
+InputManager* instance = nullptr;
 
 }  // namespace
 
@@ -27,7 +27,7 @@
 InputManagerImpl::~InputManagerImpl() {
   DCHECK_EQ(instance, this);
   Shutdown();
-  instance = NULL;
+  instance = nullptr;
 }
 
 void InputManagerImpl::Init() {
@@ -83,7 +83,7 @@
 
 ui::EventTargeter* InputManagerImpl::GetEventTargeter() {
   NOTREACHED();
-  return NULL;
+  return nullptr;
 }
 
 void InputManagerImpl::OnEvent(ui::Event* event) {
diff --git a/athena/main/athena_launcher.cc b/athena/main/athena_launcher.cc
index 28059df2..b03ddea 100644
--- a/athena/main/athena_launcher.cc
+++ b/athena/main/athena_launcher.cc
@@ -63,7 +63,7 @@
 
 DEFINE_OWNED_WINDOW_PROPERTY_KEY(athena::AthenaEnvState,
                                  kAthenaEnvStateKey,
-                                 NULL);
+                                 nullptr);
 
 // This class observes the change of the virtual keyboard and distribute the
 // change to appropriate modules of athena.
diff --git a/athena/main/athena_main.cc b/athena/main/athena_main.cc
index addb6fe..c8cc2e8 100644
--- a/athena/main/athena_main.cc
+++ b/athena/main/athena_main.cc
@@ -61,7 +61,7 @@
       content::BrowserContext* context,
       const extensions::Extension* extension) override {
     NOTIMPLEMENTED();
-    return NULL;
+    return nullptr;
   }
 
   // Adds the window to the desktop.
@@ -69,6 +69,8 @@
     NOTIMPLEMENTED();
   }
 
+  virtual void RemoveAppWindow(extensions::AppWindow* window) override {}
+
   // Closes and destroys the app windows.
   virtual void CloseAppWindows() override {}
 
diff --git a/athena/main/athena_views_delegate.cc b/athena/main/athena_views_delegate.cc
index e84322c..a8b503c5 100644
--- a/athena/main/athena_views_delegate.cc
+++ b/athena/main/athena_views_delegate.cc
@@ -44,7 +44,7 @@
 void ShutdownAthenaViewsDelegate() {
   CHECK(views::ViewsDelegate::views_delegate);
   delete views::ViewsDelegate::views_delegate;
-  views::ViewsDelegate::views_delegate = NULL;
+  views::ViewsDelegate::views_delegate = nullptr;
 }
 
 }  // namespace athena
diff --git a/athena/resource_manager/memory_pressure_notifier_unittest.cc b/athena/resource_manager/memory_pressure_notifier_unittest.cc
index 0cbf3e7..0678740f0 100644
--- a/athena/resource_manager/memory_pressure_notifier_unittest.cc
+++ b/athena/resource_manager/memory_pressure_notifier_unittest.cc
@@ -83,7 +83,7 @@
 // Our testing base.
 class MemoryPressureTest : public AthenaTestBase {
  public:
-  MemoryPressureTest() : test_resource_manager_delegate_(NULL) {}
+  MemoryPressureTest() : test_resource_manager_delegate_(nullptr) {}
   virtual ~MemoryPressureTest() {}
 
   // AthenaTestBase:
diff --git a/athena/resource_manager/resource_manager_impl.cc b/athena/resource_manager/resource_manager_impl.cc
index b88d7d7..771ad22 100644
--- a/athena/resource_manager/resource_manager_impl.cc
+++ b/athena/resource_manager/resource_manager_impl.cc
@@ -147,7 +147,7 @@
 };
 
 namespace {
-ResourceManagerImpl* instance = NULL;
+ResourceManagerImpl* instance = nullptr;
 
 // We allow this many activities to be visible. All others must be at state of
 // invisible or below.
@@ -367,7 +367,7 @@
   }
 
   // Check if / which activity we want to unload.
-  Activity* oldest_media_activity = NULL;
+  Activity* oldest_media_activity = nullptr;
   std::vector<Activity*> unloadable_activities;
   for (std::vector<Activity*>::iterator it = activity_list_.begin();
        it != activity_list_.end(); ++it) {
@@ -476,14 +476,14 @@
 void ResourceManager::Shutdown() {
   DCHECK(instance);
   delete instance;
-  instance = NULL;
+  instance = nullptr;
 }
 
 ResourceManager::ResourceManager() {}
 
 ResourceManager::~ResourceManager() {
   DCHECK(instance);
-  instance = NULL;
+  instance = nullptr;
 }
 
 }  // namespace athena
diff --git a/athena/screen/modal_window_controller.cc b/athena/screen/modal_window_controller.cc
index 71a19ff5..90357e9 100644
--- a/athena/screen/modal_window_controller.cc
+++ b/athena/screen/modal_window_controller.cc
@@ -18,7 +18,7 @@
 
 DEFINE_OWNED_WINDOW_PROPERTY_KEY(ModalWindowController,
                                  kModalWindowControllerKey,
-                                 NULL);
+                                 nullptr);
 
 }  // namespace
 
@@ -31,8 +31,8 @@
 }
 
 ModalWindowController::ModalWindowController(int priority)
-    : modal_container_(NULL),
-      dimmer_window_(new aura::Window(NULL)),
+    : modal_container_(nullptr),
+      dimmer_window_(new aura::Window(nullptr)),
       dimmed_(false) {
   ScreenManager::ContainerParams params("ModalContainer", priority);
   params.can_activate_children = true;
@@ -61,14 +61,14 @@
   DCHECK_NE(child, dimmer_window_);
   if (IsChildWindow(child)) {
     child->AddObserver(this);
-    UpdateDimming(NULL);
+    UpdateDimming(nullptr);
   }
 }
 
 void ModalWindowController::OnWindowVisibilityChanged(aura::Window* window,
                                                       bool visible) {
   if (IsChildWindow(window))
-    UpdateDimming(NULL);
+    UpdateDimming(nullptr);
 }
 
 void ModalWindowController::OnWindowBoundsChanged(aura::Window* window,
@@ -113,8 +113,8 @@
     modal_container_->RemoveObserver(this);
     modal_container_->parent()->RemoveChild(modal_container_);
     base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, modal_container_);
-    modal_container_ = NULL;
-    dimmer_window_ = NULL;
+    modal_container_ = nullptr;
+    dimmer_window_ = nullptr;
   }
 }
 
diff --git a/athena/screen/modal_window_controller_unittest.cc b/athena/screen/modal_window_controller_unittest.cc
index b73399a6..b2b36c6 100644
--- a/athena/screen/modal_window_controller_unittest.cc
+++ b/athena/screen/modal_window_controller_unittest.cc
@@ -23,7 +23,7 @@
 TEST_F(ModalWindowControllerTest, ModalContainer) {
   aura::test::EventCountDelegate delegate;
   scoped_ptr<aura::Window> modal(test::CreateTransientWindow(
-      &delegate, NULL, ui::MODAL_TYPE_SYSTEM, false));
+      &delegate, nullptr, ui::MODAL_TYPE_SYSTEM, false));
 
   aura::Window* modal_container = FindContainerByPriority(CP_SYSTEM_MODAL);
   EXPECT_TRUE(modal_container);
@@ -49,9 +49,9 @@
 
   // Create two.
   modal = test::CreateTransientWindow(
-              &delegate, NULL, ui::MODAL_TYPE_SYSTEM, false).Pass();
+              &delegate, nullptr, ui::MODAL_TYPE_SYSTEM, false).Pass();
   scoped_ptr<aura::Window> modal2(test::CreateTransientWindow(
-      &delegate, NULL, ui::MODAL_TYPE_SYSTEM, false));
+      &delegate, nullptr, ui::MODAL_TYPE_SYSTEM, false));
 
   modal_container = FindContainerByPriority(CP_SYSTEM_MODAL);
   EXPECT_TRUE(modal_container);
@@ -94,7 +94,8 @@
   aura::Window* default_container = FindContainerByPriority(CP_DEFAULT);
   EXPECT_TRUE(default_container);
 
-  scoped_ptr<aura::Window> normal_w1(test::CreateNormalWindow(&delegate, NULL));
+  scoped_ptr<aura::Window> normal_w1(
+      test::CreateNormalWindow(&delegate, nullptr));
   EXPECT_EQ(default_container, normal_w1->parent());
 
   scoped_ptr<aura::Window> normal_m1(test::CreateTransientWindow(
@@ -119,7 +120,7 @@
   // Creating a modal with always on top creates the modal dialog on top
   // most dialog container.
   scoped_ptr<aura::Window> top_m0(test::CreateTransientWindow(
-      &delegate, NULL, ui::MODAL_TYPE_SYSTEM, true));
+      &delegate, nullptr, ui::MODAL_TYPE_SYSTEM, true));
 
   aura::Window* top_modal_container = FindContainerByPriority(CP_END + 1);
   EXPECT_EQ(top_modal_container, top_m0->parent());
diff --git a/athena/screen/screen_manager_impl.cc b/athena/screen/screen_manager_impl.cc
index 9cc22e73..a650e96 100644
--- a/athena/screen/screen_manager_impl.cc
+++ b/athena/screen/screen_manager_impl.cc
@@ -33,9 +33,9 @@
 
 DEFINE_OWNED_WINDOW_PROPERTY_KEY(ScreenManager::ContainerParams,
                                  kContainerParamsKey,
-                                 NULL);
+                                 nullptr);
 
-ScreenManagerImpl* instance = NULL;
+ScreenManagerImpl* instance = nullptr;
 
 // A functor to find a container that has the higher priority.
 struct HigherPriorityFinder {
@@ -111,7 +111,7 @@
   virtual aura::Window* GetNextActivatableWindow(
       aura::Window* ignore) const override {
     aura::Window* next = wm::BaseFocusRules::GetNextActivatableWindow(ignore);
-    // TODO(oshima): Search from activatable containers if |next| is NULL.
+    // TODO(oshima): Search from activatable containers if |next| is nullptr.
     // crbug.com/424750.
     return next;
   }
@@ -195,7 +195,7 @@
     // there is no target found so that windows behind it will not be searched.
     const ScreenManager::ContainerParams* params =
         static_cast<aura::Window*>(root)->GetProperty(kContainerParamsKey);
-    return (params && params->block_events) ? root : NULL;
+    return (params && params->block_events) ? root : nullptr;
   }
 
   // Not owned.
@@ -216,13 +216,13 @@
 }
 
 ScreenManagerImpl::~ScreenManagerImpl() {
-  aura::client::SetScreenPositionClient(root_window_, NULL);
-  aura::client::SetWindowTreeClient(root_window_, NULL);
+  aura::client::SetScreenPositionClient(root_window_, nullptr);
+  aura::client::SetWindowTreeClient(root_window_, nullptr);
   wm::FocusController* focus_controller =
       static_cast<wm::FocusController*>(focus_client_.get());
   root_window_->RemovePreTargetHandler(focus_controller);
-  aura::client::SetActivationClient(root_window_, NULL);
-  aura::client::SetFocusClient(root_window_, NULL);
+  aura::client::SetActivationClient(root_window_, nullptr);
+  aura::client::SetFocusClient(root_window_, nullptr);
   aura::Window::Windows children = root_window_->children();
   // Close All children:
   for (aura::Window::Windows::iterator iter = children.begin();
@@ -230,7 +230,7 @@
        ++iter) {
     delete *iter;
   }
-  instance = NULL;
+  instance = nullptr;
 }
 
 void ScreenManagerImpl::Init() {
@@ -260,7 +260,7 @@
     if (window->GetProperty(kContainerParamsKey)->z_order_priority == priority)
       return window;
   }
-  return NULL;
+  return nullptr;
 }
 
 aura::Window* ScreenManagerImpl::CreateContainer(
@@ -277,7 +277,7 @@
   // Default parent must specify modal_container_priority.
   DCHECK(!params.default_parent || params.modal_container_priority != -1);
 
-  aura::Window* container = new aura::Window(NULL);
+  aura::Window* container = new aura::Window(nullptr);
   CHECK_GE(params.z_order_priority, 0);
   container->Init(aura::WINDOW_LAYER_NOT_DRAWN);
   container->SetName(params.name);
diff --git a/athena/screen/screen_manager_unittest.cc b/athena/screen/screen_manager_unittest.cc
index c8787da..83b9ce3 100644
--- a/athena/screen/screen_manager_unittest.cc
+++ b/athena/screen/screen_manager_unittest.cc
@@ -104,8 +104,8 @@
   aura::Window* activatable_container =
       ScreenManager::Get()->CreateContainer(activatable);
 
-  scoped_ptr<aura::Window> window(
-      CreateWindow(no_activatable_container, NULL, gfx::Rect(0, 0, 100, 100)));
+  scoped_ptr<aura::Window> window(CreateWindow(
+      no_activatable_container, nullptr, gfx::Rect(0, 0, 100, 100)));
   EXPECT_FALSE(wm::CanActivateWindow(window.get()));
 
   activatable_container->AddChild(window.get());
@@ -155,7 +155,7 @@
   params.default_parent = true;
   params.modal_container_priority = CP_END + 2;
   aura::Window* new_default = ScreenManager::Get()->CreateContainer(params);
-  aura::Window* w = test::CreateNormalWindow(NULL, NULL).release();
+  aura::Window* w = test::CreateNormalWindow(nullptr, nullptr).release();
   EXPECT_EQ(new_default, w->parent());
   delete new_default;
 
@@ -170,7 +170,7 @@
       public testing::WithParamInterface<bool> {
  public:
   ScreenManagerTargeterTest()
-      : targeter_(GetParam() ? NULL : new aura::WindowTargeter) {}
+      : targeter_(GetParam() ? nullptr : new aura::WindowTargeter) {}
   virtual ~ScreenManagerTargeterTest() {}
 
  protected:
diff --git a/athena/screen_lock/screen_lock_manager_base.cc b/athena/screen_lock/screen_lock_manager_base.cc
index 80a847b..abd221b 100644
--- a/athena/screen_lock/screen_lock_manager_base.cc
+++ b/athena/screen_lock/screen_lock_manager_base.cc
@@ -9,7 +9,7 @@
 namespace athena {
 namespace {
 
-ScreenLockManager* instance = NULL;
+ScreenLockManager* instance = nullptr;
 
 }  // namespace
 
@@ -20,7 +20,7 @@
 
 ScreenLockManagerBase::~ScreenLockManagerBase() {
   DCHECK_EQ(instance, this);
-  instance = NULL;
+  instance = nullptr;
 }
 
 // static
diff --git a/athena/screen_lock/shell/shell_screen_lock_manager.cc b/athena/screen_lock/shell/shell_screen_lock_manager.cc
index bb9c2356..e9a9673 100644
--- a/athena/screen_lock/shell/shell_screen_lock_manager.cc
+++ b/athena/screen_lock/shell/shell_screen_lock_manager.cc
@@ -8,7 +8,7 @@
 namespace athena {
 
 ScreenLockManager* ScreenLockManager::Create() {
-  return NULL;
+  return nullptr;
 }
 
 }  // namespace athena
\ No newline at end of file
diff --git a/athena/system/background_controller.cc b/athena/system/background_controller.cc
index 75740dc..ca41109 100644
--- a/athena/system/background_controller.cc
+++ b/athena/system/background_controller.cc
@@ -16,7 +16,7 @@
 
 class BackgroundView : public views::View {
  public:
-  BackgroundView() : system_info_view_(NULL) {
+  BackgroundView() : system_info_view_(nullptr) {
     system_info_view_ =
         SystemUI::Get()->CreateSystemInfoView(SystemUI::COLOR_SCHEME_LIGHT);
     AddChildView(system_info_view_);
diff --git a/athena/system/network_selector.cc b/athena/system/network_selector.cc
index ef45bfb..dc93948 100644
--- a/athena/system/network_selector.cc
+++ b/athena/system/network_selector.cc
@@ -57,10 +57,10 @@
                const base::Callback<void(bool)>& callback)
       : network_(network),
         callback_(callback),
-        connect_(NULL),
-        cancel_(NULL),
-        textfield_(NULL),
-        error_msg_(NULL),
+        connect_(nullptr),
+        cancel_(nullptr),
+        textfield_(nullptr),
+        error_msg_(nullptr),
         weak_ptr_(this) {
     const int kHorizontal = 5;
     const int kVertical = 0;
@@ -163,7 +163,7 @@
       if (error_msg_) {
         RemoveChildView(error_msg_);
         delete error_msg_;
-        error_msg_ = NULL;
+        error_msg_ = nullptr;
       }
       connect_->SetEnabled(false);
       NetworkHandler::Get()->network_configuration_handler()->SetNetworkProfile(
@@ -317,7 +317,7 @@
                         public views::DialogDelegate {
  public:
   NetworkSelector()
-      : scroll_content_(NULL), scroller_(NULL), network_list_(this) {
+      : scroll_content_(nullptr), scroller_(nullptr), network_list_(this) {
     CreateNetworkList();
     CreateWidget();
 
@@ -335,7 +335,7 @@
   void CreateWidget() {
     // Same as CreateDialogWidgetWithBounds() with an empty |bounds|.
     views::Widget* widget = views::DialogDelegate::CreateDialogWidget(
-        this, athena::ScreenManager::Get()->GetContext(), NULL);
+        this, athena::ScreenManager::Get()->GetContext(), nullptr);
     widget->Show();
     widget->CenterWindow(gfx::Size(400, 400));
   }
diff --git a/athena/system/status_icon_container_view.cc b/athena/system/status_icon_container_view.cc
index a7c5f85..8b022a1 100644
--- a/athena/system/status_icon_container_view.cc
+++ b/athena/system/status_icon_container_view.cc
@@ -224,7 +224,8 @@
   AddChildView(CreateLabel(color_scheme, "Network:"));
   views::Label* network_label = CreateLabel(color_scheme, std::string());
   AddChildView(network_label);
-  network_status_.reset(new NetworkStatus(network_label));
+  if (chromeos::NetworkHandler::IsInitialized())
+    network_status_.reset(new NetworkStatus(network_label));
 
   views::ImageView* battery_view = new views::ImageView();
   AddChildView(battery_view);
diff --git a/athena/system/system_ui_impl.cc b/athena/system/system_ui_impl.cc
index 64653ba..5bbd3ee 100644
--- a/athena/system/system_ui_impl.cc
+++ b/athena/system/system_ui_impl.cc
@@ -21,7 +21,7 @@
 namespace athena {
 namespace {
 
-SystemUI* instance = NULL;
+SystemUI* instance = nullptr;
 
 // View which positions the TimeView on the left and the StatusIconView on the
 // right.
@@ -74,7 +74,7 @@
  public:
   SystemUIImpl(scoped_refptr<base::TaskRunner> blocking_task_runner)
       : orientation_controller_(new OrientationController()),
-        background_container_(NULL) {
+        background_container_(nullptr) {
     orientation_controller_->InitWith(blocking_task_runner);
   }
 
@@ -144,7 +144,7 @@
 void SystemUI::Shutdown() {
   CHECK(instance);
   delete instance;
-  instance = NULL;
+  instance = nullptr;
 }
 
 }  // namespace athena
diff --git a/athena/test/base/activity_lifetime_tracker.cc b/athena/test/base/activity_lifetime_tracker.cc
index f3618ec..e5aeea5f 100644
--- a/athena/test/base/activity_lifetime_tracker.cc
+++ b/athena/test/base/activity_lifetime_tracker.cc
@@ -8,8 +8,8 @@
 
 namespace athena {
 
-ActivityLifetimeTracker::ActivityLifetimeTracker() : new_activity_(NULL),
-                                                     deleted_activity_(NULL) {
+ActivityLifetimeTracker::ActivityLifetimeTracker()
+    : new_activity_(nullptr), deleted_activity_(nullptr) {
   ActivityManager::Get()->AddObserver(this);
 }
 
@@ -27,13 +27,13 @@
 
 Activity* ActivityLifetimeTracker::GetNewActivityAndReset() {
   Activity* activity = new_activity_;
-  new_activity_ = NULL;
+  new_activity_ = nullptr;
   return activity;
 }
 
 void* ActivityLifetimeTracker::GetDeletedActivityAndReset() {
   void* activity = deleted_activity_;
-  deleted_activity_ = NULL;
+  deleted_activity_ = nullptr;
   return activity;
 }
 
diff --git a/athena/test/base/activity_lifetime_tracker.h b/athena/test/base/activity_lifetime_tracker.h
index 670385f..2c1ae165e 100644
--- a/athena/test/base/activity_lifetime_tracker.h
+++ b/athena/test/base/activity_lifetime_tracker.h
@@ -32,10 +32,10 @@
   void* GetDeletedActivityAndReset();
 
  private:
-  // The activity which got created if not NULL.
+  // The activity which got created if not nullptr.
   Activity* new_activity_;
 
-  // An old activity which got unloaded if not NULL.
+  // An old activity which got unloaded if not nullptr.
   void* deleted_activity_;
 
   DISALLOW_COPY_AND_ASSIGN(ActivityLifetimeTracker);
diff --git a/athena/test/base/athena_test_helper.cc b/athena/test/base/athena_test_helper.cc
index dd9177e..538ed1c9 100644
--- a/athena/test/base/athena_test_helper.cc
+++ b/athena/test/base/athena_test_helper.cc
@@ -15,7 +15,6 @@
 #include "base/run_loop.h"
 #include "base/threading/thread.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/network/network_handler.h"
 #include "ui/aura/env.h"
 #include "ui/aura/input_state_lookup.h"
 #include "ui/aura/test/env_test_helper.h"
@@ -52,7 +51,6 @@
   file_thread_->StartWithOptions(options);
 
   chromeos::DBusThreadManager::Initialize();
-  chromeos::NetworkHandler::Initialize();
   ui::InitializeInputMethodForTesting();
   aura::Env::CreateInstance(true);
   aura::Env::GetInstance()->set_context_factory(context_factory);
@@ -67,7 +65,7 @@
   athena::ExtensionsDelegate::CreateExtensionsDelegateForTest();
   athena::StartAthenaSession(new SampleActivityFactory(),
                              make_scoped_ptr(new TestAppModelBuilder()),
-                             CreateSearchControllerFactory(NULL));
+                             CreateSearchControllerFactory(nullptr));
 }
 
 void AthenaTestHelper::TearDown() {
@@ -81,7 +79,6 @@
 #endif
 
   ui::ShutdownInputMethodForTesting();
-  chromeos::NetworkHandler::Shutdown();
   chromeos::DBusThreadManager::Shutdown();
 }
 
diff --git a/athena/test/base/sample_activity.cc b/athena/test/base/sample_activity.cc
index 2c4bd65..43495e7b 100644
--- a/athena/test/base/sample_activity.cc
+++ b/athena/test/base/sample_activity.cc
@@ -18,7 +18,7 @@
     : color_(color),
       contents_color_(contents_color),
       title_(title),
-      contents_view_(NULL),
+      contents_view_(nullptr),
       current_state_(ACTIVITY_UNLOADED) {
 }
 
@@ -46,12 +46,12 @@
 }
 
 aura::Window* SampleActivity::GetWindow() {
-  return !contents_view_ ? NULL
+  return !contents_view_ ? nullptr
                          : contents_view_->GetWidget()->GetNativeWindow();
 }
 
 content::WebContents* SampleActivity::GetWebContents() {
-  return NULL;
+  return nullptr;
 }
 
 void SampleActivity::Init() {
@@ -83,7 +83,7 @@
 }
 
 views::Widget* SampleActivity::CreateWidget() {
-  return NULL;
+  return nullptr;
 }
 
 gfx::ImageSkia SampleActivity::GetOverviewModeImage() {
diff --git a/athena/test/base/test_app_model_builder.cc b/athena/test/base/test_app_model_builder.cc
index 6f2c37e..beaa846e 100644
--- a/athena/test/base/test_app_model_builder.cc
+++ b/athena/test/base/test_app_model_builder.cc
@@ -96,7 +96,7 @@
 TestAppModelBuilder::~TestAppModelBuilder() {
 }
 
-void TestAppModelBuilder::PopulateApps(app_list::AppListModel* model) {
+void TestAppModelBuilder::RegisterAppListModel(app_list::AppListModel* model) {
   for (int i = 0; i < static_cast<int>(DummyItem::LAST_TYPE); ++i) {
     model->AddItem(scoped_ptr<app_list::AppListItem>(
         new DummyItem(static_cast<DummyItem::Type>(i))));
diff --git a/athena/test/base/test_app_model_builder.h b/athena/test/base/test_app_model_builder.h
index 262ce25..e7a7e4b 100644
--- a/athena/test/base/test_app_model_builder.h
+++ b/athena/test/base/test_app_model_builder.h
@@ -16,7 +16,7 @@
   virtual ~TestAppModelBuilder();
 
   // Overridden from AppModelBuilder:
-  virtual void PopulateApps(app_list::AppListModel* model) override;
+  virtual void RegisterAppListModel(app_list::AppListModel* model) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestAppModelBuilder);
diff --git a/athena/util/fill_layout_manager_unittest.cc b/athena/util/fill_layout_manager_unittest.cc
index 01d5d0d..c712a77 100644
--- a/athena/util/fill_layout_manager_unittest.cc
+++ b/athena/util/fill_layout_manager_unittest.cc
@@ -11,11 +11,11 @@
 namespace athena {
 
 TEST(FillLayoutManagerTest, ChildWindowSizedCorrectly) {
-  scoped_ptr<aura::Window> parent(new aura::Window(NULL));
+  scoped_ptr<aura::Window> parent(new aura::Window(nullptr));
   parent->SetBounds(gfx::Rect(10, 20, 30, 40));
   parent->SetLayoutManager(new FillLayoutManager(parent.get()));
 
-  scoped_ptr<aura::Window> child(new aura::Window(NULL));
+  scoped_ptr<aura::Window> child(new aura::Window(nullptr));
   child->SetBounds(gfx::Rect(0, 0, 5, 10));
 
   EXPECT_NE(child->bounds().size().ToString(),
@@ -30,7 +30,7 @@
             parent->bounds().size().ToString());
 
   // Menu and tooltip should not be filled.
-  scoped_ptr<aura::Window> menu(new aura::Window(NULL));
+  scoped_ptr<aura::Window> menu(new aura::Window(nullptr));
   menu->SetType(ui::wm::WINDOW_TYPE_MENU);
   menu->SetBounds(gfx::Rect(0, 0, 5, 10));
 
@@ -40,7 +40,7 @@
   menu->SetBounds(gfx::Rect(0, 0, 100, 200));
   EXPECT_EQ(menu->bounds().ToString(), "0,0 100x200");
 
-  scoped_ptr<aura::Window> tooltip(new aura::Window(NULL));
+  scoped_ptr<aura::Window> tooltip(new aura::Window(nullptr));
   tooltip->SetType(ui::wm::WINDOW_TYPE_TOOLTIP);
   tooltip->SetBounds(gfx::Rect(0, 0, 5, 10));
 
diff --git a/athena/virtual_keyboard/virtual_keyboard_manager_impl.cc b/athena/virtual_keyboard/virtual_keyboard_manager_impl.cc
index 70b0630..4c19e2a 100644
--- a/athena/virtual_keyboard/virtual_keyboard_manager_impl.cc
+++ b/athena/virtual_keyboard/virtual_keyboard_manager_impl.cc
@@ -62,8 +62,7 @@
 class VirtualKeyboardManagerImpl : public VirtualKeyboardManager {
  public:
   explicit VirtualKeyboardManagerImpl(content::BrowserContext* browser_context)
-      : browser_context_(browser_context),
-        container_(NULL) {
+      : browser_context_(browser_context), container_(nullptr) {
     CHECK(!instance);
     instance = this;
     Init();
@@ -71,9 +70,9 @@
 
   virtual ~VirtualKeyboardManagerImpl() {
     CHECK_EQ(this, instance);
-    instance = NULL;
+    instance = nullptr;
 
-    keyboard::KeyboardController::ResetInstance(NULL);
+    keyboard::KeyboardController::ResetInstance(nullptr);
   }
 
  private:
diff --git a/athena/wm/bezel_controller.cc b/athena/wm/bezel_controller.cc
index 63168a8..6924aa60 100644
--- a/athena/wm/bezel_controller.cc
+++ b/athena/wm/bezel_controller.cc
@@ -67,8 +67,8 @@
     : container_(container),
       state_(NONE),
       scroll_bezel_(BEZEL_NONE),
-      scroll_target_(NULL),
-      left_right_delegate_(NULL) {
+      scroll_target_(nullptr),
+      left_right_delegate_(nullptr) {
 }
 
 void BezelController::SetState(BezelController::State state) {
@@ -88,7 +88,7 @@
 
   if (state == NONE) {
     scroll_bezel_ = BEZEL_NONE;
-    scroll_target_ = NULL;
+    scroll_target_ = nullptr;
   }
 
   if (state == BEZEL_SCROLLING_TWO_FINGERS) {
diff --git a/athena/wm/split_view_controller.cc b/athena/wm/split_view_controller.cc
index 6d33743..4689f70 100644
--- a/athena/wm/split_view_controller.cc
+++ b/athena/wm/split_view_controller.cc
@@ -133,7 +133,7 @@
   virtual void OnWindowDestroying(aura::Window* window) override {
     DCHECK_EQ(window, window_);
     window_->RemoveObserver(this);
-    window_ = NULL;
+    window_ = nullptr;
   }
 
   // Minimum dimension of a target to be comfortably touchable.
@@ -170,12 +170,12 @@
     : state_(INACTIVE),
       container_(container),
       window_list_provider_(window_list_provider),
-      left_window_(NULL),
-      right_window_(NULL),
+      left_window_(nullptr),
+      right_window_(nullptr),
       divider_position_(0),
       divider_scroll_start_position_(0),
-      divider_widget_(NULL),
-      drag_handle_(NULL),
+      divider_widget_(nullptr),
+      drag_handle_(nullptr),
       weak_factory_(this) {
 }
 
@@ -264,7 +264,7 @@
   CHECK(replace_with != left_window_ && replace_with != right_window_);
   DCHECK(window_list_provider_->IsWindowInList(replace_with));
 
-  aura::Window* not_replaced = NULL;
+  aura::Window* not_replaced = nullptr;
   if (window == left_window_) {
     left_window_ = replace_with;
     not_replaced = right_window_;
@@ -285,7 +285,7 @@
   CHECK_EQ(ACTIVE, state_);
   SetState(INACTIVE);
   UpdateLayout(false);
-  left_window_ = right_window_ = NULL;
+  left_window_ = right_window_ = nullptr;
 }
 
 void SplitViewController::InitializeDivider() {
@@ -373,7 +373,7 @@
   if (state_ == state)
     return;
 
-  if (divider_widget_ == NULL)
+  if (divider_widget_ == nullptr)
     InitializeDivider();
 
   state_ = state;
@@ -454,7 +454,7 @@
     SetWindowTransforms(
         left_transform, right_transform, divider_transform, animate);
   }
-  // Note: |left_window_| and |right_window_| may be NULL if calling
+  // Note: |left_window_| and |right_window_| may be nullptr if calling
   // SetWindowTransforms():
   // - caused the in-progress animation to abort.
   // - started a zero duration animation.
@@ -495,7 +495,7 @@
 
 void SplitViewController::OnAnimationCompleted() {
   // Animation can be cancelled when deactivated.
-  if (left_window_ == NULL)
+  if (left_window_ == nullptr)
     return;
   UpdateLayout(false);
 
@@ -504,8 +504,8 @@
   to_hide_.clear();
 
   if (state_ == INACTIVE) {
-    left_window_ = NULL;
-    right_window_ = NULL;
+    left_window_ = nullptr;
+    right_window_ = nullptr;
   }
 }
 
diff --git a/athena/wm/split_view_controller.h b/athena/wm/split_view_controller.h
index fa87734..2f97745 100644
--- a/athena/wm/split_view_controller.h
+++ b/athena/wm/split_view_controller.h
@@ -48,9 +48,10 @@
   bool IsSplitViewModeActive() const;
 
   // Activates split-view mode with |left| and |right| windows. If |left| and/or
-  // |right| is NULL, then the first window in the window-list (which is neither
+  // |right| is nullptr, then the first window in the window-list (which is
+  // neither
   // |left| nor |right|) is selected instead. |to_activate| indicates which of
-  // |left| or |right| should be activated. If |to_activate| is NULL, the
+  // |left| or |right| should be activated. If |to_activate| is nullptr, the
   // currently active window is kept active if it is one of the split-view
   // windows.
   void ActivateSplitMode(aura::Window* left,
@@ -79,7 +80,7 @@
 
   enum State {
     // Split View mode is not active. |left_window_| and |right_window| are
-    // NULL.
+    // nullptr.
     INACTIVE,
     // Two windows |left_window_| and |right_window| are shown side by side and
     // there is a horizontal scroll in progress which is dragging the divider
@@ -140,7 +141,7 @@
   WindowListProvider* window_list_provider_;
 
   // Windows for the left and right activities shown in SCROLLING and ACTIVE
-  // states. In INACTIVE state these are NULL.
+  // states. In INACTIVE state these are nullptr.
   aura::Window* left_window_;
   aura::Window* right_window_;
 
diff --git a/athena/wm/split_view_controller_unittest.cc b/athena/wm/split_view_controller_unittest.cc
index c90a3cf..f901b014 100644
--- a/athena/wm/split_view_controller_unittest.cc
+++ b/athena/wm/split_view_controller_unittest.cc
@@ -103,7 +103,8 @@
   ScopedVector<aura::Window> windows;
   const int kNumWindows = 6;
   for (size_t i = 0; i < kNumWindows; ++i) {
-    scoped_ptr<aura::Window> window = test::CreateNormalWindow(NULL, NULL);
+    scoped_ptr<aura::Window> window =
+        test::CreateNormalWindow(nullptr, nullptr);
     windows.push_back(window.release());
     windows[i]->Hide();
   }
@@ -114,7 +115,7 @@
   SplitViewController* controller = api()->GetSplitViewController();
   ASSERT_FALSE(controller->IsSplitViewModeActive());
 
-  controller->ActivateSplitMode(NULL, NULL, NULL);
+  controller->ActivateSplitMode(nullptr, nullptr, nullptr);
   ASSERT_TRUE(controller->IsSplitViewModeActive());
   // The last two windows should be on the left and right, respectively.
   EXPECT_EQ(windows[kNumWindows - 1], controller->left_window());
@@ -126,7 +127,7 @@
   // Select the window that is currently on the left for the right panel. The
   // windows should switch.
   controller->ActivateSplitMode(
-      NULL, windows[kNumWindows - 1], windows[kNumWindows - 1]);
+      nullptr, windows[kNumWindows - 1], windows[kNumWindows - 1]);
   EXPECT_EQ(windows[kNumWindows - 2], controller->left_window());
   EXPECT_EQ(windows[kNumWindows - 1], controller->right_window());
   EXPECT_EQ(windows[kNumWindows - 1], GetTopmostWindow());
@@ -134,7 +135,7 @@
   EXPECT_TRUE(OnlySplitViewWindowsVisible());
 
   controller->ActivateSplitMode(
-      windows[kNumWindows - 1], NULL, windows[kNumWindows - 1]);
+      windows[kNumWindows - 1], nullptr, windows[kNumWindows - 1]);
   EXPECT_EQ(windows[kNumWindows - 1], controller->left_window());
   EXPECT_EQ(windows[kNumWindows - 2], controller->right_window());
   EXPECT_EQ(windows[kNumWindows - 1], GetTopmostWindow());
@@ -153,14 +154,14 @@
 
   // Select one of the windows behind the stacks for the right panel. The window
   // on the left should remain unchanged.
-  controller->ActivateSplitMode(NULL, windows[0], windows[0]);
+  controller->ActivateSplitMode(nullptr, windows[0], windows[0]);
   EXPECT_EQ(windows[kNumWindows - 1], controller->left_window());
   EXPECT_EQ(windows[0], controller->right_window());
   EXPECT_EQ(windows[0], GetTopmostWindow());
   EXPECT_EQ(windows[kNumWindows - 1], GetSecondTopmostWindow());
   EXPECT_TRUE(OnlySplitViewWindowsVisible());
 
-  controller->ActivateSplitMode(windows[1], NULL, NULL);
+  controller->ActivateSplitMode(windows[1], nullptr, nullptr);
   EXPECT_EQ(windows[1], controller->left_window());
   EXPECT_EQ(windows[0], controller->right_window());
   EXPECT_EQ(windows[0], GetTopmostWindow());
@@ -174,7 +175,7 @@
   EXPECT_EQ(windows[4], GetSecondTopmostWindow());
   EXPECT_TRUE(OnlySplitViewWindowsVisible());
 
-  controller->ActivateSplitMode(windows[0], NULL, windows[0]);
+  controller->ActivateSplitMode(windows[0], nullptr, windows[0]);
   EXPECT_EQ(windows[0], controller->left_window());
   EXPECT_EQ(windows[5], controller->right_window());
   EXPECT_EQ(windows[0], GetTopmostWindow());
@@ -195,7 +196,8 @@
   ScopedVector<aura::Window> windows;
   const int kNumWindows = 2;
   for (size_t i = 0; i < kNumWindows; ++i) {
-    scoped_ptr<aura::Window> window = test::CreateNormalWindow(NULL, NULL);
+    scoped_ptr<aura::Window> window =
+        test::CreateNormalWindow(nullptr, nullptr);
     windows.push_back(window.release());
     windows[i]->Hide();
   }
@@ -239,8 +241,8 @@
   HandleScrollUpdate(large_distance);
   HandleScrollEnd(0.0f);
   ASSERT_FALSE(controller->IsSplitViewModeActive());
-  EXPECT_EQ(NULL, controller->left_window());
-  EXPECT_EQ(NULL, controller->right_window());
+  EXPECT_EQ(nullptr, controller->left_window());
+  EXPECT_EQ(nullptr, controller->right_window());
   EXPECT_EQ(left_window, GetTopmostWindow());
 
   // Re-activate split view mode.
@@ -267,8 +269,8 @@
   HandleScrollUpdate(-large_distance);
   HandleScrollEnd(slow_velocity);
   ASSERT_FALSE(controller->IsSplitViewModeActive());
-  EXPECT_EQ(NULL, controller->left_window());
-  EXPECT_EQ(NULL, controller->right_window());
+  EXPECT_EQ(nullptr, controller->left_window());
+  EXPECT_EQ(nullptr, controller->right_window());
   EXPECT_EQ(right_window, GetTopmostWindow());
 
   // Re-activate split view mode.
@@ -281,8 +283,8 @@
   HandleScrollUpdate(-large_distance);
   HandleScrollEnd(fast_velocity);
   ASSERT_FALSE(controller->IsSplitViewModeActive());
-  EXPECT_EQ(NULL, controller->left_window());
-  EXPECT_EQ(NULL, controller->right_window());
+  EXPECT_EQ(nullptr, controller->left_window());
+  EXPECT_EQ(nullptr, controller->right_window());
   EXPECT_EQ(left_window, GetTopmostWindow());
 }
 
@@ -291,7 +293,8 @@
   ScopedVector<aura::Window> windows;
   const int kNumWindows = 2;
   for (size_t i = 0; i < kNumWindows; ++i) {
-    scoped_ptr<aura::Window> window = test::CreateNormalWindow(NULL, NULL);
+    scoped_ptr<aura::Window> window =
+        test::CreateNormalWindow(nullptr, nullptr);
     window->Hide();
     windows.push_back(window.release());
   }
@@ -305,7 +308,7 @@
   ASSERT_TRUE(IsSplitViewAllowed());
   ASSERT_FALSE(controller->IsSplitViewModeActive());
 
-  controller->ActivateSplitMode(NULL, NULL, NULL);
+  controller->ActivateSplitMode(nullptr, nullptr, nullptr);
   ASSERT_TRUE(controller->IsSplitViewModeActive());
 
   // Screen rotation should be locked while in splitview.
diff --git a/athena/wm/title_drag_controller.cc b/athena/wm/title_drag_controller.cc
index b41b7fd..a0301e1 100644
--- a/athena/wm/title_drag_controller.cc
+++ b/athena/wm/title_drag_controller.cc
@@ -59,7 +59,7 @@
 void TitleDragController::OnTransitionEnd(aura::Window* window, bool complete) {
   weak_ptr_.InvalidateWeakPtrs();
   if (!tracker_.Contains(window))
-    window = NULL;
+    window = nullptr;
   shadow_.reset();
   if (window) {
     window->SetTransform(gfx::Transform());
diff --git a/athena/wm/window_list_provider_impl_unittest.cc b/athena/wm/window_list_provider_impl_unittest.cc
index d3dd285..22cb166 100644
--- a/athena/wm/window_list_provider_impl_unittest.cc
+++ b/athena/wm/window_list_provider_impl_unittest.cc
@@ -157,11 +157,11 @@
       new WindowListProviderImpl(container.get()));
 
   scoped_ptr<aura::Window> normal_window =
-      CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+      CreateWindow(nullptr, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
   scoped_ptr<aura::Window> popup_window =
-      CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_POPUP);
+      CreateWindow(nullptr, &delegate, ui::wm::WINDOW_TYPE_POPUP);
   scoped_ptr<aura::Window> menu_window =
-      CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_MENU);
+      CreateWindow(nullptr, &delegate, ui::wm::WINDOW_TYPE_MENU);
 
   // Check which windows are valid and which are not.
   EXPECT_TRUE(list_provider->IsValidWindow(normal_window.get()));
@@ -188,11 +188,11 @@
       new WindowListObserver(list_provider.get()));
 
   scoped_ptr<aura::Window> window1 =
-      CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+      CreateWindow(nullptr, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
   scoped_ptr<aura::Window> window2 =
-      CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+      CreateWindow(nullptr, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
   scoped_ptr<aura::Window> window3 =
-      CreateWindow(NULL, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
+      CreateWindow(nullptr, &delegate, ui::wm::WINDOW_TYPE_NORMAL);
 
   EXPECT_FALSE(list_provider->IsWindowInList(window1.get()));
   EXPECT_FALSE(list_provider->IsWindowInList(window2.get()));
@@ -296,9 +296,9 @@
 
   scoped_ptr<WindowListObserver> observer(
       new WindowListObserver(list_provider));
-  scoped_ptr<aura::Window> w1 = test::CreateNormalWindow(&delegate, NULL);
+  scoped_ptr<aura::Window> w1 = test::CreateNormalWindow(&delegate, nullptr);
   w1->Show();
-  scoped_ptr<aura::Window> w2 = test::CreateNormalWindow(&delegate, NULL);
+  scoped_ptr<aura::Window> w2 = test::CreateNormalWindow(&delegate, nullptr);
   w2->Show();
   scoped_ptr<aura::Window> t1 = test::CreateTransientWindow(
       &delegate, w1.get(), ui::MODAL_TYPE_NONE, false);
diff --git a/athena/wm/window_manager_impl.cc b/athena/wm/window_manager_impl.cc
index f0020c4..99b2ec1a 100644
--- a/athena/wm/window_manager_impl.cc
+++ b/athena/wm/window_manager_impl.cc
@@ -31,7 +31,7 @@
 
 namespace athena {
 namespace {
-class WindowManagerImpl* instance = NULL;
+class WindowManagerImpl* instance = nullptr;
 
 void SetWindowState(aura::Window* window,
                     const gfx::Rect& bounds,
@@ -185,7 +185,7 @@
   // |title_drag_controller_| needs to be reset before |container_|.
   title_drag_controller_.reset();
   container_.reset();
-  instance = NULL;
+  instance = nullptr;
 }
 
 void WindowManagerImpl::ToggleSplitView() {
@@ -201,7 +201,7 @@
     FOR_EACH_OBSERVER(WindowManagerObserver,
                       observers_,
                       OnSplitViewModeEnter());
-    split_view_controller_->ActivateSplitMode(NULL, NULL, NULL);
+    split_view_controller_->ActivateSplitMode(nullptr, nullptr, nullptr);
   }
 }
 
@@ -209,7 +209,7 @@
   if (IsOverviewModeActive())
     return;
 
-  bezel_controller_->set_left_right_delegate(NULL);
+  bezel_controller_->set_left_right_delegate(nullptr);
   FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnOverviewModeEnter());
 
   // Note: The window_list_provider_ resembles the exact window list of the
@@ -370,7 +370,7 @@
       std::find(windows.rbegin(), windows.rend(), window);
   CHECK(iter != windows.rend());
   ++iter;
-  aura::Window* behind = NULL;
+  aura::Window* behind = nullptr;
   if (iter != windows.rend())
     behind = *iter++;
 
@@ -379,7 +379,7 @@
     aura::Window* right = split_view_controller_->right_window();
     CHECK(window == left || window == right);
     if (behind == left || behind == right)
-      behind = (iter == windows.rend()) ? NULL : *iter;
+      behind = (iter == windows.rend()) ? nullptr : *iter;
   }
 
   return behind;
diff --git a/athena/wm/window_manager_unittest.cc b/athena/wm/window_manager_unittest.cc
index 9cbedaa..737a620 100644
--- a/athena/wm/window_manager_unittest.cc
+++ b/athena/wm/window_manager_unittest.cc
@@ -29,7 +29,8 @@
 
   scoped_ptr<aura::Window> CreateAndActivateWindow(
       aura::WindowDelegate* delegate) {
-    scoped_ptr<aura::Window> window(test::CreateNormalWindow(delegate, NULL));
+    scoped_ptr<aura::Window> window(
+        test::CreateNormalWindow(delegate, nullptr));
     window->Show();
     wm::ActivateWindow(window.get());
     return window.Pass();
@@ -94,7 +95,7 @@
 
   // Go into split-view mode.
   WindowOverviewModeDelegate* overview_delegate = wm_api.wm();
-  overview_delegate->OnSelectSplitViewWindow(w3.get(), NULL, w3.get());
+  overview_delegate->OnSelectSplitViewWindow(w3.get(), nullptr, w3.get());
   EXPECT_TRUE(w3->IsVisible());
   EXPECT_TRUE(w2->IsVisible());
   EXPECT_FALSE(w1->IsVisible());
@@ -297,7 +298,7 @@
   EXPECT_EQ(first->bounds().ToString(), second->bounds().ToString());
 
   // Get into split view.
-  wm_api.GetSplitViewController()->ActivateSplitMode(NULL, NULL, NULL);
+  wm_api.GetSplitViewController()->ActivateSplitMode(nullptr, nullptr, nullptr);
   const gfx::Rect left_bounds =
       wm_api.GetSplitViewController()->left_window()->bounds();
   EXPECT_NE(work_area.ToString(),
@@ -364,7 +365,7 @@
   scoped_ptr<aura::Window> w3(CreateAndActivateWindow(&delegate));
 
   // Get into split-view mode, and then turn on overview mode.
-  wm_api.GetSplitViewController()->ActivateSplitMode(NULL, NULL, NULL);
+  wm_api.GetSplitViewController()->ActivateSplitMode(nullptr, nullptr, nullptr);
   WindowManager::Get()->EnterOverview();
   EXPECT_TRUE(wm_api.GetSplitViewController()->IsSplitViewModeActive());
   EXPECT_EQ(w3.get(), wm_api.GetSplitViewController()->left_window());
diff --git a/athena/wm/window_overview_mode.cc b/athena/wm/window_overview_mode.cc
index 70deb30d..bfe9d661 100644
--- a/athena/wm/window_overview_mode.cc
+++ b/athena/wm/window_overview_mode.cc
@@ -54,7 +54,7 @@
 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*);
 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState,
                                  kWindowOverviewState,
-                                 NULL);
+                                 nullptr);
 
 namespace athena {
 
@@ -297,7 +297,7 @@
             container,
             scoped_ptr<ui::EventTargeter>(
                 new StaticWindowTargeter(container)))),
-        dragged_window_(NULL) {
+        dragged_window_(nullptr) {
     CHECK(delegate_);
     container_->set_target_handler(this);
 
@@ -425,13 +425,13 @@
       targeter = window->GetEventTargeter();
     }
     if (!targeter)
-      return NULL;
+      return nullptr;
     aura::Window* target = static_cast<aura::Window*>(
         targeter->FindTargetForLocatedEvent(container_, event));
     while (target && target->parent() != container_)
       target = target->parent();
     aura::Window* transient_parent =
-        target ? wm::GetTransientParent(target) : NULL;
+        target ? wm::GetTransientParent(target) : nullptr;
     return transient_parent ? transient_parent : target;
   }
 
@@ -508,7 +508,7 @@
 
   aura::Window* GetSplitWindowDropTarget(const ui::GestureEvent& event) const {
     if (!split_view_controller_->IsSplitViewModeActive())
-      return NULL;
+      return nullptr;
     CHECK(dragged_window_);
     CHECK_NE(split_view_controller_->left_window(), dragged_window_);
     CHECK_NE(split_view_controller_->right_window(), dragged_window_);
@@ -518,7 +518,7 @@
     window = split_view_controller_->right_window();
     if (GetTransformedBounds(window).Contains(event.location()))
       return window;
-    return NULL;
+    return nullptr;
   }
 
   void DragWindow(const ui::GestureEvent& event) {
@@ -631,7 +631,7 @@
       setter.SetOpacity(kMinOpacity);
     }
     delete dragged_window_;
-    dragged_window_ = NULL;
+    dragged_window_ = nullptr;
   }
 
   void RestoreDragWindow() {
@@ -643,7 +643,7 @@
     AnimateTransientGroupSetter setter(dragged_window_);
     setter.SetTransform(GetTransformForState(dragged_window_, dragged_state));
     setter.SetOpacity(1.0f);
-    dragged_window_ = NULL;
+    dragged_window_ = nullptr;
   }
 
   void EndDragWindow(const ui::GestureEvent& gesture) {
@@ -652,9 +652,8 @@
     OverviewToolbar::ActionType action = overview_toolbar_->current_action();
     overview_toolbar_.reset();
     if (action == OverviewToolbar::ACTION_TYPE_SPLIT) {
-      delegate_->OnSelectSplitViewWindow(NULL,
-                                         dragged_window_,
-                                         dragged_window_);
+      delegate_->OnSelectSplitViewWindow(
+          nullptr, dragged_window_, dragged_window_);
       return;
     }
 
@@ -733,7 +732,7 @@
           // these windows will terminate the split-view mode. Until then, do
           // not allow closing these (since otherwise it gets into an undefined
           // state).
-          dragged_window_ = NULL;
+          dragged_window_ = nullptr;
         }
 
         if (dragged_window_) {
@@ -771,7 +770,7 @@
         RemoveAnimationObserver();
         gesture->SetHandled();
       }
-      dragged_window_ = NULL;
+      dragged_window_ = nullptr;
     }
   }
 
diff --git a/athena/wm/window_overview_mode.h b/athena/wm/window_overview_mode.h
index 208b027..80f2844 100644
--- a/athena/wm/window_overview_mode.h
+++ b/athena/wm/window_overview_mode.h
@@ -17,12 +17,13 @@
   virtual ~WindowOverviewModeDelegate() {}
 
   // Called to activate |window|, set its bounds and set its visibility when
-  // |window| is selected in overview mode. |window| is NULL if there are no
+  // |window| is selected in overview mode. |window| is nullptr if there are no
   // windows in overview mode.
   virtual void OnSelectWindow(aura::Window* window) = 0;
 
   // Gets into split-view mode with |left| on the left-side of the screen, and
-  // |right| on the right-side. If |left| or |right| is NULL, then the delegate
+  // |right| on the right-side. If |left| or |right| is nullptr, then the
+  // delegate
   // selects the best option in its place.
   virtual void OnSelectSplitViewWindow(aura::Window* left,
                                        aura::Window* right,
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 669d739..556a09a 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1421,8 +1421,7 @@
   # GYP: //base.gyp:base_java
   android_library("base_java") {
     srcjar_deps = [
-      ":base_java_application_state",
-      ":base_java_memory_pressure_level_list",
+      ":base_android_java_enums_srcjar",
       ":base_native_libraries_gen",
     ]
 
@@ -1458,27 +1457,16 @@
   }
 
   # GYP: //base.gyp:base_java_application_state
-  java_cpp_template("base_java_application_state") {
+  # GYP: //base.gyp:base_java_memory_pressure_level
+  java_cpp_enum("base_android_java_enums_srcjar") {
     sources = [
-      "android/java/src/org/chromium/base/ApplicationState.template",
+      "android/application_status_listener.h",
+      "memory/memory_pressure_listener.h",
     ]
-    inputs = [
-      "android/application_state_list.h"
+    outputs = [
+      "org/chromium/base/ApplicationState.java",
+      "org/chromium/base/MemoryPressureLevel.java",
     ]
-
-    package_name = "org/chromium/base"
-  }
-
-  # GYP: //base.gyp:base_java_memory_pressure_level_list
-  java_cpp_template("base_java_memory_pressure_level_list") {
-    sources = [
-      "android/java/src/org/chromium/base/MemoryPressureLevelList.template",
-    ]
-    inputs = [
-      "memory/memory_pressure_level_list.h"
-    ]
-
-    package_name = "org/chromium/base"
   }
 
   # GYP: //base/base.gyp:base_native_libraries_gen
diff --git a/base/PRESUBMIT.py b/base/PRESUBMIT.py
index 758a7905..4e9e64bc 100644
--- a/base/PRESUBMIT.py
+++ b/base/PRESUBMIT.py
@@ -8,10 +8,6 @@
 for more details on the presubmit API built into gcl.
 """
 
-import re
-
-BASE_SOURCE_FILES=(r'^base/.*\.(cc|h|mm)$',)
-
 def _CheckNoInterfacesInBase(input_api, output_api):
   """Checks to make sure no files in libbase.a have |@interface|."""
   pattern = input_api.re.compile(r'^\s*@interface', input_api.re.MULTILINE)
@@ -40,45 +36,8 @@
   results.extend(_CheckNoInterfacesInBase(input_api, output_api))
   return results
 
-def _CheckOverrideFinal(input_api, output_api,
-                       whitelist=BASE_SOURCE_FILES, blacklist=None):
-  """Make sure new lines of code don't use the OVERRIDE or FINAL macros."""
-
-  # TODO(mostynb): remove this check once the macros are removed
-  # from base/compiler_specific.h.
-
-  errors = []
-
-  source_file_filter = lambda x: input_api.FilterSourceFile(
-    x, white_list=BASE_SOURCE_FILES, black_list=None)
-
-  override_files = []
-  final_files = []
-
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-
-    # "override" and "final" should be used instead of OVERRIDE/FINAL now.
-    if re.search(r"\bOVERRIDE\b", contents):
-      override_files.append(f.LocalPath())
-
-    if re.search(r"\bFINAL\b", contents):
-      final_files.append(f.LocalPath())
-
-  if override_files:
-    return [output_api.PresubmitError(
-      'These files use OVERRIDE instead of using override:',
-      items=override_files)]
-  if final_files:
-    return [output_api.PresubmitError(
-      'These files use FINAL instead of using final:',
-      items=final_files)]
-
-  return []
-
 def CheckChangeOnUpload(input_api, output_api):
   results = []
-  results.extend(_CheckOverrideFinal(input_api, output_api))
   results.extend(_CommonChecks(input_api, output_api))
   return results
 
@@ -92,12 +51,12 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_rel_swarming': set(['defaulttests']),
+      'linux_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.mac': {
-      'mac_chromium_rel_swarming': set(['defaulttests']),
+      'mac_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.win': {
-      'win_chromium_rel_swarming': set(['defaulttests']),
+      'win_chromium_rel': set(['defaulttests']),
     }
   }
diff --git a/base/android/application_state_list.h b/base/android/application_state_list.h
deleted file mode 100644
index cbc833e5..0000000
--- a/base/android/application_state_list.h
+++ /dev/null
@@ -1,17 +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.
-
-// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum values.
-
-// Note that these states represent the most visible Activity state.
-// If there are activities with states paused and stopped, only
-// HAS_PAUSED_ACTIVITIES should be returned.
-#ifndef DEFINE_APPLICATION_STATE
-#error "DEFINE_APPLICATION_STATE should be defined before including this file"
-#endif
-DEFINE_APPLICATION_STATE(HAS_RUNNING_ACTIVITIES, 1)
-DEFINE_APPLICATION_STATE(HAS_PAUSED_ACTIVITIES, 2)
-DEFINE_APPLICATION_STATE(HAS_STOPPED_ACTIVITIES, 3)
-DEFINE_APPLICATION_STATE(HAS_DESTROYED_ACTIVITIES, 4)
diff --git a/base/android/application_status_listener.h b/base/android/application_status_listener.h
index ef98985f..30048b2 100644
--- a/base/android/application_status_listener.h
+++ b/base/android/application_status_listener.h
@@ -19,10 +19,18 @@
 
 // Define application state values like APPLICATION_STATE_VISIBLE in a
 // way that ensures they're always the same than their Java counterpart.
+//
+// Note that these states represent the most visible Activity state.
+// If there are activities with states paused and stopped, only
+// HAS_PAUSED_ACTIVITIES should be returned.
+//
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
 enum ApplicationState {
-#define DEFINE_APPLICATION_STATE(x, y) APPLICATION_STATE_##x = y,
-#include "base/android/application_state_list.h"
-#undef DEFINE_APPLICATION_STATE
+  APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = 1,
+  APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = 2,
+  APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = 3,
+  APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = 4
 };
 
 // A native helper class to listen to state changes of the Android
diff --git a/base/android/java/src/org/chromium/base/ApplicationState.template b/base/android/java/src/org/chromium/base/ApplicationState.template
deleted file mode 100644
index 892c055..0000000
--- a/base/android/java/src/org/chromium/base/ApplicationState.template
+++ /dev/null
@@ -1,14 +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.
-
-package org.chromium.base;
-
-// A simple auto-generated interface used to list the various
-// states of an application as used by both org.chromium.base.ApplicationStatus
-// and base/android/application_status.h
-public interface ApplicationState {
-#define DEFINE_APPLICATION_STATE(x,y) public final int x = y;
-#include "base/android/application_state_list.h"
-#undef DEFINE_APPLICATION_STATE
-}
diff --git a/base/android/java/src/org/chromium/base/MemoryPressureLevelList.template b/base/android/java/src/org/chromium/base/MemoryPressureLevelList.template
deleted file mode 100644
index cebca842..0000000
--- a/base/android/java/src/org/chromium/base/MemoryPressureLevelList.template
+++ /dev/null
@@ -1,12 +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.base;
-
-class MemoryPressureLevelList {
-#define DEFINE_MEMORY_PRESSURE_LEVEL(name, value) \
-    static final int name = value;
-#include "base/memory/memory_pressure_level_list.h"
-#undef DEFINE_MEMORY_PRESSURE_LEVEL
-}
diff --git a/base/android/java/src/org/chromium/base/MemoryPressureListener.java b/base/android/java/src/org/chromium/base/MemoryPressureListener.java
index 1f3b77f1..28d9651 100644
--- a/base/android/java/src/org/chromium/base/MemoryPressureListener.java
+++ b/base/android/java/src/org/chromium/base/MemoryPressureListener.java
@@ -53,7 +53,7 @@
 
                     @Override
                     public void onLowMemory() {
-                        nativeOnMemoryPressure(MemoryPressureLevelList.MEMORY_PRESSURE_CRITICAL);
+                        nativeOnMemoryPressure(MemoryPressureLevel.CRITICAL);
                     }
 
                     @Override
@@ -85,12 +85,12 @@
 
     public static void maybeNotifyMemoryPresure(int level) {
         if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
-            nativeOnMemoryPressure(MemoryPressureLevelList.MEMORY_PRESSURE_CRITICAL);
+            nativeOnMemoryPressure(MemoryPressureLevel.CRITICAL);
         } else if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND ||
                 level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
             // Don't notifiy on TRIM_MEMORY_UI_HIDDEN, since this class only
             // dispatches actionable memory pressure signals to native.
-            nativeOnMemoryPressure(MemoryPressureLevelList.MEMORY_PRESSURE_MODERATE);
+            nativeOnMemoryPressure(MemoryPressureLevel.MODERATE);
         }
     }
 
diff --git a/base/android/BUILD.gn b/base/android/linker/BUILD.gn
similarity index 65%
rename from base/android/BUILD.gn
rename to base/android/linker/BUILD.gn
index befe3979..b26e3b0 100644
--- a/base/android/BUILD.gn
+++ b/base/android/linker/BUILD.gn
@@ -1,10 +1,15 @@
+# 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.
+
 import("//build/config/android/config.gni")
 
 assert(is_android)
 assert(!is_android_webview_build)
 
+# GYP: //base/base.gyp:chromium_android_linker
 shared_library("chromium_android_linker") {
-  sources = [ "linker/linker_jni.cc" ]
+  sources = [ "linker_jni.cc" ]
   # The NDK contains the crazy_linker here:
   #   '<(android_ndk_root)/crazy_linker.gyp:crazy_linker'
   # However, we use our own fork.  See bug 384700.
diff --git a/base/android/linker/config.gni b/base/android/linker/config.gni
new file mode 100644
index 0000000..99cbcf0e
--- /dev/null
+++ b/base/android/linker/config.gni
@@ -0,0 +1,8 @@
+# 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.
+
+# TODO(GYP) add "|| profiling_full_stack_frames
+# Only enable the chromium linker on regular builds, since the
+# component build crashes on Android 4.4. See b/11379966
+chromium_linker_supported = !is_component_build
diff --git a/base/base.gyp b/base/base.gyp
index 1a4b54e..cdbfaa9 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -216,7 +216,7 @@
             ],
           },
         }],
-        ['OS != "win" and OS != "ios"', {
+        ['OS != "win" and (OS != "ios" or _toolset == "host")', {
             'dependencies': ['../third_party/libevent/libevent.gyp:libevent'],
         },],
         ['component=="shared_library"', {
@@ -265,6 +265,7 @@
     },
     {
       'target_name': 'base_i18n',
+      'toolsets': ['host', 'target'],
       'type': '<(component)',
       'variables': {
         'enable_wexit_time_destructors': 1,
@@ -855,6 +856,7 @@
     {
       # GN: //base/test:test_support
       'target_name': 'test_support_base',
+      'toolsets': ['host', 'target'],
       'type': 'static_library',
       'dependencies': [
         'base',
@@ -985,11 +987,20 @@
             # by file name rules).
             ['include', '^test/test_file_util_mac\\.cc$'],
           ],
+        }],
+        ['OS == "ios" and _toolset == "target"', {
           'sources!': [
             # iOS uses its own unit test launcher.
             'test/launcher/unit_test_launcher.cc',
           ],
         }],
+        ['OS == "ios" and _toolset == "host"', {
+          'sources!': [
+            'test/launcher/unit_test_launcher_ios.cc',
+            'test/test_support_ios.h',
+            'test/test_support_ios.mm',
+          ],
+        }],
       ],  # target_conditions
     },
     {
@@ -1011,6 +1022,21 @@
     },
   ],
   'conditions': [
+    ['OS=="ios" and "<(GENERATOR)"=="ninja"', {
+      'targets': [
+        {
+          'target_name': 'test_launcher',
+          'toolsets': ['host'],
+          'type': 'executable',
+          'dependencies': [
+            'test_support_base',
+          ],
+          'sources': [
+            'test/launcher/test_launcher_ios.cc',
+          ],
+        },
+      ],
+    }],
     ['OS!="ios"', {
       'targets': [
         {
@@ -1280,6 +1306,7 @@
         {
           # GN: //base:base_jni_headers
           'target_name': 'base_jni_headers',
+          'toolsets': ['host', 'target'],
           'type': 'none',
           'sources': [
             'android/java/src/org/chromium/base/ApplicationStatus.java',
@@ -1311,6 +1338,7 @@
         {
           # TODO(GN)
           'target_name': 'base_unittests_jni_headers',
+          'toolsets': ['host', 'target'],
           'type': 'none',
           'sources': [
             'test/android/java/src/org/chromium/base/ContentUriTestUtils.java',
@@ -1323,6 +1351,7 @@
         {
           # GN: //base:base_native_libraries_gen
           'target_name': 'base_native_libraries_gen',
+          'toolsets': ['host', 'target'],
           'type': 'none',
           'sources': [
             'android/java/templates/NativeLibraries.template',
@@ -1336,6 +1365,7 @@
         {
           # GN: //base:base_java
           'target_name': 'base_java',
+          'toolsets': ['host', 'target'],
           'type': 'none',
           'variables': {
             'java_in_dir': '../base/android/java',
@@ -1343,7 +1373,7 @@
           },
           'dependencies': [
             'base_java_application_state',
-            'base_java_memory_pressure_level_list',
+            'base_java_memory_pressure_level',
             'base_native_libraries_gen',
           ],
           'includes': [ '../build/java.gypi' ],
@@ -1358,6 +1388,7 @@
         {
           # GN: //base:base_java_unittest_support
           'target_name': 'base_java_unittest_support',
+          'toolsets': ['host', 'target'],
           'type': 'none',
           'dependencies': [
             'base_java',
@@ -1368,34 +1399,24 @@
           'includes': [ '../build/java.gypi' ],
         },
         {
-          # GN: //base:base_java_application_state
+          # GN: //base:base_android_java_enums_srcjar
           'target_name': 'base_java_application_state',
+          'toolsets': ['host', 'target'],
           'type': 'none',
-          # This target is used to auto-generate ApplicationState.java
-          # from a template file. The source file contains a list of
-          # Java constant declarations matching the ones in
-          # android/application_state_list.h.
-          'sources': [
-            'android/java/src/org/chromium/base/ApplicationState.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/base',
-            'template_deps': ['android/application_state_list.h'],
+            'source_file': 'android/application_status_listener.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
         {
-          # GN: //base:base_java_memory_pressure_level_list
-          'target_name': 'base_java_memory_pressure_level_list',
+          # GN: //base:base_android_java_enums_srcjar
+          'target_name': 'base_java_memory_pressure_level',
+          'toolsets': ['host', 'target'],
           'type': 'none',
-          'sources': [
-            'android/java/src/org/chromium/base/MemoryPressureLevelList.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/base',
-            'template_deps': ['memory/memory_pressure_level_list.h'],
+            'source_file': 'memory/memory_pressure_listener.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
         {
           # GN: //base:base_java_test_support
@@ -1423,7 +1444,7 @@
           'includes': [ '../build/java.gypi' ],
         },
         {
-          # GN: //base/android/chromium_android_linker
+          # GN: //base/android/linker:chromium_android_linker
           'target_name': 'chromium_android_linker',
           'type': 'shared_library',
           'conditions': [
diff --git a/base/base_nacl.gyp b/base/base_nacl.gyp
index 7221d2a..63e1ed4 100644
--- a/base/base_nacl.gyp
+++ b/base/base_nacl.gyp
@@ -36,7 +36,7 @@
             ],
           },
           'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
+            '../native_client/tools.gyp:prep_toolchain',
           ],
         },
         {
@@ -59,22 +59,15 @@
             ],
           },
           'dependencies': [
-            '<(DEPTH)/third_party/icu/icu_nacl.gyp:icudata_nacl',
-            '<(DEPTH)/third_party/icu/icu_nacl.gyp:icui18n_nacl',
-            '<(DEPTH)/third_party/icu/icu_nacl.gyp:icuuc_nacl',
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
+            '../native_client/tools.gyp:prep_toolchain',
+            '../third_party/icu/icu_nacl.gyp:icudata_nacl',
+            '../third_party/icu/icu_nacl.gyp:icui18n_nacl',
+            '../third_party/icu/icu_nacl.gyp:icuuc_nacl',
           ],
         },
-      ],
-    }],
-    ['disable_nacl==0', {
-      'targets': [
         {
           'target_name': 'base_nacl_nonsfi',
           'type': 'none',
-          'include_dirs': [
-            '<(DEPTH)/native_client/src/public/linux_syscalls',
-          ],
           'variables': {
             'base_target': 1,
             'nacl_untrusted_build': 1,
@@ -116,8 +109,8 @@
             'rand_util_nacl.cc',
           ],
           'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
-            '<(DEPTH)/third_party/libevent/libevent_nacl_nonsfi.gyp:event_nacl_nonsfi',
+            '../native_client/tools.gyp:prep_toolchain',
+            '../third_party/libevent/libevent_nacl_nonsfi.gyp:event_nacl_nonsfi',
           ],
         },
       ],
diff --git a/base/basictypes.h b/base/basictypes.h
index 12d4c97..bf75e673 100644
--- a/base/basictypes.h
+++ b/base/basictypes.h
@@ -22,24 +22,11 @@
 typedef int8_t int8;
 typedef uint8_t uint8;
 typedef int16_t int16;
-typedef int32_t int32;
 typedef uint16_t uint16;
+typedef int32_t int32;
 typedef uint32_t uint32;
-
-// TODO(vtl): Figure what's up with the 64-bit types. Can we just define them as
-// |int64_t|/|uint64_t|?
-// The NSPR system headers define 64-bit as |long| when possible, except on
-// Mac OS X.  In order to not have typedef mismatches, we do the same on LP64.
-//
-// On Mac OS X, |long long| is used for 64-bit types for compatibility with
-// <inttypes.h> format macros even in the LP64 model.
-#if defined(__LP64__) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
-typedef long int64;
-typedef unsigned long uint64;
-#else
-typedef long long int64;
-typedef unsigned long long uint64;
-#endif
+typedef int64_t int64;
+typedef uint64_t uint64;
 
 // DEPRECATED: Please use std::numeric_limits (from <limits>) instead.
 const uint8  kuint8max  =  0xFF;
diff --git a/base/callback_list.h b/base/callback_list.h
index aeed5f1..5b911fd 100644
--- a/base/callback_list.h
+++ b/base/callback_list.h
@@ -1,3 +1,8 @@
+// This file was GENERATED by command:
+//     pump.py callback_list.h.pump
+// DO NOT EDIT BY HAND!!!
+
+
 // 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.
@@ -203,21 +208,192 @@
 
 template <typename Sig> class CallbackList;
 
-template <typename... Args>
-class CallbackList<void(Args...)>
-    : public internal::CallbackListBase<Callback<void(Args...)> > {
+template <>
+class CallbackList<void(void)>
+    : public internal::CallbackListBase<Callback<void(void)> > {
  public:
-  typedef Callback<void(Args...)> CallbackType;
+  typedef Callback<void(void)> CallbackType;
 
   CallbackList() {}
 
-  void Notify(
-      typename internal::CallbackParamTraits<Args>::ForwardType... args) {
+  void Notify() {
+    internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+    CallbackType* cb;
+    while ((cb = it.GetNext()) != NULL) {
+      cb->Run();
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CallbackList);
+};
+
+template <typename A1>
+class CallbackList<void(A1)>
+    : public internal::CallbackListBase<Callback<void(A1)> > {
+ public:
+  typedef Callback<void(A1)> CallbackType;
+
+  CallbackList() {}
+
+  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1) {
     typename internal::CallbackListBase<CallbackType>::Iterator it =
         this->GetIterator();
     CallbackType* cb;
     while ((cb = it.GetNext()) != NULL) {
-      cb->Run(args...);
+      cb->Run(a1);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CallbackList);
+};
+
+template <typename A1, typename A2>
+class CallbackList<void(A1, A2)>
+    : public internal::CallbackListBase<Callback<void(A1, A2)> > {
+ public:
+  typedef Callback<void(A1, A2)> CallbackType;
+
+  CallbackList() {}
+
+  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+              typename internal::CallbackParamTraits<A2>::ForwardType a2) {
+    typename internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+    CallbackType* cb;
+    while ((cb = it.GetNext()) != NULL) {
+      cb->Run(a1, a2);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CallbackList);
+};
+
+template <typename A1, typename A2, typename A3>
+class CallbackList<void(A1, A2, A3)>
+    : public internal::CallbackListBase<Callback<void(A1, A2, A3)> > {
+ public:
+  typedef Callback<void(A1, A2, A3)> CallbackType;
+
+  CallbackList() {}
+
+  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+              typename internal::CallbackParamTraits<A2>::ForwardType a2,
+              typename internal::CallbackParamTraits<A3>::ForwardType a3) {
+    typename internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+    CallbackType* cb;
+    while ((cb = it.GetNext()) != NULL) {
+      cb->Run(a1, a2, a3);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CallbackList);
+};
+
+template <typename A1, typename A2, typename A3, typename A4>
+class CallbackList<void(A1, A2, A3, A4)>
+    : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4)> > {
+ public:
+  typedef Callback<void(A1, A2, A3, A4)> CallbackType;
+
+  CallbackList() {}
+
+  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+              typename internal::CallbackParamTraits<A2>::ForwardType a2,
+              typename internal::CallbackParamTraits<A3>::ForwardType a3,
+              typename internal::CallbackParamTraits<A4>::ForwardType a4) {
+    typename internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+    CallbackType* cb;
+    while ((cb = it.GetNext()) != NULL) {
+      cb->Run(a1, a2, a3, a4);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CallbackList);
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5>
+class CallbackList<void(A1, A2, A3, A4, A5)>
+    : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5)> > {
+ public:
+  typedef Callback<void(A1, A2, A3, A4, A5)> CallbackType;
+
+  CallbackList() {}
+
+  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+              typename internal::CallbackParamTraits<A2>::ForwardType a2,
+              typename internal::CallbackParamTraits<A3>::ForwardType a3,
+              typename internal::CallbackParamTraits<A4>::ForwardType a4,
+              typename internal::CallbackParamTraits<A5>::ForwardType a5) {
+    typename internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+    CallbackType* cb;
+    while ((cb = it.GetNext()) != NULL) {
+      cb->Run(a1, a2, a3, a4, a5);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CallbackList);
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+    typename A6>
+class CallbackList<void(A1, A2, A3, A4, A5, A6)>
+    : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5,
+        A6)> > {
+ public:
+  typedef Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType;
+
+  CallbackList() {}
+
+  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+              typename internal::CallbackParamTraits<A2>::ForwardType a2,
+              typename internal::CallbackParamTraits<A3>::ForwardType a3,
+              typename internal::CallbackParamTraits<A4>::ForwardType a4,
+              typename internal::CallbackParamTraits<A5>::ForwardType a5,
+              typename internal::CallbackParamTraits<A6>::ForwardType a6) {
+    typename internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+    CallbackType* cb;
+    while ((cb = it.GetNext()) != NULL) {
+      cb->Run(a1, a2, a3, a4, a5, a6);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CallbackList);
+};
+
+template <typename A1, typename A2, typename A3, typename A4, typename A5,
+    typename A6, typename A7>
+class CallbackList<void(A1, A2, A3, A4, A5, A6, A7)>
+    : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5, A6,
+        A7)> > {
+ public:
+  typedef Callback<void(A1, A2, A3, A4, A5, A6, A7)> CallbackType;
+
+  CallbackList() {}
+
+  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
+              typename internal::CallbackParamTraits<A2>::ForwardType a2,
+              typename internal::CallbackParamTraits<A3>::ForwardType a3,
+              typename internal::CallbackParamTraits<A4>::ForwardType a4,
+              typename internal::CallbackParamTraits<A5>::ForwardType a5,
+              typename internal::CallbackParamTraits<A6>::ForwardType a6,
+              typename internal::CallbackParamTraits<A7>::ForwardType a7) {
+    typename internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+    CallbackType* cb;
+    while ((cb = it.GetNext()) != NULL) {
+      cb->Run(a1, a2, a3, a4, a5, a6, a7);
     }
   }
 
diff --git a/base/callback_list.h.pump b/base/callback_list.h.pump
new file mode 100644
index 0000000..d7f84736
--- /dev/null
+++ b/base/callback_list.h.pump
@@ -0,0 +1,269 @@
+$$ This is a pump file for generating file templates.  Pump is a python
+$$ script that is part of the Google Test suite of utilities.  Description
+$$ can be found here:
+$$
+$$ http://code.google.com/p/googletest/wiki/PumpManual
+$$
+
+$$ See comment for MAX_ARITY in base/bind.h.pump.
+$var MAX_ARITY = 7
+
+// 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 BASE_CALLBACK_LIST_H_
+#define BASE_CALLBACK_LIST_H_
+
+#include <list>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/callback_internal.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+
+// OVERVIEW:
+//
+// A container for a list of callbacks.  Unlike a normal STL vector or list,
+// this container can be modified during iteration without invalidating the
+// iterator. It safely handles the case of a callback removing itself
+// or another callback from the list while callbacks are being run.
+//
+// TYPICAL USAGE:
+//
+// class MyWidget {
+//  public:
+//   ...
+//
+//   typedef base::Callback<void(const Foo&)> OnFooCallback;
+//
+//   scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
+//   RegisterCallback(const OnFooCallback& cb) {
+//     return callback_list_.Add(cb);
+//   }
+//
+//  private:
+//   void NotifyFoo(const Foo& foo) {
+//      callback_list_.Notify(foo);
+//   }
+//
+//   base::CallbackList<void(const Foo&)> callback_list_;
+//
+//   DISALLOW_COPY_AND_ASSIGN(MyWidget);
+// };
+//
+//
+// class MyWidgetListener {
+//  public:
+//   MyWidgetListener::MyWidgetListener() {
+//     foo_subscription_ = MyWidget::GetCurrent()->RegisterCallback(
+//             base::Bind(&MyWidgetListener::OnFoo, this)));
+//   }
+//
+//   MyWidgetListener::~MyWidgetListener() {
+//      // Subscription gets deleted automatically and will deregister
+//      // the callback in the process.
+//   }
+//
+//  private:
+//   void OnFoo(const Foo& foo) {
+//     // Do something.
+//   }
+//
+//   scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
+//       foo_subscription_;
+//
+//   DISALLOW_COPY_AND_ASSIGN(MyWidgetListener);
+// };
+
+namespace base {
+
+namespace internal {
+
+template <typename CallbackType>
+class CallbackListBase {
+ public:
+  class Subscription {
+   public:
+    Subscription(CallbackListBase<CallbackType>* list,
+                 typename std::list<CallbackType>::iterator iter)
+        : list_(list),
+          iter_(iter) {
+    }
+
+    ~Subscription() {
+      if (list_->active_iterator_count_) {
+        iter_->Reset();
+      } else {
+        list_->callbacks_.erase(iter_);
+        if (!list_->removal_callback_.is_null())
+          list_->removal_callback_.Run();
+      }
+    }
+
+   private:
+    CallbackListBase<CallbackType>* list_;
+    typename std::list<CallbackType>::iterator iter_;
+
+    DISALLOW_COPY_AND_ASSIGN(Subscription);
+  };
+
+  // Add a callback to the list. The callback will remain registered until the
+  // returned Subscription is destroyed, which must occur before the
+  // CallbackList is destroyed.
+  scoped_ptr<Subscription> Add(const CallbackType& cb) WARN_UNUSED_RESULT {
+    DCHECK(!cb.is_null());
+    return scoped_ptr<Subscription>(
+        new Subscription(this, callbacks_.insert(callbacks_.end(), cb)));
+  }
+
+  // Sets a callback which will be run when a subscription list is changed.
+  void set_removal_callback(const Closure& callback) {
+    removal_callback_ = callback;
+  }
+
+  // Returns true if there are no subscriptions. This is only valid to call when
+  // not looping through the list.
+  bool empty() {
+    DCHECK_EQ(0, active_iterator_count_);
+    return callbacks_.empty();
+  }
+
+ protected:
+  // An iterator class that can be used to access the list of callbacks.
+  class Iterator {
+   public:
+    explicit Iterator(CallbackListBase<CallbackType>* list)
+        : list_(list),
+          list_iter_(list_->callbacks_.begin()) {
+      ++list_->active_iterator_count_;
+    }
+
+    Iterator(const Iterator& iter)
+        : list_(iter.list_),
+          list_iter_(iter.list_iter_) {
+      ++list_->active_iterator_count_;
+    }
+
+    ~Iterator() {
+      if (list_ && --list_->active_iterator_count_ == 0) {
+        list_->Compact();
+      }
+    }
+
+    CallbackType* GetNext() {
+      while ((list_iter_ != list_->callbacks_.end()) && list_iter_->is_null())
+        ++list_iter_;
+
+      CallbackType* cb = NULL;
+      if (list_iter_ != list_->callbacks_.end()) {
+        cb = &(*list_iter_);
+        ++list_iter_;
+      }
+      return cb;
+    }
+
+   private:
+    CallbackListBase<CallbackType>* list_;
+    typename std::list<CallbackType>::iterator list_iter_;
+  };
+
+  CallbackListBase() : active_iterator_count_(0) {}
+
+  ~CallbackListBase() {
+    DCHECK_EQ(0, active_iterator_count_);
+    DCHECK_EQ(0U, callbacks_.size());
+  }
+
+  // Returns an instance of a CallbackListBase::Iterator which can be used
+  // to run callbacks.
+  Iterator GetIterator() {
+    return Iterator(this);
+  }
+
+  // Compact the list: remove any entries which were NULLed out during
+  // iteration.
+  void Compact() {
+    typename std::list<CallbackType>::iterator it = callbacks_.begin();
+    bool updated = false;
+    while (it != callbacks_.end()) {
+      if ((*it).is_null()) {
+        updated = true;
+        it = callbacks_.erase(it);
+      } else {
+        ++it;
+      }
+
+      if (updated && !removal_callback_.is_null())
+        removal_callback_.Run();
+    }
+  }
+
+ private:
+  std::list<CallbackType> callbacks_;
+  int active_iterator_count_;
+  Closure removal_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(CallbackListBase);
+};
+
+}  // namespace internal
+
+template <typename Sig> class CallbackList;
+
+
+$range ARITY 0..MAX_ARITY
+$for ARITY [[
+$range ARG 1..ARITY
+
+$if ARITY == 0 [[
+template <>
+class CallbackList<void(void)>
+    : public internal::CallbackListBase<Callback<void(void)> > {
+]] $else [[
+template <$for ARG , [[typename A$(ARG)]]>
+class CallbackList<void($for ARG , [[A$(ARG)]])>
+    : public internal::CallbackListBase<Callback<void($for ARG , [[A$(ARG)]])> > {
+]]
+
+ public:
+$if ARITY == 0 [[
+
+  typedef Callback<void(void)> CallbackType;
+]] $else [[
+
+  typedef Callback<void($for ARG , [[A$(ARG)]])> CallbackType;
+]]
+
+
+  CallbackList() {}
+
+  void Notify($for ARG ,
+              [[typename internal::CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
+$if ARITY == 0 [[
+
+    internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+]] $else [[
+
+    typename internal::CallbackListBase<CallbackType>::Iterator it =
+        this->GetIterator();
+]]
+
+    CallbackType* cb;
+    while ((cb = it.GetNext()) != NULL) {
+      cb->Run($for ARG , [[a$(ARG)]]);
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CallbackList);
+};
+
+
+]]  $$ for ARITY
+}  // namespace base
+
+#endif  // BASE_CALLBACK_LIST_H_
diff --git a/base/compiler_specific.h b/base/compiler_specific.h
index 6210d1a..47ca9778 100644
--- a/base/compiler_specific.h
+++ b/base/compiler_specific.h
@@ -139,12 +139,6 @@
 #define ALIGNOF(type) __alignof__(type)
 #endif
 
-// Annotate a virtual method indicating it must be overriding a virtual
-// method in the parent class.
-// Use like:
-//   virtual void foo() OVERRIDE;
-#define OVERRIDE override
-
 // Annotate a function indicating the caller must examine the return value.
 // Use like:
 //   int foo() WARN_UNUSED_RESULT;
diff --git a/base/files/file_path_watcher_linux.cc b/base/files/file_path_watcher_linux.cc
index fb5ba620..4078920 100644
--- a/base/files/file_path_watcher_linux.cc
+++ b/base/files/file_path_watcher_linux.cc
@@ -105,25 +105,25 @@
                          bool is_dir);
 
  protected:
-  virtual ~FilePathWatcherImpl() {}
+  ~FilePathWatcherImpl() override {}
 
  private:
   // Start watching |path| for changes and notify |delegate| on each change.
   // Returns true if watch for |path| has been added successfully.
-  virtual bool Watch(const FilePath& path,
-                     bool recursive,
-                     const FilePathWatcher::Callback& callback) override;
+  bool Watch(const FilePath& path,
+             bool recursive,
+             const FilePathWatcher::Callback& callback) override;
 
   // Cancel the watch. This unregisters the instance with InotifyReader.
-  virtual void Cancel() override;
+  void Cancel() override;
 
   // Cleans up and stops observing the message_loop() thread.
-  virtual void CancelOnMessageLoopThread() override;
+  void CancelOnMessageLoopThread() override;
 
   // Deletion of the FilePathWatcher will call Cancel() to dispose of this
   // object in the right thread. This also observes destruction of the required
   // cleanup thread, in case it quits before Cancel() is called.
-  virtual void WillDestroyCurrentMessageLoop() override;
+  void WillDestroyCurrentMessageLoop() override;
 
   // Inotify watches are installed for all directory components of |target_|. A
   // WatchEntry instance holds the watch descriptor for a component and the
diff --git a/base/i18n/icu_string_conversions_unittest.cc b/base/i18n/icu_string_conversions_unittest.cc
index 107e240..d4d3251 100644
--- a/base/i18n/icu_string_conversions_unittest.cc
+++ b/base/i18n/icu_string_conversions_unittest.cc
@@ -343,7 +343,8 @@
   {"foo-\xe4.html", "iso-8859-1", true, "foo-\xc3\xa4.html"},
   {"foo-\xe4.html", "iso-8859-7", true, "foo-\xce\xb4.html"},
   {"foo-\xe4.html", "foo-bar", false, ""},
-  {"foo-\xff.html", "ascii", false, ""},
+  // HTML Encoding spec treats US-ASCII as synonymous with windows-1252
+  {"foo-\xff.html", "ascii", true, "foo-\xc3\xbf.html"},
   {"foo.html", "ascii", true, "foo.html"},
   {"foo-a\xcc\x88.html", "utf-8", true, "foo-\xc3\xa4.html"},
   {"\x95\x32\x82\x36\xD2\xBB", "gb18030", true, "\xF0\xA0\x80\x80\xE4\xB8\x80"},
diff --git a/base/logging.h b/base/logging.h
index 88d5efff..54ff5797 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -450,14 +450,36 @@
 
 #else
 
+#if defined(_PREFAST_) && defined(OS_WIN)
+// Use __analysis_assume to tell the VC++ static analysis engine that
+// assert conditions are true, to suppress warnings.  The LAZY_STREAM
+// parameter doesn't reference 'condition' in /analyze builds because
+// this evaluation confuses /analyze. The !! before condition is because
+// __analysis_assume gets confused on some conditions:
+// http://randomascii.wordpress.com/2011/09/13/analyze-for-visual-studio-the-ugly-part-5/
+
+#define CHECK(condition)                \
+  __analysis_assume(!!(condition)),     \
+  LAZY_STREAM(LOG_STREAM(FATAL), false) \
+  << "Check failed: " #condition ". "
+
+#define PCHECK(condition)                \
+  __analysis_assume(!!(condition)),      \
+  LAZY_STREAM(PLOG_STREAM(FATAL), false) \
+  << "Check failed: " #condition ". "
+
+#else  // _PREFAST_
+
 #define CHECK(condition)                       \
   LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \
   << "Check failed: " #condition ". "
 
-#define PCHECK(condition) \
+#define PCHECK(condition)                       \
   LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \
   << "Check failed: " #condition ". "
 
+#endif  // _PREFAST_
+
 // Helper macro for binary operators.
 // Don't use this macro directly in your code, use CHECK_EQ et al below.
 //
@@ -616,6 +638,21 @@
 // variable warnings if the only use of a variable is in a DCHECK.
 // This behavior is different from DLOG_IF et al.
 
+#if defined(_PREFAST_) && defined(OS_WIN)
+// See comments on the previous use of __analysis_assume.
+
+#define DCHECK(condition)                                               \
+  __analysis_assume(!!(condition)),                                     \
+  LAZY_STREAM(LOG_STREAM(DCHECK), false)                                \
+  << "Check failed: " #condition ". "
+
+#define DPCHECK(condition)                                              \
+  __analysis_assume(!!(condition)),                                     \
+  LAZY_STREAM(PLOG_STREAM(DCHECK), false)                               \
+  << "Check failed: " #condition ". "
+
+#else  // _PREFAST_
+
 #define DCHECK(condition)                                               \
   LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON ? !(condition) : false)  \
   << "Check failed: " #condition ". "
@@ -624,6 +661,8 @@
   LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON ? !(condition) : false) \
   << "Check failed: " #condition ". "
 
+#endif  // _PREFAST_
+
 // Helper macro for binary operators.
 // Don't use this macro directly in your code, use DCHECK_EQ et al below.
 #define DCHECK_OP(name, op, val1, val2)                         \
diff --git a/base/memory/memory_pressure_level_list.h b/base/memory/memory_pressure_level_list.h
deleted file mode 100644
index bf3ce605..0000000
--- a/base/memory/memory_pressure_level_list.h
+++ /dev/null
@@ -1,19 +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.
-
-// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum and a java class for the values.
-
-#ifndef DEFINE_MEMORY_PRESSURE_LEVEL
-#error "DEFINE_MEMORY_PRESSURE_LEVEL should be defined."
-#endif
-
-// Modules are advised to free buffers that are cheap to re-allocate and not
-// immediately needed.
-DEFINE_MEMORY_PRESSURE_LEVEL(MEMORY_PRESSURE_MODERATE, 0)
-
-// At this level, modules are advised to free all possible memory.
-// The alternative is to be killed by the system, which means all memory will
-// have to be re-created, plus the cost of a cold start.
-DEFINE_MEMORY_PRESSURE_LEVEL(MEMORY_PRESSURE_CRITICAL, 2)
diff --git a/base/memory/memory_pressure_listener.h b/base/memory/memory_pressure_listener.h
index 90eb144f..f586209c 100644
--- a/base/memory/memory_pressure_listener.h
+++ b/base/memory/memory_pressure_listener.h
@@ -49,10 +49,17 @@
 //
 class BASE_EXPORT MemoryPressureListener {
  public:
+  // A Java counterpart will be generated for this enum.
+  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
   enum MemoryPressureLevel {
-#define DEFINE_MEMORY_PRESSURE_LEVEL(name, value) name = value,
-#include "base/memory/memory_pressure_level_list.h"
-#undef DEFINE_MEMORY_PRESSURE_LEVEL
+    // Modules are advised to free buffers that are cheap to re-allocate and not
+    // immediately needed.
+    MEMORY_PRESSURE_LEVEL_MODERATE = 0,
+
+    // At this level, modules are advised to free all possible memory.  The
+    // alternative is to be killed by the system, which means all memory will
+    // have to be re-created, plus the cost of a cold start.
+    MEMORY_PRESSURE_LEVEL_CRITICAL = 2,
   };
 
   typedef base::Callback<void(MemoryPressureLevel)> MemoryPressureCallback;
diff --git a/base/memory/scoped_ptr.h b/base/memory/scoped_ptr.h
index f3bbd12..ae9eb0f 100644
--- a/base/memory/scoped_ptr.h
+++ b/base/memory/scoped_ptr.h
@@ -73,16 +73,6 @@
 //
 //   scoped_ptr<Foo> foo(new Foo());
 //   scoped_ptr<FooParent> parent(foo.Pass());
-//
-// PassAs<>() should be used to upcast return value in return statement:
-//
-//   scoped_ptr<Foo> CreateFoo() {
-//     scoped_ptr<FooChild> result(new FooChild());
-//     return result.PassAs<Foo>();
-//   }
-//
-// Note that PassAs<>() is implemented only for scoped_ptr<T>, but not for
-// scoped_ptr<T[]>. This is because casting array pointers may not be safe.
 
 #ifndef BASE_MEMORY_SCOPED_PTR_H_
 #define BASE_MEMORY_SCOPED_PTR_H_
@@ -436,17 +426,6 @@
     return impl_.release();
   }
 
-  // C++98 doesn't support functions templates with default parameters which
-  // makes it hard to write a PassAs() that understands converting the deleter
-  // while preserving simple calling semantics.
-  //
-  // Until there is a use case for PassAs() with custom deleters, just ignore
-  // the custom deleter.
-  template <typename PassAsType>
-  scoped_ptr<PassAsType> PassAs() {
-    return scoped_ptr<PassAsType>(Pass());
-  }
-
  private:
   // Needed to reach into |impl_| in the constructor.
   template <typename U, typename V> friend class scoped_ptr;
diff --git a/base/memory/scoped_ptr_unittest.cc b/base/memory/scoped_ptr_unittest.cc
index 6af19b6..3f169a7 100644
--- a/base/memory/scoped_ptr_unittest.cc
+++ b/base/memory/scoped_ptr_unittest.cc
@@ -94,11 +94,6 @@
   return scoped_ptr<ConDecLogger>(new ConDecLogger(constructed));
 }
 
-scoped_ptr<ConDecLoggerParent> UpcastUsingPassAs(
-    scoped_ptr<ConDecLogger> object) {
-  return object.PassAs<ConDecLoggerParent>();
-}
-
 }  // namespace
 
 TEST(ScopedPtrTest, ScopedPtr) {
@@ -462,22 +457,6 @@
   EXPECT_EQ(0, constructed);
 }
 
-TEST(ScopedPtrTest, PassAs) {
-  int constructed = 0;
-  {
-    scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
-    EXPECT_EQ(1, constructed);
-    EXPECT_TRUE(scoper.get());
-
-    scoped_ptr<ConDecLoggerParent> scoper_parent;
-    scoper_parent = UpcastUsingPassAs(scoper.Pass());
-    EXPECT_EQ(1, constructed);
-    EXPECT_TRUE(scoper_parent.get());
-    EXPECT_FALSE(scoper.get());
-  }
-  EXPECT_EQ(0, constructed);
-}
-
 TEST(ScopedPtrTest, CustomDeleter) {
   double dummy_value;  // Custom deleter never touches this value.
   int deletes = 0;
diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h
index f6001e2..8a43392 100644
--- a/base/memory/weak_ptr.h
+++ b/base/memory/weak_ptr.h
@@ -48,17 +48,18 @@
 // ------------------------- IMPORTANT: Thread-safety -------------------------
 
 // Weak pointers may be passed safely between threads, but must always be
-// dereferenced and invalidated on the same thread otherwise checking the
-// pointer would be racey.
+// dereferenced and invalidated on the same SequencedTaskRunner otherwise
+// checking the pointer would be racey.
 //
 // To ensure correct use, the first time a WeakPtr issued by a WeakPtrFactory
 // is dereferenced, the factory and its WeakPtrs become bound to the calling
-// thread, and cannot be dereferenced or invalidated on any other thread. Bound
-// WeakPtrs can still be handed off to other threads, e.g. to use to post tasks
-// back to object on the bound thread.
+// thread or current SequencedWorkerPool token, and cannot be dereferenced or
+// invalidated on any other task runner. Bound WeakPtrs can still be handed
+// off to other task runners, e.g. to use to post tasks back to object on the
+// bound sequence.
 //
-// Invalidating the factory's WeakPtrs un-binds it from the thread, allowing it
-// to be passed for a different thread to use or delete it.
+// Invalidating the factory's WeakPtrs un-binds it from the sequence, allowing
+// it to be passed for a different sequence to use or delete it.
 
 #ifndef BASE_MEMORY_WEAK_PTR_H_
 #define BASE_MEMORY_WEAK_PTR_H_
@@ -81,8 +82,8 @@
 
 class BASE_EXPORT WeakReference {
  public:
-  // Although Flag is bound to a specific thread, it may be deleted from another
-  // via base::WeakPtr::~WeakPtr().
+  // Although Flag is bound to a specific SequencedTaskRunner, it may be
+  // deleted from another via base::WeakPtr::~WeakPtr().
   class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> {
    public:
     Flag();
diff --git a/base/message_loop/message_pump_glib.h b/base/message_loop/message_pump_glib.h
index 0f797c51..9f44571 100644
--- a/base/message_loop/message_pump_glib.h
+++ b/base/message_loop/message_pump_glib.h
@@ -22,7 +22,7 @@
 class BASE_EXPORT MessagePumpGlib : public MessagePump {
  public:
   MessagePumpGlib();
-  virtual ~MessagePumpGlib();
+  ~MessagePumpGlib() override;
 
   // Internal methods used for processing the pump callbacks.  They are
   // public for simplicity but should not be used directly.  HandlePrepare
@@ -35,10 +35,10 @@
   void HandleDispatch();
 
   // Overridden from MessagePump:
-  virtual void Run(Delegate* delegate) override;
-  virtual void Quit() override;
-  virtual void ScheduleWork() override;
-  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override;
+  void Run(Delegate* delegate) override;
+  void Quit() override;
+  void ScheduleWork() override;
+  void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override;
 
  private:
   bool ShouldQuit() const;
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
index 05afb9b..c82f33d 100644
--- a/base/metrics/field_trial.cc
+++ b/base/metrics/field_trial.cc
@@ -320,8 +320,11 @@
 
   double entropy_value;
   if (randomization_type == FieldTrial::ONE_TIME_RANDOMIZED) {
-    entropy_value = GetEntropyProviderForOneTimeRandomization()->
-          GetEntropyForTrial(trial_name, randomization_seed);
+    const FieldTrial::EntropyProvider* entropy_provider =
+        GetEntropyProviderForOneTimeRandomization();
+    CHECK(entropy_provider);
+    entropy_value = entropy_provider->GetEntropyForTrial(trial_name,
+                                                         randomization_seed);
   } else {
     DCHECK_EQ(FieldTrial::SESSION_RANDOMIZED, randomization_type);
     DCHECK_EQ(0U, randomization_seed);
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc
index 905cc22ea..80c729d 100644
--- a/base/metrics/field_trial_unittest.cc
+++ b/base/metrics/field_trial_unittest.cc
@@ -990,4 +990,15 @@
   }
 }
 
+#if GTEST_HAS_DEATH_TEST
+TEST(FieldTrialDeathTest, OneTimeRandomizedTrialWithoutFieldTrialList) {
+  // Trying to instantiate a one-time randomized field trial before the
+  // FieldTrialList is created should crash.
+  EXPECT_DEATH(FieldTrialList::FactoryGetFieldTrial(
+      "OneTimeRandomizedTrialWithoutFieldTrialList", 100, kDefaultGroupName,
+      base::FieldTrialList::kNoExpirationYear, 1, 1,
+      base::FieldTrial::ONE_TIME_RANDOMIZED, NULL), "");
+}
+#endif
+
 }  // namespace base
diff --git a/base/process/kill_posix.cc b/base/process/kill_posix.cc
index bff7be46b..b02453c 100644
--- a/base/process/kill_posix.cc
+++ b/base/process/kill_posix.cc
@@ -415,7 +415,7 @@
   }
 
   // Overridden from PlatformThread::Delegate:
-  virtual void ThreadMain() override {
+  void ThreadMain() override {
     WaitForChildToDie();
     delete this;
   }
diff --git a/base/sys_info_android.cc b/base/sys_info_android.cc
index ab760e5..0d885ee 100644
--- a/base/sys_info_android.cc
+++ b/base/sys_info_android.cc
@@ -15,8 +15,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/sys_info_internal.h"
 
-// TODO(rmcilroy): Update API level when 'L' gets an official API level.
-#if (__ANDROID_API__ >= 9999 /* 'L' */)
+#if (__ANDROID_API__ >= 21 /* 5.0 - Lollipop */)
 
 namespace {
 
diff --git a/base/test/launcher/test_launcher_ios.cc b/base/test/launcher/test_launcher_ios.cc
new file mode 100644
index 0000000..38e4ef9a
--- /dev/null
+++ b/base/test/launcher/test_launcher_ios.cc
@@ -0,0 +1,20 @@
+// 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 "base/test/launcher/test_launcher.h"
+
+#include "base/bind.h"
+#include "base/test/launcher/unit_test_launcher.h"
+
+namespace {
+
+int DummyRunTestSuite(void) {
+  return -1;
+}
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  return base::LaunchUnitTests(argc, argv, base::Bind(&DummyRunTestSuite));
+}
diff --git a/base/win/metro.cc b/base/win/metro.cc
index 62743c7..6e443ba 100644
--- a/base/win/metro.cc
+++ b/base/win/metro.cc
@@ -74,8 +74,8 @@
 }
 
 bool IsParentalControlActivityLoggingOn() {
-  // Query this info on Windows Vista and above.
-  if (base::win::GetVersion() < base::win::VERSION_VISTA)
+  // Query this info on Windows 7 and above.
+  if (base::win::GetVersion() < base::win::VERSION_WIN7)
     return false;
 
   static bool parental_control_logging_required = false;
diff --git a/base/win/pe_image.h b/base/win/pe_image.h
index 878ef52..d93e99d 100644
--- a/base/win/pe_image.h
+++ b/base/win/pe_image.h
@@ -23,7 +23,7 @@
 namespace win {
 
 // This class is a wrapper for the Portable Executable File Format (PE).
-// It's main purpose is to provide an easy way to work with imports and exports
+// Its main purpose is to provide an easy way to work with imports and exports
 // from a file, mapped in memory as image.
 class PEImage {
  public:
@@ -84,6 +84,8 @@
     module_ = reinterpret_cast<HMODULE>(const_cast<void*>(module));
   }
 
+  virtual ~PEImage() {}
+
   // Gets the HMODULE for this object.
   HMODULE module() const;
 
diff --git a/build/all.gyp b/build/all.gyp
index b469a22..f421983 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -98,7 +98,6 @@
         ['OS!="ios" and OS!="android"', {
           '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:*',
@@ -143,6 +142,21 @@
             '../v8/tools/gyp/v8.gyp:*',
             '<(libjpeg_gyp_path):*',
           ],
+          'conditions': [
+            ['use_athena==1' , {
+              'dependencies': [
+                 # Athena temporarily depends upon a subset of chrome. Since most
+                 # tests do not compile, we only include dependencies to tests we
+                 # want to build.
+                 '../chrome/chrome.gyp:chrome',
+                 '../chrome/chrome.gyp:browser_tests',
+              ]
+            }, {
+              'dependencies': [
+               '../chrome/chrome.gyp:*',
+              ],
+            }],
+          ],
         }],
         ['OS=="mac" or OS=="ios" or OS=="win"', {
           'dependencies': [
@@ -305,8 +319,6 @@
             '../chrome/chrome.gyp:chromedriver_tests',
             '../chrome/chrome.gyp:chromedriver_unittests',
             '../chrome/chrome.gyp:interactive_ui_tests',
-            '../chrome/chrome.gyp:sync_integration_tests',
-            '../chrome/chrome.gyp:unit_tests',
             '../cloud_print/cloud_print.gyp:cloud_print_unittests',
             '../content/content_shell_and_tests.gyp:content_browsertests',
             '../content/content_shell_and_tests.gyp:content_shell',
@@ -332,6 +344,14 @@
             '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
             '../tools/telemetry/telemetry.gyp:*',
           ],
+          'conditions': [
+            ['use_athena!=1', {
+              'dependencies' : [ 
+                '../chrome/chrome.gyp:sync_integration_tests',
+                '../chrome/chrome.gyp:unit_tests',
+               ],
+            }],
+          ],
         }],
         ['OS=="win"', {
           'dependencies': [
@@ -1211,8 +1231,6 @@
             '../cc/cc_tests.gyp:cc_unittests',
             '../chrome/chrome.gyp:browser_tests',
             '../chrome/chrome.gyp:chrome',
-            '../chrome/chrome.gyp:interactive_ui_tests',
-            '../chrome/chrome.gyp:unit_tests',
             '../components/components_tests.gyp:components_unittests',
             '../content/content_shell_and_tests.gyp:content_browsertests',
             '../content/content_shell_and_tests.gyp:content_unittests',
@@ -1238,6 +1256,12 @@
             'blink_tests',
           ],
           'conditions': [
+            ['use_athena!=1', {
+              'dependencies': [
+                '../chrome/chrome.gyp:interactive_ui_tests',
+                '../chrome/chrome.gyp:unit_tests',
+              ],
+            }],
             ['OS=="win"', {
               'dependencies': [
                 '../chrome/chrome.gyp:crash_service',
@@ -1302,13 +1326,19 @@
           'dependencies': [
             '../base/base.gyp:base_unittests_run',
             '../chrome/chrome.gyp:browser_tests_run',
-            '../chrome/chrome.gyp:interactive_ui_tests_run',
-            '../chrome/chrome.gyp:sync_integration_tests_run',
-            '../chrome/chrome.gyp:unit_tests_run',
             '../content/content_shell_and_tests.gyp:content_browsertests_run',
             '../content/content_shell_and_tests.gyp:content_unittests_run',
             '../net/net.gyp:net_unittests_run',
           ],
+          'conditions' : [
+            ['use_athena!=1', {
+              'dependencies': [
+                '../chrome/chrome.gyp:interactive_ui_tests_run',
+                '../chrome/chrome.gyp:sync_integration_tests_run',
+                '../chrome/chrome.gyp:unit_tests_run',
+              ],
+            }],
+          ],
         }, # target_name: chromium_swarm_tests
       ],
     }],
diff --git a/build/android/AndroidManifest.xml b/build/android/AndroidManifest.xml
index 5dacfa9..25e1db0 100644
--- a/build/android/AndroidManifest.xml
+++ b/build/android/AndroidManifest.xml
@@ -15,6 +15,6 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="dummy.package">
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
 
 </manifest>
diff --git a/build/android/adb_run_android_webview_shell b/build/android/adb_run_android_webview_shell
index cc9f6d2..1014a73 100755
--- a/build/android/adb_run_android_webview_shell
+++ b/build/android/adb_run_android_webview_shell
@@ -4,12 +4,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-if [ $# -gt 0 ] ; then
-   INTENT_ARGS="-d \"$1\""  # e.g. a URL
-fi
+optional_url=$1
 
 adb shell am start \
   -a android.intent.action.VIEW \
   -n org.chromium.android_webview.shell/.AwShellActivity \
-  $INTENT_ARGS
-
+  ${optional_url:+-d "$optional_url"}
diff --git a/build/android/adb_run_chrome_shell b/build/android/adb_run_chrome_shell
index 46558b3..79c4c32b 100755
--- a/build/android/adb_run_chrome_shell
+++ b/build/android/adb_run_chrome_shell
@@ -4,11 +4,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-if [ $# -gt 0 ] ; then
-   INTENT_ARGS="-d \"$1\""  # e.g. a URL
-fi
+optional_url=$1
 
 adb shell am start \
   -a android.intent.action.VIEW \
   -n org.chromium.chrome.shell/.ChromeShellActivity \
-  $INTENT_ARGS
+  ${optional_url:+-d "$optional_url"}
diff --git a/build/android/adb_run_content_shell b/build/android/adb_run_content_shell
index 17a734c9..3f01f3bf 100755
--- a/build/android/adb_run_content_shell
+++ b/build/android/adb_run_content_shell
@@ -4,11 +4,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-if [ $# -gt 0 ] ; then
-   INTENT_ARGS="-d \"$1\""  # e.g. a URL
-fi
+optional_url=$1
 
 adb shell am start \
   -a android.intent.action.VIEW \
   -n org.chromium.content_shell_apk/.ContentShellActivity \
-  $INTENT_ARGS
+  ${optional_url:+-d "$optional_url"}
diff --git a/build/android/adb_run_mojo_shell b/build/android/adb_run_mojo_shell
index 6f55fb2..18e796d 100755
--- a/build/android/adb_run_mojo_shell
+++ b/build/android/adb_run_mojo_shell
@@ -4,13 +4,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-if [ $# -gt 0 ] ; then
-   INTENT_ARGS="-d \"$1\""  # e.g. a URL
-fi
+optional_url=$1
 
 adb logcat -c
 adb shell am start -S \
   -a android.intent.action.VIEW \
   -n org.chromium.mojo_shell_apk/.MojoShellActivity \
-  $INTENT_ARGS
+  ${optional_url:+-d "$optional_url"}
 adb logcat -s MojoShellApplication MojoShellActivity chromium
diff --git a/build/android/android_exports.gyp b/build/android/android_exports.gyp
index c259eee3..08a3f1b 100644
--- a/build/android/android_exports.gyp
+++ b/build/android/android_exports.gyp
@@ -6,6 +6,7 @@
   'targets': [
     {
       'target_name': 'android_exports',
+      'toolsets': ['host', 'target'],
       'type': 'none',
       'inputs': [
         '<(DEPTH)/build/android/android_exports.lst',
diff --git a/build/android/buildbot/OWNERS b/build/android/buildbot/OWNERS
index 425f1d9..f289720 100644
--- a/build/android/buildbot/OWNERS
+++ b/build/android/buildbot/OWNERS
@@ -1,9 +1,6 @@
 set noparent
 
 cmp@chromium.org
-craigdh@chromium.org
-frankf@chromium.org
+jbudorick@chromium.org
 navabi@chromium.org
 
-# backup
-ilevy@chromium.org
diff --git a/build/android/buildbot/bb_device_status_check.py b/build/android/buildbot/bb_device_status_check.py
index 2eb3626..d98c1dd 100755
--- a/build/android/buildbot/bb_device_status_check.py
+++ b/build/android/buildbot/bb_device_status_check.py
@@ -31,7 +31,6 @@
 from pylib import constants
 from pylib.cmd_helper import GetCmdOutput
 from pylib.device import device_blacklist
-from pylib.device import device_errors
 from pylib.device import device_list
 from pylib.device import device_utils
 
@@ -83,8 +82,13 @@
   errors = []
   dev_good = True
   if battery_level < 15:
-    errors += ['Device critically low in battery. Turning off device.']
+    errors += ['Device critically low in battery. Will add to blacklist.']
     dev_good = False
+    if not device_adb.old_interface.IsDeviceCharging():
+      if device_adb.old_interface.CanControlUsbCharging():
+        device_adb.old_interface.EnableUsbCharging()
+      else:
+        logging.error('Device %s is not charging' % serial)
   if not options.no_provisioning_check:
     setup_wizard_disabled = (
         device_adb.GetProp('ro.setupwizard.mode') == 'DISABLED')
@@ -94,16 +98,6 @@
       battery_info.get('AC powered', None) != 'true'):
     errors += ['Mantaray device not connected to AC power.']
 
-  # Turn off devices with low battery.
-  if battery_level < 15:
-    try:
-      device_adb.EnableRoot()
-    except device_errors.CommandFailedError as e:
-      # Attempt shutdown anyway.
-      # TODO(jbudorick) Handle this exception appropriately after interface
-      #                 conversions are finished.
-      logging.error(str(e))
-    device_adb.old_interface.Shutdown()
   full_report = '\n'.join(report)
   return device_type, device_build, battery_level, full_report, errors, dev_good
 
@@ -252,7 +246,7 @@
       try:
         if 'adb' in p.name:
           yield p
-      except (psutil.error.NoSuchProcess, psutil.error.AccessDenied):
+      except (psutil.NoSuchProcess, psutil.AccessDenied):
         pass
 
   for sig in [signal.SIGTERM, signal.SIGQUIT, signal.SIGKILL]:
@@ -261,12 +255,12 @@
         print 'kill %d %d (%s [%s])' % (sig, p.pid, p.name,
             ' '.join(p.cmdline))
         p.send_signal(sig)
-      except (psutil.error.NoSuchProcess, psutil.error.AccessDenied):
+      except (psutil.NoSuchProcess, psutil.AccessDenied):
         pass
   for p in GetAllAdb():
     try:
       print 'Unable to kill %d (%s [%s])' % (p.pid, p.name, ' '.join(p.cmdline))
-    except (psutil.error.NoSuchProcess, psutil.error.AccessDenied):
+    except (psutil.NoSuchProcess, psutil.AccessDenied):
       pass
 
 
@@ -377,10 +371,13 @@
         'unique_builds': unique_builds,
       }))
 
-  if False in fail_step_lst:
-    # TODO(navabi): Build fails on device status check step if there exists any
-    # devices with critically low battery. Remove those devices from testing,
-    # allowing build to continue with good devices.
+  num_failed_devs = 0
+  for fail_status, device in zip(fail_step_lst, devices):
+    if not fail_status:
+      device_blacklist.ExtendBlacklist([str(device)])
+      num_failed_devs += 1
+
+  if num_failed_devs == len(devices):
     return 2
 
   if not devices:
diff --git a/build/android/buildbot/bb_device_steps.py b/build/android/buildbot/bb_device_steps.py
index c0f9fe7..6a7c90b 100755
--- a/build/android/buildbot/bb_device_steps.py
+++ b/build/android/buildbot/bb_device_steps.py
@@ -75,9 +75,9 @@
       'webview:android_webview/test/data/device_files'),
     ])
 
-VALID_TESTS = set(['chromedriver', 'chrome_proxy', 'gpu', 'mojo', 'sync',
+VALID_TESTS = set(['chromedriver', 'chrome_proxy', 'gpu', 'sync',
                    'telemetry_perf_unittests', 'ui', 'unit', 'webkit',
-                   'webkit_layout'])
+                   'webkit_layout', 'python_unittests'])
 
 RunCmd = bb_utils.RunCmd
 
@@ -145,6 +145,9 @@
     args.append('--tool=asan')
   if options.gtest_filter:
     args.append('--gtest-filter=%s' % options.gtest_filter)
+  if options.flakiness_server:
+    args.append('--flakiness-dashboard-server=%s' %
+                options.flakiness_server)
 
   for suite in suites:
     bb_annotations.PrintNamedStep(suite)
@@ -186,7 +189,7 @@
   test = I('ChromeSyncShell',
            'ChromeSyncShell.apk',
            'org.chromium.chrome.browser.sync',
-           'ChromeSyncShellTest.apk',
+           'ChromeSyncShellTest',
            'chrome:chrome/test/data/android/device_files')
   RunInstrumentationSuite(options, test)
 
@@ -205,20 +208,6 @@
   RunCmd(['tools/perf/run_tests'] + args)
 
 
-def RunMojoTests(options):
-  """Runs the mojo unit tests.
-
-  Args:
-    options: options object.
-  """
-  test = I('MojoTest',
-           None,
-           'org.chromium.mojo.tests',
-           'MojoTest',
-           'bindings:mojo/public/interfaces/bindings/tests/data')
-  RunInstrumentationSuite(options, test)
-
-
 def InstallApk(options, test, print_step=False):
   """Install an apk to all phones.
 
@@ -531,12 +520,18 @@
           EscapeBuilderName(builder_name)])
 
 
+def RunPythonUnitTests(_options):
+  for suite in constants.PYTHON_UNIT_TEST_SUITES:
+    bb_annotations.PrintNamedStep(suite)
+    RunCmd(['build/android/test_runner.py', 'python', '-s', suite])
+
+
 def GetTestStepCmds():
   return [
       ('chromedriver', RunChromeDriverTests),
       ('chrome_proxy', RunChromeProxyTests),
       ('gpu', RunGPUTests),
-      ('mojo', RunMojoTests),
+      ('python_unittests', RunPythonUnitTests),
       ('sync', RunChromeSyncShellTests),
       ('telemetry_perf_unittests', RunTelemetryPerfUnitTests),
       ('ui', RunInstrumentationTests),
diff --git a/build/android/buildbot/bb_run_bot.py b/build/android/buildbot/bb_run_bot.py
index 586287b8..28ccfba 100755
--- a/build/android/buildbot/bb_run_bot.py
+++ b/build/android/buildbot/bb_run_bot.py
@@ -117,11 +117,12 @@
   compile_step = ['compile']
   chrome_proxy_tests = ['chrome_proxy']
   chrome_sync_shell_tests = ['sync']
+  python_unittests = ['python_unittests']
   std_host_tests = ['check_webview_licenses', 'findbugs']
   emma_coverage_tests = [x for x in std_host_tests if x is not 'findbugs']
   std_build_steps = ['compile', 'zip_build']
   std_test_steps = ['extract_build']
-  std_tests = ['ui', 'unit', 'mojo']
+  std_tests = ['ui', 'unit']
   telemetry_tests = ['telemetry_perf_unittests']
   flakiness_server = (
       '--flakiness-server=%s' % constants.UPSTREAM_FLAKINESS_SERVER)
@@ -167,7 +168,7 @@
         H(compile_step + std_host_tests, target_arch='ia32')),
       B('fyi-builder-rel', H(std_build_steps,  experimental)),
       B('fyi-tests', H(std_test_steps),
-        T(std_tests + chrome_sync_shell_tests,
+        T(std_tests + chrome_sync_shell_tests + python_unittests,
                       ['--experimental', flakiness_server,
                       '--coverage-bucket', CHROMIUM_COVERAGE_BUCKET,
                       '--cleanup'])),
diff --git a/build/android/disable_lto.gypi b/build/android/disable_lto.gypi
new file mode 100644
index 0000000..448945ce
--- /dev/null
+++ b/build/android/disable_lto.gypi
@@ -0,0 +1,20 @@
+# Copyright (c) 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.
+
+# This file is meant to be included to disable LTO on a target.
+
+{
+  'target_conditions': [
+    ['_toolset=="target"', {
+      'conditions': [
+        ['use_lto==1 or use_lto_o2==1', {
+          'cflags!': [
+            '-flto',
+            '-ffat-lto-objects',
+          ],
+        }],
+      ],
+    }],
+  ],
+}
diff --git a/build/android/gyp/java_cpp_enum.py b/build/android/gyp/java_cpp_enum.py
index 6a1d5c1..8ae5f36b 100755
--- a/build/android/gyp/java_cpp_enum.py
+++ b/build/android/gyp/java_cpp_enum.py
@@ -14,17 +14,23 @@
 from util import build_utils
 
 class EnumDefinition(object):
-  def __init__(self, class_name=None, class_package=None, entries=None):
-    self.class_name = class_name
-    self.class_package = class_package
+  def __init__(self, original_enum_name=None, class_name_override=None,
+               enum_package=None, entries=None):
+    self.original_enum_name = original_enum_name
+    self.class_name_override = class_name_override
+    self.enum_package = enum_package
     self.entries = collections.OrderedDict(entries or [])
-    self.prefix_to_strip = ''
+    self.prefix_to_strip = None
 
   def AppendEntry(self, key, value):
     if key in self.entries:
       raise Exception('Multiple definitions of key %s found.' % key)
     self.entries[key] = value
 
+  @property
+  def class_name(self):
+    return self.class_name_override or self.original_enum_name
+
   def Finalize(self):
     self._Validate()
     self._AssignEntryIndices()
@@ -32,7 +38,7 @@
 
   def _Validate(self):
     assert self.class_name
-    assert self.class_package
+    assert self.enum_package
     assert self.entries
 
   def _AssignEntryIndices(self):
@@ -54,23 +60,59 @@
 
 
   def _StripPrefix(self):
-    if not self.prefix_to_strip:
-      prefix_to_strip = re.sub('(?!^)([A-Z]+)', r'_\1', self.class_name).upper()
+    prefix_to_strip = self.prefix_to_strip
+    if not prefix_to_strip:
+      prefix_to_strip = self.original_enum_name
+      prefix_to_strip = re.sub('(?!^)([A-Z]+)', r'_\1', prefix_to_strip).upper()
       prefix_to_strip += '_'
       if not all([w.startswith(prefix_to_strip) for w in self.entries.keys()]):
         prefix_to_strip = ''
-    else:
-      prefix_to_strip = self.prefix_to_strip
-    entries = ((k.replace(prefix_to_strip, '', 1), v) for (k, v) in
-               self.entries.iteritems())
-    self.entries = collections.OrderedDict(entries)
+
+    entries = collections.OrderedDict()
+    for (k, v) in self.entries.iteritems():
+      stripped_key = k.replace(prefix_to_strip, '', 1)
+      if isinstance(v, basestring):
+        stripped_value = v.replace(prefix_to_strip, '', 1)
+      else:
+        stripped_value = v
+      entries[stripped_key] = stripped_value
+
+    self.entries = entries
+
+class DirectiveSet(object):
+  class_name_override_key = 'CLASS_NAME_OVERRIDE'
+  enum_package_key = 'ENUM_PACKAGE'
+  prefix_to_strip_key = 'PREFIX_TO_STRIP'
+
+  known_keys = [class_name_override_key, enum_package_key, prefix_to_strip_key]
+
+  def __init__(self):
+    self._directives = {}
+
+  def Update(self, key, value):
+    if key not in DirectiveSet.known_keys:
+      raise Exception("Unknown directive: " + key)
+    self._directives[key] = value
+
+  @property
+  def empty(self):
+    return len(self._directives) == 0
+
+  def UpdateDefinition(self, definition):
+    definition.class_name_override = self._directives.get(
+        DirectiveSet.class_name_override_key, '')
+    definition.enum_package = self._directives.get(
+        DirectiveSet.enum_package_key)
+    definition.prefix_to_strip = self._directives.get(
+        DirectiveSet.prefix_to_strip_key)
+
 
 class HeaderParser(object):
   single_line_comment_re = re.compile(r'\s*//')
   multi_line_comment_start_re = re.compile(r'\s*/\*')
   enum_start_re = re.compile(r'^\s*enum\s+(\w+)\s+{\s*$')
   enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?')
-  enum_end_re = re.compile(r'^\s*}\s*;\s*$')
+  enum_end_re = re.compile(r'^\s*}\s*;\.*$')
   generator_directive_re = re.compile(
       r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$')
 
@@ -79,7 +121,7 @@
     self._enum_definitions = []
     self._in_enum = False
     self._current_definition = None
-    self._generator_directives = {}
+    self._generator_directives = DirectiveSet()
 
   def ParseDefinitions(self):
     for line in self._lines:
@@ -109,31 +151,23 @@
       enum_value = enum_entry.groups()[2]
       self._current_definition.AppendEntry(enum_key, enum_value)
 
-  def _GetCurrentEnumPackageName(self):
-    return self._generator_directives.get('ENUM_PACKAGE')
-
-  def _GetCurrentEnumPrefixToStrip(self):
-    return self._generator_directives.get('PREFIX_TO_STRIP', '')
-
   def _ApplyGeneratorDirectives(self):
-    current_definition = self._current_definition
-    current_definition.class_package = self._GetCurrentEnumPackageName()
-    current_definition.prefix_to_strip = self._GetCurrentEnumPrefixToStrip()
-    self._generator_directives = {}
+    self._generator_directives.UpdateDefinition(self._current_definition)
+    self._generator_directives = DirectiveSet()
 
   def _ParseRegularLine(self, line):
     enum_start = HeaderParser.enum_start_re.match(line)
     generator_directive = HeaderParser.generator_directive_re.match(line)
     if enum_start:
-      if not self._GetCurrentEnumPackageName():
+      if self._generator_directives.empty:
         return
-      self._current_definition = EnumDefinition()
-      self._current_definition.class_name = enum_start.groups()[0]
+      self._current_definition = EnumDefinition(
+          original_enum_name=enum_start.groups()[0])
       self._in_enum = True
     elif generator_directive:
       directive_name = generator_directive.groups()[0]
       directive_value = generator_directive.groups()[1]
-      self._generator_directives[directive_name] = directive_value
+      self._generator_directives.Update(directive_name, directive_value)
 
 
 def GetScriptName():
@@ -147,7 +181,7 @@
   for source_path in source_paths:
     enum_definitions = DoParseHeaderFile(source_path)
     for enum_definition in enum_definitions:
-      package_path = enum_definition.class_package.replace('.', os.path.sep)
+      package_path = enum_definition.enum_package.replace('.', os.path.sep)
       file_name = enum_definition.class_name + '.java'
       output_path = os.path.join(options.output_dir, package_path, file_name)
       output_paths.append(output_path)
@@ -193,7 +227,7 @@
   values = {
       'CLASS_NAME': enum_definition.class_name,
       'ENUM_ENTRIES': enum_entries_string,
-      'PACKAGE': enum_definition.class_package,
+      'PACKAGE': enum_definition.enum_package,
       'SCRIPT_NAME': GetScriptName(),
       'SOURCE_PATH': source_path,
   }
diff --git a/build/android/gyp/java_cpp_enum_tests.py b/build/android/gyp/java_cpp_enum_tests.py
index 24da05fd4..bb8150d7 100755
--- a/build/android/gyp/java_cpp_enum_tests.py
+++ b/build/android/gyp/java_cpp_enum_tests.py
@@ -9,13 +9,20 @@
 """
 
 import collections
+import optparse
+import os
+import sys
 import unittest
+
 from java_cpp_enum import EnumDefinition, GenerateOutput, HeaderParser
 
+sys.path.append(os.path.join(os.path.dirname(__file__), "gyp"))
+from util import build_utils
+
 class TestPreprocess(unittest.TestCase):
   def testOutput(self):
-    definition = EnumDefinition(class_name='ClassName',
-                                class_package='some.package',
+    definition = EnumDefinition(original_enum_name='ClassName',
+                                enum_package='some.package',
                                 entries=[('E1', 1), ('E2', '2 << 2')])
     output = GenerateOutput('path/to/file', definition)
     expected = """
@@ -49,11 +56,54 @@
     self.assertEqual(1, len(definitions))
     definition = definitions[0]
     self.assertEqual('EnumName', definition.class_name)
-    self.assertEqual('test.namespace', definition.class_package)
+    self.assertEqual('test.namespace', definition.enum_package)
     self.assertEqual(collections.OrderedDict([('VALUE_ZERO', 0),
                                               ('VALUE_ONE', 1)]),
                      definition.entries)
 
+  def testParseBitShifts(self):
+    test_data = """
+      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
+      enum EnumName {
+        VALUE_ZERO = 1 << 0,
+        VALUE_ONE = 1 << 1,
+      };
+    """.split('\n')
+    definitions = HeaderParser(test_data).ParseDefinitions()
+    self.assertEqual(1, len(definitions))
+    definition = definitions[0]
+    self.assertEqual('EnumName', definition.class_name)
+    self.assertEqual('test.namespace', definition.enum_package)
+    self.assertEqual(collections.OrderedDict([('VALUE_ZERO', '1 << 0'),
+                                              ('VALUE_ONE', '1 << 1')]),
+                     definition.entries)
+
+  def testParseClassNameOverride(self):
+    test_data = """
+      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
+      // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OverrideName
+      enum EnumName {
+        FOO
+      };
+
+      // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
+      // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OtherOverride
+      enum PrefixTest {
+        PREFIX_TEST_A,
+        PREFIX_TEST_B,
+      };
+    """.split('\n')
+    definitions = HeaderParser(test_data).ParseDefinitions()
+    self.assertEqual(2, len(definitions))
+    definition = definitions[0]
+    self.assertEqual('OverrideName', definition.class_name)
+
+    definition = definitions[1]
+    self.assertEqual('OtherOverride', definition.class_name)
+    self.assertEqual(collections.OrderedDict([('A', 0),
+                                              ('B', 1)]),
+                     definition.entries)
+
   def testParseTwoEnums(self):
     test_data = """
       // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
@@ -78,20 +128,30 @@
     self.assertEqual(2, len(definitions))
     definition = definitions[0]
     self.assertEqual('EnumOne', definition.class_name)
-    self.assertEqual('test.namespace', definition.class_package)
+    self.assertEqual('test.namespace', definition.enum_package)
     self.assertEqual(collections.OrderedDict([('A', '1'),
                                               ('B', 'A')]),
                      definition.entries)
 
     definition = definitions[1]
     self.assertEqual('EnumTwo', definition.class_name)
-    self.assertEqual('other.package', definition.class_package)
+    self.assertEqual('other.package', definition.enum_package)
     self.assertEqual(collections.OrderedDict([('A', 0),
                                               ('B', 1)]),
                      definition.entries)
 
+  def testParseThrowsOnUnknownDirective(self):
+    test_data = """
+      // GENERATED_JAVA_UNKNOWN: Value
+      enum EnumName {
+        VALUE_ONE,
+      };
+    """.split('\n')
+    with self.assertRaises(Exception):
+      HeaderParser(test_data).ParseDefinitions()
+
   def testEnumValueAssignmentNoneDefined(self):
-    definition = EnumDefinition('c', 'p', [])
+    definition = EnumDefinition(original_enum_name='c', enum_package='p')
     definition.AppendEntry('A', None)
     definition.AppendEntry('B', None)
     definition.AppendEntry('C', None)
@@ -102,7 +162,7 @@
                      definition.entries)
 
   def testEnumValueAssignmentAllDefined(self):
-    definition = EnumDefinition('c', 'p', [])
+    definition = EnumDefinition(original_enum_name='c', enum_package='p')
     definition.AppendEntry('A', '1')
     definition.AppendEntry('B', '2')
     definition.AppendEntry('C', '3')
@@ -113,7 +173,7 @@
                      definition.entries)
 
   def testEnumValueAssignmentReferences(self):
-    definition = EnumDefinition('c', 'p', [])
+    definition = EnumDefinition(original_enum_name='c', enum_package='p')
     definition.AppendEntry('A', None)
     definition.AppendEntry('B', 'A')
     definition.AppendEntry('C', None)
@@ -125,39 +185,85 @@
                                               ('D', 1)]),
                      definition.entries)
 
-  def testEnumValueAssignmentRaises(self):
-    definition = EnumDefinition('c', 'p', [])
+  def testEnumValueAssignmentSet(self):
+    definition = EnumDefinition(original_enum_name='c', enum_package='p')
     definition.AppendEntry('A', None)
-    definition.AppendEntry('B', '1')
+    definition.AppendEntry('B', '2')
+    definition.AppendEntry('C', None)
+    definition.Finalize()
+    self.assertEqual(collections.OrderedDict([('A', 0),
+                                              ('B', 2),
+                                              ('C', 3)]),
+                     definition.entries)
+
+  def testEnumValueAssignmentSetReferences(self):
+    definition = EnumDefinition(original_enum_name='c', enum_package='p')
+    definition.AppendEntry('A', None)
+    definition.AppendEntry('B', 'A')
+    definition.AppendEntry('C', 'B')
+    definition.AppendEntry('D', None)
+    definition.Finalize()
+    self.assertEqual(collections.OrderedDict([('A', 0),
+                                              ('B', 0),
+                                              ('C', 0),
+                                              ('D', 1)]),
+                     definition.entries)
+
+  def testEnumValueAssignmentRaises(self):
+    definition = EnumDefinition(original_enum_name='c', enum_package='p')
+    definition.AppendEntry('A', None)
+    definition.AppendEntry('B', 'foo')
     definition.AppendEntry('C', None)
     with self.assertRaises(Exception):
       definition.Finalize()
 
   def testExplicitPrefixStripping(self):
-    definition = EnumDefinition('c', 'p', [])
+    definition = EnumDefinition(original_enum_name='c', enum_package='p')
     definition.AppendEntry('P_A', None)
     definition.AppendEntry('B', None)
     definition.AppendEntry('P_C', None)
+    definition.AppendEntry('P_LAST', 'P_C')
     definition.prefix_to_strip = 'P_'
     definition.Finalize()
-    self.assertEqual(['A', 'B', 'C'], definition.entries.keys())
+    self.assertEqual(collections.OrderedDict([('A', 0),
+                                              ('B', 1),
+                                              ('C', 2),
+                                              ('LAST', 2)]),
+                     definition.entries)
 
   def testImplicitPrefixStripping(self):
-    definition = EnumDefinition('ClassName', 'p', [])
+    definition = EnumDefinition(original_enum_name='ClassName',
+                                enum_package='p')
     definition.AppendEntry('CLASS_NAME_A', None)
     definition.AppendEntry('CLASS_NAME_B', None)
     definition.AppendEntry('CLASS_NAME_C', None)
+    definition.AppendEntry('CLASS_NAME_LAST', 'CLASS_NAME_C')
     definition.Finalize()
-    self.assertEqual(['A', 'B', 'C'], definition.entries.keys())
+    self.assertEqual(collections.OrderedDict([('A', 0),
+                                              ('B', 1),
+                                              ('C', 2),
+                                              ('LAST', 2)]),
+                     definition.entries)
 
   def testImplicitPrefixStrippingRequiresAllConstantsToBePrefixed(self):
-    definition = EnumDefinition('Name', 'p', [])
+    definition = EnumDefinition(original_enum_name='Name',
+                                enum_package='p')
     definition.AppendEntry('A', None)
     definition.AppendEntry('B', None)
     definition.AppendEntry('NAME_LAST', None)
     definition.Finalize()
     self.assertEqual(['A', 'B', 'NAME_LAST'], definition.entries.keys())
 
+def main(argv):
+  parser = optparse.OptionParser()
+  parser.add_option("--stamp", help="File to touch on success.")
+  options, _ = parser.parse_args(argv)
+
+  suite = unittest.TestLoader().loadTestsFromTestCase(TestPreprocess)
+  unittest.TextTestRunner(verbosity=0).run(suite)
+
+  if options.stamp:
+    build_utils.Touch(options.stamp)
 
 if __name__ == '__main__':
-  unittest.main()
+  main(sys.argv[1:])
diff --git a/build/android/gyp/pack_arm_relocations.py b/build/android/gyp/pack_arm_relocations.py
index de131d20..149e340b 100755
--- a/build/android/gyp/pack_arm_relocations.py
+++ b/build/android/gyp/pack_arm_relocations.py
@@ -35,9 +35,6 @@
                               has_relocations_with_addends,
                               library_path,
                               output_path):
-  if not build_utils.IsTimeStale(output_path, [library_path]):
-    return
-
   # Select an appropriate name for the section we add.
   if has_relocations_with_addends:
     new_section = '.android.rela.dyn'
@@ -59,15 +56,17 @@
 
 
 def CopyArmLibraryUnchanged(library_path, output_path):
-  if not build_utils.IsTimeStale(output_path, [library_path]):
-    return
-
   shutil.copy(library_path, output_path)
 
 
 def main(args):
   args = build_utils.ExpandFileArgs(args)
   parser = optparse.OptionParser()
+  build_utils.AddDepfileOption(parser)
+  parser.add_option('--clear-dir', action='store_true',
+                    help='If set, the destination directory will be deleted '
+                    'before copying files to it. This is highly recommended to '
+                    'ensure that no stale files are left in the directory.')
 
   parser.add_option('--configuration-name',
       default='Release',
@@ -102,11 +101,15 @@
 
   libraries = build_utils.ParseGypList(options.libraries)
 
+  if options.clear_dir:
+    build_utils.DeleteDirectory(options.packed_libraries_dir)
+
   build_utils.MakeDirectory(options.packed_libraries_dir)
 
   for library in libraries:
     library_path = os.path.join(options.stripped_libraries_dir, library)
-    output_path = os.path.join(options.packed_libraries_dir, library)
+    output_path = os.path.join(
+        options.packed_libraries_dir, os.path.basename(library))
 
     if enable_packing and library not in exclude_packing_set:
       PackArmLibraryRelocations(options.android_pack_relocations,
@@ -117,6 +120,11 @@
     else:
       CopyArmLibraryUnchanged(library_path, output_path)
 
+  if options.depfile:
+    build_utils.WriteDepfile(
+        options.depfile,
+        libraries + build_utils.GetPythonDependencies())
+
   if options.stamp:
     build_utils.Touch(options.stamp)
 
diff --git a/build/android/gyp/package_resources.py b/build/android/gyp/package_resources.py
index f34578f..6444ed9f 100755
--- a/build/android/gyp/package_resources.py
+++ b/build/android/gyp/package_resources.py
@@ -126,6 +126,7 @@
 
                        '-I', android_jar,
                        '-F', options.apk_path,
+                       '--ignore-assets', build_utils.AAPT_IGNORE_PATTERN,
                        ]
 
     if options.no_compress:
diff --git a/build/android/gyp/process_resources.py b/build/android/gyp/process_resources.py
index 6f353889..6bf71f35 100755
--- a/build/android/gyp/process_resources.py
+++ b/build/android/gyp/process_resources.py
@@ -21,6 +21,7 @@
 
 from util import build_utils
 
+
 def ParseArgs(args):
   """Parses command line options.
 
@@ -220,7 +221,8 @@
                        '--auto-add-overlay',
                        '-I', android_jar,
                        '--output-text-symbols', gen_dir,
-                       '-J', gen_dir]
+                       '-J', gen_dir,
+                       '--ignore-assets', build_utils.AAPT_IGNORE_PATTERN]
 
     for d in input_resource_dirs:
       package_command += ['-S', d]
@@ -258,7 +260,8 @@
       aapt_cmd = [aapt,
                   'crunch',
                   '-C', crunch_dir,
-                  '-S', d]
+                  '-S', d,
+                  '--ignore-assets', build_utils.AAPT_IGNORE_PATTERN]
       build_utils.CheckOutput(aapt_cmd, stderr_filter=FilterCrunchStderr,
                               fail_func=DidCrunchFail)
 
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py
index e3a3525..a0cd7c12 100644
--- a/build/android/gyp/util/build_utils.py
+++ b/build/android/gyp/util/build_utils.py
@@ -22,6 +22,9 @@
                  os.pardir, os.pardir, os.pardir, os.pardir))
 COLORAMA_ROOT = os.path.join(CHROMIUM_SRC,
                              'third_party', 'colorama', 'src')
+# aapt should ignore OWNERS files in addition the default ignore pattern.
+AAPT_IGNORE_PATTERN = ('!OWNERS:!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:' +
+                       '!CVS:!thumbs.db:!picasa.ini:!*~')
 
 
 @contextlib.contextmanager
diff --git a/build/android/increase_size_for_speed.gypi b/build/android/increase_size_for_speed.gypi
index f5f2d62..4081cd7 100644
--- a/build/android/increase_size_for_speed.gypi
+++ b/build/android/increase_size_for_speed.gypi
@@ -18,6 +18,22 @@
               'cflags!': ['-Os'],
               'cflags': ['-O2'],
             }],
+            # Do not merge -Os and -O2 in LTO.
+            # LTO merges all optimization options at link-time. -O2 takes
+            # precedence over -Os. Avoid using LTO simultaneously
+            # on -Os and -O2 parts for that reason.
+            ['use_lto==1', {
+              'cflags!': [
+                '-flto',
+                '-ffat-lto-objects',
+              ],
+            }],
+            ['use_lto_o2==1', {
+              'cflags': [
+                '-flto',
+                '-ffat-lto-objects',
+              ],
+            }],
           ],
         }],
       ],
diff --git a/build/android/java_cpp_template.gypi b/build/android/java_cpp_template.gypi
index 036f32cf..3296659 100644
--- a/build/android/java_cpp_template.gypi
+++ b/build/android/java_cpp_template.gypi
@@ -6,6 +6,9 @@
 # to generate Java source files from templates that are processed
 # through the host C pre-processor.
 #
+# NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum
+#       rule instead.
+#
 # To use this, create a gyp target with the following form:
 #  {
 #    'target_name': 'android_net_java_constants',
@@ -15,7 +18,7 @@
 #    ],
 #    'variables': {
 #      'package_name': 'org/chromium/net',
-#      'template_deps': ['net/base/certificate_mime_type_list.h'],
+#      'template_deps': ['base/net_error_list.h'],
 #    },
 #    'includes': [ '../build/android/java_cpp_template.gypi' ],
 #  },
diff --git a/build/android/provision_devices.py b/build/android/provision_devices.py
index 468ef3f32..9962f0a 100755
--- a/build/android/provision_devices.py
+++ b/build/android/provision_devices.py
@@ -190,9 +190,11 @@
                      battery_info.get('level', 0))
         time.sleep(60)
         battery_info = device.old_interface.GetBatteryInfo()
-    device.RunShellCommand('date -u %f' % time.time(), as_root=True)
     # TODO(jbudorick): Tune the timeout per OS version.
     device.Reboot(True, timeout=600, retries=0)
+    device.RunShellCommand('date -s %s' % time.strftime('%Y%m%d.%H%M%S',
+                                                        time.gmtime()),
+                           as_root=True)
     props = device.RunShellCommand('getprop')
     for prop in props:
       logging.info('  %s' % prop)
diff --git a/build/android/pylib/OWNERS b/build/android/pylib/OWNERS
index 3899fa3..dbbbba7 100644
--- a/build/android/pylib/OWNERS
+++ b/build/android/pylib/OWNERS
@@ -1,4 +1,4 @@
-frankf@chromium.org
 jbudorick@chromium.org
+klundberg@chromium.org
 navabi@chromium.org
 skyostil@chromium.org
diff --git a/build/android/pylib/base/test_dispatcher.py b/build/android/pylib/base/test_dispatcher.py
index cb789de..677a908a 100644
--- a/build/android/pylib/base/test_dispatcher.py
+++ b/build/android/pylib/base/test_dispatcher.py
@@ -272,7 +272,6 @@
           #                 for the above are switched or wrapped.
           android_commands.errors.DeviceUnresponsiveError) as e:
     logging.error(e)
-    exit_code = constants.WARNING_EXIT_CODE
 
   if not all((len(tc) == 0 for tc in test_collections)):
     logging.error('Only ran %d tests (all devices are likely offline).' %
diff --git a/build/android/pylib/constants.py b/build/android/pylib/constants.py
index d324946..95b1868 100644
--- a/build/android/pylib/constants.py
+++ b/build/android/pylib/constants.py
@@ -146,8 +146,23 @@
 
 SCREENSHOTS_DIR = os.path.join(DIR_SOURCE_ROOT, 'out_screenshots')
 
-ANDROID_SDK_VERSION = 21
-ANDROID_SDK_BUILD_TOOLS_VERSION = '21.0.0'
+class ANDROID_SDK_VERSION_CODES(object):
+  """Android SDK version codes.
+
+  http://developer.android.com/reference/android/os/Build.VERSION_CODES.html
+  """
+
+  ICE_CREAM_SANDWICH = 14
+  ICE_CREAM_SANDWICH_MR1 = 15
+  JELLY_BEAN = 16
+  JELLY_BEAN_MR1 = 17
+  JELLY_BEAN_MR2 = 18
+  KITKAT = 19
+  KITKAT_WATCH = 20
+  LOLLIPOP = 21
+
+ANDROID_SDK_VERSION = ANDROID_SDK_VERSION_CODES.LOLLIPOP
+ANDROID_SDK_BUILD_TOOLS_VERSION = '21.0.1'
 ANDROID_SDK_ROOT = os.path.join(DIR_SOURCE_ROOT,
                                 'third_party/android_tools/sdk')
 ANDROID_SDK_TOOLS = os.path.join(ANDROID_SDK_ROOT,
@@ -167,6 +182,23 @@
 
 DEVICE_LOCAL_PROPERTIES_PATH = '/data/local.prop'
 
+PYTHON_UNIT_TEST_SUITES = {
+  'pylib_py_unittests': {
+    'path': os.path.join(DIR_SOURCE_ROOT, 'build', 'android'),
+    'test_modules': [
+      'pylib.device.device_utils_test',
+    ]
+  },
+# TODO(mkosiba) Enable after fixing these tests.
+# 'gyp_py_unittests': {
+#   'path': os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'android', 'gyp'),
+#   'test_modules': [
+#     'java_cpp_enum_tests'
+#   ]
+# },
+}
+
+
 def GetBuildType():
   try:
     return os.environ['BUILDTYPE']
diff --git a/build/android/pylib/content_settings.py b/build/android/pylib/content_settings.py
index d222053..f00553f 100644
--- a/build/android/pylib/content_settings.py
+++ b/build/android/pylib/content_settings.py
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from pylib import constants
+
 
 class ContentSettings(dict):
 
@@ -15,7 +17,7 @@
     sdk_version_string = device.GetProp('ro.build.version.sdk')
     try:
       sdk_version = int(sdk_version_string)
-      assert sdk_version >= 16, (
+      assert sdk_version >= constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN, (
           'ContentSettings supported only on SDK 16 and later')
     except ValueError:
       assert False, ('Unknown SDK version %s' % sdk_version_string)
diff --git a/build/android/pylib/device_settings.py b/build/android/pylib/device_settings.py
index bc39b5d..4050694e 100644
--- a/build/android/pylib/device_settings.py
+++ b/build/android/pylib/device_settings.py
@@ -4,6 +4,7 @@
 
 import logging
 
+from pylib import constants
 from pylib import content_settings
 
 _LOCK_SCREEN_SETTINGS_PATH = '/data/system/locksettings.db'
@@ -32,7 +33,7 @@
                   device.GetProp('ro.build.version.sdk'))
     return
 
-  if sdk_version < 16:
+  if sdk_version < constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN:
     logging.error('Skipping content settings configuration due to outdated sdk')
     return
 
diff --git a/build/android/pylib/gtest/setup.py b/build/android/pylib/gtest/setup.py
index 61a8539..c3af91f 100644
--- a/build/android/pylib/gtest/setup.py
+++ b/build/android/pylib/gtest/setup.py
@@ -121,6 +121,7 @@
       '--config-variable', 'component', 'static_library',
       '--config-variable', 'fastbuild', '0',
       '--config-variable', 'icu_use_data_file_flag', '1',
+      '--config-variable', 'libpeer_target_type', 'static_library',
       '--config-variable', 'lsan', '0',
       # TODO(maruel): This may not be always true.
       '--config-variable', 'target_arch', 'arm',
diff --git a/build/android/pylib/instrumentation/test_jar.py b/build/android/pylib/instrumentation/test_jar.py
index 964dca7..c81258f8 100644
--- a/build/android/pylib/instrumentation/test_jar.py
+++ b/build/android/pylib/instrumentation/test_jar.py
@@ -268,13 +268,14 @@
               '%s has no annotations. Assuming "%s".', test,
               self._DEFAULT_ANNOTATION)
           available_tests.append(test)
-      if exclude_annotation_list:
-        excluded_tests = self.GetAnnotatedTests(exclude_annotation_list)
-        available_tests = list(set(available_tests) - set(excluded_tests))
     else:
       available_tests = [m for m in self.GetTestMethods()
                          if not self.IsHostDrivenTest(m)]
 
+    if exclude_annotation_list:
+      excluded_tests = self.GetAnnotatedTests(exclude_annotation_list)
+      available_tests = list(set(available_tests) - set(excluded_tests))
+
     tests = []
     if test_filter:
       # |available_tests| are in adb instrument format: package.path.class#test.
diff --git a/build/android/pylib/instrumentation/test_runner.py b/build/android/pylib/instrumentation/test_runner.py
index 821fec1..aa0a2c0 100644
--- a/build/android/pylib/instrumentation/test_runner.py
+++ b/build/android/pylib/instrumentation/test_runner.py
@@ -487,6 +487,9 @@
     timeout = (self._GetIndividualTestTimeoutSecs(test) *
                self._GetIndividualTestTimeoutScale(test) *
                self.tool.GetTimeoutScale())
+    if (self.device.GetProp('ro.build.version.sdk')
+        < constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN):
+      timeout *= 4
 
     start_ms = 0
     duration_ms = 0
diff --git a/build/android/pylib/utils/json_results_generator.py b/build/android/pylib/utils/json_results_generator.py
index 52446b1a..d40860d 100644
--- a/build/android/pylib/utils/json_results_generator.py
+++ b/build/android/pylib/utils/json_results_generator.py
@@ -516,7 +516,7 @@
       this_test = this_test[segment]
 
     if not len(this_test):
-      self._PopulateResutlsAndTimesJSON(this_test)
+      self._PopulateResultsAndTimesJSON(this_test)
 
     if self.RESULTS in this_test:
       self._InsertItemRunLengthEncoded(result, this_test[self.RESULTS])
@@ -558,7 +558,7 @@
 
     results[self.TESTS] = test_results_trie
 
-  def _PopulateResutlsAndTimesJSON(self, results_and_times):
+  def _PopulateResultsAndTimesJSON(self, results_and_times):
     results_and_times[self.RESULTS] = []
     results_and_times[self.TIMES] = []
     return results_and_times
diff --git a/build/android/pylib/utils/report_results.py b/build/android/pylib/utils/report_results.py
index b13b9bc84..9841dc6 100644
--- a/build/android/pylib/utils/report_results.py
+++ b/build/android/pylib/utils/report_results.py
@@ -39,24 +39,28 @@
   logging.info('Upload results for test type "%s", test package "%s" to %s' %
                (test_type, test_package, flakiness_server))
 
-  # TODO(frankf): Enable uploading for gtests.
-  if test_type != 'Instrumentation':
-    logging.warning('Invalid test type.')
-    return
-
   try:
-    if flakiness_server == constants.UPSTREAM_FLAKINESS_SERVER:
-      assert test_package in ['ContentShellTest',
+    if test_type == 'Instrumentation':
+      if flakiness_server == constants.UPSTREAM_FLAKINESS_SERVER:
+        assert test_package in ['ContentShellTest',
                                 'ChromeShellTest',
-                              'AndroidWebViewTest']
-      dashboard_test_type = ('%s_instrumentation_tests' %
-                             test_package.lower().rstrip('test'))
-    # Downstream server.
+                                'AndroidWebViewTest']
+        dashboard_test_type = ('%s_instrumentation_tests' %
+                               test_package.lower().rstrip('test'))
+      # Downstream server.
+      else:
+        dashboard_test_type = 'Chromium_Android_Instrumentation'
+
+    elif test_type == 'Unit test':
+      dashboard_test_type = test_package
+
     else:
-      dashboard_test_type = 'Chromium_Android_Instrumentation'
+      logging.warning('Invalid test type')
+      return
 
     flakiness_dashboard_results_uploader.Upload(
         results, flakiness_server, dashboard_test_type)
+
   except Exception as e:
     logging.error(e)
 
diff --git a/build/android/rezip.gyp b/build/android/rezip.gyp
index 0dacffc..1115177 100644
--- a/build/android/rezip.gyp
+++ b/build/android/rezip.gyp
@@ -6,6 +6,7 @@
 {
   'targets': [
     {
+      # GN: //build/android/rezip:rezip
       'target_name': 'rezip_apk_jar',
       'type': 'none',
       'variables': {
diff --git a/build/android/rezip/BUILD.gn b/build/android/rezip/BUILD.gn
new file mode 100644
index 0000000..8b8f78e
--- /dev/null
+++ b/build/android/rezip/BUILD.gn
@@ -0,0 +1,11 @@
+# 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.
+
+import("//build/config/android/rules.gni")
+
+# GYP: //build/android/rezip.gyp:rezip_apk_jar
+java_library("rezip") {
+  jar_path = "$root_build_dir/lib.java/rezip_apk.jar"
+  DEPRECATED_java_in_dir = "."
+}
diff --git a/build/android/setup.gyp b/build/android/setup.gyp
index 7dce19d..0b89c0d 100644
--- a/build/android/setup.gyp
+++ b/build/android/setup.gyp
@@ -53,6 +53,7 @@
       # trying to create these directories.
       # The build/java.gypi target depends on this target.
       'target_name': 'build_output_dirs',
+      'toolsets': ['host', 'target'],
       'type': 'none',
       'actions': [
         {
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 92c97981..2f5058f 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -14,6 +14,7 @@
 import signal
 import sys
 import threading
+import unittest
 
 from pylib import android_commands
 from pylib import constants
@@ -44,6 +45,9 @@
 from pylib.utils import run_tests_helper
 
 
+HOST_TESTS = ['junit', 'python']
+
+
 def AddCommonOptions(option_parser):
   """Adds all common options to |option_parser|."""
 
@@ -60,9 +64,6 @@
   group.add_option('--build-directory', dest='build_directory',
                    help=('Path to the directory in which build files are'
                          ' located (should not include build type)'))
-  group.add_option('-c', dest='cleanup_test_files',
-                   help='Cleanup test files on the device after run',
-                   action='store_true')
   group.add_option('--num_retries', dest='num_retries', type='int',
                    default=2,
                    help=('Number of retries for a test before '
@@ -73,22 +74,10 @@
                    default=0,
                    action='count',
                    help='Verbose level (multiple times for more)')
-  group.add_option('--tool',
-                   dest='tool',
-                   help=('Run the test under a tool '
-                         '(use --tool help to list them)'))
   group.add_option('--flakiness-dashboard-server',
                    dest='flakiness_dashboard_server',
                    help=('Address of the server that is hosting the '
                          'Chrome for Android flakiness dashboard.'))
-  group.add_option('--skip-deps-push', dest='push_deps',
-                   action='store_false', default=True,
-                   help=('Do not push dependencies to the device. '
-                         'Use this at own risk for speeding up test '
-                         'execution on local machine.'))
-  group.add_option('-d', '--device', dest='test_device',
-                   help=('Target device for the test suite '
-                         'to run on.'))
   option_parser.add_option_group(group)
 
 
@@ -100,6 +89,26 @@
     constants.SetBuildDirectory(options.build_directory)
 
 
+def AddDeviceOptions(option_parser):
+  group = optparse.OptionGroup(option_parser, 'Device Options')
+  group.add_option('-c', dest='cleanup_test_files',
+                   help='Cleanup test files on the device after run',
+                   action='store_true')
+  group.add_option('--tool',
+                   dest='tool',
+                   help=('Run the test under a tool '
+                         '(use --tool help to list them)'))
+  group.add_option('--skip-deps-push', dest='push_deps',
+                   action='store_false', default=True,
+                   help=('Do not push dependencies to the device. '
+                         'Use this at own risk for speeding up test '
+                         'execution on local machine.'))
+  group.add_option('-d', '--device', dest='test_device',
+                   help=('Target device for the test suite '
+                         'to run on.'))
+  option_parser.add_option_group(group)
+
+
 def AddGTestOptions(option_parser):
   """Adds gtest options to |option_parser|."""
 
@@ -133,6 +142,7 @@
   # TODO(gkanwar): Move these to Common Options once we have the plumbing
   # in our other test types to handle these commands
   AddCommonOptions(option_parser)
+  AddDeviceOptions(option_parser)
 
 
 def AddLinkerTestOptions(option_parser):
@@ -143,6 +153,7 @@
   option_parser.add_option('-f', '--gtest-filter', dest='test_filter',
                            help='googletest-style filter string.')
   AddCommonOptions(option_parser)
+  AddDeviceOptions(option_parser)
 
 
 def ProcessGTestOptions(options):
@@ -226,6 +237,7 @@
 
   AddJavaTestOptions(option_parser)
   AddCommonOptions(option_parser)
+  AddDeviceOptions(option_parser)
 
   option_parser.add_option('-j', '--java-only', action='store_true',
                            default=False, help='Run only the Java tests.')
@@ -334,6 +346,7 @@
 
   AddJavaTestOptions(option_parser)
   AddCommonOptions(option_parser)
+  AddDeviceOptions(option_parser)
 
 
 def ProcessUIAutomatorOptions(options, error_func):
@@ -447,6 +460,7 @@
             '[default: "%default"].'))
 
   AddCommonOptions(option_parser)
+  AddDeviceOptions(option_parser)
 
 
 def ProcessMonkeyTestOptions(options, error_func):
@@ -520,6 +534,7 @@
       action='store_true',
       help='Just print the steps without executing.')
   AddCommonOptions(option_parser)
+  AddDeviceOptions(option_parser)
 
 
 def ProcessPerfTestOptions(options, args, error_func):
@@ -547,6 +562,24 @@
       options.dry_run, single_step)
 
 
+def AddPythonTestOptions(option_parser):
+  option_parser.add_option('-s', '--suite', dest='suite_name',
+                           help=('Name of the test suite to run'
+                                 '(use -s help to list them).'))
+  AddCommonOptions(option_parser)
+
+
+def ProcessPythonTestOptions(options, error_func):
+  if options.suite_name not in constants.PYTHON_UNIT_TEST_SUITES:
+    available = ('Available test suites: [%s]' %
+                 ', '.join(constants.PYTHON_UNIT_TEST_SUITES.iterkeys()))
+    if options.suite_name == 'help':
+      print available
+    else:
+      error_func('"%s" is not a valid suite. %s' %
+                 (options.suite_name, available))
+
+
 def _RunGTests(options, devices):
   """Subcommand of RunTestsCommands which runs gtests."""
   ProcessGTestOptions(options)
@@ -737,6 +770,25 @@
   return 0
 
 
+def _RunPythonTests(options, error_func):
+  """Subcommand of RunTestsCommand which runs python unit tests."""
+  ProcessPythonTestOptions(options, error_func)
+
+  suite_vars = constants.PYTHON_UNIT_TEST_SUITES[options.suite_name]
+  suite_path = suite_vars['path']
+  suite_test_modules = suite_vars['test_modules']
+
+  sys.path = [suite_path] + sys.path
+  try:
+    suite = unittest.TestSuite()
+    suite.addTests(unittest.defaultTestLoader.loadTestsFromName(m)
+                   for m in suite_test_modules)
+    runner = unittest.TextTestRunner(verbosity=1+options.verbose_count)
+    return 0 if runner.run(suite).wasSuccessful() else 1
+  finally:
+    sys.path = sys.path[1:]
+
+
 def _GetAttachedDevices(test_device=None):
   """Get all attached devices.
 
@@ -790,7 +842,10 @@
 
   ProcessCommonOptions(options)
 
-  devices = _GetAttachedDevices(options.test_device)
+  if command in HOST_TESTS:
+    devices = []
+  else:
+    devices = _GetAttachedDevices(options.test_device)
 
   forwarder.Forwarder.RemoveHostLog()
   if not ports.ResetTestServerPortAllocation():
@@ -810,6 +865,8 @@
     return _RunMonkeyTests(options, option_parser.error, devices)
   elif command == 'perf':
     return _RunPerfTests(options, args, option_parser.error)
+  elif command == 'python':
+    return _RunPythonTests(options, option_parser.error)
   else:
     raise Exception('Unknown test type.')
 
@@ -872,6 +929,8 @@
         AddMonkeyTestOptions, RunTestsCommand),
     'perf': CommandFunctionTuple(
         AddPerfTestOptions, RunTestsCommand),
+    'python': CommandFunctionTuple(
+        AddPythonTestOptions, RunTestsCommand),
     'linker': CommandFunctionTuple(
         AddLinkerTestOptions, RunTestsCommand),
     'help': CommandFunctionTuple(lambda option_parser: None, HelpCommand)
diff --git a/build/common.gypi b/build/common.gypi
index 0ad62ee..708e12c 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -387,10 +387,13 @@
       # -fsanitize=address only works with clang, but asan=1 implies clang=1
       # See https://sites.google.com/a/chromium.org/dev/developers/testing/addresssanitizer
       'asan%': 0,
+      'asan_blacklist%': '<(PRODUCT_DIR)/../../tools/memory/asan/blacklist.txt',
       # Enable coverage gathering instrumentation in ASan. This flag also
       # controls coverage granularity (1 for function-level coverage, 2 for
       # block-level coverage).
       'asan_coverage%': 0,
+      # Enable intra-object-overflow detection in ASan (experimental).
+      'asan_field_padding%': 0,
 
       # Enable Chromium overrides of the default configurations for various
       # dynamic tools (like ASan).
@@ -637,6 +640,16 @@
       # compiler. Always do this by default.
       'host_clang%': 1,
 
+      # Variables to control Link-Time Optimizations (LTO).
+      # Note: the variables must *not* be enabled at the same time.
+      #       In this case LTO would 'merge' the optimization flags
+      #       at link-time which would lead to all code be optimized with -O2.
+      # Enable LTO on the code compiled with -Os.
+      # See crbug.com/407544
+      'use_lto%': 0,
+      # Enable LTO on code compiled with -O2.
+      'use_lto_o2%': 0,
+
       'conditions': [
         # A flag for POSIX platforms
         ['OS=="win"', {
@@ -903,7 +916,7 @@
           'use_allocator%': 'none',
           # sysroot needs to be an absolute path otherwise it generates
           # incorrect results when passed to pkg-config
-          'sysroot%': '<!(cd <(DEPTH) && pwd -P)/arm-sysroot',
+          'sysroot%': '<!(cd <(DEPTH) && pwd -P)/chrome/installer/linux/debian_wheezy_arm-sysroot',
         }], # OS=="linux" and target_arch=="arm" and chromeos==0
 
         ['OS=="linux" and branding=="Chrome" and buildtype=="Official" and chromeos==0', {
@@ -1110,7 +1123,9 @@
     'clang_use_chrome_plugins%': '<(clang_use_chrome_plugins)',
     'mac_want_real_dsym%': '<(mac_want_real_dsym)',
     'asan%': '<(asan)',
+    'asan_blacklist%': '<(asan_blacklist)',
     'asan_coverage%': '<(asan_coverage)',
+    'asan_field_padding%': '<(asan_field_padding)',
     'use_sanitizer_options%': '<(use_sanitizer_options)',
     'syzyasan%': '<(syzyasan)',
     'syzygy_optimize%': '<(syzygy_optimize)',
@@ -1185,6 +1200,8 @@
     'proprietary_codecs%': '<(proprietary_codecs)',
     'use_goma%': '<(use_goma)',
     'gomadir%': '<(gomadir)',
+    'use_lto%': '<(use_lto)',
+    'use_lto_o2%': '<(use_lto_o2)',
     'video_hole%': '<(video_hole)',
     'enable_load_completion_hacks%': '<(enable_load_completion_hacks)',
     'support_pre_M6_history_database%': '<(support_pre_M6_history_database)',
@@ -1635,7 +1652,7 @@
             'android_host_arch%': '<!(uname -m)',
             # Android API-level of the SDK used for compilation.
             'android_sdk_version%': '21',
-            'android_sdk_build_tools_version%': '21.0.0',
+            'android_sdk_build_tools_version%': '21.0.1',
             'host_os%': "<!(uname -s | sed -e 's/Linux/linux/;s/Darwin/mac/')",
           },
           # Copy conditionally-set variables out one scope.
@@ -1663,7 +1680,7 @@
             ['target_arch == "x64"', {
               'android_app_abi%': 'x86_64',
               'android_gdbserver%': '<(android_ndk_root)/prebuilt/android-x86_64/gdbserver/gdbserver',
-              'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-L/arch-x86_64',
+              'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-21/arch-x86_64',
               'android_ndk_lib_dir%': 'usr/lib64',
               'android_toolchain%': '<(android_ndk_root)/toolchains/x86_64-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
             }],
@@ -1683,7 +1700,7 @@
             ['target_arch == "arm64"', {
               'android_app_abi%': 'arm64-v8a',
               'android_gdbserver%': '<(android_ndk_root)/prebuilt/android-arm64/gdbserver/gdbserver',
-              'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-L/arch-arm64',
+              'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-21/arch-arm64',
               'android_ndk_lib_dir%': 'usr/lib',
               'android_toolchain%': '<(android_ndk_root)/toolchains/aarch64-linux-android-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
             }],
@@ -1697,7 +1714,7 @@
             ['target_arch == "mips64el"', {
               'android_app_abi%': 'mips64',
               'android_gdbserver%': '<(android_ndk_root)/prebuilt/android-mips64/gdbserver/gdbserver',
-              'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-L/arch-mips64',
+              'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-21/arch-mips64',
               'android_ndk_lib_dir%': 'usr/lib64',
               'android_toolchain%': '<(android_ndk_root)/toolchains/mips64el-linux-android-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
               'gcc_version%': 49,
@@ -2313,6 +2330,11 @@
       }, {
          'use_seccomp_bpf%': 0,
       }],
+      # Set component build with LTO until all tests pass.
+      # This also reduces link time.
+      ['use_lto==1', {
+        'component%': "shared_library",
+      }],
     ],
 
     # older history files use fts2 instead of fts3
@@ -3755,6 +3777,13 @@
                     'cflags': [
                       '-march=<(arm_arch)',
                     ],
+                    'conditions': [
+                      ['use_lto==1 or use_lto_o2==1', {
+                        'ldflags': [
+                          '-march=<(arm_arch)',
+                        ],
+                      }],
+                    ],
                   }],
                   ['clang==1 and OS!="android"', {
                     'cflags': [
@@ -3767,21 +3796,49 @@
                     'cflags': [
                       '-mtune=<(arm_tune)',
                     ],
+                    'conditions': [
+                      ['use_lto==1 or use_lto_o2==1', {
+                        'ldflags': [
+                          '-mtune=<(arm_tune)',
+                        ],
+                      }],
+                    ],
                   }],
                   ['arm_fpu!=""', {
                     'cflags': [
                       '-mfpu=<(arm_fpu)',
                     ],
+                    'conditions': [
+                      ['use_lto==1 or use_lto_o2==1', {
+                        'ldflags': [
+                          '-mfpu=<(arm_fpu)',
+                        ],
+                      }],
+                    ],
                   }],
                   ['arm_float_abi!=""', {
                     'cflags': [
                       '-mfloat-abi=<(arm_float_abi)',
                     ],
+                    'conditions': [
+                      ['use_lto==1 or use_lto_o2==1', {
+                        'ldflags': [
+                          '-mfloat-abi=<(arm_float_abi)',
+                        ],
+                      }],
+                    ],
                   }],
                   ['arm_thumb==1', {
                     'cflags': [
                       '-mthumb',
                     ],
+                    'conditions': [
+                      ['use_lto==1 or use_lto_o2==1', {
+                        'ldflags': [
+                          '-mthumb',
+                        ],
+                      }],
+                    ],
                   }],
                   ['OS=="android"', {
                     # Most of the following flags are derived from what Android
@@ -4060,6 +4117,7 @@
               ['_toolset=="target"', {
                 'cflags': [
                   '-fsanitize=address',
+                  '-fsanitize-blacklist=<(asan_blacklist)',
                 ],
                 'ldflags': [
                   '-fsanitize=address',
@@ -4121,6 +4179,15 @@
               }],
             ],
           }],
+          ['asan_field_padding!=0', {
+            'target_conditions': [
+              ['_toolset=="target"', {
+                'cflags': [
+                  '-fsanitize-address-field-padding=<(asan_field_padding)',
+                ],
+              }],
+            ],
+          }],
           ['lsan==1', {
             'target_conditions': [
               ['_toolset=="target"', {
@@ -5685,6 +5752,29 @@
        ['CXX.host_wrapper', '<(gomadir)/gomacc'],
       ],
     }],
+    ['use_lto==1', {
+      'target_defaults': {
+        'target_conditions': [
+          ['_toolset=="target"', {
+            'cflags': [
+              '-flto',
+              '-ffat-lto-objects',
+            ],
+          }],
+        ],
+      },
+    }],
+    ['use_lto==1 or use_lto_o2==1', {
+      'target_defaults': {
+        'target_conditions': [
+          ['_toolset=="target"', {
+            'ldflags': [
+              '-flto=32',
+            ],
+          }],
+        ],
+      },
+    }],
   ],
   'xcode_settings': {
     # DON'T ADD ANYTHING NEW TO THIS BLOCK UNLESS YOU REALLY REALLY NEED IT!
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index e548f77..64abdf3 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -32,7 +32,6 @@
   defines = [
       "CHROMIUM_BUILD",
       "ENABLE_EGLIMAGE=1",
-      "ENABLE_BACKGROUND=1",
       "V8_DEPRECATION_WARNINGS",  # Don't use deprecated V8 APIs anywhere.
   ]
 
@@ -192,6 +191,9 @@
   if (enable_hidpi) {
     defines += [ "ENABLE_HIDPI=1" ]
   }
+  if (proprietary_codecs) {
+    defines += [ "USE_PROPRIETARY_CODECS" ]
+  }
 }
 
 # Debug/release ----------------------------------------------------------------
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index d002ba29..aa2e71f 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -5,12 +5,25 @@
 # This file contains common system config stuff for the Android build.
 
 if (is_android) {
+  has_chrome_android_internal = exec_script("//build/dir_exists.py",
+          [ rebase_path("//clank", root_build_dir) ],
+          "string") == "True"
+
+  if (has_chrome_android_internal) {
+    import("//clank/config.gni")
+  } else {
+    default_android_sdk_root = "//third_party/android_tools/sdk"
+    default_android_sdk_version = "21"
+    default_android_sdk_build_tools_version = "21.0.1"
+  }
+
   declare_args() {
     # Absolute directory containing the Android source code.
     android_src = ""
 
-    android_sdk_root = "//third_party/android_tools/sdk"
-    android_sdk_version = "21"
+    android_sdk_root = default_android_sdk_root
+    android_sdk_version = default_android_sdk_version
+    android_sdk_build_tools_version = default_android_sdk_build_tools_version
 
     # This is set when building the Android WebView inside the Android build
     # system, using the 'android' gyp backend. The WebView code is still built
@@ -32,7 +45,6 @@
            "You must specify android_src for an Android WebView build.")
   }
 
-
   # Host stuff -----------------------------------------------------------------
 
   # Defines the name the Android build gives to the current host CPU
@@ -68,7 +80,7 @@
   android_sdk = "${android_sdk_root}/platforms/android-${android_sdk_version}"
 
   android_sdk_tools = "${android_sdk_root}/tools"
-  android_sdk_build_tools = "${android_sdk_root}/build-tools/21.0.0"
+  android_sdk_build_tools = "${android_sdk_root}/build-tools/$android_sdk_build_tools_version"
 
   # Path to the SDK's android.jar
   android_sdk_jar = "$android_sdk/android.jar"
@@ -114,7 +126,9 @@
     assert(false, "Need android libgcc support for your target arch.")
   }
 
-  android_readelf = "$android_toolchain_root/bin/$_binary_prefix-readelf"
+  android_tool_prefix = "$android_toolchain_root/bin/$_binary_prefix-"
+  android_readelf = "${android_tool_prefix}readelf"
+  android_objcopy = "${android_tool_prefix}objcopy"
   android_gdbserver = "$android_ndk_root/prebuilt/$android_prebuilt_arch/gdbserver/gdbserver"
 
   # stlport stuff --------------------------------------------------------------
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index abd97112..de29cce 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -236,6 +236,7 @@
   _keystore_path = invoker.keystore_path
   _keystore_name = invoker.keystore_name
   _keystore_password = invoker.keystore_password
+  _load_library_from_apk = invoker.load_library_from_apk
 
   _deps = []
   if (defined(invoker.deps)) {
@@ -252,8 +253,8 @@
     _asset_location = invoker.asset_location
   }
 
-  _version_code = "1"
-  _version_name = "Developer Build"
+  _version_code = invoker.version_code
+  _version_name = invoker.version_name
 
   _base_apk_path = _base_path + ".apk_intermediates"
 
@@ -271,7 +272,7 @@
 
     script = "//build/android/gyp/package_resources.py"
     depfile = "${target_gen_dir}/${target_name}.d"
-    source_prereqs = [
+    inputs = [
       _android_manifest,
       _resources_zip,
     ]
@@ -302,7 +303,7 @@
 
     depfile = "$target_gen_dir/$target_name.d"
 
-    source_prereqs = [
+    inputs = [
       _dex_path,
       _resource_packaged_apk_path,
       _ant_script
@@ -344,7 +345,7 @@
     depfile = "$target_gen_dir/$target_name.d"
 
     sources = [_packaged_apk_path]
-    source_prereqs = [_keystore_path]
+    inputs = [_keystore_path]
     outputs = [depfile, _final_apk_path]
 
     args = [
@@ -356,6 +357,16 @@
       "--key-name", _keystore_name,
       "--key-passwd", _keystore_password,
     ]
+    if (_load_library_from_apk) {
+      _rezip_jar_path = "$root_build_dir/lib.java/rezip_apk.jar"
+      inputs += [
+        _rezip_jar_path
+      ]
+      args += [
+        "--load-library-from-zip-file=1",
+        "--rezip-apk-jar-path", rebase_path(_rezip_jar_path, root_build_dir)
+      ]
+    }
   }
 
   group(target_name) {
@@ -446,7 +457,7 @@
 #     dependencies srcjar outputs will be compiled and added to the output jar.
 #   jar_path: Use this to explicitly set the output jar path. Defaults to
 #     "${target_gen_dir}/${target_name}.jar.
-template("java_library") {
+template("compile_java") {
   if (defined(invoker.testonly)) { testonly = invoker.testonly }
 
   assert(defined(invoker.java_files))
@@ -546,7 +557,7 @@
   if (defined(invoker.testonly)) { testonly = invoker.testonly }
 
   assert(defined(invoker.java_files) || defined(invoker.DEPRECATED_java_in_dir)
-      || defined(invoker.srcjars))
+      || defined(invoker.srcjars) || defined(invoker.srcjar_deps))
   assert(defined(invoker.build_config))
   assert(defined(invoker.jar_path))
   assert(defined(invoker.dex_path))
@@ -598,7 +609,7 @@
   _final_deps = []
   _final_datadeps = []
 
-  java_library("${target_name}__java_library") {
+  compile_java("${target_name}__compile_java") {
     jar_path = _jar_path
     if (defined(invoker.jar_excluded_patterns)) {
       jar_excluded_patterns = invoker.jar_excluded_patterns
@@ -634,7 +645,7 @@
 
   group(target_name) {
     deps = [
-      ":${target_name}__java_library",
+      ":${target_name}__compile_java",
       ":${target_name}__dex",
     ] + _final_deps + _final_datadeps
   }
@@ -672,7 +683,7 @@
         )
     sources = rebase_path(sources_build_rel, ".", root_build_dir)
 
-    source_prereqs = [
+    inputs = [
       build_config,
       android_manifest,
     ]
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index ac6fe5a..3701dfb2 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -2,13 +2,14 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//base/android/linker/config.gni")
 import("//build/config/android/config.gni")
 import("//build/config/android/internal_rules.gni")
 import("//tools/grit/grit_rule.gni")
+import("//tools/relocation_packer/config.gni")
 
 assert(is_android)
 
-
 # Declare a jni target
 #
 # This target generates the native jni bindings for a set of .java files.
@@ -186,6 +187,9 @@
 
 # Declare a target for c-preprocessor-generated java files
 #
+# NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum
+#       rule instead.
+#
 # This target generates java files using the host C pre-processor. Each file in
 # sources will be compiled using the C pre-processor. If include_path is
 # specified, it will be passed (with --I) to the pre-processor.
@@ -416,6 +420,8 @@
   _build_config = _base_path + ".build_config"
 
   write_build_config("${target_name}__build_config") {
+    build_config = _build_config
+    resources_zip = _resources_zip
     type = "android_resources"
   }
 
@@ -675,7 +681,7 @@
   if (defined(invoker.testonly)) { testonly = invoker.testonly }
 
   assert(defined(invoker.java_files) || defined(invoker.DEPRECATED_java_in_dir)
-      || defined(invoker.srcjars))
+      || defined(invoker.srcjars) || defined(invoker.srcjar_deps))
   _base_path = "$target_gen_dir/$target_name"
   _build_config = _base_path + ".build_config"
   _jar_path = _base_path + ".jar"
@@ -732,6 +738,68 @@
   }
 }
 
+template("java_library") {
+  if (defined(invoker.testonly)) { testonly = invoker.testonly }
+
+  assert(defined(invoker.java_files) || defined(invoker.DEPRECATED_java_in_dir)
+      || defined(invoker.srcjars))
+
+  _srcjar_deps = []
+  if (defined(invoker.srcjar_deps)) {
+    _srcjar_deps = invoker.srcjar_deps
+  }
+
+  _srcjars = []
+  if (defined(invoker.srcjars)) {
+    _srcjars = invoker.srcjars
+  }
+
+  _java_files = []
+  if (defined(invoker.java_files)) {
+    _java_files = invoker.java_files
+  } else if (defined(invoker.DEPRECATED_java_in_dir)) {
+    _src_dir = invoker.DEPRECATED_java_in_dir + "/src"
+    _src_dir_exists = exec_script("//build/dir_exists.py",
+          [ rebase_path(_src_dir, root_build_dir) ],
+          "string")
+    assert(_src_dir_exists == "False",
+        "In GN, java_in_dir should be the fully specified java directory " +
+        "(i.e. including the trailing \"/src\")")
+
+    _java_files_build_rel = exec_script(
+        "//build/android/gyp/find.py",
+        [
+          "--pattern",
+          "*.java",
+          rebase_path(invoker.DEPRECATED_java_in_dir, root_build_dir)
+        ],
+        "list lines"
+        )
+    _java_files = rebase_path(_java_files_build_rel, ".", root_build_dir)
+  }
+  assert(_java_files != [] || _srcjar_deps != [] || _srcjars != [])
+
+  # TODO(cjhopman): Write a proper build config so that java library
+  # dependencies work correctly.
+  _build_config = "$target_gen_dir/$target_name.build_config"
+  write_file(
+      _build_config,
+      "{ \"javac\": { \"classpath\": [], \"srcjars\": [] } }")
+
+  _jar_path = "$root_build_dir/lib.java/$target_name.jar"
+  if (defined(invoker.jar_path)) {
+    _jar_path = invoker.jar_path
+  }
+
+  compile_java(target_name) {
+    build_config = _build_config
+    jar_path = _jar_path
+    java_files = _java_files
+    srcjar_deps = _srcjar_deps
+    srcjars = _srcjars
+  }
+}
+
 
 # Declare an Android library target for a prebuilt jar
 #
@@ -875,28 +943,6 @@
   _dist_jar_path = _dist_jar_path_list[0]
 
   _native_libs = []
-  if (defined(invoker.native_libs)) {
-    _use_chromium_linker = false
-    if (defined(invoker.use_chromium_linker)) {
-      _use_chromium_linker = invoker.use_chromium_linker
-    }
-
-    # TODO(GYP) add "|| profiling_full_stack_frames
-    # Only enable the chromium linker on regular builds, since the
-    # component build crashes on Android 4.4. See b/11379966
-    if (is_component_build || cpu_arch == "arm64" || cpu_arch == "x64") {
-      _use_chromium_linker = false
-    }
-
-    _native_libs = invoker.native_libs
-    _native_libs_dir = base_path + "/libs"
-
-    if (_use_chromium_linker) {
-      _native_libs += [
-        "$root_build_dir/lib.stripped/libchromium_android_linker.so"
-      ]
-    }
-  }
 
   _keystore_path = android_default_keystore_path
   _keystore_name = android_default_keystore_name
@@ -913,6 +959,46 @@
     _srcjar_deps += invoker.srcjar_deps
   }
 
+  _load_library_from_apk = false
+
+  if (defined(invoker.native_libs)) {
+    _use_chromium_linker = false
+    if (defined(invoker.use_chromium_linker)) {
+      _use_chromium_linker = (invoker.use_chromium_linker &&
+        chromium_linker_supported)
+    }
+
+    if (defined(invoker.load_library_from_apk) &&
+        invoker.load_library_from_apk) {
+      _load_library_from_apk = true
+      assert(_use_chromium_linker, "Loading library from the apk requires use" +
+          " of the Chromium linker.")
+    }
+
+    _enable_relocation_packing = false
+    if (defined(invoker.enable_relocation_packing) &&
+        invoker.enable_relocation_packing) {
+      _enable_relocation_packing = relocation_packing_supported
+      assert(_use_chromium_linker, "Relocation packing requires use of the" +
+          " Chromium linker.")
+    }
+
+    _native_libs = invoker.native_libs
+    _native_libs_dir = base_path + "/libs"
+
+    if (_use_chromium_linker) {
+      _native_libs += [
+        "$root_build_dir/lib.stripped/libchromium_android_linker.so"
+      ]
+    }
+
+    _enable_relocation_packing = false
+    if (_use_chromium_linker && defined(invoker.enable_relocation_packing) &&
+        invoker.enable_relocation_packing) {
+      _enable_relocation_packing = true
+    }
+  }
+
   _rebased_build_config = rebase_path(build_config, root_build_dir)
 
   write_build_config("${_template_name}__build_config") {
@@ -945,7 +1031,6 @@
       _enable_chromium_linker_tests = invoker.enable_chromium_linker_tests
     }
 
-    _load_library_from_apk = false
     _native_lib_version_name = ""
 
     java_cpp_template("${_template_name}__native_libraries_java") {
@@ -1025,19 +1110,48 @@
   }
 
   if (_native_libs != []) {
-    copy_ex("${_template_name}__prepare_native") {
-      clear_dir = true
+    action("${_template_name}__prepare_native") {
+      script = "//build/android/gyp/pack_arm_relocations.py"
+      packed_libraries_dir = "$_native_libs_dir/$android_app_abi"
+      depfile = "$target_gen_dir/$target_name.d"
+      outputs = [
+        depfile
+      ]
       inputs = [
         build_config
       ]
-      dest = "$_native_libs_dir/$android_app_abi"
-      args = [
-        "--files=@FileArg(${_rebased_build_config}:native:libraries)",
+      deps = []
+      skip_packing_list = [
+        "gdbserver",
+        "libchromium_android_linker.so",
       ]
+
+      enable_packing_arg = 0
+      if (_enable_relocation_packing) {
+        enable_packing_arg = 1
+        deps += [
+          relocation_packer_target
+        ]
+      }
+
+      args = [
+        "--depfile", rebase_path(depfile, root_build_dir),
+        "--enable-packing=$enable_packing_arg",
+        "--has-relocations-with-addends=$relocations_have_addends",
+        "--exclude-packing-list=$skip_packing_list",
+        "--android-pack-relocations", rebase_path(relocation_packer_exe, root_build_dir),
+        "--android-objcopy", rebase_path(android_objcopy, root_build_dir),
+        "--stripped-libraries-dir", rebase_path(root_build_dir, root_build_dir),
+        "--packed-libraries-dir", rebase_path(packed_libraries_dir, root_build_dir),
+        "--libraries=@FileArg(${_rebased_build_config}:native:libraries)",
+        "--clear-dir"
+      ]
+
       if (is_debug) {
-        rebased_gdbserver = rebase_path(android_gdbserver, root_build_dir)
+        rebased_gdbserver = rebase_path([ android_gdbserver ], root_build_dir)
+        inputs += [ android_gdbserver ]
         args += [
-          "--files=[\"$rebased_gdbserver\"]"
+          "--libraries=$rebased_gdbserver"
         ]
       }
     }
@@ -1049,6 +1163,17 @@
     android_manifest = invoker.android_manifest
     resources_zip = all_resources_zip_path
     dex_path = final_dex_path
+    load_library_from_apk = _load_library_from_apk
+
+    version_code = "1"
+    if (defined(invoker.version_code)) {
+      version_code = invoker.version_code
+    }
+
+    version_name = "Developer Build"
+    if (defined(invoker.version_name)) {
+      version_name = invoker.version_name
+    }
 
     if (defined(invoker.asset_location)) {
       asset_location = invoker.asset_location
diff --git a/build/config/features.gni b/build/config/features.gni
index 4ed933f..49fe155 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -36,6 +36,9 @@
   #enable_webrtc = !is_ios  TODO(GYP) use this condition when WebRTC works in
   #                         the GN build.
   enable_webrtc = false
+
+  # Enables proprietary codecs and demuxers; e.g. H264, MOV, AAC, and MP3.
+  proprietary_codecs = false
 }
 
 # Additional dependent variables -----------------------------------------------
diff --git a/build/get_landmines.py b/build/get_landmines.py
index f15d8db..f4a9249 100755
--- a/build/get_landmines.py
+++ b/build/get_landmines.py
@@ -57,8 +57,8 @@
   print 'blink_resources.grd changed: crbug.com/400860'
   print 'ninja dependency cycle: crbug.com/408192'
   if platform() == 'android':
-    print 'Clobber: To delete stale generated .java files.'
-    print 'Delete stale generated .java files again. crbug.com/349592'
+    print 'Delete stale generated .java files yet again. crbug.com/349592'
+    print 'Clobber to delete incompatible object binary format with NDK r10c'
 
 
 def main():
diff --git a/build/get_syzygy_binaries.py b/build/get_syzygy_binaries.py
index 79a186d..b5424c21 100755
--- a/build/get_syzygy_binaries.py
+++ b/build/get_syzygy_binaries.py
@@ -46,9 +46,7 @@
   ('benchmark.zip', 'benchmark', '', None),
   ('binaries.zip', 'binaries', 'exe', None),
   ('symbols.zip', 'symbols', 'exe',
-      lambda x: x.filename.endswith('.dll.pdb')),
-  ('include.zip', 'include', 'include', None),
-  ('lib.zip', 'library', 'lib', None)]
+      lambda x: x.filename.endswith('.dll.pdb'))]
 
 
 def _Shell(*cmd, **kw):
diff --git a/build/linux/install-arm-sysroot.py b/build/linux/install-arm-sysroot.py
index 4d593cc..495fc757 100755
--- a/build/linux/install-arm-sysroot.py
+++ b/build/linux/install-arm-sysroot.py
@@ -3,103 +3,10 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-"""Script to install ARM root image for cross building of ARM chrome on linux.
-This script can be run manually but is more often run as part of gclient
-hooks. When run from hooks this script should be a no-op on non-linux
-platforms.
-
-The sysroot image could be constructed from scratch based on the current
-state or precise/arm but for consistency we currently use a pre-built root
-image which was originally designed for building trusted NaCl code. The image
-will normally need to be rebuilt every time chrome's build dependancies are
-changed.
-
-Steps to rebuild the arm sysroot image:
-
-- cd $SRC/native_client
-- ./tools/trusted_cross_toolchains/trusted-toolchain-creator.armel.precise.sh \
-    UpdatePackageLists
-- ./tools/trusted_cross_toolchains/trusted-toolchain-creator.armel.precise.sh \
-    BuildJail $SRC/out/arm-sysroot.tar.gz
-- gsutil cp -a public-read $SRC/out/arm-sysroot.tar.gz \
-    nativeclient-archive2/toolchain/$NACL_REV/sysroot-arm-trusted.tgz
-"""
-
-# TODO(sbc): merge this script into:
-#  chrome/installer/linux/sysroot_scripts/install-debian.wheezy.sysroot.py
-
-import hashlib
-import os
-import shutil
-import subprocess
 import sys
 
-
-SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-URL_PREFIX = 'https://storage.googleapis.com'
-URL_PATH = 'chrome-linux-sysroot/toolchain'
-REVISION = 285950
-TARBALL = 'debian_wheezy_arm_sysroot.tgz'
-TARBALL_SHA1SUM = 'fc2f54db168887c5190c4c6686c869bedf668b4e'
-
-
-def get_sha1(filename):
-  sha1 = hashlib.sha1()
-  with open(filename, 'rb') as f:
-    while True:
-      # Read in 1mb chunks, so it doesn't all have to be loaded into memory.
-      chunk = f.read(1024*1024)
-      if not chunk:
-        break
-      sha1.update(chunk)
-  return sha1.hexdigest()
-
-
-def main(args):
-  if '--linux-only' in args:
-    # This argument is passed when run from the gclient hooks.
-    # In this case we return early on non-linux platforms
-    # or if GYP_DEFINES doesn't include target_arch=arm
-    if not sys.platform.startswith('linux'):
-      return 0
-
-    if "target_arch=arm" not in os.environ.get('GYP_DEFINES', ''):
-      return 0
-
-  src_root = os.path.dirname(os.path.dirname(SCRIPT_DIR))
-  sysroot = os.path.join(src_root, 'arm-sysroot')
-  url = "%s/%s/%s/%s" % (URL_PREFIX, URL_PATH, REVISION, TARBALL)
-
-  stamp = os.path.join(sysroot, ".stamp")
-  if os.path.exists(stamp):
-    with open(stamp) as s:
-      if s.read() == url:
-        print "ARM root image already up-to-date: %s" % sysroot
-        return 0
-
-  print "Installing ARM root image: %s" % sysroot
-  if os.path.isdir(sysroot):
-    shutil.rmtree(sysroot)
-  os.mkdir(sysroot)
-  tarball = os.path.join(sysroot, TARBALL)
-  curl = ['curl', '--fail', '-L', url, '-o', tarball]
-  if os.isatty(sys.stdout.fileno()):
-    curl.append('--progress')
-  else:
-    curl.append('--silent')
-  subprocess.check_call(curl)
-  sha1sum = get_sha1(tarball)
-  if sha1sum != TARBALL_SHA1SUM:
-    print 'Tarball sha1sum is wrong.'
-    print 'Expected %s, actual: %s' % (TARBALL_SHA1SUM, sha1sum)
-    return 1
-  subprocess.check_call(['tar', 'xf', tarball, '-C', sysroot])
-  os.remove(tarball)
-
-  with open(stamp, 'w') as s:
-    s.write(url)
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+msg = '''\
+ERROR: This script has merged with install-debian.wheezy.sysroot.py.
+Please use that instead (with --arch=arm).
+'''
+sys.stderr.write(msg)
diff --git a/build/linux/install-chromeos-fonts.py b/build/linux/install-chromeos-fonts.py
index 98c3a57..a24adc92 100755
--- a/build/linux/install-chromeos-fonts.py
+++ b/build/linux/install-chromeos-fonts.py
@@ -12,16 +12,12 @@
 import subprocess
 import sys
 
-URL_PREFIX = 'https://commondatastorage.googleapis.com'
-URL_DIR = 'chromeos-localmirror/distfiles'
-URL_FILE = 'notofonts-20121206.tar.gz'
+# Taken from the media-fonts/notofonts ebuild in chromiumos-overlay.
+VERSION = '20140815'
+URL = ('https://commondatastorage.googleapis.com/chromeos-localmirror/'
+       'distfiles/notofonts-%s.tar.bz2') % (VERSION)
 FONTS_DIR = '/usr/local/share/fonts'
 
-# The URL matches the URL in the ebuild script in chromiumos. See:
-#  /path/to/chromiumos/src/
-#  third_party/chromiumos-overlay/media-fonts/notofonts/
-#  notofonts-20121206.ebuild
-
 def main(args):
   if not sys.platform.startswith('linux'):
     print "Error: %s must be run on Linux." % __file__
@@ -37,12 +33,10 @@
 
   dest_dir = os.path.join(FONTS_DIR, 'chromeos')
 
-  url = "%s/%s/%s" % (URL_PREFIX, URL_DIR, URL_FILE)
-
   stamp = os.path.join(dest_dir, ".stamp02")
   if os.path.exists(stamp):
     with open(stamp) as s:
-      if s.read() == url:
+      if s.read() == URL:
         print "Chrome OS fonts already up-to-date in %s." % dest_dir
         return 0
 
@@ -52,8 +46,8 @@
   os.chmod(dest_dir, 0755)
 
   print "Installing Chrome OS fonts to %s." % dest_dir
-  tarball = os.path.join(dest_dir, URL_FILE)
-  subprocess.check_call(['curl', '-L', url, '-o', tarball])
+  tarball = os.path.join(dest_dir, os.path.basename(URL))
+  subprocess.check_call(['curl', '-L', URL, '-o', tarball])
   subprocess.check_call(['tar', '--no-same-owner', '--no-same-permissions',
                          '-xf', tarball, '-C', dest_dir])
   os.remove(tarball)
@@ -65,7 +59,7 @@
     s.write("Script: %s\n" % __file__)
 
   with open(stamp, 'w') as s:
-    s.write(url)
+    s.write(URL)
 
   for base, dirs, files in os.walk(dest_dir):
     for dir in dirs:
diff --git a/build/sanitizers/sanitizer_options.cc b/build/sanitizers/sanitizer_options.cc
index 1e926258..821ba485a 100644
--- a/build/sanitizers/sanitizer_options.cc
+++ b/build/sanitizers/sanitizer_options.cc
@@ -46,6 +46,9 @@
 //   strip_path_prefix=Release/../../ - prefixes up to and including this
 //     substring will be stripped from source file paths in symbolized reports
 //     (if symbolize=true, which is set when running with LeakSanitizer).
+//   fast_unwind_on_fatal=1 - use the fast (frame-pointer-based) stack unwinder
+//     to print error reports. V8 doesn't generate debug info for the JIT code,
+//     so the slow unwinder may not work properly.
 #if defined(OS_LINUX)
 #if defined(GOOGLE_CHROME_BUILD)
 // Default AddressSanitizer options for the official build. These do not affect
@@ -54,18 +57,18 @@
 const char kAsanDefaultOptions[] =
     "legacy_pthread_cond=1 malloc_context_size=5 strict_memcmp=0 "
     "symbolize=false check_printf=1 use_sigaltstack=1 detect_leaks=0 "
-    "strip_path_prefix=Release/../../ ";
+    "strip_path_prefix=Release/../../ fast_unwind_on_fatal=1";
 #else
 // Default AddressSanitizer options for buildbots and non-official builds.
 const char *kAsanDefaultOptions =
     "strict_memcmp=0 symbolize=false check_printf=1 use_sigaltstack=1 "
-    "detect_leaks=0 strip_path_prefix=Release/../../ ";
+    "detect_leaks=0 strip_path_prefix=Release/../../ fast_unwind_on_fatal=1";
 #endif  // GOOGLE_CHROME_BUILD
 
 #elif defined(OS_MACOSX)
 const char *kAsanDefaultOptions =
     "strict_memcmp=0 replace_intrin=0 check_printf=1 use_sigaltstack=1 "
-    "strip_path_prefix=Release/../../ ";
+    "strip_path_prefix=Release/../../ fast_unwind_on_fatal=1";
 static const char kNaClDefaultOptions[] = "handle_segv=0";
 static const char kNaClFlag[] = "--type=nacl-loader";
 #endif  // OS_LINUX
diff --git a/build/secondary/tools/grit/grit_rule.gni b/build/secondary/tools/grit/grit_rule.gni
index 5103d73..572b11f2 100644
--- a/build/secondary/tools/grit/grit_rule.gni
+++ b/build/secondary/tools/grit/grit_rule.gni
@@ -330,6 +330,10 @@
     deps = [ ":$grit_custom_target" ]
     public_configs = [ ":$grit_config" ]
 
+    if (defined(invoker.public_configs)) {
+      public_configs += invoker.public_configs
+    }
+
     if (defined(invoker.visibility)) {
       visibility = invoker.visibility
     }
diff --git a/cc/PRESUBMIT.py b/cc/PRESUBMIT.py
index 1aa48f3..46c3a54 100644
--- a/cc/PRESUBMIT.py
+++ b/cc/PRESUBMIT.py
@@ -191,12 +191,6 @@
         errors.append(output_api.PresubmitError(
           '%s:%d uses scoped_ptr<T>(). Use nullptr instead.' %
           (f.LocalPath(), line_number)))
-      # Disallow:
-      # foo.PassAs<T>();
-      if re.search(r'\bPassAs<.*?>\(\)', line):
-        errors.append(output_api.PresubmitError(
-          '%s:%d uses PassAs<T>(). Use Pass() instead.' %
-          (f.LocalPath(), line_number)))
   return errors
 
 def FindUnquotedQuote(contents, pos):
@@ -332,42 +326,6 @@
   else:
     return []
 
-def CheckOverrideFinal(input_api, output_api,
-                       whitelist=CC_SOURCE_FILES, blacklist=None):
-  """Make sure new lines of code don't use the OVERRIDE or FINAL macros."""
-
-  # TODO(mostynb): remove this check once the macros are removed
-  # from base/compiler_specific.h.
-
-  errors = []
-
-  source_file_filter = lambda x: input_api.FilterSourceFile(
-    x, white_list=CC_SOURCE_FILES, black_list=None)
-
-  override_files = []
-  final_files = []
-
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-
-    # "override" and "final" should be used instead of OVERRIDE/FINAL now.
-    if re.search(r"\bOVERRIDE\b", contents):
-      override_files.append(f.LocalPath())
-
-    if re.search(r"\bFINAL\b", contents):
-      final_files.append(f.LocalPath())
-
-  if override_files:
-    return [output_api.PresubmitError(
-      'These files use OVERRIDE instead of using override:',
-      items=override_files)]
-  if final_files:
-    return [output_api.PresubmitError(
-      'These files use FINAL instead of using final:',
-      items=final_files)]
-
-  return []
-
 def CheckChangeOnUpload(input_api, output_api):
   results = []
   results += CheckAsserts(input_api, output_api)
@@ -380,7 +338,6 @@
   results += CheckNamespace(input_api, output_api)
   results += CheckForUseOfWrongClock(input_api, output_api)
   results += FindUselessIfdefs(input_api, output_api)
-  results += CheckOverrideFinal(input_api, output_api)
   results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api)
   return results
 
diff --git a/cc/animation/keyframed_animation_curve.cc b/cc/animation/keyframed_animation_curve.cc
index de18a2b1..333a5c9a 100644
--- a/cc/animation/keyframed_animation_curve.cc
+++ b/cc/animation/keyframed_animation_curve.cc
@@ -6,7 +6,7 @@
 
 #include "cc/animation/keyframed_animation_curve.h"
 #include "ui/gfx/animation/tween.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
 
 namespace cc {
 
diff --git a/cc/animation/keyframed_animation_curve_unittest.cc b/cc/animation/keyframed_animation_curve_unittest.cc
index 32bc141..71fd5219 100644
--- a/cc/animation/keyframed_animation_curve_unittest.cc
+++ b/cc/animation/keyframed_animation_curve_unittest.cc
@@ -8,7 +8,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/animation/tween.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
 #include "ui/gfx/test/gfx_util.h"
 
 namespace cc {
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index ab6db10..b779a37 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -16,7 +16,7 @@
 #include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/base/scoped_ptr_algorithm.h"
 #include "cc/output/filter_operations.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/animation/layer_animation_controller_unittest.cc b/cc/animation/layer_animation_controller_unittest.cc
index 96c406c3a..49ac0a5 100644
--- a/cc/animation/layer_animation_controller_unittest.cc
+++ b/cc/animation/layer_animation_controller_unittest.cc
@@ -14,7 +14,7 @@
 #include "cc/test/animation_test_common.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/animation/scrollbar_animation_controller.h b/cc/animation/scrollbar_animation_controller.h
index 8c98c9e..92efe755 100644
--- a/cc/animation/scrollbar_animation_controller.h
+++ b/cc/animation/scrollbar_animation_controller.h
@@ -9,7 +9,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "cc/base/cc_export.h"
-#include "ui/gfx/vector2d_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
diff --git a/cc/animation/transform_operation.cc b/cc/animation/transform_operation.cc
index f4403fa3..e9ae86d 100644
--- a/cc/animation/transform_operation.cc
+++ b/cc/animation/transform_operation.cc
@@ -14,9 +14,9 @@
 #include "base/logging.h"
 #include "cc/animation/transform_operation.h"
 #include "cc/animation/transform_operations.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/transform_util.h"
-#include "ui/gfx/vector3d_f.h"
 
 namespace {
 const SkMScalar kAngleEpsilon = 1e-4f;
diff --git a/cc/animation/transform_operations.cc b/cc/animation/transform_operations.cc
index 7c328af6..7bc4ce2a 100644
--- a/cc/animation/transform_operations.cc
+++ b/cc/animation/transform_operations.cc
@@ -7,9 +7,9 @@
 #include <algorithm>
 
 #include "ui/gfx/animation/tween.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/transform_util.h"
-#include "ui/gfx/vector3d_f.h"
 
 namespace cc {
 
diff --git a/cc/animation/transform_operations_unittest.cc b/cc/animation/transform_operations_unittest.cc
index cf29e97..7aae696 100644
--- a/cc/animation/transform_operations_unittest.cc
+++ b/cc/animation/transform_operations_unittest.cc
@@ -10,9 +10,9 @@
 #include "cc/test/geometry_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/animation/tween.h"
-#include "ui/gfx/box_f.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/vector3d_f.h"
+#include "ui/gfx/geometry/box_f.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 
 namespace cc {
 namespace {
diff --git a/cc/base/float_quad_unittest.cc b/cc/base/float_quad_unittest.cc
index c2186fd81..6d9ce02f 100644
--- a/cc/base/float_quad_unittest.cc
+++ b/cc/base/float_quad_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "cc/base/math_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/quad_f.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/base/invalidation_region.h b/cc/base/invalidation_region.h
index 9cb2fe3..7aa4a8b2 100644
--- a/cc/base/invalidation_region.h
+++ b/cc/base/invalidation_region.h
@@ -7,7 +7,7 @@
 
 #include "cc/base/cc_export.h"
 #include "cc/base/region.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc
index 8cd0692..816f6fc 100644
--- a/cc/base/math_util.cc
+++ b/cc/base/math_util.cc
@@ -10,12 +10,12 @@
 
 #include "base/debug/trace_event_argument.h"
 #include "base/values.h"
-#include "ui/gfx/quad_f.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
-#include "ui/gfx/vector2d_f.h"
 
 namespace cc {
 
diff --git a/cc/base/math_util.h b/cc/base/math_util.h
index 622ea4dd..50494e1 100644
--- a/cc/base/math_util.h
+++ b/cc/base/math_util.h
@@ -12,11 +12,11 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/scroll_offset.h"
-#include "ui/gfx/point3_f.h"
-#include "ui/gfx/point_f.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
diff --git a/cc/base/math_util_unittest.cc b/cc/base/math_util_unittest.cc
index fb8c27f..325870d 100644
--- a/cc/base/math_util_unittest.cc
+++ b/cc/base/math_util_unittest.cc
@@ -9,8 +9,8 @@
 #include "cc/test/geometry_test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/base/region.h b/cc/base/region.h
index d78d4cb7..294ea63 100644
--- a/cc/base/region.h
+++ b/cc/base/region.h
@@ -10,7 +10,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
 #include "third_party/skia/include/core/SkRegion.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/skia_util.h"
 
 namespace base {
diff --git a/cc/base/simple_enclosed_region.h b/cc/base/simple_enclosed_region.h
index c9625ba..5e8a6b2 100644
--- a/cc/base/simple_enclosed_region.h
+++ b/cc/base/simple_enclosed_region.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "cc/base/cc_export.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/base/tiling_data.cc b/cc/base/tiling_data.cc
index 61bb8517..7b39878b3 100644
--- a/cc/base/tiling_data.cc
+++ b/cc/base/tiling_data.cc
@@ -6,8 +6,8 @@
 
 #include <algorithm>
 
-#include "ui/gfx/rect.h"
-#include "ui/gfx/vector2d.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
 
 namespace cc {
 
diff --git a/cc/base/tiling_data.h b/cc/base/tiling_data.h
index 08d421c..5e8a4d6 100644
--- a/cc/base/tiling_data.h
+++ b/cc/base/tiling_data.h
@@ -10,8 +10,8 @@
 #include "base/basictypes.h"
 #include "base/logging.h"
 #include "cc/base/cc_export.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace gfx {
 class Vector2d;
diff --git a/cc/blink/web_layer_impl_fixed_bounds.h b/cc/blink/web_layer_impl_fixed_bounds.h
index 907975a..099feafa 100644
--- a/cc/blink/web_layer_impl_fixed_bounds.h
+++ b/cc/blink/web_layer_impl_fixed_bounds.h
@@ -6,7 +6,7 @@
 #define CC_BLINK_WEB_LAYER_IMPL_FIXED_BOUNDS_H_
 
 #include "cc/blink/web_layer_impl.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 #include "ui/gfx/transform.h"
 
 namespace cc_blink {
diff --git a/cc/blink/web_layer_impl_fixed_bounds_unittest.cc b/cc/blink/web_layer_impl_fixed_bounds_unittest.cc
index f439366..ceeb311 100644
--- a/cc/blink/web_layer_impl_fixed_bounds_unittest.cc
+++ b/cc/blink/web_layer_impl_fixed_bounds_unittest.cc
@@ -12,7 +12,7 @@
 #include "third_party/WebKit/public/platform/WebFloatPoint.h"
 #include "third_party/WebKit/public/platform/WebSize.h"
 #include "third_party/skia/include/utils/SkMatrix44.h"
-#include "ui/gfx/point3_f.h"
+#include "ui/gfx/geometry/point3_f.h"
 
 using blink::WebFloatPoint;
 using blink::WebSize;
diff --git a/cc/debug/debug_rect_history.h b/cc/debug/debug_rect_history.h
index 278b208..6d25b296 100644
--- a/cc/debug/debug_rect_history.h
+++ b/cc/debug/debug_rect_history.h
@@ -9,7 +9,7 @@
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
 #include "cc/layers/layer_lists.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/debug/invalidation_benchmark.cc b/cc/debug/invalidation_benchmark.cc
index 87d2edd..1a6a2b8 100644
--- a/cc/debug/invalidation_benchmark.cc
+++ b/cc/debug/invalidation_benchmark.cc
@@ -14,7 +14,7 @@
 #include "cc/layers/picture_layer.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_host_common.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/debug/picture_record_benchmark.cc b/cc/debug/picture_record_benchmark.cc
index a8a296d..5f832ae 100644
--- a/cc/debug/picture_record_benchmark.cc
+++ b/cc/debug/picture_record_benchmark.cc
@@ -12,7 +12,7 @@
 #include "cc/layers/picture_layer.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_host_common.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc
index 7a1319d9..f24dce3b 100644
--- a/cc/debug/rasterize_and_record_benchmark.cc
+++ b/cc/debug/rasterize_and_record_benchmark.cc
@@ -17,7 +17,7 @@
 #include "cc/layers/picture_layer.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_host_common.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc
index 77bc259..612dad82 100644
--- a/cc/debug/rasterize_and_record_benchmark_impl.cc
+++ b/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -15,7 +15,7 @@
 #include "cc/resources/raster_worker_pool.h"
 #include "cc/trees/layer_tree_host_common.h"
 #include "cc/trees/layer_tree_host_impl.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
@@ -211,9 +211,10 @@
 
   FixedInvalidationPictureLayerTilingClient client(
       layer, gfx::Rect(layer->content_bounds()));
-  PictureLayerTilingSet tiling_set(&client, layer->content_bounds());
+  PictureLayerTilingSet tiling_set(&client);
 
-  PictureLayerTiling* tiling = tiling_set.AddTiling(layer->contents_scale_x());
+  PictureLayerTiling* tiling =
+      tiling_set.AddTiling(layer->contents_scale_x(), layer->bounds());
   tiling->CreateAllTilesForTesting();
   for (PictureLayerTiling::CoverageIterator it(
            tiling, layer->contents_scale_x(), layer->visible_content_rect());
diff --git a/cc/input/layer_scroll_offset_delegate.h b/cc/input/layer_scroll_offset_delegate.h
index f7ca485..02ba011 100644
--- a/cc/input/layer_scroll_offset_delegate.h
+++ b/cc/input/layer_scroll_offset_delegate.h
@@ -7,7 +7,7 @@
 
 #include "base/basictypes.h"
 #include "ui/gfx/geometry/scroll_offset.h"
-#include "ui/gfx/size_f.h"
+#include "ui/gfx/geometry/size_f.h"
 
 namespace cc {
 
diff --git a/cc/input/page_scale_animation.cc b/cc/input/page_scale_animation.cc
index 23bf21b..111502b 100644
--- a/cc/input/page_scale_animation.cc
+++ b/cc/input/page_scale_animation.cc
@@ -8,9 +8,9 @@
 
 #include "base/logging.h"
 #include "cc/animation/timing_function.h"
-#include "ui/gfx/point_f.h"
-#include "ui/gfx/rect_f.h"
-#include "ui/gfx/vector2d_conversions.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 
 namespace {
 
diff --git a/cc/input/page_scale_animation.h b/cc/input/page_scale_animation.h
index fca9563c3..ce13dcf8 100644
--- a/cc/input/page_scale_animation.h
+++ b/cc/input/page_scale_animation.h
@@ -9,8 +9,8 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
 #include "cc/base/cc_export.h"
-#include "ui/gfx/size.h"
-#include "ui/gfx/vector2d_f.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
diff --git a/cc/input/scrollbar.h b/cc/input/scrollbar.h
index 8321ae2..19ac92a 100644
--- a/cc/input/scrollbar.h
+++ b/cc/input/scrollbar.h
@@ -6,8 +6,8 @@
 #define CC_INPUT_SCROLLBAR_H_
 
 #include "cc/base/cc_export.h"
-#include "ui/gfx/point.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/rect.h"
 
 class SkCanvas;
 
diff --git a/cc/input/top_controls_manager.cc b/cc/input/top_controls_manager.cc
index 18a93a5..cd3534c 100644
--- a/cc/input/top_controls_manager.cc
+++ b/cc/input/top_controls_manager.cc
@@ -13,8 +13,8 @@
 #include "cc/output/begin_frame_args.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "ui/gfx/frame_time.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
-#include "ui/gfx/vector2d_f.h"
 
 namespace cc {
 namespace {
diff --git a/cc/input/top_controls_manager.h b/cc/input/top_controls_manager.h
index 1aface8..a90d33d3 100644
--- a/cc/input/top_controls_manager.h
+++ b/cc/input/top_controls_manager.h
@@ -9,8 +9,8 @@
 #include "base/memory/weak_ptr.h"
 #include "cc/input/top_controls_state.h"
 #include "cc/layers/layer_impl.h"
-#include "ui/gfx/size.h"
-#include "ui/gfx/vector2d_f.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace base {
 class TimeTicks;
diff --git a/cc/input/top_controls_manager_unittest.cc b/cc/input/top_controls_manager_unittest.cc
index 9bde132..77b40c9d 100644
--- a/cc/input/top_controls_manager_unittest.cc
+++ b/cc/input/top_controls_manager_unittest.cc
@@ -14,7 +14,7 @@
 #include "cc/trees/layer_tree_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/frame_time.h"
-#include "ui/gfx/vector2d_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 namespace {
diff --git a/cc/layers/contents_scaling_layer.cc b/cc/layers/contents_scaling_layer.cc
index 5811bdc..733bac09 100644
--- a/cc/layers/contents_scaling_layer.cc
+++ b/cc/layers/contents_scaling_layer.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "cc/layers/contents_scaling_layer.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 
diff --git a/cc/layers/delegated_frame_provider.h b/cc/layers/delegated_frame_provider.h
index b71c748..3bcf9195 100644
--- a/cc/layers/delegated_frame_provider.h
+++ b/cc/layers/delegated_frame_provider.h
@@ -12,8 +12,8 @@
 #include "cc/base/cc_export.h"
 #include "cc/resources/return_callback.h"
 #include "cc/resources/returned_resource.h"
-#include "ui/gfx/rect_f.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 class DelegatedFrameData;
diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc
index e66cc766..3fb1c482 100644
--- a/cc/layers/delegated_renderer_layer_impl_unittest.cc
+++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc
@@ -1416,7 +1416,12 @@
                                         pass1_id,
                                         gfx::Rect(layer_size),
                                         gfx::Transform());
-  AddRenderPassQuad(pass1, pass2, 0, FilterOperations(), transform);
+  AddRenderPassQuad(pass1,
+                    pass2,
+                    0,
+                    FilterOperations(),
+                    transform,
+                    SkXfermode::kSrcOver_Mode);
   delegated_renderer_layer_impl->SetFrameDataForRenderPasses(
       1.f, &delegated_render_passes);
 
diff --git a/cc/layers/draw_properties.h b/cc/layers/draw_properties.h
index 23845a0..403393e4 100644
--- a/cc/layers/draw_properties.h
+++ b/cc/layers/draw_properties.h
@@ -6,7 +6,7 @@
 #define CC_LAYERS_DRAW_PROPERTIES_H_
 
 #include "base/memory/scoped_ptr.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc
index 1dbdc64..0692139 100644
--- a/cc/layers/heads_up_display_layer_impl.cc
+++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -25,8 +25,8 @@
 #include "third_party/skia/include/core/SkPaint.h"
 #include "third_party/skia/include/core/SkTypeface.h"
 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
-#include "ui/gfx/point.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/layers/io_surface_layer_impl.h b/cc/layers/io_surface_layer_impl.h
index 17b70936..663bcef 100644
--- a/cc/layers/io_surface_layer_impl.h
+++ b/cc/layers/io_surface_layer_impl.h
@@ -9,7 +9,7 @@
 
 #include "cc/base/cc_export.h"
 #include "cc/layers/layer_impl.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index dd71307..08f39b9 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -26,8 +26,8 @@
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "third_party/skia/include/core/SkImageFilter.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/vector2d_conversions.h"
-#include "ui/gfx/rect_conversions.h"
 
 namespace cc {
 
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index c6279af1..f372186 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -29,10 +29,10 @@
 #include "third_party/skia/include/core/SkImageFilter.h"
 #include "third_party/skia/include/core/SkPicture.h"
 #include "third_party/skia/include/core/SkXfermode.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/geometry/scroll_offset.h"
-#include "ui/gfx/point3_f.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
 #include "ui/gfx/transform.h"
 
 namespace gfx {
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 4c16da7..391fa922 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -26,12 +26,12 @@
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/layer_tree_settings.h"
 #include "cc/trees/proxy.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
+#include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/geometry/vector2d_conversions.h"
-#include "ui/gfx/point_conversions.h"
-#include "ui/gfx/quad_f.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
 
 namespace cc {
 LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id)
@@ -625,6 +625,13 @@
   float scale = layer_tree_impl()->page_scale_factor();
 
   gfx::Vector2dF delta_from_scroll = scroll_clip_layer_->bounds_delta();
+
+  // In virtual-viewport mode, we don't need to compensate for pinch zoom or
+  // scale since the fixed container is the outer viewport, which sits below
+  // the page scale.
+  if (layer_tree_impl()->settings().use_pinch_virtual_viewport)
+    return delta_from_scroll;
+
   delta_from_scroll.Scale(1.f / scale);
 
   // The delta-from-pinch component requires some explanation: A viewport of
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index bcac36ce..1c14eeb 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -31,10 +31,10 @@
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkImageFilter.h"
 #include "third_party/skia/include/core/SkPicture.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/geometry/scroll_offset.h"
-#include "ui/gfx/point3_f.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
diff --git a/cc/layers/layer_utils.cc b/cc/layers/layer_utils.cc
index 9c299c2..888174a 100644
--- a/cc/layers/layer_utils.cc
+++ b/cc/layers/layer_utils.cc
@@ -6,7 +6,7 @@
 
 #include "cc/layers/layer_impl.h"
 #include "cc/trees/layer_tree_host_common.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
 
 namespace cc {
 
diff --git a/cc/layers/layer_utils_unittest.cc b/cc/layers/layer_utils_unittest.cc
index bf4e9dba..1eb1986 100644
--- a/cc/layers/layer_utils_unittest.cc
+++ b/cc/layers/layer_utils_unittest.cc
@@ -11,7 +11,7 @@
 #include "cc/test/fake_layer_tree_host_impl.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/box_f.h"
 #include "ui/gfx/test/gfx_util.h"
 
 namespace cc {
diff --git a/cc/layers/nine_patch_layer.h b/cc/layers/nine_patch_layer.h
index f5aa712..9054610b 100644
--- a/cc/layers/nine_patch_layer.h
+++ b/cc/layers/nine_patch_layer.h
@@ -10,7 +10,7 @@
 #include "cc/layers/layer.h"
 #include "cc/layers/ui_resource_layer.h"
 #include "cc/resources/ui_resource_client.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/layers/nine_patch_layer_impl.cc b/cc/layers/nine_patch_layer_impl.cc
index b350ba9..1c76d110 100644
--- a/cc/layers/nine_patch_layer_impl.cc
+++ b/cc/layers/nine_patch_layer_impl.cc
@@ -10,7 +10,7 @@
 #include "cc/quads/texture_draw_quad.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/occlusion.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect_f.h"
 
 namespace cc {
 
diff --git a/cc/layers/nine_patch_layer_impl.h b/cc/layers/nine_patch_layer_impl.h
index 9af6f32..5320d39 100644
--- a/cc/layers/nine_patch_layer_impl.h
+++ b/cc/layers/nine_patch_layer_impl.h
@@ -12,8 +12,8 @@
 #include "cc/layers/ui_resource_layer_impl.h"
 #include "cc/resources/resource_provider.h"
 #include "cc/resources/ui_resource_client.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace base {
 class DictionaryValue;
diff --git a/cc/layers/nine_patch_layer_impl_unittest.cc b/cc/layers/nine_patch_layer_impl_unittest.cc
index 2b82d48..730b3e50 100644
--- a/cc/layers/nine_patch_layer_impl_unittest.cc
+++ b/cc/layers/nine_patch_layer_impl_unittest.cc
@@ -15,8 +15,8 @@
 #include "cc/trees/single_thread_proxy.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/safe_integer_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/safe_integer_conversions.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/layers/paint_properties.h b/cc/layers/paint_properties.h
index 323e9499..b57f90f3 100644
--- a/cc/layers/paint_properties.h
+++ b/cc/layers/paint_properties.h
@@ -5,7 +5,7 @@
 #ifndef CC_LAYERS_PAINT_PROPERTIES_H_
 #define CC_LAYERS_PAINT_PROPERTIES_H_
 
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/layers/painted_scrollbar_layer_impl.cc b/cc/layers/painted_scrollbar_layer_impl.cc
index dcb1e826..ea48086 100644
--- a/cc/layers/painted_scrollbar_layer_impl.cc
+++ b/cc/layers/painted_scrollbar_layer_impl.cc
@@ -13,7 +13,7 @@
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/layer_tree_settings.h"
 #include "cc/trees/occlusion.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 
 namespace cc {
 
diff --git a/cc/layers/picture_image_layer.h b/cc/layers/picture_image_layer.h
index 34678040..3575d88 100644
--- a/cc/layers/picture_image_layer.h
+++ b/cc/layers/picture_image_layer.h
@@ -9,7 +9,7 @@
 #include "cc/layers/content_layer_client.h"
 #include "cc/layers/picture_layer.h"
 #include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/layers/picture_image_layer_impl_unittest.cc b/cc/layers/picture_image_layer_impl_unittest.cc
index 2851392..6ae23a76 100644
--- a/cc/layers/picture_image_layer_impl_unittest.cc
+++ b/cc/layers/picture_image_layer_impl_unittest.cc
@@ -63,8 +63,7 @@
         new TestablePictureImageLayerImpl(tree, id);
     layer->SetBounds(gfx::Size(100, 200));
     layer->SetContentBounds(gfx::Size(100, 200));
-    layer->tilings_.reset(new PictureLayerTilingSet(&tiling_client_,
-                                                    layer->bounds()));
+    layer->tilings_.reset(new PictureLayerTilingSet(&tiling_client_));
     layer->pile_ = tiling_client_.GetPile();
     return make_scoped_ptr(layer);
   }
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index 1bb7d54..ca4033f 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -9,7 +9,7 @@
 #include "cc/layers/picture_layer_impl.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "third_party/skia/include/core/SkPictureRecorder.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 
 namespace cc {
 
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index fd8a507..e51821fb 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -26,9 +26,9 @@
 #include "cc/resources/tile_manager.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/occlusion.h"
-#include "ui/gfx/quad_f.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace {
 const float kMaxScaleRatioDuringPinch = 2.0f;
@@ -168,7 +168,7 @@
     SolidColorLayerImpl::AppendSolidQuads(render_pass,
                                           occlusion_in_content_space,
                                           shared_quad_state,
-                                          content_bounds(),
+                                          visible_content_rect(),
                                           pile_->solid_color(),
                                           append_quads_data);
     return;
@@ -483,6 +483,9 @@
   was_screen_space_transform_animating_ =
       draw_properties().screen_space_transform_is_animating;
 
+  if (draw_transform_is_animating())
+    pile_->set_likely_to_be_used_for_transform_animation();
+
   should_update_tile_priorities_ = true;
 
   UpdateTilePriorities(occlusion_in_content_space);
@@ -498,10 +501,12 @@
       (layer_tree_impl()->CurrentBeginFrameArgs().frame_time -
        base::TimeTicks()).InSecondsF();
 
+  gfx::Rect viewport_rect_in_layer_space =
+      GetViewportForTilePriorityInContentSpace();
   bool tiling_needs_update = false;
   for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
-    if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTime(
-            current_frame_time_in_seconds)) {
+    if (tilings_->tiling_at(i)->NeedsUpdateForFrameAtTimeAndViewport(
+            current_frame_time_in_seconds, viewport_rect_in_layer_space)) {
       tiling_needs_update = true;
       break;
     }
@@ -509,8 +514,6 @@
   if (!tiling_needs_update)
     return;
 
-  gfx::Rect viewport_rect_in_layer_space =
-      GetViewportForTilePriorityInContentSpace();
   WhichTree tree =
       layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
   bool can_require_tiles_for_activation =
@@ -790,7 +793,7 @@
     const PictureLayerTiling* tiling) {
   if (!CanHaveTilingWithScale(tiling->contents_scale()))
     return;
-  tilings_->AddTiling(tiling->contents_scale());
+  tilings_->AddTiling(tiling->contents_scale(), bounds());
 
   // If this tree needs update draw properties, then the tiling will
   // get updated prior to drawing or activation.  If this tree does not
@@ -840,7 +843,7 @@
   DCHECK(layer_tree_impl()->IsPendingTree());
 
   if (!tilings_)
-    tilings_.reset(new PictureLayerTilingSet(this, bounds()));
+    tilings_ = make_scoped_ptr(new PictureLayerTilingSet(this));
 
   DCHECK(!twin_layer_);
   twin_layer_ = static_cast<PictureLayerImpl*>(
@@ -861,7 +864,7 @@
   DCHECK(CanHaveTilingWithScale(contents_scale)) <<
       "contents_scale: " << contents_scale;
 
-  PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale);
+  PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale, bounds());
 
   DCHECK(pile_->HasRecordings());
 
@@ -1239,19 +1242,7 @@
 }
 
 bool PictureLayerImpl::ShouldAdjustRasterScaleDuringScaleAnimations() const {
-  if (!layer_tree_impl()->use_gpu_rasterization())
-    return false;
-
-  // Re-rastering text at different scales using GPU rasterization causes
-  // texture uploads for glyphs at each scale (see crbug.com/366225). To
-  // workaround this performance issue, we don't re-rasterize layers with
-  // text during scale animations.
-  // TODO(ajuma): Remove this workaround once text can be efficiently
-  // re-rastered at different scales (e.g. by using distance-field fonts).
-  if (pile_->has_text())
-    return false;
-
-  return true;
+  return layer_tree_impl()->use_gpu_rasterization();
 }
 
 float PictureLayerImpl::MaximumTilingContentsScale() const {
@@ -1450,7 +1441,7 @@
           PictureLayerTiling::TilingRasterTileIterator(tiling);
     }
 
-    if (tiling->resolution() == LOW_RESOLUTION) {
+    if (prioritize_low_res && tiling->resolution() == LOW_RESOLUTION) {
       iterators_[LOW_RES] =
           PictureLayerTiling::TilingRasterTileIterator(tiling);
     }
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 73906af..3920779 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -28,8 +28,8 @@
 #include "cc/test/test_web_graphics_context_3d.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 namespace {
@@ -1431,6 +1431,40 @@
             render_pass->quad_list.front()->material);
 }
 
+TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) {
+  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+
+  gfx::Size tile_size(1000, 1000);
+  gfx::Size layer_bounds(1500, 1500);
+  gfx::Rect visible_rect(1000, 1000);
+
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
+  scoped_refptr<FakePicturePileImpl> active_pile =
+      FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
+
+  pending_pile->set_is_solid_color(true);
+  active_pile->set_is_solid_color(true);
+
+  SetupTrees(pending_pile, active_pile);
+
+  active_layer_->draw_properties().visible_content_rect = visible_rect;
+
+  AppendQuadsData data;
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+  active_layer_->DidDraw(nullptr);
+
+  Region remaining = visible_rect;
+  for (auto& quad : render_pass->quad_list) {
+    EXPECT_TRUE(visible_rect.Contains(quad.rect));
+    EXPECT_TRUE(remaining.Contains(quad.rect));
+    remaining.Subtract(quad.rect);
+  }
+
+  EXPECT_TRUE(remaining.IsEmpty());
+}
+
 TEST_F(PictureLayerImplTest, MarkRequiredOffscreenTiles) {
   gfx::Size tile_size(100, 100);
   gfx::Size layer_bounds(200, 200);
@@ -2194,16 +2228,20 @@
 
   SetupDrawPropertiesAndUpdateTiles(
       active_layer_, 0.5f, 0.5f, 0.5f, 0.5f, false);
+  pending_layer_->tilings()->RemoveAllTilings();
   active_layer_->tilings()->RemoveAllTilings();
-  PictureLayerTiling* tiling = active_layer_->tilings()->AddTiling(0.5f);
-  active_layer_->tilings()->AddTiling(1.5f);
-  active_layer_->tilings()->AddTiling(0.25f);
+  PictureLayerTiling* tiling = active_layer_->AddTiling(0.5f);
+  active_layer_->AddTiling(1.5f);
+  active_layer_->AddTiling(0.25f);
   tiling->set_resolution(HIGH_RESOLUTION);
 
   // Sanity checks.
   ASSERT_EQ(3u, active_layer_->tilings()->num_tilings());
   ASSERT_EQ(tiling, active_layer_->tilings()->TilingAtScale(0.5f));
 
+  pending_layer_->tilings()->RemoveAllTilings();
+  ASSERT_EQ(0u, pending_layer_->tilings()->num_tilings());
+
   // Now, set the bounds to be 1x1 (so that minimum contents scale becomes
   // 1.0f). Note that we should also ensure that the pending layer needs post
   // commit initialization, since this is what would happen during commit. In
@@ -2602,8 +2640,9 @@
   static_cast<FakePicturePileImpl*>(pending_layer_->pile())->set_has_text(true);
   static_cast<FakePicturePileImpl*>(active_layer_->pile())->set_has_text(true);
 
-  // Since we're GPU-rasterizing but have text, starting an animation should
-  // cause tiling resolution to get set to the maximum animation scale.
+  // When we're GPU-rasterizing, even if we have text, starting an animation
+  // should cause tiling resolution to get set to the content scale, since we
+  // render animating text at content scale using distance fields.
   animating_transform = true;
   contents_scale = 2.f;
   maximum_animation_scale = 3.f;
@@ -2613,10 +2652,10 @@
                                page_scale,
                                maximum_animation_scale,
                                animating_transform);
-  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);
+  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);
 
-  // Further changes to scale during the animation should not cause a new
-  // high-res tiling to get created.
+  // Further changes to scale during the animation should still cause a new
+  // high-res tiling to get created at content scale.
   contents_scale = 4.f;
   maximum_animation_scale = 5.f;
 
@@ -2625,7 +2664,7 @@
                                page_scale,
                                maximum_animation_scale,
                                animating_transform);
-  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);
+  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f);
 
   // Once we stop animating, a new high-res tiling should be created.
   animating_transform = false;
@@ -2704,7 +2743,7 @@
 
   EXPECT_TRUE(reached_prepaint);
   EXPECT_EQ(0u, non_ideal_tile_count);
-  EXPECT_EQ(1u, low_res_tile_count);
+  EXPECT_EQ(0u, low_res_tile_count);
   EXPECT_EQ(16u, high_res_tile_count);
   EXPECT_EQ(low_res_tile_count + high_res_tile_count + non_ideal_tile_count,
             unique_tiles.size());
@@ -2761,8 +2800,7 @@
   non_ideal_tile_count = 0;
   low_res_tile_count = 0;
   high_res_tile_count = 0;
-  for (it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, false);
-       it;
+  for (it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, true); it;
        ++it) {
     Tile* tile = *it;
     TilePriority priority = tile->priority(PENDING_TREE);
@@ -3794,7 +3832,7 @@
     if (tile_is_visible)
       unoccluded_tile_count++;
   }
-  EXPECT_EQ(unoccluded_tile_count, 25 + 4);
+  EXPECT_EQ(unoccluded_tile_count, 25);
 
   // Partial occlusion.
   pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
@@ -3824,7 +3862,7 @@
     if (tile_is_visible)
       unoccluded_tile_count++;
   }
-  EXPECT_EQ(20 + 2, unoccluded_tile_count);
+  EXPECT_EQ(20, unoccluded_tile_count);
 
   // Full occlusion.
   layer1->SetPosition(gfx::Point(0, 0));
@@ -4385,12 +4423,12 @@
   SetupPendingTree(pending_pile);
   ActivateTree();
 
+  active_layer_->set_fixed_tile_size(tile_size);
+  host_impl_.active_tree()->UpdateDrawProperties();
   if (test_for_solid) {
     EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
   } else {
     ASSERT_TRUE(active_layer_->tilings());
-    active_layer_->set_fixed_tile_size(tile_size);
-    host_impl_.active_tree()->UpdateDrawProperties();
     ASSERT_GT(active_layer_->tilings()->num_tilings(), 0u);
     std::vector<Tile*> tiles =
         active_layer_->tilings()->tiling_at(0)->AllTilesForTesting();
@@ -4490,6 +4528,65 @@
   EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
 }
 
+TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) {
+  base::TimeTicks time_ticks;
+  time_ticks += base::TimeDelta::FromMilliseconds(1);
+  host_impl_.SetCurrentBeginFrameArgs(
+      CreateBeginFrameArgsForTesting(time_ticks));
+
+  gfx::Size tile_size(100, 100);
+  gfx::Size layer_bounds(400, 4000);
+
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  scoped_refptr<FakePicturePileImpl> active_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+  SetupTrees(pending_pile, active_pile);
+
+  Region invalidation;
+  gfx::Rect viewport = gfx::Rect(0, 0, 100, 100);
+  gfx::Transform transform;
+
+  host_impl_.SetRequiresHighResToDraw();
+
+  // Update tiles.
+  pending_layer_->draw_properties().visible_content_rect = viewport;
+  pending_layer_->draw_properties().screen_space_transform = transform;
+  SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+
+  // Ensure we can't activate.
+  EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
+
+  // Now in the same frame, move the viewport (this can happen during
+  // animation).
+  viewport = gfx::Rect(0, 2000, 100, 100);
+
+  // Update tiles.
+  pending_layer_->draw_properties().visible_content_rect = viewport;
+  pending_layer_->draw_properties().screen_space_transform = transform;
+  SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+
+  // Make sure all viewport tiles (viewport from the tiling) are ready to draw.
+  std::vector<Tile*> tiles;
+  for (PictureLayerTiling::CoverageIterator iter(
+           pending_layer_->HighResTiling(),
+           1.f,
+           pending_layer_->HighResTiling()->GetCurrentVisibleRectForTesting());
+       iter;
+       ++iter) {
+    if (*iter)
+      tiles.push_back(*iter);
+  }
+
+  host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
+
+  // Ensure we can activate.
+  EXPECT_TRUE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
+}
+
 class TileSizeSettings : public ImplSidePaintingSettings {
  public:
   TileSizeSettings() {
diff --git a/cc/layers/render_surface.h b/cc/layers/render_surface.h
index 4da8d23..1e3719d 100644
--- a/cc/layers/render_surface.h
+++ b/cc/layers/render_surface.h
@@ -12,8 +12,8 @@
 #include "base/memory/ref_counted.h"
 #include "cc/base/cc_export.h"
 #include "cc/layers/layer_lists.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc
index ecb97a3..9d36235 100644
--- a/cc/layers/render_surface_impl.cc
+++ b/cc/layers/render_surface_impl.cc
@@ -20,7 +20,7 @@
 #include "cc/trees/damage_tracker.h"
 #include "cc/trees/occlusion_tracker.h"
 #include "third_party/skia/include/core/SkImageFilter.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/layers/render_surface_impl.h b/cc/layers/render_surface_impl.h
index 52e4f386..3303e94 100644
--- a/cc/layers/render_surface_impl.h
+++ b/cc/layers/render_surface_impl.h
@@ -14,8 +14,8 @@
 #include "cc/layers/layer_lists.h"
 #include "cc/quads/render_pass.h"
 #include "cc/quads/shared_quad_state.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/layers/scrollbar_layer_impl_base.cc b/cc/layers/scrollbar_layer_impl_base.cc
index 8d93a545..4248617 100644
--- a/cc/layers/scrollbar_layer_impl_base.cc
+++ b/cc/layers/scrollbar_layer_impl_base.cc
@@ -6,7 +6,7 @@
 
 #include <algorithm>
 #include "cc/trees/layer_tree_impl.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 
 namespace cc {
 
diff --git a/cc/layers/solid_color_layer_impl.cc b/cc/layers/solid_color_layer_impl.cc
index c8ddc7d7..e7ba09f1a 100644
--- a/cc/layers/solid_color_layer_impl.cc
+++ b/cc/layers/solid_color_layer_impl.cc
@@ -31,15 +31,17 @@
     RenderPass* render_pass,
     const Occlusion& occlusion_in_content_space,
     SharedQuadState* shared_quad_state,
-    const gfx::Size& content_bounds,
+    const gfx::Rect& visible_content_rect,
     SkColor color,
     AppendQuadsData* append_quads_data) {
   // We create a series of smaller quads instead of just one large one so that
   // the culler can reduce the total pixels drawn.
-  int width = content_bounds.width();
-  int height = content_bounds.height();
-  for (int x = 0; x < width; x += kSolidQuadTileSize) {
-    for (int y = 0; y < height; y += kSolidQuadTileSize) {
+  int width = visible_content_rect.width();
+  int height = visible_content_rect.height();
+  for (int x = visible_content_rect.x(); x < visible_content_rect.right();
+       x += kSolidQuadTileSize) {
+    for (int y = visible_content_rect.y(); y < visible_content_rect.bottom();
+         y += kSolidQuadTileSize) {
       gfx::Rect quad_rect(x,
                           y,
                           std::min(width - x, kSolidQuadTileSize),
@@ -71,10 +73,12 @@
   AppendDebugBorderQuad(
       render_pass, content_bounds(), shared_quad_state, append_quads_data);
 
+  // TODO(hendrikw): We need to pass the visible content rect rather than
+  // |content_bounds()| here.
   AppendSolidQuads(render_pass,
                    occlusion_in_content_space,
                    shared_quad_state,
-                   content_bounds(),
+                   gfx::Rect(content_bounds()),
                    background_color(),
                    append_quads_data);
 }
diff --git a/cc/layers/solid_color_layer_impl.h b/cc/layers/solid_color_layer_impl.h
index 34a38197..3793481 100644
--- a/cc/layers/solid_color_layer_impl.h
+++ b/cc/layers/solid_color_layer_impl.h
@@ -21,7 +21,7 @@
   static void AppendSolidQuads(RenderPass* render_pass,
                                const Occlusion& occlusion_in_content_space,
                                SharedQuadState* shared_quad_state,
-                               const gfx::Size& content_bounds,
+                               const gfx::Rect& visible_content_rect,
                                SkColor color,
                                AppendQuadsData* append_quads_data);
 
diff --git a/cc/layers/tiled_layer.cc b/cc/layers/tiled_layer.cc
index e4d5f7cc..2a32741 100644
--- a/cc/layers/tiled_layer.cc
+++ b/cc/layers/tiled_layer.cc
@@ -19,7 +19,7 @@
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/occlusion_tracker.h"
 #include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 
 namespace cc {
 
diff --git a/cc/layers/tiled_layer_impl.cc b/cc/layers/tiled_layer_impl.cc
index 6052591..c66e124 100644
--- a/cc/layers/tiled_layer_impl.cc
+++ b/cc/layers/tiled_layer_impl.cc
@@ -19,7 +19,7 @@
 #include "cc/trees/occlusion.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/quad_f.h"
+#include "ui/gfx/geometry/quad_f.h"
 
 namespace cc {
 
diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc
index 925cdc8..0f3112c 100644
--- a/cc/layers/tiled_layer_unittest.cc
+++ b/cc/layers/tiled_layer_unittest.cc
@@ -25,7 +25,7 @@
 #include "cc/trees/occlusion_tracker.h"
 #include "cc/trees/single_thread_proxy.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
@@ -128,8 +128,7 @@
                                                   nullptr,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false);
+                                                  1);
     host_impl_ = make_scoped_ptr(
         new FakeLayerTreeHostImpl(proxy_, shared_bitmap_manager_.get()));
   }
diff --git a/cc/layers/ui_resource_layer.h b/cc/layers/ui_resource_layer.h
index e22318c..3bfd9b2f 100644
--- a/cc/layers/ui_resource_layer.h
+++ b/cc/layers/ui_resource_layer.h
@@ -9,7 +9,7 @@
 #include "cc/base/cc_export.h"
 #include "cc/layers/layer.h"
 #include "cc/resources/ui_resource_client.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/layers/ui_resource_layer_impl.cc b/cc/layers/ui_resource_layer_impl.cc
index dc08a90..35d242be 100644
--- a/cc/layers/ui_resource_layer_impl.cc
+++ b/cc/layers/ui_resource_layer_impl.cc
@@ -10,7 +10,7 @@
 #include "cc/quads/texture_draw_quad.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/occlusion.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect_f.h"
 
 namespace cc {
 
diff --git a/cc/layers/ui_resource_layer_impl.h b/cc/layers/ui_resource_layer_impl.h
index 515a0f1..d98f1fb 100644
--- a/cc/layers/ui_resource_layer_impl.h
+++ b/cc/layers/ui_resource_layer_impl.h
@@ -11,8 +11,8 @@
 #include "cc/layers/layer_impl.h"
 #include "cc/resources/resource_provider.h"
 #include "cc/resources/ui_resource_client.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace base {
 class DictionaryValue;
diff --git a/cc/output/copy_output_request.h b/cc/output/copy_output_request.h
index 60a5f11..58aa790 100644
--- a/cc/output/copy_output_request.h
+++ b/cc/output/copy_output_request.h
@@ -10,7 +10,7 @@
 #include "cc/base/cc_export.h"
 #include "cc/resources/single_release_callback.h"
 #include "cc/resources/texture_mailbox.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 class SkBitmap;
 
diff --git a/cc/output/copy_output_result.h b/cc/output/copy_output_result.h
index 8529e3f..3662818 100644
--- a/cc/output/copy_output_result.h
+++ b/cc/output/copy_output_result.h
@@ -9,7 +9,7 @@
 #include "cc/base/cc_export.h"
 #include "cc/resources/single_release_callback.h"
 #include "cc/resources/texture_mailbox.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 class SkBitmap;
 
diff --git a/cc/output/filter_operations_unittest.cc b/cc/output/filter_operations_unittest.cc
index e97379c..d6ae6ab5 100644
--- a/cc/output/filter_operations_unittest.cc
+++ b/cc/output/filter_operations_unittest.cc
@@ -6,7 +6,7 @@
 #include "skia/ext/refptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/effects/SkBlurImageFilter.h"
-#include "ui/gfx/point.h"
+#include "ui/gfx/geometry/point.h"
 
 namespace cc {
 namespace {
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 61d233a4a7..78e2a2a 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -124,6 +124,44 @@
   }
 }
 
+BlendMode BlendModeFromSkXfermode(SkXfermode::Mode mode) {
+  switch (mode) {
+    case SkXfermode::kSrcOver_Mode:
+      return BlendModeNormal;
+    case SkXfermode::kOverlay_Mode:
+      return BlendModeOverlay;
+    case SkXfermode::kDarken_Mode:
+      return BlendModeDarken;
+    case SkXfermode::kLighten_Mode:
+      return BlendModeLighten;
+    case SkXfermode::kColorDodge_Mode:
+      return BlendModeColorDodge;
+    case SkXfermode::kColorBurn_Mode:
+      return BlendModeColorBurn;
+    case SkXfermode::kHardLight_Mode:
+      return BlendModeHardLight;
+    case SkXfermode::kSoftLight_Mode:
+      return BlendModeSoftLight;
+    case SkXfermode::kDifference_Mode:
+      return BlendModeDifference;
+    case SkXfermode::kExclusion_Mode:
+      return BlendModeExclusion;
+    case SkXfermode::kMultiply_Mode:
+      return BlendModeMultiply;
+    case SkXfermode::kHue_Mode:
+      return BlendModeHue;
+    case SkXfermode::kSaturation_Mode:
+      return BlendModeSaturation;
+    case SkXfermode::kColor_Mode:
+      return BlendModeColor;
+    case SkXfermode::kLuminosity_Mode:
+      return BlendModeLuminosity;
+    default:
+      NOTREACHED();
+      return BlendModeNormal;
+  }
+}
+
 // Smallest unit that impact anti-aliasing output. We use this to
 // determine when anti-aliasing is unnecessary.
 const float kAntiAliasingEpsilon = 1.0f / 1024.0f;
@@ -337,6 +375,9 @@
 
   use_sync_query_ = context_caps.gpu.sync_query;
   use_blend_minmax_ = context_caps.gpu.blend_minmax;
+  use_blend_equation_advanced_ = context_caps.gpu.blend_equation_advanced;
+  use_blend_equation_advanced_coherent_ =
+      context_caps.gpu.blend_equation_advanced_coherent;
 
   InitializeSharedObjects();
 }
@@ -697,7 +738,8 @@
 }
 
 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) {
-  return (use_blend_minmax_ && blend_mode == SkXfermode::kLighten_Mode) ||
+  return use_blend_equation_advanced_ ||
+         (use_blend_minmax_ && blend_mode == SkXfermode::kLighten_Mode) ||
          blend_mode == SkXfermode::kScreen_Mode ||
          blend_mode == SkXfermode::kSrcOver_Mode;
 }
@@ -706,11 +748,67 @@
   DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode));
 
   // Any modes set here must be reset in RestoreBlendFuncToDefault
-  if (blend_mode == SkXfermode::kScreen_Mode) {
-    GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE));
-  } else if (blend_mode == SkXfermode::kLighten_Mode) {
-    GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE));
-    GLC(gl_, gl_->BlendEquation(GL_MAX_EXT));
+  if (use_blend_equation_advanced_) {
+    GLenum equation = GL_FUNC_ADD;
+
+    switch (blend_mode) {
+      case SkXfermode::kScreen_Mode:
+        equation = GL_SCREEN_KHR;
+        break;
+      case SkXfermode::kOverlay_Mode:
+        equation = GL_OVERLAY_KHR;
+        break;
+      case SkXfermode::kDarken_Mode:
+        equation = GL_DARKEN_KHR;
+        break;
+      case SkXfermode::kLighten_Mode:
+        equation = GL_LIGHTEN_KHR;
+        break;
+      case SkXfermode::kColorDodge_Mode:
+        equation = GL_COLORDODGE_KHR;
+        break;
+      case SkXfermode::kColorBurn_Mode:
+        equation = GL_COLORBURN_KHR;
+        break;
+      case SkXfermode::kHardLight_Mode:
+        equation = GL_HARDLIGHT_KHR;
+        break;
+      case SkXfermode::kSoftLight_Mode:
+        equation = GL_SOFTLIGHT_KHR;
+        break;
+      case SkXfermode::kDifference_Mode:
+        equation = GL_DIFFERENCE_KHR;
+        break;
+      case SkXfermode::kExclusion_Mode:
+        equation = GL_EXCLUSION_KHR;
+        break;
+      case SkXfermode::kMultiply_Mode:
+        equation = GL_MULTIPLY_KHR;
+        break;
+      case SkXfermode::kHue_Mode:
+        equation = GL_HSL_HUE_KHR;
+        break;
+      case SkXfermode::kSaturation_Mode:
+        equation = GL_HSL_SATURATION_KHR;
+        break;
+      case SkXfermode::kColor_Mode:
+        equation = GL_HSL_COLOR_KHR;
+        break;
+      case SkXfermode::kLuminosity_Mode:
+        equation = GL_HSL_LUMINOSITY_KHR;
+        break;
+      default:
+        return;
+    }
+
+    GLC(gl_, gl_->BlendEquation(equation));
+  } else {
+    if (blend_mode == SkXfermode::kScreen_Mode) {
+      GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE));
+    } else if (blend_mode == SkXfermode::kLighten_Mode) {
+      GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE));
+      GLC(gl_, gl_->BlendEquation(GL_MAX_EXT));
+    }
   }
 }
 
@@ -718,144 +816,14 @@
   if (blend_mode == SkXfermode::kSrcOver_Mode)
     return;
 
-  GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
-
-  if (blend_mode == SkXfermode::kLighten_Mode)
+  if (use_blend_equation_advanced_) {
     GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD));
-}
-
-static skia::RefPtr<SkImage> ApplyBlendModeWithBackdrop(
-    scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context,
-    ResourceProvider* resource_provider,
-    skia::RefPtr<SkImage> source_bitmap_with_filters,
-    ScopedResource* source_texture_resource,
-    ScopedResource* background_texture_resource,
-    SkXfermode::Mode blend_mode) {
-  if (!use_gr_context)
-    return source_bitmap_with_filters;
-
-  DCHECK(background_texture_resource);
-  DCHECK(source_texture_resource);
-
-  gfx::Size source_size = source_texture_resource->size();
-  gfx::Size background_size = background_texture_resource->size();
-
-  DCHECK_LE(background_size.width(), source_size.width());
-  DCHECK_LE(background_size.height(), source_size.height());
-
-  int source_texture_with_filters_id;
-  scoped_ptr<ResourceProvider::ScopedReadLockGL> lock;
-  if (source_bitmap_with_filters) {
-    DCHECK_EQ(source_size.width(), source_bitmap_with_filters->width());
-    DCHECK_EQ(source_size.height(), source_bitmap_with_filters->height());
-    GrTexture* texture =
-        reinterpret_cast<GrTexture*>(source_bitmap_with_filters->getTexture());
-    source_texture_with_filters_id = texture->getTextureHandle();
   } else {
-    lock.reset(new ResourceProvider::ScopedReadLockGL(
-        resource_provider, source_texture_resource->id()));
-    source_texture_with_filters_id = lock->texture_id();
+    GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
+
+    if (blend_mode == SkXfermode::kLighten_Mode)
+      GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD));
   }
-
-  ResourceProvider::ScopedReadLockGL lock_background(
-      resource_provider, background_texture_resource->id());
-
-  // Wrap the source texture in a Ganesh platform texture.
-  GrBackendTextureDesc backend_texture_description;
-  backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
-  backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
-
-  backend_texture_description.fWidth = source_size.width();
-  backend_texture_description.fHeight = source_size.height();
-  backend_texture_description.fTextureHandle = source_texture_with_filters_id;
-  skia::RefPtr<GrTexture> source_texture =
-      skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
-          backend_texture_description));
-  if (!source_texture) {
-    TRACE_EVENT_INSTANT0(
-        "cc",
-        "ApplyBlendModeWithBackdrop wrap source texture failed",
-        TRACE_EVENT_SCOPE_THREAD);
-    return skia::RefPtr<SkImage>();
-  }
-
-  backend_texture_description.fWidth = background_size.width();
-  backend_texture_description.fHeight = background_size.height();
-  backend_texture_description.fTextureHandle = lock_background.texture_id();
-  skia::RefPtr<GrTexture> background_texture =
-      skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
-          backend_texture_description));
-  if (!background_texture) {
-    TRACE_EVENT_INSTANT0(
-        "cc",
-        "ApplyBlendModeWithBackdrop wrap background texture failed",
-        TRACE_EVENT_SCOPE_THREAD);
-    return skia::RefPtr<SkImage>();
-  }
-
-  SkImageInfo source_info =
-      SkImageInfo::MakeN32Premul(source_size.width(), source_size.height());
-  // Place the platform texture inside an SkBitmap.
-  SkBitmap source;
-  source.setInfo(source_info);
-  skia::RefPtr<SkGrPixelRef> source_pixel_ref =
-      skia::AdoptRef(new SkGrPixelRef(source_info, source_texture.get()));
-  source.setPixelRef(source_pixel_ref.get());
-
-  SkImageInfo background_info = SkImageInfo::MakeN32Premul(
-      background_size.width(), background_size.height());
-
-  SkBitmap background;
-  background.setInfo(background_info);
-  skia::RefPtr<SkGrPixelRef> background_pixel_ref =
-      skia::AdoptRef(new SkGrPixelRef(
-          background_info, background_texture.get()));
-  background.setPixelRef(background_pixel_ref.get());
-
-  // Create a scratch texture for backing store.
-  GrTextureDesc desc;
-  desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
-  desc.fSampleCnt = 0;
-  desc.fWidth = source.width();
-  desc.fHeight = source.height();
-  desc.fConfig = kSkia8888_GrPixelConfig;
-  desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
-  skia::RefPtr<GrTexture> backing_store =
-      skia::AdoptRef(use_gr_context->context()->refScratchTexture(
-          desc, GrContext::kExact_ScratchTexMatch));
-  if (!backing_store) {
-    TRACE_EVENT_INSTANT0(
-        "cc",
-        "ApplyBlendModeWithBackdrop scratch texture allocation failed",
-        TRACE_EVENT_SCOPE_THREAD);
-    return source_bitmap_with_filters;
-  }
-
-  // Create a device and canvas using that backing store.
-  skia::RefPtr<SkSurface> surface = skia::AdoptRef(
-      SkSurface::NewRenderTargetDirect(backing_store->asRenderTarget()));
-  if (!surface)
-    return skia::RefPtr<SkImage>();
-  skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas());
-
-  // Draw the source bitmap through the filter to the canvas.
-  canvas->clear(SK_ColorTRANSPARENT);
-  canvas->drawSprite(background, 0, 0);
-  SkPaint paint;
-  paint.setXfermodeMode(blend_mode);
-  canvas->drawSprite(source, 0, 0, &paint);
-
-  skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot());
-  if (!image || !image->getTexture()) {
-    return skia::RefPtr<SkImage>();
-  }
-
-  // Flush the GrContext to ensure all buffered GL calls are drawn to the
-  // backing store before we access and return it, and have cc begin using the
-  // GL context again.
-  canvas->flush();
-
-  return image;
 }
 
 bool GLRenderer::ShouldApplyBackgroundFilters(DrawingFrame* frame,
@@ -879,7 +847,8 @@
 gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
     DrawingFrame* frame,
     const RenderPassDrawQuad* quad,
-    const gfx::Transform& contents_device_transform) {
+    const gfx::Transform& contents_device_transform,
+    bool use_aa) {
   gfx::Rect backdrop_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect(
       contents_device_transform, SharedGeometryQuad().BoundingBox()));
 
@@ -889,6 +858,11 @@
     backdrop_rect.Inset(-left, -top, -right, -bottom);
   }
 
+  if (!backdrop_rect.IsEmpty() && use_aa) {
+    const int kOutsetForAntialiasing = 1;
+    backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing);
+  }
+
   backdrop_rect.Intersect(
       MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect));
   return backdrop_rect;
@@ -933,7 +907,6 @@
     DrawingFrame* frame,
     const RenderPassDrawQuad* quad,
     const gfx::Transform& contents_device_transform_inverse,
-    ScopedResource* device_background_texture,
     skia::RefPtr<SkImage> filtered_device_background,
     const gfx::Rect& backdrop_bounding_rect) {
   // This method draws a background filter, which applies a filter to any pixels
@@ -960,18 +933,9 @@
   // TODO(danakj): When this algorithm changes, update
   // LayerTreeHost::PrioritizeTextures() accordingly.
 
-  DCHECK(device_background_texture);
+  DCHECK(filtered_device_background);
 
-  int filtered_device_background_texture_id = 0;
-  scoped_ptr<ResourceProvider::ScopedReadLockGL> lock;
-  if (filtered_device_background) {
-    GrTexture* texture = filtered_device_background->getTexture();
-    filtered_device_background_texture_id = texture->getTextureHandle();
-  } else {
-    lock.reset(new ResourceProvider::ScopedReadLockGL(
-        resource_provider_, device_background_texture->id()));
-    filtered_device_background_texture_id = lock->texture_id();
-  }
+  GrTexture* texture = filtered_device_background->getTexture();
 
   scoped_ptr<ScopedResource> background_texture =
       ScopedResource::Create(resource_provider_);
@@ -1005,7 +969,7 @@
     bool flip_vertically = false;
 
     CopyTextureToFramebuffer(frame,
-                             filtered_device_background_texture_id,
+                             texture->getTextureHandle(),
                              backdrop_bounding_rect,
                              device_to_framebuffer_transform,
                              flip_vertically);
@@ -1021,9 +985,9 @@
 void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
                                     const RenderPassDrawQuad* quad) {
   SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
-  SetBlendEnabled(quad->ShouldDrawWithBlending() ||
-                  (!IsDefaultBlendMode(blend_mode) &&
-                   CanApplyBlendModeUsingBlendFunc(blend_mode)));
+  SetBlendEnabled(
+      CanApplyBlendModeUsingBlendFunc(blend_mode) &&
+      (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
 
   ScopedResource* contents_texture =
       render_pass_textures_.get(quad->render_pass_id);
@@ -1042,44 +1006,70 @@
   if (!contents_device_transform.GetInverse(&contents_device_transform_inverse))
     return;
 
+  bool clipped = false;
+  gfx::QuadF device_quad = MathUtil::MapQuad(
+      contents_device_transform, SharedGeometryQuad(), &clipped);
+  // Use anti-aliasing programs only when necessary.
+  bool use_aa =
+      !clipped &&
+      (settings_->force_antialiasing || !device_quad.IsRectilinear() ||
+       !gfx::IsNearestRectWithinDistance(device_quad.BoundingBox(),
+                                         kAntiAliasingEpsilon));
+
   bool need_background_texture = !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
                                  ShouldApplyBackgroundFilters(frame, quad);
 
   scoped_ptr<ScopedResource> background_texture;
+  skia::RefPtr<SkImage> background_image;
+  gfx::Rect background_rect;
   if (need_background_texture) {
+    // Compute a bounding box around the pixels that will be visible through
+    // the quad.
+    background_rect = GetBackdropBoundingBoxForRenderPassQuad(
+        frame, quad, contents_device_transform, use_aa);
+  }
+
+  if (!background_rect.IsEmpty()) {
     // The pixels from the filtered background should completely replace the
     // current pixel values.
     bool disable_blending = blend_enabled();
     if (disable_blending)
       SetBlendEnabled(false);
 
-    // Compute a bounding box around the pixels that will be visible through
-    // the quad.
-    gfx::Rect backdrop_rect = GetBackdropBoundingBoxForRenderPassQuad(
-        frame, quad, contents_device_transform);
-
     // Read the pixels in the bounding box into a buffer R.
     scoped_ptr<ScopedResource> scoped_background_texture =
-        GetBackdropTexture(backdrop_rect);
+        GetBackdropTexture(background_rect);
 
     skia::RefPtr<SkImage> background_with_filters;
-    if (ShouldApplyBackgroundFilters(frame, quad)) {
+    if (ShouldApplyBackgroundFilters(frame, quad) &&
+        scoped_background_texture) {
       // Apply the background filters to R, so that it is applied in the pixels'
       // coordinate space.
       background_with_filters =
           ApplyBackgroundFilters(frame, quad, scoped_background_texture.get());
     }
-    // Apply the quad's inverse transform to map the pixels in R into the
-    // quad's content space. This implicitly clips R by the content bounds of
-    // the quad since the destination texture has bounds matching the quad's
-    // content.
-    background_texture = ApplyInverseTransformForBackgroundFilters(
-        frame,
-        quad,
-        contents_device_transform_inverse,
-        scoped_background_texture.get(),
-        background_with_filters,
-        backdrop_rect);
+
+    if (CanApplyBlendModeUsingBlendFunc(blend_mode) &&
+        background_with_filters) {
+      // The background with filters will be copied to the frame buffer.
+      // Apply the quad's inverse transform to map the pixels in R into the
+      // quad's content space. This implicitly clips R by the content bounds of
+      // the quad since the destination texture has bounds matching the quad's
+      // content.
+      background_texture = ApplyInverseTransformForBackgroundFilters(
+          frame,
+          quad,
+          contents_device_transform_inverse,
+          background_with_filters,
+          background_rect);
+    } else if (!CanApplyBlendModeUsingBlendFunc(blend_mode)) {
+      if (background_with_filters) {
+        // The background with filters will be used as backdrop for blending.
+        background_image = background_with_filters;
+      } else {
+        background_texture = scoped_background_texture.Pass();
+      }
+    }
 
     if (disable_blending)
       SetBlendEnabled(true);
@@ -1117,49 +1107,27 @@
     }
   }
 
-  if (background_texture) {
-    if (CanApplyBlendModeUsingBlendFunc(blend_mode)) {
-      // Draw the background texture if it has some filters applied.
-      DCHECK(ShouldApplyBackgroundFilters(frame, quad));
-      DCHECK(background_texture->size() == quad->rect.size());
-      ResourceProvider::ScopedReadLockGL lock(resource_provider_,
-                                              background_texture->id());
+  if (background_texture && ShouldApplyBackgroundFilters(frame, quad)) {
+    // Draw the background texture if it has some filters applied.
+    DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode));
+    DCHECK(background_texture->size() == quad->rect.size());
+    ResourceProvider::ScopedReadLockGL lock(resource_provider_,
+                                            background_texture->id());
 
-      // The background_texture is oriented the same as the frame buffer. The
-      // transform we are copying with has a vertical flip, so flip the contents
-      // in the shader to maintain orientation
-      bool flip_vertically = true;
+    // The background_texture is oriented the same as the frame buffer. The
+    // transform we are copying with has a vertical flip, so flip the contents
+    // in the shader to maintain orientation
+    bool flip_vertically = true;
 
-      CopyTextureToFramebuffer(frame,
-                               lock.texture_id(),
-                               quad->rect,
-                               quad->quadTransform(),
-                               flip_vertically);
-    } else {
-      // If blending is applied using shaders, the background texture with
-      // filters will be used as backdrop for blending operation, so we don't
-      // need to copy it to the frame buffer.
-      filter_image =
-          ApplyBlendModeWithBackdrop(ScopedUseGrContext::Create(this, frame),
-                                     resource_provider_,
-                                     filter_image,
-                                     contents_texture,
-                                     background_texture.get(),
-                                     quad->shared_quad_state->blend_mode);
-    }
+    CopyTextureToFramebuffer(frame,
+                             lock.texture_id(),
+                             quad->rect,
+                             quad->quadTransform(),
+                             flip_vertically);
   }
 
-  bool clipped = false;
-  gfx::QuadF device_quad = MathUtil::MapQuad(
-      contents_device_transform, SharedGeometryQuad(), &clipped);
   LayerQuad device_layer_bounds(gfx::QuadF(device_quad.BoundingBox()));
   LayerQuad device_layer_edges(device_quad);
-
-  // Use anti-aliasing programs only when necessary.
-  bool use_aa =
-      !clipped && (!device_quad.IsRectilinear() ||
-                   !gfx::IsNearestRectWithinDistance(device_quad.BoundingBox(),
-                                                     kAntiAliasingEpsilon));
   if (use_aa) {
     device_layer_bounds.InflateAntiAliasingDistance();
     device_layer_edges.InflateAntiAliasingDistance();
@@ -1191,8 +1159,12 @@
               contents_resource_lock->target());
   }
 
-  if (CanApplyBlendModeUsingBlendFunc(blend_mode))
+  if (CanApplyBlendModeUsingBlendFunc(blend_mode)) {
+    if (!use_blend_equation_advanced_coherent_ && use_blend_equation_advanced_)
+      GLC(gl_, gl_->BlendBarrierKHR());
+
     ApplyBlendModeUsingBlendFunc(blend_mode);
+  }
 
   TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
       gl_,
@@ -1211,10 +1183,17 @@
   int shader_color_matrix_location = -1;
   int shader_color_offset_location = -1;
   int shader_tex_transform_location = -1;
+  int shader_backdrop_location = -1;
+  int shader_backdrop_rect_location = -1;
+
+  BlendMode shader_blend_mode = ((background_texture || background_image) &&
+                                 !CanApplyBlendModeUsingBlendFunc(blend_mode))
+                                    ? BlendModeFromSkXfermode(blend_mode)
+                                    : BlendModeNormal;
 
   if (use_aa && mask_texture_id && !use_color_matrix) {
     const RenderPassMaskProgramAA* program =
-        GetRenderPassMaskProgramAA(tex_coord_precision);
+        GetRenderPassMaskProgramAA(tex_coord_precision, shader_blend_mode);
     SetUseProgram(program->program());
     GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
 
@@ -1231,9 +1210,12 @@
     shader_alpha_location = program->fragment_shader().alpha_location();
     shader_tex_transform_location =
         program->vertex_shader().tex_transform_location();
+    shader_backdrop_location = program->fragment_shader().backdrop_location();
+    shader_backdrop_rect_location =
+        program->fragment_shader().backdrop_rect_location();
   } else if (!use_aa && mask_texture_id && !use_color_matrix) {
     const RenderPassMaskProgram* program =
-        GetRenderPassMaskProgram(tex_coord_precision);
+        GetRenderPassMaskProgram(tex_coord_precision, shader_blend_mode);
     SetUseProgram(program->program());
     GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
 
@@ -1247,9 +1229,12 @@
     shader_alpha_location = program->fragment_shader().alpha_location();
     shader_tex_transform_location =
         program->vertex_shader().tex_transform_location();
+    shader_backdrop_location = program->fragment_shader().backdrop_location();
+    shader_backdrop_rect_location =
+        program->fragment_shader().backdrop_rect_location();
   } else if (use_aa && !mask_texture_id && !use_color_matrix) {
     const RenderPassProgramAA* program =
-        GetRenderPassProgramAA(tex_coord_precision);
+        GetRenderPassProgramAA(tex_coord_precision, shader_blend_mode);
     SetUseProgram(program->program());
     GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
 
@@ -1260,9 +1245,13 @@
     shader_alpha_location = program->fragment_shader().alpha_location();
     shader_tex_transform_location =
         program->vertex_shader().tex_transform_location();
+    shader_backdrop_location = program->fragment_shader().backdrop_location();
+    shader_backdrop_rect_location =
+        program->fragment_shader().backdrop_rect_location();
   } else if (use_aa && mask_texture_id && use_color_matrix) {
     const RenderPassMaskColorMatrixProgramAA* program =
-        GetRenderPassMaskColorMatrixProgramAA(tex_coord_precision);
+        GetRenderPassMaskColorMatrixProgramAA(tex_coord_precision,
+                                              shader_blend_mode);
     SetUseProgram(program->program());
     GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
 
@@ -1283,9 +1272,13 @@
         program->fragment_shader().color_matrix_location();
     shader_color_offset_location =
         program->fragment_shader().color_offset_location();
+    shader_backdrop_location = program->fragment_shader().backdrop_location();
+    shader_backdrop_rect_location =
+        program->fragment_shader().backdrop_rect_location();
   } else if (use_aa && !mask_texture_id && use_color_matrix) {
     const RenderPassColorMatrixProgramAA* program =
-        GetRenderPassColorMatrixProgramAA(tex_coord_precision);
+        GetRenderPassColorMatrixProgramAA(tex_coord_precision,
+                                          shader_blend_mode);
     SetUseProgram(program->program());
     GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
 
@@ -1300,9 +1293,13 @@
         program->fragment_shader().color_matrix_location();
     shader_color_offset_location =
         program->fragment_shader().color_offset_location();
+    shader_backdrop_location = program->fragment_shader().backdrop_location();
+    shader_backdrop_rect_location =
+        program->fragment_shader().backdrop_rect_location();
   } else if (!use_aa && mask_texture_id && use_color_matrix) {
     const RenderPassMaskColorMatrixProgram* program =
-        GetRenderPassMaskColorMatrixProgram(tex_coord_precision);
+        GetRenderPassMaskColorMatrixProgram(tex_coord_precision,
+                                            shader_blend_mode);
     SetUseProgram(program->program());
     GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
 
@@ -1320,9 +1317,12 @@
         program->fragment_shader().color_matrix_location();
     shader_color_offset_location =
         program->fragment_shader().color_offset_location();
+    shader_backdrop_location = program->fragment_shader().backdrop_location();
+    shader_backdrop_rect_location =
+        program->fragment_shader().backdrop_rect_location();
   } else if (!use_aa && !mask_texture_id && use_color_matrix) {
     const RenderPassColorMatrixProgram* program =
-        GetRenderPassColorMatrixProgram(tex_coord_precision);
+        GetRenderPassColorMatrixProgram(tex_coord_precision, shader_blend_mode);
     SetUseProgram(program->program());
     GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
 
@@ -1334,9 +1334,12 @@
         program->fragment_shader().color_matrix_location();
     shader_color_offset_location =
         program->fragment_shader().color_offset_location();
+    shader_backdrop_location = program->fragment_shader().backdrop_location();
+    shader_backdrop_rect_location =
+        program->fragment_shader().backdrop_rect_location();
   } else {
     const RenderPassProgram* program =
-        GetRenderPassProgram(tex_coord_precision);
+        GetRenderPassProgram(tex_coord_precision, shader_blend_mode);
     SetUseProgram(program->program());
     GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
 
@@ -1344,6 +1347,9 @@
     shader_alpha_location = program->fragment_shader().alpha_location();
     shader_tex_transform_location =
         program->vertex_shader().tex_transform_location();
+    shader_backdrop_location = program->fragment_shader().backdrop_location();
+    shader_backdrop_rect_location =
+        program->fragment_shader().backdrop_rect_location();
   }
   float tex_scale_x =
       quad->rect.width() / static_cast<float>(contents_texture->size().width());
@@ -1363,6 +1369,7 @@
                      tex_scale_x,
                      -tex_scale_y));
 
+  GLint last_texture_unit = 0;
   scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_mask_sampler_lock;
   if (shader_mask_sampler_location != -1) {
     DCHECK_NE(shader_mask_tex_coord_scale_location, 1);
@@ -1383,6 +1390,8 @@
         gl_->Uniform2f(shader_mask_tex_coord_scale_location,
                        mask_uv_rect.width() / tex_scale_x,
                        -mask_uv_rect.height() / tex_scale_y));
+
+    last_texture_unit = 1;
   }
 
   if (shader_edge_location != -1) {
@@ -1418,6 +1427,37 @@
     GLC(gl_, gl_->Uniform4fv(shader_color_offset_location, 1, offset));
   }
 
+  scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_background_sampler_lock;
+  if (shader_backdrop_location != -1) {
+    DCHECK(background_texture || background_image);
+    DCHECK_NE(shader_backdrop_location, 0);
+    DCHECK_NE(shader_backdrop_rect_location, 0);
+
+    GLC(gl_, gl_->Uniform1i(shader_backdrop_location, ++last_texture_unit));
+
+    GLC(gl_,
+        gl_->Uniform4f(shader_backdrop_rect_location,
+                       background_rect.x(),
+                       background_rect.y(),
+                       background_rect.width(),
+                       background_rect.height()));
+
+    if (background_image) {
+      GrTexture* texture = background_image->getTexture();
+      GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0 + last_texture_unit));
+      gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle());
+      GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
+    } else {
+      shader_background_sampler_lock = make_scoped_ptr(
+          new ResourceProvider::ScopedSamplerGL(resource_provider_,
+                                                background_texture->id(),
+                                                GL_TEXTURE0 + last_texture_unit,
+                                                GL_LINEAR));
+      DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
+                shader_background_sampler_lock->target());
+    }
+  }
+
   // Map device space quad to surface space. contents_device_transform has no 3d
   // component since it was flattened, so we don't need to project.
   gfx::QuadF surface_quad = MathUtil::MapQuad(contents_device_transform_inverse,
@@ -2353,7 +2393,8 @@
   TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
       gl_, &highp_threshold_cache_, highp_threshold_min_, rect.bottom_right());
 
-  const RenderPassProgram* program = GetRenderPassProgram(tex_coord_precision);
+  const RenderPassProgram* program =
+      GetRenderPassProgram(tex_coord_precision, BlendModeNormal);
   SetUseProgram(program->program());
 
   GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
@@ -2832,112 +2873,155 @@
 }
 
 const GLRenderer::RenderPassProgram* GLRenderer::GetRenderPassProgram(
-    TexCoordPrecision precision) {
+    TexCoordPrecision precision,
+    BlendMode blend_mode) {
   DCHECK_GE(precision, 0);
   DCHECK_LT(precision, NumTexCoordPrecisions);
-  RenderPassProgram* program = &render_pass_program_[precision];
+  DCHECK_GE(blend_mode, 0);
+  DCHECK_LT(blend_mode, NumBlendModes);
+  RenderPassProgram* program = &render_pass_program_[precision][blend_mode];
   if (!program->initialized()) {
     TRACE_EVENT0("cc", "GLRenderer::renderPassProgram::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, SamplerType2D);
+    program->Initialize(output_surface_->context_provider(),
+                        precision,
+                        SamplerType2D,
+                        blend_mode);
   }
   return program;
 }
 
 const GLRenderer::RenderPassProgramAA* GLRenderer::GetRenderPassProgramAA(
-    TexCoordPrecision precision) {
+    TexCoordPrecision precision,
+    BlendMode blend_mode) {
   DCHECK_GE(precision, 0);
   DCHECK_LT(precision, NumTexCoordPrecisions);
-  RenderPassProgramAA* program = &render_pass_program_aa_[precision];
+  DCHECK_GE(blend_mode, 0);
+  DCHECK_LT(blend_mode, NumBlendModes);
+  RenderPassProgramAA* program =
+      &render_pass_program_aa_[precision][blend_mode];
   if (!program->initialized()) {
     TRACE_EVENT0("cc", "GLRenderer::renderPassProgramAA::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, SamplerType2D);
+    program->Initialize(output_surface_->context_provider(),
+                        precision,
+                        SamplerType2D,
+                        blend_mode);
   }
   return program;
 }
 
 const GLRenderer::RenderPassMaskProgram* GLRenderer::GetRenderPassMaskProgram(
-    TexCoordPrecision precision) {
+    TexCoordPrecision precision,
+    BlendMode blend_mode) {
   DCHECK_GE(precision, 0);
   DCHECK_LT(precision, NumTexCoordPrecisions);
-  RenderPassMaskProgram* program = &render_pass_mask_program_[precision];
+  DCHECK_GE(blend_mode, 0);
+  DCHECK_LT(blend_mode, NumBlendModes);
+  RenderPassMaskProgram* program =
+      &render_pass_mask_program_[precision][blend_mode];
   if (!program->initialized()) {
     TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgram::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, SamplerType2D);
+    program->Initialize(output_surface_->context_provider(),
+                        precision,
+                        SamplerType2D,
+                        blend_mode);
   }
   return program;
 }
 
 const GLRenderer::RenderPassMaskProgramAA*
-GLRenderer::GetRenderPassMaskProgramAA(TexCoordPrecision precision) {
+GLRenderer::GetRenderPassMaskProgramAA(TexCoordPrecision precision,
+                                       BlendMode blend_mode) {
   DCHECK_GE(precision, 0);
   DCHECK_LT(precision, NumTexCoordPrecisions);
-  RenderPassMaskProgramAA* program = &render_pass_mask_program_aa_[precision];
+  DCHECK_GE(blend_mode, 0);
+  DCHECK_LT(blend_mode, NumBlendModes);
+  RenderPassMaskProgramAA* program =
+      &render_pass_mask_program_aa_[precision][blend_mode];
   if (!program->initialized()) {
     TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgramAA::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, SamplerType2D);
+    program->Initialize(output_surface_->context_provider(),
+                        precision,
+                        SamplerType2D,
+                        blend_mode);
   }
   return program;
 }
 
 const GLRenderer::RenderPassColorMatrixProgram*
-GLRenderer::GetRenderPassColorMatrixProgram(TexCoordPrecision precision) {
+GLRenderer::GetRenderPassColorMatrixProgram(TexCoordPrecision precision,
+                                            BlendMode blend_mode) {
   DCHECK_GE(precision, 0);
   DCHECK_LT(precision, NumTexCoordPrecisions);
+  DCHECK_GE(blend_mode, 0);
+  DCHECK_LT(blend_mode, NumBlendModes);
   RenderPassColorMatrixProgram* program =
-      &render_pass_color_matrix_program_[precision];
+      &render_pass_color_matrix_program_[precision][blend_mode];
   if (!program->initialized()) {
     TRACE_EVENT0("cc", "GLRenderer::renderPassColorMatrixProgram::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, SamplerType2D);
+    program->Initialize(output_surface_->context_provider(),
+                        precision,
+                        SamplerType2D,
+                        blend_mode);
   }
   return program;
 }
 
 const GLRenderer::RenderPassColorMatrixProgramAA*
-GLRenderer::GetRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
+GLRenderer::GetRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
+                                              BlendMode blend_mode) {
   DCHECK_GE(precision, 0);
   DCHECK_LT(precision, NumTexCoordPrecisions);
+  DCHECK_GE(blend_mode, 0);
+  DCHECK_LT(blend_mode, NumBlendModes);
   RenderPassColorMatrixProgramAA* program =
-      &render_pass_color_matrix_program_aa_[precision];
+      &render_pass_color_matrix_program_aa_[precision][blend_mode];
   if (!program->initialized()) {
     TRACE_EVENT0("cc",
                  "GLRenderer::renderPassColorMatrixProgramAA::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, SamplerType2D);
+    program->Initialize(output_surface_->context_provider(),
+                        precision,
+                        SamplerType2D,
+                        blend_mode);
   }
   return program;
 }
 
 const GLRenderer::RenderPassMaskColorMatrixProgram*
-GLRenderer::GetRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
+GLRenderer::GetRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
+                                                BlendMode blend_mode) {
   DCHECK_GE(precision, 0);
   DCHECK_LT(precision, NumTexCoordPrecisions);
+  DCHECK_GE(blend_mode, 0);
+  DCHECK_LT(blend_mode, NumBlendModes);
   RenderPassMaskColorMatrixProgram* program =
-      &render_pass_mask_color_matrix_program_[precision];
+      &render_pass_mask_color_matrix_program_[precision][blend_mode];
   if (!program->initialized()) {
     TRACE_EVENT0("cc",
                  "GLRenderer::renderPassMaskColorMatrixProgram::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, SamplerType2D);
+    program->Initialize(output_surface_->context_provider(),
+                        precision,
+                        SamplerType2D,
+                        blend_mode);
   }
   return program;
 }
 
 const GLRenderer::RenderPassMaskColorMatrixProgramAA*
-GLRenderer::GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
+GLRenderer::GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
+                                                  BlendMode blend_mode) {
   DCHECK_GE(precision, 0);
   DCHECK_LT(precision, NumTexCoordPrecisions);
+  DCHECK_GE(blend_mode, 0);
+  DCHECK_LT(blend_mode, NumBlendModes);
   RenderPassMaskColorMatrixProgramAA* program =
-      &render_pass_mask_color_matrix_program_aa_[precision];
+      &render_pass_mask_color_matrix_program_aa_[precision][blend_mode];
   if (!program->initialized()) {
     TRACE_EVENT0("cc",
                  "GLRenderer::renderPassMaskColorMatrixProgramAA::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, SamplerType2D);
+    program->Initialize(output_surface_->context_provider(),
+                        precision,
+                        SamplerType2D,
+                        blend_mode);
   }
   return program;
 }
@@ -3163,15 +3247,16 @@
       tile_program_aa_[i][j].Cleanup(gl_);
       tile_program_swizzle_aa_[i][j].Cleanup(gl_);
     }
-
-    render_pass_mask_program_[i].Cleanup(gl_);
-    render_pass_program_[i].Cleanup(gl_);
-    render_pass_mask_program_aa_[i].Cleanup(gl_);
-    render_pass_program_aa_[i].Cleanup(gl_);
-    render_pass_color_matrix_program_[i].Cleanup(gl_);
-    render_pass_mask_color_matrix_program_aa_[i].Cleanup(gl_);
-    render_pass_color_matrix_program_aa_[i].Cleanup(gl_);
-    render_pass_mask_color_matrix_program_[i].Cleanup(gl_);
+    for (int j = 0; j < NumBlendModes; j++) {
+      render_pass_mask_program_[i][j].Cleanup(gl_);
+      render_pass_program_[i][j].Cleanup(gl_);
+      render_pass_mask_program_aa_[i][j].Cleanup(gl_);
+      render_pass_program_aa_[i][j].Cleanup(gl_);
+      render_pass_color_matrix_program_[i][j].Cleanup(gl_);
+      render_pass_mask_color_matrix_program_aa_[i][j].Cleanup(gl_);
+      render_pass_color_matrix_program_aa_[i][j].Cleanup(gl_);
+      render_pass_mask_color_matrix_program_[i][j].Cleanup(gl_);
+    }
 
     texture_program_[i].Cleanup(gl_);
     nonpremultiplied_texture_program_[i].Cleanup(gl_);
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index a379dc0..625d458 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -153,7 +153,8 @@
   gfx::Rect GetBackdropBoundingBoxForRenderPassQuad(
       DrawingFrame* frame,
       const RenderPassDrawQuad* quad,
-      const gfx::Transform& contents_device_transform);
+      const gfx::Transform& contents_device_transform,
+      bool use_aa);
   scoped_ptr<ScopedResource> GetBackdropTexture(const gfx::Rect& bounding_rect);
 
   static bool ShouldApplyBackgroundFilters(DrawingFrame* frame,
@@ -166,7 +167,6 @@
       DrawingFrame* frame,
       const RenderPassDrawQuad* quad,
       const gfx::Transform& contents_device_transform_inverse,
-      ScopedResource* background_texture,
       skia::RefPtr<SkImage> backdrop_bitmap,
       const gfx::Rect& backdrop_bounding_rect);
 
@@ -328,22 +328,28 @@
 
   const TileCheckerboardProgram* GetTileCheckerboardProgram();
 
-  const RenderPassProgram* GetRenderPassProgram(
-      TexCoordPrecision precision);
-  const RenderPassProgramAA* GetRenderPassProgramAA(
-      TexCoordPrecision precision);
+  const RenderPassProgram* GetRenderPassProgram(TexCoordPrecision precision,
+                                                BlendMode blend_mode);
+  const RenderPassProgramAA* GetRenderPassProgramAA(TexCoordPrecision precision,
+                                                    BlendMode blend_mode);
   const RenderPassMaskProgram* GetRenderPassMaskProgram(
-      TexCoordPrecision precision);
+      TexCoordPrecision precision,
+      BlendMode blend_mode);
   const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA(
-      TexCoordPrecision precision);
+      TexCoordPrecision precision,
+      BlendMode blend_mode);
   const RenderPassColorMatrixProgram* GetRenderPassColorMatrixProgram(
-      TexCoordPrecision precision);
+      TexCoordPrecision precision,
+      BlendMode blend_mode);
   const RenderPassColorMatrixProgramAA* GetRenderPassColorMatrixProgramAA(
-      TexCoordPrecision precision);
+      TexCoordPrecision precision,
+      BlendMode blend_mode);
   const RenderPassMaskColorMatrixProgram* GetRenderPassMaskColorMatrixProgram(
-      TexCoordPrecision precision);
+      TexCoordPrecision precision,
+      BlendMode blend_mode);
   const RenderPassMaskColorMatrixProgramAA*
-      GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision);
+  GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
+                                        BlendMode blend_mode);
 
   const TextureProgram* GetTextureProgram(
       TexCoordPrecision precision);
@@ -388,18 +394,21 @@
       nonpremultiplied_texture_background_program_[NumTexCoordPrecisions];
   TextureProgram texture_io_surface_program_[NumTexCoordPrecisions];
 
-  RenderPassProgram render_pass_program_[NumTexCoordPrecisions];
-  RenderPassProgramAA render_pass_program_aa_[NumTexCoordPrecisions];
-  RenderPassMaskProgram render_pass_mask_program_[NumTexCoordPrecisions];
-  RenderPassMaskProgramAA render_pass_mask_program_aa_[NumTexCoordPrecisions];
+  RenderPassProgram render_pass_program_[NumTexCoordPrecisions][NumBlendModes];
+  RenderPassProgramAA
+      render_pass_program_aa_[NumTexCoordPrecisions][NumBlendModes];
+  RenderPassMaskProgram
+      render_pass_mask_program_[NumTexCoordPrecisions][NumBlendModes];
+  RenderPassMaskProgramAA
+      render_pass_mask_program_aa_[NumTexCoordPrecisions][NumBlendModes];
   RenderPassColorMatrixProgram
-      render_pass_color_matrix_program_[NumTexCoordPrecisions];
-  RenderPassColorMatrixProgramAA
-      render_pass_color_matrix_program_aa_[NumTexCoordPrecisions];
-  RenderPassMaskColorMatrixProgram
-      render_pass_mask_color_matrix_program_[NumTexCoordPrecisions];
-  RenderPassMaskColorMatrixProgramAA
-      render_pass_mask_color_matrix_program_aa_[NumTexCoordPrecisions];
+      render_pass_color_matrix_program_[NumTexCoordPrecisions][NumBlendModes];
+  RenderPassColorMatrixProgramAA render_pass_color_matrix_program_aa_
+      [NumTexCoordPrecisions][NumBlendModes];
+  RenderPassMaskColorMatrixProgram render_pass_mask_color_matrix_program_
+      [NumTexCoordPrecisions][NumBlendModes];
+  RenderPassMaskColorMatrixProgramAA render_pass_mask_color_matrix_program_aa_
+      [NumTexCoordPrecisions][NumBlendModes];
 
   VideoYUVProgram video_yuv_program_[NumTexCoordPrecisions];
   VideoYUVAProgram video_yuva_program_[NumTexCoordPrecisions];
@@ -440,6 +449,8 @@
   scoped_ptr<SyncQuery> current_sync_query_;
   bool use_sync_query_;
   bool use_blend_minmax_;
+  bool use_blend_equation_advanced_;
+  bool use_blend_equation_advanced_coherent_;
 
   SkBitmap on_demand_tile_raster_bitmap_;
   ResourceProvider::ResourceId on_demand_tile_raster_resource_id_;
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index 42e4b5e..8de90c4 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -55,6 +55,44 @@
     EXPECT_TRUE((program_binding)->initialized()); \
   } while (false)
 
+static inline SkXfermode::Mode BlendModeToSkXfermode(BlendMode blend_mode) {
+  switch (blend_mode) {
+    case BlendModeNormal:
+      return SkXfermode::kSrcOver_Mode;
+    case BlendModeOverlay:
+      return SkXfermode::kOverlay_Mode;
+    case BlendModeDarken:
+      return SkXfermode::kDarken_Mode;
+    case BlendModeLighten:
+      return SkXfermode::kLighten_Mode;
+    case BlendModeColorDodge:
+      return SkXfermode::kColorDodge_Mode;
+    case BlendModeColorBurn:
+      return SkXfermode::kColorBurn_Mode;
+    case BlendModeHardLight:
+      return SkXfermode::kHardLight_Mode;
+    case BlendModeSoftLight:
+      return SkXfermode::kSoftLight_Mode;
+    case BlendModeDifference:
+      return SkXfermode::kDifference_Mode;
+    case BlendModeExclusion:
+      return SkXfermode::kExclusion_Mode;
+    case BlendModeMultiply:
+      return SkXfermode::kMultiply_Mode;
+    case BlendModeHue:
+      return SkXfermode::kHue_Mode;
+    case BlendModeSaturation:
+      return SkXfermode::kSaturation_Mode;
+    case BlendModeColor:
+      return SkXfermode::kColor_Mode;
+    case BlendModeLuminosity:
+      return SkXfermode::kLuminosity_Mode;
+    case NumBlendModes:
+      NOTREACHED();
+  }
+  return SkXfermode::kSrcOver_Mode;
+}
+
 // Explicitly named to be a friend in GLRenderer for shader access.
 class GLRendererShaderPixelTest : public GLRendererPixelTest {
  public:
@@ -70,18 +108,25 @@
   }
 
   void TestShadersWithTexCoordPrecision(TexCoordPrecision precision) {
-    EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgram(precision));
-    EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgramAA(precision));
-    EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(precision));
-    EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(precision));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetRenderPassColorMatrixProgram(precision));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetRenderPassMaskColorMatrixProgramAA(precision));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetRenderPassColorMatrixProgramAA(precision));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetRenderPassMaskColorMatrixProgram(precision));
+    for (int i = 0; i < NumBlendModes; ++i) {
+      BlendMode blend_mode = static_cast<BlendMode>(i);
+      EXPECT_PROGRAM_VALID(
+          renderer()->GetRenderPassProgram(precision, blend_mode));
+      EXPECT_PROGRAM_VALID(
+          renderer()->GetRenderPassProgramAA(precision, blend_mode));
+      EXPECT_PROGRAM_VALID(
+          renderer()->GetRenderPassMaskProgram(precision, blend_mode));
+      EXPECT_PROGRAM_VALID(
+          renderer()->GetRenderPassMaskProgramAA(precision, blend_mode));
+      EXPECT_PROGRAM_VALID(
+          renderer()->GetRenderPassColorMatrixProgram(precision, blend_mode));
+      EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
+          precision, blend_mode));
+      EXPECT_PROGRAM_VALID(
+          renderer()->GetRenderPassColorMatrixProgramAA(precision, blend_mode));
+      EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
+          precision, blend_mode));
+    }
     EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision));
     EXPECT_PROGRAM_VALID(
         renderer()->GetNonPremultipliedTextureProgram(precision));
@@ -159,8 +204,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false).Pass();
+                                                  1).Pass();
     renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
                                                    &settings_,
                                                    output_surface_.get(),
@@ -196,69 +240,91 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false).Pass();
+                                                  1).Pass();
     renderer_.reset(new FakeRendererGL(&renderer_client_,
                                        &settings_,
                                        output_surface_.get(),
                                        resource_provider_.get()));
   }
 
-  void TestRenderPassProgram(TexCoordPrecision precision) {
-    EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_[precision]);
-    EXPECT_EQ(renderer_->render_pass_program_[precision].program(),
-              renderer_->program_shadow_);
-  }
-
-  void TestRenderPassColorMatrixProgram(TexCoordPrecision precision) {
+  void TestRenderPassProgram(TexCoordPrecision precision,
+                             BlendMode blend_mode) {
     EXPECT_PROGRAM_VALID(
-        &renderer_->render_pass_color_matrix_program_[precision]);
-    EXPECT_EQ(renderer_->render_pass_color_matrix_program_[precision].program(),
+        &renderer_->render_pass_program_[precision][blend_mode]);
+    EXPECT_EQ(renderer_->render_pass_program_[precision][blend_mode].program(),
               renderer_->program_shadow_);
   }
 
-  void TestRenderPassMaskProgram(TexCoordPrecision precision) {
-    EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_[precision]);
-    EXPECT_EQ(renderer_->render_pass_mask_program_[precision].program(),
-              renderer_->program_shadow_);
-  }
-
-  void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
+  void TestRenderPassColorMatrixProgram(TexCoordPrecision precision,
+                                        BlendMode blend_mode) {
     EXPECT_PROGRAM_VALID(
-        &renderer_->render_pass_mask_color_matrix_program_[precision]);
+        &renderer_->render_pass_color_matrix_program_[precision][blend_mode]);
     EXPECT_EQ(
-        renderer_->render_pass_mask_color_matrix_program_[precision].program(),
+        renderer_->render_pass_color_matrix_program_[precision][blend_mode]
+            .program(),
         renderer_->program_shadow_);
   }
 
-  void TestRenderPassProgramAA(TexCoordPrecision precision) {
-    EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_aa_[precision]);
-    EXPECT_EQ(renderer_->render_pass_program_aa_[precision].program(),
-              renderer_->program_shadow_);
-  }
-
-  void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
+  void TestRenderPassMaskProgram(TexCoordPrecision precision,
+                                 BlendMode blend_mode) {
     EXPECT_PROGRAM_VALID(
-        &renderer_->render_pass_color_matrix_program_aa_[precision]);
+        &renderer_->render_pass_mask_program_[precision][blend_mode]);
     EXPECT_EQ(
-        renderer_->render_pass_color_matrix_program_aa_[precision].program(),
+        renderer_->render_pass_mask_program_[precision][blend_mode].program(),
         renderer_->program_shadow_);
   }
 
-  void TestRenderPassMaskProgramAA(TexCoordPrecision precision) {
-    EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_aa_[precision]);
-    EXPECT_EQ(renderer_->render_pass_mask_program_aa_[precision].program(),
-              renderer_->program_shadow_);
+  void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
+                                            BlendMode blend_mode) {
+    EXPECT_PROGRAM_VALID(
+        &renderer_
+             ->render_pass_mask_color_matrix_program_[precision][blend_mode]);
+    EXPECT_EQ(
+        renderer_->render_pass_mask_color_matrix_program_[precision][blend_mode]
+            .program(),
+        renderer_->program_shadow_);
   }
 
-  void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
+  void TestRenderPassProgramAA(TexCoordPrecision precision,
+                               BlendMode blend_mode) {
     EXPECT_PROGRAM_VALID(
-        &renderer_->render_pass_mask_color_matrix_program_aa_[precision]);
-    EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_[precision]
+        &renderer_->render_pass_program_aa_[precision][blend_mode]);
+    EXPECT_EQ(
+        renderer_->render_pass_program_aa_[precision][blend_mode].program(),
+        renderer_->program_shadow_);
+  }
+
+  void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
+                                          BlendMode blend_mode) {
+    EXPECT_PROGRAM_VALID(
+        &renderer_
+             ->render_pass_color_matrix_program_aa_[precision][blend_mode]);
+    EXPECT_EQ(
+        renderer_->render_pass_color_matrix_program_aa_[precision][blend_mode]
+            .program(),
+        renderer_->program_shadow_);
+  }
+
+  void TestRenderPassMaskProgramAA(TexCoordPrecision precision,
+                                   BlendMode blend_mode) {
+    EXPECT_PROGRAM_VALID(
+        &renderer_->render_pass_mask_program_aa_[precision][blend_mode]);
+    EXPECT_EQ(renderer_->render_pass_mask_program_aa_[precision][blend_mode]
                   .program(),
               renderer_->program_shadow_);
   }
 
+  void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
+                                              BlendMode blend_mode) {
+    EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_aa_
+                              [precision][blend_mode]);
+    EXPECT_EQ(
+        renderer_
+            ->render_pass_mask_color_matrix_program_aa_[precision][blend_mode]
+            .program(),
+        renderer_->program_shadow_);
+  }
+
   void TestSolidColorProgramAA() {
     EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
     EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
@@ -470,8 +536,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -511,8 +576,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -551,8 +615,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -604,8 +667,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -650,8 +712,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -736,8 +797,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -808,8 +868,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -900,8 +959,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   settings.should_clear_root_render_pass = false;
@@ -999,8 +1057,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -1098,8 +1155,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   settings.partial_swap_enabled = true;
@@ -1288,8 +1344,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   LayerTreeSettings settings;
   FakeRendererClient renderer_client;
@@ -1361,191 +1416,224 @@
   gfx::Transform transform_causing_aa;
   transform_causing_aa.Rotate(20.0);
 
-  // RenderPassProgram
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             gfx::Transform());
+  for (int i = 0; i < NumBlendModes; ++i) {
+    BlendMode blend_mode = static_cast<BlendMode>(i);
+    SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
+    // RenderPassProgram
+    render_passes_in_draw_order_.clear();
+    child_pass = AddRenderPass(&render_passes_in_draw_order_,
+                               child_pass_id,
+                               child_rect,
+                               gfx::Transform());
 
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
+    root_pass = AddRenderPass(&render_passes_in_draw_order_,
+                              root_pass_id,
+                              viewport_rect,
+                              gfx::Transform());
 
-  AddRenderPassQuad(
-      root_pass, child_pass, 0, FilterOperations(), gfx::Transform());
+    AddRenderPassQuad(root_pass,
+                      child_pass,
+                      0,
+                      FilterOperations(),
+                      gfx::Transform(),
+                      xfer_mode);
 
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  TestRenderPassProgram(TexCoordPrecisionMedium);
+    renderer_->DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+    renderer_->DrawFrame(&render_passes_in_draw_order_,
+                         1.f,
+                         viewport_rect,
+                         viewport_rect,
+                         false);
+    TestRenderPassProgram(TexCoordPrecisionMedium, blend_mode);
 
-  // RenderPassColorMatrixProgram
-  render_passes_in_draw_order_.clear();
+    // RenderPassColorMatrixProgram
+    render_passes_in_draw_order_.clear();
 
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             transform_causing_aa);
+    child_pass = AddRenderPass(&render_passes_in_draw_order_,
+                               child_pass_id,
+                               child_rect,
+                               transform_causing_aa);
 
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
+    root_pass = AddRenderPass(&render_passes_in_draw_order_,
+                              root_pass_id,
+                              viewport_rect,
+                              gfx::Transform());
 
-  AddRenderPassQuad(root_pass, child_pass, 0, filters, gfx::Transform());
+    AddRenderPassQuad(
+        root_pass, child_pass, 0, filters, gfx::Transform(), xfer_mode);
 
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium);
+    renderer_->DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+    renderer_->DrawFrame(&render_passes_in_draw_order_,
+                         1.f,
+                         viewport_rect,
+                         viewport_rect,
+                         false);
+    TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium, blend_mode);
 
-  // RenderPassMaskProgram
-  render_passes_in_draw_order_.clear();
+    // RenderPassMaskProgram
+    render_passes_in_draw_order_.clear();
 
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             gfx::Transform());
+    child_pass = AddRenderPass(&render_passes_in_draw_order_,
+                               child_pass_id,
+                               child_rect,
+                               gfx::Transform());
 
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
+    root_pass = AddRenderPass(&render_passes_in_draw_order_,
+                              root_pass_id,
+                              viewport_rect,
+                              gfx::Transform());
 
-  AddRenderPassQuad(
-      root_pass, child_pass, mask, FilterOperations(), gfx::Transform());
+    AddRenderPassQuad(root_pass,
+                      child_pass,
+                      mask,
+                      FilterOperations(),
+                      gfx::Transform(),
+                      xfer_mode);
 
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  TestRenderPassMaskProgram(TexCoordPrecisionMedium);
+    renderer_->DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+    renderer_->DrawFrame(&render_passes_in_draw_order_,
+                         1.f,
+                         viewport_rect,
+                         viewport_rect,
+                         false);
+    TestRenderPassMaskProgram(TexCoordPrecisionMedium, blend_mode);
 
-  // RenderPassMaskColorMatrixProgram
-  render_passes_in_draw_order_.clear();
+    // RenderPassMaskColorMatrixProgram
+    render_passes_in_draw_order_.clear();
 
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             gfx::Transform());
+    child_pass = AddRenderPass(&render_passes_in_draw_order_,
+                               child_pass_id,
+                               child_rect,
+                               gfx::Transform());
 
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
+    root_pass = AddRenderPass(&render_passes_in_draw_order_,
+                              root_pass_id,
+                              viewport_rect,
+                              gfx::Transform());
 
-  AddRenderPassQuad(root_pass, child_pass, mask, filters, gfx::Transform());
+    AddRenderPassQuad(
+        root_pass, child_pass, mask, filters, gfx::Transform(), xfer_mode);
 
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium);
+    renderer_->DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+    renderer_->DrawFrame(&render_passes_in_draw_order_,
+                         1.f,
+                         viewport_rect,
+                         viewport_rect,
+                         false);
+    TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium, blend_mode);
 
-  // RenderPassProgramAA
-  render_passes_in_draw_order_.clear();
+    // RenderPassProgramAA
+    render_passes_in_draw_order_.clear();
 
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             transform_causing_aa);
+    child_pass = AddRenderPass(&render_passes_in_draw_order_,
+                               child_pass_id,
+                               child_rect,
+                               transform_causing_aa);
 
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
+    root_pass = AddRenderPass(&render_passes_in_draw_order_,
+                              root_pass_id,
+                              viewport_rect,
+                              gfx::Transform());
 
-  AddRenderPassQuad(
-      root_pass, child_pass, 0, FilterOperations(), transform_causing_aa);
+    AddRenderPassQuad(root_pass,
+                      child_pass,
+                      0,
+                      FilterOperations(),
+                      transform_causing_aa,
+                      xfer_mode);
 
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  TestRenderPassProgramAA(TexCoordPrecisionMedium);
+    renderer_->DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+    renderer_->DrawFrame(&render_passes_in_draw_order_,
+                         1.f,
+                         viewport_rect,
+                         viewport_rect,
+                         false);
+    TestRenderPassProgramAA(TexCoordPrecisionMedium, blend_mode);
 
-  // RenderPassColorMatrixProgramAA
-  render_passes_in_draw_order_.clear();
+    // RenderPassColorMatrixProgramAA
+    render_passes_in_draw_order_.clear();
 
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             transform_causing_aa);
+    child_pass = AddRenderPass(&render_passes_in_draw_order_,
+                               child_pass_id,
+                               child_rect,
+                               transform_causing_aa);
 
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
+    root_pass = AddRenderPass(&render_passes_in_draw_order_,
+                              root_pass_id,
+                              viewport_rect,
+                              gfx::Transform());
 
-  AddRenderPassQuad(root_pass, child_pass, 0, filters, transform_causing_aa);
+    AddRenderPassQuad(
+        root_pass, child_pass, 0, filters, transform_causing_aa, xfer_mode);
 
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium);
+    renderer_->DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+    renderer_->DrawFrame(&render_passes_in_draw_order_,
+                         1.f,
+                         viewport_rect,
+                         viewport_rect,
+                         false);
+    TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium, blend_mode);
 
-  // RenderPassMaskProgramAA
-  render_passes_in_draw_order_.clear();
+    // RenderPassMaskProgramAA
+    render_passes_in_draw_order_.clear();
 
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             transform_causing_aa);
+    child_pass = AddRenderPass(&render_passes_in_draw_order_,
+                               child_pass_id,
+                               child_rect,
+                               transform_causing_aa);
 
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
+    root_pass = AddRenderPass(&render_passes_in_draw_order_,
+                              root_pass_id,
+                              viewport_rect,
+                              gfx::Transform());
 
-  AddRenderPassQuad(
-      root_pass, child_pass, mask, FilterOperations(), transform_causing_aa);
+    AddRenderPassQuad(root_pass,
+                      child_pass,
+                      mask,
+                      FilterOperations(),
+                      transform_causing_aa,
+                      xfer_mode);
 
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  TestRenderPassMaskProgramAA(TexCoordPrecisionMedium);
+    renderer_->DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+    renderer_->DrawFrame(&render_passes_in_draw_order_,
+                         1.f,
+                         viewport_rect,
+                         viewport_rect,
+                         false);
+    TestRenderPassMaskProgramAA(TexCoordPrecisionMedium, blend_mode);
 
-  // RenderPassMaskColorMatrixProgramAA
-  render_passes_in_draw_order_.clear();
+    // RenderPassMaskColorMatrixProgramAA
+    render_passes_in_draw_order_.clear();
 
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             transform_causing_aa);
+    child_pass = AddRenderPass(&render_passes_in_draw_order_,
+                               child_pass_id,
+                               child_rect,
+                               transform_causing_aa);
 
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            transform_causing_aa);
+    root_pass = AddRenderPass(&render_passes_in_draw_order_,
+                              root_pass_id,
+                              viewport_rect,
+                              transform_causing_aa);
 
-  AddRenderPassQuad(root_pass, child_pass, mask, filters, transform_causing_aa);
+    AddRenderPassQuad(
+        root_pass, child_pass, mask, filters, transform_causing_aa, xfer_mode);
 
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium);
+    renderer_->DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+    renderer_->DrawFrame(&render_passes_in_draw_order_,
+                         1.f,
+                         viewport_rect,
+                         viewport_rect,
+                         false);
+    TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium, blend_mode);
+  }
 }
 
 // At this time, the AA code path cannot be taken if the surface's rect would
@@ -1580,8 +1668,12 @@
                             viewport_rect,
                             gfx::Transform());
 
-  AddRenderPassQuad(
-      root_pass, child_pass, 0, FilterOperations(), transform_preventing_aa);
+  AddRenderPassQuad(root_pass,
+                    child_pass,
+                    0,
+                    FilterOperations(),
+                    transform_preventing_aa,
+                    SkXfermode::kSrcOver_Mode);
 
   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   renderer_->DrawFrame(&render_passes_in_draw_order_,
@@ -1592,7 +1684,7 @@
 
   // If use_aa incorrectly ignores clipping, it will use the
   // RenderPassProgramAA shader instead of the RenderPassProgram.
-  TestRenderPassProgram(TexCoordPrecisionMedium);
+  TestRenderPassProgram(TexCoordPrecisionMedium, BlendModeNormal);
 }
 
 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
@@ -1668,8 +1760,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false).Pass();
+                                                  1).Pass();
 
     renderer_.reset(new FakeRendererGL(&renderer_client_,
                                        &settings_,
diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h
index bb37a91..99b174b 100644
--- a/cc/output/output_surface_client.h
+++ b/cc/output/output_surface_client.h
@@ -11,7 +11,7 @@
 #include "cc/base/cc_export.h"
 #include "cc/output/begin_frame_args.h"
 #include "cc/output/context_provider.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace gfx {
 class Transform;
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index 92b19c7..8b7dc2a8 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -244,15 +244,8 @@
 
   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
       new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(&output_surface,
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1,
-                               false));
+  scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+      &output_surface, shared_bitmap_manager.get(), NULL, NULL, 0, false, 1));
 
   scoped_ptr<DefaultOverlayProcessor> overlay_processor(
       new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
@@ -276,8 +269,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false);
+                                                  1);
 
     overlay_processor_.reset(new SingleOverlayProcessor(
         output_surface_.get(), resource_provider_.get()));
@@ -588,7 +580,7 @@
     output_surface_.reset(new OverlayOutputSurface(provider_));
     CHECK(output_surface_->BindToClient(&output_surface_client_));
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), NULL, NULL, NULL, 0, false, 1, false);
+        output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
 
     provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
         &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
diff --git a/cc/output/program_binding.h b/cc/output/program_binding.h
index 912329ef..722c782 100644
--- a/cc/output/program_binding.h
+++ b/cc/output/program_binding.h
@@ -58,13 +58,16 @@
 
   void Initialize(ContextProvider* context_provider,
                   TexCoordPrecision precision,
-                  SamplerType sampler) {
+                  SamplerType sampler,
+                  BlendMode blend_mode = BlendModeNormal) {
     DCHECK(context_provider);
     DCHECK(!initialized_);
 
     if (context_provider->IsContextLost())
       return;
 
+    fragment_shader_.set_blend_mode(blend_mode);
+
     if (!ProgramBindingBase::Init(
             context_provider->ContextGL(),
             vertex_shader_.GetShaderString(),
diff --git a/cc/output/renderer_unittest.cc b/cc/output/renderer_unittest.cc
index 229558d..6e43cc0 100644
--- a/cc/output/renderer_unittest.cc
+++ b/cc/output/renderer_unittest.cc
@@ -83,7 +83,7 @@
     output_surface_.reset(new TestOutputSurface(context_provider_));
     output_surface_->BindToClient(&output_surface_client_);
     resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), NULL, NULL, NULL, 0, false, 1, false);
+        output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
     renderer_ = CreateRenderer<T>(&renderer_client_,
                                   &tree_settings_,
                                   output_surface_.get(),
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index 8a25214..b2d76a7e 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -13,9 +13,10 @@
 
 #define SHADER0(Src) #Src
 #define VERTEX_SHADER(Src) SetVertexTexCoordPrecision(SHADER0(Src))
-#define FRAGMENT_SHADER(Src)              \
-  SetFragmentTexCoordPrecision(precision, \
-                               SetFragmentSamplerType(sampler, SHADER0(Src)))
+#define FRAGMENT_SHADER(Src)    \
+  SetFragmentTexCoordPrecision( \
+      precision,                \
+      SetFragmentSamplerType(sampler, SetBlendModeFunctions(SHADER0(Src))))
 
 using gpu::gles2::GLES2Interface;
 
@@ -666,6 +667,308 @@
   // clang-format on
 }
 
+#define BLEND_MODE_UNIFORMS "s_backdropTexture", "backdropRect"
+#define UNUSED_BLEND_MODE_UNIFORMS (is_default_blend_mode() ? 2 : 0)
+#define BLEND_MODE_SET_LOCATIONS(X, POS)                   \
+  if (!is_default_blend_mode()) {                          \
+    DCHECK_LT(static_cast<size_t>(POS) + 1, arraysize(X)); \
+    backdrop_location_ = locations[POS];                   \
+    backdrop_rect_location_ = locations[POS + 1];          \
+  }
+
+FragmentTexBlendMode::FragmentTexBlendMode()
+    : backdrop_location_(-1),
+      backdrop_rect_location_(-1),
+      blend_mode_(BlendModeNormal) {
+}
+
+std::string FragmentTexBlendMode::SetBlendModeFunctions(
+    std::string shader_string) const {
+  if (shader_string.find("ApplyBlendMode") == std::string::npos)
+    return shader_string;
+
+  if (is_default_blend_mode()) {
+    return "#define ApplyBlendMode(X) (X)\n" + shader_string;
+  }
+
+  // clang-format off
+  static const std::string kFunctionApplyBlendMode = SHADER0(
+      // clang-format on
+      uniform SamplerType s_backdropTexture;
+      uniform TexCoordPrecision vec4 backdropRect;
+
+      vec4 GetBackdropColor() {
+        TexCoordPrecision vec2 bgTexCoord = gl_FragCoord.xy - backdropRect.xy;
+        bgTexCoord.x /= backdropRect.z;
+        bgTexCoord.y /= backdropRect.w;
+        return TextureLookup(s_backdropTexture, bgTexCoord);
+      }
+
+      vec4 ApplyBlendMode(vec4 src) {
+        vec4 dst = GetBackdropColor();
+        return Blend(src, dst);
+      }
+      // clang-format off
+  );  // NOLINT(whitespace/parens)
+  // clang-format on
+
+  return "precision mediump float;" + GetHelperFunctions() +
+         GetBlendFunction() + kFunctionApplyBlendMode + shader_string;
+}
+
+std::string FragmentTexBlendMode::GetHelperFunctions() const {
+  // clang-format off
+  static const std::string kFunctionHardLight = SHADER0(
+      // clang-format on
+      vec3 hardLight(vec4 src, vec4 dst) {
+        vec3 result;
+        result.r =
+            (2.0 * src.r <= src.a)
+                ? (2.0 * src.r * dst.r)
+                : (src.a * dst.a - 2.0 * (dst.a - dst.r) * (src.a - src.r));
+        result.g =
+            (2.0 * src.g <= src.a)
+                ? (2.0 * src.g * dst.g)
+                : (src.a * dst.a - 2.0 * (dst.a - dst.g) * (src.a - src.g));
+        result.b =
+            (2.0 * src.b <= src.a)
+                ? (2.0 * src.b * dst.b)
+                : (src.a * dst.a - 2.0 * (dst.a - dst.b) * (src.a - src.b));
+        result.rgb += src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
+        return result;
+      }
+      // clang-format off
+  );  // NOLINT(whitespace/parens)
+
+  static const std::string kFunctionColorDodgeComponent = SHADER0(
+      // clang-format on
+      float getColorDodgeComponent(
+          float srcc, float srca, float dstc, float dsta) {
+        if (0.0 == dstc)
+          return srcc * (1.0 - dsta);
+        float d = srca - srcc;
+        if (0.0 == d)
+          return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
+        d = min(dsta, dstc * srca / d);
+        return d * srca + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
+      }
+      // clang-format off
+  );  // NOLINT(whitespace/parens)
+
+  static const std::string kFunctionColorBurnComponent = SHADER0(
+      // clang-format on
+      float getColorBurnComponent(
+          float srcc, float srca, float dstc, float dsta) {
+        if (dsta == dstc)
+          return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
+        if (0.0 == srcc)
+          return dstc * (1.0 - srca);
+        float d = max(0.0, dsta - (dsta - dstc) * srca / srcc);
+        return srca * d + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
+      }
+      // clang-format off
+  );  // NOLINT(whitespace/parens)
+
+  static const std::string kFunctionSoftLightComponentPosDstAlpha = SHADER0(
+      // clang-format on
+      float getSoftLightComponent(
+          float srcc, float srca, float dstc, float dsta) {
+        if (2.0 * srcc <= srca) {
+          return (dstc * dstc * (srca - 2.0 * srcc)) / dsta +
+                 (1.0 - dsta) * srcc + dstc * (-srca + 2.0 * srcc + 1.0);
+        } else if (4.0 * dstc <= dsta) {
+          float DSqd = dstc * dstc;
+          float DCub = DSqd * dstc;
+          float DaSqd = dsta * dsta;
+          float DaCub = DaSqd * dsta;
+          return (-DaCub * srcc +
+                  DaSqd * (srcc - dstc * (3.0 * srca - 6.0 * srcc - 1.0)) +
+                  12.0 * dsta * DSqd * (srca - 2.0 * srcc) -
+                  16.0 * DCub * (srca - 2.0 * srcc)) /
+                 DaSqd;
+        } else {
+          return -sqrt(dsta * dstc) * (srca - 2.0 * srcc) - dsta * srcc +
+                 dstc * (srca - 2.0 * srcc + 1.0) + srcc;
+        }
+      }
+      // clang-format off
+  );  // NOLINT(whitespace/parens)
+
+  static const std::string kFunctionLum = SHADER0(
+      // clang-format on
+      float luminance(vec3 color) { return dot(vec3(0.3, 0.59, 0.11), color); }
+
+      vec3 set_luminance(vec3 hueSat, float alpha, vec3 lumColor) {
+        float diff = luminance(lumColor - hueSat);
+        vec3 outColor = hueSat + diff;
+        float outLum = luminance(outColor);
+        float minComp = min(min(outColor.r, outColor.g), outColor.b);
+        float maxComp = max(max(outColor.r, outColor.g), outColor.b);
+        if (minComp < 0.0) {
+          outColor = outLum +
+                     ((outColor - vec3(outLum, outLum, outLum)) * outLum) /
+                         (outLum - minComp);
+        }
+        if (maxComp > alpha) {
+          outColor =
+              outLum +
+              ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) /
+                  (maxComp - outLum);
+        }
+        return outColor;
+      }
+      // clang-format off
+  );  // NOLINT(whitespace/parens)
+
+  static const std::string kFunctionSat = SHADER0(
+      // clang-format on
+      float saturation(vec3 color) {
+        return max(max(color.r, color.g), color.b) -
+               min(min(color.r, color.g), color.b);
+      }
+
+      vec3 set_saturation_helper(
+          float minComp, float midComp, float maxComp, float sat) {
+        if (minComp < maxComp) {
+          vec3 result;
+          result.r = 0.0;
+          result.g = sat * (midComp - minComp) / (maxComp - minComp);
+          result.b = sat;
+          return result;
+        } else {
+          return vec3(0, 0, 0);
+        }
+      }
+
+      vec3 set_saturation(vec3 hueLumColor, vec3 satColor) {
+        float sat = saturation(satColor);
+        if (hueLumColor.r <= hueLumColor.g) {
+          if (hueLumColor.g <= hueLumColor.b) {
+            hueLumColor.rgb = set_saturation_helper(
+                hueLumColor.r, hueLumColor.g, hueLumColor.b, sat);
+          } else if (hueLumColor.r <= hueLumColor.b) {
+            hueLumColor.rbg = set_saturation_helper(
+                hueLumColor.r, hueLumColor.b, hueLumColor.g, sat);
+          } else {
+            hueLumColor.brg = set_saturation_helper(
+                hueLumColor.b, hueLumColor.r, hueLumColor.g, sat);
+          }
+        } else if (hueLumColor.r <= hueLumColor.b) {
+          hueLumColor.grb = set_saturation_helper(
+              hueLumColor.g, hueLumColor.r, hueLumColor.b, sat);
+        } else if (hueLumColor.g <= hueLumColor.b) {
+          hueLumColor.gbr = set_saturation_helper(
+              hueLumColor.g, hueLumColor.b, hueLumColor.r, sat);
+        } else {
+          hueLumColor.bgr = set_saturation_helper(
+              hueLumColor.b, hueLumColor.g, hueLumColor.r, sat);
+        }
+        return hueLumColor;
+      }
+      // clang-format off
+  );  // NOLINT(whitespace/parens)
+  // clang-format on
+
+  switch (blend_mode_) {
+    case BlendModeOverlay:
+    case BlendModeHardLight:
+      return kFunctionHardLight;
+    case BlendModeColorDodge:
+      return kFunctionColorDodgeComponent;
+    case BlendModeColorBurn:
+      return kFunctionColorBurnComponent;
+    case BlendModeSoftLight:
+      return kFunctionSoftLightComponentPosDstAlpha;
+    case BlendModeHue:
+    case BlendModeSaturation:
+      return kFunctionLum + kFunctionSat;
+    case BlendModeColor:
+    case BlendModeLuminosity:
+      return kFunctionLum;
+    default:
+      return std::string();
+  }
+}
+
+std::string FragmentTexBlendMode::GetBlendFunction() const {
+  return "vec4 Blend(vec4 src, vec4 dst) {"
+         "    vec4 result;"
+         "    result.a = src.a + (1.0 - src.a) * dst.a;" +
+         GetBlendFunctionBodyForRGB() +
+         "    return result;"
+         "}";
+}
+
+std::string FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const {
+  switch (blend_mode_) {
+    case BlendModeLighten:
+      return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb,"
+             "                 (1.0 - dst.a) * src.rgb + dst.rgb);";
+    case BlendModeOverlay:
+      return "result.rgb = hardLight(dst, src);";
+    case BlendModeDarken:
+      return "result.rgb = min((1.0 - src.a) * dst.rgb + src.rgb,"
+             "                 (1.0 - dst.a) * src.rgb + dst.rgb);";
+    case BlendModeColorDodge:
+      return "result.r = getColorDodgeComponent(src.r, src.a, dst.r, dst.a);"
+             "result.g = getColorDodgeComponent(src.g, src.a, dst.g, dst.a);"
+             "result.b = getColorDodgeComponent(src.b, src.a, dst.b, dst.a);";
+    case BlendModeColorBurn:
+      return "result.r = getColorBurnComponent(src.r, src.a, dst.r, dst.a);"
+             "result.g = getColorBurnComponent(src.g, src.a, dst.g, dst.a);"
+             "result.b = getColorBurnComponent(src.b, src.a, dst.b, dst.a);";
+    case BlendModeHardLight:
+      return "result.rgb = hardLight(src, dst);";
+    case BlendModeSoftLight:
+      return "if (0.0 == dst.a) {"
+             "  result.rgb = src.rgb;"
+             "} else {"
+             "  result.r = getSoftLightComponent(src.r, src.a, dst.r, dst.a);"
+             "  result.g = getSoftLightComponent(src.g, src.a, dst.g, dst.a);"
+             "  result.b = getSoftLightComponent(src.b, src.a, dst.b, dst.a);"
+             "}";
+    case BlendModeDifference:
+      return "result.rgb = src.rgb + dst.rgb -"
+             "    2.0 * min(src.rgb * dst.a, dst.rgb * src.a);";
+    case BlendModeExclusion:
+      return "result.rgb = dst.rgb + src.rgb - 2.0 * dst.rgb * src.rgb;";
+    case BlendModeMultiply:
+      return "result.rgb = (1.0 - src.a) * dst.rgb +"
+             "    (1.0 - dst.a) * src.rgb + src.rgb * dst.rgb;";
+    case BlendModeHue:
+      return "vec4 dstSrcAlpha = dst * src.a;"
+             "result.rgb ="
+             "    set_luminance(set_saturation(src.rgb * dst.a,"
+             "                                 dstSrcAlpha.rgb),"
+             "                  dstSrcAlpha.a,"
+             "                  dstSrcAlpha.rgb);"
+             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
+    case BlendModeSaturation:
+      return "vec4 dstSrcAlpha = dst * src.a;"
+             "result.rgb = set_luminance(set_saturation(dstSrcAlpha.rgb,"
+             "                                          src.rgb * dst.a),"
+             "                           dstSrcAlpha.a,"
+             "                           dstSrcAlpha.rgb);"
+             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
+    case BlendModeColor:
+      return "vec4 srcDstAlpha = src * dst.a;"
+             "result.rgb = set_luminance(srcDstAlpha.rgb,"
+             "                           srcDstAlpha.a,"
+             "                           dst.rgb * src.a);"
+             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
+    case BlendModeLuminosity:
+      return "vec4 srcDstAlpha = src * dst.a;"
+             "result.rgb = set_luminance(dst.rgb * src.a,"
+             "                           srcDstAlpha.a,"
+             "                           srcDstAlpha.rgb);"
+             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
+    default:
+      NOTREACHED();
+      // simple alpha compositing
+      return "result.rgb = src.rgb * src.a + dst.rgb * dst.a * (1 - src.a)";
+  }
+}
+
 FragmentTexAlphaBinding::FragmentTexAlphaBinding()
     : sampler_location_(-1), alpha_location_(-1) {
 }
@@ -674,18 +977,19 @@
                                    unsigned program,
                                    int* base_uniform_index) {
   static const char* uniforms[] = {
-      "s_texture", "alpha",
+      "s_texture", "alpha", BLEND_MODE_UNIFORMS,
   };
   int locations[arraysize(uniforms)];
 
   GetProgramUniformLocations(context,
                              program,
-                             arraysize(uniforms),
+                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                              uniforms,
                              locations,
                              base_uniform_index);
   sampler_location_ = locations[0];
   alpha_location_ = locations[1];
+  BLEND_MODE_SET_LOCATIONS(locations, 2);
 }
 
 FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
@@ -699,13 +1003,13 @@
                                               unsigned program,
                                               int* base_uniform_index) {
   static const char* uniforms[] = {
-      "s_texture", "alpha", "colorMatrix", "colorOffset",
+      "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS,
   };
   int locations[arraysize(uniforms)];
 
   GetProgramUniformLocations(context,
                              program,
-                             arraysize(uniforms),
+                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                              uniforms,
                              locations,
                              base_uniform_index);
@@ -713,6 +1017,7 @@
   alpha_location_ = locations[1];
   color_matrix_location_ = locations[2];
   color_offset_location_ = locations[3];
+  BLEND_MODE_SET_LOCATIONS(locations, 4);
 }
 
 FragmentTexOpaqueBinding::FragmentTexOpaqueBinding() : sampler_location_(-1) {
@@ -747,7 +1052,7 @@
       uniform float alpha;
       void main() {
         vec4 texColor = TextureLookup(s_texture, v_texCoord);
-        gl_FragColor = texColor * alpha;
+        gl_FragColor = ApplyBlendMode(texColor * alpha);
       }
       // clang-format off
   );  // NOLINT(whitespace/parens)
@@ -773,7 +1078,7 @@
         texColor = colorMatrix * texColor + colorOffset;
         texColor.rgb *= texColor.a;
         texColor = clamp(texColor, 0.0, 1.0);
-        gl_FragColor = texColor * alpha;
+        gl_FragColor = ApplyBlendMode(texColor * alpha);
       }
       // clang-format off
   );  // NOLINT(whitespace/parens)
@@ -966,18 +1271,19 @@
                                         unsigned program,
                                         int* base_uniform_index) {
   static const char* uniforms[] = {
-      "s_texture", "alpha",
+      "s_texture", "alpha", BLEND_MODE_UNIFORMS,
   };
   int locations[arraysize(uniforms)];
 
   GetProgramUniformLocations(context,
                              program,
-                             arraysize(uniforms),
+                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                              uniforms,
                              locations,
                              base_uniform_index);
   sampler_location_ = locations[0];
   alpha_location_ = locations[1];
+  BLEND_MODE_SET_LOCATIONS(locations, 2);
 }
 
 std::string FragmentShaderRGBATexAlphaAA::GetShaderString(
@@ -997,7 +1303,7 @@
         vec4 d4 = min(edge_dist[0], edge_dist[1]);
         vec2 d2 = min(d4.xz, d4.yw);
         float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-        gl_FragColor = texColor * alpha * aa;
+        gl_FragColor = ApplyBlendMode(texColor * alpha * aa);
       }
       // clang-format off
   );  // NOLINT(whitespace/parens)
@@ -1097,13 +1403,18 @@
                                           unsigned program,
                                           int* base_uniform_index) {
   static const char* uniforms[] = {
-      "s_texture", "s_mask", "alpha", "maskTexCoordScale", "maskTexCoordOffset",
+      "s_texture",
+      "s_mask",
+      "alpha",
+      "maskTexCoordScale",
+      "maskTexCoordOffset",
+      BLEND_MODE_UNIFORMS,
   };
   int locations[arraysize(uniforms)];
 
   GetProgramUniformLocations(context,
                              program,
-                             arraysize(uniforms),
+                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                              uniforms,
                              locations,
                              base_uniform_index);
@@ -1112,6 +1423,7 @@
   alpha_location_ = locations[2];
   mask_tex_coord_scale_location_ = locations[3];
   mask_tex_coord_offset_location_ = locations[4];
+  BLEND_MODE_SET_LOCATIONS(locations, 5);
 }
 
 std::string FragmentShaderRGBATexAlphaMask::GetShaderString(
@@ -1133,7 +1445,7 @@
             vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
                  maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
         vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
-        gl_FragColor = texColor * alpha * maskColor.w;
+        gl_FragColor = ApplyBlendMode(texColor * alpha * maskColor.w);
       }
       // clang-format off
   );  // NOLINT(whitespace/parens)
@@ -1152,13 +1464,18 @@
                                             unsigned program,
                                             int* base_uniform_index) {
   static const char* uniforms[] = {
-      "s_texture", "s_mask", "alpha", "maskTexCoordScale", "maskTexCoordOffset",
+      "s_texture",
+      "s_mask",
+      "alpha",
+      "maskTexCoordScale",
+      "maskTexCoordOffset",
+      BLEND_MODE_UNIFORMS,
   };
   int locations[arraysize(uniforms)];
 
   GetProgramUniformLocations(context,
                              program,
-                             arraysize(uniforms),
+                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                              uniforms,
                              locations,
                              base_uniform_index);
@@ -1167,6 +1484,7 @@
   alpha_location_ = locations[2];
   mask_tex_coord_scale_location_ = locations[3];
   mask_tex_coord_offset_location_ = locations[4];
+  BLEND_MODE_SET_LOCATIONS(locations, 5);
 }
 
 std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString(
@@ -1193,7 +1511,7 @@
         vec4 d4 = min(edge_dist[0], edge_dist[1]);
         vec2 d2 = min(d4.xz, d4.yw);
         float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-        gl_FragColor = texColor * alpha * maskColor.w * aa;
+        gl_FragColor = ApplyBlendMode(texColor * alpha * maskColor.w * aa);
       }
       // clang-format off
   );  // NOLINT(whitespace/parens)
@@ -1222,12 +1540,13 @@
       "maskTexCoordOffset",
       "colorMatrix",
       "colorOffset",
+      BLEND_MODE_UNIFORMS,
   };
   int locations[arraysize(uniforms)];
 
   GetProgramUniformLocations(context,
                              program,
-                             arraysize(uniforms),
+                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                              uniforms,
                              locations,
                              base_uniform_index);
@@ -1238,6 +1557,7 @@
   mask_tex_coord_offset_location_ = locations[4];
   color_matrix_location_ = locations[5];
   color_offset_location_ = locations[6];
+  BLEND_MODE_SET_LOCATIONS(locations, 7);
 }
 
 std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString(
@@ -1271,7 +1591,7 @@
         vec4 d4 = min(edge_dist[0], edge_dist[1]);
         vec2 d2 = min(d4.xz, d4.yw);
         float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-        gl_FragColor = texColor * alpha * maskColor.w * aa;
+        gl_FragColor = ApplyBlendMode(texColor * alpha * maskColor.w * aa);
       }
       // clang-format off
   );  // NOLINT(whitespace/parens)
@@ -1290,13 +1610,13 @@
                                                    unsigned program,
                                                    int* base_uniform_index) {
   static const char* uniforms[] = {
-      "s_texture", "alpha", "colorMatrix", "colorOffset",
+      "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS,
   };
   int locations[arraysize(uniforms)];
 
   GetProgramUniformLocations(context,
                              program,
-                             arraysize(uniforms),
+                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                              uniforms,
                              locations,
                              base_uniform_index);
@@ -1304,6 +1624,7 @@
   alpha_location_ = locations[1];
   color_matrix_location_ = locations[2];
   color_offset_location_ = locations[3];
+  BLEND_MODE_SET_LOCATIONS(locations, 4);
 }
 
 std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString(
@@ -1330,7 +1651,7 @@
         vec4 d4 = min(edge_dist[0], edge_dist[1]);
         vec2 d2 = min(d4.xz, d4.yw);
         float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-        gl_FragColor = texColor * alpha * aa;
+        gl_FragColor = ApplyBlendMode(texColor * alpha * aa);
       }
       // clang-format off
   );  // NOLINT(whitespace/parens)
@@ -1356,12 +1677,13 @@
       "maskTexCoordOffset",
       "colorMatrix",
       "colorOffset",
+      BLEND_MODE_UNIFORMS,
   };
   int locations[arraysize(uniforms)];
 
   GetProgramUniformLocations(context,
                              program,
-                             arraysize(uniforms),
+                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
                              uniforms,
                              locations,
                              base_uniform_index);
@@ -1372,6 +1694,7 @@
   mask_tex_coord_offset_location_ = locations[4];
   color_matrix_location_ = locations[5];
   color_offset_location_ = locations[6];
+  BLEND_MODE_SET_LOCATIONS(locations, 7);
 }
 
 std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString(
@@ -1400,7 +1723,7 @@
             vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
                  maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
         vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
-        gl_FragColor = texColor * alpha * maskColor.w;
+        gl_FragColor = ApplyBlendMode(texColor * alpha * maskColor.w);
       }
       // clang-format off
   );  // NOLINT(whitespace/parens)
diff --git a/cc/output/shader.h b/cc/output/shader.h
index 3039c80e..0384366 100644
--- a/cc/output/shader.h
+++ b/cc/output/shader.h
@@ -38,6 +38,25 @@
   NumSamplerTypes = 4
 };
 
+enum BlendMode {
+  BlendModeNormal,
+  BlendModeOverlay,
+  BlendModeDarken,
+  BlendModeLighten,
+  BlendModeColorDodge,
+  BlendModeColorBurn,
+  BlendModeHardLight,
+  BlendModeSoftLight,
+  BlendModeDifference,
+  BlendModeExclusion,
+  BlendModeMultiply,
+  BlendModeHue,
+  BlendModeSaturation,
+  BlendModeColor,
+  BlendModeLuminosity,
+  NumBlendModes
+};
+
 // Note: The highp_threshold_cache must be provided by the caller to make
 // the caching multi-thread/context safe in an easy low-overhead manner.
 // The caller must make sure to clear highp_threshold_cache to 0, so it can be
@@ -279,7 +298,32 @@
   DISALLOW_COPY_AND_ASSIGN(VertexShaderVideoTransform);
 };
 
-class FragmentTexAlphaBinding {
+class FragmentTexBlendMode {
+ public:
+  int backdrop_location() const { return backdrop_location_; }
+  int backdrop_rect_location() const { return backdrop_rect_location_; }
+
+  BlendMode blend_mode() const { return blend_mode_; }
+  void set_blend_mode(BlendMode blend_mode) { blend_mode_ = blend_mode; }
+  bool is_default_blend_mode() const { return blend_mode_ == BlendModeNormal; }
+
+ protected:
+  FragmentTexBlendMode();
+
+  std::string SetBlendModeFunctions(std::string shader_string) const;
+
+  int backdrop_location_;
+  int backdrop_rect_location_;
+
+ private:
+  BlendMode blend_mode_;
+
+  std::string GetHelperFunctions() const;
+  std::string GetBlendFunction() const;
+  std::string GetBlendFunctionBodyForRGB() const;
+};
+
+class FragmentTexAlphaBinding : public FragmentTexBlendMode {
  public:
   FragmentTexAlphaBinding();
 
@@ -297,7 +341,7 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentTexAlphaBinding);
 };
 
-class FragmentTexColorMatrixAlphaBinding {
+class FragmentTexColorMatrixAlphaBinding : public FragmentTexBlendMode {
  public:
     FragmentTexColorMatrixAlphaBinding();
 
@@ -317,7 +361,7 @@
     int color_offset_location_;
 };
 
-class FragmentTexOpaqueBinding {
+class FragmentTexOpaqueBinding : public FragmentTexBlendMode {
  public:
   FragmentTexOpaqueBinding();
 
@@ -335,7 +379,7 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentTexOpaqueBinding);
 };
 
-class FragmentTexBackgroundBinding {
+class FragmentTexBackgroundBinding : public FragmentTexBlendMode {
  public:
   FragmentTexBackgroundBinding();
 
@@ -417,7 +461,7 @@
       TexCoordPrecision precision, SamplerType sampler) const;
 };
 
-class FragmentShaderRGBATexAlphaAA {
+class FragmentShaderRGBATexAlphaAA : public FragmentTexBlendMode {
  public:
   FragmentShaderRGBATexAlphaAA();
 
@@ -437,7 +481,7 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaAA);
 };
 
-class FragmentTexClampAlphaAABinding {
+class FragmentTexClampAlphaAABinding : public FragmentTexBlendMode {
  public:
   FragmentTexClampAlphaAABinding();
 
@@ -473,7 +517,7 @@
       TexCoordPrecision precision, SamplerType sampler) const;
 };
 
-class FragmentShaderRGBATexAlphaMask {
+class FragmentShaderRGBATexAlphaMask : public FragmentTexBlendMode {
  public:
   FragmentShaderRGBATexAlphaMask();
   std::string GetShaderString(
@@ -502,7 +546,7 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMask);
 };
 
-class FragmentShaderRGBATexAlphaMaskAA {
+class FragmentShaderRGBATexAlphaMaskAA : public FragmentTexBlendMode {
  public:
   FragmentShaderRGBATexAlphaMaskAA();
   std::string GetShaderString(
@@ -531,7 +575,8 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMaskAA);
 };
 
-class FragmentShaderRGBATexAlphaMaskColorMatrixAA {
+class FragmentShaderRGBATexAlphaMaskColorMatrixAA
+    : public FragmentTexBlendMode {
  public:
   FragmentShaderRGBATexAlphaMaskColorMatrixAA();
   std::string GetShaderString(
@@ -562,7 +607,7 @@
   int color_offset_location_;
 };
 
-class FragmentShaderRGBATexAlphaColorMatrixAA {
+class FragmentShaderRGBATexAlphaColorMatrixAA : public FragmentTexBlendMode {
  public:
   FragmentShaderRGBATexAlphaColorMatrixAA();
   std::string GetShaderString(
@@ -583,7 +628,7 @@
   int color_offset_location_;
 };
 
-class FragmentShaderRGBATexAlphaMaskColorMatrix {
+class FragmentShaderRGBATexAlphaMaskColorMatrix : public FragmentTexBlendMode {
  public:
   FragmentShaderRGBATexAlphaMaskColorMatrix();
   std::string GetShaderString(
@@ -614,7 +659,7 @@
   int color_offset_location_;
 };
 
-class FragmentShaderYUVVideo {
+class FragmentShaderYUVVideo : public FragmentTexBlendMode {
  public:
   FragmentShaderYUVVideo();
   std::string GetShaderString(
@@ -641,8 +686,7 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVVideo);
 };
 
-
-class FragmentShaderYUVAVideo {
+class FragmentShaderYUVAVideo : public FragmentTexBlendMode {
  public:
   FragmentShaderYUVAVideo();
   std::string GetShaderString(
@@ -672,7 +716,7 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVAVideo);
 };
 
-class FragmentShaderColor {
+class FragmentShaderColor : public FragmentTexBlendMode {
  public:
   FragmentShaderColor();
   std::string GetShaderString(
@@ -689,7 +733,7 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentShaderColor);
 };
 
-class FragmentShaderColorAA {
+class FragmentShaderColorAA : public FragmentTexBlendMode {
  public:
   FragmentShaderColorAA();
   std::string GetShaderString(
@@ -706,7 +750,7 @@
   DISALLOW_COPY_AND_ASSIGN(FragmentShaderColorAA);
 };
 
-class FragmentShaderCheckerboard {
+class FragmentShaderCheckerboard : public FragmentTexBlendMode {
  public:
   FragmentShaderCheckerboard();
   std::string GetShaderString(
diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc
index c3cb828c..acc897f0 100644
--- a/cc/output/software_renderer.cc
+++ b/cc/output/software_renderer.cc
@@ -239,14 +239,16 @@
   current_canvas_->setMatrix(sk_device_matrix);
 
   current_paint_.reset();
-  if (!IsScaleAndIntegerTranslate(sk_device_matrix)) {
+  if (settings_->force_antialiasing ||
+      !IsScaleAndIntegerTranslate(sk_device_matrix)) {
     // TODO(danakj): Until we can enable AA only on exterior edges of the
     // layer, disable AA if any interior edges are present. crbug.com/248175
     bool all_four_edges_are_exterior = quad->IsTopEdge() &&
                                        quad->IsLeftEdge() &&
                                        quad->IsBottomEdge() &&
                                        quad->IsRightEdge();
-    if (settings_->allow_antialiasing && all_four_edges_are_exterior)
+    if (settings_->allow_antialiasing &&
+        (settings_->force_antialiasing || all_four_edges_are_exterior))
       current_paint_.setAntiAlias(true);
     current_paint_.setFilterLevel(SkPaint::kLow_FilterLevel);
   }
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc
index 1e373b2..60f75d9 100644
--- a/cc/output/software_renderer_unittest.cc
+++ b/cc/output/software_renderer_unittest.cc
@@ -42,8 +42,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false);
+                                                  1);
     renderer_ = SoftwareRenderer::Create(
         this, &settings_, output_surface_.get(), resource_provider());
   }
diff --git a/cc/quads/content_draw_quad_base.h b/cc/quads/content_draw_quad_base.h
index 6917e6b..b0e53dcb 100644
--- a/cc/quads/content_draw_quad_base.h
+++ b/cc/quads/content_draw_quad_base.h
@@ -9,8 +9,8 @@
 #include "cc/base/cc_export.h"
 #include "cc/quads/draw_quad.h"
 #include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/point.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/quads/draw_polygon.h b/cc/quads/draw_polygon.h
index 8e65ea8..32643ee 100644
--- a/cc/quads/draw_polygon.h
+++ b/cc/quads/draw_polygon.h
@@ -9,11 +9,11 @@
 
 #include "cc/base/math_util.h"
 #include "cc/output/bsp_compare_result.h"
-#include "ui/gfx/point3_f.h"
-#include "ui/gfx/quad_f.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/transform.h"
-#include "ui/gfx/vector3d_f.h"
 
 namespace cc {
 
diff --git a/cc/quads/draw_quad.cc b/cc/quads/draw_quad.cc
index 38b24b0..7322a7a 100644
--- a/cc/quads/draw_quad.cc
+++ b/cc/quads/draw_quad.cc
@@ -20,7 +20,7 @@
 #include "cc/quads/texture_draw_quad.h"
 #include "cc/quads/tile_draw_quad.h"
 #include "cc/quads/yuv_video_draw_quad.h"
-#include "ui/gfx/quad_f.h"
+#include "ui/gfx/geometry/quad_f.h"
 
 namespace cc {
 
diff --git a/cc/quads/io_surface_draw_quad.h b/cc/quads/io_surface_draw_quad.h
index 9c8b50b..ba64384 100644
--- a/cc/quads/io_surface_draw_quad.h
+++ b/cc/quads/io_surface_draw_quad.h
@@ -8,7 +8,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
 #include "cc/quads/draw_quad.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/quads/picture_draw_quad.h b/cc/quads/picture_draw_quad.h
index d2a7271..1bea1a2 100644
--- a/cc/quads/picture_draw_quad.h
+++ b/cc/quads/picture_draw_quad.h
@@ -10,9 +10,9 @@
 #include "cc/base/cc_export.h"
 #include "cc/quads/content_draw_quad_base.h"
 #include "cc/resources/picture_pile_impl.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/quads/render_pass.h b/cc/quads/render_pass.h
index 65c712d..76536b5b 100644
--- a/cc/quads/render_pass.h
+++ b/cc/quads/render_pass.h
@@ -15,8 +15,8 @@
 #include "cc/quads/list_container.h"
 #include "cc/quads/render_pass_id.h"
 #include "skia/ext/refptr.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
diff --git a/cc/quads/shared_quad_state.h b/cc/quads/shared_quad_state.h
index dde87a8..ebf7d11 100644
--- a/cc/quads/shared_quad_state.h
+++ b/cc/quads/shared_quad_state.h
@@ -8,7 +8,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
 #include "third_party/skia/include/core/SkXfermode.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
diff --git a/cc/quads/texture_draw_quad.cc b/cc/quads/texture_draw_quad.cc
index 72435c2..9ff9744 100644
--- a/cc/quads/texture_draw_quad.cc
+++ b/cc/quads/texture_draw_quad.cc
@@ -8,7 +8,7 @@
 #include "base/logging.h"
 #include "base/values.h"
 #include "cc/base/math_util.h"
-#include "ui/gfx/vector2d_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
diff --git a/cc/quads/texture_draw_quad.h b/cc/quads/texture_draw_quad.h
index 3e0632c..9137d51 100644
--- a/cc/quads/texture_draw_quad.h
+++ b/cc/quads/texture_draw_quad.h
@@ -8,7 +8,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
 #include "cc/quads/draw_quad.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect_f.h"
 
 namespace cc {
 
diff --git a/cc/resources/content_layer_updater.cc b/cc/resources/content_layer_updater.cc
index f6469ff..971362f 100644
--- a/cc/resources/content_layer_updater.cc
+++ b/cc/resources/content_layer_updater.cc
@@ -5,15 +5,13 @@
 #include "cc/resources/content_layer_updater.h"
 
 #include "base/debug/trace_event.h"
-#include "base/time/time.h"
 #include "cc/debug/rendering_stats_instrumentation.h"
 #include "cc/resources/layer_painter.h"
 #include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkPaint.h"
 #include "third_party/skia/include/core/SkRect.h"
 #include "third_party/skia/include/core/SkScalar.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/skia_util.h"
 
 namespace cc {
diff --git a/cc/resources/content_layer_updater.h b/cc/resources/content_layer_updater.h
index e0c54e5..4ba18ba9 100644
--- a/cc/resources/content_layer_updater.h
+++ b/cc/resources/content_layer_updater.h
@@ -7,7 +7,7 @@
 
 #include "cc/base/cc_export.h"
 #include "cc/resources/layer_updater.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 class SkCanvas;
 
diff --git a/cc/resources/gpu_memory_buffer_manager.h b/cc/resources/gpu_memory_buffer_manager.h
index 1e114c3..52434e05 100644
--- a/cc/resources/gpu_memory_buffer_manager.h
+++ b/cc/resources/gpu_memory_buffer_manager.h
@@ -7,8 +7,8 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
+#include "ui/gfx/geometry/size.h"
 #include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/size.h"
 
 namespace cc {
 
diff --git a/cc/resources/gpu_raster_worker_pool.cc b/cc/resources/gpu_raster_worker_pool.cc
index a0bc86f..cba427e 100644
--- a/cc/resources/gpu_raster_worker_pool.cc
+++ b/cc/resources/gpu_raster_worker_pool.cc
@@ -26,17 +26,25 @@
  public:
   RasterBufferImpl(ResourceProvider* resource_provider,
                    const Resource* resource,
-                   SkMultiPictureDraw* multi_picture_draw)
+                   SkMultiPictureDraw* multi_picture_draw,
+                   bool use_distance_field_text)
       : lock_(resource_provider, resource->id()),
         resource_(resource),
-        multi_picture_draw_(multi_picture_draw) {}
+        multi_picture_draw_(multi_picture_draw),
+        use_distance_field_text_(use_distance_field_text) {}
 
   // Overridden from RasterBuffer:
   void Playback(const PicturePileImpl* picture_pile,
                 const gfx::Rect& rect,
                 float scale,
                 RenderingStatsInstrumentation* stats) override {
-    if (!lock_.sk_surface())
+    // Turn on distance fields for layers that have ever animated.
+    bool use_distance_field_text =
+        use_distance_field_text_ ||
+        picture_pile->likely_to_be_used_for_transform_animation();
+    SkSurface* sk_surface = lock_.GetSkSurface(use_distance_field_text);
+
+    if (!sk_surface)
       return;
 
     SkPictureRecorder recorder;
@@ -50,13 +58,14 @@
 
     // Add the canvas and recorded picture to |multi_picture_draw_|.
     skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording());
-    multi_picture_draw_->add(lock_.sk_surface()->getCanvas(), picture.get());
+    multi_picture_draw_->add(sk_surface->getCanvas(), picture.get());
   }
 
  private:
   ResourceProvider::ScopedWriteLockGr lock_;
   const Resource* resource_;
   SkMultiPictureDraw* multi_picture_draw_;
+  bool use_distance_field_text_;
 
   DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
 };
@@ -67,20 +76,26 @@
 scoped_ptr<RasterWorkerPool> GpuRasterWorkerPool::Create(
     base::SequencedTaskRunner* task_runner,
     ContextProvider* context_provider,
-    ResourceProvider* resource_provider) {
-  return make_scoped_ptr<RasterWorkerPool>(new GpuRasterWorkerPool(
-      task_runner, context_provider, resource_provider));
+    ResourceProvider* resource_provider,
+    bool use_distance_field_text) {
+  return make_scoped_ptr<RasterWorkerPool>(
+      new GpuRasterWorkerPool(task_runner,
+                              context_provider,
+                              resource_provider,
+                              use_distance_field_text));
 }
 
 GpuRasterWorkerPool::GpuRasterWorkerPool(base::SequencedTaskRunner* task_runner,
                                          ContextProvider* context_provider,
-                                         ResourceProvider* resource_provider)
+                                         ResourceProvider* resource_provider,
+                                         bool use_distance_field_text)
     : task_runner_(task_runner),
       task_graph_runner_(new TaskGraphRunner),
       namespace_token_(task_graph_runner_->GetNamespaceToken()),
       context_provider_(context_provider),
       resource_provider_(resource_provider),
       run_tasks_on_origin_thread_pending_(false),
+      use_distance_field_text_(use_distance_field_text),
       raster_finished_weak_ptr_factory_(this),
       weak_ptr_factory_(this) {
   DCHECK(context_provider_);
@@ -190,7 +205,10 @@
 scoped_ptr<RasterBuffer> GpuRasterWorkerPool::AcquireBufferForRaster(
     const Resource* resource) {
   return make_scoped_ptr<RasterBuffer>(
-      new RasterBufferImpl(resource_provider_, resource, &multi_picture_draw_));
+      new RasterBufferImpl(resource_provider_,
+                           resource,
+                           &multi_picture_draw_,
+                           use_distance_field_text_));
 }
 
 void GpuRasterWorkerPool::ReleaseBufferForRaster(
diff --git a/cc/resources/gpu_raster_worker_pool.h b/cc/resources/gpu_raster_worker_pool.h
index a4e4197..c5ff13f 100644
--- a/cc/resources/gpu_raster_worker_pool.h
+++ b/cc/resources/gpu_raster_worker_pool.h
@@ -23,7 +23,8 @@
   static scoped_ptr<RasterWorkerPool> Create(
       base::SequencedTaskRunner* task_runner,
       ContextProvider* context_provider,
-      ResourceProvider* resource_provider);
+      ResourceProvider* resource_provider,
+      bool use_distance_field_text);
 
   // Overridden from RasterWorkerPool:
   Rasterizer* AsRasterizer() override;
@@ -42,7 +43,8 @@
  private:
   GpuRasterWorkerPool(base::SequencedTaskRunner* task_runner,
                       ContextProvider* context_provider,
-                      ResourceProvider* resource_provider);
+                      ResourceProvider* resource_provider,
+                      bool use_distance_field_text);
 
   void OnRasterFinished(TaskSet task_set);
   void ScheduleRunTasksOnOriginThread();
@@ -58,6 +60,7 @@
   SkMultiPictureDraw multi_picture_draw_;
 
   bool run_tasks_on_origin_thread_pending_;
+  bool use_distance_field_text_;
 
   TaskSetCollection raster_pending_;
 
diff --git a/cc/resources/layer_quad.cc b/cc/resources/layer_quad.cc
index fdd68662..38ec7b32b 100644
--- a/cc/resources/layer_quad.cc
+++ b/cc/resources/layer_quad.cc
@@ -5,7 +5,7 @@
 #include "cc/resources/layer_quad.h"
 
 #include "base/logging.h"
-#include "ui/gfx/quad_f.h"
+#include "ui/gfx/geometry/quad_f.h"
 
 namespace cc {
 
diff --git a/cc/resources/layer_quad.h b/cc/resources/layer_quad.h
index 1d71193..ed1db10 100644
--- a/cc/resources/layer_quad.h
+++ b/cc/resources/layer_quad.h
@@ -8,7 +8,7 @@
 
 #include "base/basictypes.h"
 #include "cc/base/cc_export.h"
-#include "ui/gfx/point_f.h"
+#include "ui/gfx/geometry/point_f.h"
 
 namespace gfx {
 class QuadF;
diff --git a/cc/resources/layer_quad_unittest.cc b/cc/resources/layer_quad_unittest.cc
index 8d3909c..3560b8d 100644
--- a/cc/resources/layer_quad_unittest.cc
+++ b/cc/resources/layer_quad_unittest.cc
@@ -5,7 +5,7 @@
 #include "cc/resources/layer_quad.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/quad_f.h"
+#include "ui/gfx/geometry/quad_f.h"
 
 namespace cc {
 namespace {
diff --git a/cc/resources/layer_tiling_data.h b/cc/resources/layer_tiling_data.h
index b369d61..5168118 100644
--- a/cc/resources/layer_tiling_data.h
+++ b/cc/resources/layer_tiling_data.h
@@ -14,7 +14,7 @@
 #include "cc/base/cc_export.h"
 #include "cc/base/simple_enclosed_region.h"
 #include "cc/base/tiling_data.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/resources/layer_updater.h b/cc/resources/layer_updater.h
index 4614c5a3..a5eb0a1 100644
--- a/cc/resources/layer_updater.h
+++ b/cc/resources/layer_updater.h
@@ -9,8 +9,8 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/vector2d.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
 
 namespace cc {
 
diff --git a/cc/resources/one_copy_raster_worker_pool.cc b/cc/resources/one_copy_raster_worker_pool.cc
index 66b6ea0..cc5dd192 100644
--- a/cc/resources/one_copy_raster_worker_pool.cc
+++ b/cc/resources/one_copy_raster_worker_pool.cc
@@ -5,6 +5,7 @@
 #include "cc/resources/one_copy_raster_worker_pool.h"
 
 #include <algorithm>
+#include <limits>
 
 #include "base/debug/trace_event.h"
 #include "base/debug/trace_event_argument.h"
@@ -21,23 +22,28 @@
 
 class RasterBufferImpl : public RasterBuffer {
  public:
-  RasterBufferImpl(ResourceProvider* resource_provider,
+  RasterBufferImpl(OneCopyRasterWorkerPool* worker_pool,
+                   ResourceProvider* resource_provider,
                    ResourcePool* resource_pool,
                    const Resource* resource)
-      : resource_provider_(resource_provider),
+      : worker_pool_(worker_pool),
+        resource_provider_(resource_provider),
         resource_pool_(resource_pool),
         resource_(resource),
         raster_resource_(resource_pool->AcquireResource(resource->size())),
         lock_(new ResourceProvider::ScopedWriteLockGpuMemoryBuffer(
             resource_provider_,
-            raster_resource_->id())) {}
+            raster_resource_->id())),
+        sequence_(0) {}
 
   ~RasterBufferImpl() override {
-    // First unlock raster resource.
+    // Release write lock in case a copy was never scheduled.
     lock_.reset();
 
-    // Copy contents of raster resource to |resource_|.
-    resource_provider_->CopyResource(raster_resource_->id(), resource_->id());
+    // Make sure any scheduled copy operations are issued before we release the
+    // raster resource.
+    if (sequence_)
+      worker_pool_->AdvanceLastIssuedCopyTo(sequence_);
 
     // Return raster resource to pool so it can be used by another RasterBuffer
     // instance.
@@ -54,28 +60,46 @@
       return;
 
     RasterWorkerPool::PlaybackToMemory(gpu_memory_buffer->Map(),
-                                       resource_->format(),
-                                       resource_->size(),
+                                       raster_resource_->format(),
+                                       raster_resource_->size(),
                                        gpu_memory_buffer->GetStride(),
                                        picture_pile,
                                        rect,
                                        scale,
                                        stats);
     gpu_memory_buffer->Unmap();
+
+    sequence_ = worker_pool_->ScheduleCopyOnWorkerThread(
+        lock_.Pass(), raster_resource_.get(), resource_);
   }
 
  private:
+  OneCopyRasterWorkerPool* worker_pool_;
   ResourceProvider* resource_provider_;
   ResourcePool* resource_pool_;
   const Resource* resource_;
   scoped_ptr<ScopedResource> raster_resource_;
   scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> lock_;
+  CopySequenceNumber sequence_;
 
   DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
 };
 
+// Flush interval when performing copy operations.
+const int kCopyFlushPeriod = 4;
+
 }  // namespace
 
+OneCopyRasterWorkerPool::CopyOperation::CopyOperation(
+    scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
+    ResourceProvider::ResourceId src,
+    ResourceProvider::ResourceId dst)
+    : write_lock(write_lock.Pass()), src(src), dst(dst) {
+}
+
+OneCopyRasterWorkerPool::CopyOperation::~CopyOperation() {
+}
+
 // static
 scoped_ptr<RasterWorkerPool> OneCopyRasterWorkerPool::Create(
     base::SequencedTaskRunner* task_runner,
@@ -103,6 +127,10 @@
       context_provider_(context_provider),
       resource_provider_(resource_provider),
       resource_pool_(resource_pool),
+      last_issued_copy_operation_(0),
+      last_flushed_copy_operation_(0),
+      next_copy_operation_sequence_(1),
+      weak_ptr_factory_(this),
       raster_finished_weak_ptr_factory_(this) {
   DCHECK(context_provider_);
 }
@@ -201,6 +229,7 @@
 
   task_graph_runner_->CollectCompletedTasks(namespace_token_,
                                             &completed_tasks_);
+
   for (Task::Vector::const_iterator it = completed_tasks_.begin();
        it != completed_tasks_.end();
        ++it) {
@@ -213,15 +242,13 @@
     task->RunReplyOnOriginThread();
   }
   completed_tasks_.clear();
-
-  context_provider_->ContextGL()->ShallowFlushCHROMIUM();
 }
 
 scoped_ptr<RasterBuffer> OneCopyRasterWorkerPool::AcquireBufferForRaster(
     const Resource* resource) {
   DCHECK_EQ(resource->format(), resource_pool_->resource_format());
   return make_scoped_ptr<RasterBuffer>(
-      new RasterBufferImpl(resource_provider_, resource_pool_, resource));
+      new RasterBufferImpl(this, resource_provider_, resource_pool_, resource));
 }
 
 void OneCopyRasterWorkerPool::ReleaseBufferForRaster(
@@ -229,6 +256,55 @@
   // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
 }
 
+CopySequenceNumber OneCopyRasterWorkerPool::ScheduleCopyOnWorkerThread(
+    scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
+    const Resource* src,
+    const Resource* dst) {
+  CopySequenceNumber sequence;
+
+  {
+    base::AutoLock lock(lock_);
+
+    sequence = next_copy_operation_sequence_++;
+
+    pending_copy_operations_.push_back(make_scoped_ptr(
+        new CopyOperation(write_lock.Pass(), src->id(), dst->id())));
+  }
+
+  // Post task that will advance last flushed copy operation to |sequence|
+  // if we have reached the flush period.
+  if ((sequence % kCopyFlushPeriod) == 0) {
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&OneCopyRasterWorkerPool::AdvanceLastFlushedCopyTo,
+                   weak_ptr_factory_.GetWeakPtr(),
+                   sequence));
+  }
+
+  return sequence;
+}
+
+void OneCopyRasterWorkerPool::AdvanceLastIssuedCopyTo(
+    CopySequenceNumber sequence) {
+  if (last_issued_copy_operation_ >= sequence)
+    return;
+
+  IssueCopyOperations(sequence - last_issued_copy_operation_);
+  last_issued_copy_operation_ = sequence;
+}
+
+void OneCopyRasterWorkerPool::AdvanceLastFlushedCopyTo(
+    CopySequenceNumber sequence) {
+  if (last_flushed_copy_operation_ >= sequence)
+    return;
+
+  AdvanceLastIssuedCopyTo(sequence);
+
+  // Flush all issued copy operations.
+  context_provider_->ContextGL()->ShallowFlushCHROMIUM();
+  last_flushed_copy_operation_ = last_issued_copy_operation_;
+}
+
 void OneCopyRasterWorkerPool::OnRasterFinished(TaskSet task_set) {
   TRACE_EVENT1(
       "cc", "OneCopyRasterWorkerPool::OnRasterFinished", "task_set", task_set);
@@ -244,6 +320,32 @@
   client_->DidFinishRunningTasks(task_set);
 }
 
+void OneCopyRasterWorkerPool::IssueCopyOperations(int64 count) {
+  TRACE_EVENT1(
+      "cc", "OneCopyRasterWorkerPool::IssueCopyOperations", "count", count);
+
+  CopyOperation::Deque copy_operations;
+
+  {
+    base::AutoLock lock(lock_);
+
+    for (int64 i = 0; i < count; ++i) {
+      DCHECK(!pending_copy_operations_.empty());
+      copy_operations.push_back(pending_copy_operations_.take_front());
+    }
+  }
+
+  while (!copy_operations.empty()) {
+    scoped_ptr<CopyOperation> copy_operation = copy_operations.take_front();
+
+    // Remove the write lock.
+    copy_operation->write_lock.reset();
+
+    // Copy contents of source resource to destination resource.
+    resource_provider_->CopyResource(copy_operation->src, copy_operation->dst);
+  }
+}
+
 scoped_refptr<base::debug::ConvertableToTraceFormat>
 OneCopyRasterWorkerPool::StateAsValue() const {
   scoped_refptr<base::debug::TracedValue> state =
diff --git a/cc/resources/one_copy_raster_worker_pool.h b/cc/resources/one_copy_raster_worker_pool.h
index c84b559..7372fb7 100644
--- a/cc/resources/one_copy_raster_worker_pool.h
+++ b/cc/resources/one_copy_raster_worker_pool.h
@@ -6,10 +6,13 @@
 #define CC_RESOURCES_ONE_COPY_RASTER_WORKER_POOL_H_
 
 #include "base/memory/weak_ptr.h"
+#include "base/synchronization/lock.h"
 #include "base/values.h"
+#include "cc/base/scoped_ptr_deque.h"
 #include "cc/output/context_provider.h"
 #include "cc/resources/raster_worker_pool.h"
 #include "cc/resources/rasterizer.h"
+#include "cc/resources/resource_provider.h"
 
 namespace base {
 namespace debug {
@@ -21,7 +24,8 @@
 namespace cc {
 class ResourcePool;
 class ResourceProvider;
-class ScopedResource;
+
+typedef int64 CopySequenceNumber;
 
 class CC_EXPORT OneCopyRasterWorkerPool : public RasterWorkerPool,
                                           public Rasterizer,
@@ -50,6 +54,17 @@
       const Resource* resource) override;
   void ReleaseBufferForRaster(scoped_ptr<RasterBuffer> buffer) override;
 
+  // Schedule copy of |src| resource to |dst| resource. Returns a non-zero
+  // sequence number for this copy operation.
+  CopySequenceNumber ScheduleCopyOnWorkerThread(
+      scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
+      const Resource* src,
+      const Resource* dst);
+
+  // Issues copy operations until |sequence| has been processed. This will
+  // return immediately if |sequence| has already been processed.
+  void AdvanceLastIssuedCopyTo(CopySequenceNumber sequence);
+
  protected:
   OneCopyRasterWorkerPool(base::SequencedTaskRunner* task_runner,
                           TaskGraphRunner* task_graph_runner,
@@ -58,7 +73,23 @@
                           ResourcePool* resource_pool);
 
  private:
+  struct CopyOperation {
+    typedef ScopedPtrDeque<CopyOperation> Deque;
+
+    CopyOperation(
+        scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
+        ResourceProvider::ResourceId src,
+        ResourceProvider::ResourceId dst);
+    ~CopyOperation();
+
+    scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock;
+    ResourceProvider::ResourceId src;
+    ResourceProvider::ResourceId dst;
+  };
+
   void OnRasterFinished(TaskSet task_set);
+  void AdvanceLastFlushedCopyTo(CopySequenceNumber sequence);
+  void IssueCopyOperations(int64 count);
   scoped_refptr<base::debug::ConvertableToTraceFormat> StateAsValue() const;
   void StagingStateAsValueInto(base::debug::TracedValue* staging_state) const;
 
@@ -71,12 +102,22 @@
   ResourcePool* resource_pool_;
   TaskSetCollection raster_pending_;
   scoped_refptr<RasterizerTask> raster_finished_tasks_[kNumberOfTaskSets];
+  CopySequenceNumber last_issued_copy_operation_;
+  CopySequenceNumber last_flushed_copy_operation_;
 
   // Task graph used when scheduling tasks and vector used to gather
   // completed tasks.
   TaskGraph graph_;
   Task::Vector completed_tasks_;
 
+  base::Lock lock_;
+  // |lock_| must be acquired when accessing the following members.
+  CopyOperation::Deque pending_copy_operations_;
+  CopySequenceNumber next_copy_operation_sequence_;
+
+  base::WeakPtrFactory<OneCopyRasterWorkerPool> weak_ptr_factory_;
+  // "raster finished" tasks need their own factory as they need to be
+  // canceled when ScheduleTasks() is called.
   base::WeakPtrFactory<OneCopyRasterWorkerPool>
       raster_finished_weak_ptr_factory_;
 
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
index d9b10be1..c35da96 100644
--- a/cc/resources/picture.cc
+++ b/cc/resources/picture.cc
@@ -18,17 +18,16 @@
 #include "cc/debug/traced_value.h"
 #include "cc/layers/content_layer_client.h"
 #include "skia/ext/pixel_ref_utils.h"
+#include "third_party/skia/include/core/SkBBHFactory.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkData.h"
-#include "third_party/skia/include/core/SkDrawFilter.h"
 #include "third_party/skia/include/core/SkPaint.h"
 #include "third_party/skia/include/core/SkPictureRecorder.h"
 #include "third_party/skia/include/core/SkStream.h"
 #include "third_party/skia/include/utils/SkNullCanvas.h"
-#include "third_party/skia/include/utils/SkPictureUtils.h"
 #include "ui/gfx/codec/jpeg_codec.h"
 #include "ui/gfx/codec/png_codec.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/skia_util.h"
 
 namespace cc {
diff --git a/cc/resources/picture.h b/cc/resources/picture.h
index e0b64412..1677309 100644
--- a/cc/resources/picture.h
+++ b/cc/resources/picture.h
@@ -21,7 +21,7 @@
 #include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkBBHFactory.h"
 #include "third_party/skia/include/core/SkPicture.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 class SkPixelRef;
 
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index f47c700..4dc46e0 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -15,10 +15,10 @@
 #include "cc/base/math_util.h"
 #include "cc/resources/tile.h"
 #include "cc/resources/tile_priority.h"
-#include "ui/gfx/point_conversions.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/safe_integer_conversions.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/safe_integer_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 namespace {
@@ -539,7 +539,8 @@
     float ideal_contents_scale,
     double current_frame_time_in_seconds,
     const Occlusion& occlusion_in_layer_space) {
-  if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
+  if (!NeedsUpdateForFrameAtTimeAndViewport(current_frame_time_in_seconds,
+                                            viewport_in_layer_space)) {
     // This should never be zero for the purposes of has_ever_been_updated().
     DCHECK_NE(current_frame_time_in_seconds, 0.0);
     return;
@@ -550,6 +551,7 @@
 
   if (tiling_size().IsEmpty()) {
     last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
+    last_viewport_in_layer_space_ = viewport_in_layer_space;
     last_visible_rect_in_content_space_ = visible_rect_in_content_space;
     return;
   }
@@ -587,6 +589,7 @@
   SetLiveTilesRect(eventually_rect);
 
   last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
+  last_viewport_in_layer_space_ = viewport_in_layer_space;
   last_visible_rect_in_content_space_ = visible_rect_in_content_space;
 
   eviction_tiles_cache_valid_ = false;
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index a12b1d2..f692702 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -18,7 +18,7 @@
 #include "cc/resources/tile.h"
 #include "cc/resources/tile_priority.h"
 #include "cc/trees/occlusion.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace base {
 namespace debug {
@@ -262,8 +262,11 @@
                                 double current_frame_time_in_seconds,
                                 const Occlusion& occlusion_in_layer_space);
 
-  bool NeedsUpdateForFrameAtTime(double frame_time_in_seconds) {
-    return frame_time_in_seconds != last_impl_frame_time_in_seconds_;
+  bool NeedsUpdateForFrameAtTimeAndViewport(
+      double frame_time_in_seconds,
+      const gfx::Rect& viewport_in_layer_space) {
+    return frame_time_in_seconds != last_impl_frame_time_in_seconds_ ||
+           viewport_in_layer_space != last_viewport_in_layer_space_;
   }
 
   void GetAllTilesForTracing(std::set<const Tile*>* tiles) const;
@@ -340,6 +343,7 @@
 
   // State saved for computing velocities based upon finite differences.
   double last_impl_frame_time_in_seconds_;
+  gfx::Rect last_viewport_in_layer_space_;
   gfx::Rect last_visible_rect_in_content_space_;
   float content_to_screen_scale_;
 
diff --git a/cc/resources/picture_layer_tiling_perftest.cc b/cc/resources/picture_layer_tiling_perftest.cc
index 9cc3a59..8f91763 100644
--- a/cc/resources/picture_layer_tiling_perftest.cc
+++ b/cc/resources/picture_layer_tiling_perftest.cc
@@ -40,8 +40,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false).Pass();
+                                                  1).Pass();
   }
 
   virtual void SetUp() override {
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
index 1806ebc..96b47a6 100644
--- a/cc/resources/picture_layer_tiling_set.cc
+++ b/cc/resources/picture_layer_tiling_set.cc
@@ -19,12 +19,8 @@
 
 }  // namespace
 
-
-PictureLayerTilingSet::PictureLayerTilingSet(
-    PictureLayerTilingClient* client,
-    const gfx::Size& layer_bounds)
-    : client_(client),
-      layer_bounds_(layer_bounds) {
+PictureLayerTilingSet::PictureLayerTilingSet(PictureLayerTilingClient* client)
+    : client_(client) {
 }
 
 PictureLayerTilingSet::~PictureLayerTilingSet() {
@@ -47,7 +43,6 @@
                                         float minimum_contents_scale) {
   if (new_layer_bounds.IsEmpty()) {
     RemoveAllTilings();
-    layer_bounds_ = new_layer_bounds;
     return false;
   }
 
@@ -99,17 +94,17 @@
   }
   tilings_.sort(LargestToSmallestScaleFunctor());
 
-  layer_bounds_ = new_layer_bounds;
   return have_high_res_tiling;
 }
 
-PictureLayerTiling* PictureLayerTilingSet::AddTiling(float contents_scale) {
+PictureLayerTiling* PictureLayerTilingSet::AddTiling(
+    float contents_scale,
+    const gfx::Size& layer_bounds) {
   for (size_t i = 0; i < tilings_.size(); ++i)
     DCHECK_NE(tilings_[i]->contents_scale(), contents_scale);
 
-  tilings_.push_back(PictureLayerTiling::Create(contents_scale,
-                                                layer_bounds_,
-                                                client_));
+  tilings_.push_back(
+      PictureLayerTiling::Create(contents_scale, layer_bounds, client_));
   PictureLayerTiling* appended = tilings_.back();
 
   tilings_.sort(LargestToSmallestScaleFunctor());
diff --git a/cc/resources/picture_layer_tiling_set.h b/cc/resources/picture_layer_tiling_set.h
index 63f3110..ddde1d7b 100644
--- a/cc/resources/picture_layer_tiling_set.h
+++ b/cc/resources/picture_layer_tiling_set.h
@@ -8,7 +8,7 @@
 #include "cc/base/region.h"
 #include "cc/base/scoped_ptr_vector.h"
 #include "cc/resources/picture_layer_tiling.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace base {
 namespace debug {
@@ -34,8 +34,7 @@
     size_t end;
   };
 
-  PictureLayerTilingSet(PictureLayerTilingClient* client,
-                        const gfx::Size& layer_bounds);
+  explicit PictureLayerTilingSet(PictureLayerTilingClient* client);
   ~PictureLayerTilingSet();
 
   void SetClient(PictureLayerTilingClient* client);
@@ -53,9 +52,8 @@
                    const Region& layer_invalidation,
                    float minimum_contents_scale);
 
-  gfx::Size layer_bounds() const { return layer_bounds_; }
-
-  PictureLayerTiling* AddTiling(float contents_scale);
+  PictureLayerTiling* AddTiling(float contents_scale,
+                                const gfx::Size& layer_bounds);
   size_t num_tilings() const { return tilings_.size(); }
   int NumHighResTilings() const;
   PictureLayerTiling* tiling_at(size_t idx) { return tilings_[idx]; }
@@ -126,7 +124,6 @@
 
  private:
   PictureLayerTilingClient* client_;
-  gfx::Size layer_bounds_;
   ScopedPtrVector<PictureLayerTiling> tilings_;
 
   friend class Iterator;
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index f4059e4..2005175 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -7,15 +7,13 @@
 #include <map>
 #include <vector>
 
-#include "cc/resources/resource_pool.h"
 #include "cc/resources/resource_provider.h"
 #include "cc/test/fake_output_surface.h"
 #include "cc/test/fake_output_surface_client.h"
 #include "cc/test/fake_picture_layer_tiling_client.h"
-#include "cc/test/fake_tile_manager_client.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 namespace {
@@ -23,12 +21,12 @@
 TEST(PictureLayerTilingSetTest, NoResources) {
   FakePictureLayerTilingClient client;
   gfx::Size layer_bounds(1000, 800);
-  PictureLayerTilingSet set(&client, layer_bounds);
+  PictureLayerTilingSet set(&client);
   client.SetTileSize(gfx::Size(256, 256));
 
-  set.AddTiling(1.0);
-  set.AddTiling(1.5);
-  set.AddTiling(2.0);
+  set.AddTiling(1.0, layer_bounds);
+  set.AddTiling(1.5, layer_bounds);
+  set.AddTiling(2.0, layer_bounds);
 
   float contents_scale = 2.0;
   gfx::Size content_bounds(
@@ -64,14 +62,14 @@
   PictureLayerTiling* high_res_tiling;
   PictureLayerTiling* low_res_tiling;
 
-  PictureLayerTilingSet set(&client, layer_bounds);
-  set.AddTiling(2.0);
-  high_res_tiling = set.AddTiling(1.0);
+  PictureLayerTilingSet set(&client);
+  set.AddTiling(2.0, layer_bounds);
+  high_res_tiling = set.AddTiling(1.0, layer_bounds);
   high_res_tiling->set_resolution(HIGH_RESOLUTION);
-  set.AddTiling(0.5);
-  low_res_tiling = set.AddTiling(0.25);
+  set.AddTiling(0.5, layer_bounds);
+  low_res_tiling = set.AddTiling(0.25, layer_bounds);
   low_res_tiling->set_resolution(LOW_RESOLUTION);
-  set.AddTiling(0.125);
+  set.AddTiling(0.125, layer_bounds);
 
   higher_than_high_res_range =
       set.GetTilingRange(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
@@ -96,12 +94,12 @@
   EXPECT_EQ(4u, lower_than_low_res_range.start);
   EXPECT_EQ(5u, lower_than_low_res_range.end);
 
-  PictureLayerTilingSet set_without_low_res(&client, layer_bounds);
-  set_without_low_res.AddTiling(2.0);
-  high_res_tiling = set_without_low_res.AddTiling(1.0);
+  PictureLayerTilingSet set_without_low_res(&client);
+  set_without_low_res.AddTiling(2.0, layer_bounds);
+  high_res_tiling = set_without_low_res.AddTiling(1.0, layer_bounds);
   high_res_tiling->set_resolution(HIGH_RESOLUTION);
-  set_without_low_res.AddTiling(0.5);
-  set_without_low_res.AddTiling(0.25);
+  set_without_low_res.AddTiling(0.5, layer_bounds);
+  set_without_low_res.AddTiling(0.25, layer_bounds);
 
   higher_than_high_res_range = set_without_low_res.GetTilingRange(
       PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
@@ -126,10 +124,10 @@
       PictureLayerTilingSet::LOWER_THAN_LOW_RES);
   EXPECT_EQ(0u, lower_than_low_res_range.end - lower_than_low_res_range.start);
 
-  PictureLayerTilingSet set_with_only_high_and_low_res(&client, layer_bounds);
-  high_res_tiling = set_with_only_high_and_low_res.AddTiling(1.0);
+  PictureLayerTilingSet set_with_only_high_and_low_res(&client);
+  high_res_tiling = set_with_only_high_and_low_res.AddTiling(1.0, layer_bounds);
   high_res_tiling->set_resolution(HIGH_RESOLUTION);
-  low_res_tiling = set_with_only_high_and_low_res.AddTiling(0.5);
+  low_res_tiling = set_with_only_high_and_low_res.AddTiling(0.5, layer_bounds);
   low_res_tiling->set_resolution(LOW_RESOLUTION);
 
   higher_than_high_res_range = set_with_only_high_and_low_res.GetTilingRange(
@@ -158,8 +156,8 @@
       PictureLayerTilingSet::LOWER_THAN_LOW_RES);
   EXPECT_EQ(0u, lower_than_low_res_range.end - lower_than_low_res_range.start);
 
-  PictureLayerTilingSet set_with_only_high_res(&client, layer_bounds);
-  high_res_tiling = set_with_only_high_res.AddTiling(1.0);
+  PictureLayerTilingSet set_with_only_high_res(&client);
+  high_res_tiling = set_with_only_high_res.AddTiling(1.0, layer_bounds);
   high_res_tiling->set_resolution(HIGH_RESOLUTION);
 
   higher_than_high_res_range = set_with_only_high_res.GetTilingRange(
@@ -209,18 +207,17 @@
                                  NULL,
                                  0,
                                  false,
-                                 1,
-                                 false);
+                                 1);
 
     FakePictureLayerTilingClient client(resource_provider.get());
     client.SetTileSize(gfx::Size(256, 256));
     client.set_tree(PENDING_TREE);
     gfx::Size layer_bounds(1000, 800);
-    PictureLayerTilingSet set(&client, layer_bounds);
+    PictureLayerTilingSet set(&client);
 
     float scale = min_scale;
     for (int i = 0; i < num_tilings; ++i, scale += scale_increment) {
-      PictureLayerTiling* tiling = set.AddTiling(scale);
+      PictureLayerTiling* tiling = set.AddTiling(scale, layer_bounds);
       tiling->CreateAllTilesForTesting();
       std::vector<Tile*> tiles = tiling->AllTilesForTesting();
       client.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
@@ -298,8 +295,8 @@
     source_client_.set_tree(PENDING_TREE);
     target_client_.SetTileSize(tile_size_);
     target_client_.set_tree(PENDING_TREE);
-    source_.reset(new PictureLayerTilingSet(&source_client_, source_bounds_));
-    target_.reset(new PictureLayerTilingSet(&target_client_, target_bounds_));
+    source_.reset(new PictureLayerTilingSet(&source_client_));
+    target_.reset(new PictureLayerTilingSet(&target_client_));
   }
 
   // Sync from source to target.
@@ -329,7 +326,6 @@
   void VerifyTargetEqualsSource(const gfx::Size& new_bounds) {
     ASSERT_FALSE(new_bounds.IsEmpty());
     EXPECT_EQ(target_->num_tilings(), source_->num_tilings());
-    EXPECT_EQ(target_->layer_bounds().ToString(), new_bounds.ToString());
 
     for (size_t i = 0; i < target_->num_tilings(); ++i) {
       ASSERT_GT(source_->num_tilings(), i);
@@ -404,21 +400,20 @@
 TEST_F(PictureLayerTilingSetSyncTest, EmptyBounds) {
   float source_scales[] = {1.f, 1.2f};
   for (size_t i = 0; i < arraysize(source_scales); ++i)
-    source_->AddTiling(source_scales[i]);
+    source_->AddTiling(source_scales[i], source_bounds_);
 
-  gfx::Size new_bounds;
-  SyncTilings(new_bounds);
+  gfx::Size empty_bounds;
+  SyncTilings(empty_bounds);
   EXPECT_EQ(target_->num_tilings(), 0u);
-  EXPECT_EQ(target_->layer_bounds().ToString(), new_bounds.ToString());
 }
 
 TEST_F(PictureLayerTilingSetSyncTest, AllNew) {
   float source_scales[] = {0.5f, 1.f, 1.2f};
   for (size_t i = 0; i < arraysize(source_scales); ++i)
-    source_->AddTiling(source_scales[i]);
+    source_->AddTiling(source_scales[i], source_bounds_);
   float target_scales[] = {0.75f, 1.4f, 3.f};
   for (size_t i = 0; i < arraysize(target_scales); ++i)
-    target_->AddTiling(target_scales[i]);
+    target_->AddTiling(target_scales[i], target_bounds_);
 
   gfx::Size new_bounds(15, 40);
   SyncTilings(new_bounds);
@@ -437,10 +432,10 @@
 TEST_F(PictureLayerTilingSetSyncTest, KeepExisting) {
   float source_scales[] = {0.7f, 1.f, 1.1f, 2.f};
   for (size_t i = 0; i < arraysize(source_scales); ++i)
-    source_->AddTiling(source_scales[i]);
+    source_->AddTiling(source_scales[i], source_bounds_);
   float target_scales[] = {0.5f, 1.f, 2.f};
   for (size_t i = 0; i < arraysize(target_scales); ++i)
-    target_->AddTiling(target_scales[i]);
+    target_->AddTiling(target_scales[i], target_bounds_);
 
   PictureLayerTiling* tiling1 = source_->TilingAtScale(1.f);
   ASSERT_TRUE(tiling1);
@@ -472,7 +467,7 @@
 TEST_F(PictureLayerTilingSetSyncTest, EmptySet) {
   float target_scales[] = {0.2f, 1.f};
   for (size_t i = 0; i < arraysize(target_scales); ++i)
-    target_->AddTiling(target_scales[i]);
+    target_->AddTiling(target_scales[i], target_bounds_);
 
   gfx::Size new_bounds(15, 40);
   SyncTilings(new_bounds);
@@ -482,10 +477,10 @@
 TEST_F(PictureLayerTilingSetSyncTest, MinimumScale) {
   float source_scales[] = {0.7f, 1.f, 1.1f, 2.f};
   for (size_t i = 0; i < arraysize(source_scales); ++i)
-    source_->AddTiling(source_scales[i]);
+    source_->AddTiling(source_scales[i], source_bounds_);
   float target_scales[] = {0.5f, 0.7f, 1.f, 1.1f, 2.f};
   for (size_t i = 0; i < arraysize(target_scales); ++i)
-    target_->AddTiling(target_scales[i]);
+    target_->AddTiling(target_scales[i], target_bounds_);
 
   gfx::Size new_bounds(15, 40);
   float minimum_scale = 1.5f;
@@ -497,8 +492,8 @@
 }
 
 TEST_F(PictureLayerTilingSetSyncTest, Invalidation) {
-  source_->AddTiling(2.f);
-  target_->AddTiling(2.f);
+  source_->AddTiling(2.f, source_bounds_);
+  target_->AddTiling(2.f, target_bounds_);
   target_->tiling_at(0)->CreateAllTilesForTesting();
 
   Region layer_invalidation;
@@ -535,8 +530,8 @@
 }
 
 TEST_F(PictureLayerTilingSetSyncTest, TileSizeChange) {
-  source_->AddTiling(1.f);
-  target_->AddTiling(1.f);
+  source_->AddTiling(1.f, source_bounds_);
+  target_->AddTiling(1.f, target_bounds_);
 
   target_->tiling_at(0)->CreateAllTilesForTesting();
   std::vector<Tile*> original_tiles =
diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc
index c871da4..2952c6a 100644
--- a/cc/resources/picture_layer_tiling_unittest.cc
+++ b/cc/resources/picture_layer_tiling_unittest.cc
@@ -15,8 +15,9 @@
 #include "cc/test/test_context_provider.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 namespace {
@@ -1262,15 +1263,8 @@
   scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d();
   CHECK(output_surface->BindToClient(&output_surface_client));
   TestSharedBitmapManager shared_bitmap_manager;
-  scoped_ptr<ResourceProvider> resource_provider =
-      ResourceProvider::Create(output_surface.get(),
-                               &shared_bitmap_manager,
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1,
-                               false);
+  scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
+      output_surface.get(), &shared_bitmap_manager, NULL, NULL, 0, false, 1);
 
   FakePictureLayerTilingClient client(resource_provider.get());
   scoped_ptr<TestablePictureLayerTiling> tiling;
@@ -1463,9 +1457,9 @@
   client_.SetTileSize(tile_size);
   client_.set_tree(PENDING_TREE);
 
-  PictureLayerTilingSet active_set(&client_, layer_bounds);
+  PictureLayerTilingSet active_set(&client_);
 
-  active_set.AddTiling(1.f);
+  active_set.AddTiling(1.f, layer_bounds);
 
   VerifyTiles(active_set.tiling_at(0),
               1.f,
@@ -1485,7 +1479,7 @@
               base::Bind(&TileExists, true));
 
   // Add the same tilings to the pending set.
-  PictureLayerTilingSet pending_set(&client_, layer_bounds);
+  PictureLayerTilingSet pending_set(&client_);
   Region invalidation;
   pending_set.SyncTilings(active_set, layer_bounds, invalidation, 0.f);
 
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index 93464f6..372bcbd 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -10,9 +10,8 @@
 
 #include "cc/base/region.h"
 #include "cc/debug/rendering_stats_instrumentation.h"
-#include "cc/resources/picture_pile_impl.h"
 #include "cc/resources/raster_worker_pool.h"
-#include "cc/resources/tile_priority.h"
+#include "skia/ext/analysis_canvas.h"
 
 namespace {
 // Layout pixel buffer around the visible layer rect to record.  Any base
diff --git a/cc/resources/picture_pile.h b/cc/resources/picture_pile.h
index d68387f..595ded4 100644
--- a/cc/resources/picture_pile.h
+++ b/cc/resources/picture_pile.h
@@ -6,7 +6,7 @@
 #define CC_RESOURCES_PICTURE_PILE_H_
 
 #include "cc/resources/picture_pile_base.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 class PicturePileImpl;
diff --git a/cc/resources/picture_pile_base.cc b/cc/resources/picture_pile_base.cc
index d850e41..45db791 100644
--- a/cc/resources/picture_pile_base.cc
+++ b/cc/resources/picture_pile_base.cc
@@ -11,10 +11,9 @@
 #include "base/debug/trace_event_argument.h"
 #include "base/logging.h"
 #include "base/values.h"
-#include "cc/base/math_util.h"
 #include "cc/debug/traced_value.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 
 namespace {
 // Dimensions of the tiles in this picture pile as well as the dimensions of
diff --git a/cc/resources/picture_pile_base.h b/cc/resources/picture_pile_base.h
index 991a29c..bb9116c 100644
--- a/cc/resources/picture_pile_base.h
+++ b/cc/resources/picture_pile_base.h
@@ -15,7 +15,7 @@
 #include "cc/base/region.h"
 #include "cc/base/tiling_data.h"
 #include "cc/resources/picture.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace base {
 namespace debug {
diff --git a/cc/resources/picture_pile_impl.cc b/cc/resources/picture_pile_impl.cc
index f4fbdf2d..e8cee1e 100644
--- a/cc/resources/picture_pile_impl.cc
+++ b/cc/resources/picture_pile_impl.cc
@@ -12,10 +12,7 @@
 #include "skia/ext/analysis_canvas.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPictureRecorder.h"
-#include "third_party/skia/include/core/SkSize.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
-#include "ui/gfx/skia_util.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 
 namespace cc {
 
@@ -28,11 +25,13 @@
   return make_scoped_refptr(new PicturePileImpl(other));
 }
 
-PicturePileImpl::PicturePileImpl() {
+PicturePileImpl::PicturePileImpl()
+    : likely_to_be_used_for_transform_animation_(false) {
 }
 
 PicturePileImpl::PicturePileImpl(const PicturePileBase* other)
-    : PicturePileBase(other) {
+    : PicturePileBase(other),
+      likely_to_be_used_for_transform_animation_(false) {
 }
 
 PicturePileImpl::~PicturePileImpl() {
diff --git a/cc/resources/picture_pile_impl.h b/cc/resources/picture_pile_impl.h
index a9bef0c7..243601ea 100644
--- a/cc/resources/picture_pile_impl.h
+++ b/cc/resources/picture_pile_impl.h
@@ -58,6 +58,13 @@
 
   skia::RefPtr<SkPicture> GetFlattenedPicture();
 
+  bool likely_to_be_used_for_transform_animation() const {
+    return likely_to_be_used_for_transform_animation_;
+  }
+  void set_likely_to_be_used_for_transform_animation() {
+    likely_to_be_used_for_transform_animation_ = true;
+  }
+
   struct CC_EXPORT Analysis {
     Analysis();
     ~Analysis();
@@ -124,6 +131,8 @@
       RenderingStatsInstrumentation* rendering_stats_instrumentation,
       bool is_analysis) const;
 
+  bool likely_to_be_used_for_transform_animation_;
+
   DISALLOW_COPY_AND_ASSIGN(PicturePileImpl);
 };
 
diff --git a/cc/resources/picture_pile_impl_unittest.cc b/cc/resources/picture_pile_impl_unittest.cc
index d0daa6b..0ced279 100644
--- a/cc/resources/picture_pile_impl_unittest.cc
+++ b/cc/resources/picture_pile_impl_unittest.cc
@@ -10,8 +10,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkPixelRef.h"
 #include "third_party/skia/include/core/SkShader.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 namespace {
diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc
index 881055f3..537872da 100644
--- a/cc/resources/picture_pile_unittest.cc
+++ b/cc/resources/picture_pile_unittest.cc
@@ -9,8 +9,8 @@
 #include "cc/test/fake_content_layer_client.h"
 #include "cc/test/fake_rendering_stats_instrumentation.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 namespace {
diff --git a/cc/resources/picture_unittest.cc b/cc/resources/picture_unittest.cc
index 4abeceb5..07faf0c 100644
--- a/cc/resources/picture_unittest.cc
+++ b/cc/resources/picture_unittest.cc
@@ -11,10 +11,8 @@
 #include "cc/test/skia_common.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBBHFactory.h"
-#include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkGraphics.h"
-#include "third_party/skia/include/core/SkPixelRef.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/skia_util.h"
 
 namespace cc {
diff --git a/cc/resources/prioritized_resource.h b/cc/resources/prioritized_resource.h
index 7920f81..e3bb2bc 100644
--- a/cc/resources/prioritized_resource.h
+++ b/cc/resources/prioritized_resource.h
@@ -9,12 +9,11 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
-#include "cc/resources/priority_calculator.h"
 #include "cc/resources/resource.h"
 #include "cc/resources/resource_provider.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
-#include "ui/gfx/vector2d.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d.h"
 
 namespace cc {
 
diff --git a/cc/resources/prioritized_resource_manager.cc b/cc/resources/prioritized_resource_manager.cc
index 54ed308..657c14f 100644
--- a/cc/resources/prioritized_resource_manager.cc
+++ b/cc/resources/prioritized_resource_manager.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 
 #include "base/debug/trace_event.h"
-#include "base/stl_util.h"
 #include "cc/resources/prioritized_resource.h"
 #include "cc/resources/priority_calculator.h"
 #include "cc/trees/proxy.h"
diff --git a/cc/resources/prioritized_resource_manager.h b/cc/resources/prioritized_resource_manager.h
index 681fee35..b7583f4 100644
--- a/cc/resources/prioritized_resource_manager.h
+++ b/cc/resources/prioritized_resource_manager.h
@@ -16,12 +16,10 @@
 #include "cc/resources/prioritized_resource.h"
 #include "cc/resources/priority_calculator.h"
 #include "cc/resources/resource.h"
-#include "cc/trees/proxy.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
-class PriorityCalculator;
 class Proxy;
 
 class CC_EXPORT PrioritizedResourceManager {
diff --git a/cc/resources/prioritized_resource_unittest.cc b/cc/resources/prioritized_resource_unittest.cc
index 5109a602..8869e706 100644
--- a/cc/resources/prioritized_resource_unittest.cc
+++ b/cc/resources/prioritized_resource_unittest.cc
@@ -34,8 +34,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false);
+                                                  1);
   }
 
   virtual ~PrioritizedResourceTest() {
diff --git a/cc/resources/priority_calculator.cc b/cc/resources/priority_calculator.cc
index 2a0cd18..5f5916fda 100644
--- a/cc/resources/priority_calculator.cc
+++ b/cc/resources/priority_calculator.cc
@@ -6,7 +6,7 @@
 
 #include <algorithm>
 
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/resources/raster_tile_priority_queue.cc b/cc/resources/raster_tile_priority_queue.cc
index daf4567..667d54d 100644
--- a/cc/resources/raster_tile_priority_queue.cc
+++ b/cc/resources/raster_tile_priority_queue.cc
@@ -17,7 +17,7 @@
       const RasterTilePriorityQueue::PairedPictureLayerQueue* a,
       const RasterTilePriorityQueue::PairedPictureLayerQueue* b) const {
     // Note that in this function, we have to return true if and only if
-    // b is strictly lower priority than a. Note that for the sake of
+    // a is strictly lower priority than b. Note that for the sake of
     // completeness, empty queue is considered to have lowest priority.
     if (a->IsEmpty() || b->IsEmpty())
       return b->IsEmpty() < a->IsEmpty();
@@ -39,6 +39,22 @@
         b_tile->priority_for_tree_priority(tree_priority_);
     bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY;
 
+    // In smoothness mode, we should return pending NOW tiles before active
+    // EVENTUALLY tiles. So if both priorities here are eventually, we need to
+    // check the pending priority.
+    if (prioritize_low_res &&
+        a_priority.priority_bin == TilePriority::EVENTUALLY &&
+        b_priority.priority_bin == TilePriority::EVENTUALLY) {
+      bool a_is_pending_now =
+          a_tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW;
+      bool b_is_pending_now =
+          b_tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW;
+      if (a_is_pending_now || b_is_pending_now)
+        return a_is_pending_now < b_is_pending_now;
+
+      // In case neither one is pending now, fall through.
+    }
+
     // If the bin is the same but the resolution is not, then the order will be
     // determined by whether we prioritize low res or not.
     // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile
@@ -56,6 +72,7 @@
         return b_priority.resolution == LOW_RESOLUTION;
       return b_priority.resolution == HIGH_RESOLUTION;
     }
+
     return b_priority.IsHigherPriorityThan(a_priority);
   }
 
diff --git a/cc/resources/raster_worker_pool_perftest.cc b/cc/resources/raster_worker_pool_perftest.cc
index 4264373b..0f7a845 100644
--- a/cc/resources/raster_worker_pool_perftest.cc
+++ b/cc/resources/raster_worker_pool_perftest.cc
@@ -262,7 +262,8 @@
         raster_worker_pool_ =
             GpuRasterWorkerPool::Create(task_runner_.get(),
                                         context_provider_.get(),
-                                        resource_provider_.get());
+                                        resource_provider_.get(),
+                                        false);
         break;
       case RASTER_WORKER_POOL_TYPE_BITMAP:
         CreateSoftwareOutputSurfaceAndResourceProvider();
@@ -406,8 +407,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false).Pass();
+                                                  1).Pass();
   }
 
   void CreateSoftwareOutputSurfaceAndResourceProvider() {
@@ -420,8 +420,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false).Pass();
+                                                  1).Pass();
   }
 
   std::string TestModifierString() const {
@@ -491,7 +490,7 @@
     CHECK(output_surface_->BindToClient(&output_surface_client_));
     resource_provider_ =
         ResourceProvider::Create(
-            output_surface_.get(), NULL, NULL, NULL, 0, false, 1, false).Pass();
+            output_surface_.get(), NULL, NULL, NULL, 0, false, 1).Pass();
   }
 
   void RunBuildRasterTaskQueueTest(const std::string& test_name,
diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc
index 22271280..a6d6c65 100644
--- a/cc/resources/raster_worker_pool_unittest.cc
+++ b/cc/resources/raster_worker_pool_unittest.cc
@@ -164,7 +164,8 @@
         raster_worker_pool_ =
             GpuRasterWorkerPool::Create(base::MessageLoopProxy::current().get(),
                                         context_provider_.get(),
-                                        resource_provider_.get());
+                                        resource_provider_.get(),
+                                        false);
         break;
       case RASTER_WORKER_POOL_TYPE_BITMAP:
         CreateSoftwareOutputSurfaceAndResourceProvider();
@@ -279,8 +280,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false).Pass();
+                                                  1).Pass();
   }
 
   void CreateSoftwareOutputSurfaceAndResourceProvider() {
@@ -293,8 +293,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false).Pass();
+                                                  1).Pass();
   }
 
   void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
diff --git a/cc/resources/resource.h b/cc/resources/resource.h
index 24cb88a..707d77e 100644
--- a/cc/resources/resource.h
+++ b/cc/resources/resource.h
@@ -8,7 +8,7 @@
 #include "cc/base/cc_export.h"
 #include "cc/resources/resource_provider.h"
 #include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 1697ac2..a37789a 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -27,9 +27,9 @@
 #include "third_party/skia/include/core/SkSurface.h"
 #include "third_party/skia/include/gpu/GrContext.h"
 #include "ui/gfx/frame_time.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
 #include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/vector2d.h"
 
 using gpu::gles2::GLES2Interface;
 
@@ -411,8 +411,7 @@
     BlockingTaskRunner* blocking_main_thread_task_runner,
     int highp_threshold_min,
     bool use_rgba_4444_texture_format,
-    size_t id_allocation_chunk_size,
-    bool use_distance_field_text) {
+    size_t id_allocation_chunk_size) {
   scoped_ptr<ResourceProvider> resource_provider(
       new ResourceProvider(output_surface,
                            shared_bitmap_manager,
@@ -420,8 +419,7 @@
                            blocking_main_thread_task_runner,
                            highp_threshold_min,
                            use_rgba_4444_texture_format,
-                           id_allocation_chunk_size,
-                           use_distance_field_text));
+                           id_allocation_chunk_size));
 
   if (resource_provider->ContextGL())
     resource_provider->InitializeGL();
@@ -995,38 +993,12 @@
   resource->read_lock_fences_enabled = true;
 }
 
-const ResourceProvider::Resource* ResourceProvider::LockForWriteToSkSurface(
-    ResourceId id) {
+void ResourceProvider::LockForWriteToSkSurface(ResourceId id) {
   Resource* resource = GetResource(id);
   DCHECK_EQ(GLTexture, resource->type);
   DCHECK(CanLockForWrite(id));
 
   resource->locked_for_write = true;
-  if (!resource->sk_surface) {
-    class GrContext* gr_context = GrContext();
-    // TODO(alokp): Implement TestContextProvider::GrContext().
-    if (!gr_context)
-      return resource;
-
-    LazyAllocate(resource);
-
-    GrBackendTextureDesc desc;
-    desc.fFlags = kRenderTarget_GrBackendTextureFlag;
-    desc.fWidth = resource->size.width();
-    desc.fHeight = resource->size.height();
-    desc.fConfig = ToGrPixelConfig(resource->format);
-    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
-    desc.fTextureHandle = resource->gl_id;
-    skia::RefPtr<GrTexture> gr_texture =
-        skia::AdoptRef(gr_context->wrapBackendTexture(desc));
-    SkSurface::TextRenderMode text_render_mode =
-        use_distance_field_text_ ? SkSurface::kDistanceField_TextRenderMode
-                                 : SkSurface::kStandard_TextRenderMode;
-    resource->sk_surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
-        gr_texture->asRenderTarget(), text_render_mode));
-  }
-
-  return resource;
 }
 
 void ResourceProvider::UnlockForWriteToSkSurface(ResourceId id) {
@@ -1141,16 +1113,49 @@
 ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr(
     ResourceProvider* resource_provider,
     ResourceProvider::ResourceId resource_id)
-    : resource_provider_(resource_provider),
-      resource_id_(resource_id),
-      sk_surface_(resource_provider->LockForWriteToSkSurface(resource_id)
-                      ->sk_surface.get()) {
+    : resource_provider_(resource_provider), resource_id_(resource_id) {
+  resource_provider->LockForWriteToSkSurface(resource_id);
 }
 
 ResourceProvider::ScopedWriteLockGr::~ScopedWriteLockGr() {
   resource_provider_->UnlockForWriteToSkSurface(resource_id_);
 }
 
+SkSurface* ResourceProvider::ScopedWriteLockGr::GetSkSurface(
+    bool use_distance_field_text) {
+  Resource* resource = resource_provider_->GetResource(resource_id_);
+  DCHECK(resource->locked_for_write);
+
+  // If the surface doesn't exist, or doesn't have the correct dff setting,
+  // recreate the surface within the resource.
+  if (!resource->sk_surface ||
+      use_distance_field_text !=
+          resource->sk_surface->props().isUseDistanceFieldFonts()) {
+    class GrContext* gr_context = resource_provider_->GrContext();
+    // TODO(alokp): Implement TestContextProvider::GrContext().
+    if (!gr_context)
+      return nullptr;
+
+    resource_provider_->LazyAllocate(resource);
+
+    GrBackendTextureDesc desc;
+    desc.fFlags = kRenderTarget_GrBackendTextureFlag;
+    desc.fWidth = resource->size.width();
+    desc.fHeight = resource->size.height();
+    desc.fConfig = ToGrPixelConfig(resource->format);
+    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
+    desc.fTextureHandle = resource->gl_id;
+    skia::RefPtr<GrTexture> gr_texture =
+        skia::AdoptRef(gr_context->wrapBackendTexture(desc));
+    SkSurface::TextRenderMode text_render_mode =
+        use_distance_field_text ? SkSurface::kDistanceField_TextRenderMode
+                                : SkSurface::kStandard_TextRenderMode;
+    resource->sk_surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
+        gr_texture->asRenderTarget(), text_render_mode));
+  }
+  return resource->sk_surface.get();
+}
+
 ResourceProvider::ResourceProvider(
     OutputSurface* output_surface,
     SharedBitmapManager* shared_bitmap_manager,
@@ -1158,8 +1163,7 @@
     BlockingTaskRunner* blocking_main_thread_task_runner,
     int highp_threshold_min,
     bool use_rgba_4444_texture_format,
-    size_t id_allocation_chunk_size,
-    bool use_distance_field_text)
+    size_t id_allocation_chunk_size)
     : output_surface_(output_surface),
       shared_bitmap_manager_(shared_bitmap_manager),
       gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
@@ -1177,8 +1181,7 @@
       best_texture_format_(RGBA_8888),
       use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
       id_allocation_chunk_size_(id_allocation_chunk_size),
-      use_sync_query_(false),
-      use_distance_field_text_(use_distance_field_text) {
+      use_sync_query_(false) {
   DCHECK(output_surface_->HasClient());
   DCHECK(id_allocation_chunk_size_);
 }
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index 1e70132..2e2fecb 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -31,7 +31,7 @@
 #include "third_party/khronos/GLES2/gl2ext.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 class GrContext;
 
@@ -83,8 +83,7 @@
       BlockingTaskRunner* blocking_main_thread_task_runner,
       int highp_threshold_min,
       bool use_rgba_4444_texture_format,
-      size_t id_allocation_chunk_size,
-      bool use_distance_field_text);
+      size_t id_allocation_chunk_size);
   virtual ~ResourceProvider();
 
   void InitializeSoftware();
@@ -328,12 +327,11 @@
                       ResourceProvider::ResourceId resource_id);
     ~ScopedWriteLockGr();
 
-    SkSurface* sk_surface() { return sk_surface_; }
+    SkSurface* GetSkSurface(bool use_distance_field_text);
 
    private:
     ResourceProvider* resource_provider_;
     ResourceProvider::ResourceId resource_id_;
-    SkSurface* sk_surface_;
 
     DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGr);
   };
@@ -488,8 +486,7 @@
                    BlockingTaskRunner* blocking_main_thread_task_runner,
                    int highp_threshold_min,
                    bool use_rgba_4444_texture_format,
-                   size_t id_allocation_chunk_size,
-                   bool use_distance_field_text);
+                   size_t id_allocation_chunk_size);
 
   void CleanUpGLIfNeeded();
 
@@ -500,7 +497,7 @@
   void UnlockForWrite(ResourceId id);
   const Resource* LockForWriteToGpuMemoryBuffer(ResourceId id);
   void UnlockForWriteToGpuMemoryBuffer(ResourceId id);
-  const Resource* LockForWriteToSkSurface(ResourceId id);
+  void LockForWriteToSkSurface(ResourceId id);
   void UnlockForWriteToSkSurface(ResourceId id);
 
   static void PopulateSkBitmapWithResource(SkBitmap* sk_bitmap,
@@ -562,8 +559,6 @@
 
   bool use_sync_query_;
 
-  bool use_distance_field_text_;
-
   DISALLOW_COPY_AND_ASSIGN(ResourceProvider);
 };
 
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc
index 3aea34ff..4efe74d2 100644
--- a/cc/resources/resource_provider_unittest.cc
+++ b/cc/resources/resource_provider_unittest.cc
@@ -29,8 +29,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "third_party/khronos/GLES2/gl2ext.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/rect.h"
 
 using testing::Mock;
 using testing::NiceMock;
@@ -423,8 +423,7 @@
                                  main_thread_task_runner_.get(),
                                  0,
                                  false,
-                                 1,
-                                 false);
+                                 1);
     child_resource_provider_ =
         ResourceProvider::Create(child_output_surface_.get(),
                                  shared_bitmap_manager_.get(),
@@ -432,8 +431,7 @@
                                  main_thread_task_runner_.get(),
                                  0,
                                  false,
-                                 1,
-                                 false);
+                                 1);
   }
 
   static void CollectResources(ReturnedResourceArray* array,
@@ -1168,8 +1166,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -1651,8 +1648,7 @@
                                  NULL,
                                  0,
                                  false,
-                                 1,
-                                 false));
+                                 1));
 
     scoped_ptr<TextureStateTrackingContext> parent_context_owned(
         new TextureStateTrackingContext);
@@ -1670,8 +1666,7 @@
                                  NULL,
                                  0,
                                  false,
-                                 1,
-                                 false));
+                                 1));
 
     gfx::Size size(1, 1);
     ResourceFormat format = RGBA_8888;
@@ -2303,8 +2298,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -2391,8 +2385,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -2447,8 +2440,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -2507,8 +2499,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   gfx::Size size(1, 1);
   ResourceFormat format = RGBA_8888;
@@ -2581,8 +2572,7 @@
                                main_thread_task_runner_.get(),
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   uint32 release_sync_point = 0;
   bool lost_resource = false;
@@ -2634,8 +2624,7 @@
                                main_thread_task_runner_.get(),
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   unsigned texture_id = 1;
   uint32 sync_point = 30;
@@ -2720,8 +2709,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   unsigned texture_id = 1;
   uint32 sync_point = 30;
@@ -2796,8 +2784,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   uint32 sync_point = 30;
   unsigned target = GL_TEXTURE_2D;
@@ -2856,8 +2843,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   uint32 sync_point = 0;
   unsigned target = GL_TEXTURE_2D;
@@ -2983,8 +2969,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   gfx::Size size(2, 2);
   gfx::Vector2d offset(0, 0);
@@ -3064,8 +3049,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   gfx::Size size(2, 2);
 
@@ -3125,8 +3109,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   gfx::Size size(2, 2);
   const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888};
@@ -3185,8 +3168,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
@@ -3233,8 +3215,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
@@ -3281,8 +3262,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   EXPECT_CALL(*context, NextTextureId()).WillRepeatedly(Return(texture_id));
 
@@ -3327,8 +3307,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
@@ -3415,8 +3394,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   source_id = resource_provider->CreateResource(
       size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
@@ -3498,8 +3476,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
 
   CheckCreateResource(ResourceProvider::Bitmap, resource_provider.get(), NULL);
 
@@ -3538,8 +3515,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
   int texture_id = 123;
 
   ResourceProvider::ResourceId id = resource_provider->CreateResource(
@@ -3575,8 +3551,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
   int texture_id = 123;
   uint8_t pixels[8];
 
@@ -3637,8 +3612,7 @@
                                  NULL,
                                  0,
                                  false,
-                                 kTextureAllocationChunkSize,
-                                 false));
+                                 kTextureAllocationChunkSize));
 
     ResourceProvider::ResourceId id = resource_provider->CreateResource(
         size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
@@ -3658,8 +3632,7 @@
                                  NULL,
                                  0,
                                  false,
-                                 kTextureAllocationChunkSize,
-                                 false));
+                                 kTextureAllocationChunkSize));
 
     ResourceProvider::ResourceId id = resource_provider->CreateResource(
         size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format);
diff --git a/cc/resources/resource_update.h b/cc/resources/resource_update.h
index 1eddf83..d4911417 100644
--- a/cc/resources/resource_update.h
+++ b/cc/resources/resource_update.h
@@ -6,8 +6,8 @@
 #define CC_RESOURCES_RESOURCE_UPDATE_H_
 
 #include "cc/base/cc_export.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/vector2d.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
 
 class SkBitmap;
 
diff --git a/cc/resources/resource_update_controller_unittest.cc b/cc/resources/resource_update_controller_unittest.cc
index 49f7b47..d6b4f39 100644
--- a/cc/resources/resource_update_controller_unittest.cc
+++ b/cc/resources/resource_update_controller_unittest.cc
@@ -130,8 +130,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false);
+                                                  1);
   }
 
   void AppendFullUploadsOfIndexedTextureToUpdateQueue(int count,
diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc
index 7c7e055..a141218 100644
--- a/cc/resources/scoped_resource_unittest.cc
+++ b/cc/resources/scoped_resource_unittest.cc
@@ -28,8 +28,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
   scoped_ptr<ScopedResource> texture =
       ScopedResource::Create(resource_provider.get());
 
@@ -55,8 +54,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
   scoped_ptr<ScopedResource> texture =
       ScopedResource::Create(resource_provider.get());
   texture->Allocate(
@@ -85,8 +83,7 @@
                                NULL,
                                0,
                                false,
-                               1,
-                               false));
+                               1));
   {
     scoped_ptr<ScopedResource> texture =
         ScopedResource::Create(resource_provider.get());
diff --git a/cc/resources/scoped_ui_resource.h b/cc/resources/scoped_ui_resource.h
index f7def7f..0e5a02c 100644
--- a/cc/resources/scoped_ui_resource.h
+++ b/cc/resources/scoped_ui_resource.h
@@ -9,7 +9,6 @@
 #include "cc/base/cc_export.h"
 #include "cc/resources/ui_resource_bitmap.h"
 #include "cc/resources/ui_resource_client.h"
-#include "ui/gfx/size.h"
 
 namespace cc {
 
diff --git a/cc/resources/shared_bitmap.h b/cc/resources/shared_bitmap.h
index a90e47a0..ca127106 100644
--- a/cc/resources/shared_bitmap.h
+++ b/cc/resources/shared_bitmap.h
@@ -10,7 +10,7 @@
 #include "base/memory/shared_memory.h"
 #include "cc/base/cc_export.h"
 #include "gpu/command_buffer/common/mailbox.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace base { class SharedMemory; }
 
diff --git a/cc/resources/shared_bitmap_manager.h b/cc/resources/shared_bitmap_manager.h
index e6e49af..fe61b09 100644
--- a/cc/resources/shared_bitmap_manager.h
+++ b/cc/resources/shared_bitmap_manager.h
@@ -8,7 +8,7 @@
 #include "base/basictypes.h"
 #include "cc/base/cc_export.h"
 #include "cc/resources/shared_bitmap.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/resources/texture_mailbox.cc b/cc/resources/texture_mailbox.cc
index 90ce6be..92736f41 100644
--- a/cc/resources/texture_mailbox.cc
+++ b/cc/resources/texture_mailbox.cc
@@ -6,7 +6,6 @@
 
 #include "base/logging.h"
 #include "cc/resources/shared_bitmap.h"
-#include "third_party/khronos/GLES2/gl2.h"
 
 namespace cc {
 
diff --git a/cc/resources/texture_mailbox.h b/cc/resources/texture_mailbox.h
index 4626dd36..4a0b76a 100644
--- a/cc/resources/texture_mailbox.h
+++ b/cc/resources/texture_mailbox.h
@@ -7,11 +7,10 @@
 
 #include <string>
 
-#include "base/callback.h"
 #include "base/memory/shared_memory.h"
 #include "cc/base/cc_export.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/resources/texture_uploader.cc b/cc/resources/texture_uploader.cc
index 8c7010b5..9526fcb 100644
--- a/cc/resources/texture_uploader.cc
+++ b/cc/resources/texture_uploader.cc
@@ -10,14 +10,13 @@
 #include "base/debug/trace_event.h"
 #include "base/metrics/histogram.h"
 #include "cc/base/util.h"
-#include "cc/resources/prioritized_resource.h"
 #include "cc/resources/resource.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/vector2d.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
 
 using gpu::gles2::GLES2Interface;
 
diff --git a/cc/resources/tile.h b/cc/resources/tile.h
index e61b5c5..a712a754 100644
--- a/cc/resources/tile.h
+++ b/cc/resources/tile.h
@@ -6,14 +6,12 @@
 #define CC_RESOURCES_TILE_H_
 
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
 #include "cc/base/ref_counted_managed.h"
 #include "cc/resources/managed_tile_state.h"
 #include "cc/resources/picture_pile_impl.h"
 #include "cc/resources/tile_priority.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index cb9d766..77c4df60 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -20,7 +20,7 @@
 #include "cc/resources/raster_buffer.h"
 #include "cc/resources/rasterizer.h"
 #include "cc/resources/tile.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 
 namespace cc {
 namespace {
@@ -193,8 +193,6 @@
   DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
 };
 
-const size_t kScheduledRasterTasksLimit = 32u;
-
 }  // namespace
 
 RasterTaskCompletionStats::RasterTaskCompletionStats()
@@ -215,12 +213,14 @@
     base::SequencedTaskRunner* task_runner,
     ResourcePool* resource_pool,
     Rasterizer* rasterizer,
-    RenderingStatsInstrumentation* rendering_stats_instrumentation) {
+    RenderingStatsInstrumentation* rendering_stats_instrumentation,
+    size_t scheduled_raster_task_limit) {
   return make_scoped_ptr(new TileManager(client,
                                          task_runner,
                                          resource_pool,
                                          rasterizer,
-                                         rendering_stats_instrumentation));
+                                         rendering_stats_instrumentation,
+                                         scheduled_raster_task_limit));
 }
 
 TileManager::TileManager(
@@ -228,11 +228,13 @@
     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     ResourcePool* resource_pool,
     Rasterizer* rasterizer,
-    RenderingStatsInstrumentation* rendering_stats_instrumentation)
+    RenderingStatsInstrumentation* rendering_stats_instrumentation,
+    size_t scheduled_raster_task_limit)
     : client_(client),
       task_runner_(task_runner),
       resource_pool_(resource_pool),
       rasterizer_(rasterizer),
+      scheduled_raster_task_limit_(scheduled_raster_task_limit),
       all_tiles_that_need_to_be_rasterized_are_scheduled_(true),
       rendering_stats_instrumentation_(rendering_stats_instrumentation),
       did_initialize_visible_tile_(false),
@@ -570,7 +572,7 @@
 
     // We won't be able to schedule this tile, so break out early.
     if (tiles_that_need_to_be_rasterized->size() >=
-        kScheduledRasterTasksLimit) {
+        scheduled_raster_task_limit_) {
       all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
       break;
     }
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index 2abf177..6f579f9 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -98,7 +98,8 @@
       base::SequencedTaskRunner* task_runner,
       ResourcePool* resource_pool,
       Rasterizer* rasterizer,
-      RenderingStatsInstrumentation* rendering_stats_instrumentation);
+      RenderingStatsInstrumentation* rendering_stats_instrumentation,
+      size_t scheduled_raster_task_limit);
   ~TileManager() override;
 
   void ManageTiles(const GlobalStateThatImpactsTilePriority& state);
@@ -163,7 +164,8 @@
               const scoped_refptr<base::SequencedTaskRunner>& task_runner,
               ResourcePool* resource_pool,
               Rasterizer* rasterizer,
-              RenderingStatsInstrumentation* rendering_stats_instrumentation);
+              RenderingStatsInstrumentation* rendering_stats_instrumentation,
+              size_t scheduled_raster_task_limit);
 
   void FreeResourcesForReleasedTiles();
   void CleanUpReleasedTiles();
@@ -236,6 +238,7 @@
   ResourcePool* resource_pool_;
   Rasterizer* rasterizer_;
   GlobalStateThatImpactsTilePriority global_state_;
+  const size_t scheduled_raster_task_limit_;
 
   typedef base::hash_map<Tile::Id, Tile*> TileMap;
   TileMap tiles_;
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index 46f2e146..398474bd 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -157,21 +157,26 @@
   }
 
   EXPECT_EQ(tile_count, all_tiles.size());
-  EXPECT_EQ(17u, tile_count);
+  EXPECT_EQ(16u, tile_count);
 
   // Sanity check, all tiles should be visible.
   std::set<Tile*> smoothness_tiles;
   queue.Reset();
   host_impl_.BuildRasterQueue(&queue, SMOOTHNESS_TAKES_PRIORITY);
+  bool had_low_res = false;
   while (!queue.IsEmpty()) {
     Tile* tile = queue.Top();
     EXPECT_TRUE(tile);
     EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin);
     EXPECT_EQ(TilePriority::NOW, tile->priority(PENDING_TREE).priority_bin);
-    smoothness_tiles.insert(tile);
+    if (tile->priority(ACTIVE_TREE).resolution == LOW_RESOLUTION)
+      had_low_res = true;
+    else
+      smoothness_tiles.insert(tile);
     queue.Pop();
   }
   EXPECT_EQ(all_tiles, smoothness_tiles);
+  EXPECT_TRUE(had_low_res);
 
   Region invalidation(gfx::Rect(0, 0, 500, 500));
 
@@ -198,10 +203,13 @@
 
   // Populate all tiles directly from the tilings.
   all_tiles.clear();
+  std::set<Tile*> high_res_tiles;
   std::vector<Tile*> pending_high_res_tiles =
       pending_layer_->HighResTiling()->AllTilesForTesting();
-  for (size_t i = 0; i < pending_high_res_tiles.size(); ++i)
+  for (size_t i = 0; i < pending_high_res_tiles.size(); ++i) {
     all_tiles.insert(pending_high_res_tiles[i]);
+    high_res_tiles.insert(pending_high_res_tiles[i]);
+  }
 
   std::vector<Tile*> pending_low_res_tiles =
       pending_layer_->LowResTiling()->AllTilesForTesting();
@@ -210,8 +218,10 @@
 
   std::vector<Tile*> active_high_res_tiles =
       active_layer_->HighResTiling()->AllTilesForTesting();
-  for (size_t i = 0; i < active_high_res_tiles.size(); ++i)
+  for (size_t i = 0; i < active_high_res_tiles.size(); ++i) {
     all_tiles.insert(active_high_res_tiles[i]);
+    high_res_tiles.insert(active_high_res_tiles[i]);
+  }
 
   std::vector<Tile*> active_low_res_tiles =
       active_layer_->LowResTiling()->AllTilesForTesting();
@@ -275,6 +285,7 @@
   // Here we expect to get increasing PENDING_TREE priority_bin.
   queue.Reset();
   host_impl_.BuildRasterQueue(&queue, NEW_CONTENT_TAKES_PRIORITY);
+  tile_count = 0;
   while (!queue.IsEmpty()) {
     Tile* tile = queue.Top();
     EXPECT_TRUE(tile);
@@ -300,14 +311,72 @@
 
     last_tile = tile;
     new_content_tiles.insert(tile);
+    ++tile_count;
     queue.Pop();
   }
 
   EXPECT_EQ(tile_count, new_content_tiles.size());
-  EXPECT_EQ(all_tiles, new_content_tiles);
+  EXPECT_EQ(high_res_tiles, new_content_tiles);
   // Since we don't guarantee increasing distance due to spiral iterator, we
   // should check that we're _mostly_ right.
-  EXPECT_GT(increasing_distance_tiles, 3 * tile_count / 4);
+  EXPECT_GE(increasing_distance_tiles, 3 * tile_count / 4);
+}
+
+TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeEventually) {
+  SetupDefaultTrees(gfx::Size(1000, 1000));
+
+  active_layer_->CreateDefaultTilingsAndTiles();
+  pending_layer_->CreateDefaultTilingsAndTiles();
+
+  // Create a pending child layer.
+  gfx::Size tile_size(256, 256);
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000));
+  scoped_ptr<FakePictureLayerImpl> pending_child =
+      FakePictureLayerImpl::CreateWithPile(
+          host_impl_.pending_tree(), id_ + 1, pending_pile);
+  pending_layer_->AddChild(pending_child.Pass());
+  FakePictureLayerImpl* pending_child_raw = static_cast<FakePictureLayerImpl*>(
+      host_impl_.pending_tree()->LayerById(id_ + 1));
+  ASSERT_TRUE(pending_child_raw);
+
+  pending_child_raw->SetDrawsContent(true);
+  pending_child_raw->DoPostCommitInitializationIfNeeded();
+  pending_child_raw->CreateDefaultTilingsAndTiles();
+  ASSERT_TRUE(pending_child_raw->HighResTiling());
+
+  // Set a small viewport, so we have soon and eventually tiles.
+  gfx::Rect viewport(200, 200);
+  active_layer_->draw_properties().visible_content_rect = viewport;
+  active_layer_->UpdateTiles(Occlusion(), false);
+  pending_layer_->draw_properties().visible_content_rect = viewport;
+  pending_layer_->UpdateTiles(Occlusion(), false);
+  pending_child_raw->draw_properties().visible_content_rect = viewport;
+  pending_child_raw->UpdateTiles(Occlusion(), false);
+
+  RasterTilePriorityQueue queue;
+  host_impl_.SetRequiresHighResToDraw();
+  host_impl_.BuildRasterQueue(&queue, SMOOTHNESS_TAKES_PRIORITY);
+  EXPECT_FALSE(queue.IsEmpty());
+
+  // Get all the tiles that are NOW or SOON and make sure they are ready to
+  // draw.
+  std::vector<Tile*> all_tiles;
+  while (!queue.IsEmpty()) {
+    Tile* tile = queue.Top();
+    if (tile->combined_priority().priority_bin >= TilePriority::EVENTUALLY)
+      break;
+
+    all_tiles.push_back(tile);
+    queue.Pop();
+  }
+
+  tile_manager()->InitializeTilesWithResourcesForTesting(
+      std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
+
+  // Ensure we can activate.
+  EXPECT_TRUE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
+  EXPECT_TRUE(pending_child_raw->AllTilesRequiredForActivationAreReadyToDraw());
 }
 
 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) {
@@ -332,7 +401,7 @@
   }
 
   EXPECT_EQ(tile_count, all_tiles.size());
-  EXPECT_EQ(17u, tile_count);
+  EXPECT_EQ(16u, tile_count);
 
   tile_manager()->InitializeTilesWithResourcesForTesting(
       std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
@@ -507,7 +576,7 @@
     raster_queue.Pop();
   }
   EXPECT_EQ(tile_count, all_tiles.size());
-  EXPECT_EQ(34u, tile_count);
+  EXPECT_EQ(32u, tile_count);
 
   pending_layer_->ResetAllTilesPriorities();
 
@@ -609,7 +678,7 @@
   }
 
   EXPECT_EQ(tile_count, all_tiles.size());
-  EXPECT_EQ(17u, tile_count);
+  EXPECT_EQ(16u, tile_count);
 
   queue.Reset();
   for (int i = 1; i < 10; ++i) {
@@ -633,7 +702,7 @@
     queue.Pop();
   }
   EXPECT_EQ(tile_count, all_tiles.size());
-  EXPECT_EQ(17u, tile_count);
+  EXPECT_EQ(16u, tile_count);
 }
 
 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) {
@@ -655,7 +724,7 @@
     raster_queue.Pop();
   }
   EXPECT_EQ(tile_count, all_tiles.size());
-  EXPECT_EQ(17u, tile_count);
+  EXPECT_EQ(16u, tile_count);
 
   std::vector<Tile*> tiles(all_tiles.begin(), all_tiles.end());
   host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
@@ -682,7 +751,7 @@
     queue.Pop();
   }
   EXPECT_EQ(tile_count, all_tiles.size());
-  EXPECT_EQ(17u, tile_count);
+  EXPECT_EQ(16u, tile_count);
 }
 
 }  // namespace
diff --git a/cc/resources/tile_priority.h b/cc/resources/tile_priority.h
index 433abad..d1610571 100644
--- a/cc/resources/tile_priority.h
+++ b/cc/resources/tile_priority.h
@@ -9,12 +9,9 @@
 #include <limits>
 #include <string>
 
-#include "base/memory/ref_counted.h"
+#include "base/debug/trace_event_argument.h"
 #include "base/memory/scoped_ptr.h"
-#include "cc/resources/picture_pile.h"
-#include "ui/gfx/quad_f.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
+#include "cc/base/cc_export.h"
 
 namespace base {
 class Value;
diff --git a/cc/resources/transferable_resource.cc b/cc/resources/transferable_resource.cc
index a375f2e6..558d6e8 100644
--- a/cc/resources/transferable_resource.cc
+++ b/cc/resources/transferable_resource.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/logging.h"
 #include "cc/resources/returned_resource.h"
 #include "cc/resources/transferable_resource.h"
 
diff --git a/cc/resources/transferable_resource.h b/cc/resources/transferable_resource.h
index bd6b060..03b47e6 100644
--- a/cc/resources/transferable_resource.h
+++ b/cc/resources/transferable_resource.h
@@ -11,7 +11,7 @@
 #include "cc/base/cc_export.h"
 #include "cc/resources/resource_format.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/resources/ui_resource_bitmap.h b/cc/resources/ui_resource_bitmap.h
index 09403a3..ec651139 100644
--- a/cc/resources/ui_resource_bitmap.h
+++ b/cc/resources/ui_resource_bitmap.h
@@ -10,8 +10,7 @@
 #include "cc/base/cc_export.h"
 #include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkPixelRef.h"
-#include "third_party/skia/include/core/SkTypes.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 class SkBitmap;
 
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index 4d0e125..01a6042 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -14,7 +14,7 @@
 #include "media/filters/skcanvas_video_renderer.h"
 #include "third_party/khronos/GLES2/gl2.h"
 #include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 
diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h
index e9b924be..99800b4c 100644
--- a/cc/resources/video_resource_updater.h
+++ b/cc/resources/video_resource_updater.h
@@ -9,13 +9,12 @@
 
 #include "base/basictypes.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "cc/base/cc_export.h"
 #include "cc/resources/release_callback_impl.h"
 #include "cc/resources/resource_format.h"
 #include "cc/resources/texture_mailbox.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace media {
 class SkCanvasVideoRenderer;
diff --git a/cc/resources/video_resource_updater_unittest.cc b/cc/resources/video_resource_updater_unittest.cc
index bb6238c..c0a4af4 100644
--- a/cc/resources/video_resource_updater_unittest.cc
+++ b/cc/resources/video_resource_updater_unittest.cc
@@ -35,8 +35,7 @@
                                  NULL,
                                  0,
                                  false,
-                                 1,
-                                 false);
+                                 1);
   }
 
   scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame() {
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc
index a395f5c..29b0f8e 100644
--- a/cc/surfaces/display.cc
+++ b/cc/surfaces/display.cc
@@ -58,7 +58,6 @@
   int highp_threshold_min = 0;
   bool use_rgba_4444_texture_format = false;
   size_t id_allocation_chunk_size = 1;
-  bool use_distance_field_text = false;
   scoped_ptr<ResourceProvider> resource_provider =
       ResourceProvider::Create(output_surface_.get(),
                                bitmap_manager_,
@@ -66,8 +65,7 @@
                                blocking_main_thread_task_runner_.get(),
                                highp_threshold_min,
                                use_rgba_4444_texture_format,
-                               id_allocation_chunk_size,
-                               use_distance_field_text);
+                               id_allocation_chunk_size);
   if (!resource_provider)
     return;
 
diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h
index c55dfe84..ffa5042 100644
--- a/cc/surfaces/surface.h
+++ b/cc/surfaces/surface.h
@@ -18,7 +18,7 @@
 #include "cc/quads/render_pass_id.h"
 #include "cc/surfaces/surface_id.h"
 #include "cc/surfaces/surfaces_export.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace ui {
 struct LatencyInfo;
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
index f6bf6d6..e3574e5 100644
--- a/cc/surfaces/surface_aggregator.cc
+++ b/cc/surfaces/surface_aggregator.cc
@@ -40,7 +40,7 @@
 
 SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager,
                                      ResourceProvider* provider)
-    : manager_(manager), provider_(provider) {
+    : manager_(manager), provider_(provider), next_render_pass_id_(1) {
   DCHECK(manager_);
 }
 
@@ -48,25 +48,23 @@
 
 class SurfaceAggregator::RenderPassIdAllocator {
  public:
-  explicit RenderPassIdAllocator(SurfaceId surface_id)
-      : surface_id_(surface_id), next_index_(1) {}
+  explicit RenderPassIdAllocator(int* next_index) : next_index_(next_index) {}
   ~RenderPassIdAllocator() {}
 
   void AddKnownPass(RenderPassId id) {
     if (id_to_index_map_.find(id) != id_to_index_map_.end())
       return;
-    id_to_index_map_[id] = next_index_++;
+    id_to_index_map_[id] = (*next_index_)++;
   }
 
   RenderPassId Remap(RenderPassId id) {
     DCHECK(id_to_index_map_.find(id) != id_to_index_map_.end());
-    return RenderPassId(surface_id_.id, id_to_index_map_[id]);
+    return RenderPassId(1, id_to_index_map_[id]);
   }
 
  private:
   base::hash_map<RenderPassId, int> id_to_index_map_;
-  SurfaceId surface_id_;
-  int next_index_;
+  int* next_index_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderPassIdAllocator);
 };
@@ -82,7 +80,7 @@
                                             SurfaceId surface_id) {
   RenderPassIdAllocator* allocator = render_pass_allocator_map_.get(surface_id);
   if (!allocator) {
-    allocator = new RenderPassIdAllocator(surface_id);
+    allocator = new RenderPassIdAllocator(&next_render_pass_id_);
     render_pass_allocator_map_.set(surface_id, make_scoped_ptr(allocator));
   }
   allocator->AddKnownPass(surface_local_pass_id);
diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h
index 64c10e1..31d35ddc 100644
--- a/cc/surfaces/surface_aggregator.h
+++ b/cc/surfaces/surface_aggregator.h
@@ -66,6 +66,7 @@
   typedef base::ScopedPtrHashMap<SurfaceId, RenderPassIdAllocator>
       RenderPassIdAllocatorMap;
   RenderPassIdAllocatorMap render_pass_allocator_map_;
+  int next_render_pass_id_;
 
   typedef base::hash_map<SurfaceId, int> SurfaceToResourceChildIdMap;
   SurfaceToResourceChildIdMap surface_id_to_resource_child_id_;
diff --git a/cc/surfaces/surface_aggregator_test_helpers.h b/cc/surfaces/surface_aggregator_test_helpers.h
index 4e02472..6f3a342 100644
--- a/cc/surfaces/surface_aggregator_test_helpers.h
+++ b/cc/surfaces/surface_aggregator_test_helpers.h
@@ -10,7 +10,7 @@
 #include "cc/quads/render_pass_id.h"
 #include "cc/surfaces/surface_id.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc
index ef369f4..4771c82 100644
--- a/cc/surfaces/surface_aggregator_unittest.cc
+++ b/cc/surfaces/surface_aggregator_unittest.cc
@@ -67,7 +67,7 @@
 
 class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
  public:
-  SurfaceAggregatorValidSurfaceTest() : allocator_(1u) {}
+  SurfaceAggregatorValidSurfaceTest() : allocator_(1u), child_allocator_(2u) {}
 
   virtual void SetUp() {
     SurfaceAggregatorTest::SetUp();
@@ -96,6 +96,12 @@
     TestPassesMatchExpectations(
         expected_passes, expected_pass_count, &frame_data->render_pass_list);
 
+    // Ensure no duplicate pass ids output.
+    std::set<RenderPassId> used_passes;
+    for (auto* pass : frame_data->render_pass_list) {
+      EXPECT_TRUE(used_passes.insert(pass->id).second);
+    }
+
     EXPECT_EQ(expected_surface_count,
               aggregator_.previous_contained_surfaces().size());
     for (size_t i = 0; i < expected_surface_count; i++) {
@@ -133,6 +139,7 @@
  protected:
   SurfaceId root_surface_id_;
   SurfaceIdAllocator allocator_;
+  SurfaceIdAllocator child_allocator_;
 };
 
 // Tests that a very simple frame containing only two solid color quads makes it
@@ -153,8 +160,9 @@
                             test::Quad::SolidColorQuad(SK_ColorLTGRAY)},
                            {test::Quad::SolidColorQuad(SK_ColorGRAY),
                             test::Quad::SolidColorQuad(SK_ColorDKGRAY)}};
-  test::Pass passes[] = {test::Pass(quads[0], arraysize(quads[0])),
-                         test::Pass(quads[1], arraysize(quads[1]))};
+  test::Pass passes[] = {
+      test::Pass(quads[0], arraysize(quads[0]), RenderPassId(1, 1)),
+      test::Pass(quads[1], arraysize(quads[1]), RenderPassId(1, 2))};
 
   SubmitFrame(passes, arraysize(passes), root_surface_id_);
 
@@ -341,7 +349,7 @@
 
 // This tests referencing a surface that has multiple render passes.
 TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
-  SurfaceId embedded_surface_id = allocator_.GenerateId();
+  SurfaceId embedded_surface_id = child_allocator_.GenerateId();
   factory_.Create(embedded_surface_id, SurfaceSize());
 
   RenderPassId pass_ids[] = {RenderPassId(1, 1), RenderPassId(1, 2),
@@ -1127,8 +1135,7 @@
                                                   NULL,
                                                   0,
                                                   false,
-                                                  1,
-                                                  false);
+                                                  1);
 
     aggregator_.reset(
         new SurfaceAggregator(&manager_, resource_provider_.get()));
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc
index 636a5ff..4e0865a 100644
--- a/cc/surfaces/surface_factory_unittest.cc
+++ b/cc/surfaces/surface_factory_unittest.cc
@@ -9,7 +9,7 @@
 #include "cc/surfaces/surface_factory_client.h"
 #include "cc/surfaces/surface_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 namespace {
diff --git a/cc/surfaces/surface_unittest.cc b/cc/surfaces/surface_unittest.cc
index d2b1dfa..b8990c55 100644
--- a/cc/surfaces/surface_unittest.cc
+++ b/cc/surfaces/surface_unittest.cc
@@ -6,7 +6,7 @@
 #include "cc/surfaces/surface_factory.h"
 #include "cc/surfaces/surface_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 namespace {
diff --git a/cc/test/data/background_filter_blur_off_axis.png b/cc/test/data/background_filter_blur_off_axis.png
index b5777f4..050ec54 100644
--- a/cc/test/data/background_filter_blur_off_axis.png
+++ b/cc/test/data/background_filter_blur_off_axis.png
Binary files differ
diff --git a/cc/test/data/blending_render_pass.png b/cc/test/data/blending_render_pass.png
new file mode 100644
index 0000000..76fe369
--- /dev/null
+++ b/cc/test/data/blending_render_pass.png
Binary files differ
diff --git a/cc/test/data/blending_render_pass_cm.png b/cc/test/data/blending_render_pass_cm.png
new file mode 100644
index 0000000..9a72d44
--- /dev/null
+++ b/cc/test/data/blending_render_pass_cm.png
Binary files differ
diff --git a/cc/test/data/blending_render_pass_mask.png b/cc/test/data/blending_render_pass_mask.png
new file mode 100644
index 0000000..8b63f35c
--- /dev/null
+++ b/cc/test/data/blending_render_pass_mask.png
Binary files differ
diff --git a/cc/test/data/blending_render_pass_mask_cm.png b/cc/test/data/blending_render_pass_mask_cm.png
new file mode 100644
index 0000000..4e210aa3
--- /dev/null
+++ b/cc/test/data/blending_render_pass_mask_cm.png
Binary files differ
diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h
index 8f13284..7a7cc44 100644
--- a/cc/test/fake_content_layer_client.h
+++ b/cc/test/fake_content_layer_client.h
@@ -12,7 +12,7 @@
 #include "cc/layers/content_layer_client.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkPaint.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/test/fake_picture_layer_tiling_client.h b/cc/test/fake_picture_layer_tiling_client.h
index dece2fc..0e2f645 100644
--- a/cc/test/fake_picture_layer_tiling_client.h
+++ b/cc/test/fake_picture_layer_tiling_client.h
@@ -10,7 +10,7 @@
 #include "cc/resources/tile.h"
 #include "cc/resources/tile_manager.h"
 #include "cc/test/fake_tile_manager_client.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/test/fake_picture_pile_impl.h b/cc/test/fake_picture_pile_impl.h
index 7c7e66f7..2d495f4 100644
--- a/cc/test/fake_picture_pile_impl.h
+++ b/cc/test/fake_picture_pile_impl.h
@@ -70,6 +70,10 @@
 
   void set_has_text(bool has_text) { has_text_ = has_text; }
 
+  void set_is_solid_color(bool is_solid_color) {
+    is_solid_color_ = is_solid_color;
+  }
+
  protected:
   FakePicturePileImpl();
   ~FakePicturePileImpl() override;
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index bebd797..8aa343b 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -5,6 +5,7 @@
 #include "cc/test/fake_tile_manager.h"
 
 #include <deque>
+#include <limits>
 
 #include "base/lazy_instance.h"
 #include "cc/resources/raster_buffer.h"
@@ -68,7 +69,9 @@
                   base::MessageLoopProxy::current(),
                   NULL,
                   g_fake_rasterizer.Pointer(),
-                  NULL) {}
+                  NULL,
+                  std::numeric_limits<size_t>::max()) {
+}
 
 FakeTileManager::FakeTileManager(TileManagerClient* client,
                                  ResourcePool* resource_pool)
@@ -76,7 +79,9 @@
                   base::MessageLoopProxy::current(),
                   resource_pool,
                   g_fake_rasterizer.Pointer(),
-                  NULL) {}
+                  NULL,
+                  std::numeric_limits<size_t>::max()) {
+}
 
 FakeTileManager::~FakeTileManager() {}
 
diff --git a/cc/test/layer_test_common.cc b/cc/test/layer_test_common.cc
index 4ad0aec..a6dfa9c8 100644
--- a/cc/test/layer_test_common.cc
+++ b/cc/test/layer_test_common.cc
@@ -13,10 +13,10 @@
 #include "cc/test/mock_occlusion_tracker.h"
 #include "cc/trees/layer_tree_host_common.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/point_conversions.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 2f293f7..31d30a4 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -28,9 +28,10 @@
 
 LayerTreePixelTest::LayerTreePixelTest()
     : pixel_comparator_(new ExactPixelComparator(true)),
-      test_type_(GL_WITH_DEFAULT),
+      test_type_(PIXEL_TEST_GL),
       pending_texture_mailbox_callbacks_(0),
-      impl_side_painting_(true) {}
+      impl_side_painting_(true) {
+}
 
 LayerTreePixelTest::~LayerTreePixelTest() {}
 
@@ -40,8 +41,7 @@
   scoped_ptr<PixelTestOutputSurface> output_surface;
 
   switch (test_type_) {
-    case SOFTWARE_WITH_DEFAULT:
-    case SOFTWARE_WITH_BITMAP: {
+    case PIXEL_TEST_SOFTWARE: {
       scoped_ptr<PixelTestSoftwareOutputDevice> software_output_device(
           new PixelTestSoftwareOutputDevice);
       software_output_device->set_surface_expansion_size(
@@ -50,9 +50,7 @@
           new PixelTestOutputSurface(software_output_device.Pass()));
       break;
     }
-
-    case GL_WITH_DEFAULT:
-    case GL_WITH_BITMAP: {
+    case PIXEL_TEST_GL: {
       output_surface = make_scoped_ptr(
           new PixelTestOutputSurface(new TestInProcessContextProvider));
       break;
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h
index 5c220d5..e6f5cb7a4 100644
--- a/cc/test/layer_tree_pixel_test.h
+++ b/cc/test/layer_tree_pixel_test.h
@@ -59,10 +59,8 @@
                                                  const SkBitmap& bitmap);
 
   enum PixelTestType {
-    GL_WITH_DEFAULT,
-    GL_WITH_BITMAP,
-    SOFTWARE_WITH_DEFAULT,
-    SOFTWARE_WITH_BITMAP
+    PIXEL_TEST_GL,
+    PIXEL_TEST_SOFTWARE,
   };
 
   void RunPixelTest(PixelTestType type,
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index c19c63f..aabad9b 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -29,7 +29,7 @@
 #include "cc/trees/thread_proxy.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "ui/gfx/frame_time.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 
diff --git a/cc/test/pixel_comparator.cc b/cc/test/pixel_comparator.cc
index 73807ed..4067787 100644
--- a/cc/test/pixel_comparator.cc
+++ b/cc/test/pixel_comparator.cc
@@ -7,7 +7,7 @@
 #include <algorithm>
 
 #include "base/logging.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index c47a083..1565b8a 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -124,8 +124,7 @@
                                main_thread_task_runner_.get(),
                                0,
                                false,
-                               1,
-                               false);
+                               1);
 
   texture_mailbox_deleter_ = make_scoped_ptr(
       new TextureMailboxDeleter(base::MessageLoopProxy::current()));
@@ -173,8 +172,7 @@
                                main_thread_task_runner_.get(),
                                0,
                                false,
-                               1,
-                               false);
+                               1);
   renderer_ = SoftwareRenderer::Create(
       this, &settings_, output_surface_.get(), resource_provider_.get());
 }
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h
index 838acaf..1a6c5ba 100644
--- a/cc/test/pixel_test.h
+++ b/cc/test/pixel_test.h
@@ -8,7 +8,7 @@
 #include "cc/quads/render_pass.h"
 #include "cc/test/pixel_comparator.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 #include "ui/gl/gl_implementation.h"
 
 #ifndef CC_TEST_PIXEL_TEST_H_
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc
index 519c74a9..f9def0f7 100644
--- a/cc/test/render_pass_test_utils.cc
+++ b/cc/test/render_pass_test_utils.cc
@@ -11,7 +11,7 @@
 #include "cc/test/render_pass_test_common.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkImageFilter.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
@@ -111,7 +111,8 @@
                        TestRenderPass* contributing_pass,
                        ResourceProvider::ResourceId mask_resource_id,
                        const FilterOperations& filters,
-                       gfx::Transform transform) {
+                       gfx::Transform transform,
+                       SkXfermode::Mode blend_mode) {
   gfx::Rect output_rect = contributing_pass->output_rect;
   SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState();
   shared_state->SetAll(transform,
@@ -120,7 +121,7 @@
                        output_rect,
                        false,
                        1,
-                       SkXfermode::kSrcOver_Mode,
+                       blend_mode,
                        0);
   RenderPassDrawQuad* quad =
       to_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
diff --git a/cc/test/render_pass_test_utils.h b/cc/test/render_pass_test_utils.h
index 7bf026ca..49ea113 100644
--- a/cc/test/render_pass_test_utils.h
+++ b/cc/test/render_pass_test_utils.h
@@ -53,7 +53,8 @@
                        TestRenderPass* contributing_pass,
                        ResourceProvider::ResourceId mask_resource_id,
                        const FilterOperations& filters,
-                       gfx::Transform transform);
+                       gfx::Transform transform,
+                       SkXfermode::Mode blend_mode);
 
 }  // namespace cc
 
diff --git a/cc/test/skia_common.cc b/cc/test/skia_common.cc
index d91e707..1ccb2d1a 100644
--- a/cc/test/skia_common.cc
+++ b/cc/test/skia_common.cc
@@ -7,7 +7,7 @@
 #include "cc/resources/picture.h"
 #include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/skia_util.h"
 
 namespace cc {
diff --git a/cc/test/solid_color_content_layer_client.cc b/cc/test/solid_color_content_layer_client.cc
index 7199f36..237dbb6 100644
--- a/cc/test/solid_color_content_layer_client.cc
+++ b/cc/test/solid_color_content_layer_client.cc
@@ -6,8 +6,8 @@
 
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPaint.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
 
 namespace cc {
 
diff --git a/cc/test/test_texture.h b/cc/test/test_texture.h
index 0e50bf0..9265589 100644
--- a/cc/test/test_texture.h
+++ b/cc/test/test_texture.h
@@ -10,7 +10,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/resources/resource_format.h"
 #include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h
index 0dfba9df..eda6f0f2 100644
--- a/cc/test/test_web_graphics_context_3d.h
+++ b/cc/test/test_web_graphics_context_3d.h
@@ -20,7 +20,7 @@
 #include "cc/test/ordered_texture_map.h"
 #include "cc/test/test_texture.h"
 #include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 extern "C" typedef struct _ClientBuffer* ClientBuffer;
 
diff --git a/cc/test/tiled_layer_test_common.h b/cc/test/tiled_layer_test_common.h
index 18b9817..abf2de4 100644
--- a/cc/test/tiled_layer_test_common.h
+++ b/cc/test/tiled_layer_test_common.h
@@ -12,8 +12,8 @@
 #include "cc/resources/prioritized_resource.h"
 #include "cc/resources/resource_provider.h"
 #include "cc/resources/resource_update_queue.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
diff --git a/cc/trees/damage_tracker.h b/cc/trees/damage_tracker.h
index 37c4c6e..aafbd03 100644
--- a/cc/trees/damage_tracker.h
+++ b/cc/trees/damage_tracker.h
@@ -9,7 +9,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
 #include "cc/layers/layer_lists.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 class SkImageFilter;
 
diff --git a/cc/trees/layer_sorter.h b/cc/trees/layer_sorter.h
index 7dd980ce..b783ded0 100644
--- a/cc/trees/layer_sorter.h
+++ b/cc/trees/layer_sorter.h
@@ -11,10 +11,10 @@
 #include "base/containers/hash_tables.h"
 #include "cc/base/cc_export.h"
 #include "cc/layers/layer_impl.h"
-#include "ui/gfx/point3_f.h"
-#include "ui/gfx/quad_f.h"
-#include "ui/gfx/rect_f.h"
-#include "ui/gfx/vector3d_f.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 
 namespace gfx {
 class Transform;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 08fb8105..7e17fef 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -40,7 +40,7 @@
 #include "cc/trees/single_thread_proxy.h"
 #include "cc/trees/thread_proxy.h"
 #include "cc/trees/tree_synchronizer.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace {
 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index aede050..b312e50 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -39,7 +39,7 @@
 #include "cc/trees/layer_tree_settings.h"
 #include "cc/trees/proxy.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 class AnimationRegistrar;
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 4e80fc6..fd15b52 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -16,7 +16,7 @@
 #include "cc/layers/render_surface_impl.h"
 #include "cc/trees/layer_sorter.h"
 #include "cc/trees/layer_tree_impl.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index d4c09c69..089fe293 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -13,9 +13,9 @@
 #include "cc/base/cc_export.h"
 #include "cc/base/scoped_ptr_vector.h"
 #include "cc/layers/layer_lists.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
 #include "ui/gfx/transform.h"
-#include "ui/gfx/vector2d.h"
 
 namespace cc {
 
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 99e479a..e0436bad 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -33,7 +33,7 @@
 #include "cc/trees/single_thread_proxy.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/quad_f.h"
+#include "ui/gfx/geometry/quad_f.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index ddb315f..5e89bbe 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -72,8 +72,8 @@
 #include "gpu/GLES2/gl2extchromium.h"
 #include "ui/gfx/frame_time.h"
 #include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
-#include "ui/gfx/vector2d_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 
 namespace cc {
 namespace {
@@ -1586,7 +1586,7 @@
 
   if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) {
     bool disable_picture_quad_image_filtering =
-        IsCurrentlyScrolling() || needs_animate_layers();
+        IsActivelyScrolling() || needs_animate_layers();
 
     scoped_ptr<SoftwareRenderer> temp_software_renderer =
         SoftwareRenderer::Create(this, &settings_, output_surface_.get(), NULL);
@@ -1768,8 +1768,8 @@
   return active_tree_->CurrentlyScrollingLayer();
 }
 
-bool LayerTreeHostImpl::IsCurrentlyScrolling() const {
-  return CurrentlyScrollingLayer() ||
+bool LayerTreeHostImpl::IsActivelyScrolling() const {
+  return (did_lock_scrolling_layer_ && CurrentlyScrollingLayer()) ||
          (InnerViewportScrollLayer() &&
           InnerViewportScrollLayer()->IsExternalFlingActive()) ||
          (OuterViewportScrollLayer() &&
@@ -2028,8 +2028,11 @@
                              GL_TEXTURE_2D,
                              resource_provider_->best_texture_format());
 
-    raster_worker_pool_ = GpuRasterWorkerPool::Create(
-        task_runner, context_provider, resource_provider_.get());
+    raster_worker_pool_ =
+        GpuRasterWorkerPool::Create(task_runner,
+                                    context_provider,
+                                    resource_provider_.get(),
+                                    settings_.use_distance_field_text);
   } else if (UseZeroCopyRasterizer()) {
     resource_pool_ = ResourcePool::Create(
         resource_provider_.get(),
@@ -2076,7 +2079,8 @@
                                       task_runner,
                                       resource_pool_.get(),
                                       raster_worker_pool_->AsRasterizer(),
-                                      rendering_stats_instrumentation_);
+                                      rendering_stats_instrumentation_,
+                                      settings().scheduled_raster_task_limit);
 
   UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
   need_to_update_visible_tiles_before_draw_ = false;
@@ -2135,8 +2139,7 @@
                                proxy_->blocking_main_thread_task_runner(),
                                settings_.highp_threshold_min,
                                settings_.use_rgba_4444_textures,
-                               settings_.texture_id_allocation_chunk_size,
-                               settings_.use_distance_field_text);
+                               settings_.texture_id_allocation_chunk_size);
 
   if (output_surface_->capabilities().deferred_gl_initialization)
     EnforceZeroBudget(true);
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index a6448c1..450b2721 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -35,7 +35,7 @@
 #include "cc/scheduler/draw_result.h"
 #include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
@@ -325,7 +325,7 @@
   void QueueSwapPromiseForMainThreadScrollUpdate(
       scoped_ptr<SwapPromise> swap_promise);
 
-  bool IsCurrentlyScrolling() const;
+  bool IsActivelyScrolling() const;
 
   virtual void SetVisible(bool visible);
   bool visible() const { return visible_; }
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index ec1100f..64758be7 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -61,9 +61,9 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkMallocPixelRef.h"
 #include "ui/gfx/frame_time.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
-#include "ui/gfx/vector2d_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 
 using ::testing::Mock;
 using ::testing::Return;
@@ -512,6 +512,20 @@
   EXPECT_TRUE(did_request_commit_);
 }
 
+TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) {
+  SetupScrollAndContentsLayers(gfx::Size(100, 100));
+  host_impl_->SetViewportSize(gfx::Size(50, 50));
+  DrawFrame();
+
+  EXPECT_EQ(InputHandler::ScrollStarted,
+            host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
+  EXPECT_FALSE(host_impl_->IsActivelyScrolling());
+  host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
+  EXPECT_TRUE(host_impl_->IsActivelyScrolling());
+  host_impl_->ScrollEnd();
+  EXPECT_FALSE(host_impl_->IsActivelyScrolling());
+}
+
 TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
   // We should not crash when trying to scroll an empty layer tree.
   EXPECT_EQ(InputHandler::ScrollIgnored,
@@ -906,19 +920,10 @@
     scroll_layer->SetScrollDelta(gfx::Vector2d());
 
     float page_scale_delta = 2.f;
-    gfx::Vector2dF expected_container_size_delta(
-        container_layer->bounds().width(), container_layer->bounds().height());
-    expected_container_size_delta.Scale((1.f - page_scale_delta) /
-                                        (page_scale_factor * page_scale_delta));
 
     host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
     host_impl_->PinchGestureBegin();
     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
-    // While the gesture is still active, the scroll layer should have a
-    // container size delta = container->bounds() * ((1.f -
-    // page_scale_delta)/())
-    EXPECT_EQ(expected_container_size_delta,
-              scroll_layer->FixedContainerSizeDelta());
     host_impl_->PinchGestureEnd();
     host_impl_->ScrollEnd();
     EXPECT_FALSE(did_request_animate_);
@@ -2249,6 +2254,7 @@
         clip_size_(layer_size_) {
     settings_.calculate_top_controls_position = true;
     settings_.top_controls_height = 50;
+    settings_.use_pinch_virtual_viewport = true;
 
     viewport_size_ =
         gfx::Size(clip_size_.width(),
@@ -2391,8 +2397,8 @@
 }
 
 TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) {
-  CreateHostImpl(settings_, CreateOutputSurface());
-  SetupTopControlsAndScrollLayer();
+  SetupTopControlsAndScrollLayerWithVirtualViewport(
+      gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10));
   DrawFrame();
 
   EXPECT_EQ(InputHandler::ScrollStarted,
@@ -2414,36 +2420,56 @@
             inner_viewport_scroll_layer->FixedContainerSizeDelta());
 }
 
-TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsWithPageScale) {
-  CreateHostImpl(settings_, CreateOutputSurface());
-  SetupTopControlsAndScrollLayer();
+// Test that the fixed position container delta is appropriately adjusted
+// by the top controls showing/hiding and page scale doesn't affect it.
+TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) {
+  SetupTopControlsAndScrollLayerWithVirtualViewport(
+      gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100));
   DrawFrame();
 
+  float page_scale = 1.5f;
+  float top_controls_height = settings_.top_controls_height;
+  LayerImpl* outer_viewport_scroll_layer =
+      host_impl_->active_tree()->OuterViewportScrollLayer();
+
+  // Zoom in, since the fixed container is the outer viewport, the delta should
+  // not be scaled.
+  host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 1.f, 2.f);
+
   EXPECT_EQ(InputHandler::ScrollStarted,
             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
 
-  float page_scale = 1.5f;
-  host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 1.f, 2.f);
-
-  gfx::Vector2dF top_controls_scroll_delta(0.f, 5.f);
-  gfx::Vector2dF expected_container_size_delta =
-      ScaleVector2d(top_controls_scroll_delta, 1.f / page_scale);
+  // Scroll down, the top controls hiding should expand the viewport size so
+  // the delta should be equal to the scroll distance.
+  gfx::Vector2dF top_controls_scroll_delta(0.f, 20.f);
   host_impl_->top_controls_manager()->ScrollBegin();
   host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
-  host_impl_->top_controls_manager()->ScrollEnd();
-
-  LayerImpl* inner_viewport_scroll_layer =
-      host_impl_->active_tree()->InnerViewportScrollLayer();
-  DCHECK(inner_viewport_scroll_layer);
+  EXPECT_EQ(top_controls_height - top_controls_scroll_delta.y(),
+            host_impl_->top_controls_manager()->ContentTopOffset());
+  EXPECT_VECTOR_EQ(top_controls_scroll_delta,
+                   outer_viewport_scroll_layer->FixedContainerSizeDelta());
   host_impl_->ScrollEnd();
 
-  // Use a tolerance that requires the container size delta to be within 0.01
-  // pixels.
-  double tolerance = 0.0001;
-  EXPECT_LT(
-      (expected_container_size_delta -
-       inner_viewport_scroll_layer->FixedContainerSizeDelta()).LengthSquared(),
-      tolerance);
+  // Scroll past the maximum extent. The delta shouldn't be greater than the
+  // top controls height.
+  host_impl_->top_controls_manager()->ScrollBegin();
+  host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
+  host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
+  host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
+  EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
+  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height),
+                   outer_viewport_scroll_layer->FixedContainerSizeDelta());
+  host_impl_->ScrollEnd();
+
+  // Scroll in the direction to make the top controls show.
+  host_impl_->top_controls_manager()->ScrollBegin();
+  host_impl_->top_controls_manager()->ScrollBy(-top_controls_scroll_delta);
+  EXPECT_EQ(top_controls_scroll_delta.y(),
+            host_impl_->top_controls_manager()->ContentTopOffset());
+  EXPECT_VECTOR_EQ(
+      gfx::Vector2dF(0, top_controls_height - top_controls_scroll_delta.y()),
+      outer_viewport_scroll_layer->FixedContainerSizeDelta());
+  host_impl_->top_controls_manager()->ScrollEnd();
 }
 
 // Ensure setting the top controls position explicitly using the setters on the
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc
index f01d426c..5bce9dd 100644
--- a/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "cc/layers/image_layer.h"
 #include "cc/layers/solid_color_layer.h"
-#include "cc/layers/texture_layer.h"
 #include "cc/test/layer_tree_pixel_test.h"
 #include "cc/test/pixel_comparator.h"
 
@@ -22,7 +22,36 @@
     SkXfermode::kHue_Mode,       SkXfermode::kSaturation_Mode,
     SkXfermode::kColor_Mode,     SkXfermode::kLuminosity_Mode};
 
+SkColor kCSSTestColors[] = {
+    0xffff0000,  // red
+    0xff00ff00,  // lime
+    0xff0000ff,  // blue
+    0xff00ffff,  // aqua
+    0xffff00ff,  // fuchsia
+    0xffffff00,  // yellow
+    0xff008000,  // green
+    0xff800000,  // maroon
+    0xff000080,  // navy
+    0xff800080,  // purple
+    0xff808000,  // olive
+    0xff008080,  // teal
+    0xfffa8072,  // salmon
+    0xffc0c0c0,  // silver
+    0xff000000,  // black
+    0xff808080,  // gray
+    0x80000000,  // black with transparency
+    0xffffffff,  // white
+    0x80ffffff,  // white with transparency
+    0x00000000   // transparent
+};
+
 const int kBlendModesCount = arraysize(kBlendModes);
+const int kCSSTestColorsCount = arraysize(kCSSTestColors);
+
+using RenderPassOptions = uint32;
+const uint32 kUseMasks = 1 << 0;
+const uint32 kUseAntialiasing = 1 << 1;
+const uint32 kUseColorMatrix = 1 << 2;
 
 class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest {
  public:
@@ -30,6 +59,10 @@
     pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
   }
 
+  virtual void InitializeSettings(LayerTreeSettings* settings) override {
+    settings->force_antialiasing = force_antialiasing_;
+  }
+
  protected:
   void RunBlendingWithRootPixelTestType(PixelTestType type) {
     const int kLaneWidth = 15;
@@ -82,14 +115,183 @@
                  root,
                  base::FilePath(FILE_PATH_LITERAL("blending_transparent.png")));
   }
+
+  scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) {
+    // Draw the backdrop with horizontal lanes.
+    const int kLaneWidth = width;
+    const int kLaneHeight = height / kCSSTestColorsCount;
+    SkBitmap backing_store;
+    backing_store.allocN32Pixels(width, height);
+    SkCanvas canvas(backing_store);
+    canvas.clear(SK_ColorTRANSPARENT);
+    for (int i = 0; i < kCSSTestColorsCount; ++i) {
+      SkPaint paint;
+      paint.setColor(kCSSTestColors[i]);
+      canvas.drawRect(
+          SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint);
+    }
+    scoped_refptr<ImageLayer> layer = ImageLayer::Create();
+    layer->SetIsDrawable(true);
+    layer->SetBounds(gfx::Size(width, height));
+    layer->SetBitmap(backing_store);
+    return layer;
+  }
+
+  void SetupMaskLayer(scoped_refptr<Layer> layer) {
+    const int kMaskOffset = 5;
+    gfx::Size bounds = layer->bounds();
+    scoped_refptr<ImageLayer> mask = ImageLayer::Create();
+    mask->SetIsDrawable(true);
+    mask->SetIsMask(true);
+    mask->SetBounds(bounds);
+
+    SkBitmap bitmap;
+    bitmap.allocN32Pixels(bounds.width(), bounds.height());
+    SkCanvas canvas(bitmap);
+    SkPaint paint;
+    paint.setColor(SK_ColorWHITE);
+    canvas.clear(SK_ColorTRANSPARENT);
+    canvas.drawRect(SkRect::MakeXYWH(kMaskOffset,
+                                     kMaskOffset,
+                                     bounds.width() - kMaskOffset * 2,
+                                     bounds.height() - kMaskOffset * 2),
+                    paint);
+    mask->SetBitmap(bitmap);
+    layer->SetMaskLayer(mask.get());
+  }
+
+  void SetupColorMatrix(scoped_refptr<Layer> layer) {
+    FilterOperations filter_operations;
+    filter_operations.Append(FilterOperation::CreateSepiaFilter(1.f));
+    layer->SetFilters(filter_operations);
+  }
+
+  void CreateBlendingColorLayers(int width,
+                                 int height,
+                                 scoped_refptr<Layer> background,
+                                 RenderPassOptions flags) {
+    const int kLanesCount = kBlendModesCount + 4;
+    int lane_width = width / kLanesCount;
+    const SkColor kMiscOpaqueColor = 0xffc86464;
+    const SkColor kMiscTransparentColor = 0x80c86464;
+    const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode;
+    const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode;
+    // add vertical lanes with each of the blend modes
+    for (int i = 0; i < kLanesCount; ++i) {
+      gfx::Rect child_rect(i * lane_width, 0, lane_width, height);
+      SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
+      float opacity = 1.f;
+      SkColor color = kMiscOpaqueColor;
+
+      if (i < kBlendModesCount) {
+        blend_mode = kBlendModes[i];
+      } else if (i == kBlendModesCount) {
+        blend_mode = kCoeffBlendMode;
+        opacity = 0.5f;
+      } else if (i == kBlendModesCount + 1) {
+        blend_mode = kCoeffBlendMode;
+        color = kMiscTransparentColor;
+      } else if (i == kBlendModesCount + 2) {
+        blend_mode = kShaderBlendMode;
+        opacity = 0.5f;
+      } else if (i == kBlendModesCount + 3) {
+        blend_mode = kShaderBlendMode;
+        color = kMiscTransparentColor;
+      }
+
+      scoped_refptr<SolidColorLayer> lane =
+          CreateSolidColorLayer(child_rect, color);
+      lane->SetBlendMode(blend_mode);
+      lane->SetOpacity(opacity);
+      lane->SetForceRenderSurface(true);
+      if (flags & kUseMasks)
+        SetupMaskLayer(lane);
+      if (flags & kUseColorMatrix) {
+        SetupColorMatrix(lane);
+      }
+      background->AddChild(lane);
+    }
+  }
+
+  void RunBlendingWithRenderPass(PixelTestType type,
+                                 const base::FilePath::CharType* expected_path,
+                                 RenderPassOptions flags) {
+    const int kRootSize = 400;
+
+    scoped_refptr<SolidColorLayer> root =
+        CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE);
+    scoped_refptr<Layer> background =
+        CreateColorfulBackdropLayer(kRootSize, kRootSize);
+
+    background->SetIsRootForIsolatedGroup(true);
+    root->AddChild(background);
+
+    CreateBlendingColorLayers(kRootSize, kRootSize, background.get(), flags);
+
+    this->impl_side_painting_ = false;
+    this->force_antialiasing_ = (flags & kUseAntialiasing);
+
+    if ((flags & kUseAntialiasing) && (type == PIXEL_TEST_GL)) {
+      // Anti aliasing causes differences up to 7 pixels at the edges.
+      int large_error_allowed = 7;
+      // Blending results might differ with one pixel.
+      int small_error_allowed = 1;
+      // Most of the errors are one pixel errors.
+      float percentage_pixels_small_error = 12.5f;
+      // Because of anti-aliasing, around 3% of pixels (at the edges) have
+      // bigger errors (from small_error_allowed + 1 to large_error_allowed).
+      float percentage_pixels_error = 15.0f;
+      // The average error is still close to 1.
+      float average_error_allowed_in_bad_pixels = 1.3f;
+
+      // The sepia filter generates more small errors, but the number of large
+      // errors remains around 3%.
+      if (flags & kUseColorMatrix) {
+        percentage_pixels_small_error = 26.f;
+        percentage_pixels_error = 29.f;
+      }
+
+      // Anti-aliased pixels in combination with non-separable blend modes and
+      // a white background produces several black pixels (6 for these tests).
+      // Having a mask will hide the black pixels.
+      // TODO(rosca): fix this issue for non-separable blend modes.
+      if (!(flags & kUseMasks))
+        large_error_allowed = 255;
+
+      pixel_comparator_.reset(
+          new FuzzyPixelComparator(false,  // discard_alpha
+                                   percentage_pixels_error,
+                                   percentage_pixels_small_error,
+                                   average_error_allowed_in_bad_pixels,
+                                   large_error_allowed,
+                                   small_error_allowed));
+    } else if ((flags & kUseColorMatrix) && (type == PIXEL_TEST_GL)) {
+      float percentage_pixels_error = 100.f;
+      float percentage_pixels_small_error = 0.f;
+      float average_error_allowed_in_bad_pixels = 1.f;
+      int large_error_allowed = 2;
+      int small_error_allowed = 0;
+      pixel_comparator_.reset(
+          new FuzzyPixelComparator(false,  // discard_alpha
+                                   percentage_pixels_error,
+                                   percentage_pixels_small_error,
+                                   average_error_allowed_in_bad_pixels,
+                                   large_error_allowed,
+                                   small_error_allowed));
+    }
+
+    RunPixelTest(type, root, base::FilePath(expected_path));
+  }
+
+  bool force_antialiasing_ = false;
 };
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
-  RunBlendingWithRootPixelTestType(GL_WITH_BITMAP);
+  RunBlendingWithRootPixelTestType(PIXEL_TEST_GL);
 }
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) {
-  RunBlendingWithRootPixelTestType(SOFTWARE_WITH_BITMAP);
+  RunBlendingWithRootPixelTestType(PIXEL_TEST_SOFTWARE);
 }
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
@@ -115,17 +317,124 @@
     green_lane->SetBlendMode(kBlendModes[i]);
   }
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png")));
 }
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) {
-  RunBlendingWithTransparentPixelTestType(GL_WITH_BITMAP);
+  RunBlendingWithTransparentPixelTestType(PIXEL_TEST_GL);
 }
 
 TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) {
-  RunBlendingWithTransparentPixelTestType(SOFTWARE_WITH_BITMAP);
+  RunBlendingWithTransparentPixelTestType(PIXEL_TEST_SOFTWARE);
+}
+
+// Tests for render passes
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_GL, FILE_PATH_LITERAL("blending_render_pass.png"), 0);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), 0);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass.png"),
+                            kUseAntialiasing);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass.png"),
+                            kUseAntialiasing);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+                            kUseMasks);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMask_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+                            kUseMasks);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+                            kUseMasks | kUseAntialiasing);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskAA_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+                            kUseMasks | kUseAntialiasing);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass_cm.png"),
+                            kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassColorMatrix_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass_cm.png"),
+                            kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) {
+  RunBlendingWithRenderPass(PIXEL_TEST_GL,
+                            FILE_PATH_LITERAL("blending_render_pass_cm.png"),
+                            kUseAntialiasing | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassColorMatrixAA_Software) {
+  RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE,
+                            FILE_PATH_LITERAL("blending_render_pass_cm.png"),
+                            kUseAntialiasing | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskColorMatrix_GL) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_GL,
+      FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
+      kUseMasks | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskColorMatrix_Software) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_SOFTWARE,
+      FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
+      kUseMasks | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskColorMatrixAA_GL) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_GL,
+      FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
+      kUseMasks | kUseAntialiasing | kUseColorMatrix);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+       BlendingWithRenderPassWithMaskColorMatrixAA_Software) {
+  RunBlendingWithRenderPass(
+      PIXEL_TEST_SOFTWARE,
+      FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"),
+      kUseMasks | kUseAntialiasing | kUseColorMatrix);
 }
 
 }  // namespace
diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc
index c0438ec..40fa2c3 100644
--- a/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -49,7 +49,7 @@
       small_error_allowed));
 #endif
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL("background_filter_blur.png")));
 }
@@ -90,10 +90,10 @@
       small_error_allowed));
 #endif
 
-  RunPixelTest(GL_WITH_BITMAP,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "background_filter_blur_outsets.png")));
+  RunPixelTest(
+      PIXEL_TEST_GL,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("background_filter_blur_outsets.png")));
 }
 
 TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
@@ -151,10 +151,10 @@
       small_error_allowed));
 #endif
 
-  RunPixelTest(GL_WITH_BITMAP,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "background_filter_blur_off_axis.png")));
+  RunPixelTest(
+      PIXEL_TEST_GL,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("background_filter_blur_off_axis.png")));
 }
 
 class LayerTreeHostFiltersScaledPixelTest
@@ -207,28 +207,20 @@
   float device_scale_factor_;
 };
 
-TEST_F(LayerTreeHostFiltersScaledPixelTest, StandardDpi_GLBitmap) {
-  RunPixelTestType(100, 1.f, GL_WITH_BITMAP);
-}
-
-TEST_F(LayerTreeHostFiltersScaledPixelTest, StandardDpi_GLDefault) {
-  RunPixelTestType(100, 1.f, GL_WITH_DEFAULT);
+TEST_F(LayerTreeHostFiltersScaledPixelTest, StandardDpi_GL) {
+  RunPixelTestType(100, 1.f, PIXEL_TEST_GL);
 }
 
 TEST_F(LayerTreeHostFiltersScaledPixelTest, StandardDpi_Software) {
-  RunPixelTestType(100, 1.f, SOFTWARE_WITH_BITMAP);
+  RunPixelTestType(100, 1.f, PIXEL_TEST_SOFTWARE);
 }
 
-TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_GLBitmap) {
-  RunPixelTestType(50, 2.f, GL_WITH_BITMAP);
-}
-
-TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_GLDefault) {
-  RunPixelTestType(50, 2.f, GL_WITH_DEFAULT);
+TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_GL) {
+  RunPixelTestType(50, 2.f, PIXEL_TEST_GL);
 }
 
 TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_Software) {
-  RunPixelTestType(50, 2.f, SOFTWARE_WITH_BITMAP);
+  RunPixelTestType(50, 2.f, PIXEL_TEST_SOFTWARE);
 }
 
 class ImageFilterClippedPixelTest : public LayerTreeHostFiltersPixelTest {
@@ -278,11 +270,11 @@
 };
 
 TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_GL) {
-  RunPixelTestType(GL_WITH_BITMAP);
+  RunPixelTestType(PIXEL_TEST_GL);
 }
 
 TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_Software) {
-  RunPixelTestType(SOFTWARE_WITH_BITMAP);
+  RunPixelTestType(PIXEL_TEST_SOFTWARE);
 }
 
 }  // namespace
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc
index 5aef5e3e..1b60eae 100644
--- a/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -67,7 +67,7 @@
   mask->SetIsMask(true);
   green->SetMaskLayer(mask.get());
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png")));
 }
@@ -98,7 +98,7 @@
   green->SetMaskLayer(mask.get());
   background->AddChild(green);
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png")));
 }
@@ -126,7 +126,7 @@
   mask->SetIsMask(true);
   green->SetMaskLayer(mask.get());
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL("mask_of_clipped_layer.png")));
 }
@@ -156,7 +156,7 @@
   replica->SetTransform(replica_transform);
   green->SetReplicaLayer(replica.get());
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL("mask_with_replica.png")));
 }
@@ -194,7 +194,7 @@
   replica->SetTransform(replica_transform);
   green->SetReplicaLayer(replica.get());
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL(
                    "mask_with_replica_of_clipped_layer.png")));
@@ -230,7 +230,7 @@
   replica->SetMaskLayer(mask.get());
   green->SetReplicaLayer(replica.get());
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
                base::FilePath(FILE_PATH_LITERAL("mask_of_replica.png")));
 }
@@ -272,10 +272,10 @@
   replica->SetMaskLayer(mask.get());
   green->SetReplicaLayer(replica.get());
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "mask_of_replica_of_clipped_layer.png")));
+               base::FilePath(
+                   FILE_PATH_LITERAL("mask_of_replica_of_clipped_layer.png")));
 }
 
 }  // namespace
diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
index 0689a27..74e20f5 100644
--- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
+++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
@@ -11,8 +11,8 @@
 #include "cc/trees/layer_tree_impl.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_f.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rect_f.h"
 
 #if !defined(OS_ANDROID)
 
@@ -97,7 +97,7 @@
   layer->SetBounds(layer_rect.size());
   layer->SetPosition(layer_rect.origin());
 
-  RunPixelTest(GL_WITH_BITMAP,
+  RunPixelTest(PIXEL_TEST_GL,
                layer,
                base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")));
 }
diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc
index 6b67e506..0a06144 100644
--- a/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -22,28 +22,51 @@
 class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest {
  protected:
   LayerTreeHostReadbackPixelTest()
-      : insert_copy_request_after_frame_count_(0) {}
+      : readback_type_(READBACK_INVALID),
+        insert_copy_request_after_frame_count_(0) {}
+
+  enum ReadbackType {
+    READBACK_INVALID,
+    READBACK_DEFAULT,
+    READBACK_BITMAP,
+  };
+
+  void RunReadbackTest(PixelTestType test_type,
+                       ReadbackType readback_type,
+                       scoped_refptr<Layer> content_root,
+                       base::FilePath file_name) {
+    readback_type_ = readback_type;
+    RunPixelTest(test_type, content_root, file_name);
+  }
+
+  void RunReadbackTestWithReadbackTarget(PixelTestType type,
+                                         ReadbackType readback_type,
+                                         scoped_refptr<Layer> content_root,
+                                         Layer* target,
+                                         base::FilePath file_name) {
+    readback_type_ = readback_type;
+    RunPixelTestWithReadbackTarget(type, content_root, target, file_name);
+  }
 
   scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest() override {
     scoped_ptr<CopyOutputRequest> request;
 
-    switch (test_type_) {
-      case GL_WITH_BITMAP:
-      case SOFTWARE_WITH_BITMAP:
-        request = CopyOutputRequest::CreateBitmapRequest(
-            base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
-                       base::Unretained(this)));
-        break;
-      case SOFTWARE_WITH_DEFAULT:
+    if (readback_type_ == READBACK_BITMAP) {
+      request = CopyOutputRequest::CreateBitmapRequest(
+          base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
+                     base::Unretained(this)));
+    } else {
+      DCHECK_EQ(readback_type_, READBACK_DEFAULT);
+      if (test_type_ == PIXEL_TEST_SOFTWARE) {
         request = CopyOutputRequest::CreateRequest(
             base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
                        base::Unretained(this)));
-        break;
-      case GL_WITH_DEFAULT:
+      } else {
+        DCHECK_EQ(test_type_, PIXEL_TEST_GL);
         request = CopyOutputRequest::CreateRequest(
             base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture,
                        base::Unretained(this)));
-        break;
+      }
     }
 
     if (!copy_subrect_.IsEmpty())
@@ -93,421 +116,438 @@
     ReadbackResultAsBitmap(CopyOutputResult::CreateBitmapResult(bitmap.Pass()));
   }
 
+  ReadbackType readback_type_;
   gfx::Rect copy_subrect_;
   int insert_copy_request_after_frame_count_;
 };
 
-void IgnoreReadbackResult(scoped_ptr<CopyOutputResult> result) {}
+void IgnoreReadbackResult(scoped_ptr<CopyOutputResult> result) {
+}
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTest(SOFTWARE_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green.png")));
+  RunReadbackTest(PIXEL_TEST_SOFTWARE,
+                  READBACK_DEFAULT,
+                  background,
+                  base::FilePath(FILE_PATH_LITERAL("green.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTest(SOFTWARE_WITH_BITMAP,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green.png")));
+  RunReadbackTest(PIXEL_TEST_SOFTWARE,
+                  READBACK_BITMAP,
+                  background,
+                  base::FilePath(FILE_PATH_LITERAL("green.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTest(GL_WITH_BITMAP,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green.png")));
+  RunReadbackTest(PIXEL_TEST_GL,
+                  READBACK_BITMAP,
+                  background,
+                  base::FilePath(FILE_PATH_LITERAL("green.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTest(GL_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green.png")));
+  RunReadbackTest(PIXEL_TEST_GL,
+                  READBACK_DEFAULT,
+                  background,
+                  base::FilePath(FILE_PATH_LITERAL("green.png")));
 }
 
-TEST_F(LayerTreeHostReadbackPixelTest,
-       ReadbackRootLayerWithChild_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_Software) {
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
-  RunPixelTest(SOFTWARE_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green_with_blue_corner.png")));
+  RunReadbackTest(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
-  RunPixelTest(GL_WITH_BITMAP,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green_with_blue_corner.png")));
+  RunReadbackTest(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
-  RunPixelTest(GL_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green_with_blue_corner.png")));
+  RunReadbackTest(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green.png")));
 }
 
-TEST_F(LayerTreeHostReadbackPixelTest,
-       ReadbackSmallNonRootLayer_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_Software) {
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
   background->AddChild(green);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
        ReadbackSmallNonRootLayerWithChild_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
-  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
        ReadbackSmallNonRootLayerWithChild_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
        ReadbackSubtreeSurroundsTargetLayer_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorRED);
+  scoped_refptr<SolidColorLayer> target =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorRED);
   background->AddChild(target);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN);
   target->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
   target->AddChild(blue);
 
   copy_subrect_ = gfx::Rect(0, 0, 100, 100);
-  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
-                                 background,
-                                 target.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      target.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
        ReadbackSubtreeSurroundsLayer_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorRED);
+  scoped_refptr<SolidColorLayer> target =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorRED);
   background->AddChild(target);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN);
   target->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
   target->AddChild(blue);
 
   copy_subrect_ = gfx::Rect(0, 0, 100, 100);
-  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
-                                 background,
-                                 target.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
+      background,
+      target.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
-TEST_F(LayerTreeHostReadbackPixelTest,
-       ReadbackSubtreeSurroundsTargetLayer_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
+TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubtreeSurroundsTargetLayer_GL) {
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 100, 100), SK_ColorRED);
+  scoped_refptr<SolidColorLayer> target =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorRED);
   background->AddChild(target);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN);
   target->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
   target->AddChild(blue);
 
   copy_subrect_ = gfx::Rect(0, 0, 100, 100);
-  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
-                                 background,
-                                 target.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      target.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
        ReadbackSubtreeExtendsBeyondTargetLayer_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 150, 150), SK_ColorRED);
+  scoped_refptr<SolidColorLayer> target =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 150, 150), SK_ColorRED);
   background->AddChild(target);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 200, 200), SK_ColorGREEN);
   target->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
   target->AddChild(blue);
 
   copy_subrect_ = gfx::Rect(50, 50, 100, 100);
-  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
-                                 background,
-                                 target.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      target.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
        ReadbackSubtreeExtendsBeyondTargetLayer_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 150, 150), SK_ColorRED);
+  scoped_refptr<SolidColorLayer> target =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 150, 150), SK_ColorRED);
   background->AddChild(target);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 200, 200), SK_ColorGREEN);
   target->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
   target->AddChild(blue);
 
   copy_subrect_ = gfx::Rect(50, 50, 100, 100);
-  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
-                                 background,
-                                 target.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
+      background,
+      target.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
        ReadbackSubtreeExtendsBeyondTargetLayer_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 150, 150), SK_ColorRED);
+  scoped_refptr<SolidColorLayer> target =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 150, 150), SK_ColorRED);
   background->AddChild(target);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(50, 50, 200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(50, 50, 200, 200), SK_ColorGREEN);
   target->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
   target->AddChild(blue);
 
   copy_subrect_ = gfx::Rect(50, 50, 100, 100);
-  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
-                                 background,
-                                 target.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      target.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackHiddenSubtree_Software) {
@@ -523,8 +563,9 @@
       CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
   hidden_target->AddChild(blue);
 
-  RunPixelTestWithReadbackTarget(
-      SOFTWARE_WITH_DEFAULT,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
       background,
       hidden_target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
@@ -543,8 +584,9 @@
       CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
   hidden_target->AddChild(blue);
 
-  RunPixelTestWithReadbackTarget(
-      GL_WITH_BITMAP,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
       background,
       hidden_target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
@@ -563,8 +605,9 @@
       CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
   hidden_target->AddChild(blue);
 
-  RunPixelTestWithReadbackTarget(
-      GL_WITH_DEFAULT,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
       background,
       hidden_target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
@@ -586,9 +629,10 @@
 
   hidden_target->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
       base::Bind(&IgnoreReadbackResult)));
-  RunPixelTest(SOFTWARE_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL("black.png")));
+  RunReadbackTest(PIXEL_TEST_SOFTWARE,
+                  READBACK_DEFAULT,
+                  background,
+                  base::FilePath(FILE_PATH_LITERAL("black.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
@@ -607,9 +651,10 @@
 
   hidden_target->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
       base::Bind(&IgnoreReadbackResult)));
-  RunPixelTest(GL_WITH_BITMAP,
-               background,
-               base::FilePath(FILE_PATH_LITERAL("black.png")));
+  RunReadbackTest(PIXEL_TEST_GL,
+                  READBACK_BITMAP,
+                  background,
+                  base::FilePath(FILE_PATH_LITERAL("black.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest,
@@ -628,138 +673,145 @@
 
   hidden_target->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
       base::Bind(&IgnoreReadbackResult)));
-  RunPixelTest(GL_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL("black.png")));
+  RunReadbackTest(PIXEL_TEST_GL,
+                  READBACK_DEFAULT,
+                  background,
+                  base::FilePath(FILE_PATH_LITERAL("black.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
   // Grab the middle of the root layer.
   copy_subrect_ = gfx::Rect(50, 50, 100, 100);
 
-  RunPixelTest(SOFTWARE_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green_small_with_blue_corner.png")));
+  RunReadbackTest(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
   // Grab the middle of the root layer.
   copy_subrect_ = gfx::Rect(50, 50, 100, 100);
 
-  RunPixelTest(GL_WITH_BITMAP,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green_small_with_blue_corner.png")));
+  RunReadbackTest(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
   // Grab the middle of the root layer.
   copy_subrect_ = gfx::Rect(50, 50, 100, 100);
 
-  RunPixelTest(GL_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green_small_with_blue_corner.png")));
+  RunReadbackTest(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_Software) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
   // Grab the middle of the green layer.
   copy_subrect_ = gfx::Rect(25, 25, 100, 100);
 
-  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_GL_Bitmap) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
   // Grab the middle of the green layer.
   copy_subrect_ = gfx::Rect(25, 25, 100, 100);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_GL) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
   // Grab the middle of the green layer.
   copy_subrect_ = gfx::Rect(25, 25, 100, 100);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackWhenNoDamage_Software) {
@@ -779,8 +831,9 @@
   target->AddChild(blue);
 
   insert_copy_request_after_frame_count_ = 1;
-  RunPixelTestWithReadbackTarget(
-      SOFTWARE_WITH_DEFAULT,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
       background,
       target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
@@ -803,8 +856,9 @@
   target->AddChild(blue);
 
   insert_copy_request_after_frame_count_ = 1;
-  RunPixelTestWithReadbackTarget(
-      GL_WITH_BITMAP,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
       background,
       target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
@@ -827,8 +881,9 @@
   target->AddChild(blue);
 
   insert_copy_request_after_frame_count_ = 1;
-  RunPixelTestWithReadbackTarget(
-      GL_WITH_DEFAULT,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
       background,
       target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
@@ -853,8 +908,9 @@
   target->AddChild(blue);
 
   insert_copy_request_after_frame_count_ = 1;
-  RunPixelTestWithReadbackTarget(
-      SOFTWARE_WITH_DEFAULT,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
       background,
       target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
@@ -879,8 +935,9 @@
   target->AddChild(blue);
 
   insert_copy_request_after_frame_count_ = 1;
-  RunPixelTestWithReadbackTarget(
-      GL_WITH_BITMAP,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_BITMAP,
       background,
       target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
@@ -904,8 +961,9 @@
   target->AddChild(blue);
 
   insert_copy_request_after_frame_count_ = 1;
-  RunPixelTestWithReadbackTarget(
-      GL_WITH_DEFAULT,
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
       background,
       target.get(),
       base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
@@ -941,8 +999,7 @@
   SolidColorContentLayerClient blue_client_;
 };
 
-TEST_F(LayerTreeHostReadbackDeviceScalePixelTest,
-       ReadbackSubrect_Software) {
+TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackSubrect_Software) {
   scoped_refptr<FakePictureLayer> background =
       FakePictureLayer::Create(&white_client_);
   background->SetBounds(gfx::Size(100, 100));
@@ -964,14 +1021,14 @@
   // Grab the middle of the root layer.
   copy_subrect_ = gfx::Rect(25, 25, 50, 50);
   device_scale_factor_ = 2.f;
-  RunPixelTest(SOFTWARE_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green_small_with_blue_corner.png")));
+  RunReadbackTest(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
-TEST_F(LayerTreeHostReadbackDeviceScalePixelTest,
-       ReadbackSubrect_GL) {
+TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackSubrect_GL) {
   scoped_refptr<FakePictureLayer> background =
       FakePictureLayer::Create(&white_client_);
   background->SetBounds(gfx::Size(100, 100));
@@ -993,10 +1050,11 @@
   // Grab the middle of the root layer.
   copy_subrect_ = gfx::Rect(25, 25, 50, 50);
   device_scale_factor_ = 2.f;
-  RunPixelTest(GL_WITH_DEFAULT,
-               background,
-               base::FilePath(FILE_PATH_LITERAL(
-                   "green_small_with_blue_corner.png")));
+  RunReadbackTest(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackDeviceScalePixelTest,
@@ -1023,11 +1081,12 @@
   // Grab the green layer's content with blue in the bottom right.
   copy_subrect_ = gfx::Rect(25, 25, 50, 50);
   device_scale_factor_ = 2.f;
-  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_SOFTWARE,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackDeviceScalePixelTest,
@@ -1054,33 +1113,35 @@
   // Grab the green layer's content with blue in the bottom right.
   copy_subrect_ = gfx::Rect(25, 25, 50, 50);
   device_scale_factor_ = 2.f;
-  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_small_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
 }
 
 TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerOutsideViewport) {
-  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorWHITE);
+  scoped_refptr<SolidColorLayer> background =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
 
-  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
-      gfx::Rect(200, 200), SK_ColorGREEN);
+  scoped_refptr<SolidColorLayer> green =
+      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN);
   // Only the top left quarter of the layer is inside the viewport, so the
   // blue layer is entirely outside.
   green->SetPosition(gfx::Point(100, 100));
   background->AddChild(green);
 
-  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
-      gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
+  scoped_refptr<SolidColorLayer> blue =
+      CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
   green->AddChild(blue);
 
-  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
-                                 background,
-                                 green.get(),
-                                 base::FilePath(FILE_PATH_LITERAL(
-                                     "green_with_blue_corner.png")));
+  RunReadbackTestWithReadbackTarget(
+      PIXEL_TEST_GL,
+      READBACK_DEFAULT,
+      background,
+      green.get(),
+      base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")));
 }
 
 }  // namespace
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 8fb9b8c..8d554dc 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -55,9 +55,9 @@
 #include "third_party/khronos/GLES2/gl2ext.h"
 #include "third_party/skia/include/core/SkPicture.h"
 #include "ui/gfx/frame_time.h"
-#include "ui/gfx/point_conversions.h"
-#include "ui/gfx/size_conversions.h"
-#include "ui/gfx/vector2d_conversions.h"
+#include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 
 using testing::_;
 using testing::AnyNumber;
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 8349bae..15ac8643 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -919,8 +919,7 @@
                                  NULL,
                                  0,
                                  false,
-                                 1,
-                                 false);
+                                 1);
   }
 
   static void EmptyReleaseCallback(unsigned sync_point, bool lost) {}
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index c4f2eb3..e922f217 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -16,9 +16,9 @@
 #include "cc/test/layer_tree_test.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/trees/layer_tree_impl.h"
-#include "ui/gfx/point_conversions.h"
-#include "ui/gfx/size_conversions.h"
-#include "ui/gfx/vector2d_conversions.h"
+#include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 
 namespace cc {
 namespace {
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 206ec60..8f2f0139 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -27,9 +27,9 @@
 #include "cc/trees/layer_tree_host_common.h"
 #include "cc/trees/layer_tree_host_impl.h"
 #include "cc/trees/occlusion_tracker.h"
-#include "ui/gfx/point_conversions.h"
-#include "ui/gfx/size_conversions.h"
-#include "ui/gfx/vector2d_conversions.h"
+#include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 
 namespace cc {
 
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc
index 7fc16457..f8de8b0 100644
--- a/cc/trees/layer_tree_impl_unittest.cc
+++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -13,7 +13,7 @@
 #include "cc/test/layer_tree_host_common_test.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/trees/layer_tree_host_impl.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 namespace {
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index 8e11015..1d5cf1bb 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -15,6 +15,7 @@
 LayerTreeSettings::LayerTreeSettings()
     : impl_side_painting(false),
       allow_antialiasing(true),
+      force_antialiasing(false),
       throttle_frame_production(true),
       single_thread_proxy_scheduler(true),
       begin_frame_scheduling_enabled(false),
@@ -66,6 +67,7 @@
       ignore_root_layer_flings(false),
       use_rgba_4444_textures(false),
       texture_id_allocation_chunk_size(64),
+      scheduled_raster_task_limit(32),
       use_occlusion_for_tile_prioritization(false),
       record_full_layer(false) {
 }
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index c0c14538..74a3b0c 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -9,7 +9,7 @@
 #include "cc/base/cc_export.h"
 #include "cc/debug/layer_tree_debug_state.h"
 #include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/size.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace cc {
 
@@ -20,6 +20,7 @@
 
   bool impl_side_painting;
   bool allow_antialiasing;
+  bool force_antialiasing;
   bool throttle_frame_production;
   bool single_thread_proxy_scheduler;
   bool begin_frame_scheduling_enabled;
@@ -76,6 +77,7 @@
   bool ignore_root_layer_flings;
   bool use_rgba_4444_textures;
   size_t texture_id_allocation_chunk_size;
+  size_t scheduled_raster_task_limit;
   bool use_occlusion_for_tile_prioritization;
   bool record_full_layer;
 
diff --git a/cc/trees/occlusion.cc b/cc/trees/occlusion.cc
index 70ee32c..14168f9 100644
--- a/cc/trees/occlusion.cc
+++ b/cc/trees/occlusion.cc
@@ -5,7 +5,7 @@
 #include "cc/trees/occlusion.h"
 
 #include "cc/base/math_util.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
diff --git a/cc/trees/occlusion.h b/cc/trees/occlusion.h
index 6d1e5b1f..56f9962d 100644
--- a/cc/trees/occlusion.h
+++ b/cc/trees/occlusion.h
@@ -8,7 +8,7 @@
 #include "base/basictypes.h"
 #include "cc/base/cc_export.h"
 #include "cc/base/simple_enclosed_region.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc
index 7d90834..bce1fd5 100644
--- a/cc/trees/occlusion_tracker.cc
+++ b/cc/trees/occlusion_tracker.cc
@@ -12,8 +12,8 @@
 #include "cc/layers/layer_impl.h"
 #include "cc/layers/render_surface.h"
 #include "cc/layers/render_surface_impl.h"
-#include "ui/gfx/quad_f.h"
-#include "ui/gfx/rect_conversions.h"
+#include "ui/gfx/geometry/quad_f.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 
 namespace cc {
 
diff --git a/cc/trees/occlusion_tracker.h b/cc/trees/occlusion_tracker.h
index b96752ce..4d6555a 100644
--- a/cc/trees/occlusion_tracker.h
+++ b/cc/trees/occlusion_tracker.h
@@ -12,7 +12,7 @@
 #include "cc/base/simple_enclosed_region.h"
 #include "cc/layers/layer_iterator.h"
 #include "cc/trees/occlusion.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 class LayerImpl;
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index f1ef3610..429b587 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -1305,7 +1305,7 @@
   bool smoothness_takes_priority =
       impl().layer_tree_host_impl->pinch_gesture_active() ||
       impl().layer_tree_host_impl->page_scale_animation_active() ||
-      impl().layer_tree_host_impl->IsCurrentlyScrolling();
+      impl().layer_tree_host_impl->IsActivelyScrolling();
 
   // Schedule expiration if smoothness currently takes priority.
   if (smoothness_takes_priority)
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index f5753590..90a5314 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -529,6 +529,26 @@
 
 if (is_android) {
 
+# GYP: //chrome/chrome.gyp:content_setting_java
+java_cpp_enum("content_setting_javagen") {
+  sources = [
+    "../components/content_settings/core/common/content_settings.h"
+  ]
+  outputs = [
+    "org/chromium/chrome/browser/ContentSetting.java",
+  ]
+}
+
+# GYP: //chrome/chrome.gyp:content_settings_type_java
+java_cpp_enum("content_settings_type_javagen") {
+  sources = [
+    "../components/content_settings/core/common/content_settings_types.h"
+  ]
+  outputs = [
+    "org/chromium/chrome/browser/ContentSettingsType.java",
+  ]
+}
+
 # GYP: //chrome/chrome.gyp:page_info_connection_type_java
 java_cpp_enum("page_info_connection_type_javagen") {
   sources = [
diff --git a/chrome/OWNERS b/chrome/OWNERS
index ff7a3940..42e4b8c7 100644
--- a/chrome/OWNERS
+++ b/chrome/OWNERS
@@ -8,10 +8,6 @@
 thakis@chromium.org
 thestig@chromium.org
 
-# Just owners:
-darin@chromium.org
-jam@chromium.org
-
 # per-file rules:
 # These are for the common case of adding or renaming files. If you're doing
 # structural changes, please get a review from a reviewer in this file.
diff --git a/chrome/VERSION b/chrome/VERSION
index 88266486..414b7586 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=40
 MINOR=0
-BUILD=2197
+BUILD=2200
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 3eea9ee..e852cfe 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -98,28 +98,37 @@
   ]
 
   srcjar_deps = [
-    ":activity_type_ids_javagen",
     ":app_banner_metrics_ids_javagen",
-    ":profile_account_management_metrics_javagen",
-    ":profile_sync_service_model_type_selection_javagen",
-    ":resource_id_javagen",
-    ":toolbar_model_security_levels_javagen",
-    ":tab_load_status_javagen",
+    ":chrome_android_java_enums_srcjar",
     ":chrome_version_srcjar",
+    ":resource_id_javagen",
     "//chrome:page_info_connection_type_javagen",
+    "//chrome:content_setting_javagen",
+    "//chrome:content_settings_type_javagen",
   ]
 
   DEPRECATED_java_in_dir = "java/src"
 }
 
 # GYP: //chrome/chrome_browser.gypi:activity_type_ids_java
-java_cpp_template("activity_type_ids_javagen") {
+# GYP: //chrome/chrome_browser.gypi:profile_account_management_metrics_java
+# GYP: //chrome/chrome_browser.gypi:profile_sync_service_model_type_selection_java
+# GYP: //chrome/chrome_browser.gypi:tab_load_status_java
+# GYP: //chrome/chrome_browser.gypi:toolbar_model_security_levels_java
+java_cpp_enum("chrome_android_java_enums_srcjar") {
   sources = [
-    "java/ActivityTypeIds.template",
+    "//chrome/browser/android/activity_type_ids.h",
+    "//chrome/browser/android/tab_android.h",
+    "//chrome/browser/profiles/profile_metrics.h",
+    "//chrome/browser/sync/profile_sync_service_android.cc",
+    "//chrome/browser/ui/toolbar/toolbar_model.h",
   ]
-  package_name = "org/chromium/chrome/browser"
-  inputs = [
-    "../browser/android/activity_type_id_list.h"
+  outputs = [
+    "org/chromium/chrome/browser/ActivityTypeIds.java",
+    "org/chromium/chrome/browser/TabLoadStatus.java",
+    "org/chromium/chrome/browser/profiles/ProfileAccountManagementMetrics.java",
+    "org/chromium/chrome/browser/sync/ModelTypeSelection.java",
+    "org/chromium/chrome/browser/ui/toolbar/ToolbarModelSecurityLevel.java",
   ]
 }
 
@@ -145,50 +154,6 @@
   ]
 }
 
-# GYP: //chrome/chrome_browser.gypi:profile_account_management_metrics_java
-java_cpp_template("profile_account_management_metrics_javagen") {
-  sources = [
-    "java/ProfileAccountManagementMetrics.template",
-  ]
-  package_name = "org/chromium/chrome/browser/profiles"
-  inputs = [
-    "../browser/profiles/profile_metrics_list.h"
-  ]
-}
-
-# GYP: //chrome/chrome_browser.gypi:profile_sync_service_model_type_selection_java
-java_cpp_template("profile_sync_service_model_type_selection_javagen") {
-  sources = [
-    "java/ModelTypeSelection.template",
-  ]
-  package_name = "org/chromium/chrome/browser/sync"
-  inputs = [
-    "../browser/sync/profile_sync_service_model_type_selection_android.h"
-  ]
-}
-
-# GYP: //chrome/chrome_browser.gypi:toolbar_model_security_levels_java
-java_cpp_template("toolbar_model_security_levels_javagen") {
-  sources = [
-    "java/ToolbarModelSecurityLevel.template",
-  ]
-  package_name = "org/chromium/chrome/browser/ui/toolbar"
-  inputs = [
-    "../browser/ui/toolbar/toolbar_model_security_level_list.h"
-  ]
-}
-
-# GYP: //chrome/chrome_browser.gypi:tab_load_status_java
-java_cpp_template("tab_load_status_javagen") {
-  sources = [
-    "java/TabLoadStatus.template",
-  ]
-  package_name = "org/chromium/chrome/browser"
-  inputs = [
-    "../browser/android/tab_load_status.h"
-  ]
-}
-
 # GYP: //chrome/chrome_shell.gypi:libchromeshell_base
 static_library("chrome_shell_base") {
   sources = [
diff --git a/chrome/android/java/ActivityTypeIds.template b/chrome/android/java/ActivityTypeIds.template
deleted file mode 100644
index 4f64e8b..0000000
--- a/chrome/android/java/ActivityTypeIds.template
+++ /dev/null
@@ -1,11 +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.
-
-package org.chromium.chrome.browser;
-
-public class ActivityTypeIds {
-#define DEFINE_ACTIVITY_ID(id,value) public static final int ACTIVITY_##id = value;
-#include "chrome/browser/android/activity_type_id_list.h"
-#undef DEFINE_ACTIVITY_ID
-}
diff --git a/chrome/android/java/ModelTypeSelection.template b/chrome/android/java/ModelTypeSelection.template
deleted file mode 100644
index 339e0a5..0000000
--- a/chrome/android/java/ModelTypeSelection.template
+++ /dev/null
@@ -1,10 +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.sync;
-
-public class ModelTypeSelection {
-#define DEFINE_MODEL_TYPE_SELECTION(name, value) public static final int name = value;
-#include "chrome/browser/sync/profile_sync_service_model_type_selection_android.h"
-}
diff --git a/chrome/android/java/ProfileAccountManagementMetrics.template b/chrome/android/java/ProfileAccountManagementMetrics.template
deleted file mode 100644
index 1e2736d8..0000000
--- a/chrome/android/java/ProfileAccountManagementMetrics.template
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.chrome.browser.profiles;
-
-/**
- * Constants for the Android account management screen histogram.
- */
-public class ProfileAccountManagementMetrics {
-#define PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(label, value) public static final int label = value;
-#include "chrome/browser/profiles/profile_metrics_list.h"
-}
diff --git a/chrome/android/java/TabLoadStatus.template b/chrome/android/java/TabLoadStatus.template
deleted file mode 100644
index e004489..0000000
--- a/chrome/android/java/TabLoadStatus.template
+++ /dev/null
@@ -1,11 +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.
-
-package org.chromium.chrome.browser;
-
-public class TabLoadStatus {
-#define DEFINE_TAB_LOAD_STATUS(name,value) \
-  public static final int name = value;
-#include "chrome/browser/android/tab_load_status.h"
-}
diff --git a/chrome/android/java/ToolbarModelSecurityLevel.template b/chrome/android/java/ToolbarModelSecurityLevel.template
deleted file mode 100644
index 2f4f1fbd..0000000
--- a/chrome/android/java/ToolbarModelSecurityLevel.template
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 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.ui.toolbar;
-
-public class ToolbarModelSecurityLevel {
-#define DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(name,value) \
-  public static final int name = value;
-#include "chrome/browser/ui/toolbar/toolbar_model_security_level_list.h"
-}
diff --git a/chrome/android/java/res/OWNERS b/chrome/android/java/res/OWNERS
new file mode 100644
index 0000000..7b0bde5
--- /dev/null
+++ b/chrome/android/java/res/OWNERS
@@ -0,0 +1,7 @@
+set noparent
+tedchoc@chromium.org
+aurimas@chromium.org
+newt@chromium.org
+dtrainor@chromium.org
+yusufo@chromium.org
+dfalcantara@chromium.org
diff --git a/chrome/android/java/res/drawable-hdpi/page_info_arrow_down.png b/chrome/android/java/res/drawable-hdpi/page_info_arrow_down.png
new file mode 100644
index 0000000..2857791
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/page_info_arrow_down.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_auto_downloads.png b/chrome/android/java/res/drawable-hdpi/permission_auto_downloads.png
new file mode 100644
index 0000000..16c73b40
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_auto_downloads.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_fullscreen.png b/chrome/android/java/res/drawable-hdpi/permission_fullscreen.png
new file mode 100644
index 0000000..ed44f48
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_fullscreen.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_images.png b/chrome/android/java/res/drawable-hdpi/permission_images.png
new file mode 100644
index 0000000..dad1fc6
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_images.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_javascript.png b/chrome/android/java/res/drawable-hdpi/permission_javascript.png
new file mode 100644
index 0000000..536da728
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_javascript.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_location.png b/chrome/android/java/res/drawable-hdpi/permission_location.png
new file mode 100644
index 0000000..f32f0fd
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_location.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_media.png b/chrome/android/java/res/drawable-hdpi/permission_media.png
new file mode 100644
index 0000000..bdbffb5
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_media.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_plugins.png b/chrome/android/java/res/drawable-hdpi/permission_plugins.png
new file mode 100644
index 0000000..b78a60c
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_plugins.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_popups.png b/chrome/android/java/res/drawable-hdpi/permission_popups.png
new file mode 100644
index 0000000..8434086
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_popups.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/permission_push_notification.png b/chrome/android/java/res/drawable-hdpi/permission_push_notification.png
new file mode 100644
index 0000000..9fca575
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/permission_push_notification.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/page_info_arrow_down.png b/chrome/android/java/res/drawable-mdpi/page_info_arrow_down.png
new file mode 100644
index 0000000..425dada
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/page_info_arrow_down.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_auto_downloads.png b/chrome/android/java/res/drawable-mdpi/permission_auto_downloads.png
new file mode 100644
index 0000000..276b4cb
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_auto_downloads.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_fullscreen.png b/chrome/android/java/res/drawable-mdpi/permission_fullscreen.png
new file mode 100644
index 0000000..3ea17ff
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_fullscreen.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_images.png b/chrome/android/java/res/drawable-mdpi/permission_images.png
new file mode 100644
index 0000000..5848f59
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_images.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_javascript.png b/chrome/android/java/res/drawable-mdpi/permission_javascript.png
new file mode 100644
index 0000000..120c412ed
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_javascript.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_location.png b/chrome/android/java/res/drawable-mdpi/permission_location.png
new file mode 100644
index 0000000..8197d5a
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_location.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_media.png b/chrome/android/java/res/drawable-mdpi/permission_media.png
new file mode 100644
index 0000000..88c8dd5e
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_media.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_plugins.png b/chrome/android/java/res/drawable-mdpi/permission_plugins.png
new file mode 100644
index 0000000..8f74011
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_plugins.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_popups.png b/chrome/android/java/res/drawable-mdpi/permission_popups.png
new file mode 100644
index 0000000..2b8d7df
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_popups.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/permission_push_notification.png b/chrome/android/java/res/drawable-mdpi/permission_push_notification.png
new file mode 100644
index 0000000..f10ad07
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/permission_push_notification.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/page_info_arrow_down.png b/chrome/android/java/res/drawable-xhdpi/page_info_arrow_down.png
new file mode 100644
index 0000000..94a7329
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/page_info_arrow_down.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_auto_downloads.png b/chrome/android/java/res/drawable-xhdpi/permission_auto_downloads.png
new file mode 100644
index 0000000..4b290e29
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_auto_downloads.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_fullscreen.png b/chrome/android/java/res/drawable-xhdpi/permission_fullscreen.png
new file mode 100644
index 0000000..f3279cd
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_fullscreen.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_images.png b/chrome/android/java/res/drawable-xhdpi/permission_images.png
new file mode 100644
index 0000000..e756ce9f
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_images.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_javascript.png b/chrome/android/java/res/drawable-xhdpi/permission_javascript.png
new file mode 100644
index 0000000..285dad6
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_javascript.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_location.png b/chrome/android/java/res/drawable-xhdpi/permission_location.png
new file mode 100644
index 0000000..63fa514
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_location.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_media.png b/chrome/android/java/res/drawable-xhdpi/permission_media.png
new file mode 100644
index 0000000..2af4118
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_media.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_plugins.png b/chrome/android/java/res/drawable-xhdpi/permission_plugins.png
new file mode 100644
index 0000000..e5d7934
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_plugins.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_popups.png b/chrome/android/java/res/drawable-xhdpi/permission_popups.png
new file mode 100644
index 0000000..9cb18065
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_popups.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/permission_push_notification.png b/chrome/android/java/res/drawable-xhdpi/permission_push_notification.png
new file mode 100644
index 0000000..5d38016c
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/permission_push_notification.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/page_info_arrow_down.png b/chrome/android/java/res/drawable-xxhdpi/page_info_arrow_down.png
new file mode 100644
index 0000000..e7c29bb
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/page_info_arrow_down.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_auto_downloads.png b/chrome/android/java/res/drawable-xxhdpi/permission_auto_downloads.png
new file mode 100644
index 0000000..455b1ed
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_auto_downloads.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_fullscreen.png b/chrome/android/java/res/drawable-xxhdpi/permission_fullscreen.png
new file mode 100644
index 0000000..8173402
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_fullscreen.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_images.png b/chrome/android/java/res/drawable-xxhdpi/permission_images.png
new file mode 100644
index 0000000..632a152
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_images.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_javascript.png b/chrome/android/java/res/drawable-xxhdpi/permission_javascript.png
new file mode 100644
index 0000000..be712c7
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_javascript.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_location.png b/chrome/android/java/res/drawable-xxhdpi/permission_location.png
new file mode 100644
index 0000000..87f5683
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_location.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_media.png b/chrome/android/java/res/drawable-xxhdpi/permission_media.png
new file mode 100644
index 0000000..090367e
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_media.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_plugins.png b/chrome/android/java/res/drawable-xxhdpi/permission_plugins.png
new file mode 100644
index 0000000..467db27
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_plugins.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_popups.png b/chrome/android/java/res/drawable-xxhdpi/permission_popups.png
new file mode 100644
index 0000000..eefb7da
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_popups.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/permission_push_notification.png b/chrome/android/java/res/drawable-xxhdpi/permission_push_notification.png
new file mode 100644
index 0000000..78ac926
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/permission_push_notification.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/page_info_arrow_down.png b/chrome/android/java/res/drawable-xxxhdpi/page_info_arrow_down.png
new file mode 100644
index 0000000..ab9499f4
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/page_info_arrow_down.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_auto_downloads.png b/chrome/android/java/res/drawable-xxxhdpi/permission_auto_downloads.png
new file mode 100644
index 0000000..776948b6
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_auto_downloads.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_fullscreen.png b/chrome/android/java/res/drawable-xxxhdpi/permission_fullscreen.png
new file mode 100644
index 0000000..4767cfa
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_fullscreen.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_images.png b/chrome/android/java/res/drawable-xxxhdpi/permission_images.png
new file mode 100644
index 0000000..b24e12c1
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_images.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_javascript.png b/chrome/android/java/res/drawable-xxxhdpi/permission_javascript.png
new file mode 100644
index 0000000..f1dc487
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_javascript.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_location.png b/chrome/android/java/res/drawable-xxxhdpi/permission_location.png
new file mode 100644
index 0000000..fc36d31
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_location.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_media.png b/chrome/android/java/res/drawable-xxxhdpi/permission_media.png
new file mode 100644
index 0000000..a0aff53
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_media.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_plugins.png b/chrome/android/java/res/drawable-xxxhdpi/permission_plugins.png
new file mode 100644
index 0000000..7bd43ca
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_plugins.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_popups.png b/chrome/android/java/res/drawable-xxxhdpi/permission_popups.png
new file mode 100644
index 0000000..2694af7
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_popups.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/permission_push_notification.png b/chrome/android/java/res/drawable-xxxhdpi/permission_push_notification.png
new file mode 100644
index 0000000..4fcdf3d0
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/permission_push_notification.png
Binary files differ
diff --git a/chrome/android/java/res/drawable/website_settings_permission_spinner_dropdown_item.xml b/chrome/android/java/res/drawable/website_settings_permission_spinner_dropdown_item.xml
new file mode 100644
index 0000000..5b898f53
--- /dev/null
+++ b/chrome/android/java/res/drawable/website_settings_permission_spinner_dropdown_item.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    style="?android:attr/spinnerDropDownItemStyle"
+    android:singleLine="true"
+    android:layout_width="match_parent"
+    android:layout_height="?android:attr/listPreferredItemHeight"
+    android:textColor="@color/website_settings_popup_permission_spinner_text"
+    android:textSize="@dimen/website_settings_popup_permission_spinner_text_size"
+    android:ellipsize="marquee" />
diff --git a/chrome/android/java/res/drawable/website_settings_permission_spinner_item.xml b/chrome/android/java/res/drawable/website_settings_permission_spinner_item.xml
new file mode 100644
index 0000000..cc25891
--- /dev/null
+++ b/chrome/android/java/res/drawable/website_settings_permission_spinner_item.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    android:layout_width="match_parent"
+    android:layout_height="32dp"
+    android:paddingRight="20dp"
+    android:background="@drawable/website_settings_permission_spinner_item_background"
+    android:ellipsize="marquee"
+    android:gravity="center_vertical"
+    android:singleLine="true"
+    android:textColor="@color/website_settings_popup_permission_spinner_text"
+    android:textSize="@dimen/website_settings_popup_permission_spinner_text_size" />
diff --git a/chrome/android/java/res/drawable/website_settings_permission_spinner_item_background.xml b/chrome/android/java/res/drawable/website_settings_permission_spinner_item_background.xml
new file mode 100644
index 0000000..28145d1
--- /dev/null
+++ b/chrome/android/java/res/drawable/website_settings_permission_spinner_item_background.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+  <!-- To achieve a single border along the bottom, draw a rectangle offset by
+       1dp in all dimensions but the bottom. -->
+  <item android:top="-1dp" android:right="-1dp" android:left="-1dp">
+    <shape android:shape="rectangle" >
+       <stroke android:width="1dip" android:color="#e5e5e5"/>
+    </shape>
+  </item>
+  <item><bitmap android:gravity="right" android:src="@drawable/page_info_arrow_down" /></item>
+
+</layer-list>
diff --git a/chrome/android/java/res/layout/infobar_text.xml b/chrome/android/java/res/layout/infobar_text.xml
index d56dd76..cfdb0d9 100644
--- a/chrome/android/java/res/layout/infobar_text.xml
+++ b/chrome/android/java/res/layout/infobar_text.xml
@@ -5,7 +5,8 @@
      found in the LICENSE file.
 -->
 
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+<org.chromium.ui.widget.TextViewWithClickableSpans
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/infobar_message"
     android:layout_marginTop="@dimen/infobar_margin"
     android:layout_marginBottom="@dimen/infobar_margin"
diff --git a/chrome/android/java/res/layout/website_settings.xml b/chrome/android/java/res/layout/website_settings.xml
index 59aede5b..886a2674 100644
--- a/chrome/android/java/res/layout/website_settings.xml
+++ b/chrome/android/java/res/layout/website_settings.xml
@@ -8,26 +8,111 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/website_settings_popup_background"
-    android:orientation="vertical"
-    android:paddingBottom="@dimen/website_settings_margin_bottom"
-    android:paddingEnd="@dimen/website_settings_margin_sides"
-    android:paddingStart="@dimen/website_settings_margin_sides"
-    android:paddingTop="@dimen/website_settings_margin_top" >
+    android:background="#ffffff"
+    android:orientation="vertical" >
 
-    <TextView
-        android:id="@+id/website_settings_url"
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingBottom="@dimen/website_settings_margin_below_url"
-        android:textColor="@color/website_settings_popup_url"
-        android:textSize="@dimen/website_settings_url_title_size" />
+        android:orientation="vertical"
+        android:paddingEnd="@dimen/website_settings_popup_padding_sides"
+        android:paddingStart="@dimen/website_settings_popup_padding_sides" >
 
-    <TextView
-        android:id="@+id/website_settings_permission_message"
+        <TextView
+            android:id="@+id/website_settings_url"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:lineSpacingExtra="4dp"
+            android:paddingTop="16dp"
+            android:textColor="@color/website_settings_popup_url"
+            android:textSize="16dp"/>
+
+        <TextView
+            android:id="@+id/website_settings_connection_message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:lineSpacingExtra="3dp"
+            android:paddingTop="12dp"
+            android:textColor="#444444"
+            android:textSize="14dp" />
+
+        <Button
+            android:id="@+id/website_settings_copy_url_button"
+            style="?android:attr/borderlessButtonStyle"
+            android:layout_gravity="end"
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/website_settings_popup_button_height"
+            android:layout_marginEnd="@dimen/website_settings_popup_button_margin_sides"
+            android:layout_marginStart="@dimen/website_settings_popup_button_margin_sides"
+            android:layout_marginBottom="8dp"
+            android:layout_marginTop="24dp"
+            android:paddingEnd="@dimen/website_settings_popup_button_padding_sides"
+            android:paddingStart="@dimen/website_settings_popup_button_padding_sides"
+            android:text="@string/page_info_copy_url_button"
+            android:textAllCaps="true"
+            android:textColor="#4184f3"
+            android:textSize="@dimen/website_settings_popup_button_text_size"
+            android:textStyle="bold" />
+    </LinearLayout>
+
+    <!-- Horizontal separator -->
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dip"
+        android:background="#e7e7e7" />
+
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:textColor="@color/website_settings_popup_text"
-        android:textSize="@dimen/website_settings_url_description_size" />
+        android:orientation="vertical"
+        android:paddingStart="@dimen/website_settings_popup_padding_sides"
+        android:paddingEnd="@dimen/website_settings_popup_padding_sides" >
 
-</LinearLayout>
\ No newline at end of file
+        <LinearLayout
+            android:id="@+id/website_settings_permissions_list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical" >
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="end"
+            android:orientation="horizontal"
+            android:paddingTop="16dp"
+            android:paddingBottom="16dp" >
+
+            <Button
+                android:id="@+id/website_settings_site_settings_button"
+                style="?android:attr/borderlessButtonStyle"
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/website_settings_popup_button_height"
+                android:layout_marginEnd="@dimen/website_settings_popup_button_margin_sides"
+                android:layout_marginStart="@dimen/website_settings_popup_button_margin_sides"
+                android:paddingEnd="@dimen/website_settings_popup_button_padding_sides"
+                android:paddingStart="@dimen/website_settings_popup_button_padding_sides"
+                android:text="@string/page_info_site_settings_button"
+                android:textAllCaps="true"
+                android:textColor="@color/website_settings_popup_button_text"
+                android:textSize="@dimen/website_settings_popup_button_text_size"
+                android:textStyle="bold" />
+
+            <Button
+                android:id="@+id/website_settings_done_button"
+                style="?android:attr/borderlessButtonStyle"
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/website_settings_popup_button_height"
+                android:layout_marginEnd="@dimen/website_settings_popup_button_margin_sides"
+                android:layout_marginStart="@dimen/website_settings_popup_button_margin_sides"
+                android:paddingEnd="@dimen/website_settings_popup_button_padding_sides"
+                android:paddingStart="@dimen/website_settings_popup_button_padding_sides"
+                android:text="@string/page_info_done_button"
+                android:textAllCaps="true"
+                android:textColor="@color/website_settings_popup_button_text"
+                android:textSize="@dimen/website_settings_popup_button_text_size"
+                android:textStyle="bold" />
+        </LinearLayout>
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/chrome/android/java/res/layout/website_settings_permission_row.xml b/chrome/android/java/res/layout/website_settings_permission_row.xml
new file mode 100644
index 0000000..4d3dc8f
--- /dev/null
+++ b/chrome/android/java/res/layout/website_settings_permission_row.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+   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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:paddingTop="18dp" >
+
+    <ImageView
+        android:id="@+id/website_settings_permission_icon"
+        android:layout_width="@dimen/website_settings_popup_permission_icon_size"
+        android:layout_height="@dimen/website_settings_popup_permission_icon_size" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingStart="16dp" >
+
+        <TextView
+            android:id="@+id/website_settings_permission_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textColor="#444444"
+            android:textSize="14dp"
+            android:textStyle="bold" />
+
+        <Spinner
+            android:id="@+id/website_settings_permission_spinner"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml
index 550b8ac..6ba7bc5e 100644
--- a/chrome/android/java/res/values/colors.xml
+++ b/chrome/android/java/res/values/colors.xml
@@ -34,14 +34,14 @@
     <color name="website_settings_popup_reset_cert_decisions_button">#000000</color>
 
     <!--  Website Settings Popup colors -->
-    <color name="website_settings_popup_background">#f2f2f2</color>
-    <color name="website_settings_popup_text">#333333</color>
-    <color name="website_settings_popup_url">#666666</color>
-    <color name="website_settings_popup_url_domain">#333333</color>
+    <color name="website_settings_popup_button_text">#444444</color>
+    <color name="website_settings_popup_url">#848484</color>
+    <color name="website_settings_popup_url_domain">#444444</color>
     <color name="website_settings_popup_url_scheme_http">#666666</color>
     <color name="website_settings_popup_url_scheme_https">#1ac222</color>
-    <color name="website_settings_popup_url_scheme_mixed">#eba200</color>
+    <color name="website_settings_popup_url_scheme_mixed">#f2a600</color>
     <color name="website_settings_popup_url_scheme_broken">#db4437</color>
+    <color name="website_settings_popup_permission_spinner_text">#646464</color>
 
     <!--  Distilled Page Prefs colors -->
     <color name="distilled_page_prefs_selected">#999999</color>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index 38def67e..9b5e0303 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -10,12 +10,13 @@
     <dimen name="certificate_viewer_padding_thin">16dp</dimen>
 
     <!-- Website Settings Popup Dimensions -->
-    <dimen name="website_settings_margin_top">16dp</dimen>
-    <dimen name="website_settings_margin_sides">16dp</dimen>
-    <dimen name="website_settings_margin_bottom">18dp</dimen>
-    <dimen name="website_settings_margin_below_url">10dp</dimen>
-    <dimen name="website_settings_url_title_size">16dp</dimen>
-    <dimen name="website_settings_url_description_size">12dp</dimen>
+    <dimen name="website_settings_popup_padding_sides">16dp</dimen>
+    <dimen name="website_settings_popup_button_text_size">14dp</dimen>
+    <dimen name="website_settings_popup_button_height">36dp</dimen>
+    <dimen name="website_settings_popup_button_padding_sides">8dp</dimen>
+    <dimen name="website_settings_popup_button_margin_sides">4dp</dimen>
+    <dimen name="website_settings_popup_permission_icon_size">24dp</dimen>
+    <dimen name="website_settings_popup_permission_spinner_text_size">16dp</dimen>
 
     <!-- Accessibility tab switcher -->
     <dimen name="accessibility_tab_height">65dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/ChromeSwitches.java b/chrome/android/java/src/org/chromium/chrome/ChromeSwitches.java
index c19e061..765a21f 100644
--- a/chrome/android/java/src/org/chromium/chrome/ChromeSwitches.java
+++ b/chrome/android/java/src/org/chromium/chrome/ChromeSwitches.java
@@ -9,11 +9,11 @@
  * portion of Chromium on Android.
  */
 public abstract class ChromeSwitches {
-    // Enables the new Website Settings dialog, which replaces the old one.
-    // TODO(sashab): Once the new WebsiteSettingsPopup is ready to launch,
+    // Disables the new Website Settings dialog, which replaces the old one.
+    // TODO(sashab): Once the new WebsiteSettingsPopup is ready to be permanent,
     // remove this flag and delete WebsiteSettingsLegacyPopup and all it's
     // dependencies.
-    public static final String ENABLE_NEW_WEBSITE_SETTINGS = "enable-new-website-settings";
+    public static final String DISABLE_NEW_WEBSITE_SETTINGS = "disable-new-website-settings";
 
     // Prevent instantiation.
     private ChromeSwitches() {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BookmarksBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/BookmarksBridge.java
index 162a150..c521dda 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/BookmarksBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/BookmarksBridge.java
@@ -268,6 +268,7 @@
     /**
      * @return The BookmarkId for Mobile folder node
      */
+    @VisibleForTesting
     public BookmarkId getMobileFolderId() {
         assert mIsNativeBookmarkModelLoaded;
         return nativeGetMobileFolderId(mNativeBookmarksBridge);
@@ -434,7 +435,7 @@
      *         not editable), returns null.
      */
     public BookmarkId addFolder(BookmarkId parent, int index, String title) {
-        assert parent.getType() == BookmarkType.BOOKMARK_TYPE_NORMAL;
+        assert parent.getType() == BookmarkType.NORMAL;
         assert index >= 0;
         assert title != null;
 
@@ -454,7 +455,7 @@
      *         not editable), returns null.
      */
     public BookmarkId addBookmark(BookmarkId parent, int index, String title, String url) {
-        assert parent.getType() == BookmarkType.BOOKMARK_TYPE_NORMAL;
+        assert parent.getType() == BookmarkType.NORMAL;
         assert index >= 0;
         assert title != null;
         assert url != null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/NavigationPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/NavigationPopup.java
index 792a15f..f7dd876 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/NavigationPopup.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/NavigationPopup.java
@@ -23,7 +23,7 @@
 
 import org.chromium.base.CalledByNative;
 import org.chromium.base.ThreadUtils;
-import org.chromium.content.browser.NavigationClient;
+import org.chromium.content_public.browser.NavigationController;
 import org.chromium.content_public.browser.NavigationEntry;
 import org.chromium.content_public.browser.NavigationHistory;
 import org.chromium.ui.base.LocalizationUtils;
@@ -41,7 +41,7 @@
     private static final int MAXIMUM_HISTORY_ITEMS = 8;
 
     private final Context mContext;
-    private final NavigationClient mNavigationClient;
+    private final NavigationController mNavigationController;
     private final NavigationHistory mHistory;
     private final NavigationAdapter mAdapter;
     private final ListItemFactory mListItemFactory;
@@ -54,15 +54,15 @@
      * Constructs a new popup with the given history information.
      *
      * @param context The context used for building the popup.
-     * @param navigationClient The owner of the history being displayed.
+     * @param navigationController The controller which takes care of page navigations.
      * @param isForward Whether to request forward navigation entries.
      */
     public NavigationPopup(
-            Context context, NavigationClient navigationClient, boolean isForward) {
+            Context context, NavigationController navigationController, boolean isForward) {
         super(context, null, android.R.attr.popupMenuStyle);
         mContext = context;
-        mNavigationClient = navigationClient;
-        mHistory = mNavigationClient.getDirectedNavigationHistory(
+        mNavigationController = navigationController;
+        mHistory = mNavigationController.getDirectedNavigationHistory(
                 isForward, MAXIMUM_HISTORY_ITEMS);
         mAdapter = new NavigationAdapter();
 
@@ -130,7 +130,7 @@
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         NavigationEntry entry = (NavigationEntry) parent.getItemAtPosition(position);
-        mNavigationClient.goToNavigationIndex(entry.getIndex());
+        mNavigationController.goToNavigationIndex(entry.getIndex());
         dismiss();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
index 2ef9f0b4..e3ed41141 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
@@ -15,6 +15,7 @@
 import org.chromium.base.ObserverList;
 import org.chromium.base.TraceEvent;
 import org.chromium.base.VisibleForTesting;
+import org.chromium.chrome.R;
 import org.chromium.chrome.browser.banners.AppBannerManager;
 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItemDelegate;
 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator;
@@ -30,10 +31,8 @@
 import org.chromium.content.browser.ContentView;
 import org.chromium.content.browser.ContentViewClient;
 import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content.browser.NavigationClient;
 import org.chromium.content.browser.WebContentsObserver;
 import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.content_public.browser.NavigationHistory;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.Clipboard;
 import org.chromium.ui.base.WindowAndroid;
@@ -71,7 +70,7 @@
  *  unless special care is taken to make sure {@link Tab#incrementIdCounterTo(int)} is called with
  *  the correct value across all affected {@link Activity}s.
  */
-public class Tab implements NavigationClient {
+public class Tab {
     public static final int INVALID_TAB_ID = -1;
 
     /** Used for automatically generating tab ids. */
@@ -408,23 +407,6 @@
         if (getWebContents() != null) getWebContents().getNavigationController().goForward();
     }
 
-    @Override
-    public NavigationHistory getDirectedNavigationHistory(boolean isForward, int itemLimit) {
-        if (getWebContents() != null) {
-            return getWebContents().getNavigationController()
-                    .getDirectedNavigationHistory(isForward, itemLimit);
-        } else {
-            return new NavigationHistory();
-        }
-    }
-
-    @Override
-    public void goToNavigationIndex(int index) {
-        if (getWebContents() != null) {
-            getWebContents().getNavigationController().goToNavigationIndex(index);
-        }
-    }
-
     /**
      * Loads the current navigation if there is a pending lazy load (after tab restore).
      */
@@ -806,6 +788,8 @@
     protected void initContentViewCore(long nativeWebContents) {
         ContentViewCore cvc = new ContentViewCore(mContext);
         ContentView cv = ContentView.newInstance(mContext, cvc);
+        cv.setContentDescription(mContext.getResources().getString(
+                R.string.accessibility_content_view));
         cvc.initialize(cv, cv, nativeWebContents, getWindowAndroid());
         setContentViewCore(cvc);
     }
@@ -1111,6 +1095,8 @@
             long newWebContents, boolean didStartLoad, boolean didFinishLoad) {
         ContentViewCore cvc = new ContentViewCore(mContext);
         ContentView cv = ContentView.newInstance(mContext, cvc);
+        cv.setContentDescription(mContext.getResources().getString(
+                R.string.accessibility_content_view));
         cvc.initialize(cv, cv, newWebContents, getWindowAndroid());
         swapContentViewCore(cvc, false, didStartLoad, didFinishLoad);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
index 9b1311a..bb84a44 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/WebsiteSettingsPopup.java
@@ -12,26 +12,70 @@
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
 import android.text.style.ForegroundColorSpan;
+import android.text.style.StrikethroughSpan;
 import android.text.style.StyleSpan;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
+import android.widget.Spinner;
 import android.widget.TextView;
 
 import org.chromium.base.CalledByNative;
 import org.chromium.base.CommandLine;
 import org.chromium.chrome.ChromeSwitches;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.toolbar.ToolbarModel;
+import org.chromium.chrome.browser.ui.toolbar.ToolbarModelSecurityLevel;
 import org.chromium.content.browser.WebContentsObserver;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.ui.base.Clipboard;
+import org.chromium.ui.base.DeviceFormFactor;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Java side of Android implementation of the website settings UI.
+ * TODO(sashab): Rename this, and all its resources, to PageInfo* and page_info_* instead of
+ *               WebsiteSettings* and website_settings_*. Do this on the C++ side as well.
  */
-public class WebsiteSettingsPopup {
+public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedListener {
+    /**
+     * An entry in the settings dropdown for a given permission. There are two options for each
+     * permission: Allow and Block.
+     */
+    private static final class PageInfoPermissionEntry {
+        public final String name;
+        public final int type;
+        public final int value;
+
+        PageInfoPermissionEntry(String name, int type, int value) {
+            this.name = name;
+            this.type = type;
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+
+    private static final int MAX_TABLET_DIALOG_WIDTH_DP = 400;
+
     private final Context mContext;
     private final WebContents mWebContents;
 
@@ -44,13 +88,26 @@
     // UI elements in the dialog.
     private final TextView mUrlTitle;
     private final TextView mUrlConnectionMessage;
+    private final LinearLayout mPermissionsList;
+    private final Button mCopyUrlButton;
+    private final Button mSiteSettingsButton;
+    private final Button mDoneButton;
 
     // The dialog the container is placed in.
     private final Dialog mDialog;
 
+    // The full URL from the URL bar, which is copied to the user's clipboard when they select 'Copy
+    // URL'.
+    private String mFullUrl;
+    private URI mUrl;
+
     /**
-     * Creates the WebsiteSettingsPopup, but does not display it. Also
-     * initializes the corresponding C++ object and saves a pointer to it.
+     * Creates the WebsiteSettingsPopup, but does not display it. Also initializes the corresponding
+     * C++ object and saves a pointer to it.
+     *
+     * @param context Context which is used for launching a dialog.
+     * @param webContents The WebContents for which to show Website information. This information is
+     *                    retrieved for the visible entry.
      */
     private WebsiteSettingsPopup(Context context, WebContents webContents) {
         mContext = context;
@@ -63,25 +120,42 @@
         mUrlTitle = (TextView) mContainer
                 .findViewById(R.id.website_settings_url);
         mUrlConnectionMessage = (TextView) mContainer
-                .findViewById(R.id.website_settings_permission_message);
+                .findViewById(R.id.website_settings_connection_message);
+        mPermissionsList = (LinearLayout) mContainer
+                .findViewById(R.id.website_settings_permissions_list);
+
+        mCopyUrlButton = (Button) mContainer.findViewById(R.id.website_settings_copy_url_button);
+        mCopyUrlButton.setOnClickListener(this);
+
+        mSiteSettingsButton = (Button) mContainer
+                .findViewById(R.id.website_settings_site_settings_button);
+        mSiteSettingsButton.setOnClickListener(this);
+        // Hide the Site Settings button until there's a link to take it to.
+        // TODO(sashab,finnur): Make this button visible once Site Settings is working.
+        mSiteSettingsButton.setVisibility(View.GONE);
+
+        mDoneButton = (Button) mContainer.findViewById(R.id.website_settings_done_button);
+        mDoneButton.setOnClickListener(this);
 
         // Create the dialog.
         mDialog = new Dialog(mContext);
         mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
         mDialog.setCanceledOnTouchOutside(true);
 
-        // Place the dialog at the top of the screen, and remove its border.
-        Window window = mDialog.getWindow();
-        window.setGravity(Gravity.TOP);
-        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+        // On smaller screens, place the dialog at the top of the screen, and remove its border.
+        if (!DeviceFormFactor.isTablet(mContext)) {
+            Window window = mDialog.getWindow();
+            window.setGravity(Gravity.TOP);
+            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+        }
 
         // This needs to come after other member initialization.
         mNativeWebsiteSettingsPopup = nativeInit(this, webContents);
         final WebContentsObserver webContentsObserver = new WebContentsObserver(mWebContents) {
             @Override
             public void navigationEntryCommitted() {
-                // If a navigation is committed (e.g. from in-page redirect), the data we're
-                // showing is stale so dismiss the dialog.
+                // If a navigation is committed (e.g. from in-page redirect), the data we're showing
+                // is stale so dismiss the dialog.
                 mDialog.dismiss();
             }
         };
@@ -96,110 +170,249 @@
     }
 
     /**
-     * Sets the URL in the title to: (scheme)://(domain)(path). Also colors
-     * different parts of the URL depending on connectionType.
-     * connectionType should be a valid PageInfoConnectionType.
+     * Finds the Image resource of the icon to use for the given permission.
+     *
+     * @param permission A valid ContentSettingsType that can be displayed in the PageInfo dialog to
+     *                   retrieve the image for.
+     * @return The resource ID of the icon to use for that permission.
      */
-    @CalledByNative
-    private void setURLTitle(String scheme, String domain, String path, int connectionType) {
-        boolean makeDomainBold = false;
-        int schemeColorId = R.color.website_settings_popup_url_scheme_broken;
-        switch (connectionType) {
-            case PageInfoConnectionType.CONNECTION_UNKNOWN:
-                schemeColorId = R.color.website_settings_popup_url_scheme_http;
-                makeDomainBold = true;
-                break;
-            case PageInfoConnectionType.CONNECTION_ENCRYPTED:
-                schemeColorId = R.color.website_settings_popup_url_scheme_https;
-                break;
-            case PageInfoConnectionType.CONNECTION_MIXED_CONTENT:
-                schemeColorId = R.color.website_settings_popup_url_scheme_mixed;
-                makeDomainBold = true;
-                break;
-            case PageInfoConnectionType.CONNECTION_UNENCRYPTED:
-                schemeColorId = R.color.website_settings_popup_url_scheme_http;
-                makeDomainBold = true;
-                break;
-            case PageInfoConnectionType.CONNECTION_ENCRYPTED_ERROR:
-                schemeColorId = R.color.website_settings_popup_url_scheme_broken;
-                makeDomainBold = true;
-                break;
-            case PageInfoConnectionType.CONNECTION_INTERNAL_PAGE:
-                schemeColorId = R.color.website_settings_popup_url_scheme_http;
-                break;
+    private int getImageResourceForPermission(int permission) {
+        switch (permission) {
+            case ContentSettingsType.CONTENT_SETTINGS_TYPE_IMAGES:
+                return R.drawable.permission_images;
+            case ContentSettingsType.CONTENT_SETTINGS_TYPE_JAVASCRIPT:
+                return R.drawable.permission_javascript;
+            case ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION:
+                return R.drawable.permission_location;
+            case ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM:
+                return R.drawable.permission_media;
+            case ContentSettingsType.CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
+                return R.drawable.permission_push_notification;
+            case ContentSettingsType.CONTENT_SETTINGS_TYPE_POPUPS:
+                return R.drawable.permission_popups;
             default:
-                assert false : "Unexpected connection type: " + connectionType;
+                assert false : "Icon requested for invalid permission: " + permission;
+                return -1;
+        }
+    }
+
+    @CalledByNative
+    private void updatePageDetails(boolean isInternalPage) {
+        mFullUrl = mWebContents.getVisibleUrl();
+        int securityLevel = ToolbarModel.getSecurityLevelForWebContents(mWebContents);
+
+        try {
+            mUrl = new URI(mFullUrl);
+        } catch (URISyntaxException e) {
+            assert false : "Invalid URL specified: " + mFullUrl;
         }
 
-        SpannableStringBuilder sb = new SpannableStringBuilder(scheme + "://" + domain + path);
+        int schemeColorId = -1;
+        if (securityLevel == ToolbarModelSecurityLevel.SECURITY_ERROR) {
+            schemeColorId = R.color.website_settings_popup_url_scheme_broken;
 
-        ForegroundColorSpan schemeColorSpan = new ForegroundColorSpan(
-                mContext.getResources().getColor(schemeColorId));
-        sb.setSpan(schemeColorSpan, 0, scheme.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+            String leadingText = mContext.getResources().getString(
+                    R.string.page_info_connection_broken_leading_text);
+            String followingText = mContext.getResources().getString(
+                    R.string.page_info_connection_broken_following_text,
+                    UrlUtilities.getOriginForDisplay(mUrl, false));
+            SpannableStringBuilder sb = new SpannableStringBuilder(leadingText + " "
+                    + followingText);
+            final ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources()
+                    .getColor(R.color.website_settings_popup_url_scheme_broken));
+            final StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
+            sb.setSpan(redSpan, 0, leadingText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+            sb.setSpan(boldSpan, 0, leadingText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+            mUrlConnectionMessage.setText(sb);
+        } else {
+            int connectionMessageId = 0;
+            if (isInternalPage) {
+                schemeColorId = R.color.website_settings_popup_url_scheme_http;
+                connectionMessageId = R.string.page_info_connection_internal_page;
+            } else {
+                switch (securityLevel) {
+                    case ToolbarModelSecurityLevel.NONE:
+                        schemeColorId = R.color.website_settings_popup_url_scheme_http;
+                        connectionMessageId = R.string.page_info_connection_http;
+                        break;
+                    case ToolbarModelSecurityLevel.SECURE:
+                    case ToolbarModelSecurityLevel.EV_SECURE:
+                        schemeColorId = R.color.website_settings_popup_url_scheme_https;
+                        connectionMessageId = R.string.page_info_connection_https;
+                        break;
+                    case ToolbarModelSecurityLevel.SECURITY_WARNING:
+                    case ToolbarModelSecurityLevel.SECURITY_POLICY_WARNING:
+                        schemeColorId = R.color.website_settings_popup_url_scheme_mixed;
+                        connectionMessageId = R.string.page_info_connection_mixed;
+                        break;
+                    default:
+                        assert false : "Invalid security level specified: " + securityLevel;
+                        schemeColorId = R.color.website_settings_popup_url_scheme_http;
+                        connectionMessageId = R.string.page_info_connection_http;
+                }
+            }
+            mUrlConnectionMessage.setText(mContext.getResources().getString(connectionMessageId));
+        }
 
-        int domainStartIndex = scheme.length() + 3;
-        ForegroundColorSpan domainColorSpan = new ForegroundColorSpan(
+        // Color the URI-parsed version of the URL.
+        SpannableStringBuilder sb = new SpannableStringBuilder(mUrl.toString());
+        final ForegroundColorSpan schemeColorSpan = new ForegroundColorSpan(mContext.getResources()
+                .getColor(schemeColorId));
+        sb.setSpan(schemeColorSpan, 0, mUrl.getScheme().length(),
+                Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+        if (securityLevel == ToolbarModelSecurityLevel.SECURITY_ERROR) {
+            sb.setSpan(new StrikethroughSpan(), 0, mUrl.getScheme().length(),
+                    Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+        }
+
+        // The domain is everything after the scheme until the end of the
+        // origin.
+        final ForegroundColorSpan domainColorSpan = new ForegroundColorSpan(
                 mContext.getResources().getColor(R.color.website_settings_popup_url_domain));
-        sb.setSpan(domainColorSpan, domainStartIndex, domainStartIndex + domain.length(),
-                Spannable.SPAN_INCLUSIVE_INCLUSIVE);
-
-        if (makeDomainBold) {
-            StyleSpan boldStyleSpan = new StyleSpan(android.graphics.Typeface.BOLD);
-            sb.setSpan(boldStyleSpan, domainStartIndex, domainStartIndex + domain.length(),
-                    Spannable.SPAN_INCLUSIVE_INCLUSIVE);
-        }
-
+        sb.setSpan(domainColorSpan, mUrl.getScheme().length(),
+                UrlUtilities.getOriginForDisplay(mUrl, true).length(),
+                Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
         mUrlTitle.setText(sb);
     }
 
     /**
-     * Sets the connection message displayed at the top of the dialog to
-     * connectionMessage (e.g. "Could not securely connect to this site").
+     * Adds a new row for the given permission.
+     *
+     * @param name The title of the permission to display to the user.
+     * @param type The ContentSettingsType of the permission.
+     * @param currentSetting The ContentSetting of the currently selected setting.
      */
     @CalledByNative
-    private void setConnectionMessage(String connectionMessage) {
-        mUrlConnectionMessage.setText(connectionMessage);
+    private void addPermissionSection(String name, int type, int currentSetting) {
+        LinearLayout permissionRow = (LinearLayout) LayoutInflater.from(mContext).inflate(
+                R.layout.website_settings_permission_row, null);
+
+        ImageView permission_icon = (ImageView) permissionRow.findViewById(
+                R.id.website_settings_permission_icon);
+        permission_icon.setImageResource(getImageResourceForPermission(type));
+
+        TextView permission_name = (TextView) permissionRow.findViewById(
+                R.id.website_settings_permission_name);
+        permission_name.setText(name);
+
+        Spinner permission_spinner = (Spinner) permissionRow.findViewById(
+                R.id.website_settings_permission_spinner);
+
+        // Work out the index of the currently selected setting.
+        int selectedSettingIndex = -1;
+        switch (currentSetting) {
+            case ContentSetting.ALLOW:
+                selectedSettingIndex = 0;
+                break;
+            case ContentSetting.BLOCK:
+                selectedSettingIndex = 1;
+                break;
+            default:
+                assert false : "Invalid setting " + currentSetting + " for permission " + type;
+        }
+
+        List<PageInfoPermissionEntry> settingsChoices = Arrays.asList(
+                new PageInfoPermissionEntry(mContext.getResources().getString(
+                        R.string.page_info_permission_allow), type, ContentSetting.ALLOW),
+                new PageInfoPermissionEntry(mContext.getResources().getString(
+                        R.string.page_info_permission_block), type, ContentSetting.BLOCK));
+        ArrayAdapter<PageInfoPermissionEntry> adapter = new ArrayAdapter<PageInfoPermissionEntry>(
+                mContext, R.drawable.website_settings_permission_spinner_item, settingsChoices);
+        adapter.setDropDownViewResource(
+                R.drawable.website_settings_permission_spinner_dropdown_item);
+        permission_spinner.setAdapter(adapter);
+        permission_spinner.setSelection(selectedSettingIndex, false);
+        permission_spinner.setOnItemSelectedListener(this);
+        mPermissionsList.addView(permissionRow);
     }
 
-    /** Displays the WebsiteSettingsPopup. */
+    /**
+     * Displays the WebsiteSettingsPopup.
+     */
     @CalledByNative
     private void showDialog() {
-        // Wrap the dialog in a ScrollView in case the content is too long.
-        ScrollView scrollView = new ScrollView(mContext);
-        scrollView.addView(mContainer);
-        mDialog.addContentView(scrollView, new LinearLayout.LayoutParams(
-                LinearLayout.LayoutParams.MATCH_PARENT,
-                LinearLayout.LayoutParams.MATCH_PARENT));
+        if (!DeviceFormFactor.isTablet(mContext)) {
+            // On smaller screens, make the dialog fill the width of the screen.
+            ScrollView scrollView = new ScrollView(mContext);
+            scrollView.addView(mContainer);
+            mDialog.addContentView(scrollView, new LinearLayout.LayoutParams(
+                    LinearLayout.LayoutParams.MATCH_PARENT,
+                    LinearLayout.LayoutParams.MATCH_PARENT));
 
-        // Make the dialog fill the width of the screen. This must be called
-        // after addContentView, or it won't fully fill to the edge.
-        Window window = mDialog.getWindow();
-        window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.WRAP_CONTENT);
+            // This must be called after addContentView, or it won't fully fill to the edge.
+            Window window = mDialog.getWindow();
+            window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT);
+        } else {
+            // On larger screens, make the dialog centered in the screen and have a maximum width.
+            ScrollView scrollView = new ScrollView(mContext) {
+                @Override
+                protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+                    final int maxDialogWidthInPx = (int) (MAX_TABLET_DIALOG_WIDTH_DP
+                            * mContext.getResources().getDisplayMetrics().density);
+                    if (MeasureSpec.getSize(widthMeasureSpec) > maxDialogWidthInPx) {
+                        widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxDialogWidthInPx,
+                                MeasureSpec.EXACTLY);
+                    }
+                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+                }
+            };
+
+            scrollView.addView(mContainer);
+            mDialog.addContentView(scrollView, new LinearLayout.LayoutParams(
+                    LinearLayout.LayoutParams.WRAP_CONTENT,
+                    LinearLayout.LayoutParams.MATCH_PARENT));
+        }
 
         mDialog.show();
     }
 
+    @Override
+    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+        PageInfoPermissionEntry entry = (PageInfoPermissionEntry) parent.getItemAtPosition(pos);
+        nativeOnPermissionSettingChanged(mNativeWebsiteSettingsPopup, entry.type, entry.value);
+    }
+
+    @Override
+    public void onNothingSelected(AdapterView<?> parent) {
+        // Do nothing intentionally.
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (view == mCopyUrlButton) {
+            new Clipboard(mContext).setText(mFullUrl, mFullUrl);
+            mDialog.dismiss();
+        } else if (view == mSiteSettingsButton) {
+            // TODO(sashab,finnur): Make this open the Website Settings dialog.
+            assert false : "No Website Settings here!";
+            mDialog.dismiss();
+        } else if (view == mDoneButton) {
+            mDialog.dismiss();
+        }
+    }
+
     /**
-     * Shows a WebsiteSettings dialog for the provided WebContents. The popup
-     * adds itself to the view hierarchy which owns the reference while it's
-     * visible.
+     * Shows a WebsiteSettings dialog for the provided WebContents. The popup adds itself to the
+     * view hierarchy which owns the reference while it's visible.
      *
      * @param context Context which is used for launching a dialog.
-     * @param webContents The WebContents for which to show Website information.
-     *                    This information is retrieved for the visible entry.
+     * @param webContents The WebContents for which to show Website information. This information is
+     *                    retrieved for the visible entry.
      */
     @SuppressWarnings("unused")
     public static void show(Context context, WebContents webContents) {
-        if (CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_NEW_WEBSITE_SETTINGS)) {
+        if (!CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_NEW_WEBSITE_SETTINGS)) {
             new WebsiteSettingsPopup(context, webContents);
         } else {
             WebsiteSettingsPopupLegacy.show(context, webContents);
         }
     }
 
-    private static native long nativeInit(WebsiteSettingsPopup popup,
-            WebContents webContents);
+    private static native long nativeInit(WebsiteSettingsPopup popup, WebContents webContents);
 
     private native void nativeDestroy(long nativeWebsiteSettingsPopupAndroid);
+
+    private native void nativeOnPermissionSettingChanged(long nativeWebsiteSettingsPopupAndroid,
+            int type, int setting);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java
index a63e2a51..7ef17791 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuButtonHelper.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.appmenu;
 
+import android.annotation.SuppressLint;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnTouchListener;
@@ -75,8 +76,8 @@
         return showAppMenu(false);
     }
 
+    @SuppressLint("ClickableViewAccessibility")
     @Override
-
     public boolean onTouch(View view, MotionEvent event) {
         boolean isTouchEventConsumed = false;
 
@@ -103,4 +104,4 @@
         }
         return isTouchEventConsumed;
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/autofill/OWNERS
new file mode 100644
index 0000000..98819a3
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/OWNERS
@@ -0,0 +1,2 @@
+aurimas@chromium.org
+aruslan@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index 25d0350..e17fbcb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -87,17 +87,18 @@
             }
             final TemplateUrlService templateUrlServiceInstance = TemplateUrlService.getInstance();
             final boolean isSearchByImageAvailable =
-                    UrlUtilities.isDownloadableScheme(params.getSrcUrl()) &&
-                            templateUrlServiceInstance.isLoaded() &&
-                            templateUrlServiceInstance.isSearchByImageAvailable() &&
-                            templateUrlServiceInstance.getDefaultSearchEngineTemplateUrl() != null;
+                    UrlUtilities.isDownloadableScheme(params.getSrcUrl())
+                            && templateUrlServiceInstance.isLoaded()
+                            && templateUrlServiceInstance.isSearchByImageAvailable()
+                            && templateUrlServiceInstance.getDefaultSearchEngineTemplateUrl()
+                                    != null;
 
             menu.findItem(R.id.contextmenu_search_by_image).setVisible(isSearchByImageAvailable);
             if (isSearchByImageAvailable) {
                 menu.findItem(R.id.contextmenu_search_by_image).setTitle(
                         context.getString(R.string.contextmenu_search_web_for_image,
-                                TemplateUrlService.getInstance().
-                                        getDefaultSearchEngineTemplateUrl().getShortName()));
+                                TemplateUrlService.getInstance()
+                                        .getDefaultSearchEngineTemplateUrl().getShortName()));
             }
 
             menu.findItem(R.id.contextmenu_copy_image).setVisible(
@@ -113,8 +114,8 @@
             mDelegate.onOpenInNewIncognitoTab(params.getLinkUrl());
         } else if (itemId == R.id.contextmenu_open_image) {
             mDelegate.onOpenImageUrl(params.getSrcUrl(), params.getReferrer());
-        } else if (itemId == R.id.contextmenu_open_image_in_new_tab ||
-                itemId == R.id.contextmenu_open_original_image_in_new_tab) {
+        } else if (itemId == R.id.contextmenu_open_image_in_new_tab
+                || itemId == R.id.contextmenu_open_original_image_in_new_tab) {
             mDelegate.onOpenImageInNewTab(params.getSrcUrl(), params.getReferrer());
         } else if (itemId == R.id.contextmenu_copy_link_address_text) {
             mDelegate.onSaveToClipboard(params.getUnfilteredLinkUrl(), true);
@@ -122,8 +123,8 @@
             mDelegate.onSaveToClipboard(MailTo.parse(params.getLinkUrl()).getTo(), false);
         } else if (itemId == R.id.contextmenu_copy_link_text) {
             mDelegate.onSaveToClipboard(params.getLinkText(), false);
-        } else if (itemId == R.id.contextmenu_save_image ||
-                itemId == R.id.contextmenu_save_video) {
+        } else if (itemId == R.id.contextmenu_save_image
+                || itemId == R.id.contextmenu_save_video) {
             if (mDelegate.startDownload(params.getSrcUrl(), false)) {
                 helper.startContextMenuDownload(false);
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/OWNERS
new file mode 100644
index 0000000..812e8d9
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/OWNERS
@@ -0,0 +1 @@
+aurimas@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/NetworkPredictionOptions.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/NetworkPredictionOptions.java
new file mode 100644
index 0000000..fc8b585a
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/NetworkPredictionOptions.java
@@ -0,0 +1,77 @@
+// 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.
+
+package org.chromium.chrome.browser.preferences;
+
+import org.chromium.chrome.R;
+
+import java.util.Locale;
+
+/**
+ * Bandwidth options available based on network.
+ */
+public enum NetworkPredictionOptions {
+    NETWORK_PREDICTION_ALWAYS,
+    NETWORK_PREDICTION_WIFI_ONLY,
+    NETWORK_PREDICTION_NEVER;
+
+    public static final NetworkPredictionOptions DEFAULT = NETWORK_PREDICTION_WIFI_ONLY;
+
+    /**
+     * @return The number of choices offered for the user.
+     */
+    public static int choiceCount() {
+        return values().length;
+    }
+
+    /**
+     * Fetch the display title for the preference.
+     * @return resource for the title.
+     */
+    public int getDisplayTitle() {
+        switch(this) {
+            case NETWORK_PREDICTION_ALWAYS:
+                return R.string.always_prefetch_bandwidth_entry;
+            case NETWORK_PREDICTION_WIFI_ONLY :
+                return R.string.wifi_prefetch_bandwidth_entry;
+            case NETWORK_PREDICTION_NEVER:
+                return R.string.never_prefetch_bandwidth_entry;
+            default:
+                assert false;
+                return 0;
+        }
+    }
+
+    /**
+     * Convert an integer to enum NetworkPredictionOptions.
+     * @return NetworkPredictionOptions instance.
+     */
+    public static NetworkPredictionOptions intToEnum(int index) {
+        return NetworkPredictionOptions.values()[index];
+    }
+
+    /**
+     * Convert an enum NetworkPredictionOptions to integer.
+     * @return Integer corresponding to NetworkPredictionOptions instance.
+     */
+    public int enumToInt() {
+        return ordinal();
+    }
+
+    /**
+     * Convert an string to enum NetworkPredictionOptions.
+     * @return NetworkPredictionOptions instance.
+     */
+    public static NetworkPredictionOptions stringToEnum(String name) {
+        return valueOf(name.toUpperCase(Locale.US));
+    }
+
+    /**
+     * Convert an enum NetworkPredictionOptions to String.
+     * @return String corresponding to NetworkPredictionOptions instance.
+     */
+    public String enumToString() {
+        return name().toLowerCase(Locale.US);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
new file mode 100644
index 0000000..0191010
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
@@ -0,0 +1,703 @@
+// 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.
+
+package org.chromium.chrome.browser.preferences;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.ThreadUtils;
+import org.chromium.chrome.browser.search_engines.TemplateUrlService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * PrefServiceBridge is a singleton which provides access to some native preferences. Ideally
+ * preferences should be grouped with their relevant functionality but this is a grab-bag for other
+ * preferences.
+ */
+public final class PrefServiceBridge {
+
+    // Does not need sync with native; used for the popup settings check
+    public static final String EXCEPTION_SETTING_ALLOW = "allow";
+    public static final String EXCEPTION_SETTING_BLOCK = "block";
+    public static final String EXCEPTION_SETTING_DEFAULT = "default";
+
+    // These values must match the native enum values in
+    // SupervisedUserURLFilter::FilteringBehavior
+    public static final int SUPERVISED_USER_FILTERING_ALLOW = 0;
+    public static final int SUPERVISED_USER_FILTERING_WARN = 1;
+    public static final int SUPERVISED_USER_FILTERING_BLOCK = 2;
+
+    private static String sProfilePathValue;
+
+    // Object to notify when "clear browsing data" completes.
+    private OnClearBrowsingDataListener mClearBrowsingDataListener;
+    private static final String LOG_TAG = "PrefServiceBridge";
+
+    // Constants related to the Contextual Search preference.
+    private static final String CONTEXTUAL_SEARCH_DISABLED = "false";
+    private static final String CONTEXTUAL_SEARCH_ENABLED = "true";
+
+    /**
+     * Structure that holds all the version information about the current Chrome browser.
+     */
+    public static class AboutVersionStrings {
+        private final String mApplicationVersion;
+        private final String mWebkitVersion;
+        private final String mJavascriptVersion;
+        private final String mOSVersion;
+
+        private AboutVersionStrings(String applicationVersion, String webkitVersion,
+                String javascriptVersion, String osVersion) {
+            mApplicationVersion = applicationVersion;
+            mWebkitVersion = webkitVersion;
+            mJavascriptVersion = javascriptVersion;
+            mOSVersion = osVersion;
+        }
+
+        public String getApplicationVersion() {
+            return mApplicationVersion;
+        }
+
+        public String getWebkitVersion() {
+            return mWebkitVersion;
+        }
+
+        public String getJavascriptVersion() {
+            return mJavascriptVersion;
+        }
+
+        public String getOSVersion() {
+            return mOSVersion;
+        }
+    }
+
+    /**
+     * Website popup exception entry.
+     */
+    public static class PopupExceptionInfo {
+        private final String mPattern;
+        private final String mSetting;
+        private final String mSource;
+
+        private PopupExceptionInfo(String pattern, String setting, String source) {
+            mPattern = pattern;
+            mSetting = setting;
+            mSource = source;
+        }
+
+        public String getPattern() {
+            return mPattern;
+        }
+
+        public String getSetting() {
+            return mSetting;
+        }
+
+        public String getSource() {
+            return mSource;
+        }
+    }
+
+    @CalledByNative
+    private static AboutVersionStrings createAboutVersionStrings(
+            String applicationVersion, String webkitVersion, String javascriptVersion,
+            String osVersion) {
+        return new AboutVersionStrings(
+                applicationVersion, webkitVersion, javascriptVersion, osVersion);
+    }
+
+    private PrefServiceBridge() {
+        TemplateUrlService.getInstance().load();
+    }
+
+    private static PrefServiceBridge sInstance;
+
+    /**
+     * @return The singleton preferences object.
+     */
+    public static PrefServiceBridge getInstance() {
+        ThreadUtils.assertOnUiThread();
+        if (sInstance == null) sInstance = new PrefServiceBridge();
+        return sInstance;
+    }
+
+    /**
+     * @return Whether the preferences have been initialized.
+     */
+    public static boolean isInitialized() {
+        return sInstance != null;
+    }
+
+    /**
+     * @return the About Chrome value for profile path.
+     */
+    public String getProfilePathValue() {
+        return sProfilePathValue;
+    }
+
+    /**
+     * Set the About Chrome value for profile path.
+     */
+    @CalledByNative
+    public static void setProfilePathValue(String pathValue) {
+        sProfilePathValue = pathValue;
+    }
+
+    public boolean isAcceptCookiesEnabled() {
+        return nativeGetAcceptCookiesEnabled();
+    }
+
+    /**
+     * @return whether cookies acceptance is configured by policy
+     */
+    public boolean isAcceptCookiesManaged() {
+        return nativeGetAcceptCookiesManaged();
+    }
+
+    public boolean isRememberPasswordsEnabled() {
+        return nativeGetRememberPasswordsEnabled();
+    }
+
+    /**
+     * @return whether password storage is configured by policy
+     */
+    public boolean isRememberPasswordsManaged() {
+        return nativeGetRememberPasswordsManaged();
+    }
+
+    /**
+     * @return whether geolocation informatoin can be shared with content
+     */
+    public boolean isAllowLocationEnabled() {
+        return nativeGetAllowLocationEnabled();
+    }
+
+    /**
+     * @return whether the location preference is configured by policy
+     */
+    public boolean isAllowLocationManaged() {
+        return nativeGetAllowLocationManaged();
+    }
+
+    /**
+     * @return whether Do Not Track is enabled
+     */
+    public boolean isDoNotTrackEnabled() {
+        return nativeGetDoNotTrackEnabled();
+    }
+
+    public boolean getPasswordEchoEnabled() {
+        return nativeGetPasswordEchoEnabled();
+    }
+
+    /**
+     * @return Whether EULA has been accepted by the user.
+     */
+    public boolean isFirstRunEulaAccepted() {
+        return nativeGetFirstRunEulaAccepted();
+    }
+
+    /**
+     * @return true if JavaScript is enabled. It may return the temporary value set by
+     * {@link #setJavaScriptEnabled}. The default is true.
+     */
+    public boolean javaScriptEnabled() {
+        return nativeGetJavaScriptEnabled();
+    }
+
+    /**
+     * @return whether Javascript is managed by policy
+     */
+    public boolean javaScriptManaged() {
+        return nativeGetJavaScriptManaged();
+    }
+
+    /**
+     * Sets the preference that controls protected media identifier.
+     */
+    public void setProtectedMediaIdentifierEnabled(boolean enabled) {
+        nativeSetProtectedMediaIdentifierEnabled(enabled);
+    }
+
+    /**
+     * Sets the preference that controls translate
+     */
+    public void setTranslateEnabled(boolean enabled) {
+        nativeSetTranslateEnabled(enabled);
+    }
+
+    /**
+     * Sets the preference that signals when the user has accepted the EULA.
+     */
+    public void setEulaAccepted() {
+        nativeSetEulaAccepted();
+    }
+
+    /**
+     * Resets translate defaults if needed
+     */
+    public void resetTranslateDefaults() {
+        nativeResetTranslateDefaults();
+    }
+
+    /**
+     * Enable or disable JavaScript.
+     */
+    public void setJavaScriptEnabled(boolean enabled) {
+        nativeSetJavaScriptEnabled(enabled);
+    }
+
+    /**
+     * @return the last account username associated with sync.
+     */
+    public String getSyncLastAccountName() {
+        return nativeGetSyncLastAccountName();
+    }
+
+    /**
+     * Enable or disable x-auto-login
+     */
+    public void setAutologinEnabled(boolean autologinEnabled) {
+        nativeSetAutologinEnabled(autologinEnabled);
+    }
+
+    /**
+     * @return true if x-auto-login is enabled, false otherwise.
+     */
+    public boolean isAutologinEnabled() {
+        return nativeGetAutologinEnabled();
+    }
+
+    /**
+     * @return whether usage and crash report is managed.
+     */
+    public boolean isCrashReportManaged() {
+        return nativeGetCrashReportManaged();
+    }
+
+    /**
+     * Enable or disable crashes_ui.
+     */
+    public void setCrashReporting(boolean reporting) {
+        nativeSetCrashReporting(reporting);
+    }
+
+    /**
+     * @return whether Search Suggest is enabled.
+     */
+    public boolean isSearchSuggestEnabled() {
+        return nativeGetSearchSuggestEnabled();
+    }
+
+    /**
+     * Sets whether search suggest should be enabled.
+     */
+    public void setSearchSuggestEnabled(boolean enabled) {
+        nativeSetSearchSuggestEnabled(enabled);
+    }
+
+    /**
+     * @return whether Search Suggest is configured by policy.
+     */
+    public boolean isSearchSuggestManaged() {
+        return nativeGetSearchSuggestManaged();
+    }
+
+    /**
+     * @return the Contextual Search preference.
+     */
+    public String getContextualSearchPreference() {
+        return nativeGetContextualSearchPreference();
+    }
+
+    /**
+     * Sets the Contextual Search preference.
+     * @param prefValue one of "", CONTEXTUAL_SEARCH_ENABLED or CONTEXTUAL_SEARCH_DISABLED.
+     */
+    public void setContextualSearchPreference(String prefValue) {
+        nativeSetContextualSearchPreference(prefValue);
+    }
+
+    /**
+     * @return whether the Contextual Search feature was disabled by the user explicitly.
+     */
+    public boolean isContextualSearchDisabled() {
+        return getContextualSearchPreference().equals(CONTEXTUAL_SEARCH_DISABLED);
+    }
+
+    /**
+     * @return whether the Contextual Search feature is uninitialized (preference unset by the
+     *         user).
+     */
+    public boolean isContextualSearchUninitialized() {
+        return getContextualSearchPreference().isEmpty();
+    }
+
+    /**
+     * @param whether Contextual Search should be enabled.
+     */
+    public void setContextualSearchState(boolean enabled) {
+        setContextualSearchPreference(enabled
+                ? CONTEXTUAL_SEARCH_ENABLED : CONTEXTUAL_SEARCH_DISABLED);
+    }
+
+    /**
+     * @return whether there is a user set value for kNetworkPredictionEnabled.  This should only be
+     * used for preference migration.
+     */
+    public boolean networkPredictionEnabledHasUserSetting() {
+        return nativeNetworkPredictionEnabledHasUserSetting();
+    }
+
+    /**
+     * @return whether there is a user set value for kNetworkPredictionOptions.  This should only be
+     * used for preference migration.
+     */
+    public boolean networkPredictionOptionsHasUserSetting() {
+        return nativeNetworkPredictionOptionsHasUserSetting();
+    }
+
+    /**
+     * @return the user set value for kNetworkPredictionEnabled. This should only be used for
+     * preference migration.
+     */
+    public boolean getNetworkPredictionEnabledUserPrefValue() {
+        return nativeGetNetworkPredictionEnabledUserPrefValue();
+    }
+
+    /**
+     * @return Network predictions preference.
+     */
+    public NetworkPredictionOptions getNetworkPredictionOptions() {
+        return NetworkPredictionOptions.intToEnum(nativeGetNetworkPredictionOptions());
+    }
+
+    /**
+     * Sets network predictions preference.
+     */
+    public void setNetworkPredictionOptions(NetworkPredictionOptions option) {
+        nativeSetNetworkPredictionOptions(option.enumToInt());
+    }
+
+    /**
+     * @return whether Network Predictions is configured by policy.
+     */
+    public boolean isNetworkPredictionManaged() {
+        return nativeGetNetworkPredictionManaged();
+    }
+
+    /**
+     * Checks whether network predictions are allowed given preferences and current network
+     * connection type.
+     * @return Whether network predictions are allowed.
+     */
+    public boolean canPredictNetworkActions() {
+        return nativeCanPredictNetworkActions();
+    }
+
+    /**
+     * @return whether the web service to resolve navigation error is enabled.
+     */
+    public boolean isResolveNavigationErrorEnabled() {
+        return nativeGetResolveNavigationErrorEnabled();
+    }
+
+    /**
+     * @return whether the web service to resolve navigation error is configured by policy.
+     */
+    public boolean isResolveNavigationErrorManaged() {
+        return nativeGetResolveNavigationErrorManaged();
+    }
+
+    /**
+     * @return whether or not the protected media identifier is enabled.
+     */
+    public boolean isProtectedMediaIdentifierEnabled() {
+        return nativeGetProtectedMediaIdentifierEnabled();
+    }
+
+    /**
+     * @return true if translate is enabled, false otherwise.
+     */
+    public boolean isTranslateEnabled() {
+        return nativeGetTranslateEnabled();
+    }
+
+    /**
+     * @return whether translate is configured by policy
+     */
+    public boolean isTranslateManaged() {
+        return nativeGetTranslateManaged();
+    }
+
+    /**
+     * Sets whether the web service to resolve navigation error should be enabled.
+     */
+    public void setResolveNavigationErrorEnabled(boolean enabled) {
+        nativeSetResolveNavigationErrorEnabled(enabled);
+    }
+
+    /**
+     * Interface for a class that is listening to clear browser data events.
+     */
+    public interface OnClearBrowsingDataListener {
+        public abstract void onBrowsingDataCleared();
+    }
+
+    /**
+     * Clear the specified types of browsing data asynchronously.
+     * |listener| is an object to be notified when clearing completes.
+     * It can be null, but many operations (e.g. navigation) are
+     * ill-advised while browsing data is being cleared.
+     */
+    public void clearBrowsingData(OnClearBrowsingDataListener listener,
+            boolean history, boolean cache, boolean cookiesAndSiteData,
+            boolean passwords, boolean formData) {
+        assert mClearBrowsingDataListener == null;
+        mClearBrowsingDataListener = listener;
+        nativeClearBrowsingData(history, cache, cookiesAndSiteData, passwords, formData);
+    }
+
+    @CalledByNative
+    private void browsingDataCleared() {
+        if (mClearBrowsingDataListener != null) {
+            mClearBrowsingDataListener.onBrowsingDataCleared();
+            mClearBrowsingDataListener = null;
+        }
+    }
+
+    public void setAllowCookiesEnabled(boolean allow) {
+        nativeSetAllowCookiesEnabled(allow);
+    }
+
+    public void setDoNotTrackEnabled(boolean enabled) {
+        nativeSetDoNotTrackEnabled(enabled);
+    }
+
+    public void setRememberPasswordsEnabled(boolean allow) {
+        nativeSetRememberPasswordsEnabled(allow);
+    }
+
+    public void setAllowLocationEnabled(boolean allow) {
+        nativeSetAllowLocationEnabled(allow);
+    }
+
+    public void setPasswordEchoEnabled(boolean enabled) {
+        nativeSetPasswordEchoEnabled(enabled);
+    }
+
+    /**
+     * @return The setting if popups are enabled
+     */
+    public boolean popupsEnabled() {
+        return nativeGetAllowPopupsEnabled();
+    }
+
+    /**
+     * @return Whether the setting to allow popups is configured by policy
+     */
+    public boolean isPopupsManaged() {
+        return nativeGetAllowPopupsManaged();
+    }
+
+    /**
+     * Sets the preferences on whether to enable/disable popups
+     *
+     * @param allow attribute to enable/disable popups
+     */
+    public void setAllowPopupsEnabled(boolean allow) {
+        nativeSetAllowPopupsEnabled(allow);
+    }
+
+    /**
+     * @return true if incognito mode is enabled.
+     */
+    public boolean isIncognitoModeEnabled() {
+        return nativeGetIncognitoModeEnabled();
+    }
+
+    /**
+     * @return true if incognito mode is managed by policy.
+     */
+    public boolean isIncognitoModeManaged() {
+        return nativeGetIncognitoModeManaged();
+    }
+
+    /**
+     * @return Whether printing is enabled.
+     */
+    public boolean isPrintingEnabled() {
+        return nativeGetPrintingEnabled();
+    }
+
+    /**
+     * Adds/Edit a popup exception
+     *
+     * @param pattern attribute for the popup exception pattern
+     * @param allow attribute to specify whether to allow or block pattern
+     */
+    public void setPopupException(String pattern, boolean allow) {
+        nativeSetPopupException(pattern, allow);
+    }
+
+    /**
+     * Removes a popup exception
+     *
+     * @param pattern attribute for the popup exception pattern
+     */
+    public void removePopupException(String pattern) {
+        nativeRemovePopupException(pattern);
+    }
+
+    /**
+     * get all the currently saved popup exceptions
+     *
+     * @return List of all the exceptions and their settings
+     */
+    public List<PopupExceptionInfo> getPopupExceptions() {
+        List<PopupExceptionInfo> list = new ArrayList<PopupExceptionInfo>();
+        nativeGetPopupExceptions(list);
+        return list;
+    }
+
+    @CalledByNative
+    private static void insertPopupExceptionToList(
+            ArrayList<PopupExceptionInfo> list, String pattern, String setting, String source) {
+        PopupExceptionInfo exception = new PopupExceptionInfo(pattern, setting, source);
+        list.add(exception);
+    }
+
+    /**
+     * Get all the version strings from native.
+     * @return AboutVersionStrings about version strings.
+     */
+    public AboutVersionStrings getAboutVersionStrings() {
+        return nativeGetAboutVersionStrings();
+    }
+
+    /**
+     * Set profile path value needed for about chrome.
+     */
+    public void setPathValuesForAboutChrome() {
+        if (sProfilePathValue == null) {
+            nativeSetPathValuesForAboutChrome();
+        }
+    }
+
+    /**
+     * Reset accept-languages to its default value.
+     *
+     * @param defaultLocale A fall-back value such as en_US, de_DE, zh_CN, etc.
+     */
+    public void resetAcceptLanguages(String defaultLocale) {
+        nativeResetAcceptLanguages(defaultLocale);
+    }
+
+    /**
+     * @return whether ForceSafeSearch is set
+     */
+    public boolean isForceSafeSearch() {
+        return nativeGetForceSafeSearch();
+    }
+
+    /**
+     * @return the default supervised user filtering behavior
+     */
+    public int getDefaultSupervisedUserFilteringBehavior() {
+        return nativeGetDefaultSupervisedUserFilteringBehavior();
+    }
+
+    public String getSupervisedUserCustodianName() {
+        return nativeGetSupervisedUserCustodianName();
+    }
+
+    public String getSupervisedUserCustodianEmail() {
+        return nativeGetSupervisedUserCustodianEmail();
+    }
+
+    public String getSupervisedUserCustodianProfileImageURL() {
+        return nativeGetSupervisedUserCustodianProfileImageURL();
+    }
+
+    public String getSupervisedUserSecondCustodianName() {
+        return nativeGetSupervisedUserSecondCustodianName();
+    }
+
+    public String getSupervisedUserSecondCustodianEmail() {
+        return nativeGetSupervisedUserSecondCustodianEmail();
+    }
+
+    public String getSupervisedUserSecondCustodianProfileImageURL() {
+        return nativeGetSupervisedUserSecondCustodianProfileImageURL();
+    }
+
+    private native boolean nativeGetAcceptCookiesEnabled();
+    private native boolean nativeGetAcceptCookiesManaged();
+    private native boolean nativeGetRememberPasswordsEnabled();
+    private native boolean nativeGetRememberPasswordsManaged();
+    private native boolean nativeGetAllowLocationManaged();
+    private native boolean nativeGetDoNotTrackEnabled();
+    private native boolean nativeGetPasswordEchoEnabled();
+    private native boolean nativeGetFirstRunEulaAccepted();
+    private native boolean nativeGetJavaScriptManaged();
+    private native boolean nativeGetTranslateEnabled();
+    private native boolean nativeGetTranslateManaged();
+    private native boolean nativeGetResolveNavigationErrorEnabled();
+    private native boolean nativeGetResolveNavigationErrorManaged();
+    private native boolean nativeGetProtectedMediaIdentifierEnabled();
+    private native boolean nativeGetCrashReportManaged();
+    private native boolean nativeGetIncognitoModeEnabled();
+    private native boolean nativeGetIncognitoModeManaged();
+    private native boolean nativeGetPrintingEnabled();
+    private native boolean nativeGetForceSafeSearch();
+    private native void nativeSetTranslateEnabled(boolean enabled);
+    private native void nativeResetTranslateDefaults();
+    private native boolean nativeGetJavaScriptEnabled();
+    private native void nativeSetJavaScriptEnabled(boolean enabled);
+    private native void nativeClearBrowsingData(boolean history, boolean cache,
+            boolean cookiesAndSiteData, boolean passwords, boolean formData);
+    private native boolean nativeGetAllowCookiesEnabled();
+    private native void nativeSetAllowCookiesEnabled(boolean allow);
+    private native void nativeSetDoNotTrackEnabled(boolean enabled);
+    private native void nativeSetRememberPasswordsEnabled(boolean allow);
+    private native void nativeSetProtectedMediaIdentifierEnabled(boolean enabled);
+    private native boolean nativeGetAllowLocationEnabled();
+    private native void nativeSetAllowLocationEnabled(boolean allow);
+    private native void nativeSetPasswordEchoEnabled(boolean enabled);
+    private native boolean nativeGetAllowPopupsEnabled();
+    private native boolean nativeGetAllowPopupsManaged();
+    private native void nativeSetAllowPopupsEnabled(boolean allow);
+    private native void nativeSetPopupException(String pattern, boolean allow);
+    private native void nativeRemovePopupException(String pattern);
+    private native void nativeGetPopupExceptions(Object list);
+    private native boolean nativeGetAutologinEnabled();
+    private native void nativeSetAutologinEnabled(boolean autologinEnabled);
+    private native void nativeSetCrashReporting(boolean reporting);
+    private native boolean nativeCanPredictNetworkActions();
+    private native AboutVersionStrings nativeGetAboutVersionStrings();
+    private native void nativeSetPathValuesForAboutChrome();
+    private native void nativeSetContextualSearchPreference(String preference);
+    private native String nativeGetContextualSearchPreference();
+    private native boolean nativeGetSearchSuggestEnabled();
+    private native void nativeSetSearchSuggestEnabled(boolean enabled);
+    private native boolean nativeGetSearchSuggestManaged();
+    private native boolean nativeGetNetworkPredictionManaged();
+    private native boolean nativeNetworkPredictionEnabledHasUserSetting();
+    private native boolean nativeNetworkPredictionOptionsHasUserSetting();
+    private native boolean nativeGetNetworkPredictionEnabledUserPrefValue();
+    private native int nativeGetNetworkPredictionOptions();
+    private native void nativeSetNetworkPredictionOptions(int option);
+    private native void nativeSetResolveNavigationErrorEnabled(boolean enabled);
+    private native void nativeSetEulaAccepted();
+    private native void nativeResetAcceptLanguages(String defaultLocale);
+    private native String nativeGetSyncLastAccountName();
+    private native String nativeGetSupervisedUserCustodianName();
+    private native String nativeGetSupervisedUserCustodianEmail();
+    private native String nativeGetSupervisedUserCustodianProfileImageURL();
+    private native int nativeGetDefaultSupervisedUserFilteringBehavior();
+    private native String nativeGetSupervisedUserSecondCustodianName();
+    private native String nativeGetSupervisedUserSecondCustodianEmail();
+    private native String nativeGetSupervisedUserSecondCustodianProfileImageURL();
+}
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 946b49b..27e2d12 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
@@ -193,8 +193,8 @@
             if (semaphore.tryAcquire(timeout, unit)) {
                 return result.get();
             } else {
-                Log.d(TAG, "Failed to retrieve auth token within timeout (" +
-                        timeout + " + " + unit.name() + ")");
+                Log.d(TAG, "Failed to retrieve auth token within timeout ("
+                        + timeout + " + " + unit.name() + ")");
                 return null;
             }
         } catch (InterruptedException e) {
@@ -295,8 +295,8 @@
     @CalledByNative
     private static void saveStoredAccounts(Context context, String[] accounts) {
         Set<String> set = new HashSet<String>(Arrays.asList(accounts));
-        PreferenceManager.getDefaultSharedPreferences(context).edit().
-                putStringSet(STORED_ACCOUNTS_KEY, set).apply();
+        PreferenceManager.getDefaultSharedPreferences(context).edit()
+                .putStringSet(STORED_ACCOUNTS_KEY, set).apply();
     }
 
     private static native Object nativeGetForProfile(Profile profile);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
index a51629b..4f8e37f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
@@ -58,6 +58,10 @@
     }
 
     @Override
+    public void closeAllTabs(boolean allowDelegation) {
+    }
+
+    @Override
     public int getCount() {
         // We must return 0 to be consistent with getTab(i)
         return 0;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
index 87945ef..565cfc04 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
@@ -84,6 +84,14 @@
     public void closeAllTabs();
 
     /**
+     * Close all tabs on this model. If allowDelegation is true, the model has the option
+     * of not closing all tabs and delegating the closure to another class.
+     * @param allowDelegation true iff the model may delegate the close all request.
+     *                        false iff the model must close all tabs.
+     */
+    public void closeAllTabs(boolean allowDelegation);
+
+    /**
      * @return Whether or not this model supports pending closures.
      */
     public boolean supportsPendingClosures();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelBase.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelBase.java
index b94acad..fb9595618a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelBase.java
@@ -48,13 +48,10 @@
      */
     private int mIndex = INVALID_TAB_INDEX;
 
-    /** Native TabModelBase pointer which will be set by nativeInit(). */
-    private long mNativeTabModelImpl = 0;
-
     public TabModelBase(boolean incognito, TabModelOrderController orderController,
             TabModelDelegate modelDelegate) {
         super(incognito);
-        mNativeTabModelImpl = nativeInit(incognito);
+        initializeNative();
         mOrderController = orderController;
         mModelDelegate = modelDelegate;
         mObservers = new ObserverList<TabModelObserver>();
@@ -71,7 +68,6 @@
         mObservers.clear();
 
         super.destroy();
-        mNativeTabModelImpl = 0;
     }
 
     @Override
@@ -291,6 +287,19 @@
 
     @Override
     public boolean closeTab(Tab tabToClose, boolean animate, boolean uponExit, boolean canUndo) {
+        return closeTab(tabToClose, animate, uponExit, canUndo, canUndo);
+    }
+
+    /**
+     * See TabModel.java documentation for description of other parameters.
+     * @param notify Whether or not to notify observers about the pending closure. If this is
+     *               {@code true}, {@link #supportsPendingClosures()} is {@code true},
+     *               and canUndo is {@code true}, observers will be notified of the pending
+     *               closure. Observers will still be notified of a committed/cancelled closure
+     *               even if they are not notified of a pending closure to start with.
+     */
+    private boolean closeTab(Tab tabToClose, boolean animate, boolean uponExit,
+            boolean canUndo, boolean notify) {
         if (tabToClose == null) {
             assert false : "Tab is null!";
             return false;
@@ -303,7 +312,7 @@
 
         canUndo &= supportsPendingClosures();
 
-        if (canUndo) {
+        if (notify && canUndo) {
             for (TabModelObserver obs : mObservers) obs.tabPendingClosure(tabToClose);
         }
         startTabClosure(tabToClose, animate, uponExit, canUndo);
@@ -314,6 +323,11 @@
 
     @Override
     public void closeAllTabs() {
+        closeAllTabs(true);
+    }
+
+    @Override
+    public void closeAllTabs(boolean allowDelegation) {
         commitAllTabClosures();
 
         while (getCount() > 0) {
@@ -321,6 +335,29 @@
         }
     }
 
+    /**
+     * Close all tabs on this model without notifying observers about pending tab closures.
+     *
+     * @param animate true iff the closing animation should be displayed
+     * @param uponExit true iff the tabs are being closed upon application exit (after user presses
+     *                 the system back button)
+     * @param canUndo Whether or not this action can be undone. If this is {@code true} and
+     *                {@link #supportsPendingClosures()} is {@code true}, these {@link Tab}s
+     *                will not actually be closed until {@link #commitTabClosure(int)} or
+     *                {@link #commitAllTabClosures()} is called, but they will be effectively
+     *                removed from this list.
+     * @return a list containing the ids of tabs that have been closed
+     */
+    public ArrayList<Integer> closeAllTabs(boolean animate, boolean uponExit, boolean canUndo) {
+        ArrayList<Integer> closedTabs = new ArrayList<Integer>();
+        while (getCount() > 0) {
+            Tab tab = getTabAt(0);
+            closedTabs.add(tab.getId());
+            closeTab(tab, animate, uponExit, canUndo, false);
+        }
+        return closedTabs;
+    }
+
     @Override
     public Tab getTabAt(int index) {
         // This will catch INVALID_TAB_INDEX and return null
@@ -584,6 +621,4 @@
     protected boolean isSessionRestoreInProgress() {
         return mModelDelegate.isSessionRestoreInProgress();
     }
-
-    private native long nativeInit(boolean isIncognito);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
index b74d6ba..a935e3f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
@@ -14,28 +14,27 @@
 public abstract class TabModelJniBridge implements TabModel {
     private final boolean mIsIncognito;
 
-    /** Native TabModelJniBridge pointer, which will be set by {@link #setNativePtr(long)}. */
+    /** Native TabModelJniBridge pointer, which will be set by {@link #initializeNative()}. */
     private long mNativeTabModelJniBridge;
 
     public TabModelJniBridge(boolean isIncognito) {
         mIsIncognito = isIncognito;
     }
 
-    @CalledByNative
-    private void clearNativePtr() {
-        assert mNativeTabModelJniBridge != 0;
-        mNativeTabModelJniBridge = 0;
+    /** Initializes the native-side counterpart to this class. */
+    protected void initializeNative() {
+        assert mNativeTabModelJniBridge == 0;
+        mNativeTabModelJniBridge = nativeInit(mIsIncognito);
     }
 
-    @CalledByNative
-    private void setNativePtr(long nativePointer) {
-        assert mNativeTabModelJniBridge == 0;
-        mNativeTabModelJniBridge = nativePointer;
+    /** @return Whether the native-side pointer has been initialized. */
+    public boolean isNativeInitialized() {
+        return mNativeTabModelJniBridge != 0;
     }
 
     @Override
     public void destroy() {
-        if (mNativeTabModelJniBridge != 0) {
+        if (isNativeInitialized()) {
             // This will invalidate all other native references to this object in child classes.
             nativeDestroy(mNativeTabModelJniBridge);
             mNativeTabModelJniBridge = 0;
@@ -54,7 +53,7 @@
 
     /** Broadcast a native-side notification that all tabs are now loaded from storage. */
     public void broadcastSessionRestoreComplete() {
-        assert mNativeTabModelJniBridge != 0;
+        assert isNativeInitialized();
         nativeBroadcastSessionRestoreComplete(mNativeTabModelJniBridge);
     }
 
@@ -63,7 +62,7 @@
      * @param tab Tab being added to the model.
      */
     protected void tabAddedToModel(Tab tab) {
-        if (mNativeTabModelJniBridge != 0) nativeTabAddedToModel(mNativeTabModelJniBridge, tab);
+        if (isNativeInitialized()) nativeTabAddedToModel(mNativeTabModelJniBridge, tab);
     }
 
     /**
@@ -116,6 +115,7 @@
     @CalledByNative
     protected abstract boolean isSessionRestoreInProgress();
 
+    private native long nativeInit(boolean isIncognito);
     private native Profile nativeGetProfileAndroid(long nativeTabModelJniBridge);
     private native void nativeBroadcastSessionRestoreComplete(long nativeTabModelJniBridge);
     private native void nativeDestroy(long nativeTabModelJniBridge);
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 050ed82..2a4a10c 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -262,6 +262,9 @@
       <message name="IDS_ACCESSIBILITY_MENU_BACK" desc="Content description for the backard navigation button.">
         Go back
       </message>
+      <message name="IDS_ACCESSIBILITY_CONTENT_VIEW" desc="Content description for the content view that holds the web contents [CHAR-LIMIT=30]">
+        Web View
+      </message>
       <!-- ContextMenu -->
       <message name="IDS_CONTEXTMENU_OPEN_IN_NEW_TAB" desc="Context sensitive menu item to open the selected link in a new tab. [CHAR-LIMIT=30]">
         Open in new tab
@@ -408,6 +411,52 @@
         Add to homescreen
       </message>
 
+      <!-- WebsiteSettingsPopup (PageInfo dialog) -->
+      <message name="IDS_PAGE_INFO_COPY_URL_BUTTON" desc="Text in the button that copies the URL to the clipboard.">
+        Copy URL
+      </message>
+      <message name="IDS_PAGE_INFO_SITE_SETTINGS_BUTTON" desc="Text in the button that opens a website's Site Settings from the Page Info dialog.">
+        Site Settings
+      </message>
+      <message name="IDS_PAGE_INFO_DONE_BUTTON" desc="Text in the button that closes the Page Info dialog.">
+        Done
+      </message>
+      <message name="IDS_PAGE_INFO_PERMISSION_ALLOW" desc="The label used in the permissions dropdowns in the Page Info dialog on mobile for the option that grants a permission.">
+        Allow
+      </message>
+      <message name="IDS_PAGE_INFO_PERMISSION_BLOCK" desc="The label used in the permissions dropdowns in the Page Info dialog on mobile for the option that denies a permission.">
+        Block
+      </message>
+      <message name="IDS_PAGE_INFO_CONNECTION_HTTPS" desc="Message to display in the page info bubble when the connection is private (HTTPS).">
+        Your connection to this site is private.
+      </message>
+      <message name="IDS_PAGE_INFO_CONNECTION_HTTP" desc="Message to display in the page info bubble when the connection is not private (HTTP).">
+        Your connection to this site is not private.
+      </message>
+      <message name="IDS_PAGE_INFO_CONNECTION_MIXED" desc="Message to display in the page info bubble when the main connection is private, but there is content on the page that is not private.">
+        Your connection to this site is private, but someone on the network might be able to change the look of the page.
+      </message>
+      <message name="IDS_PAGE_INFO_CONNECTION_BROKEN_LEADING_TEXT" desc="Message to display highlighted red in the page info bubble when the connection is insecure because the HTTPS certificate is invalid.">
+        Your connection to this site is not private.
+      </message>
+      <message name="IDS_PAGE_INFO_CONNECTION_BROKEN_FOLLOWING_TEXT" desc="Message to display after a 'Your connection to this site is not private' message' in the page info bubble when the connection is insecure because the HTTPS certificate is invalid.">
+        Attackers might be trying to steal your information (for example, photos, passwords, messages and credit cards) from <ph name="DOMAIN_NAME">%1$s<ex>google.com</ex></ph>.
+      </message>
+      <message name="IDS_PAGE_INFO_CONNECTION_INTERNAL_PAGE" desc="Message to display in the page info bubble when the page is an internal Chrome page (e.g. the bookmarks page, or about:blank).">
+        You are viewing a secure Google Chrome page.
+      </message>
+
+      <!-- Network prediction internal values -->
+      <message name="IDS_NEVER_PREFETCH_BANDWIDTH_ENTRY" desc="Option to always disable the prefetching of web pages. [CHAR-LIMIT=16]">
+        Never
+      </message>
+      <message name="IDS_WIFI_PREFETCH_BANDWIDTH_ENTRY" desc="Option that enables the prefetching of web pages when connected via wi-fi. [CHAR-LIMIT=16]">
+        Only on Wi-Fi
+      </message>
+      <message name="IDS_ALWAYS_PREFETCH_BANDWIDTH_ENTRY" desc="Option to always prefetch web pages regardless of connection. [CHAR-LIMIT=16]">
+        Always
+      </message>
+
     </messages>
   </release>
 </grit>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
index 96f6256..9c7d855 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
@@ -13,9 +13,10 @@
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.shell.ChromeShellActivity;
 import org.chromium.chrome.shell.ChromeShellTestBase;
-import org.chromium.content.browser.NavigationClient;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.browser.NavigationController;
 import org.chromium.content_public.browser.NavigationEntry;
 import org.chromium.content_public.browser.NavigationHistory;
 
@@ -54,11 +55,11 @@
         }
     }
 
-    private static class TestNavigationClient implements NavigationClient {
+    private static class TestNavigationController implements NavigationController {
         private TestNavigationHistory mHistory;
         private int mNavigatedIndex = INVALID_NAVIGATION_INDEX;
 
-        public TestNavigationClient() {
+        public TestNavigationController() {
             mHistory = new TestNavigationHistory();
             mHistory.addEntry(new TestNavigationEntry(
                     1, "about:blank", null, null, "About Blank", null));
@@ -67,6 +68,93 @@
         }
 
         @Override
+        public boolean canGoBack() {
+            return false;
+        }
+
+        @Override
+        public boolean canGoForward() {
+            return false;
+        }
+
+        @Override
+        public boolean canGoToOffset(int offset) {
+            return false;
+        }
+
+        @Override
+        public void goToOffset(int offset) {
+        }
+
+        @Override
+        public void goBack() {
+        }
+
+        @Override
+        public void goForward() {
+        }
+
+        @Override
+        public void loadIfNecessary() {
+        }
+
+        @Override
+        public void requestRestoreLoad() {
+        }
+
+        @Override
+        public void reload(boolean checkForRepost) {
+        }
+
+        @Override
+        public void reloadIgnoringCache(boolean checkForRepost) {
+        }
+
+        @Override
+        public void cancelPendingReload() {
+        }
+
+        @Override
+        public void continuePendingReload() {
+        }
+
+        @Override
+        public void loadUrl(LoadUrlParams params) {
+        }
+
+        @Override
+        public void clearHistory() {
+        }
+
+        @Override
+        public NavigationHistory getNavigationHistory() {
+            return null;
+        }
+
+        @Override
+        public String getOriginalUrlForVisibleNavigationEntry() {
+            return null;
+        }
+
+        @Override
+        public void clearSslPreferences() {
+        }
+
+        @Override
+        public boolean getUseDesktopUserAgent() {
+            return false;
+        }
+
+        @Override
+        public void setUseDesktopUserAgent(boolean override, boolean reloadOnChange) {
+        }
+
+        @Override
+        public NavigationEntry getPendingEntry() {
+            return null;
+        }
+
+        @Override
         public NavigationHistory getDirectedNavigationHistory(boolean isForward, int itemLimit) {
             return mHistory;
         }
@@ -80,9 +168,9 @@
     @MediumTest
     @Feature({"Navigation"})
     public void testFaviconFetching() throws InterruptedException {
-        final TestNavigationClient client = new TestNavigationClient();
+        final TestNavigationController controller = new TestNavigationController();
         final NavigationPopup popup = new NavigationPopup(
-                mActivity, client, true);
+                mActivity, controller, true);
         popup.setWidth(300);
         popup.setAnchorView(mActivity.getActiveContentViewCore().getContainerView());
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -100,7 +188,7 @@
                             return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
                                 @Override
                                 public Boolean call() throws Exception {
-                                    NavigationHistory history = client.mHistory;
+                                    NavigationHistory history = controller.mHistory;
                                     for (int i = 0; i < history.getEntryCount(); i++) {
                                         if (history.getEntryAtIndex(i).getFavicon() == null) {
                                             return false;
@@ -126,9 +214,9 @@
     @SmallTest
     @Feature({"Navigation"})
     public void testItemSelection() {
-        final TestNavigationClient client = new TestNavigationClient();
+        final TestNavigationController controller = new TestNavigationController();
         final NavigationPopup popup = new NavigationPopup(
-                mActivity, client, true);
+                mActivity, controller, true);
         popup.setWidth(300);
         popup.setAnchorView(mActivity.getActiveContentViewCore().getContainerView());
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@@ -146,7 +234,8 @@
         });
 
         assertFalse("Popup did not hide as expected.", popup.isShowing());
-        assertEquals("Popup attempted to navigate to the wrong index", 5, client.mNavigatedIndex);
+        assertEquals("Popup attempted to navigate to the wrong index", 5,
+                controller.mNavigatedIndex);
     }
 
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/OWNERS b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/OWNERS
new file mode 100644
index 0000000..98819a3
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/OWNERS
@@ -0,0 +1,2 @@
+aurimas@chromium.org
+aruslan@chromium.org
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java
index 9e043ff..d0f8fe30 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java
@@ -35,8 +35,8 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                DomDistillerService domDistillerService = DomDistillerServiceFactory.
-                        getForProfile(Profile.getLastUsedProfile());
+                DomDistillerService domDistillerService = DomDistillerServiceFactory
+                        .getForProfile(Profile.getLastUsedProfile());
                 mDistilledPagePrefs = domDistillerService.getDistilledPagePrefs();
             }
         });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/PrefServiceBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/PrefServiceBridgeTest.java
new file mode 100644
index 0000000..6c0b8c5b
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/PrefServiceBridgeTest.java
@@ -0,0 +1,47 @@
+// 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.
+
+package org.chromium.chrome.browser.preferences;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.shell.ChromeShellTestBase;
+
+/**
+ * Test for PrefServiceBridge
+ */
+public class PrefServiceBridgeTest extends ChromeShellTestBase {
+    /**
+     * Test the x-auto-login setting.
+     */
+    @SmallTest
+    @Feature({"Preferences", "Main"})
+    public void testAutologinEnabled() {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                PrefServiceBridge prefs = PrefServiceBridge.getInstance();
+
+                boolean autologinEnabled = prefs.isAutologinEnabled();
+
+                // Make sure the value doesn't change
+                prefs.setAutologinEnabled(autologinEnabled);
+                assertEquals(autologinEnabled, prefs.isAutologinEnabled());
+
+                // Try flipping the value
+                autologinEnabled = !autologinEnabled;
+                prefs.setAutologinEnabled(autologinEnabled);
+                assertEquals(autologinEnabled, prefs.isAutologinEnabled());
+            }
+        });
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        launchChromeShellWithBlankPage();
+    }
+}
diff --git a/chrome/android/shell/java/AndroidManifest.xml b/chrome/android/shell/java/AndroidManifest.xml
index 1e329d0..0074e76 100644
--- a/chrome/android/shell/java/AndroidManifest.xml
+++ b/chrome/android/shell/java/AndroidManifest.xml
@@ -9,7 +9,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.chromium.chrome.shell">
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <permission android:name="org.chromium.chrome.shell.permission.SANDBOX"
             android:protectionLevel="signature" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java
index 42f5ed2..386026c 100644
--- a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java
+++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellToolbar.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.shell;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.drawable.ClipDrawable;
@@ -189,6 +190,7 @@
             }
         });
         menuButton.setOnTouchListener(new OnTouchListener() {
+            @SuppressLint("ClickableViewAccessibility")
             @Override
             public boolean onTouch(View view, MotionEvent event) {
                 return mAppMenuButtonHelper != null && mAppMenuButtonHelper.onTouch(view, event);
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/omnibox/SuggestionPopup.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/omnibox/SuggestionPopup.java
index 63e65b7..50dc4585 100644
--- a/chrome/android/shell/java/src/org/chromium/chrome/shell/omnibox/SuggestionPopup.java
+++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/omnibox/SuggestionPopup.java
@@ -104,10 +104,10 @@
 
     private int getSuggestionPopupHeight() {
         Rect appRect = new Rect();
-        ((ChromeShellActivity) mContext).getWindow().getDecorView().
-                getWindowVisibleDisplayFrame(appRect);
-        int dropDownItemHeight = mContext.getResources().
-                getDimensionPixelSize(R.dimen.dropdown_item_height);
+        ((ChromeShellActivity) mContext).getWindow().getDecorView()
+                .getWindowVisibleDisplayFrame(appRect);
+        int dropDownItemHeight = mContext.getResources()
+                .getDimensionPixelSize(R.dimen.dropdown_item_height);
         // Applying margin height equal to |dropDownItemHeight| if constrained by app rect.
         int popupHeight = appRect.height() - dropDownItemHeight;
         if (mSuggestionsPopup != null) {
diff --git a/chrome/android/shell/javatests/AndroidManifest.xml b/chrome/android/shell/javatests/AndroidManifest.xml
index a9ed06d9..d8b1f02 100644
--- a/chrome/android/shell/javatests/AndroidManifest.xml
+++ b/chrome/android/shell/javatests/AndroidManifest.xml
@@ -19,7 +19,7 @@
             </intent-filter>
         </activity>
     </application>
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.chrome.shell"
         android:label="Tests for org.chromium.chrome.shell"/>
diff --git a/chrome/android/sync_shell/java/AndroidManifest.xml b/chrome/android/sync_shell/java/AndroidManifest.xml
index e756c75..2d24628 100644
--- a/chrome/android/sync_shell/java/AndroidManifest.xml
+++ b/chrome/android/sync_shell/java/AndroidManifest.xml
@@ -9,7 +9,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.chromium.chrome.sync_shell">
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <permission android:name="org.chromium.chrome.shell.permission.SANDBOX"
             android:protectionLevel="signature" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
diff --git a/chrome/android/sync_shell/javatests/AndroidManifest.xml b/chrome/android/sync_shell/javatests/AndroidManifest.xml
index 8b667809..c1cf622c 100644
--- a/chrome/android/sync_shell/javatests/AndroidManifest.xml
+++ b/chrome/android/sync_shell/javatests/AndroidManifest.xml
@@ -19,7 +19,7 @@
             </intent-filter>
         </activity>
     </application>
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.chrome.sync_shell"
         android:label="Tests for org.chromium.chrome.sync_shell"/>
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h
index faeecd7..f92d8996 100644
--- a/chrome/app/chrome_command_ids.h
+++ b/chrome/app/chrome_command_ids.h
@@ -94,7 +94,6 @@
 #define IDC_ENCODING_AUTO_DETECT        35500
 #define IDC_ENCODING_UTF8               35501
 #define IDC_ENCODING_UTF16LE            35502
-#define IDC_ENCODING_ISO88591           35503
 #define IDC_ENCODING_WINDOWS1252        35504
 #define IDC_ENCODING_GBK                35505
 #define IDC_ENCODING_GB18030            35506
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc
index 67115ea..f1f5fc4 100644
--- a/chrome/app/chrome_exe_main_win.cc
+++ b/chrome/app/chrome_exe_main_win.cc
@@ -10,6 +10,7 @@
 #include "base/at_exit.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
+#include "base/logging.h"
 #include "base/win/windows_version.h"
 #include "chrome/app/client_util.h"
 #include "chrome/browser/chrome_process_finder_win.h"
@@ -78,6 +79,59 @@
       chrome::NOTIFY_SUCCESS;
 }
 
+// Duplicated from Win8.1 SDK ShellScalingApi.h
+typedef enum PROCESS_DPI_AWARENESS {
+    PROCESS_DPI_UNAWARE = 0,
+    PROCESS_SYSTEM_DPI_AWARE = 1,
+    PROCESS_PER_MONITOR_DPI_AWARE = 2
+} PROCESS_DPI_AWARENESS;
+
+typedef enum MONITOR_DPI_TYPE {
+    MDT_EFFECTIVE_DPI = 0,
+    MDT_ANGULAR_DPI = 1,
+    MDT_RAW_DPI = 2,
+    MDT_DEFAULT = MDT_EFFECTIVE_DPI
+} MONITOR_DPI_TYPE;
+
+// Win8.1 supports monitor-specific DPI scaling.
+bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
+  typedef BOOL(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
+  SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
+      reinterpret_cast<SetProcessDpiAwarenessPtr>(
+          GetProcAddress(GetModuleHandleA("user32.dll"),
+                          "SetProcessDpiAwarenessInternal"));
+  if (set_process_dpi_awareness_func) {
+    HRESULT hr = set_process_dpi_awareness_func(value);
+    if (SUCCEEDED(hr)) {
+      VLOG(1) << "SetProcessDpiAwareness succeeded.";
+      return true;
+    } else if (hr == E_ACCESSDENIED) {
+      LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
+          "Function called twice, or manifest was used.";
+    }
+  }
+  return false;
+}
+
+// This function works for Windows Vista through Win8. Win8.1 must use
+// SetProcessDpiAwareness[Wrapper]
+BOOL SetProcessDPIAwareWrapper() {
+  typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
+  SetProcessDPIAwarePtr set_process_dpi_aware_func =
+      reinterpret_cast<SetProcessDPIAwarePtr>(
+      GetProcAddress(GetModuleHandleA("user32.dll"),
+                      "SetProcessDPIAware"));
+  return set_process_dpi_aware_func &&
+    set_process_dpi_aware_func();
+}
+
+
+void EnableHighDPISupport() {
+  if (!SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
+    SetProcessDPIAwareWrapper();
+  }
+}
+
 }  // namespace
 
 #if !defined(ADDRESS_SANITIZER)
@@ -102,7 +156,7 @@
   // DirectWrite there. GDI fonts are kerned very badly, so better to leave
   // DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
   if (base::win::GetVersion() > base::win::VERSION_VISTA)
-    gfx::EnableHighDPISupport();
+    EnableHighDPISupport();
 
   if (AttemptFastNotify(*CommandLine::ForCurrentProcess()))
     return 0;
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 2d277a6..118ac5d 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -487,13 +487,12 @@
   // original command line.
   if (command_line.HasSwitch(chromeos::switches::kLoginUser) ||
       command_line.HasSwitch(switches::kDiagnosticsRecovery)) {
-
     // The statistics subsystem needs get initialized soon enough for the
     // statistics to be collected.  It's safe to call this more than once.
     base::StatisticsRecorder::Initialize();
 
     CommandLine interim_command_line(command_line.GetProgram());
-    const char* kSwitchNames[] = {switches::kUserDataDir, };
+    const char* const kSwitchNames[] = {switches::kUserDataDir, };
     interim_command_line.CopySwitchesFrom(
         command_line, kSwitchNames, arraysize(kSwitchNames));
     interim_command_line.AppendSwitch(switches::kDiagnostics);
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 3a66367..9588658 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1436,8 +1436,8 @@
   <message name="IDS_LOGIN_CONFIRM_PASSWORD_ERROR_TEXT" desc="Error text to show when the password typed by the user could not be verified.">
     Sorry, your password could not be verified. Please try again.
   </message>
-  <message name="IDS_LOGIN_FATAL_ERROR_NO_EMAIL" desc="Message to show when the authentication could not be completed because the user's e-mail address could not be retrieved.">
-    Oops, couldn't sign you in. Sign-in failed because your e-mail address could not be retrieved.
+  <message name="IDS_LOGIN_FATAL_ERROR_NO_ACCOUNT_DETAILS" desc="Message to show when the authentication could not be completed because the user's account details could not be retrieved.">
+    Oops, couldn't sign you in. Sign-in failed because your account details could not be retrieved.
   </message>
   <message name="IDS_LOGIN_FATAL_ERROR_NO_PASSWORD" desc="Message to show when the authentication could not be completed because the user's password could not be retrieved.">
     Something went wrong with signing in.
@@ -4752,6 +4752,9 @@
   <message name="IDS_IME_NAME_INPUTMETHOD_ZHUYIN" desc="The input method name shows in system tray menu, this is Zhuyin input method for Traditional Chinese.">
     Zhuyin input method
   </message>
+  <message name="IDS_IME_NAME_INPUTMETHOD_HANGUL" desc="The input method name shows in system tray menu, this is Korean Hangul input method.">
+    Hangul input method
+  </message>
   <message name="IDS_IME_NAME_INPUTMETHOD_HANGUL_2_SET" desc="The input method name shows in system tray menu, this is Korean Hangul input method, 2 Set mode.">
     Hangul 2 Set
   </message>
@@ -5073,6 +5076,12 @@
   <message name="IDS_LOGIN_CONNECTING_INDICATOR_TEXT" desc="A message to show telling the user that the device is attempting to re-connect to the network.">
     Connecting and verifying<ph name="ANIMATED_ELLIPSIS">$1<ex>...</ex></ph>
   </message>
+  <message name="IDS_DEVICE_DISABLED_HEADING" desc="Heading of the message shown to the user when the device has been disabled by its owner.">
+    Locked
+  </message>
+  <message name="IDS_DEVICE_DISABLED_EXPLANATION" desc="Explanation shown to the user when the device has been disabled by its owner.">
+    This device was locked by its owner. Only an approved administrator can unlock it. Take this device to Tech Support for assistance.
+  </message>
 
   <!-- Idle warning dialog -->
   <message name="IDS_IDLE_WARNING_TITLE" desc="Title of the warning dialog shown when the user becomes idle and is about to get logged out.">
@@ -5100,22 +5109,19 @@
     Kiosk application launch canceled.
   </message>
   <message name="IDS_KIOSK_EXTERNAL_UPDATE_IN_PROGRESS" desc="Message shown on screen when the system is updating kiosk apps from usb stick.">
-    Kiosk applications are being updated from usb stick, please wait. Do not remove the usb stick.
+    Please wait....Kiosk app is in the process of being updated. Do not remove the USB stick.
   </message>
   <message name="IDS_KIOSK_EXTERNAL_UPDATE_NO_UPDATES" desc="Error message for no external extensions to update.">
-    No kiosk apps with newer version are found on the usb stick, nothing to update. Please remove the usb stick.
-  </message>
-  <message name="IDS_KIOSK_EXTERNAL_UPDATE_NO_MANIFEST" desc="Error message for external update manifest file not found.">
-    Can't find kiosk external update manifest file on the usb stick, failed to update kiosk apps. Please remove the usb stick.
+    No Kiosk apps with newer version found. Nothing to update. Please remove the USB stick.
   </message>
   <message name="IDS_KIOSK_EXTERNAL_UPDATE_INVALID_MANIFEST" desc="Error message for invalid external update manifest file from usb stick.">
-    Found invalid kiosk external update manifest file on the usb stick, failed to update kiosk apps. Please remove the usb stick.
+    Invalid Kiosk external update manifest file found. Failed to update Kiosk app. Please remove the USB stick.
   </message>
   <message name="IDS_KIOSK_EXTERNAL_UPDATE_COMPLETE" desc="Message shown on screen when the system completes updating kiosk apps from usb stick.">
-    Kiosk app updating from usb stick is completed. Please remove the usb stick from the device.
+    Kiosk app has been updated. Please remove the USB stick.
   </message>
   <message name="IDS_KIOSK_EXTERNAL_UPDATE_SUCCESSFUL_UPDATED_APPS" desc="Message shown for successfully updated kiosk apps.">
-    The following kiosk apps have been updated, please reboot the device to complete the update process: <ph name="updated_apps">$1<ex>PrintApp</ex></ph>.
+    The following kiosk apps "<ph name="updated_apps">$1<ex>PrintApp</ex></ph>" have been updated. Please reboot the device to complete the update process.
   </message>
   <message name="IDS_KIOSK_EXTERNAL_UPDATE_FAILED_UPDATED_APPS" desc="Message shown for failed updated kiosk apps.">
     The following kiosk apps have been failed for updating:
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index c68194c..7908c00 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -429,7 +429,7 @@
         Use hardware acceleration when available
       </message>
       <message name="IDS_OPTIONS_SYSTEM_ENABLE_HARDWARE_ACCELERATION_MODE_RESTART" desc="The restart string after changing hardware acceleration mode">
-        (requires Chromium <ph name="BEGIN_BUTTON">&lt;button id="gpu-mode-reset-restart-button" type="button" class="link-button standalone-link-button"&gt;</ph>restart<ph name="END_BUTTON">&lt;/button&gt;</ph>)
+        (requires Chromium <ph name="BEGIN_BUTTON">&lt;a is="action-link" id="gpu-mode-reset-restart-button" class="standalone-action-link"&gt;</ph>restart<ph name="END_BUTTON">&lt;/a&gt;</ph>)
       </message>
       <message name="IDS_CANT_WRITE_USER_DIRECTORY_SUMMARY" desc="Summary of problem displayed in dialog when we can't create a directory for this user.">
 Chromium cannot read and write to its data directory:
@@ -467,7 +467,7 @@
       </if>
       <!-- Password generation strings -->
       <message name="IDS_PASSWORD_GENERATION_PROMPT" desc="Autofill dropdown text describing password generation. The text inside |bars| is link text.">
-        Chromium will store this in your |Google saved passwords| and autofill it for you so you don't have to remember it yourself.
+        Chromium will store this in your |Google saved passwords| and remember it the next time you need it.
       </message>
       <message name="IDS_PASSWORD_GENERATION_SUGGESTION" desc="Text shown next to a generated password describing it as a suggestion.">
         Use password generated by Chromium
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 7c45527e..3a8fba1 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -578,6 +578,12 @@
       <message name="IDS_HISTORY_UNKNOWN_DEVICE" desc="On the dropdown menu for a history entry, the text that is shown instead of a device name, when the device name is not known.">
         Unknown device
       </message>
+      <message name="IDS_HISTORY_ENTRY_BOOKMARKED" desc="Whether a history entry is bookmarked.">
+        Bookmarked
+      </message>
+      <message name="IDS_HISTORY_ENTRY_SUMMARY" desc="Summary of all the fields in a history entry (time, whether the entry is bookmarked, title, and domain).">
+        <ph name="TIME"><ex>3:14</ex>$1</ph> <ph name="BOOKMARKED"><ex>bookmarked</ex>$2</ph> <ph name="TITLE"><ex>PI: The Magical Number</ex>$3</ph> <ph name="DOMAIN"><ex>pi.com</ex>$4</ph>
+      </message>
 
       <!-- Generic terms -->
       <message name="IDS_OK" desc="Used for OK on buttons">
@@ -1219,6 +1225,9 @@
           <message name="IDS_PIN_TO_START_SCREEN" desc="In Title Case: The text label of the Pin to start screen menu item">
             Pin this Page to Start Screen...
           </message>
+          <message name="IDS_EDIT2" desc="In Title Case: The text label before the cut/copy/paste buttons in the merged menu">
+            Edit
+          </message>
           <message name="IDS_CUT" desc="In Title Case: The text label of the Cut menu item">
             Cu&amp;t
           </message>
@@ -1249,6 +1258,9 @@
           <message name="IDS_ZOOM_MENU" desc="In Title Case: The text label of the Zoom submenu">
             &amp;Zoom
           </message>
+          <message name="IDS_ZOOM_MENU2" desc="In Title Case: The text label of the Zoom menu in the merged menu">
+            Zoom
+          </message>
           <message name="IDS_ZOOM_PLUS" desc="In Title Case: The text label of the Make Text Larger menu item">
             &amp;Larger
           </message>
@@ -1289,7 +1301,7 @@
         Make Text Smaller
       </message>
 
-      <message name="IDS_ENCODING_DISPLAY_TEMPLATE" desc="The format of encodings in the encoding menu. Encoding categories are Unicode, Western, Turkish, Cyrillic, Chinese Simplified, Thai, Arabic, Hebrew and so forth. Encoding names are UTF-8, ISO-8859-1, Windows-1251, GB2312, etc.">
+      <message name="IDS_ENCODING_DISPLAY_TEMPLATE" desc="The format of encodings in the encoding menu. Encoding categories are Unicode, Western, Turkish, Cyrillic, Chinese Simplified, Thai, Arabic, Hebrew and so forth. Encoding names are UTF-8, Windows-1252, ISO-8859-8, GB2312, etc.">
         <ph name="ENCODING_CATEGORY">$1<ex>Japanese</ex></ph> (<ph name="ENCODING_NAME">$2<ex>Shift_JIS</ex></ph>)
       </message>
       <message name="IDS_ENCODING_UNICODE" desc="The text label of Unicode encodings">
@@ -1433,9 +1445,6 @@
         <message name="IDS_FULLSCREEN" desc="Switches into fullscreen mode">
           &amp;Full screen
         </message>
-        <message name="IDS_ACCNAME_FULLSCREEN" desc="The accessible name of the fullscreen button in the new merged menu">
-          Full screen
-        </message>
         <message name="IDS_CLEAR_BROWSING_DATA" desc="The text label for the menu item for clearing of browsing data">
           &amp;Clear browsing data...
         </message>
@@ -2169,93 +2178,69 @@
 
       <!-- "Application Information" dialog -->
       <if expr="not use_titlecase">
-        <message name="IDS_APPLICATION_INFO_WEB_STORE_LINK" desc="Text for the link that opens the app in the Web Store..">
+        <message name="IDS_APPLICATION_INFO_WEB_STORE_LINK" desc="Text for the link that opens the app or extension in the Web Store..">
           View in store
         </message>
-        <message name="IDS_APPLICATION_INFO_HOMEPAGE_LINK" desc="Text for the link that opens the app's homepage, as specified by the developer.">
+        <message name="IDS_APPLICATION_INFO_HOMEPAGE_LINK" desc="Text for the link that opens the app or extension's homepage, as specified by the developer.">
           Developer website
         </message>
-        <message name="IDS_APPLICATION_INFO_UNINSTALL_BUTTON_TEXT" desc="Text for the button that removes (uninstalls) the app.">
+        <message name="IDS_APPLICATION_INFO_APP_OVERVIEW_TITLE" desc="Text displayed above the current details for the app or extension.">
+          Overview
+        </message>
+        <message name="IDS_APPLICATION_INFO_APP_PERMISSIONS_TITLE" desc="Text displayed above the current permissions for the app or extension.">
+          Permissions
+        </message>
+        <message name="IDS_APPLICATION_INFO_UNINSTALL_BUTTON_TEXT" desc="Text for the button that removes (uninstalls) the app or extension.">
           Remove
         </message>
-        <message name="IDS_APPLICATION_INFO_LICENSES_BUTTON_TEXT" desc="Text for the button that displays the licenses for the app.">
+        <message name="IDS_APPLICATION_INFO_LICENSES_BUTTON_TEXT" desc="Text for the button that displays the licenses for the app or extension.">
           Licenses
         </message>
-        <message name="IDS_APPLICATION_INFO_SIZE_LABEL" desc="Text displayed before the app's size on disk in the details section of the dialog.">
+        <message name="IDS_APPLICATION_INFO_SIZE_LABEL" desc="Text displayed before the app or extension's size on disk in the details section of the dialog.">
           Size:
         </message>
-        <message name="IDS_APPLICATION_INFO_VERSION_LABEL" desc="Text displayed before the app's version in the details section of the dialog.">
+        <message name="IDS_APPLICATION_INFO_VERSION_LABEL" desc="Text displayed before the app or extension's version in the details section of the dialog.">
           Version:
         </message>
-        <message name="IDS_APPLICATION_INFO_VERSION_BUILT_IN_LABEL" desc="Text displayed in the app's version field to show that it is a built-in app (such as the Chrome Web Store, or the Files app).">
-          Built-in
-        </message>
-        <message name="IDS_APPLICATION_INFO_RETAINED_FILE_PERMISSIONS_TEXT" desc="Heading above the current retained files for the app, which are files the app has permanent access to (the app can read and write to these files).">
-          Files
-        </message>
-        <message name="IDS_APPLICATION_INFO_REVOKE_RETAINED_FILE_PERMISSIONS_BUTTON_TEXT" desc="Text displayed in the button to remove the app's file permissions. After pressing this button, the app no longer has access to the files.">
-          Revoke file access
-        </message>
         <message name="IDS_APPLICATION_INFO_CREATE_SHORTCUTS_BUTTON_TEXT" desc="Text for the button that opens the dialog to create shortcuts for the app.">
           Create shortcuts
         </message>
-        <message name="IDS_APPLICATION_INFO_RETAINED_DEVICE_PERMISSIONS_TEXT" desc="Heading above the current retained devices for the app, which are devices the app has permanent access to.">
-          Devices
-        </message>
-        <message name="IDS_APPLICATION_INFO_REVOKE_DEVICE_PERMISSIONS_BUTTON_TEXT" desc="Text displayed in the button to remove the app's device permissions. After pressing this button, the app no longer has access to the devices.">
-          Revoke device access
-        </message>
       </if>
       <if expr="use_titlecase">
-        <message name="IDS_APPLICATION_INFO_WEB_STORE_LINK" desc="In Title Case: Text for the link that opens the app in the Web Store..">
+        <message name="IDS_APPLICATION_INFO_WEB_STORE_LINK" desc="In Title Case: Text for the link that opens the app or extension in the Web Store..">
           View in Store
         </message>
-        <message name="IDS_APPLICATION_INFO_HOMEPAGE_LINK" desc="In Title Case: Text for the link that opens the app's homepage, as specified by the developer.">
+        <message name="IDS_APPLICATION_INFO_HOMEPAGE_LINK" desc="In Title Case: Text for the link that opens the app or extension's homepage, as specified by the developer.">
           Developer Website
         </message>
-        <message name="IDS_APPLICATION_INFO_UNINSTALL_BUTTON_TEXT" desc="In Title Case: Text for the button that removes (uninstalls) the app.">
+        <message name="IDS_APPLICATION_INFO_APP_OVERVIEW_TITLE" desc="In Title Case: Text displayed above the current details for the app or extension.">
+          Overview
+        </message>
+        <message name="IDS_APPLICATION_INFO_APP_PERMISSIONS_TITLE" desc="In Title Case: Text displayed above the current permissions for the app or extension.">
+          Permissions
+        </message>
+        <message name="IDS_APPLICATION_INFO_UNINSTALL_BUTTON_TEXT" desc="In Title Case: Text for the button that removes (uninstalls) the app or extension.">
           Remove
         </message>
-        <message name="IDS_APPLICATION_INFO_LICENSES_BUTTON_TEXT" desc="In Title Case: Text for the button that displays the licenses for the app.">
+        <message name="IDS_APPLICATION_INFO_LICENSES_BUTTON_TEXT" desc="In Title Case: Text for the button that displays the licenses for the app or extension.">
           Licenses
         </message>
-        <message name="IDS_APPLICATION_INFO_SIZE_LABEL" desc="In Title Case: Text displayed before the app's size on disk in the details section of the dialog.">
+        <message name="IDS_APPLICATION_INFO_SIZE_LABEL" desc="In Title Case: Text displayed before the app or extension's size on disk in the details section of the dialog.">
           Size:
         </message>
-        <message name="IDS_APPLICATION_INFO_VERSION_LABEL" desc="In Title Case: Text displayed before the app's version in the details section of the dialog.">
+        <message name="IDS_APPLICATION_INFO_VERSION_LABEL" desc="In Title Case: Text displayed before the app or extension's version in the details section of the dialog.">
           Version:
         </message>
-        <message name="IDS_APPLICATION_INFO_VERSION_BUILT_IN_LABEL" desc="In Title Case: Text displayed in the app's version field to show that it is a built-in app (such as the Chrome Web Store, or the Files app).">
-          Built-In
-        </message>
-        <message name="IDS_APPLICATION_INFO_RETAINED_FILE_PERMISSIONS_TEXT" desc="In Title Case: Heading above the current retained files for the app, which are files the app has permanent access to (the app can read and write to these files).">
-          Files
-        </message>
-        <message name="IDS_APPLICATION_INFO_REVOKE_RETAINED_FILE_PERMISSIONS_BUTTON_TEXT" desc="In Title Case: Text displayed in the button to remove the app's file permissions. After pressing this button, the app no longer has access to the files.">
-          Revoke File Access
-        </message>
         <message name="IDS_APPLICATION_INFO_CREATE_SHORTCUTS_BUTTON_TEXT" desc="In Title Case: Text for the button that opens the dialog to create shortcuts for the app.">
           Create Shortcuts
         </message>
-        <message name="IDS_APPLICATION_INFO_RETAINED_DEVICES_PERMISSIONS_TEXT" desc="In Title Case: Heading above the current retained devices for tha pp, which are devices the app has permanent access to.">
-          Devices
-        </message>
-        <message name="IDS_APPLICATION_INFO_REVOKE_DEVICE_PERMISSIONS_BUTTON_TEXT" desc="In Title Case: Text displayed in the button to remove the app's device permissions. After pressing this button, the app no longer has access to the devices.">
-          Revoke Device Access
-        </message>
       </if>
-      <message name="IDS_APPLICATION_INFO_SIZE_LOADING_LABEL" desc="Text displayed instead of the app's size on disk in the details section of the dialog while the size is being calculated.">
+      <message name="IDS_APPLICATION_INFO_SIZE_LOADING_LABEL" desc="Text displayed instead of the app or extension's size on disk in the details section of the dialog while the size is being calculated.">
         Calculating...
       </message>
-      <message name="IDS_APPLICATION_INFO_SIZE_SMALL_LABEL" desc="Text displayed instead of the app's size for apps that are less than 1 megabyte in size.">
+      <message name="IDS_APPLICATION_INFO_SIZE_SMALL_LABEL" desc="Text displayed instead of the app or extension's size for apps and extensions that are less than 1 megabyte in size.">
         &lt; 1 MB
       </message>
-      <message name="IDS_APPLICATION_INFO_APP_PERMISSIONS_TITLE" desc="Text displayed above the current permissions for the app (the permissions that the user has granted the app upon installation).">
-        This app can:
-      </message>
-      <message name="IDS_APPLICATION_INFO_EXTENSION_PERMISSIONS_TITLE" desc="Text displayed above the current permissions for the extension (the permissions that the user has granted the extension upon installation).">
-        This extension can:
-      </message>
       <message name="IDS_APPLICATION_INFO_APP_NO_PERMISSIONS_TEXT" desc="Text displayed in the Permissions area of the dialog if the app has no permissions.">
         This app requires no special permissions.
       </message>
@@ -2263,6 +2248,115 @@
         This extension requires no special permissions.
       </message>
 
+      <message name="IDS_APPLICATION_INFO_RETAINED_FILES_DEFAULT" desc="A line of explanatory text that precedes the list of files the app has permanent access to, showing the number of files. This is shown when an app has persistent access to files. This is necessary for every language. This is the default for all the numbers NOT covered by special cases (singular, dual/two, few, many) some languages need. For CJK, Vietnamese, Turkish and Kannada, this is the only string necessary. For languages with singular-plural distinction, this is the generic plural. For Lithuanian, NUMBER_OF_FILES is 11 .. 19.">
+        Access <ph name="NUMBER_OF_FILES">#<ex>5</ex></ph> files stored on your computer
+      </message>
+      <if expr="lang not in ['zh-CN', 'zh-TW', 'ko', 'ja', 'vi', 'tr', 'kn']">
+        <message name="IDS_APPLICATION_INFO_RETAINED_FILE_SINGULAR" desc="A line of explanatory text that precedes the list of files the app has permanent access to, showing the number of files. This is shown when an app has persistent access to files. NUMBER_OF_FILES is one or one-like numbers : 1 (many European and most Indian languages), 1 and 0 (French, Brazilian Portuguese and Hindi), 1,21,31, .. (Russian, Ukrainian, Croatian, Serbian, Latvian, Lithuanian), or 1, 101, 201, .. (Slovenian). Do NOT translate this for CJK, Vietnamese, Turkish and Kannada">
+          Access <ph name="NUMBER_OF_FILES">#<ex>1</ex></ph> file stored on your computer
+        </message>
+      </if>
+      <if expr="lang in ['zh-CN', 'zh-TW', 'ko', 'ja', 'vi', 'tr', 'kn']">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_FILE_SINGULAR" desc="">
+          NA
+        </message>
+      </if>
+      <if expr="lang in ['ar', 'ro', 'lv']">
+        <message name="IDS_APPLICATION_INFO_RETAINED_FILES_ZERO" desc="A line of explanatory text that precedes the list of files the app has permanent access to, showing the number of files. This is shown when an app has persistent access to files. NUMBER_OF_FILES is 0 (Arabic, Latvian) or 0, 2..19, 101..119, ... (Romanian). For other languages, do NOT translate.">
+          Access <ph name="NUMBER_OF_FILES">#<ex>0</ex></ph> files stored on your computer
+        </message>
+      </if>
+      <if expr="lang not in ['ar', 'ro', 'lv']">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_FILES_ZERO" desc="">
+          NA
+        </message>
+      </if>
+      <if expr="lang in ['ga', 'sl', 'ar']">
+        <message name="IDS_APPLICATION_INFO_RETAINED_FILES_TWO" desc="A line of explanatory text that precedes the list of files the app has permanent access to, showing the number of files. This is shown when an app has persistent access to files. NUMBER_OF_FILES is two or two-like/dual numbers :  2 (Arabic and Irish) or  2, 102, 202 ... (Slovenian). For other languages, do NOT translated.">
+          Access <ph name="NUMBER_OF_FILES">#<ex>2</ex></ph> files stored on your computer
+        </message>
+      </if>
+        <if expr="lang not in ['ga', 'sl', 'ar']">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_FILES_TWO" desc="">
+          NA
+        </message>
+      </if>
+      <if expr="lang  in ['ru', 'lt', 'hr', 'uk', 'cs', 'sk', 'pl', 'sl', 'ar']">
+        <message name="IDS_APPLICATION_INFO_RETAINED_FILES_FEW" desc="A line of explanatory text that precedes the list of files the app has permanent access to, the number of files. This is shown when an app has persistent access to files. NUMBER_OF_FILES is few or few-like numbers in Arabic, Russian, Polish, Croatian, Serbian, Ukrainian, Czech, Slovak, Slovenian, Latvian. For other languages, do NOT translate.">
+          Access <ph name="NUMBER_OF_FILES">#<ex>3</ex></ph> files stored on your computer
+        </message>
+      </if>
+      <if expr="lang not in ['ru', 'lt', 'hr', 'uk', 'cs', 'sk', 'pl', 'sl', 'ar']">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_FILES_FEW" desc="">
+          NA
+        </message>
+      </if>
+      <if expr="lang == 'ar'">
+        <message name="IDS_APPLICATION_INFO_RETAINED_FILES_MANY" desc="A line of explanatory text that precedes the list of files the app has permanent access to, showing the number of files. This is shown when an app has persistent access to files. NUMBER_OF_FILES is 11 through 99 in Arabic. For all other languages, do NOT translate.">
+          Access <ph name="NUMBER_OF_FILES">#<ex>23</ex></ph> files stored on your computer
+        </message>
+      </if>
+      <if expr="lang != 'ar'">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_FILES_MANY" desc="">
+          NA
+        </message>
+      </if>
+
+      <message name="IDS_APPLICATION_INFO_RETAINED_DEVICES_DEFAULT" desc="A line of explanatory text that precedes the list of USB devices the app has permanent access to, showing the number of USB devices. This is shown when an app has persistent access to USB devices. This is necessary for every language. This is the default for all the numbers NOT covered by special cases (singular, dual/two, few, many) some languages need. For CJK, Vietnamese, Turkish and Kannada, this is the only string necessary. For languages with singular-plural distinction, this is the generic plural. For Lithuanian, NUMBER_OF_DEVICES is 11 .. 19.">
+        Communicate with <ph name="NUMBER_OF_DEVICES">#<ex>5</ex></ph> USB devices
+      </message>
+
+      <if expr="lang not in ['zh-CN', 'zh-TW', 'ko', 'ja', 'vi', 'tr', 'kn']">
+      <message name="IDS_APPLICATION_INFO_RETAINED_DEVICE_SINGULAR" desc="A line of explanatory text that precedes the list of USB devices the app has permanent access to, showing the number of USB devices. This is shown when an app has persistent access to USB devices. NUMBER_OF_DEVICES is one or one-like numbers : 1 (many European and most Indian languages), 1 and 0 (French, Brazilian Portuguese and Hindi), 1,21,31, .. (Russian, Ukrainian, Croatian, Serbian, Latvian, Lithuanian), or 1, 101, 201, .. (Slovenian). Do NOT translate this for CJK, Vietnamese, Turkish and Kannada">
+        Communicate with <ph name="NUMBER_OF_DEVICES">#<ex>1</ex></ph> USB device
+      </message>
+      </if>
+      <if expr="lang in ['zh-CN', 'zh-TW', 'ko', 'ja', 'vi', 'tr', 'kn']">
+      <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_DEVICE_SINGULAR" desc="">
+        NA
+      </message>
+      </if>
+      <if expr="lang in ['ar', 'ro', 'lv']">
+        <message name="IDS_APPLICATION_INFO_RETAINED_DEVICES_ZERO" desc="A line of explanatory text that precedes the list of USB devices the app has permanent access to, showing the number of USB devices. This is shown when an app has persistent access to USB devices. NUMBER_OF_DEVICES is 0 (Arabic, Latvian) or 0, 2..19, 101..119, ... (Romanian). For other languages, do NOT translate.">
+          Communicate with <ph name="NUMBER_OF_DEVICES">#<ex>0</ex></ph> USB devices
+        </message>
+      </if>
+      <if expr="lang not in ['ar', 'ro', 'lv']">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_DEVICES_ZERO" desc="">
+          NA
+        </message>
+      </if>
+      <if expr="lang in ['ga', 'sl', 'ar']">
+        <message name="IDS_APPLICATION_INFO_RETAINED_DEVICES_TWO" desc="A line of explanatory text that precedes the list of USB devices the app has permanent access to, showing the number of USB devices. This is shown when an app has persistent access to USB devices. NUMBER_OF_DEVICES is two or two-like/dual numbers :  2 (Arabic and Irish) or 2, 102, 202 ... (Slovenian). For other languages, do NOT translated.">
+          Communicate with <ph name="NUMBER_OF_DEVICES">#<ex>2</ex></ph> USB devices
+        </message>
+      </if>
+      <if expr="lang not in ['ga', 'sl', 'ar']">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_DEVICES_TWO" desc="">
+          NA
+        </message>
+      </if>
+      <if expr="lang  in ['ru', 'lt', 'hr', 'uk', 'cs', 'sk', 'pl', 'sl', 'ar']">
+        <message name="IDS_APPLICATION_INFO_RETAINED_DEVICES_FEW" desc="A line of explanatory text that precedes the list of USB devices the app has permanent access to, showing the number of USB devices. This is shown when an app has persistent access to USB devices. NUMBER_OF_DEVICES is few or few-like numbers in Arabic, Russian, Polish, Croatian, Serbian, Ukrainian, Czech, Slovak, Slovenian, Latvian. For other languages, do NOT translate.">
+          Communicate with <ph name="NUMBER_OF_DEVICES">#<ex>3</ex></ph> USB devices
+        </message>
+      </if>
+      <if expr="lang not in ['ru', 'lt', 'hr', 'uk', 'cs', 'sk', 'pl', 'sl', 'ar']">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_DEVICES_FEW" desc="">
+          NA
+        </message>
+      </if>
+      <if expr="lang == 'ar'">
+        <message name="IDS_APPLICATION_INFO_RETAINED_DEVICES_MANY" desc="A line of explanatory text that precedes the list of USB devices the app has permanent access to, showing the number of USB devices. This is shown when an app has persistent access to USB devices. NUMBER_OF_DEVICES is 11 through 99 in Arabic. For all other languages, do NOT translate.">
+          Communicate with <ph name="NUMBER_OF_DEVICES">#<ex>23</ex></ph> USB devices
+        </message>
+      </if>
+      <if expr="lang != 'ar'">
+        <message translateable="false" name="IDS_APPLICATION_INFO_RETAINED_DEVICES_MANY" desc="">
+          NA
+        </message>
+      </if>
+
       <!-- "Create application shortcuts" dialog -->
       <if expr="not use_titlecase">
         <message name="IDS_CREATE_SHORTCUTS_TITLE" desc="Title of the dialog to create application shortcuts for current page.">
@@ -4885,8 +4979,8 @@
           <message name="IDS_EXTENSIONS_HIDE_BUTTON" desc="The text for the Hide context menu item (sentence case).">
             Hide button
           </message>
-          <message name="IDS_MANAGE_EXTENSION" desc="The 'Manage' text in the context menu for when right-clicking on extension icons (sentence case).">
-            Manage
+          <message name="IDS_MANAGE_EXTENSION" desc="The 'Manage extensions' text in the context menu for when right-clicking on extension icons (sentence case).">
+            Manage extensions
           </message>
           <message name="IDS_EXTENSION_ACTION_INSPECT_POPUP" desc="The text for the right-click menu of page and browser actions which shows the popup and opens the developer tools (sentence case).">
             Inspect popup
@@ -4905,8 +4999,8 @@
           <message name="IDS_EXTENSIONS_HIDE_BUTTON" desc="The text for the Hide context menu item (title case).">
             Hide Button
           </message>
-          <message name="IDS_MANAGE_EXTENSION" desc="The 'Manage' text in the context menu for when right-clicking on extension icons (title case).">
-            Manage
+          <message name="IDS_MANAGE_EXTENSION" desc="The 'Manage Extensions' text in the context menu for when right-clicking on extension icons (title case).">
+            Manage Extensions
           </message>
           <message name="IDS_EXTENSION_ACTION_INSPECT_POPUP" desc="The text for the right-click menu of page and browser actions which shows the popup and opens the developer tools (title case).">
             Inspect Popup
@@ -6120,6 +6214,12 @@
       <message name="IDS_FLAGS_ENABLE_CARRIER_SWITCHING_DESCRIPTION" desc="Description for the flag to set to enable carrier switching.">
         Allows the user to switch between mobile carriers from the UI. Warning: The Sprint carrier will ONLY work for users with an existing Sprint plan.
       </message>
+      <message name="IDS_FLAGS_ENABLE_CLOUD_BACKUP" desc="Name for the flag to enable cloud backup feature.">
+        Enable cloud backup.
+      </message>
+      <message name="IDS_FLAGS_ENABLE_CLOUD_BACKUP_DESCRIPTION" desc="Description for the flag to enable cloud backup.">
+        Allows the user to easily backup content to the cloud.
+      </message>
       <message name="IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_NAME" desc="Name for the flag to set to enable Request Tablet Site in the wrench menu.">
         Enables the request tablet site option in the settings menu.
       </message>
@@ -6547,6 +6647,12 @@
       <message name="IDS_FLAGS_DISABLE_THREADED_SCROLLING_DESCRIPTION" desc="Description for the flag to disable threaded scrolling.">
         Disabled threaded handling of scroll-related input events, forcing all such scroll events to be handled on the main thread. Note that this can dramatically hurt scrolling performance of most websites and is intended for testing purposes only.
       </message>
+      <message name="IDS_FLAGS_DISABLE_EXTENSION_INFO_DIALOG_NAME" desc="Name of the flag to disable the Extensions Info dialog on the chrome://extensions page.">
+        Disable the Extensions Info dialog.
+      </message>
+      <message name="IDS_FLAGS_DISABLE_EXTENSION_INFO_DIALOG_DESCRIPTION" desc="Description for the flag to disable the Extensions Info dialog on the chrome://extensions page.">
+        Disables the Extensions Info dialog from being launched from the chrome://extensions page (reverts to the old-style dialog).
+      </message>
       <message name="IDS_FLAGS_BLEEDING_RENDERER_NAME" desc="Name of the 'Stacked Tabs' lab.">
         Bleeding Edge Renderer Paths - LIKELY TO CRASH YOUR BROWSER
       </message>
@@ -6592,12 +6698,6 @@
       <message name="IDS_FLAGS_ENABLE_EXTENSION_ACTION_REDESIGN_DESCRIPTION" desc="Description for the flag to enable the extension toolbar redesign">
         Enables the (in development) new extension toolbar toolbar design.
       </message>
-      <message name="IDS_FLAGS_ENABLE_EXTENSION_INFO_DIALOG_NAME" desc="Name of the flag to enable the Extensions Info dialog on the chrome://extensions page.">
-        Enable the Extensions Info dialog.
-      </message>
-      <message name="IDS_FLAGS_ENABLE_EXTENSION_INFO_DIALOG_DESCRIPTION" desc="Description for the flag to enable the Extensions Info dialog on the chrome://extensions page.">
-        Enables the Extensions Info dialog for each extension on the chrome://extensions page.
-      </message>
       <message name="IDS_FLAGS_ENABLE_WEBSITE_SETTINGS_NAME" desc="Name of the flag that enables the website settings manager in chrome://settings.">
         Enables the website settings manager.
       </message>
@@ -6815,9 +6915,16 @@
       <message name="IDS_PLUGIN_NOT_SUPPORTED_METRO" desc="The placeholder text for a plug-in that can't run in Windows Metro mode.">
         This plug-in only works on the desktop.
       </message>
-      <message name="IDS_PLUGIN_BLOCKED" desc="The placeholder text for a blocked plug-in.">
-        <ph name="PLUGIN_NAME">$1<ex>Flash</ex></ph> is not allowed.
-      </message>
+      <if expr="is_macosx">
+        <message name="IDS_PLUGIN_BLOCKED" desc="The placeholder text for a blocked plug-in.">
+          Control-click to play <ph name="PLUGIN_NAME">$1<ex>Flash</ex></ph>.
+        </message>
+      </if>
+      <if expr="not is_macosx">
+        <message name="IDS_PLUGIN_BLOCKED" desc="The placeholder text for a blocked plug-in.">
+          Right-click to play <ph name="PLUGIN_NAME">$1<ex>Flash</ex></ph>.
+        </message>
+      </if>
       <if expr="chromeos">
         <message name="IDS_NACL_PLUGIN_BLOCKED" desc="The placeholder text for a blocked plug-in.">
           This app is not currently supported on this device but the Chrome gnomes are hard at work to make it work soon.
@@ -7069,23 +7176,6 @@
         About Voice Search
       </message>
 
-      <!-- JavaScript Dialog Box strings -->
-      <message name="IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE" desc="Title for JavaScript alert originating from a webpage if there is no hostname to display">
-        JavaScript Alert
-      </message>
-      <message name="IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE" desc="Title for JavaScript prompt and confirm originating from a webpage if there is no hostname to display">
-        JavaScript
-      </message>
-      <message name="IDS_JAVASCRIPT_ALERT_TITLE" desc="Title for JavaScript alert originating from a webpage">
-        The page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says:
-      </message>
-      <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE" desc="Title for JavaScript prompt and confirm originating from a webpage">
-        The page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says:
-      </message>
-      <message name="IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION" desc="Optional UI shown on the message box, in the form of a checkbox, allowing the user to suppress additional message boxes from the page.">
-        Prevent this page from creating additional dialogs.
-      </message>
-
       <!-- About box strings -->
       <if expr="is_win">
         <message name="IDS_ABOUT_BOX_ERROR_DURING_UPDATE_CHECK" desc="The error label for errors that occurred while checking for updates in the About box.">
@@ -7096,34 +7186,6 @@
         </message>
       </if>
 
-      <!-- "Before Unload" Dialog Box strings -->
-      <message name="IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE" desc="Title for the 'before unload' dialog.">
-        Confirm Navigation
-      </message>
-      <message name="IDS_BEFOREUNLOAD_MESSAGEBOX_FOOTER" desc="Text shown at the bottom of the dialog, after the message provided by the script.">
-        Are you sure you want to leave this page?
-      </message>
-      <message name="IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL" desc="The text on the button which navigates the user away from the page.">
-        Leave this Page
-      </message>
-      <message name="IDS_BEFOREUNLOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL" desc="The text on the button which cancels the navigation away from the page.">
-        Stay on this Page
-      </message>
-
-      <!-- "Before Reload" Dialog Box strings (same as "Before Unload" but when reloading rather than unloading the page -->
-      <message name="IDS_BEFORERELOAD_MESSAGEBOX_TITLE" desc="Title for the 'before reload' dialog.">
-        Confirm Reload
-      </message>
-      <message name="IDS_BEFORERELOAD_MESSAGEBOX_FOOTER" desc="Text shown at the bottom of the dialog, after the message provided by the script.">
-        Are you sure you want to reload this page?
-      </message>
-      <message name="IDS_BEFORERELOAD_MESSAGEBOX_OK_BUTTON_LABEL" desc="The text on the button which reloads the page.">
-        Reload this Page
-      </message>
-      <message name="IDS_BEFORERELOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL" desc="The text on the button which cancels the page reload.">
-        Don't Reload
-      </message>
-
       <!-- Omnibox -->
       <if expr="not use_titlecase">
         <message name="IDS_PASTE_AND_GO" desc="The text label of the Paste And Go menu item when the clipboard contains a URL">
@@ -7249,6 +7311,9 @@
       <message name="IDS_ACCNAME_FORWARD" desc="The accessible name for the forward button.">
         Forward
       </message>
+      <message name="IDS_ACCNAME_FULLSCREEN" desc="The accessible name of the fullscreen button in the new merged menu">
+        Full screen
+      </message>
       <message name="IDS_ACCNAME_HOME" desc="The accessible name for the home button">
         Home
       </message>
@@ -7825,11 +7890,11 @@
       <message name="IDS_PLUGIN_LOAD_RADIO" desc="A radio button in the Content Settings dialog for allowing plug-ins use on any site.">
         Run automatically (recommended)
       </message>
-      <message name="IDS_PLUGIN_ASK_RADIO" desc="A radio button in the Content Settings dialog for allowing plug-ins use on any site.">
+      <message name="IDS_PLUGIN_ASK_RADIO" desc="A radio button in the Content Settings dialog for gating plug-ins on a mouse click (left button).">
         Click to play
       </message>
-      <message name="IDS_PLUGIN_NOLOAD_RADIO" desc="A radio button in the Content Settings dialog for preventing plug-ins use on any site.">
-        Block all
+      <message name="IDS_PLUGIN_ASK_MENU_RADIO" desc="A radio button in the Content Settings dialog for gating plug-ins on a context menu activation.">
+        Block by default (You can manually run a blocked plug-in at any time.)
       </message>
       <message name="IDS_PLUGIN_SELECTIVE_DISABLE" desc="Link to selectively disable plug-ins">
         Disable individual plug-ins...
@@ -9418,17 +9483,6 @@
         </message>
       </if>
 
-      <!-- Page Info Bubble -->
-      <message name="IDS_PAGE_INFO_ENCRYPTED_CONNECTION_SUMMARY_TEXT" desc="Message to display in the page info bubble when the connection is private.">
-        Your connection to this site is private.
-      </message>
-      <message name="IDS_PAGE_INFO_UNENCRYPTED_CONNECTION_SUMMARY_TEXT" desc="Message to display in the page info bubble when the connection is not private.">
-        Your connection to this site is not private.
-      </message>
-      <message name="IDS_PAGE_INFO_MIXED_CONTENT_CONNECTION_SUMMARY_TEXT" desc="Message to display in the page info bubble when the connection is private, but someone on the network might be able to change the look of the page (there is content on the page that is not private).">
-        Your connection to this site is private (HTTPS), but someone on the network might be able to change the look of the page.
-      </message>
-
       <!-- Critical Notification Bubble -->
       <message name="IDS_CRITICAL_NOTIFICATION_HEADLINE" desc="The headline for the critical notification">
         <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will restart in <ph name="SECONDS">$2<ex>10</ex></ph> seconds.
@@ -13045,7 +13099,7 @@
       Generated password saved
     </message>
     <message name="IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_TEXT" desc="The text that is used in the manage passwords bubble when a generated password is saved. Text inside |bars| is link text.">
-      You can access it and all your |Google saved passwords| securely from any browser.
+      You can access it and all your |Google saved passwords| from any browser.
     </message>
     <message name="IDS_MANAGE_PASSWORDS_TITLE" desc="The title text that is used in the manage passwords bubble when a password is autofilled or after a user has stored a password.">
       Saved passwords for this site:
@@ -13471,7 +13525,7 @@
         Oops! The new supervised user couldn't be created. Please make sure you're signed in properly and try again.
       </message>
       <message name="IDS_PROFILES_CREATE_EXISTING_SUPERVISED_USER_ERROR" desc="Message shown when the user enters the name of a supervised user that can be imported.">
-        Looks like you're already managing a user by that name.<ph name="LINE_BREAK">&lt;br/&gt;</ph>Did you want to <ph name="BEGIN_LINK">&lt;button id="supervised-user-import-existing" class="link-button"&gt;</ph>import <ph name="PROFILE_NAME">$1<ex>John</ex></ph> to this device<ph name="END_LINK">&lt;/button&gt;</ph>?
+        Looks like you're already managing a user by that name.<ph name="LINE_BREAK">&lt;br/&gt;</ph>Did you want to <ph name="BEGIN_LINK">&lt;a is="action-link" id="supervised-user-import-existing"&gt;</ph>import <ph name="PROFILE_NAME">$1<ex>John</ex></ph> to this device<ph name="END_LINK">&lt;/a&gt;</ph>?
       </message>
       <message name="IDS_PROFILES_CREATE_SUPERVISED_SIGNED_IN_LABEL" desc="Label for the 'Supervised user' checkbox in the create-profile dialog when the current user is signed in.">
         Control and view the websites this person visits from <ph name="CUSTODIAN_EMAIL">$1<ex>user@gmail.com</ex></ph>.
@@ -13484,7 +13538,7 @@
         Creating your supervised user. This may take a few moments.
       </message>
       <message name="IDS_PROFILES_CREATE_SUPERVISED_NOT_SIGNED_IN_HTML" desc="Label for the (disabled) 'Supervised user' checkbox in the create-profile dialog when the current user is not signed in, containing a link to the sign in page.">
-        <ph name="BEGIN_SIGN_IN_LINK">&lt;button id="create-profile-supervised-sign-in-link" class="link-button"&gt;</ph>Sign in<ph name="END_SIGN_IN_LINK">&lt;/button&gt;</ph> to control and view the websites this person visits.
+        <ph name="BEGIN_SIGN_IN_LINK">&lt;a is="action-link" id="create-profile-supervised-sign-in-link"&gt;</ph>Sign in<ph name="END_SIGN_IN_LINK">&lt;/a&gt;</ph> to control and view the websites this person visits.
       </message>
       <message name="IDS_PROFILES_CREATE_SUPERVISED_NOT_SIGNED_IN_LINK" desc="Text for the sign-in promo link, shown after the (disabled) 'Supervised user' checkbox in the create-profile dialog when the current user is not signed in.">
         Sign in now
@@ -13791,6 +13845,12 @@
     <message name="IDS_FLAGS_ENABLE_WEB_BASED_SIGNIN_DESCRIPTION" desc="Description for the flag to enable web-based sign-in flows">
       When enabled, will use a pure web-based sign-in flow on first run/NTP/wrench menu/settings page. Otherwise use a native flow with embedded webview.
     </message>
+    <message name="IDS_FLAGS_ENABLE_WEBVIEW_BASED_SIGNIN_NAME" desc="Title for the flag to enable webview-based sign-in flows.">
+      Enables webview-based Chrome sign-in flows. This flag overrides --enable-web-based-signin.
+    </message>
+    <message name="IDS_FLAGS_ENABLE_WEBVIEW_BASED_SIGNIN_DESCRIPTION" desc="Description for the flag to enable webview-based sign-in flows">
+      When enabled, will use a webview-based Chrome sign-in flow.
+    </message>
     <message name="IDS_FLAGS_ENABLE_GOOGLE_PROFILE_INFO_NAME" desc="Title for the flag to enable the google profile information">
       Enable Google profile name and icon
     </message>
@@ -13845,6 +13905,20 @@
         Enable IME extensions to supply custom views for user input such as  virtual keyboards.
       </message>
 
+      <message name="IDS_FLAGS_ENABLE_NEW_KOREAN_IME_NAME" desc="Name of about::flags option to enable the new Korean IME">
+        Enable new Korean IME.
+      </message>
+      <message name="IDS_FLAGS_ENABLE_NEW_KOREAN_IME_DESCRIPTION" desc="Description of about::flags option to enable the new Korean IME">
+        Enable new Korean IME, which is based on Google Input Tools' HMM engine.
+      </message>
+
+      <message name="IDS_FLAGS_ENABLE_PHYSICAL_KEYBOARD_AUTOCORRECT_NAME" desc="Name of about::flags option to enable physical keyboard autocorrect for US keyboard">
+        Enable physical keyboard autocorrect.
+      </message>
+      <message name="IDS_FLAGS_ENABLE_PHYSICAL_KEYBOARD_AUTOCORRECT_DESCRIPTION" desc="Description of about::flags option to enable physical keyboard autocorrect for US keyboard">
+        Enable physical keyboard autocorrect for US keyboard, which can provide suggestions as typing on physical keyboard.
+      </message>
+
       <message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_INPUT_VIEW_FEATURES_NAME" desc="Name of about::flags option to enable experimental features for IME input-views">
         Experimental input view features.
       </message>
@@ -14194,12 +14268,9 @@
     </message>
 
     <!-- Password generation strings -->
-    <message name="IDS_PASSWORD_GENERATION_BUBBLE_TITLE" desc="The title of the bubble asking users if they would like Chrome to generate a password for them on an account creation page.">
+    <message name="IDS_PASSWORD_GENERATION_ACCESSIBLE_TITLE" desc="The accessibility name of the popup asking users if they would like Chrome to generate a password for them.">
       Password Suggestion
     </message>
-    <message name="IDS_PASSWORD_GENERATION_BUTTON_TEXT" desc="The text on the button that users click to accept the generated password">
-      Try it
-    </message>
 
     <!-- Identity internals strings -->
     <message name="IDS_IDENTITY_INTERNALS_TOKEN_CACHE_TEXT" desc="The title of the token cache of the Identity API.">
@@ -14514,12 +14585,19 @@
         Personalized
       </message>
     </if>
+
     <message name="IDS_FLAGS_DISABLE_IGNORE_AUTOCOMPLETE_OFF_NAME" desc="Name of the disable ignore autocomplete='off' lab">
-      Disable ignore autocomplete='off'
+      Disable ignore autocomplete='off' (Passwords)
     </message>
     <message name="IDS_FLAGS_DISABLE_IGNORE_AUTOCOMPLETE_OFF_DESCRIPTION" desc="Description of the disable ignore autocomplete='off' lab">
       Disable ignore autocomplete='off' for password forms in the password manager.
     </message>
+    <message name="IDS_FLAGS_IGNORE_AUTOCOMPLETE_OFF_AUTOFILL_NAME" desc="Name of the ignore autocomplete='off' for Autofill lab">
+      Ignore autocomplete='off' (Autofill)
+    </message>
+    <message name="IDS_FLAGS_IGNORE_AUTOCOMPLETE_OFF_AUTOFILL_DESCRIPTION" desc="Description of the ignore autocomplete='off' for Autofill lab">
+      Ignore autocomplete='off' for forms that Chrome can Autofill with credit card or address data.
+    </message>
 
     <!-- Reader mode experiment flags -->
     <if expr="is_android">
@@ -14751,9 +14829,15 @@
     <message name="IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_HARDLOCK_PAIRING_CHANGED" desc="Tooltip text shown on a user's lock screen pod when Easy Unlock feature is enabled for the user, but the pairing data is changed. A password has to be entered to unlock the device.">
       One-time activation: Type your password to activate Chrome Smart Lock. Next time, you can just click your picture.
     </message>
+    <message name="IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_LOGIN_FAILURE" desc="Tooltip text shown on a user's lock screen when Smart Lock signin attempt fails.">
+      Smart Lock couldn't verify your account. Type your password to enter.
+    </message>
     <message name="IDS_EASY_UNLOCK_SCREENLOCK_USER_POD_AUTH_VALUE" desc="Message on lock screen user pod shown in place of password field when Easy Unlock is enabled and a phone that can unlock the Chromebook is detected in proximity.">
       Click to enter
     </message>
+    <message name="IDS_SMART_LOCK_SPINNER_ACCESSIBILITY_LABEL" desc="Label for the spinner icon used for accessibility purposes. This label is needed because this state does not have a tooltip.">
+      Finding your phone
+    </message>
     <!-- Device types -->
     <message name="IDS_EASY_UNLOCK_GENERIC_DEVICE_TYPE" desc="String for an unknown device type. Currently used to cover all non-ChromeOS devices.">
       Chrome device
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index 96e14dd..0184292 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -352,7 +352,7 @@
         Use hardware acceleration when available
       </message>
       <message name="IDS_OPTIONS_SYSTEM_ENABLE_HARDWARE_ACCELERATION_MODE_RESTART" desc="The restart string after changing hardware acceleration mode">
-        (requires Chrome <ph name="BEGIN_BUTTON">&lt;button id="gpu-mode-reset-restart-button" type="button" class="link-button standalone-link-button"&gt;</ph>restart<ph name="END_BUTTON">&lt;/button&gt;</ph>)
+        (requires Chrome <ph name="BEGIN_BUTTON">&lt;a is="action-link" id="gpu-mode-reset-restart-button" class="standalone-action-link"&gt;</ph>restart<ph name="END_BUTTON">&lt;/a&gt;</ph>)
       </message>
       <message name="IDS_CANT_WRITE_USER_DIRECTORY_SUMMARY" desc="Summary of problem displayed in dialog when we can't create a directory for this user.">
 Google Chrome cannot read and write to its data directory:
@@ -390,7 +390,7 @@
       </if>
       <!-- Password generation strings -->
       <message name="IDS_PASSWORD_GENERATION_PROMPT" desc="Autofill dropdown text describing password generation. The text inside |bars| is link text.">
-        Chrome will store this in your |Google saved passwords| and autofill it for you so you don't have to remember it yourself.
+        Chrome will store this in your |Google saved passwords| and remember it the next time you need it.
       </message>
       <message name="IDS_PASSWORD_GENERATION_SUGGESTION" desc="Text shown next to a generated password describing it as a suggestion.">
         Use password generated by Chrome
diff --git a/chrome/app/resources/locale_settings.grd b/chrome/app/resources/locale_settings.grd
index f1a07c2..9ce9405 100644
--- a/chrome/app/resources/locale_settings.grd
+++ b/chrome/app/resources/locale_settings.grd
@@ -241,7 +241,7 @@
 
       <!-- The default value for |WebPreference::default_encoding|. -->
       <message name="IDS_DEFAULT_ENCODING" use_name_for_id="true">
-        ISO-8859-1
+        windows-1252
       </message>
 
       <!-- The default value for |WebPreference::uses_universal_detector|. -->
@@ -317,7 +317,7 @@
 
       <!-- Locale-dependent static encodings string -->
       <message name="IDS_STATIC_ENCODING_LIST" use_name_for_id="true">
-        ISO-8859-1,windows-1252
+        windows-1252
       </message>
 
       <!-- The URL for the the Welcome to Chrome page shown on first run. -->
diff --git a/chrome/app/resources/locale_settings_am.xtb b/chrome/app/resources/locale_settings_am.xtb
index c2e2fcb9..149feb9 100644
--- a/chrome/app/resources/locale_settings_am.xtb
+++ b/chrome/app/resources/locale_settings_am.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="am">
 <translation id="IDS_ACCEPT_LANGUAGES">am,en-GB,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-GB</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_bn.xtb b/chrome/app/resources/locale_settings_bn.xtb
index 9fe35dc..2a30a7a 100644
--- a/chrome/app/resources/locale_settings_bn.xtb
+++ b/chrome/app/resources/locale_settings_bn.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="bn">
 <translation id="IDS_ACCEPT_LANGUAGES">bn-IN,bn,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_ca.xtb b/chrome/app/resources/locale_settings_ca.xtb
index b3ca4e5..561aac88 100644
--- a/chrome/app/resources/locale_settings_ca.xtb
+++ b/chrome/app/resources/locale_settings_ca.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="ca">
 <translation id="IDS_ACCEPT_LANGUAGES">ca-ES,ca</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">ca</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">455</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_da.xtb b/chrome/app/resources/locale_settings_da.xtb
index 976d032..00329aa 100644
--- a/chrome/app/resources/locale_settings_da.xtb
+++ b/chrome/app/resources/locale_settings_da.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="da">
 <translation id="IDS_ACCEPT_LANGUAGES">da-DK,da,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">da</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_de.xtb b/chrome/app/resources/locale_settings_de.xtb
index c633206..a2be8b64 100644
--- a/chrome/app/resources/locale_settings_de.xtb
+++ b/chrome/app/resources/locale_settings_de.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="de">
 <translation id="IDS_ACCEPT_LANGUAGES">de-DE,de,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">de</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">370</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_en-GB.xtb b/chrome/app/resources/locale_settings_en-GB.xtb
index a879f7d..96aace3 100644
--- a/chrome/app/resources/locale_settings_en-GB.xtb
+++ b/chrome/app/resources/locale_settings_en-GB.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="en-GB">
 <translation id="IDS_ACCEPT_LANGUAGES">en-GB,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-GB</translation>
 <translation id="IDS_OPTIONS_DIALOG_LEFT_COLUMN_WIDTH_CHARS">23</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_es-419.xtb b/chrome/app/resources/locale_settings_es-419.xtb
index c5c738d0..4183a09 100644
--- a/chrome/app/resources/locale_settings_es-419.xtb
+++ b/chrome/app/resources/locale_settings_es-419.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="es-419">
 <translation id="IDS_ACCEPT_LANGUAGES">es-419,es</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">es</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">380</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_es.xtb b/chrome/app/resources/locale_settings_es.xtb
index f68dc463..2b9e9e4 100644
--- a/chrome/app/resources/locale_settings_es.xtb
+++ b/chrome/app/resources/locale_settings_es.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="es">
 <translation id="IDS_ACCEPT_LANGUAGES">es-ES,es</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">es</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">450</translation>
@@ -48,7 +48,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_fi.xtb b/chrome/app/resources/locale_settings_fi.xtb
index c33189a..ceb766b 100644
--- a/chrome/app/resources/locale_settings_fi.xtb
+++ b/chrome/app/resources/locale_settings_fi.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="fi">
 <translation id="IDS_ACCEPT_LANGUAGES">fi-FI,fi,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252,ISO-8859-15</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252,ISO-8859-15</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_fil.xtb b/chrome/app/resources/locale_settings_fil.xtb
index f04ebcf3..3df036d 100644
--- a/chrome/app/resources/locale_settings_fil.xtb
+++ b/chrome/app/resources/locale_settings_fil.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="fil">
 <translation id="IDS_ACCEPT_LANGUAGES">fil,fil-PH,tl,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">14</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_fr.xtb b/chrome/app/resources/locale_settings_fr.xtb
index eacca4c..1e5b99a 100644
--- a/chrome/app/resources/locale_settings_fr.xtb
+++ b/chrome/app/resources/locale_settings_fr.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="fr">
 <translation id="IDS_ACCEPT_LANGUAGES">fr-FR,fr,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">fr</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">370</translation>
@@ -48,7 +48,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252,ISO-8859-15</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252,ISO-8859-15</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_gu.xtb b/chrome/app/resources/locale_settings_gu.xtb
index 0048954..c1031ea 100644
--- a/chrome/app/resources/locale_settings_gu.xtb
+++ b/chrome/app/resources/locale_settings_gu.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="gu">
 <translation id="IDS_ACCEPT_LANGUAGES">gu-IN,gu,hi-IN,hi,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -47,7 +47,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_hi.xtb b/chrome/app/resources/locale_settings_hi.xtb
index 947c769a..62c9195 100644
--- a/chrome/app/resources/locale_settings_hi.xtb
+++ b/chrome/app/resources/locale_settings_hi.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="hi">
 <translation id="IDS_ACCEPT_LANGUAGES">hi-IN,hi,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">hi</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_id.xtb b/chrome/app/resources/locale_settings_id.xtb
index ef016699..6e48e4c2 100644
--- a/chrome/app/resources/locale_settings_id.xtb
+++ b/chrome/app/resources/locale_settings_id.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="id">
 <translation id="IDS_ACCEPT_LANGUAGES">id-ID,id,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">id</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_it.xtb b/chrome/app/resources/locale_settings_it.xtb
index 653923e..31b3f4d 100644
--- a/chrome/app/resources/locale_settings_it.xtb
+++ b/chrome/app/resources/locale_settings_it.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="it">
 <translation id="IDS_ACCEPT_LANGUAGES">it-IT,it,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">it</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">390</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">13</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_kn.xtb b/chrome/app/resources/locale_settings_kn.xtb
index cce3145..d9094502 100644
--- a/chrome/app/resources/locale_settings_kn.xtb
+++ b/chrome/app/resources/locale_settings_kn.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="kn">
 <translation id="IDS_ACCEPT_LANGUAGES">kn-IN,kn,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_ml.xtb b/chrome/app/resources/locale_settings_ml.xtb
index c59d923..004e2833a 100644
--- a/chrome/app/resources/locale_settings_ml.xtb
+++ b/chrome/app/resources/locale_settings_ml.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="ml">
 <translation id="IDS_ACCEPT_LANGUAGES">ml-IN,ml,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_mr.xtb b/chrome/app/resources/locale_settings_mr.xtb
index 58434dc..dc95e72 100644
--- a/chrome/app/resources/locale_settings_mr.xtb
+++ b/chrome/app/resources/locale_settings_mr.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="mr">
 <translation id="IDS_ACCEPT_LANGUAGES">mr-IN,mr,hi-IN,hi,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_nb.xtb b/chrome/app/resources/locale_settings_nb.xtb
index 809f077e..f0fec49c 100644
--- a/chrome/app/resources/locale_settings_nb.xtb
+++ b/chrome/app/resources/locale_settings_nb.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="no">
 <translation id="IDS_ACCEPT_LANGUAGES">nb-NO,nb,no,nn,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">nb</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_nl.xtb b/chrome/app/resources/locale_settings_nl.xtb
index 4d78704..39d3fa4 100644
--- a/chrome/app/resources/locale_settings_nl.xtb
+++ b/chrome/app/resources/locale_settings_nl.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="nl">
 <translation id="IDS_ACCEPT_LANGUAGES">nl-NL,nl,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">nl</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_pt-BR.xtb b/chrome/app/resources/locale_settings_pt-BR.xtb
index 2894362..7881e6c1c6 100644
--- a/chrome/app/resources/locale_settings_pt-BR.xtb
+++ b/chrome/app/resources/locale_settings_pt-BR.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="pt-BR">
 <translation id="IDS_ACCEPT_LANGUAGES">pt-BR,pt,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">pt-BR</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_pt-PT.xtb b/chrome/app/resources/locale_settings_pt-PT.xtb
index a020999..5c3f059 100644
--- a/chrome/app/resources/locale_settings_pt-PT.xtb
+++ b/chrome/app/resources/locale_settings_pt-PT.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="pt-PT">
 <translation id="IDS_ACCEPT_LANGUAGES">pt-PT,pt,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">pt-PT</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">13</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">66</translation>
diff --git a/chrome/app/resources/locale_settings_sv.xtb b/chrome/app/resources/locale_settings_sv.xtb
index 1bd58740..e15cd79 100644
--- a/chrome/app/resources/locale_settings_sv.xtb
+++ b/chrome/app/resources/locale_settings_sv.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="sv">
 <translation id="IDS_ACCEPT_LANGUAGES">sv-SE,sv,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">sv</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">380</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_sw.xtb b/chrome/app/resources/locale_settings_sw.xtb
index c91e032..4448d55 100644
--- a/chrome/app/resources/locale_settings_sw.xtb
+++ b/chrome/app/resources/locale_settings_sw.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="sw">
 <translation id="IDS_ACCEPT_LANGUAGES">sw,en-GB,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-GB</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_ta.xtb b/chrome/app/resources/locale_settings_ta.xtb
index 012cc20a..765c721 100644
--- a/chrome/app/resources/locale_settings_ta.xtb
+++ b/chrome/app/resources/locale_settings_ta.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="ta">
 <translation id="IDS_ACCEPT_LANGUAGES">ta-IN,ta,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">435</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_te.xtb b/chrome/app/resources/locale_settings_te.xtb
index eec52636..b0b5297 100644
--- a/chrome/app/resources/locale_settings_te.xtb
+++ b/chrome/app/resources/locale_settings_te.xtb
@@ -2,7 +2,7 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="te">
 <translation id="IDS_ACCEPT_LANGUAGES">te-IN,te,hi-IN,hi,en-US,en</translation>
-<translation id="IDS_DEFAULT_ENCODING">ISO-8859-1</translation>
+<translation id="IDS_DEFAULT_ENCODING">windows-1252</translation>
 <translation id="IDS_USES_UNIVERSAL_DETECTOR">false</translation>
 <translation id="IDS_SPELLCHECK_DICTIONARY">en-US</translation>
 <translation id="IDS_SYSTEM_TRAY_MENU_BUBBLE_WIDTH_PIXELS">350</translation>
@@ -46,7 +46,7 @@
 <translation id="IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES">12</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS">70</translation>
 <translation id="IDS_FIRSTRUNOEMBUBBLE_DIALOG_HEIGHT_LINES">4</translation>
-<translation id="IDS_STATIC_ENCODING_LIST">ISO-8859-1,windows-1252</translation>
+<translation id="IDS_STATIC_ENCODING_LIST">windows-1252</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_WIDTH_CHARS">150</translation>
 <translation id="IDS_BOOKMARK_MANAGER_DIALOG_HEIGHT_LINES">40</translation>
 <translation id="IDS_DOWNLOAD_BIG_PROGRESS_SIZE">52</translation>
diff --git a/chrome/app/resources/locale_settings_win.grd b/chrome/app/resources/locale_settings_win.grd
index f7101a2..f0724b5 100644
--- a/chrome/app/resources/locale_settings_win.grd
+++ b/chrome/app/resources/locale_settings_win.grd
@@ -169,6 +169,12 @@
         Courier New
       </message>
 
+      <!-- The default value for |WebPreference::sans_serif_font_family_map| for
+           Arabic script.  -->
+      <message name="IDS_SANS_SERIF_FONT_FAMILY_ARABIC" use_name_for_id="true">
+        Segoe UI
+      </message>
+
       <!-- The default value for |WebPreference::serif_font_family_map| for
            Cyrillic script. -->
       <message name="IDS_SERIF_FONT_FAMILY_CYRILLIC" use_name_for_id="true">
diff --git a/mojo/examples/wm_flow/app/DEPS b/chrome/app/theme/default_300_percent/DELETE_ME
similarity index 100%
rename from mojo/examples/wm_flow/app/DEPS
rename to chrome/app/theme/default_300_percent/DELETE_ME
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 359446a..9a5ee47 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -18,6 +18,7 @@
     <output filename="grit/theme_resources_map.h" type="resource_map_header" context="default_100_percent" />
     <output filename="theme_resources_100_percent.pak" type="data_package" context="default_100_percent" />
     <output filename="theme_resources_200_percent.pak" type="data_package" context="default_200_percent" />
+    <output filename="theme_resources_300_percent.pak" type="data_package" context="default_300_percent" />
   </outputs>
   <release seq="1">
     <structures fallback_to_low_resolution="true">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 217ac9c7..cf47b3c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -113,6 +113,8 @@
     "//components/translate/core/common",
     "//components/url_fixer",
     "//components/user_prefs",
+    "//components/variations",
+    "//components/variations/net",
     "//components/webdata/common",
     "//content/public/browser",
     "//content/public/common",
@@ -171,7 +173,7 @@
       "//components/navigation_interception",
       "//components/password_manager/content/browser",
       "//components/precache/content",
-      "//components/sessions",
+      "//components/sessions:sessions_content",
       "//components/storage_monitor",
       "//components/translate/content/browser",
       "//components/url_matcher",
@@ -264,9 +266,10 @@
   if (enable_background) {
     sources += rebase_path(gypi_values.chrome_browser_background_sources,
                            ".", "//chrome")
-    if (!use_aura || is_win) {
+    if (!use_aura || is_win || is_chromeos) {
       sources -= [ "background/background_mode_manager_aura.cc" ]
     }
+    defines += [ "ENABLE_BACKGROUND=1" ]
   }
   if (enable_task_manager) {
     sources += rebase_path(gypi_values.chrome_browser_task_manager_sources,
@@ -743,8 +746,6 @@
     "download/download_test_file_activity_observer.h",
     "download/test_download_shelf.cc",
     "download/test_download_shelf.h",
-    "extensions/extension_action_test_util.cc",
-    "extensions/extension_action_test_util.h",
     "invalidation/fake_invalidation_service.cc",
     "invalidation/fake_invalidation_service.h",
     "media/fake_desktop_media_list.cc",
@@ -819,6 +820,10 @@
   }
 
   if (enable_extensions) {
+    sources += [
+      "extensions/extension_action_test_util.cc",
+      "extensions/extension_action_test_util.h",
+    ]
     deps += [
       "//extensions:test_support",
     ]
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 8955447..f9572557 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -10,6 +10,7 @@
   "+chrome_elf/create_file",
   "+chrome_elf/dll_hash",
   "+chromeos",
+  "+components/app_modal_dialogs",
   "+components/autofill/content/browser",
   "+components/autofill/content/common",
   "+components/autofill/core/browser",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index f040401..7ee392f 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1045,6 +1045,13 @@
     SINGLE_VALUE_TYPE(chromeos::switches::kEnableCarrierSwitching)
   },
   {
+    "enable-cloud-backup",
+    IDS_FLAGS_ENABLE_CLOUD_BACKUP,
+    IDS_FLAGS_ENABLE_CLOUD_BACKUP_DESCRIPTION,
+    kOsCrOS,
+    SINGLE_VALUE_TYPE(chromeos::switches::kEnableCloudBackup)
+  },
+  {
     "enable-request-tablet-site",
     IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_NAME,
     IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_DESCRIPTION,
@@ -1274,6 +1281,15 @@
     SINGLE_VALUE_TYPE(switches::kDisableGestureRequirementForMediaPlayback)
   },
 #endif
+#if defined(ENABLE_EXTENSIONS)
+  {
+    "disable-extension-info-dialog",
+    IDS_FLAGS_DISABLE_EXTENSION_INFO_DIALOG_NAME,
+    IDS_FLAGS_DISABLE_EXTENSION_INFO_DIALOG_DESCRIPTION,
+    kOsWin | kOsLinux | kOsCrOS,
+    SINGLE_VALUE_TYPE(extensions::switches::kDisableExtensionInfoDialog)
+  },
+#endif
 #if defined(OS_CHROMEOS)
   {
     "enable-virtual-keyboard",
@@ -1307,21 +1323,26 @@
                               keyboard::switches::kDisableInputView)
   },
   {
+    "enable-new-korean-ime",
+    IDS_FLAGS_ENABLE_NEW_KOREAN_IME_NAME,
+    IDS_FLAGS_ENABLE_NEW_KOREAN_IME_DESCRIPTION,
+    kOsCrOS,
+    SINGLE_VALUE_TYPE(chromeos::switches::kEnableNewKoreanIme)
+  },
+  {
+    "enable-physical-keyboard-autocorrect",
+    IDS_FLAGS_ENABLE_PHYSICAL_KEYBOARD_AUTOCORRECT_NAME,
+    IDS_FLAGS_ENABLE_PHYSICAL_KEYBOARD_AUTOCORRECT_DESCRIPTION,
+    kOsCrOS,
+    SINGLE_VALUE_TYPE(chromeos::switches::kEnablePhysicalKeyboardAutocorrect)
+  },
+  {
     "enable-experimental-input-view-features",
     IDS_FLAGS_ENABLE_EXPERIMENTAL_INPUT_VIEW_FEATURES_NAME,
     IDS_FLAGS_ENABLE_EXPERIMENTAL_INPUT_VIEW_FEATURES_DESCRIPTION,
     kOsCrOS,
     SINGLE_VALUE_TYPE(keyboard::switches::kEnableExperimentalInputViewFeatures)
   },
-#if defined(ENABLE_EXTENSIONS)
-  {
-    "enable-extension-info-dialog",
-    IDS_FLAGS_ENABLE_EXTENSION_INFO_DIALOG_NAME,
-    IDS_FLAGS_ENABLE_EXTENSION_INFO_DIALOG_DESCRIPTION,
-    kOsWin | kOsLinux | kOsCrOS,
-    SINGLE_VALUE_TYPE(extensions::switches::kEnableExtensionInfoDialog)
-  },
-#endif
 #endif
   {
     "enable-simple-cache-backend",
@@ -1446,6 +1467,13 @@
     SINGLE_VALUE_TYPE(switches::kEnableWebBasedSignin)
   },
   {
+    "enable-webview-based-signin",
+    IDS_FLAGS_ENABLE_WEBVIEW_BASED_SIGNIN_NAME,
+    IDS_FLAGS_ENABLE_WEBVIEW_BASED_SIGNIN_DESCRIPTION,
+    kOsMac | kOsWin | kOsLinux,
+    SINGLE_VALUE_TYPE(switches::kEnableWebviewBasedSignin)
+  },
+  {
     "enable-google-profile-info",
     IDS_FLAGS_ENABLE_GOOGLE_PROFILE_INFO_NAME,
     IDS_FLAGS_ENABLE_GOOGLE_PROFILE_INFO_DESCRIPTION,
@@ -1662,6 +1690,13 @@
     SINGLE_VALUE_TYPE(autofill::switches::kDisableIgnoreAutocompleteOff)
   },
   {
+    "ignore-autocomplete-off-autofill",
+    IDS_FLAGS_IGNORE_AUTOCOMPLETE_OFF_AUTOFILL_NAME,
+    IDS_FLAGS_IGNORE_AUTOCOMPLETE_OFF_AUTOFILL_DESCRIPTION,
+    kOsCrOS | kOsMac | kOsWin | kOsLinux,
+    SINGLE_VALUE_TYPE(autofill::switches::kIgnoreAutocompleteOffForAutofill)
+  },
+  {
     "enable-permissions-bubbles",
     IDS_FLAGS_ENABLE_PERMISSIONS_BUBBLES_NAME,
     IDS_FLAGS_ENABLE_PERMISSIONS_BUBBLES_DESCRIPTION,
@@ -1853,6 +1888,14 @@
         data_reduction_proxy::switches::kEnableDataReductionProxyDev,
         data_reduction_proxy::switches::kDisableDataReductionProxyDev)
   },
+  {
+    "enable-data-reduction-proxy-alt",
+    IDS_FLAGS_ENABLE_DATA_REDUCTION_PROXY_ALTERNATIVE_NAME,
+    IDS_FLAGS_ENABLE_DATA_REDUCTION_PROXY_ALTERNATIVE_DESCRIPTION,
+    kOsAndroid,
+    SINGLE_VALUE_TYPE(
+        data_reduction_proxy::switches::kEnableDataReductionProxyAlt)
+  },
 #endif
   {
     "enable-experimental-hotwording",
@@ -1926,14 +1969,6 @@
     SINGLE_VALUE_TYPE(chromeos::switches::kWakeOnPackets)
   },
 #endif  // OS_CHROMEOS
-  {
-    "enable-data-reduction-proxy-alt",
-    IDS_FLAGS_ENABLE_DATA_REDUCTION_PROXY_ALTERNATIVE_NAME,
-    IDS_FLAGS_ENABLE_DATA_REDUCTION_PROXY_ALTERNATIVE_DESCRIPTION,
-    kOsAndroid,
-    SINGLE_VALUE_TYPE(data_reduction_proxy::switches::
-                          kEnableDataReductionProxyAlt)
-  },
 #if defined(USE_AURA)
   {
     "enable-tab-audio-muting",
@@ -2102,6 +2137,11 @@
       chrome::VersionInfo::GetChannel() != chrome::VersionInfo::CHANNEL_DEV) {
     return true;
   }
+  // enable-data-reduction-proxy-alt is only available for the Dev channel.
+  if (!strcmp("enable-data-reduction-proxy-alt", experiment.internal_name) &&
+      chrome::VersionInfo::GetChannel() != chrome::VersionInfo::CHANNEL_DEV) {
+    return true;
+  }
 #endif
 
   return false;
diff --git a/chrome/browser/android/activity_type_id_list.h b/chrome/browser/android/activity_type_id_list.h
deleted file mode 100644
index 805e15e..0000000
--- a/chrome/browser/android/activity_type_id_list.h
+++ /dev/null
@@ -1,19 +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.
-
-// Intentionally no include guards because this file is meant to be included
-// inside a macro to generate enum values.
-
-// Define Activities we are interested in tracking.  IDs are assigned
-// consecutively, from NONE to MAX_VALUE.  Activities that are not explicitly
-// defined are all assigned the UNKNOWN value.  When adding new ones, make sure
-// to append them after current Activities and to update the |AndroidActivityId|
-// enum in |histograms.xml|.
-DEFINE_ACTIVITY_ID(NONE, 0)
-DEFINE_ACTIVITY_ID(UNKNOWN, 1)
-DEFINE_ACTIVITY_ID(MAIN, 2)
-DEFINE_ACTIVITY_ID(PREFERENCES, 3)
-DEFINE_ACTIVITY_ID(WEBAPPACTIVITY, 4)
-DEFINE_ACTIVITY_ID(FULLSCREENACTIVITY, 5)
-DEFINE_ACTIVITY_ID(MAX_VALUE, 6)
diff --git a/chrome/browser/android/activity_type_ids.h b/chrome/browser/android/activity_type_ids.h
index 606f875..eb478db 100644
--- a/chrome/browser/android/activity_type_ids.h
+++ b/chrome/browser/android/activity_type_ids.h
@@ -9,11 +9,25 @@
 
 namespace ActivityTypeIds {
 
+// Define Activities we are interested in tracking.  IDs are assigned
+// consecutively, from NONE to MAX_VALUE.  Activities that are not explicitly
+// defined are all assigned the UNKNOWN value.  When adding new ones, make sure
+// to append them after current Activities and to update the |AndroidActivityId|
+// enum in |histograms.xml|.
+//
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser
+// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ActivityTypeIds
+// GENERATED_JAVA_PREFIX_TO_STRIP: ACTIVITY_
 enum Type {
-#define DEFINE_ACTIVITY_ID(id,value) ACTIVITY_##id = (value),
-#include "activity_type_id_list.h"
-#undef DEFINE_ACTIVITY_ID
-};  // enum Type
+  ACTIVITY_NONE = 0,
+  ACTIVITY_UNKNOWN = 1,
+  ACTIVITY_MAIN = 2,
+  ACTIVITY_PREFERENCES = 3,
+  ACTIVITY_WEBAPPACTIVITY = 4,
+  ACTIVITY_FULLSCREENACTIVITY = 5,
+  ACTIVITY_MAX_VALUE = 6
+};
 
 // Takes an int corresponding to a Type and returns the corresponding Type.
 Type GetActivityType(int type_id);
diff --git a/chrome/browser/android/bookmarks/bookmarks_bridge.cc b/chrome/browser/android/bookmarks/bookmarks_bridge.cc
index eee1264..17d5377 100644
--- a/chrome/browser/android/bookmarks/bookmarks_bridge.cc
+++ b/chrome/browser/android/bookmarks/bookmarks_bridge.cc
@@ -420,7 +420,7 @@
         env,
         j_result_obj,
         partner_bookmarks_shim_->GetPartnerBookmarksRoot()->id(),
-        BookmarkType::PARTNER);
+        BookmarkType::BOOKMARK_TYPE_PARTNER);
   }
 }
 
@@ -738,7 +738,7 @@
 
 const BookmarkNode* BookmarksBridge::GetNodeByID(long node_id, int type) {
   const BookmarkNode* node;
-  if (type == BookmarkType::PARTNER) {
+  if (type == BookmarkType::BOOKMARK_TYPE_PARTNER) {
     node = partner_bookmarks_shim_->GetNodeByID(
         static_cast<int64>(node_id));
   } else {
@@ -788,9 +788,9 @@
 
 int BookmarksBridge::GetBookmarkType(const BookmarkNode* node) {
   if (partner_bookmarks_shim_->IsPartnerBookmark(node))
-    return BookmarkType::PARTNER;
+    return BookmarkType::BOOKMARK_TYPE_PARTNER;
   else
-    return BookmarkType::NORMAL;
+    return BookmarkType::BOOKMARK_TYPE_NORMAL;
 }
 
 base::string16 BookmarksBridge::GetTitle(const BookmarkNode* node) const {
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
index 095bbe7..acf48d8 100644
--- a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
+++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
@@ -64,7 +64,7 @@
     profile_->CreateBookmarkModel(true);
 
     model_ = BookmarkModelFactory::GetForProfile(profile_.get());
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
   }
 
   virtual void TearDown() override {
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index e67db78..982f1ca 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -29,6 +29,7 @@
 #include "chrome/browser/android/omnibox/autocomplete_controller_android.h"
 #include "chrome/browser/android/omnibox/omnibox_prerender.h"
 #include "chrome/browser/android/password_ui_view_android.h"
+#include "chrome/browser/android/preferences/pref_service_bridge.h"
 #include "chrome/browser/android/profiles/profile_downloader_android.h"
 #include "chrome/browser/android/provider/chrome_browser_provider.h"
 #include "chrome/browser/android/recently_closed_tabs_bridge.h"
@@ -69,7 +70,6 @@
 #include "chrome/browser/ui/android/navigation_popup.h"
 #include "chrome/browser/ui/android/omnibox/omnibox_view_util.h"
 #include "chrome/browser/ui/android/ssl_client_certificate_request.h"
-#include "chrome/browser/ui/android/tab_model/tab_model_base.h"
 #include "chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h"
 #include "chrome/browser/ui/android/toolbar/toolbar_model_android.h"
 #include "chrome/browser/ui/android/website_settings_popup_android.h"
@@ -170,6 +170,7 @@
     PasswordUIViewAndroid::RegisterPasswordUIViewAndroid },
   { "PersonalDataManagerAndroid",
     autofill::PersonalDataManagerAndroid::Register },
+  { "PrefServiceBridge", RegisterPrefServiceBridge },
   { "ProfileAndroid", ProfileAndroid::RegisterProfileAndroid },
   { "ProfileDownloaderAndroid", ProfileDownloaderAndroid::Register },
   { "ProfileSyncService", ProfileSyncServiceAndroid::Register },
@@ -179,7 +180,6 @@
   { "SSLClientCertificateRequest", RegisterSSLClientCertificateRequestAndroid },
   { "StartupMetricUtils", RegisterStartupMetricUtils },
   { "TabAndroid", TabAndroid::RegisterTabAndroid },
-  { "TabModelBase", RegisterTabModelBase},
   { "TabModelJniBridge", TabModelJniBridge::Register},
   { "TemplateUrlServiceAndroid", TemplateUrlServiceAndroid::Register },
   { "ToolbarModelAndroid", ToolbarModelAndroid::RegisterToolbarModelAndroid },
diff --git a/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.cc b/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.cc
index 7cc408b7..0f7f638 100644
--- a/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.cc
+++ b/chrome/browser/android/enhanced_bookmarks/enhanced_bookmarks_bridge.cc
@@ -43,7 +43,7 @@
 ScopedJavaLocalRef<jstring> EnhancedBookmarksBridge::GetBookmarkDescription(
     JNIEnv* env, jobject obj, jlong id, jint type) {
   DCHECK(bookmark_model_->loaded());
-  DCHECK_EQ(type, BookmarkType::NORMAL);
+  DCHECK_EQ(BookmarkType::BOOKMARK_TYPE_NORMAL, type);
 
   const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(
       bookmark_model_, static_cast<int64>(id));
@@ -60,7 +60,7 @@
                                                      jint type,
                                                      jstring description) {
   DCHECK(bookmark_model_->loaded());
-  DCHECK_EQ(type, BookmarkType::NORMAL);
+  DCHECK_EQ(type, BookmarkType::BOOKMARK_TYPE_NORMAL);
 
   const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(
       bookmark_model_, static_cast<int64>(id));
diff --git a/chrome/browser/android/preferences/pref_service_bridge.cc b/chrome/browser/android/preferences/pref_service_bridge.cc
new file mode 100644
index 0000000..98c420c
--- /dev/null
+++ b/chrome/browser/android/preferences/pref_service_bridge.cc
@@ -0,0 +1,694 @@
+// 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/android/preferences/pref_service_bridge.h"
+
+#include <jni.h>
+
+#include "base/android/build_info.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/android/jni_weak_ref.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browsing_data/browsing_data_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/net/prediction_options.h"
+#include "chrome/browser/prefs/incognito_mode_prefs.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/translate/chrome_translate_client.h"
+#include "chrome/browser/ui/android/android_about_app_info.h"
+#include "chrome/common/chrome_version_info.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/grit/locale_settings.h"
+#include "components/content_settings/core/common/content_settings.h"
+#include "components/content_settings/core/common/content_settings_pattern.h"
+#include "components/password_manager/core/common/password_manager_pref_names.h"
+#include "components/translate/core/browser/translate_prefs.h"
+#include "components/translate/core/common/translate_pref_names.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/user_agent.h"
+#include "jni/PrefServiceBridge_jni.h"
+#include "ui/base/l10n/l10n_util.h"
+
+using base::android::AttachCurrentThread;
+using base::android::CheckException;
+using base::android::ConvertJavaStringToUTF8;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::ScopedJavaLocalRef;
+using content::BrowserThread;
+
+namespace {
+
+enum NetworkPredictionOptions {
+  NETWORK_PREDICTION_ALWAYS,
+  NETWORK_PREDICTION_WIFI_ONLY,
+  NETWORK_PREDICTION_NEVER,
+};
+
+Profile* GetOriginalProfile() {
+  return ProfileManager::GetActiveUserProfile()->GetOriginalProfile();
+}
+
+bool GetBooleanForContentSetting(HostContentSettingsMap* content_settings,
+                                 ContentSettingsType type) {
+  switch (content_settings->GetDefaultContentSetting(type, NULL)) {
+    case CONTENT_SETTING_BLOCK:
+      return false;
+    case CONTENT_SETTING_ALLOW:
+      return true;
+    case CONTENT_SETTING_ASK:
+    default:
+      return true;
+  }
+}
+
+std::string GetStringForContentSettingsType(
+    ContentSetting content_setting) {
+  switch (content_setting) {
+    case CONTENT_SETTING_BLOCK:
+      return "block";
+    case CONTENT_SETTING_ALLOW:
+      return "allow";
+    case CONTENT_SETTING_ASK:
+      return "ask";
+    case CONTENT_SETTING_SESSION_ONLY:
+      return "session";
+    case CONTENT_SETTING_NUM_SETTINGS:
+      return "num_settings";
+    case CONTENT_SETTING_DEFAULT:
+    default:
+      return "default";
+  }
+}
+
+bool IsContentSettingManaged(HostContentSettingsMap* content_settings,
+                             ContentSettingsType content_settings_type) {
+  std::string source;
+  content_settings->GetDefaultContentSetting(content_settings_type, &source);
+  HostContentSettingsMap::ProviderType provider =
+      content_settings->GetProviderTypeFromSource(source);
+  return provider == HostContentSettingsMap::POLICY_PROVIDER;
+}
+
+void ReturnAbsoluteProfilePathValue(std::string path_value) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jstring> j_path_value =
+      ConvertUTF8ToJavaString(env, path_value);
+  Java_PrefServiceBridge_setProfilePathValue(env, j_path_value.obj());
+}
+
+void GetAbsolutePath(Profile* profile) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+  if (profile) {
+    base::FilePath profile_path = profile->GetPath();
+    profile_path = base::MakeAbsoluteFilePath(profile_path);
+    if (!profile_path.empty()) {
+      BrowserThread::PostTask(
+          BrowserThread::UI, FROM_HERE,
+          base::Bind(&ReturnAbsoluteProfilePathValue, profile_path.value()));
+    }
+  }
+}
+
+PrefService* GetPrefService() {
+  return GetOriginalProfile()->GetPrefs();
+}
+
+static void EnsureConsistentGeolocationPreferences(Profile* profile) {
+  // On Android, we use the kGeolocationEnabled flag to control geolocation on a
+  // global basis, rather than the default geolocation host content setting,
+  // which is only used if no previously stored more specific host exception
+  // cannot be found.
+  //
+  // On Android, there is currently no UI to change this default setting, so it
+  // needs to default to ASK. Additionally, for users that have previously set
+  // the default to BLOCK, we set the preference to disable geolocation
+  // globally.
+
+  ContentSetting defaultSetting = profile->GetHostContentSettingsMap()->
+      GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION, NULL);
+
+  if (defaultSetting == CONTENT_SETTING_ASK)
+    return;
+
+  profile->GetHostContentSettingsMap()->SetDefaultContentSetting(
+      CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_ASK);
+
+  if (defaultSetting == CONTENT_SETTING_BLOCK) {
+    profile->GetPrefs()->SetBoolean(prefs::kGeolocationEnabled, false);
+  }
+}
+
+static void EnsureConsistentProtectedMediaIdentifierPreferences(
+    Profile* profile) {
+  // We use the kProtectedMediaIdentifierEnabled flag to control protected media
+  // identifier on a global basis.
+  //
+  // On Android, there is currently no UI to change this default setting, so it
+  // needs to default to ASK. Additionally, for users that have previously set
+  // the default to BLOCK, we set the preference to disable protected media
+  // identifier globally.
+  ContentSetting defaultSetting =
+      profile->GetHostContentSettingsMap()->
+      GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
+                               NULL);
+
+  if (defaultSetting == CONTENT_SETTING_ASK)
+    return;
+
+  profile->GetHostContentSettingsMap()->SetDefaultContentSetting(
+      CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, CONTENT_SETTING_ASK);
+
+  if (defaultSetting == CONTENT_SETTING_BLOCK) {
+    profile->GetPrefs()->SetBoolean(prefs::kProtectedMediaIdentifierEnabled,
+                                    false);
+  }
+}
+
+}  // namespace
+
+// ----------------------------------------------------------------------------
+// Native JNI methods
+// ----------------------------------------------------------------------------
+
+static jboolean GetAcceptCookiesEnabled(JNIEnv* env, jobject obj) {
+  return GetBooleanForContentSetting(
+      GetOriginalProfile()->GetHostContentSettingsMap(),
+      CONTENT_SETTINGS_TYPE_COOKIES);
+}
+
+static jboolean GetAcceptCookiesManaged(JNIEnv* env, jobject obj) {
+  return IsContentSettingManaged(
+      GetOriginalProfile()->GetHostContentSettingsMap(),
+      CONTENT_SETTINGS_TYPE_COOKIES);
+}
+
+static jboolean GetRememberPasswordsEnabled(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetBoolean(
+      password_manager::prefs::kPasswordManagerSavingEnabled);
+}
+
+static jboolean GetRememberPasswordsManaged(JNIEnv* env, jobject obj) {
+  return GetPrefService()->IsManagedPreference(
+      password_manager::prefs::kPasswordManagerSavingEnabled);
+}
+
+static jboolean GetDoNotTrackEnabled(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetBoolean(prefs::kEnableDoNotTrack);
+}
+
+static jint GetNetworkPredictionOptions(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetInteger(prefs::kNetworkPredictionOptions);
+}
+
+static jboolean GetNetworkPredictionManaged(JNIEnv* env, jobject obj) {
+  return GetPrefService()->IsManagedPreference(
+      prefs::kNetworkPredictionOptions);
+}
+
+static jboolean GetPasswordEchoEnabled(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetBoolean(prefs::kWebKitPasswordEchoEnabled);
+}
+
+static jboolean GetPrintingEnabled(JNIEnv* env, jobject obj) {
+  return GetPrefService()->IsManagedPreference(prefs::kPrintingEnabled);
+}
+
+static jboolean GetTranslateEnabled(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetBoolean(prefs::kEnableTranslate);
+}
+
+static jboolean GetTranslateManaged(JNIEnv* env, jobject obj) {
+  return GetPrefService()->IsManagedPreference(prefs::kEnableTranslate);
+}
+
+static jboolean GetSearchSuggestEnabled(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetBoolean(prefs::kSearchSuggestEnabled);
+}
+
+static jboolean GetSearchSuggestManaged(JNIEnv* env, jobject obj) {
+  return GetPrefService()->IsManagedPreference(prefs::kSearchSuggestEnabled);
+}
+
+static jboolean GetProtectedMediaIdentifierEnabled(JNIEnv* env, jobject obj) {
+  Profile* profile = GetOriginalProfile();
+  EnsureConsistentProtectedMediaIdentifierPreferences(profile);
+  return GetPrefService()->GetBoolean(prefs::kProtectedMediaIdentifierEnabled);
+}
+
+static jboolean GetAllowLocationEnabled(JNIEnv* env, jobject obj) {
+  Profile* profile = GetOriginalProfile();
+  EnsureConsistentGeolocationPreferences(profile);
+  return GetPrefService()->GetBoolean(prefs::kGeolocationEnabled);
+}
+
+static jboolean GetAllowLocationManaged(JNIEnv* env, jobject obj) {
+  return IsContentSettingManaged(
+      GetOriginalProfile()->GetHostContentSettingsMap(),
+      CONTENT_SETTINGS_TYPE_GEOLOCATION);
+}
+
+static jboolean GetResolveNavigationErrorEnabled(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetBoolean(prefs::kAlternateErrorPagesEnabled);
+}
+
+static jboolean GetResolveNavigationErrorManaged(JNIEnv* env, jobject obj) {
+  return GetPrefService()->IsManagedPreference(
+      prefs::kAlternateErrorPagesEnabled);
+}
+
+static jboolean GetCrashReportManaged(JNIEnv* env, jobject obj) {
+  return GetPrefService()->IsManagedPreference(
+      prefs::kCrashReportingEnabled);
+}
+
+static jboolean GetForceSafeSearch(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetBoolean(prefs::kForceSafeSearch);
+}
+
+static jint GetDefaultSupervisedUserFilteringBehavior(JNIEnv* env,
+                                                      jobject obj) {
+  return GetPrefService()->GetInteger(
+      prefs::kDefaultSupervisedUserFilteringBehavior);
+}
+
+static jboolean GetIncognitoModeEnabled(JNIEnv* env, jobject obj) {
+  PrefService* prefs = GetPrefService();
+  IncognitoModePrefs::Availability incognito_pref =
+      IncognitoModePrefs::GetAvailability(prefs);
+  DCHECK(incognito_pref == IncognitoModePrefs::ENABLED ||
+         incognito_pref == IncognitoModePrefs::DISABLED) <<
+             "Unsupported incognito mode preference: " << incognito_pref;
+  return incognito_pref != IncognitoModePrefs::DISABLED;
+}
+
+static jboolean GetIncognitoModeManaged(JNIEnv* env, jobject obj) {
+  return GetPrefService()->IsManagedPreference(
+      prefs::kIncognitoModeAvailability);
+}
+
+namespace {
+
+// Redirects a BrowsingDataRemover completion callback back into Java.
+class ClearBrowsingDataObserver : public BrowsingDataRemover::Observer {
+ public:
+  // |obj| is expected to be the object passed into ClearBrowsingData(); e.g. a
+  // ChromePreference.
+  ClearBrowsingDataObserver(JNIEnv* env, jobject obj)
+      : weak_chrome_native_preferences_(env, obj) {
+  }
+
+  virtual void OnBrowsingDataRemoverDone() override {
+    // Just as a BrowsingDataRemover deletes itself when done, we delete ourself
+    // when done.  No need to remove ourself as an observer given the lifetime
+    // of BrowsingDataRemover.
+    scoped_ptr<ClearBrowsingDataObserver> auto_delete(this);
+
+    JNIEnv* env = AttachCurrentThread();
+    if (weak_chrome_native_preferences_.get(env).is_null())
+      return;
+
+    Java_PrefServiceBridge_browsingDataCleared(
+        env, weak_chrome_native_preferences_.get(env).obj());
+  }
+
+ private:
+  JavaObjectWeakGlobalRef weak_chrome_native_preferences_;
+};
+}  // namespace
+
+static void ClearBrowsingData(JNIEnv* env, jobject obj, jboolean history,
+    jboolean cache, jboolean cookies_and_site_data, jboolean passwords,
+    jboolean form_data) {
+  // BrowsingDataRemover deletes itself.
+  BrowsingDataRemover* browsing_data_remover =
+      BrowsingDataRemover::CreateForPeriod(
+          GetOriginalProfile(),
+          static_cast<BrowsingDataRemover::TimePeriod>(
+              BrowsingDataRemover::EVERYTHING));
+  browsing_data_remover->AddObserver(new ClearBrowsingDataObserver(env, obj));
+
+  int remove_mask = 0;
+  if (history)
+    remove_mask |= BrowsingDataRemover::REMOVE_HISTORY;
+  if (cache)
+    remove_mask |= BrowsingDataRemover::REMOVE_CACHE;
+  if (cookies_and_site_data) {
+    remove_mask |= BrowsingDataRemover::REMOVE_COOKIES;
+    remove_mask |= BrowsingDataRemover::REMOVE_SITE_DATA;
+  }
+  if (passwords)
+    remove_mask |= BrowsingDataRemover::REMOVE_PASSWORDS;
+  if (form_data)
+    remove_mask |= BrowsingDataRemover::REMOVE_FORM_DATA;
+  browsing_data_remover->Remove(remove_mask,
+                                BrowsingDataHelper::UNPROTECTED_WEB);
+}
+
+static jboolean GetAllowCookiesEnabled(JNIEnv* env, jobject obj) {
+  HostContentSettingsMap* content_settings =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  return GetBooleanForContentSetting(
+      content_settings, CONTENT_SETTINGS_TYPE_COOKIES);
+}
+
+static void SetAllowCookiesEnabled(JNIEnv* env, jobject obj, jboolean allow) {
+  HostContentSettingsMap* host_content_settings_map =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  host_content_settings_map->SetDefaultContentSetting(
+      CONTENT_SETTINGS_TYPE_COOKIES,
+      allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
+}
+
+static void SetRememberPasswordsEnabled(JNIEnv* env, jobject obj,
+                                        jboolean allow) {
+  GetPrefService()->SetBoolean(
+      password_manager::prefs::kPasswordManagerSavingEnabled, allow);
+}
+
+static void SetProtectedMediaIdentifierEnabled(JNIEnv* env,
+                                               jobject obj,
+                                               jboolean is_enabled) {
+  GetPrefService()->SetBoolean(prefs::kProtectedMediaIdentifierEnabled,
+                               is_enabled);
+}
+
+static void SetAllowLocationEnabled(JNIEnv* env, jobject obj, jboolean allow) {
+  GetPrefService()->SetBoolean(prefs::kGeolocationEnabled, allow);
+}
+
+static void SetCrashReporting(JNIEnv* env, jobject obj, jboolean reporting) {
+  PrefService* local_state = g_browser_process->local_state();
+  local_state->SetBoolean(prefs::kCrashReportingEnabled, reporting);
+}
+
+static jboolean CanPredictNetworkActions(JNIEnv* env, jobject obj) {
+  return chrome_browser_net::CanPrefetchAndPrerenderUI(GetPrefService());
+}
+
+static void SetDoNotTrackEnabled(JNIEnv* env, jobject obj, jboolean allow) {
+  GetPrefService()->SetBoolean(prefs::kEnableDoNotTrack, allow);
+}
+
+static jstring GetSyncLastAccountName(JNIEnv* env, jobject obj) {
+  return ConvertUTF8ToJavaString(
+      env, GetPrefService()->GetString(prefs::kGoogleServicesLastUsername))
+      .Release();
+}
+
+static void SetTranslateEnabled(JNIEnv* env, jobject obj, jboolean enabled) {
+  GetPrefService()->SetBoolean(prefs::kEnableTranslate, enabled);
+}
+
+static void ResetTranslateDefaults(JNIEnv* env, jobject obj) {
+  scoped_ptr<translate::TranslatePrefs> translate_prefs =
+      ChromeTranslateClient::CreateTranslatePrefs(GetPrefService());
+  translate_prefs->ResetToDefaults();
+}
+
+static jboolean GetJavaScriptManaged(JNIEnv* env, jobject obj) {
+  HostContentSettingsMap* content_settings =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  return IsContentSettingManaged(
+      content_settings, CONTENT_SETTINGS_TYPE_JAVASCRIPT);
+}
+
+static void SetJavaScriptEnabled(JNIEnv* env, jobject obj, jboolean enabled) {
+  GetPrefService()->SetBoolean(prefs::kWebKitJavascriptEnabled, enabled);
+}
+
+static jboolean GetJavaScriptEnabled(JNIEnv* env, jobject obj) {
+  // The user pref for Javascript is stored in kWebKitJavascriptEnabled for
+  // historical reasons, but the content setting is where a possibly managed
+  // value will be enforced.
+  HostContentSettingsMap* content_settings =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+
+  jboolean javascript_enabled = GetBooleanForContentSetting(
+      content_settings, CONTENT_SETTINGS_TYPE_JAVASCRIPT);
+  if (!GetJavaScriptManaged(env, obj)) {
+    javascript_enabled &= GetPrefService()->GetBoolean(
+        prefs::kWebKitJavascriptEnabled);
+  }
+  return javascript_enabled;
+}
+
+static void SetPasswordEchoEnabled(JNIEnv* env,
+                                   jobject obj,
+                                   jboolean passwordEchoEnabled) {
+  GetPrefService()->SetBoolean(prefs::kWebKitPasswordEchoEnabled,
+                               passwordEchoEnabled);
+}
+
+static jboolean GetAllowPopupsEnabled(JNIEnv* env, jobject obj) {
+  HostContentSettingsMap* content_settings =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  return GetBooleanForContentSetting(content_settings,
+      CONTENT_SETTINGS_TYPE_POPUPS);
+}
+
+static jboolean GetAllowPopupsManaged(JNIEnv* env, jobject obj) {
+  HostContentSettingsMap* content_settings =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  return IsContentSettingManaged(content_settings,
+                                 CONTENT_SETTINGS_TYPE_POPUPS);
+}
+
+static void SetAllowPopupsEnabled(JNIEnv* env, jobject obj, jboolean allow) {
+  HostContentSettingsMap* host_content_settings_map =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  host_content_settings_map->SetDefaultContentSetting(
+      CONTENT_SETTINGS_TYPE_POPUPS,
+      allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
+}
+
+static jboolean GetAutologinEnabled(JNIEnv* env, jobject obj) {
+  return GetPrefService()->GetBoolean(prefs::kAutologinEnabled);
+}
+
+static void SetAutologinEnabled(JNIEnv* env, jobject obj,
+                                jboolean autologinEnabled) {
+  GetPrefService()->SetBoolean(prefs::kAutologinEnabled, autologinEnabled);
+}
+
+static void SetPopupException(JNIEnv* env, jobject obj, jstring pattern,
+                              jboolean allow) {
+  HostContentSettingsMap* host_content_settings_map =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  host_content_settings_map->SetContentSetting(
+      ContentSettingsPattern::FromString(ConvertJavaStringToUTF8(env, pattern)),
+      ContentSettingsPattern::Wildcard(),
+      CONTENT_SETTINGS_TYPE_POPUPS,
+      "",
+      allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
+}
+
+static void RemovePopupException(JNIEnv* env, jobject obj, jstring pattern) {
+  HostContentSettingsMap* host_content_settings_map =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  host_content_settings_map->SetContentSetting(
+      ContentSettingsPattern::FromString(ConvertJavaStringToUTF8(env, pattern)),
+      ContentSettingsPattern::Wildcard(),
+      CONTENT_SETTINGS_TYPE_POPUPS,
+      "",
+      CONTENT_SETTING_DEFAULT);
+}
+
+static void GetPopupExceptions(JNIEnv* env, jobject obj, jobject list) {
+  HostContentSettingsMap* host_content_settings_map =
+      GetOriginalProfile()->GetHostContentSettingsMap();
+  ContentSettingsForOneType entries;
+  host_content_settings_map->GetSettingsForOneType(
+      CONTENT_SETTINGS_TYPE_POPUPS, "", &entries);
+  for (size_t i = 0; i < entries.size(); ++i) {
+    Java_PrefServiceBridge_insertPopupExceptionToList(
+        env, list,
+        ConvertUTF8ToJavaString(
+            env, entries[i].primary_pattern.ToString()).obj(),
+        ConvertUTF8ToJavaString(
+            env, GetStringForContentSettingsType(entries[i].setting)).obj(),
+        ConvertUTF8ToJavaString(env, entries[i].source).obj());
+  }
+}
+
+static void SetSearchSuggestEnabled(JNIEnv* env, jobject obj,
+                                    jboolean enabled) {
+  GetPrefService()->SetBoolean(prefs::kSearchSuggestEnabled, enabled);
+}
+
+static jstring GetContextualSearchPreference(JNIEnv* env, jobject obj) {
+  return ConvertUTF8ToJavaString(
+      env, GetPrefService()->GetString(prefs::kContextualSearchEnabled)).
+          Release();
+}
+
+static void SetContextualSearchPreference(JNIEnv* env, jobject obj,
+                                          jstring pref) {
+  GetPrefService()->SetString(prefs::kContextualSearchEnabled,
+      ConvertJavaStringToUTF8(env, pref));
+}
+
+static void SetNetworkPredictionOptions(JNIEnv* env, jobject obj, int option) {
+  GetPrefService()->SetInteger(prefs::kNetworkPredictionOptions, option);
+}
+
+static jboolean NetworkPredictionEnabledHasUserSetting(JNIEnv* env,
+                                                       jobject obj) {
+  return GetPrefService()->GetUserPrefValue(
+      prefs::kNetworkPredictionEnabled) != NULL;
+}
+
+static jboolean NetworkPredictionOptionsHasUserSetting(JNIEnv* env,
+                                                       jobject obj) {
+  return GetPrefService()->GetUserPrefValue(
+      prefs::kNetworkPredictionOptions) != NULL;
+}
+
+static jboolean GetNetworkPredictionEnabledUserPrefValue(JNIEnv* env,
+                                                         jobject obj) {
+  const base::Value* network_prediction_enabled =
+      GetPrefService()->GetUserPrefValue(prefs::kNetworkPredictionEnabled);
+  DCHECK(network_prediction_enabled);
+  bool value = false;
+  DCHECK(network_prediction_enabled->GetAsBoolean(&value));
+  return value;
+}
+
+static void SetResolveNavigationErrorEnabled(JNIEnv* env, jobject obj,
+                                             jboolean enabled) {
+  GetPrefService()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled);
+}
+
+static jboolean GetFirstRunEulaAccepted(JNIEnv* env, jobject obj) {
+  return g_browser_process->local_state()->GetBoolean(prefs::kEulaAccepted);
+}
+
+static void SetEulaAccepted(JNIEnv* env, jobject obj) {
+  g_browser_process->local_state()->SetBoolean(prefs::kEulaAccepted, true);
+}
+
+static void ResetAcceptLanguages(JNIEnv* env,
+                                 jobject obj,
+                                 jstring default_locale) {
+  std::string accept_languages(l10n_util::GetStringUTF8(IDS_ACCEPT_LANGUAGES));
+  std::string locale_string(ConvertJavaStringToUTF8(env, default_locale));
+
+  PrependToAcceptLanguagesIfNecessary(locale_string, &accept_languages);
+  GetPrefService()->SetString(prefs::kAcceptLanguages, accept_languages);
+}
+
+void PrependToAcceptLanguagesIfNecessary(std::string locale,
+                                         std::string* accept_languages) {
+  if (locale.size() != 5u || locale[2] != '_')  // not well-formed
+    return;
+
+  std::string language(locale.substr(0, 2));
+  std::string region(locale.substr(3, 2));
+
+  // Java mostly follows ISO-639-1 and ICU, except for the following three.
+  // See documentation on java.util.Locale constructor for more.
+  if (language == "iw") {
+    language = "he";
+  } else if (language == "ji") {
+    language = "yi";
+  } else if (language == "in") {
+    language = "id";
+  }
+
+  std::string language_region(language + "-" + region);
+
+  if (accept_languages->find(language_region) == std::string::npos) {
+    std::vector<std::string> parts;
+    parts.push_back(language_region);
+    // If language is not in the accept languages list, also add language code.
+    if (accept_languages->find(language + ",") == std::string::npos &&
+        !std::equal(language.rbegin(), language.rend(),
+                    accept_languages->rbegin()))
+      parts.push_back(language);
+    parts.push_back(*accept_languages);
+    *accept_languages = JoinString(parts, ',');
+  }
+}
+
+// Sends all information about the different versions to Java.
+// From browser_about_handler.cc
+static jobject GetAboutVersionStrings(JNIEnv* env, jobject obj) {
+  chrome::VersionInfo version_info;
+  std::string os_version = version_info.OSType();
+  os_version += " " + AndroidAboutAppInfo::GetOsInfo();
+
+  base::android::BuildInfo* android_build_info =
+        base::android::BuildInfo::GetInstance();
+  std::string application(android_build_info->package_label());
+  application.append(" ");
+  application.append(version_info.Version());
+
+  // OK to release, returning to Java.
+  return Java_PrefServiceBridge_createAboutVersionStrings(
+      env,
+      ConvertUTF8ToJavaString(env, application).obj(),
+      ConvertUTF8ToJavaString(env, content::GetWebKitVersion()).obj(),
+      ConvertUTF8ToJavaString(
+          env, AndroidAboutAppInfo::GetJavaScriptVersion()).obj(),
+      ConvertUTF8ToJavaString(env, os_version).obj()).Release();
+}
+
+static void SetPathValuesForAboutChrome(JNIEnv* env, jobject obj) {
+  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+                          base::Bind(&GetAbsolutePath, GetOriginalProfile()));
+}
+
+static jstring GetSupervisedUserCustodianName(JNIEnv* env, jobject obj) {
+  return ConvertUTF8ToJavaString(
+      env, GetPrefService()->GetString(prefs::kSupervisedUserCustodianName))
+      .Release();
+}
+
+static jstring GetSupervisedUserCustodianEmail(JNIEnv* env, jobject obj) {
+  return ConvertUTF8ToJavaString(
+      env, GetPrefService()->GetString(prefs::kSupervisedUserCustodianEmail))
+      .Release();
+}
+
+static jstring GetSupervisedUserCustodianProfileImageURL(JNIEnv* env,
+                                                         jobject obj) {
+  return ConvertUTF8ToJavaString(
+      env,
+      GetPrefService()->GetString(
+          prefs::kSupervisedUserCustodianProfileImageURL)).Release();
+}
+
+static jstring GetSupervisedUserSecondCustodianName(JNIEnv* env, jobject obj) {
+  return ConvertUTF8ToJavaString(
+      env,
+      GetPrefService()->GetString(prefs::kSupervisedUserSecondCustodianName))
+      .Release();
+}
+
+static jstring GetSupervisedUserSecondCustodianEmail(JNIEnv* env, jobject obj) {
+  return ConvertUTF8ToJavaString(
+      env,
+      GetPrefService()->GetString(prefs::kSupervisedUserSecondCustodianEmail))
+      .Release();
+}
+
+static jstring GetSupervisedUserSecondCustodianProfileImageURL(JNIEnv* env,
+                                                               jobject obj) {
+  return ConvertUTF8ToJavaString(
+      env,
+      GetPrefService()->GetString(
+          prefs::kSupervisedUserSecondCustodianProfileImageURL)).Release();
+}
+
+bool RegisterPrefServiceBridge(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
diff --git a/chrome/browser/android/preferences/pref_service_bridge.h b/chrome/browser/android/preferences/pref_service_bridge.h
new file mode 100644
index 0000000..af056061
--- /dev/null
+++ b/chrome/browser/android/preferences/pref_service_bridge.h
@@ -0,0 +1,20 @@
+// 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_ANDROID_PREFERENCES_PREF_SERVICE_BRIDGE_H_
+#define CHROME_BROWSER_ANDROID_PREFERENCES_PREF_SERVICE_BRIDGE_H_
+
+#include <jni.h>
+#include <string>
+
+bool RegisterPrefServiceBridge(JNIEnv* env);
+
+// Use |locale| to create a language-region pair and language code to prepend to
+// the default accept languages. For Malay, we'll end up creating
+// "ms-MY,ms,en-US,en", and for Swiss-German, we will have
+// "de-CH,de-DE,de,en-US,en".
+void PrependToAcceptLanguagesIfNecessary(std::string locale,
+                                         std::string* accept_languages);
+
+#endif  // CHROME_BROWSER_ANDROID_PREFERENCES_PREF_SERVICE_BRIDGE_H_
diff --git a/chrome/browser/android/preferences/pref_service_bridge_unittest.cc b/chrome/browser/android/preferences/pref_service_bridge_unittest.cc
new file mode 100644
index 0000000..e73e7ee
--- /dev/null
+++ b/chrome/browser/android/preferences/pref_service_bridge_unittest.cc
@@ -0,0 +1,48 @@
+// 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/android/preferences/pref_service_bridge.h"
+
+#include <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+
+// A test class for PrefServiceBridge class.
+class PrefServiceBridgeTest : public testing::Test {
+ public:
+  std::string GetAcceptLanguages(std::string locale,
+                                 std::string accept_languages) {
+    PrependToAcceptLanguagesIfNecessary(locale, &accept_languages);
+    return accept_languages;
+  }
+};
+
+TEST_F(PrefServiceBridgeTest, PrependToAcceptLanguagesAsNecessary) {
+  EXPECT_EQ("ms-MY,ms,en-US,en", GetAcceptLanguages("ms_MY", "en-US,en"));
+
+  EXPECT_EQ("de-CH,de-DE,de,en-US,en",
+      GetAcceptLanguages("de_CH", "de-DE,de,en-US,en"));
+
+  // Make sure we do not prepend language code even when a language code is at
+  // the end.
+  EXPECT_EQ("zh-TW,zh-CN,zh", GetAcceptLanguages("zh_TW", "zh-CN,zh"));
+}
+
+TEST_F(PrefServiceBridgeTest,
+       ShouldNotPrependToAcceptLanguagesWhenNotNecessary) {
+  // Java has some deprecated two letter language code. For instance, "iw" is
+  // an old code that needs to be replaced by "he" which is the new code for
+  // Hebrew.
+  EXPECT_EQ("he-IL,he,en-US,en",
+      GetAcceptLanguages("iw_IL", "he-IL,he,en-US,en"));
+
+  // This logic should not affect cases where original accept language already
+  // reflects the language code in the locale.
+  EXPECT_EQ("en-US,en", GetAcceptLanguages("en_US", "en-US,en"));
+  EXPECT_EQ("zh-CN,zh", GetAcceptLanguages("zh_CN", "zh-CN,zh"));
+
+  // "ms" is not expected. No replacement takes place.
+  EXPECT_EQ("en-US,en", GetAcceptLanguages("ms", "en-US,en"));
+}
diff --git a/chrome/browser/android/shortcut_helper_unittest.cc b/chrome/browser/android/shortcut_helper_unittest.cc
index bb8098d..76e1a5e 100644
--- a/chrome/browser/android/shortcut_helper_unittest.cc
+++ b/chrome/browser/android/shortcut_helper_unittest.cc
@@ -25,7 +25,6 @@
   }
 
   // gfx::Screen implementation (only what's needed for testing).
-  virtual bool IsDIPEnabled() override { return true; }
   virtual gfx::Point GetCursorScreenPoint() override { return gfx::Point(); }
   virtual gfx::NativeWindow GetWindowUnderCursor() override { return NULL; }
   virtual gfx::NativeWindow GetWindowAtScreenPoint(
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
index 56ac1b2..2cc134a 100644
--- a/chrome/browser/android/tab_android.h
+++ b/chrome/browser/android/tab_android.h
@@ -46,10 +46,13 @@
                    public SearchTabHelperDelegate,
                    public content::NotificationObserver {
  public:
+  // A Java counterpart will be generated for this enum.
+  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser
   enum TabLoadStatus {
-#define DEFINE_TAB_LOAD_STATUS(name, value)  name = value,
-#include "chrome/browser/android/tab_load_status.h"
-#undef DEFINE_TAB_LOAD_STATUS
+    PAGE_LOAD_FAILED = 0,
+    DEFAULT_PAGE_LOAD = 1,
+    PARTIAL_PRERENDERED_PAGE_LOAD = 2,
+    FULL_PRERENDERED_PAGE_LOAD = 3,
   };
 
   // Convenience method to retrieve the Tab associated with the passed
diff --git a/chrome/browser/android/tab_load_status.h b/chrome/browser/android/tab_load_status.h
deleted file mode 100644
index 3707b75..0000000
--- a/chrome/browser/android/tab_load_status.h
+++ /dev/null
@@ -1,15 +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.
-
-// Intentionally no include guards because this file is meant to be included
-// inside a macro to generate enum values.
-
-#ifndef DEFINE_TAB_LOAD_STATUS
-#error "Please define DEFINE_TAB_LOAD_STATUS before including this file."
-#endif
-
-DEFINE_TAB_LOAD_STATUS(PAGE_LOAD_FAILED, 0)
-DEFINE_TAB_LOAD_STATUS(DEFAULT_PAGE_LOAD, 1)
-DEFINE_TAB_LOAD_STATUS(PARTIAL_PRERENDERED_PAGE_LOAD, 2)
-DEFINE_TAB_LOAD_STATUS(FULL_PRERENDERED_PAGE_LOAD, 3)
diff --git a/chrome/browser/apps/app_window_browsertest.cc b/chrome/browser/apps/app_window_browsertest.cc
index 2a1fbb2..3ea867e 100644
--- a/chrome/browser/apps/app_window_browsertest.cc
+++ b/chrome/browser/apps/app_window_browsertest.cc
@@ -143,7 +143,13 @@
   ASSERT_TRUE(RunAppWindowAPITest("testMaximize")) << message_;
 }
 
-IN_PROC_BROWSER_TEST_F(AppWindowAPITest, TestMinimize) {
+// Flakes on linux. crbug.com/424399
+#if defined(OS_LINUX)
+#define MAYBE_TestMinimize DISABLED_TestMinimize
+#else
+#define MAYBE_TestMinimize TestMinimize
+#endif
+IN_PROC_BROWSER_TEST_F(AppWindowAPITest, MAYBE_TestMinimize) {
   ASSERT_TRUE(RunAppWindowAPITest("testMinimize")) << message_;
 }
 
diff --git a/chrome/browser/apps/ephemeral_app_launcher.cc b/chrome/browser/apps/ephemeral_app_launcher.cc
index ae4b13b6..90f423f4 100644
--- a/chrome/browser/apps/ephemeral_app_launcher.cc
+++ b/chrome/browser/apps/ephemeral_app_launcher.cc
@@ -187,8 +187,7 @@
   if (web_contents())
     return make_scoped_ptr(new ExtensionInstallPrompt(web_contents()));
 
-  return make_scoped_ptr(
-      new ExtensionInstallPrompt(profile(), parent_window_, NULL));
+  return make_scoped_ptr(new ExtensionInstallPrompt(profile(), parent_window_));
 }
 
 scoped_ptr<WebstoreInstaller::Approval> EphemeralAppLauncher::CreateApproval()
diff --git a/chrome/browser/apps/shortcut_manager_factory.cc b/chrome/browser/apps/shortcut_manager_factory.cc
index 8a8cb4e..06839ce 100644
--- a/chrome/browser/apps/shortcut_manager_factory.cc
+++ b/chrome/browser/apps/shortcut_manager_factory.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/apps/shortcut_manager_factory.h"
 
+#include "base/memory/singleton.h"
 #include "chrome/browser/apps/shortcut_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
diff --git a/chrome/browser/autocomplete/history_quick_provider_unittest.cc b/chrome/browser/autocomplete/history_quick_provider_unittest.cc
index 4d9bc362..f67d0dd 100644
--- a/chrome/browser/autocomplete/history_quick_provider_unittest.cc
+++ b/chrome/browser/autocomplete/history_quick_provider_unittest.cc
@@ -184,7 +184,7 @@
   profile_.reset(new TestingProfile());
   ASSERT_TRUE(profile_->CreateHistoryService(true, false));
   profile_->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(
+  bookmarks::test::WaitForBookmarkModelToLoad(
       BookmarkModelFactory::GetForProfile(profile_.get()));
   profile_->BlockUntilHistoryIndexIsRefreshed();
   history_service_ =
diff --git a/chrome/browser/autocomplete/zero_suggest_provider.cc b/chrome/browser/autocomplete/zero_suggest_provider.cc
index 44b5dc3..efa39c39f 100644
--- a/chrome/browser/autocomplete/zero_suggest_provider.cc
+++ b/chrome/browser/autocomplete/zero_suggest_provider.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/autocomplete/history_url_provider.h"
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "components/history/core/browser/history_types.h"
 #include "components/metrics/proto/omnibox_input_type.pb.h"
@@ -31,7 +32,7 @@
 #include "components/omnibox/search_provider.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/search_engines/template_url_service.h"
-#include "components/variations/variations_http_header_provider.h"
+#include "components/variations/net/variations_http_header_provider.h"
 #include "net/base/escape.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_util.h"
@@ -116,19 +117,21 @@
   if (!suggest_url.is_valid())
     return;
 
-  // No need to send the current page URL in personalized suggest field trial.
+  // No need to send the current page URL in personalized suggest or
+  // most visited field trials.
   if (CanSendURL(input.current_url(), suggest_url, default_provider,
                  current_page_classification_,
                  template_url_service_->search_terms_data(), client_.get()) &&
-      !OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) {
+      !OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial() &&
+      !OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) {
     // Update suggest_url to include the current_page_url.
     search_term_args.current_page_url = current_query_;
     suggest_url = GURL(default_provider->suggestions_url_ref().
                        ReplaceSearchTerms(
                            search_term_args,
                            template_url_service_->search_terms_data()));
-  } else if (!CanShowZeroSuggestWithoutSendingURL(suggest_url,
-                                                  input.current_url())) {
+  } else if (!ShouldShowNonContextualZeroSuggest(suggest_url,
+                                                 input.current_url())) {
     return;
   }
 
@@ -144,6 +147,7 @@
   if (fetcher_)
     LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_INVALIDATED);
   fetcher_.reset();
+  waiting_for_most_visited_urls_request_ = false;
   done_ = true;
 
   if (clear_cached_results) {
@@ -191,6 +195,7 @@
       listener_(listener),
       profile_(profile),
       results_from_cache_(false),
+      waiting_for_most_visited_urls_request_(false),
       weak_ptr_factory_(this) {
 }
 
@@ -309,35 +314,42 @@
 }
 
 void ZeroSuggestProvider::Run(const GURL& suggest_url) {
-  const int kFetcherID = 1;
-  fetcher_.reset(
-      net::URLFetcher::Create(kFetcherID,
-          suggest_url,
-          net::URLFetcher::GET, this));
-  fetcher_->SetRequestContext(profile_->GetRequestContext());
-  fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
-  // Add Chrome experiment state to the request headers.
-  net::HttpRequestHeaders headers;
-  variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders(
-      fetcher_->GetOriginalURL(), profile_->IsOffTheRecord(), false, &headers);
-  fetcher_->SetExtraRequestHeaders(headers.ToString());
-  fetcher_->Start();
-
   if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) {
     most_visited_urls_.clear();
     history::TopSites* ts = profile_->GetTopSites();
     if (ts) {
+      waiting_for_most_visited_urls_request_ = true;
       ts->GetMostVisitedURLs(
           base::Bind(&ZeroSuggestProvider::OnMostVisitedUrlsAvailable,
                      weak_ptr_factory_.GetWeakPtr()), false);
     }
+  } else {
+    const int kFetcherID = 1;
+    fetcher_.reset(
+        net::URLFetcher::Create(kFetcherID,
+            suggest_url,
+            net::URLFetcher::GET, this));
+    fetcher_->SetRequestContext(profile_->GetRequestContext());
+    fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
+    // Add Chrome experiment state to the request headers.
+    net::HttpRequestHeaders headers;
+    variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders(
+        fetcher_->GetOriginalURL(), profile_->IsOffTheRecord(), false,
+        &headers);
+    fetcher_->SetExtraRequestHeaders(headers.ToString());
+    fetcher_->Start();
+    LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT);
   }
-  LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT);
 }
 
 void ZeroSuggestProvider::OnMostVisitedUrlsAvailable(
     const history::MostVisitedURLList& urls) {
+  if (!waiting_for_most_visited_urls_request_) return;
   most_visited_urls_ = urls;
+  waiting_for_most_visited_urls_request_ = false;
+  done_ = true;
+  ConvertResultsToAutocompleteMatches();
+  listener_->OnProviderUpdate(true);
 }
 
 void ZeroSuggestProvider::ConvertResultsToAutocompleteMatches() {
@@ -424,7 +436,7 @@
       results_.verbatim_relevance : kDefaultVerbatimZeroSuggestRelevance;
 }
 
-bool ZeroSuggestProvider::CanShowZeroSuggestWithoutSendingURL(
+bool ZeroSuggestProvider::ShouldShowNonContextualZeroSuggest(
     const GURL& suggest_url,
     const GURL& current_page_url) const {
   if (!ZeroSuggestEnabled(suggest_url,
@@ -449,6 +461,11 @@
       (current_page_url.scheme() != url::kHttpsScheme)))
     return false;
 
+  if (OmniboxFieldTrial::InZeroSuggestMostVisitedWithoutSerpFieldTrial() &&
+      template_url_service_->
+          IsSearchResultsPageFromDefaultSearchProvider(current_page_url))
+    return false;
+
   return true;
 }
 
diff --git a/chrome/browser/autocomplete/zero_suggest_provider.h b/chrome/browser/autocomplete/zero_suggest_provider.h
index aaeaa6f..6048c0c0 100644
--- a/chrome/browser/autocomplete/zero_suggest_provider.h
+++ b/chrome/browser/autocomplete/zero_suggest_provider.h
@@ -119,10 +119,11 @@
   // Returns the relevance score for the verbatim result.
   int GetVerbatimRelevance() const;
 
-  // Whether we can show zero suggest on |current_page_url| without
-  // sending |current_page_url| as a parameter to the server at |suggest_url|.
-  bool CanShowZeroSuggestWithoutSendingURL(const GURL& suggest_url,
-                                           const GURL& current_page_url) const;
+  // Whether we can show zero suggest without sending |current_page_url| to
+  // |suggest_url| search provider. Also checks that other conditions for
+  // non-contextual zero suggest are satisfied.
+  bool ShouldShowNonContextualZeroSuggest(const GURL& suggest_url,
+                                          const GURL& current_page_url) const;
 
   // Checks whether we have a set of zero suggest results cached, and if so
   // populates |matches_| with cached results.
@@ -156,6 +157,9 @@
 
   history::MostVisitedURLList most_visited_urls_;
 
+  // Whether we are waiting for a most visited visited urls callback to run.
+  bool waiting_for_most_visited_urls_request_;
+
   // For callbacks that may be run after destruction.
   base::WeakPtrFactory<ZeroSuggestProvider> weak_ptr_factory_;
 
diff --git a/chrome/browser/autocomplete/zero_suggest_provider_unittest.cc b/chrome/browser/autocomplete/zero_suggest_provider_unittest.cc
index b6574a7..92981cf 100644
--- a/chrome/browser/autocomplete/zero_suggest_provider_unittest.cc
+++ b/chrome/browser/autocomplete/zero_suggest_provider_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
 #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
+#include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
@@ -24,6 +25,93 @@
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+namespace {
+class FakeEmptyTopSites : public history::TopSites {
+ public:
+  FakeEmptyTopSites() {
+  }
+
+  // history::TopSites:
+  bool SetPageThumbnail(const GURL& url, const gfx::Image& thumbnail,
+                        const ThumbnailScore& score) override {
+    return false;
+  }
+  bool SetPageThumbnailToJPEGBytes(const GURL& url,
+                                   const base::RefCountedMemory* memory,
+                                   const ThumbnailScore& score) override {
+    return false;
+  }
+  void GetMostVisitedURLs(const GetMostVisitedURLsCallback& callback,
+                          bool include_forced_urls) override;
+  bool GetPageThumbnail(const GURL& url, bool prefix_match,
+                        scoped_refptr<base::RefCountedMemory>* bytes) override {
+    return false;
+  }
+  bool GetPageThumbnailScore(const GURL& url, ThumbnailScore* score) override {
+    return false;
+  }
+  bool GetTemporaryPageThumbnailScore(const GURL& url, ThumbnailScore* score)
+      override {
+    return false;
+  }
+  void SyncWithHistory() override {}
+  bool HasBlacklistedItems() const override {
+    return false;
+  }
+  void AddBlacklistedURL(const GURL& url) override {}
+  void RemoveBlacklistedURL(const GURL& url) override {}
+  bool IsBlacklisted(const GURL& url) override {
+    return false;
+  }
+  void ClearBlacklistedURLs() override {}
+  void Shutdown() override {}
+  base::CancelableTaskTracker::TaskId StartQueryForMostVisited() override {
+    return 0;
+  }
+  bool IsKnownURL(const GURL& url) override {
+    return false;
+  }
+  const std::string& GetCanonicalURLString(const GURL& url) const override {
+    CHECK(false);
+    return *(new std::string());
+  }
+  bool IsNonForcedFull() override {
+    return false;
+  }
+  bool IsForcedFull() override {
+    return false;
+  }
+  bool loaded() const override {
+    return false;
+  }
+  history::MostVisitedURLList GetPrepopulatePages() override {
+    return history::MostVisitedURLList();
+  }
+  bool AddForcedURL(const GURL& url, const base::Time& time) override {
+    return false;
+  }
+  // content::NotificationObserver:
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {}
+
+  // A test-specific field for controlling when most visited callback is run
+  // after top sites have been requested.
+  GetMostVisitedURLsCallback mv_callback;
+ protected:
+  virtual ~FakeEmptyTopSites() {
+  }
+};
+
+void FakeEmptyTopSites::GetMostVisitedURLs(
+    const GetMostVisitedURLsCallback& callback,
+    bool include_forced_urls)  {
+  mv_callback = callback;
+}
+
+} // namespace
+
+
 class ZeroSuggestProviderTest : public testing::Test,
                                 public AutocompleteProviderListener {
  public:
@@ -39,6 +127,7 @@
   void ResetFieldTrialList();
 
   void CreatePersonalizedFieldTrial();
+  void CreateMostVisitedFieldTrial();
 
   // Set up threads for testing; this needs to be instantiated before
   // |profile_|.
@@ -86,6 +175,8 @@
   turl_model->Add(default_t_url_);
   turl_model->SetUserSelectedDefaultSearchProvider(default_t_url_);
 
+  profile_.SetTopSites(new FakeEmptyTopSites());
+
   provider_ = ZeroSuggestProvider::Create(this, turl_model, &profile_);
 }
 
@@ -117,6 +208,91 @@
       OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
 }
 
+void ZeroSuggestProviderTest::CreateMostVisitedFieldTrial() {
+  std::map<std::string, std::string> params;
+  params[std::string(OmniboxFieldTrial::kZeroSuggestRule)] = "true";
+  params[std::string(OmniboxFieldTrial::kZeroSuggestVariantRule)] =
+      "MostVisitedWithoutSERP";
+  variations::AssociateVariationParams(
+      OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params);
+  base::FieldTrialList::CreateFieldTrial(
+      OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
+}
+
+TEST_F(ZeroSuggestProviderTest, TestMostVisitedCallback) {
+  CreateMostVisitedFieldTrial();
+
+  std::string current_url("http://www.foxnews.com/");
+  std::string input_url("http://www.cnn.com/");
+  AutocompleteInput input(base::ASCIIToUTF16(input_url), base::string16::npos,
+                          std::string(), GURL(current_url),
+                          metrics::OmniboxEventProto::OTHER, false, false,
+                          true, true,
+                          ChromeAutocompleteSchemeClassifier(&profile_));
+  history::MostVisitedURLList urls;
+  history::MostVisitedURL url(GURL("http://foo.com/"),
+                              base::ASCIIToUTF16(std::string("Foo")));
+  urls.push_back(url);
+
+  provider_->Start(input, false);
+  EXPECT_TRUE(provider_->matches().empty());
+  static_cast<FakeEmptyTopSites*>(profile_.GetTopSites())->mv_callback.Run(
+      urls);
+  // Should have verbatim match + most visited url match.
+  EXPECT_EQ(2U, provider_->matches().size());
+  provider_->Stop(false);
+
+  provider_->Start(input, false);
+  provider_->Stop(false);
+  EXPECT_TRUE(provider_->matches().empty());
+  // Most visited results arriving after Stop() has been called, ensure they
+  // are not displayed.
+  static_cast<FakeEmptyTopSites*>(profile_.GetTopSites())->mv_callback.Run(
+      urls);
+  EXPECT_TRUE(provider_->matches().empty());
+}
+
+TEST_F(ZeroSuggestProviderTest, TestMostVisitedNavigateToSearchPage) {
+  CreateMostVisitedFieldTrial();
+
+  std::string current_url("http://www.foxnews.com/");
+  std::string input_url("http://www.cnn.com/");
+  AutocompleteInput input(base::ASCIIToUTF16(input_url), base::string16::npos,
+                          std::string(), GURL(current_url),
+                          metrics::OmniboxEventProto::OTHER, false, false,
+                          true, true,
+                          ChromeAutocompleteSchemeClassifier(&profile_));
+  history::MostVisitedURLList urls;
+  history::MostVisitedURL url(GURL("http://foo.com/"),
+                              base::ASCIIToUTF16(std::string("Foo")));
+  urls.push_back(url);
+
+  provider_->Start(input, false);
+  EXPECT_TRUE(provider_->matches().empty());
+  // Stop() doesn't always get called.
+
+  std::string search_url("https://www.google.com/?q=flowers");
+  AutocompleteInput srp_input(
+      base::ASCIIToUTF16(search_url),
+      base::string16::npos,
+      std::string(),
+      GURL(search_url),
+      metrics::OmniboxEventProto::
+          SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT,
+      false,
+      false,
+      true,
+      true,
+      ChromeAutocompleteSchemeClassifier(&profile_));
+
+  provider_->Start(srp_input, false);
+  EXPECT_TRUE(provider_->matches().empty());
+  // Most visited results arriving after a new request has been started.
+  static_cast<FakeEmptyTopSites*>(profile_.GetTopSites())->mv_callback.Run(
+      urls);
+  EXPECT_TRUE(provider_->matches().empty());
+}
+
 TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestCachingFirstRun) {
   CreatePersonalizedFieldTrial();
 
@@ -124,7 +300,7 @@
   PrefService* prefs = profile_.GetPrefs();
   prefs->SetString(prefs::kZeroSuggestCachedResults, std::string());
 
-  std::string url("http://www.cnn.com");
+  std::string url("http://www.cnn.com/");
   AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos,
                           std::string(), GURL(url),
                           metrics::OmniboxEventProto::INVALID_SPEC, true, false,
@@ -154,7 +330,7 @@
 TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestHasCachedResults) {
   CreatePersonalizedFieldTrial();
 
-  std::string url("http://www.cnn.com");
+  std::string url("http://www.cnn.com/");
   AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos,
                           std::string(), GURL(url),
                           metrics::OmniboxEventProto::INVALID_SPEC, true, false,
@@ -201,7 +377,7 @@
 TEST_F(ZeroSuggestProviderTest, TestPsuggestZeroSuggestReceivedEmptyResults) {
   CreatePersonalizedFieldTrial();
 
-  std::string url("http://www.cnn.com");
+  std::string url("http://www.cnn.com/");
   AutocompleteInput input(base::ASCIIToUTF16(url), base::string16::npos,
                           std::string(), GURL(url),
                           metrics::OmniboxEventProto::INVALID_SPEC, true, false,
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc
index d12a8de..53a823c4 100644
--- a/chrome/browser/autofill/form_structure_browsertest.cc
+++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -76,24 +76,19 @@
   AutofillManager* autofill_manager = autofill_driver->autofill_manager();
   ASSERT_NE(static_cast<AutofillManager*>(NULL), autofill_manager);
   std::vector<FormStructure*> forms = autofill_manager->form_structures_.get();
-  *output = FormStructureBrowserTest::FormStructuresToString(forms);
+  *output = FormStructuresToString(forms);
 }
 
 std::string FormStructureBrowserTest::FormStructuresToString(
     const std::vector<FormStructure*>& forms) {
   std::string forms_string;
-  for (std::vector<FormStructure*>::const_iterator iter = forms.begin();
-       iter != forms.end();
-       ++iter) {
-
-    for (std::vector<AutofillField*>::const_iterator field_iter =
-            (*iter)->begin();
-         field_iter != (*iter)->end();
-         ++field_iter) {
-      forms_string += (*field_iter)->Type().ToString();
-      forms_string += " | " + base::UTF16ToUTF8((*field_iter)->name);
-      forms_string += " | " + base::UTF16ToUTF8((*field_iter)->label);
-      forms_string += " | " + base::UTF16ToUTF8((*field_iter)->value);
+  for (const FormStructure* form : forms) {
+    for (const AutofillField* field : *form) {
+      forms_string += field->Type().ToString();
+      forms_string += " | " + base::UTF16ToUTF8(field->name);
+      forms_string += " | " + base::UTF16ToUTF8(field->label);
+      forms_string += " | " + base::UTF16ToUTF8(field->value);
+      forms_string += " | " + field->section();
       forms_string += "\n";
     }
   }
diff --git a/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
index cc9da03..ec3eb52 100644
--- a/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
@@ -150,7 +150,7 @@
   profile.CreateBookmarkModel(true);
 
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(&profile);
-  test::WaitForBookmarkModelToLoad(model);
+  bookmarks::test::WaitForBookmarkModelToLoad(model);
 
   // Create test PNG representing favicon for url1.
   SkBitmap bitmap;
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client_unittest.cc b/chrome/browser/bookmarks/chrome_bookmark_client_unittest.cc
index 59a4aab..de4b23ef 100644
--- a/chrome/browser/bookmarks/chrome_bookmark_client_unittest.cc
+++ b/chrome/browser/bookmarks/chrome_bookmark_client_unittest.cc
@@ -53,7 +53,7 @@
   void ResetModel() {
     profile_.CreateBookmarkModel(false);
     model_ = BookmarkModelFactory::GetForProfile(&profile_);
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
     model_->AddObserver(&observer_);
     client_ = ChromeBookmarkClientFactory::GetForProfile(&profile_);
     DCHECK(client_);
diff --git a/chrome/browser/browser_commands_unittest.cc b/chrome/browser/browser_commands_unittest.cc
index 17d88fc..d9ca974 100644
--- a/chrome/browser/browser_commands_unittest.cc
+++ b/chrome/browser/browser_commands_unittest.cc
@@ -140,7 +140,7 @@
   profile()->CreateBookmarkModel(true);
 
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
-  test::WaitForBookmarkModelToLoad(model);
+  bookmarks::test::WaitForBookmarkModelToLoad(model);
 
   // Navigate to a url.
   GURL url1("http://foo/1");
diff --git a/chrome/browser/browser_encoding_browsertest.cc b/chrome/browser/browser_encoding_browsertest.cc
index b26d08f..f4252f91 100644
--- a/chrome/browser/browser_encoding_browsertest.cc
+++ b/chrome/browser/browser_encoding_browsertest.cc
@@ -36,11 +36,7 @@
   { "Big5.html", "Big5" },
   { "EUC-JP.html", "EUC-JP" },
   { "gb18030.html", "gb18030" },
-#if 0
-  // Disable temporarily until Blink CL
-  // (https://codereview.chromium.org/655083002/) is relanded.
   { "iso-8859-1.html", "windows-1252" },
-#endif
   { "ISO-8859-2.html", "ISO-8859-2" },
   { "ISO-8859-4.html", "ISO-8859-4" },
   { "ISO-8859-5.html", "ISO-8859-5" },
@@ -53,10 +49,7 @@
   { "KOI8-U.html", "KOI8-U" },
   { "macintosh.html", "macintosh" },
   { "Shift-JIS.html", "Shift_JIS" },
-#if 0
-  // See the above.
   { "US-ASCII.html", "windows-1252" },  // http://crbug.com/15801
-#endif
   { "UTF-8.html", "UTF-8" },
   { "UTF-16LE.html", "UTF-16LE" },
   { "windows-874.html", "windows-874" },
@@ -139,7 +132,9 @@
     base::FilePath expected_file_name = ui_test_utils::GetTestFilePath(
         base::FilePath(kTestDir), expected);
 
-    EXPECT_TRUE(base::ContentsEqual(full_file_name, expected_file_name));
+    EXPECT_TRUE(base::ContentsEqual(full_file_name, expected_file_name)) <<
+        "generated_file = " << full_file_name.AsUTF8Unsafe() <<
+        ", expected_file = " << expected_file_name.AsUTF8Unsafe();
   }
 
   void SetUpOnMainThread() override {
@@ -196,10 +191,7 @@
   ui_test_utils::NavigateToURL(browser(), url);
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-#if 0
-  // Temporarily disable until the Blink CL to use windows-1252 is relanded.
   EXPECT_EQ("windows-1252", web_contents->GetEncoding());
-#endif
 
   // Override the encoding to "gb18030".
   const std::string selected_encoding =
@@ -251,12 +243,9 @@
       { "gb18030_with_no_encoding_specified.html",
         "expected_gb18030_saved_from_no_encoding_specified.html",
         "gb18030" },
-#if 0
-      // Disable until the Blink CL to use 'windows-1252' is relanded.
       { "iso-8859-1_with_no_encoding_specified.html",
         "expected_iso-8859-1_saved_from_no_encoding_specified.html",
         "windows-1252" },
-#endif
       { "ISO-8859-5_with_no_encoding_specified.html",
         "expected_ISO-8859-5_saved_from_no_encoding_specified.html",
         "ISO-8859-5" },
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 1613d0f..17800d05 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -169,9 +169,12 @@
       <include name="IDR_HISTORY_JS" file="resources\history\history.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_OTHER_DEVICES_JS" file="resources\history\other_devices.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_IDENTITY_API_SCOPE_APPROVAL_MANIFEST" file="resources\identity_scope_approval_dialog\manifest.json" type="BINDATA" />
+      <include name="IDR_NEW_INLINE_LOGIN_HTML" file="resources\inline_login\new_inline_login.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_INLINE_LOGIN_HTML" file="resources\inline_login\inline_login.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_INLINE_LOGIN_CSS" file="resources\inline_login\inline_login.css" flattenhtml="true" type="BINDATA" />
       <include name="IDR_INLINE_LOGIN_JS" file="resources\inline_login\inline_login.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_GAIA_AUTH_AUTHENTICATOR_JS" file="resources\gaia_auth_host\authenticator.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_GAIA_AUTH_HOST_JS" file="resources\gaia_auth_host\gaia_auth_host.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_INSPECT_CSS" file="resources\inspect\inspect.css" flattenhtml="true" type="BINDATA" />
       <include name="IDR_INSPECT_HTML" file="resources\inspect\inspect.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_INSPECT_JS" file="resources\inspect\inspect.js" flattenhtml="true" type="BINDATA" />
diff --git a/chrome/browser/browsing_data/browsing_data_appcache_helper.h b/chrome/browser/browsing_data/browsing_data_appcache_helper.h
index 9df48a8da..c03c8405 100644
--- a/chrome/browser/browsing_data/browsing_data_appcache_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_appcache_helper.h
@@ -76,11 +76,11 @@
   const OriginAppCacheInfoMap& GetOriginAppCacheInfoMap() const;
 
   // BrowsingDataAppCacheHelper methods.
-  virtual void StartFetching(const base::Closure& completion_callback) override;
-  virtual void DeleteAppCacheGroup(const GURL& manifest_url) override;
+  void StartFetching(const base::Closure& completion_callback) override;
+  void DeleteAppCacheGroup(const GURL& manifest_url) override;
 
  private:
-  virtual ~CannedBrowsingDataAppCacheHelper();
+  ~CannedBrowsingDataAppCacheHelper() override;
 
   DISALLOW_COPY_AND_ASSIGN(CannedBrowsingDataAppCacheHelper);
 };
diff --git a/chrome/browser/browsing_data/browsing_data_channel_id_helper.cc b/chrome/browser/browsing_data/browsing_data_channel_id_helper.cc
index 2c83443a5..bf495b75 100644
--- a/chrome/browser/browsing_data/browsing_data_channel_id_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_channel_id_helper.cc
@@ -24,11 +24,11 @@
       net::URLRequestContextGetter* request_context);
 
   // BrowsingDataChannelIDHelper methods.
-  virtual void StartFetching(const FetchResultCallback& callback) override;
-  virtual void DeleteChannelID(const std::string& server_id) override;
+  void StartFetching(const FetchResultCallback& callback) override;
+  void DeleteChannelID(const std::string& server_id) override;
 
  private:
-  virtual ~BrowsingDataChannelIDHelperImpl();
+  ~BrowsingDataChannelIDHelperImpl() override;
 
   // Fetch the certs. This must be called in the IO thread.
   void FetchOnIOThread();
diff --git a/chrome/browser/browsing_data/browsing_data_channel_id_helper.h b/chrome/browser/browsing_data/browsing_data_channel_id_helper.h
index 380ce9e55..520fe4857 100644
--- a/chrome/browser/browsing_data/browsing_data_channel_id_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_channel_id_helper.h
@@ -68,11 +68,11 @@
   size_t GetChannelIDCount() const;
 
   // BrowsingDataChannelIDHelper methods.
-  virtual void StartFetching(const FetchResultCallback& callback) override;
-  virtual void DeleteChannelID(const std::string& server_id) override;
+  void StartFetching(const FetchResultCallback& callback) override;
+  void DeleteChannelID(const std::string& server_id) override;
 
  private:
-  virtual ~CannedBrowsingDataChannelIDHelper();
+  ~CannedBrowsingDataChannelIDHelper() override;
 
   void FinishFetching();
 
diff --git a/chrome/browser/browsing_data/browsing_data_channel_id_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_channel_id_helper_unittest.cc
index 53a5b61..4ca5b99 100644
--- a/chrome/browser/browsing_data/browsing_data_channel_id_helper_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_channel_id_helper_unittest.cc
@@ -53,9 +53,7 @@
   }
 
   // net::SSLConfigService::Observer implementation:
-  virtual void OnSSLConfigChanged() override {
-    ssl_config_changed_count_++;
-  }
+  void OnSSLConfigChanged() override { ssl_config_changed_count_++; }
 
  protected:
   content::TestBrowserThreadBundle thread_bundle_;
diff --git a/chrome/browser/browsing_data/browsing_data_cookie_helper.h b/chrome/browser/browsing_data/browsing_data_cookie_helper.h
index 03cc8306..a703ea5 100644
--- a/chrome/browser/browsing_data/browsing_data_cookie_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_cookie_helper.h
@@ -126,9 +126,9 @@
   bool empty() const;
 
   // BrowsingDataCookieHelper methods.
-  virtual void StartFetching(
+  void StartFetching(
       const net::CookieMonster::GetCookieListCallback& callback) override;
-  virtual void DeleteCookie(const net::CanonicalCookie& cookie) override;
+  void DeleteCookie(const net::CanonicalCookie& cookie) override;
 
   // Returns the number of stored cookies.
   size_t GetCookieCount() const;
@@ -145,7 +145,7 @@
   bool DeleteMatchingCookie(const net::CanonicalCookie& add_cookie,
                             canonical_cookie::CookieHashSet* cookie_set);
 
-  virtual ~CannedBrowsingDataCookieHelper();
+  ~CannedBrowsingDataCookieHelper() override;
 
   // Returns the |CookieSet| for the given |origin|.
   canonical_cookie::CookieHashSet* GetCookiesFor(const GURL& origin);
diff --git a/chrome/browser/browsing_data/browsing_data_database_helper.h b/chrome/browser/browsing_data/browsing_data_database_helper.h
index 03b3555..a999994 100644
--- a/chrome/browser/browsing_data/browsing_data_database_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_database_helper.h
@@ -134,14 +134,13 @@
   const std::set<PendingDatabaseInfo>& GetPendingDatabaseInfo();
 
   // BrowsingDataDatabaseHelper implementation.
-  virtual void StartFetching(
-      const base::Callback<void(const std::list<DatabaseInfo>&)>& callback)
-          override;
-  virtual void DeleteDatabase(const std::string& origin_identifier,
-                              const std::string& name) override;
+  void StartFetching(const base::Callback<void(const std::list<DatabaseInfo>&)>&
+                         callback) override;
+  void DeleteDatabase(const std::string& origin_identifier,
+                      const std::string& name) override;
 
  private:
-  virtual ~CannedBrowsingDataDatabaseHelper();
+  ~CannedBrowsingDataDatabaseHelper() override;
 
   std::set<PendingDatabaseInfo> pending_database_info_;
 
diff --git a/chrome/browser/browsing_data/browsing_data_file_system_helper.cc b/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
index 0df68421..ee89647 100644
--- a/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_file_system_helper.cc
@@ -34,12 +34,13 @@
   // BrowsingDataFileSystemHelper implementation
   explicit BrowsingDataFileSystemHelperImpl(
       storage::FileSystemContext* filesystem_context);
-  virtual void StartFetching(const base::Callback<
-      void(const std::list<FileSystemInfo>&)>& callback) override;
-  virtual void DeleteFileSystemOrigin(const GURL& origin) override;
+  void StartFetching(
+      const base::Callback<void(const std::list<FileSystemInfo>&)>& callback)
+      override;
+  void DeleteFileSystemOrigin(const GURL& origin) override;
 
  private:
-  virtual ~BrowsingDataFileSystemHelperImpl();
+  ~BrowsingDataFileSystemHelperImpl() override;
 
   // Enumerates all filesystem files, storing the resulting list into
   // file_system_file_ for later use. This must be called on the file
diff --git a/chrome/browser/browsing_data/browsing_data_file_system_helper.h b/chrome/browser/browsing_data/browsing_data_file_system_helper.h
index cc1e6c8..d3c335e 100644
--- a/chrome/browser/browsing_data/browsing_data_file_system_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_file_system_helper.h
@@ -120,17 +120,18 @@
   }
 
   // BrowsingDataFileSystemHelper implementation.
-  virtual void StartFetching(const base::Callback<
-      void(const std::list<FileSystemInfo>&)>& callback) override;
+  void StartFetching(
+      const base::Callback<void(const std::list<FileSystemInfo>&)>& callback)
+      override;
 
   // Note that this doesn't actually have an implementation for this canned
   // class. It hasn't been necessary for anything that uses the canned
   // implementation, as the canned class is only used in tests, or in read-only
   // contexts (like the non-modal cookie dialog).
-  virtual void DeleteFileSystemOrigin(const GURL& origin) override {}
+  void DeleteFileSystemOrigin(const GURL& origin) override {}
 
  private:
-  virtual ~CannedBrowsingDataFileSystemHelper();
+  ~CannedBrowsingDataFileSystemHelper() override;
 
   // Holds the current list of filesystems returned to the client.
   std::list<FileSystemInfo> file_system_info_;
diff --git a/chrome/browser/browsing_data/browsing_data_flash_lso_helper.cc b/chrome/browser/browsing_data/browsing_data_flash_lso_helper.cc
index 325ffd00..d6a0fdb 100644
--- a/chrome/browser/browsing_data/browsing_data_flash_lso_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_flash_lso_helper.cc
@@ -21,20 +21,17 @@
       content::BrowserContext* browser_context);
 
   // BrowsingDataFlashLSOHelper implementation:
-  virtual void StartFetching(
-      const GetSitesWithFlashDataCallback& callback) override;
-  virtual void DeleteFlashLSOsForSite(const std::string& site) override;
+  void StartFetching(const GetSitesWithFlashDataCallback& callback) override;
+  void DeleteFlashLSOsForSite(const std::string& site) override;
 
   // PepperFlashSettingsManager::Client overrides:
-  virtual void OnGetSitesWithDataCompleted(
+  void OnGetSitesWithDataCompleted(
       uint32 request_id,
       const std::vector<std::string>& sites) override;
-  virtual void OnClearSiteDataCompleted(
-      uint32 request_id,
-      bool success) override;
+  void OnClearSiteDataCompleted(uint32 request_id, bool success) override;
 
  private:
-  virtual ~BrowsingDataFlashLSOHelperImpl();
+  ~BrowsingDataFlashLSOHelperImpl() override;
 
   // Asynchronously fetches and deletes data and calls us back.
   PepperFlashSettingsManager settings_manager_;
diff --git a/chrome/browser/browsing_data/browsing_data_indexed_db_helper.h b/chrome/browser/browsing_data/browsing_data_indexed_db_helper.h
index 79ceb84..6476848c 100644
--- a/chrome/browser/browsing_data/browsing_data_indexed_db_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_indexed_db_helper.h
@@ -115,13 +115,12 @@
       GetIndexedDBInfo() const;
 
   // BrowsingDataIndexedDBHelper methods.
-  virtual void StartFetching(
-      const base::Callback<void(const std::list<content::IndexedDBInfo>&)>&
-          callback) override;
-  virtual void DeleteIndexedDB(const GURL& origin) override;
+  void StartFetching(const base::Callback<
+      void(const std::list<content::IndexedDBInfo>&)>& callback) override;
+  void DeleteIndexedDB(const GURL& origin) override;
 
  private:
-  virtual ~CannedBrowsingDataIndexedDBHelper();
+  ~CannedBrowsingDataIndexedDBHelper() override;
 
   std::set<PendingIndexedDBInfo> pending_indexed_db_info_;
 
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper.h b/chrome/browser/browsing_data/browsing_data_local_storage_helper.h
index 6ed4249..4273995 100644
--- a/chrome/browser/browsing_data/browsing_data_local_storage_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper.h
@@ -92,13 +92,13 @@
   const std::set<GURL>& GetLocalStorageInfo() const;
 
   // BrowsingDataLocalStorageHelper implementation.
-  virtual void StartFetching(
+  void StartFetching(
       const base::Callback<void(const std::list<LocalStorageInfo>&)>& callback)
-          override;
-  virtual void DeleteOrigin(const GURL& origin) override;
+      override;
+  void DeleteOrigin(const GURL& origin) override;
 
  private:
-  virtual ~CannedBrowsingDataLocalStorageHelper();
+  ~CannedBrowsingDataLocalStorageHelper() override;
 
   std::set<GURL> pending_local_storage_info_;
 
diff --git a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.h b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.h
index 90127b1..4cd6108 100644
--- a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.h
+++ b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.h
@@ -27,14 +27,14 @@
 // IO thread, we have to communicate over thread using PostTask.
 class BrowsingDataQuotaHelperImpl : public BrowsingDataQuotaHelper {
  public:
-  virtual void StartFetching(const FetchResultCallback& callback) override;
-  virtual void RevokeHostQuota(const std::string& host) override;
+  void StartFetching(const FetchResultCallback& callback) override;
+  void RevokeHostQuota(const std::string& host) override;
 
  private:
   BrowsingDataQuotaHelperImpl(base::MessageLoopProxy* ui_thread,
                               base::MessageLoopProxy* io_thread,
                               storage::QuotaManager* quota_manager);
-  virtual ~BrowsingDataQuotaHelperImpl();
+  ~BrowsingDataQuotaHelperImpl() override;
 
   void FetchQuotaInfo();
 
diff --git a/chrome/browser/browsing_data/browsing_data_remover.h b/chrome/browser/browsing_data/browsing_data_remover.h
index e772516..133a89a 100644
--- a/chrome/browser/browsing_data/browsing_data_remover.h
+++ b/chrome/browser/browsing_data/browsing_data_remover.h
@@ -250,7 +250,14 @@
   // to be deleted by other objects so make destructor private and DeleteHelper
   // a friend.
   friend class base::DeleteHelper<BrowsingDataRemover>;
-  virtual ~BrowsingDataRemover();
+
+  // When plugins aren't enabled, there is no base class, so adding an override
+  // specifier would result in a compile error.
+#if defined(ENABLE_PLUGINS)
+  ~BrowsingDataRemover() override;
+#else
+  ~BrowsingDataRemover();
+#endif
 
   // Callback for when TemplateURLService has finished loading. Clears the data,
   // clears the respective waiting flag, and invokes NotifyAndDeleteIfDone.
@@ -261,8 +268,8 @@
 
 #if defined(ENABLE_PLUGINS)
   // PepperFlashSettingsManager::Client implementation.
-  virtual void OnDeauthorizeContentLicensesCompleted(uint32 request_id,
-                                                     bool success) override;
+  void OnDeauthorizeContentLicensesCompleted(uint32 request_id,
+                                             bool success) override;
 #endif
 
 #if defined (OS_CHROMEOS)
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
index c57f766..76246c9 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -38,7 +38,7 @@
  public:
   BrowsingDataRemoverBrowserTest() {}
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     base::FilePath path;
     PathService::Get(content::DIR_TEST_DATA, &path);
     BrowserThread::PostTask(
diff --git a/chrome/browser/browsing_data/browsing_data_remover_test_util.h b/chrome/browser/browsing_data/browsing_data_remover_test_util.h
index 2994cf6..dc7eb17 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_test_util.h
+++ b/chrome/browser/browsing_data/browsing_data_remover_test_util.h
@@ -14,13 +14,13 @@
     : public BrowsingDataRemover::Observer {
  public:
   explicit BrowsingDataRemoverCompletionObserver(BrowsingDataRemover* remover);
-  virtual ~BrowsingDataRemoverCompletionObserver();
+  ~BrowsingDataRemoverCompletionObserver() override;
 
   void BlockUntilCompletion();
 
  protected:
   // BrowsingDataRemover::Observer:
-  virtual void OnBrowsingDataRemoverDone() override;
+  void OnBrowsingDataRemoverDone() override;
 
  private:
   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
@@ -32,14 +32,14 @@
     : public BrowsingDataRemover::CompletionInhibitor {
  public:
   BrowsingDataRemoverCompletionInhibitor();
-  virtual ~BrowsingDataRemoverCompletionInhibitor();
+  ~BrowsingDataRemoverCompletionInhibitor() override;
 
   void BlockUntilNearCompletion();
   void ContinueToCompletion();
 
  protected:
   // BrowsingDataRemover::CompletionInhibitor:
-  virtual void OnBrowsingDataRemoverWouldComplete(
+  void OnBrowsingDataRemoverWouldComplete(
       BrowsingDataRemover* remover,
       const base::Closure& continue_to_completion) override;
 
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index 7f9aaad..42fd466 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -133,41 +133,30 @@
 class TestStoragePartition : public StoragePartition {
  public:
   TestStoragePartition() {}
-  virtual ~TestStoragePartition() {}
+  ~TestStoragePartition() override {}
 
   // content::StoragePartition implementation.
-  virtual base::FilePath GetPath() override { return base::FilePath(); }
-  virtual net::URLRequestContextGetter* GetURLRequestContext() override {
+  base::FilePath GetPath() override { return base::FilePath(); }
+  net::URLRequestContextGetter* GetURLRequestContext() override { return NULL; }
+  net::URLRequestContextGetter* GetMediaURLRequestContext() override {
     return NULL;
   }
-  virtual net::URLRequestContextGetter* GetMediaURLRequestContext() override {
+  storage::QuotaManager* GetQuotaManager() override { return NULL; }
+  content::AppCacheService* GetAppCacheService() override { return NULL; }
+  storage::FileSystemContext* GetFileSystemContext() override { return NULL; }
+  storage::DatabaseTracker* GetDatabaseTracker() override { return NULL; }
+  content::DOMStorageContext* GetDOMStorageContext() override { return NULL; }
+  content::IndexedDBContext* GetIndexedDBContext() override { return NULL; }
+  content::ServiceWorkerContext* GetServiceWorkerContext() override {
     return NULL;
   }
-  virtual storage::QuotaManager* GetQuotaManager() override { return NULL; }
-  virtual content::AppCacheService* GetAppCacheService() override {
-    return NULL;
-  }
-  virtual storage::FileSystemContext* GetFileSystemContext() override {
-    return NULL;
-  }
-  virtual storage::DatabaseTracker* GetDatabaseTracker() override {
-    return NULL;
-  }
-  virtual content::DOMStorageContext* GetDOMStorageContext() override {
-    return NULL;
-  }
-  virtual content::IndexedDBContext* GetIndexedDBContext() override {
-    return NULL;
-  }
-  virtual content::ServiceWorkerContext* GetServiceWorkerContext() override {
-    return NULL;
-  }
+  content::GeofencingManager* GetGeofencingManager() override { return NULL; }
 
-  virtual void ClearDataForOrigin(uint32 remove_mask,
-                                  uint32 quota_storage_remove_mask,
-                                  const GURL& storage_origin,
-                                  net::URLRequestContextGetter* rq_context,
-                                  const base::Closure& callback) override {
+  void ClearDataForOrigin(uint32 remove_mask,
+                          uint32 quota_storage_remove_mask,
+                          const GURL& storage_origin,
+                          net::URLRequestContextGetter* rq_context,
+                          const base::Closure& callback) override {
     BrowserThread::PostTask(BrowserThread::UI,
                             FROM_HERE,
                             base::Bind(&TestStoragePartition::AsyncRunCallback,
@@ -175,13 +164,13 @@
                                        callback));
   }
 
-  virtual void ClearData(uint32 remove_mask,
-                         uint32 quota_storage_remove_mask,
-                         const GURL& storage_origin,
-                         const OriginMatcherFunction& origin_matcher,
-                         const base::Time begin,
-                         const base::Time end,
-                         const base::Closure& callback) override {
+  void ClearData(uint32 remove_mask,
+                 uint32 quota_storage_remove_mask,
+                 const GURL& storage_origin,
+                 const OriginMatcherFunction& origin_matcher,
+                 const base::Time begin,
+                 const base::Time end,
+                 const base::Closure& callback) override {
     // Store stuff to verify parameters' correctness later.
     storage_partition_removal_data_.remove_mask = remove_mask;
     storage_partition_removal_data_.quota_storage_remove_mask =
@@ -317,7 +306,7 @@
     ssl_config_service_->AddObserver(this);
   }
 
-  virtual ~RemoveChannelIDTester() {
+  ~RemoveChannelIDTester() override {
     ssl_config_service_->RemoveObserver(this);
   }
 
@@ -361,9 +350,7 @@
   }
 
   // net::SSLConfigService::Observer implementation:
-  virtual void OnSSLConfigChanged() override {
-    ssl_config_changed_count_++;
-  }
+  void OnSSLConfigChanged() override { ssl_config_changed_count_++; }
 
  private:
   static void GetAllChannelIDsCallback(
@@ -441,7 +428,7 @@
     personal_data_manager_->AddObserver(this);
   }
 
-  virtual ~RemoveAutofillTester() {
+  ~RemoveAutofillTester() override {
     personal_data_manager_->RemoveObserver(this);
   }
 
@@ -512,7 +499,7 @@
   }
 
  private:
-  virtual void OnPersonalDataChanged() override {
+  void OnPersonalDataChanged() override {
     base::MessageLoop::current()->Quit();
   }
 
@@ -597,25 +584,24 @@
  public:
   MockDomainReliabilityService() : clear_count_(0) {}
 
-  virtual ~MockDomainReliabilityService() {}
+  ~MockDomainReliabilityService() override {}
 
-  virtual scoped_ptr<DomainReliabilityMonitor> CreateMonitor(
+  scoped_ptr<DomainReliabilityMonitor> CreateMonitor(
       scoped_refptr<base::SingleThreadTaskRunner> network_task_runner)
       override {
     NOTREACHED();
     return scoped_ptr<DomainReliabilityMonitor>();
   }
 
-  virtual void ClearBrowsingData(DomainReliabilityClearMode clear_mode,
-                                 const base::Closure& callback) override {
+  void ClearBrowsingData(DomainReliabilityClearMode clear_mode,
+                         const base::Closure& callback) override {
     clear_count_++;
     last_clear_mode_ = clear_mode;
     callback.Run();
   }
 
-  virtual void GetWebUIData(
-      const base::Callback<void(scoped_ptr<base::Value>)>& callback)
-      const override {
+  void GetWebUIData(const base::Callback<void(scoped_ptr<base::Value>)>&
+                        callback) const override {
     NOTREACHED();
   }
 
@@ -638,7 +624,7 @@
       : context(context),
         service(service),
         attached(false) {}
-  virtual ~TestingDomainReliabilityServiceFactoryUserData() {}
+  ~TestingDomainReliabilityServiceFactoryUserData() override {}
 
   content::BrowserContext* const context;
   MockDomainReliabilityService* const service;
@@ -801,9 +787,9 @@
   }
 
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override {
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {
     DCHECK_EQ(type, chrome::NOTIFICATION_BROWSING_DATA_REMOVED);
 
     // We're not taking ownership of the details object, but storing a copy of
diff --git a/chrome/browser/browsing_data/browsing_data_service_worker_helper.h b/chrome/browser/browsing_data/browsing_data_service_worker_helper.h
index e4861e8..100741f 100644
--- a/chrome/browser/browsing_data/browsing_data_service_worker_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_service_worker_helper.h
@@ -126,12 +126,12 @@
       GetServiceWorkerUsageInfo() const;
 
   // BrowsingDataServiceWorkerHelper methods.
-  virtual void StartFetching(const base::Callback<void(
+  void StartFetching(const base::Callback<void(
       const std::list<content::ServiceWorkerUsageInfo>&)>& callback) override;
-  virtual void DeleteServiceWorkers(const GURL& origin) override;
+  void DeleteServiceWorkers(const GURL& origin) override;
 
  private:
-  virtual ~CannedBrowsingDataServiceWorkerHelper();
+  ~CannedBrowsingDataServiceWorkerHelper() override;
 
   std::set<PendingServiceWorkerUsageInfo> pending_service_worker_info_;
 
diff --git a/chrome/browser/browsing_data/cookies_tree_model.h b/chrome/browser/browsing_data/cookies_tree_model.h
index f79f484..929044f 100644
--- a/chrome/browser/browsing_data/cookies_tree_model.h
+++ b/chrome/browser/browsing_data/cookies_tree_model.h
@@ -148,7 +148,7 @@
   CookieTreeNode() {}
   explicit CookieTreeNode(const base::string16& title)
       : ui::TreeNode<CookieTreeNode>(title) {}
-  virtual ~CookieTreeNode() {}
+  ~CookieTreeNode() override {}
 
   // Delete backend storage for this node, and any children nodes. (E.g. delete
   // the cookie from CookieMonster, clear the database, and so forth.)
@@ -173,13 +173,13 @@
 class CookieTreeRootNode : public CookieTreeNode {
  public:
   explicit CookieTreeRootNode(CookiesTreeModel* model);
-  virtual ~CookieTreeRootNode();
+  ~CookieTreeRootNode() override;
 
   CookieTreeHostNode* GetOrCreateHostNode(const GURL& url);
 
   // CookieTreeNode methods:
-  virtual CookiesTreeModel* GetModel() const override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  CookiesTreeModel* GetModel() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   CookiesTreeModel* model_;
@@ -194,10 +194,10 @@
   static base::string16 TitleForUrl(const GURL& url);
 
   explicit CookieTreeHostNode(const GURL& url);
-  virtual ~CookieTreeHostNode();
+  ~CookieTreeHostNode() override;
 
   // CookieTreeNode methods:
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   // CookieTreeHostNode methods:
   CookieTreeCookiesNode* GetOrCreateCookiesNode();
@@ -260,11 +260,11 @@
   // CookieTreeCookieNode is valid.
   explicit CookieTreeCookieNode(
       std::list<net::CanonicalCookie>::iterator cookie);
-  virtual ~CookieTreeCookieNode();
+  ~CookieTreeCookieNode() override;
 
   // CookieTreeNode methods:
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // cookie_ is expected to remain valid as long as the CookieTreeCookieNode is
@@ -277,9 +277,9 @@
 class CookieTreeCookiesNode : public CookieTreeNode {
  public:
   CookieTreeCookiesNode();
-  virtual ~CookieTreeCookiesNode();
+  ~CookieTreeCookiesNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddCookieNode(CookieTreeCookieNode* child) {
     AddChildSortedByTitle(child);
@@ -299,10 +299,10 @@
   explicit CookieTreeAppCacheNode(
       const GURL& origin_url,
       std::list<content::AppCacheInfo>::iterator appcache_info);
-  virtual ~CookieTreeAppCacheNode();
+  ~CookieTreeAppCacheNode() override;
 
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   GURL origin_url_;
@@ -313,9 +313,9 @@
 class CookieTreeAppCachesNode : public CookieTreeNode {
  public:
   CookieTreeAppCachesNode();
-  virtual ~CookieTreeAppCachesNode();
+  ~CookieTreeAppCachesNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddAppCacheNode(CookieTreeAppCacheNode* child) {
     AddChildSortedByTitle(child);
@@ -335,10 +335,10 @@
   explicit CookieTreeDatabaseNode(
       std::list<BrowsingDataDatabaseHelper::DatabaseInfo>::iterator
           database_info);
-  virtual ~CookieTreeDatabaseNode();
+  ~CookieTreeDatabaseNode() override;
 
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // database_info_ is expected to remain valid as long as the
@@ -352,9 +352,9 @@
 class CookieTreeDatabasesNode : public CookieTreeNode {
  public:
   CookieTreeDatabasesNode();
-  virtual ~CookieTreeDatabasesNode();
+  ~CookieTreeDatabasesNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddDatabaseNode(CookieTreeDatabaseNode* child) {
     AddChildSortedByTitle(child);
@@ -374,10 +374,10 @@
   explicit CookieTreeFileSystemNode(
       std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator
           file_system_info);
-  virtual ~CookieTreeFileSystemNode();
+  ~CookieTreeFileSystemNode() override;
 
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // file_system_info_ expected to remain valid as long as the
@@ -391,9 +391,9 @@
 class CookieTreeFileSystemsNode : public CookieTreeNode {
  public:
   CookieTreeFileSystemsNode();
-  virtual ~CookieTreeFileSystemsNode();
+  ~CookieTreeFileSystemsNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddFileSystemNode(CookieTreeFileSystemNode* child) {
     AddChildSortedByTitle(child);
@@ -411,11 +411,11 @@
   explicit CookieTreeLocalStorageNode(
       std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator
           local_storage_info);
-  virtual ~CookieTreeLocalStorageNode();
+  ~CookieTreeLocalStorageNode() override;
 
   // CookieTreeNode methods:
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // local_storage_info_ is expected to remain valid as long as the
@@ -429,9 +429,9 @@
 class CookieTreeLocalStoragesNode : public CookieTreeNode {
  public:
   CookieTreeLocalStoragesNode();
-  virtual ~CookieTreeLocalStoragesNode();
+  ~CookieTreeLocalStoragesNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddLocalStorageNode(CookieTreeLocalStorageNode* child) {
     AddChildSortedByTitle(child);
@@ -450,11 +450,11 @@
   explicit CookieTreeSessionStorageNode(
       std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator
           session_storage_info);
-  virtual ~CookieTreeSessionStorageNode();
+  ~CookieTreeSessionStorageNode() override;
 
   // CookieTreeNode methods:
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // session_storage_info_ is expected to remain valid as long as the
@@ -468,9 +468,9 @@
 class CookieTreeSessionStoragesNode : public CookieTreeNode {
  public:
   CookieTreeSessionStoragesNode();
-  virtual ~CookieTreeSessionStoragesNode();
+  ~CookieTreeSessionStoragesNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddSessionStorageNode(CookieTreeSessionStorageNode* child) {
     AddChildSortedByTitle(child);
@@ -488,11 +488,11 @@
   explicit CookieTreeIndexedDBNode(
       std::list<content::IndexedDBInfo>::iterator
           indexed_db_info);
-  virtual ~CookieTreeIndexedDBNode();
+  ~CookieTreeIndexedDBNode() override;
 
   // CookieTreeNode methods:
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // indexed_db_info_ is expected to remain valid as long as the
@@ -506,9 +506,9 @@
 class CookieTreeIndexedDBsNode : public CookieTreeNode {
  public:
   CookieTreeIndexedDBsNode();
-  virtual ~CookieTreeIndexedDBsNode();
+  ~CookieTreeIndexedDBsNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddIndexedDBNode(CookieTreeIndexedDBNode* child) {
     AddChildSortedByTitle(child);
@@ -525,10 +525,10 @@
   // is valid.
   explicit CookieTreeQuotaNode(
       std::list<BrowsingDataQuotaHelper::QuotaInfo>::iterator quota_info);
-  virtual ~CookieTreeQuotaNode();
+  ~CookieTreeQuotaNode() override;
 
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // quota_info_ is expected to remain valid as long as the CookieTreeQuotaNode
@@ -547,11 +547,11 @@
   // CookieTreeChannelIDNode is valid.
   explicit CookieTreeChannelIDNode(
       net::ChannelIDStore::ChannelIDList::iterator cert);
-  virtual ~CookieTreeChannelIDNode();
+  ~CookieTreeChannelIDNode() override;
 
   // CookieTreeNode methods:
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // channel_id_ is expected to remain valid as long as the
@@ -564,9 +564,9 @@
 class CookieTreeChannelIDsNode : public CookieTreeNode {
  public:
   CookieTreeChannelIDsNode();
-  virtual ~CookieTreeChannelIDsNode();
+  ~CookieTreeChannelIDsNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddChannelIDNode(CookieTreeChannelIDNode* child) {
     AddChildSortedByTitle(child);
@@ -583,11 +583,11 @@
   // CookieTreeServiceWorkerNode is valid.
   explicit CookieTreeServiceWorkerNode(
       std::list<content::ServiceWorkerUsageInfo>::iterator service_worker_info);
-  virtual ~CookieTreeServiceWorkerNode();
+  ~CookieTreeServiceWorkerNode() override;
 
   // CookieTreeNode methods:
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   // service_worker_info_ is expected to remain valid as long as the
@@ -600,9 +600,9 @@
 class CookieTreeServiceWorkersNode : public CookieTreeNode {
  public:
   CookieTreeServiceWorkersNode();
-  virtual ~CookieTreeServiceWorkersNode();
+  ~CookieTreeServiceWorkersNode() override;
 
-  virtual DetailedInfo GetDetailedInfo() const override;
+  DetailedInfo GetDetailedInfo() const override;
 
   void AddServiceWorkerNode(CookieTreeServiceWorkerNode* child) {
     AddChildSortedByTitle(child);
@@ -616,11 +616,11 @@
 class CookieTreeFlashLSONode : public CookieTreeNode {
  public:
   explicit CookieTreeFlashLSONode(const std::string& domain);
-  virtual ~CookieTreeFlashLSONode();
+  ~CookieTreeFlashLSONode() override;
 
   // CookieTreeNode methods:
-  virtual void DeleteStoredObjects() override;
-  virtual DetailedInfo GetDetailedInfo() const override;
+  void DeleteStoredObjects() override;
+  DetailedInfo GetDetailedInfo() const override;
 
  private:
   std::string domain_;
@@ -634,7 +634,7 @@
   CookiesTreeModel(LocalDataContainer* data_container,
                    ExtensionSpecialStoragePolicy* special_storage_policy,
                    bool group_by_cookie_source);
-  virtual ~CookiesTreeModel();
+  ~CookiesTreeModel() override;
 
   // Because non-cookie nodes are fetched in a background thread, they are not
   // present at the time the Model is created. The Model then notifies its
@@ -667,12 +667,12 @@
   // ui::TreeModel methods:
   // Returns the set of icons for the nodes in the tree. You only need override
   // this if you don't want to use the default folder icons.
-  virtual void GetIcons(std::vector<gfx::ImageSkia>* icons) override;
+  void GetIcons(std::vector<gfx::ImageSkia>* icons) override;
 
   // Returns the index of the icon to use for |node|. Return -1 to use the
   // default icon. The index is relative to the list of icons returned from
   // GetIcons.
-  virtual int GetIconIndex(ui::TreeModelNode* node) override;
+  int GetIconIndex(ui::TreeModelNode* node) override;
 
   // CookiesTreeModel methods:
   void DeleteAllStoredObjects();
diff --git a/chrome/browser/browsing_data/mock_browsing_data_appcache_helper.h b/chrome/browser/browsing_data/mock_browsing_data_appcache_helper.h
index f34b8e83..917ce348 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_appcache_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_appcache_helper.h
@@ -14,11 +14,11 @@
   explicit MockBrowsingDataAppCacheHelper(
       content::BrowserContext* browser_context);
 
-  virtual void StartFetching(const base::Closure& completion_callback) override;
-  virtual void DeleteAppCacheGroup(const GURL& manifest_url) override;
+  void StartFetching(const base::Closure& completion_callback) override;
+  void DeleteAppCacheGroup(const GURL& manifest_url) override;
 
  private:
-  virtual ~MockBrowsingDataAppCacheHelper();
+  ~MockBrowsingDataAppCacheHelper() override;
 
   DISALLOW_COPY_AND_ASSIGN(MockBrowsingDataAppCacheHelper);
 };
diff --git a/chrome/browser/browsing_data/mock_browsing_data_channel_id_helper.h b/chrome/browser/browsing_data/mock_browsing_data_channel_id_helper.h
index a5953d4..96e09cb 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_channel_id_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_channel_id_helper.h
@@ -17,8 +17,8 @@
   MockBrowsingDataChannelIDHelper();
 
   // BrowsingDataChannelIDHelper methods.
-  virtual void StartFetching(const FetchResultCallback& callback) override;
-  virtual void DeleteChannelID(const std::string& server_id) override;
+  void StartFetching(const FetchResultCallback& callback) override;
+  void DeleteChannelID(const std::string& server_id) override;
 
   // Adds a channel_id sample.
   void AddChannelIDSample(const std::string& server_id);
@@ -34,7 +34,7 @@
   bool AllDeleted();
 
  private:
-  virtual ~MockBrowsingDataChannelIDHelper();
+  ~MockBrowsingDataChannelIDHelper() override;
 
   FetchResultCallback callback_;
 
diff --git a/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h b/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h
index e766e78..21031a32 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.h
@@ -18,9 +18,9 @@
       net::URLRequestContextGetter* request_context_getter);
 
   // BrowsingDataCookieHelper methods.
-  virtual void StartFetching(
-      const net::CookieMonster::GetCookieListCallback &callback) override;
-  virtual void DeleteCookie(const net::CanonicalCookie& cookie) override;
+  void StartFetching(
+      const net::CookieMonster::GetCookieListCallback& callback) override;
+  void DeleteCookie(const net::CanonicalCookie& cookie) override;
 
   // Adds some cookie samples.
   void AddCookieSamples(const GURL& url, const std::string& cookie_line);
@@ -36,7 +36,7 @@
   bool AllDeleted();
 
  private:
-  virtual ~MockBrowsingDataCookieHelper();
+  ~MockBrowsingDataCookieHelper() override;
 
   net::CookieMonster::GetCookieListCallback callback_;
 
diff --git a/chrome/browser/browsing_data/mock_browsing_data_database_helper.h b/chrome/browser/browsing_data/mock_browsing_data_database_helper.h
index 010bc23..bd16cb0 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_database_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_database_helper.h
@@ -19,12 +19,11 @@
  public:
   explicit MockBrowsingDataDatabaseHelper(Profile* profile);
 
-  virtual void StartFetching(
-      const base::Callback<void(const std::list<DatabaseInfo>&)>& callback)
-          override;
+  void StartFetching(const base::Callback<void(const std::list<DatabaseInfo>&)>&
+                         callback) override;
 
-  virtual void DeleteDatabase(const std::string& origin,
-      const std::string& name) override;
+  void DeleteDatabase(const std::string& origin,
+                      const std::string& name) override;
 
   // Adds some DatabaseInfo samples.
   void AddDatabaseSamples();
@@ -44,7 +43,7 @@
   std::string last_deleted_db_;
 
  private:
-  virtual ~MockBrowsingDataDatabaseHelper();
+  ~MockBrowsingDataDatabaseHelper() override;
 
   base::Callback<void(const std::list<DatabaseInfo>&)> callback_;
 
diff --git a/chrome/browser/browsing_data/mock_browsing_data_file_system_helper.h b/chrome/browser/browsing_data/mock_browsing_data_file_system_helper.h
index 8786645..777bca2 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_file_system_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_file_system_helper.h
@@ -21,9 +21,10 @@
   explicit MockBrowsingDataFileSystemHelper(Profile* profile);
 
   // BrowsingDataFileSystemHelper implementation.
-  virtual void StartFetching(const base::Callback<
-      void(const std::list<FileSystemInfo>&)>& callback) override;
-  virtual void DeleteFileSystemOrigin(const GURL& origin) override;
+  void StartFetching(
+      const base::Callback<void(const std::list<FileSystemInfo>&)>& callback)
+      override;
+  void DeleteFileSystemOrigin(const GURL& origin) override;
 
   // Adds a specific filesystem.
   void AddFileSystem(const GURL& origin,
@@ -47,7 +48,7 @@
   GURL last_deleted_origin_;
 
  private:
-  virtual ~MockBrowsingDataFileSystemHelper();
+  ~MockBrowsingDataFileSystemHelper() override;
 
   base::Callback<void(const std::list<FileSystemInfo>&)> callback_;
 
diff --git a/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h b/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h
index f4e034a..a162da04 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h
@@ -17,9 +17,8 @@
       content::BrowserContext* browser_context);
 
   // BrowsingDataFlashLSOHelper implementation:
-  virtual void StartFetching(
-      const GetSitesWithFlashDataCallback& callback) override;
-  virtual void DeleteFlashLSOsForSite(const std::string& site) override;
+  void StartFetching(const GetSitesWithFlashDataCallback& callback) override;
+  void DeleteFlashLSOsForSite(const std::string& site) override;
 
   // Adds a domain sample.
   void AddFlashLSODomain(const std::string& domain);
@@ -31,7 +30,7 @@
   bool AllDeleted();
 
  private:
-  virtual ~MockBrowsingDataFlashLSOHelper();
+  ~MockBrowsingDataFlashLSOHelper() override;
 
   GetSitesWithFlashDataCallback callback_;
 
diff --git a/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.h b/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.h
index 7157fe4..1d859e9 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.h
@@ -36,13 +36,12 @@
   bool AllDeleted();
 
   // BrowsingDataIndexedDBHelper.
-  virtual void StartFetching(
-      const base::Callback<void(const std::list<content::IndexedDBInfo>&)>&
-          callback) override;
-  virtual void DeleteIndexedDB(const GURL& origin) override;
+  void StartFetching(const base::Callback<
+      void(const std::list<content::IndexedDBInfo>&)>& callback) override;
+  void DeleteIndexedDB(const GURL& origin) override;
 
  private:
-  virtual ~MockBrowsingDataIndexedDBHelper();
+  ~MockBrowsingDataIndexedDBHelper() override;
 
   base::Callback<void(const std::list<content::IndexedDBInfo>&)> callback_;
   std::map<GURL, bool> origins_;
diff --git a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h
index 0799b65e..30e44381 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h
@@ -21,10 +21,10 @@
   explicit MockBrowsingDataLocalStorageHelper(Profile* profile);
 
   // BrowsingDataLocalStorageHelper implementation.
-  virtual void StartFetching(
+  void StartFetching(
       const base::Callback<void(const std::list<LocalStorageInfo>&)>& callback)
-          override;
-  virtual void DeleteOrigin(const GURL& origin) override;
+      override;
+  void DeleteOrigin(const GURL& origin) override;
 
   // Adds some LocalStorageInfo samples.
   void AddLocalStorageSamples();
@@ -42,7 +42,7 @@
   GURL last_deleted_origin_;
 
  private:
-  virtual ~MockBrowsingDataLocalStorageHelper();
+  ~MockBrowsingDataLocalStorageHelper() override;
 
   base::Callback<void(const std::list<LocalStorageInfo>&)> callback_;
 
diff --git a/chrome/browser/browsing_data/mock_browsing_data_quota_helper.h b/chrome/browser/browsing_data/mock_browsing_data_quota_helper.h
index 405e897..b3fea6c 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_quota_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_quota_helper.h
@@ -15,8 +15,8 @@
  public:
   explicit MockBrowsingDataQuotaHelper(Profile* profile);
 
-  virtual void StartFetching(const FetchResultCallback& callback) override;
-  virtual void RevokeHostQuota(const std::string& host) override;
+  void StartFetching(const FetchResultCallback& callback) override;
+  void RevokeHostQuota(const std::string& host) override;
 
   void AddHost(const std::string& host,
                int64 temporary_usage,
@@ -26,7 +26,7 @@
   void Notify();
 
  private:
-  virtual ~MockBrowsingDataQuotaHelper();
+  ~MockBrowsingDataQuotaHelper() override;
 
   FetchResultCallback callback_;
   std::list<QuotaInfo> response_;
diff --git a/chrome/browser/browsing_data/mock_browsing_data_service_worker_helper.h b/chrome/browser/browsing_data/mock_browsing_data_service_worker_helper.h
index e3575f35..00b18cba 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_service_worker_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_service_worker_helper.h
@@ -36,12 +36,12 @@
   bool AllDeleted();
 
   // BrowsingDataServiceWorkerHelper.
-  virtual void StartFetching(const base::Callback<void(
+  void StartFetching(const base::Callback<void(
       const std::list<content::ServiceWorkerUsageInfo>&)>& callback) override;
-  virtual void DeleteServiceWorkers(const GURL& origin) override;
+  void DeleteServiceWorkers(const GURL& origin) override;
 
  private:
-  virtual ~MockBrowsingDataServiceWorkerHelper();
+  ~MockBrowsingDataServiceWorkerHelper() override;
 
   base::Callback<void(const std::list<content::ServiceWorkerUsageInfo>&)>
       callback_;
diff --git a/chrome/browser/character_encoding.cc b/chrome/browser/character_encoding.cc
index e01c27d..e9e2521 100644
--- a/chrome/browser/character_encoding.cc
+++ b/chrome/browser/character_encoding.cc
@@ -36,7 +36,6 @@
 const CanonicalEncodingData kCanonicalEncodingNames[] = {
   { IDC_ENCODING_UTF8, "UTF-8", IDS_ENCODING_UNICODE },
   { IDC_ENCODING_UTF16LE, "UTF-16LE", IDS_ENCODING_UNICODE },
-  { IDC_ENCODING_ISO88591, "ISO-8859-1", IDS_ENCODING_WESTERN },
   { IDC_ENCODING_WINDOWS1252, "windows-1252", IDS_ENCODING_WESTERN },
   { IDC_ENCODING_GBK, "GBK", IDS_ENCODING_SIMP_CHINESE },
   { IDC_ENCODING_GB18030, "gb18030", IDS_ENCODING_SIMP_CHINESE },
@@ -191,7 +190,6 @@
 
 const int kDefaultEncodingMenus[] = {
   IDC_ENCODING_UTF16LE,
-  IDC_ENCODING_ISO88591,
   IDC_ENCODING_WINDOWS1252,
   IDC_ENCODING_GBK,
   IDC_ENCODING_GB18030,
@@ -255,7 +253,9 @@
   base::string16 category_name = l10n_util::GetStringUTF16(category_string_id);
   if (category_string_id != IDS_ENCODING_KOREAN &&
       category_string_id != IDS_ENCODING_THAI &&
-      category_string_id != IDS_ENCODING_TURKISH) {
+      category_string_id != IDS_ENCODING_TURKISH &&
+      category_string_id != IDS_ENCODING_VIETNAMESE &&
+      category_string_id != IDS_ENCODING_ROMANIAN) {
     const CanonicalNameDisplayNameMapType* map =
         CanonicalEncodingMapSingleton()->GetCanonicalNameDisplayNameMapData();
     DCHECK(map);
@@ -379,29 +379,15 @@
   if (found_id != map->end())
     return alias_name;
 
-  UErrorCode error_code = U_ZERO_ERROR;
-
-  const char* canonical_name = ucnv_getCanonicalName(
-      alias_name.c_str(), "MIME", &error_code);
-  // If failed,  then try IANA next.
-  if (U_FAILURE(error_code) || !canonical_name) {
-    error_code = U_ZERO_ERROR;
-    canonical_name = ucnv_getCanonicalName(
-      alias_name.c_str(), "IANA", &error_code);
+  const char* standards[3] = { "HTML", "MIME", "IANA" };
+  for (size_t i = 0; i < arraysize(standards); ++i) {
+    UErrorCode error_code = U_ZERO_ERROR;
+    const char* canonical_name = ucnv_getCanonicalName(
+        alias_name.c_str(), standards[i], &error_code);
+    if (U_SUCCESS(error_code) && canonical_name)
+      return canonical_name;
   }
-
-  if (canonical_name) {
-    // TODO(jnd) use a map to handle all customized {alias, canonical}
-    // encoding mappings if we have more than one pair.
-    // We don't want to add an unnecessary charset to the encoding menu, so we
-    // alias 'US-ASCII' to 'ISO-8859-1' in our UI without touching WebKit.
-    // http://crbug.com/15801.
-    if (alias_name == "US-ASCII")
-      return GetCanonicalEncodingNameByCommandId(IDC_ENCODING_ISO88591);
-    return canonical_name;
-  } else {
-    return std::string();
-  }
+  return std::string();
 }
 
 // Static
diff --git a/chrome/browser/chrome_browser_application_mac.mm b/chrome/browser/chrome_browser_application_mac.mm
index 71c0efa..e3a8ff28 100644
--- a/chrome/browser/chrome_browser_application_mac.mm
+++ b/chrome/browser/chrome_browser_application_mac.mm
@@ -538,9 +538,14 @@
 }
 
 - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
-  if ([attribute isEqualToString:@"AXEnhancedUserInterface"] &&
-      [value intValue] == 1) {
-    content::BrowserAccessibilityState::GetInstance()->OnScreenReaderDetected();
+  // This is an undocument attribute that's set when VoiceOver is turned on/off.
+  if ([attribute isEqualToString:@"AXEnhancedUserInterface"]) {
+    content::BrowserAccessibilityState* accessibility_state =
+        content::BrowserAccessibilityState::GetInstance();
+    if ([value intValue] == 1)
+      accessibility_state->OnScreenReaderDetected();
+    else
+      accessibility_state->DisableAccessibility();
   }
   return [super accessibilitySetValue:value forAttribute:attribute];
 }
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 5a0e1f7..a58813f 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -110,7 +110,7 @@
 #include "components/startup_metric_utils/startup_metric_utils.h"
 #include "components/translate/content/common/cld_data_source.h"
 #include "components/translate/core/browser/translate_download_manager.h"
-#include "components/variations/variations_http_header_provider.h"
+#include "components/variations/net/variations_http_header_provider.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 0c4ee59..aa39454 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -47,6 +47,7 @@
 #include "chrome/installer/util/l10n_string_util.h"
 #include "chrome/installer/util/shell_util.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/common/main_function_params.h"
 #include "installer_util_strings/installer_util_strings.h"
 #include "ui/base/cursor/cursor_loader_win.h"
@@ -218,6 +219,21 @@
         chrome::MESSAGE_BOX_TYPE_WARNING);
   }
 
+  // Windows 8+ provides a mode where by a process cannot call Win32K/GDI
+  // functions in the kernel (win32k.sys). If we are on Windows 8+ and if
+  // we are launched with the kEnableWin32kRendererLockDown switch then we
+  // force the PDF pepper plugin to run out of process. This is because the
+  // PDF plugin uses GDI for text rendering which does not work in the
+  // Win32K lockdown mode. Running it out of process ensures that the process
+  // launched for the plugin does not have the Win32K lockdown mode enabled.
+  // TODO(ananta)
+  // Revisit this when the pdf plugin uses skia and stops using GDI.
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableWin32kRendererLockDown) &&
+      base::win::GetVersion() >= base::win::VERSION_WIN8) {
+    CommandLine::ForCurrentProcess()->AppendSwitch(
+        switches::kOutOfProcessPdf);
+  }
   return rv;
 }
 
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index f57d75c0..23ca026 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -712,7 +712,8 @@
   // SiteInstance URL - "chrome-guest://app_id/persist?partition".
   if (site.SchemeIs(content::kGuestScheme)) {
     partition_id = site.spec();
-  } else if (site.GetOrigin().spec() == kChromeUIChromeSigninURL) {
+  } else if (site.GetOrigin().spec() == kChromeUIChromeSigninURL &&
+            !switches::IsEnableWebviewBasedSignin()) {
     // Chrome signin page has an embedded iframe of extension and web content,
     // thus it must be isolated from other webUI pages.
     partition_id = site.GetOrigin().spec();
@@ -776,7 +777,8 @@
   }
 #endif
 
-  if (!success && (site.GetOrigin().spec() == kChromeUIChromeSigninURL)) {
+  if (!success && (site.GetOrigin().spec() == kChromeUIChromeSigninURL) &&
+      !switches::IsEnableWebviewBasedSignin()) {
     // Chrome signin page has an embedded iframe of extension and web content,
     // thus it must be isolated from other webUI pages.
     *partition_domain = chrome::kChromeUIChromeSigninHost;
@@ -1338,6 +1340,7 @@
       autofill::switches::kDisableIgnoreAutocompleteOff,
       autofill::switches::kDisablePasswordGeneration,
       autofill::switches::kEnablePasswordGeneration,
+      autofill::switches::kIgnoreAutocompleteOffForAutofill,
       autofill::switches::kLocalHeuristicsOnlyForPasswordGeneration,
 #if defined(ENABLE_EXTENSIONS)
       extensions::switches::kAllowHTTPBackgroundPage,
diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/chrome_notification_types.h
index 4a94b8b..5e7136cb 100644
--- a/chrome/browser/chrome_notification_types.h
+++ b/chrome/browser/chrome_notification_types.h
@@ -124,12 +124,6 @@
   // handler.  Use APP_TERMINATING for such needs.
   NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
 
-  // Application-modal dialogs -----------------------------------------------
-
-  // Sent after an application-modal dialog has been shown. The source
-  // is the dialog.
-  NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
-
   // This message is sent when a new InfoBar has been added to an
   // InfoBarService.  The source is a Source<InfoBarService> with a pointer to
   // the InfoBarService the InfoBar was added to.  The details is a
@@ -142,12 +136,6 @@
   // Details<InfoBar::RemovedDetails>.
   NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
 
-  // Used to fire notifications about how long various events took to
-  // complete.  E.g., this is used to get more fine grained timings from the
-  // new tab page.  The source is a WebContents and the details is a
-  // MetricEventDurationDetails.
-  NOTIFICATION_METRIC_EVENT_DURATION,
-
 #if defined(ENABLE_EXTENSIONS)
   // This notification is sent when extensions::TabHelper::SetExtensionApp is
   // invoked. The source is the extensions::TabHelper SetExtensionApp was
diff --git a/chrome/browser/chrome_plugin_browsertest.cc b/chrome/browser/chrome_plugin_browsertest.cc
index 8085e7e..43f2d1d3 100644
--- a/chrome/browser/chrome_plugin_browsertest.cc
+++ b/chrome/browser/chrome_plugin_browsertest.cc
@@ -256,7 +256,6 @@
 #if defined(OS_CHROMEOS)
     "Google Talk Plugin",
     "Google Talk Plugin Video Accelerator",
-    "Netflix",
 #endif
   };
 
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
index 9cbdec2..8f58335 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
@@ -140,10 +140,6 @@
       return;
     }
 
-    NotifyKioskUpdateProgress(
-        ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
-            IDS_KIOSK_EXTERNAL_UPDATE_IN_PROGRESS));
-
     base::DictionaryValue* parsed_manifest = new base::DictionaryValue();
     ExternalUpdateErrorCode* parsing_error = new ExternalUpdateErrorCode;
     backend_task_runner_->PostTaskAndReply(
@@ -239,9 +235,6 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (*parsing_error == ERROR_NO_MANIFEST) {
-    NotifyKioskUpdateProgress(
-        ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
-            IDS_KIOSK_EXTERNAL_UPDATE_NO_MANIFEST));
     KioskAppManager::Get()->OnKioskAppExternalUpdateComplete(false);
     return;
   } else if (*parsing_error == ERROR_INVALID_MANIFEST) {
@@ -252,6 +245,10 @@
     return;
   }
 
+  NotifyKioskUpdateProgress(
+      ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
+          IDS_KIOSK_EXTERNAL_UPDATE_IN_PROGRESS));
+
   external_update_path_ = external_update_dir;
   for (base::DictionaryValue::Iterator it(*parsed_manifest); !it.IsAtEnd();
        it.Advance()) {
diff --git a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc
index 65c4d26..689ab68 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string_util.h"
 #include "base/sys_info.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
+#include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
@@ -134,7 +135,7 @@
 }
 
 void KioskProfileLoader::LoginAsKioskAccount() {
-  login_performer_.reset(new LoginPerformer(this));
+  login_performer_.reset(new ChromeLoginPerformer(this));
   login_performer_->LoginAsKioskAccount(user_id_, use_guest_mount_);
 }
 
@@ -182,7 +183,8 @@
   NOTREACHED();
 }
 
-void KioskProfileLoader::OnProfilePrepared(Profile* profile) {
+void KioskProfileLoader::OnProfilePrepared(Profile* profile,
+                                           bool browser_launched) {
   // This object could be deleted any time after successfully reporting
   // a profile load, so invalidate the LoginUtils delegate now.
   LoginUtils::Get()->DelegateDeleted(this);
diff --git a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h
index 84b4362..c09a297 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_profile_loader.h
@@ -11,8 +11,8 @@
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
-#include "chrome/browser/chromeos/login/auth/login_performer.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
+#include "chromeos/login/auth/login_performer.h"
 
 class Profile;
 
@@ -57,7 +57,8 @@
       const std::string& email, bool success) override;
 
   // LoginUtils::Delegate implementation:
-  virtual void OnProfilePrepared(Profile* profile) override;
+  virtual void OnProfilePrepared(Profile* profile,
+                                 bool browser_launched) override;
 
   std::string user_id_;
   bool use_guest_mount_;
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc
index fb1387d5..60e2686 100644
--- a/chrome/browser/chromeos/display/display_preferences_unittest.cc
+++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -26,7 +26,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "ui/display/chromeos/display_configurator.h"
-#include "ui/gfx/vector3d_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/message_center/message_center.h"
 
 using ash::ResolutionNotificationController;
diff --git a/chrome/browser/chromeos/drive/OWNERS b/chrome/browser/chromeos/drive/OWNERS
index 3db88c0b..fadc8d8 100644
--- a/chrome/browser/chromeos/drive/OWNERS
+++ b/chrome/browser/chromeos/drive/OWNERS
@@ -1,5 +1,7 @@
 hashimoto@chromium.org
 hidehiko@chromium.org
+hirono@chromium.org
 kinaba@chromium.org
+mtomasz@chromium.org
 satorux@chromium.org
 yoshiki@chromium.org
diff --git a/chrome/browser/chromeos/events/event_rewriter.cc b/chrome/browser/chromeos/events/event_rewriter.cc
index 2316a4a0..2d051a55 100644
--- a/chrome/browser/chromeos/events/event_rewriter.cc
+++ b/chrome/browser/chromeos/events/event_rewriter.cc
@@ -30,7 +30,13 @@
 
 #if defined(USE_X11)
 #include <X11/extensions/XInput2.h>
+#include <X11/Xatom.h>
 #include <X11/Xlib.h>
+
+#ifndef XI_PROP_PRODUCT_ID
+#define XI_PROP_PRODUCT_ID "Device Product ID"
+#endif
+
 // Get rid of macros from Xlib.h that conflicts with other parts of the code.
 #undef RootWindow
 #undef Status
@@ -43,6 +49,12 @@
 
 namespace {
 
+// Hotrod controller vendor/product ids.
+const int kHotrodRemoteVendorId = 0x0471;
+const int kHotrodRemoteProductId = 0x21cc;
+const int kUnknownVendorId = -1;
+const int kUnknownProductId = -1;
+
 // Table of key properties of remappable keys and/or remapping targets.
 // This is searched in two distinct ways:
 //  - |remap_to| is an |input_method::ModifierKey|, which is the form
@@ -127,10 +139,21 @@
       ->IsRegistered(accelerator);
 }
 
-EventRewriter::DeviceType GetDeviceType(const std::string& device_name) {
+EventRewriter::DeviceType GetDeviceType(const std::string& device_name,
+                                        int vendor_id,
+                                        int product_id) {
+  if (vendor_id == kHotrodRemoteVendorId &&
+      product_id == kHotrodRemoteProductId) {
+    return EventRewriter::kDeviceHotrodRemote;
+  }
+
+  if (LowerCaseEqualsASCII(device_name, "virtual core keyboard"))
+    return EventRewriter::kDeviceVirtualCoreKeyboard;
+
   std::vector<std::string> tokens;
   Tokenize(device_name, " .", &tokens);
 
+
   // If the |device_name| contains the two words, "apple" and "keyboard", treat
   // it as an Apple keyboard.
   bool found_apple = false;
@@ -165,7 +188,10 @@
     const std::string& device_name) {
   // Tests must avoid XI2 reserved device IDs.
   DCHECK((device_id < 0) || (device_id > 1));
-  return KeyboardDeviceAddedInternal(device_id, device_name);
+  return KeyboardDeviceAddedInternal(device_id,
+                                     device_name,
+                                     kUnknownVendorId,
+                                     kUnknownProductId);
 }
 
 void EventRewriter::RewriteMouseButtonEventForTesting(
@@ -280,8 +306,20 @@
 }
 
 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) {
-  if (!device_id_to_type_.count(device_id))
-    KeyboardDeviceAdded(device_id);
+  std::map<int, DeviceType>::const_iterator iter =
+        device_id_to_type_.find(device_id);
+  DeviceType type;
+  if (iter != device_id_to_type_.end())
+    type = iter->second;
+  else
+    type = KeyboardDeviceAdded(device_id);
+
+  // Ignore virtual Xorg keyboard (magic that generates key repeat
+  // events). Pretend that the previous real keyboard is the one that is still
+  // in use.
+  if (type == kDeviceVirtualCoreKeyboard)
+    return;
+
   last_keyboard_device_id_ = device_id;
 }
 
@@ -293,6 +331,14 @@
 }
 
 bool EventRewriter::IsAppleKeyboard() const {
+  return IsLastKeyboardOfType(kDeviceAppleKeyboard);
+}
+
+bool EventRewriter::IsHotrodRemote() const {
+  return IsLastKeyboardOfType(kDeviceHotrodRemote);
+}
+
+bool EventRewriter::IsLastKeyboardOfType(DeviceType device_type) const {
   if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE)
     return false;
 
@@ -305,7 +351,7 @@
   }
 
   const DeviceType type = iter->second;
-  return type == kDeviceAppleKeyboard;
+  return type == device_type;
 }
 
 bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const {
@@ -387,6 +433,14 @@
     return ui::EVENT_REWRITE_CONTINUE;
   if (key_event.source_device_id() != ui::ED_UNKNOWN_DEVICE)
     DeviceKeyPressedOrReleased(key_event.source_device_id());
+
+  // Drop repeated keys from Hotrod remote.
+  if ((key_event.flags() & ui::EF_IS_REPEAT) &&
+      (key_event.type() == ui::ET_KEY_PRESSED) &&
+      IsHotrodRemote() && key_event.key_code() != ui::VKEY_BACK) {
+    return ui::EVENT_REWRITE_DISCARD;
+  }
+
   MutableKeyState state = {key_event.flags(), key_event.key_code()};
   // Do not rewrite an event sent by ui_controls::SendKeyPress(). See
   // crbug.com/136465.
@@ -394,6 +448,7 @@
     RewriteModifierKeys(key_event, &state);
     RewriteNumPadKeys(key_event, &state);
   }
+
   ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
   bool is_sticky_key_extension_command = false;
   if (sticky_keys_controller_) {
@@ -854,11 +909,22 @@
 
 EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal(
     int device_id,
-    const std::string& device_name) {
-  const DeviceType type = GetDeviceType(device_name);
+    const std::string& device_name,
+    int vendor_id,
+    int product_id) {
+  const DeviceType type = GetDeviceType(device_name, vendor_id, product_id);
   if (type == kDeviceAppleKeyboard) {
     VLOG(1) << "Apple keyboard '" << device_name << "' connected: "
             << "id=" << device_id;
+  } else if (type == kDeviceHotrodRemote) {
+    VLOG(1) << "Hotrod remote '" << device_name << "' connected: "
+            << "id=" << device_id;
+  } else if (type == kDeviceVirtualCoreKeyboard) {
+    VLOG(1) << "Xorg virtual '" << device_name << "' connected: "
+            << "id=" << device_id;
+  } else {
+    VLOG(1) << "Unknown keyboard '" << device_name << "' connected: "
+            << "id=" << device_id;
   }
   // Always overwrite the existing device_id since the X server may reuse a
   // device id for an unattached device.
@@ -866,15 +932,18 @@
   return type;
 }
 
-void EventRewriter::KeyboardDeviceAdded(int device_id) {
+EventRewriter::DeviceType EventRewriter::KeyboardDeviceAdded(int device_id) {
 #if defined(USE_X11)
   DCHECK_NE(XIAllDevices, device_id);
   DCHECK_NE(XIAllMasterDevices, device_id);
   if (device_id == XIAllDevices || device_id == XIAllMasterDevices) {
     LOG(ERROR) << "Unexpected device_id passed: " << device_id;
-    return;
+    return kDeviceUnknown;
   }
 
+  Atom product_id_atom =
+      XInternAtom(gfx::GetXDisplay(), XI_PROP_PRODUCT_ID, 1);
+
   int ndevices_return = 0;
   XIDeviceInfo* device_info =
       XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return);
@@ -883,19 +952,53 @@
   // the number of devices found should be either 0 (not found) or 1.
   if (!device_info) {
     LOG(ERROR) << "XIQueryDevice: Device ID " << device_id << " is unknown.";
-    return;
+    return kDeviceUnknown;
   }
 
+  DeviceType dev_type = kDeviceUnknown;
   DCHECK_EQ(1, ndevices_return);
   for (int i = 0; i < ndevices_return; ++i) {
+    // Get keyboard product and vendor id.
+    int vendor_id = kUnknownVendorId;
+    int product_id = kUnknownProductId;
+    uint32* product_info = NULL;
+    Atom type;
+    int format_return;
+    unsigned long num_items_return;
+    unsigned long bytes_after_return;
+    if (XIGetProperty(gfx::GetXDisplay(),
+                      device_info[i].deviceid,
+                      product_id_atom,
+                      0,
+                      2,
+                      0,
+                      XA_INTEGER,
+                      &type,
+                      &format_return,
+                      &num_items_return,
+                      &bytes_after_return,
+                      reinterpret_cast<unsigned char **>(&product_info)) == 0 &&
+        product_info) {
+      vendor_id = product_info[0];
+      product_id = product_info[1];
+    }
+
     DCHECK_EQ(device_id, device_info[i].deviceid);  // see the comment above.
     DCHECK(device_info[i].name);
-    KeyboardDeviceAddedInternal(device_info[i].deviceid, device_info[i].name);
+    dev_type = KeyboardDeviceAddedInternal(device_info[i].deviceid,
+                                           device_info[i].name,
+                                           vendor_id,
+                                           product_id);
   }
-
   XIFreeDeviceInfo(device_info);
+  return dev_type;
 #else
-  KeyboardDeviceAddedInternal(device_id, "keyboard");
+  // TODO(spang): Figure out where we can get keyboard vendor/product id from in
+  // Ozone/Freon version.
+  return KeyboardDeviceAddedInternal(device_id,
+                                     "keyboard",
+                                     kUnknownVendorId,
+                                     kUnknownProductId);
 #endif
 }
 
diff --git a/chrome/browser/chromeos/events/event_rewriter.h b/chrome/browser/chromeos/events/event_rewriter.h
index aae5de03..36044aa 100644
--- a/chrome/browser/chromeos/events/event_rewriter.h
+++ b/chrome/browser/chromeos/events/event_rewriter.h
@@ -41,6 +41,8 @@
   enum DeviceType {
     kDeviceUnknown = 0,
     kDeviceAppleKeyboard,
+    kDeviceHotrodRemote,
+    kDeviceVirtualCoreKeyboard,  // X-server generated events.
   };
 
   // Does not take ownership of the |sticky_keys_controller|, which may also
@@ -108,15 +110,21 @@
   const PrefService* GetPrefService() const;
 
   // Adds a device to |device_id_to_type_|.
-  void KeyboardDeviceAdded(int device_id);
+  DeviceType KeyboardDeviceAdded(int device_id);
 
-  // Checks the type of the |device_name|, and inserts a new entry to
-  // |device_id_to_type_|.
+  // Checks the type of the |device_name|, |vendor_id| and |product_id|, and
+  // inserts a new entry to |device_id_to_type_|.
   DeviceType KeyboardDeviceAddedInternal(int device_id,
-                                         const std::string& device_name);
+                                         const std::string& device_name,
+                                         int vendor_id,
+                                         int product_id);
 
   // Returns true if |last_keyboard_device_id_| is Apple's.
   bool IsAppleKeyboard() const;
+  // Returns true if |last_keyboard_device_id_| is Hotrod remote.
+  bool IsHotrodRemote() const;
+  // Returns true if |last_keyboard_device_id_| is of given |device_type|.
+  bool IsLastKeyboardOfType(DeviceType device_type) const;
 
   // Returns true if the target for |event| would prefer to receive raw function
   // keys instead of having them rewritten into back, forward, brightness,
diff --git a/chrome/browser/chromeos/events/event_rewriter_unittest.cc b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
index 79845a6..535c889 100644
--- a/chrome/browser/chromeos/events/event_rewriter_unittest.cc
+++ b/chrome/browser/chromeos/events/event_rewriter_unittest.cc
@@ -389,6 +389,7 @@
 void EventRewriterTest::TestRewriteNumPadKeys() {
   TestingPrefServiceSyncable prefs;
   EventRewriter rewriter(NULL);
+  rewriter.KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
   rewriter.set_last_keyboard_device_id_for_testing(kKeyboardDeviceId);
   rewriter.set_pref_service_for_testing(&prefs);
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_util.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_util.cc
index a97f16d..a12bfe3 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_util.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_util.cc
@@ -119,7 +119,10 @@
       // MTP, or provided file system), we should resolve the path.
       switch (params->local_path_option) {
         case NO_LOCAL_PATH_RESOLUTION:
-          break;  // No special handling needed.
+          // Pass empty local path.
+          params->selected_files.push_back(
+              ui::SelectedFileInfo(file_path, base::FilePath()));
+          break;
         case NEED_LOCAL_PATH_FOR_OPENING:
           GetFileNativeLocalPathForOpening(
               profile,
@@ -137,9 +140,10 @@
                          base::Passed(&params)));
           return;  // Remaining work is done in ContinueGetSelectedFileInfo.
       }
+    } else {
+      params->selected_files.push_back(
+          ui::SelectedFileInfo(file_path, file_path));
     }
-    params->selected_files.push_back(
-        ui::SelectedFileInfo(file_path, base::FilePath()));
   }
   params->callback.Run(params->selected_files);
 }
diff --git a/chrome/browser/chromeos/extensions/input_method_api.cc b/chrome/browser/chromeos/extensions/input_method_api.cc
index 5234e6d..030f278 100644
--- a/chrome/browser/chromeos/extensions/input_method_api.cc
+++ b/chrome/browser/chromeos/extensions/input_method_api.cc
@@ -4,12 +4,13 @@
 
 #include "chrome/browser/chromeos/extensions/input_method_api.h"
 
+#include "base/command_line.h"
 #include "base/lazy_instance.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/extensions/input_method_event_router.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
+#include "chromeos/chromeos_switches.h"
 #include "chromeos/ime/extension_ime_util.h"
 #include "chromeos/ime/input_method_descriptor.h"
 #include "chromeos/ime/input_method_manager.h"
@@ -26,6 +27,19 @@
 
 namespace extensions {
 
+ExtensionFunction::ResponseAction GetInputMethodConfigFunction::Run() {
+#if !defined(OS_CHROMEOS)
+  EXTENSION_FUNCTION_VALIDATE(false);
+#else
+  base::DictionaryValue* output = new base::DictionaryValue();
+  output->SetBoolean(
+      "isPhysicalKeyboardAutocorrectEnabled",
+      CommandLine::ForCurrentProcess()->HasSwitch(
+          chromeos::switches::kEnablePhysicalKeyboardAutocorrect));
+  return RespondNow(OneArgument(output));
+#endif
+}
+
 ExtensionFunction::ResponseAction GetCurrentInputMethodFunction::Run() {
 #if !defined(OS_CHROMEOS)
   EXTENSION_FUNCTION_VALIDATE(false);
@@ -92,6 +106,7 @@
   EventRouter::Get(context_)->RegisterObserver(this, kOnInputMethodChanged);
   ExtensionFunctionRegistry* registry =
       ExtensionFunctionRegistry::GetInstance();
+  registry->RegisterFunction<GetInputMethodConfigFunction>();
   registry->RegisterFunction<GetCurrentInputMethodFunction>();
   registry->RegisterFunction<SetCurrentInputMethodFunction>();
   registry->RegisterFunction<GetInputMethodsFunction>();
@@ -117,10 +132,6 @@
 
 void InputMethodAPI::OnListenerAdded(
     const extensions::EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("InputMethodAPI::OnListenerAdded"));
-
   DCHECK(!input_method_event_router_.get());
   input_method_event_router_.reset(
       new chromeos::ExtensionInputMethodEventRouter(context_));
diff --git a/chrome/browser/chromeos/extensions/input_method_api.h b/chrome/browser/chromeos/extensions/input_method_api.h
index c7d45e5..18d610e 100644
--- a/chrome/browser/chromeos/extensions/input_method_api.h
+++ b/chrome/browser/chromeos/extensions/input_method_api.h
@@ -17,6 +17,22 @@
 
 namespace extensions {
 
+// Implements the inputMethodPrivate.getInputMethodConfig  method.
+class GetInputMethodConfigFunction : public UIThreadExtensionFunction {
+ public:
+  GetInputMethodConfigFunction() {}
+
+ protected:
+  virtual ~GetInputMethodConfigFunction() {}
+
+  virtual ResponseAction Run() override;
+
+ private:
+  DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.getInputMethodConfig",
+                             INPUTMETHODPRIVATE_GETINPUTMETHODCONFIG)
+  DISALLOW_COPY_AND_ASSIGN(GetInputMethodConfigFunction);
+};
+
 // Implements the inputMethodPrivate.getCurrentInputMethod method.
 class GetCurrentInputMethodFunction : public UIThreadExtensionFunction {
  public:
@@ -30,6 +46,7 @@
  private:
   DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.getCurrentInputMethod",
                              INPUTMETHODPRIVATE_GETCURRENTINPUTMETHOD)
+  DISALLOW_COPY_AND_ASSIGN(GetCurrentInputMethodFunction);
 };
 
 // Implements the inputMethodPrivate.setCurrentInputMethod method.
@@ -45,6 +62,7 @@
  private:
   DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.setCurrentInputMethod",
                              INPUTMETHODPRIVATE_SETCURRENTINPUTMETHOD)
+  DISALLOW_COPY_AND_ASSIGN(SetCurrentInputMethodFunction);
 };
 
 // Implements the inputMethodPrivate.getInputMethods method.
@@ -60,6 +78,7 @@
  private:
   DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.getInputMethods",
                              INPUTMETHODPRIVATE_GETINPUTMETHODS)
+  DISALLOW_COPY_AND_ASSIGN(GetInputMethodsFunction);
 };
 
 class InputMethodAPI : public BrowserContextKeyedAPI,
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index c9769b8..c2d75cda 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -545,8 +545,9 @@
   }
   virtual GuestMode GetGuestModeParam() const = 0;
   virtual const char* GetTestCaseNameParam() const = 0;
-  virtual std::string OnMessage(const std::string& name,
-                                const base::Value* value);
+  virtual void OnMessage(const std::string& name,
+                         const base::Value& value,
+                         std::string* output);
 
   scoped_ptr<LocalTestVolume> local_volume_;
   linked_ptr<DriveTestVolume> drive_volume_;
@@ -642,16 +643,24 @@
         !message_dictionary->GetString("name", &name))
       continue;
 
-    entry.function->Reply(OnMessage(name, value.get()));
+    std::string output;
+    OnMessage(name, *value.get(), &output);
+    if (HasFatalFailure())
+      break;
+    entry.function->Reply(output);
   }
 }
 
-std::string FileManagerBrowserTestBase::OnMessage(const std::string& name,
-                                                  const base::Value* value) {
+void FileManagerBrowserTestBase::OnMessage(const std::string& name,
+                                           const base::Value& value,
+                                           std::string* output) {
   if (name == "getTestName") {
     // Pass the test case name.
-    return GetTestCaseNameParam();
-  } else if (name == "getRootPaths") {
+    *output = GetTestCaseNameParam();
+    return;
+  }
+
+  if (name == "getRootPaths") {
     // Pass the root paths.
     const scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
     res->SetString("downloads",
@@ -659,13 +668,17 @@
     res->SetString("drive",
         "/" + drive::util::GetDriveMountPointPath(profile()
             ).BaseName().AsUTF8Unsafe() + "/root");
-    std::string jsonString;
-    base::JSONWriter::Write(res.get(), &jsonString);
-    return jsonString;
-  } else if (name == "isInGuestMode") {
+    base::JSONWriter::Write(res.get(), output);
+    return;
+  }
+
+  if (name == "isInGuestMode") {
     // Obtain whether the test is in guest mode or not.
-    return GetGuestModeParam() != NOT_IN_GUEST_MODE ? "true" : "false";
-  } else if (name == "getCwsWidgetContainerMockUrl") {
+    *output = GetGuestModeParam() != NOT_IN_GUEST_MODE ? "true" : "false";
+    return;
+  }
+
+  if (name == "getCwsWidgetContainerMockUrl") {
     // Obtain whether the test is in guest mode or not.
     const GURL url = embedded_test_server()->GetURL(
           "/chromeos/file_manager/cws_container_mock/index.html");
@@ -678,15 +691,16 @@
     const scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
     res->SetString("url", url.spec());
     res->SetString("origin", origin);
-    std::string jsonString;
-    base::JSONWriter::Write(res.get(), &jsonString);
-    return jsonString;
-  } else if (name == "addEntries") {
+    base::JSONWriter::Write(res.get(), output);
+    return;
+  }
+
+  if (name == "addEntries") {
     // Add entries to the specified volume.
     base::JSONValueConverter<AddEntriesMessage> add_entries_message_converter;
     AddEntriesMessage message;
-    if (!add_entries_message_converter.Convert(*value, &message))
-      return "onError";
+    ASSERT_TRUE(add_entries_message_converter.Convert(value, &message));
+
     for (size_t i = 0; i < message.entries.size(); ++i) {
       switch (message.volume) {
         case LOCAL_VOLUME:
@@ -705,23 +719,29 @@
           break;
       }
     }
-    return "onEntryAdded";
-  } else if (name == "mountFakeUsb") {
+
+    return;
+  }
+
+  if (name == "mountFakeUsb") {
     usb_volume_.reset(new FakeTestVolume("fake-usb",
                                          VOLUME_TYPE_REMOVABLE_DISK_PARTITION,
                                          chromeos::DEVICE_TYPE_USB));
     usb_volume_->Mount(profile());
-    return "true";
-  } else if (name == "mountFakeMtp") {
+    return;
+  }
+
+  if (name == "mountFakeMtp") {
     mtp_volume_.reset(new FakeTestVolume("fake-mtp",
                                          VOLUME_TYPE_MTP,
                                          chromeos::DEVICE_TYPE_UNKNOWN));
-    if (!mtp_volume_->PrepareTestEntries(profile()))
-      return "false";
+    ASSERT_TRUE(mtp_volume_->PrepareTestEntries(profile()));
+
     mtp_volume_->Mount(profile());
-    return "true";
+    return;
   }
-  return "unknownMessage";
+
+  FAIL() << "Unknown test message: " << name;
 }
 
 drive::DriveIntegrationService*
@@ -1145,29 +1165,6 @@
     return test_case_name_.c_str();
   }
 
-  virtual std::string OnMessage(const std::string& name,
-                                const base::Value* value) override {
-    if (name == "addAllUsers") {
-      AddAllUsers();
-      return "true";
-    } else if (name == "getWindowOwnerId") {
-      chrome::MultiUserWindowManager* const window_manager =
-          chrome::MultiUserWindowManager::GetInstance();
-      extensions::AppWindowRegistry* const app_window_registry =
-          extensions::AppWindowRegistry::Get(profile());
-      DCHECK(window_manager);
-      DCHECK(app_window_registry);
-
-      const extensions::AppWindowRegistry::AppWindowList& list =
-          app_window_registry->GetAppWindowsForApp(
-              file_manager::kFileManagerAppId);
-      return list.size() == 1u ?
-          window_manager->GetUserPresentingWindow(
-              list.front()->GetNativeWindow()) : "";
-    }
-    return FileManagerBrowserTestBase::OnMessage(name, value);
-  }
-
   std::string test_case_name_;
 };
 
@@ -1229,8 +1226,9 @@
     FileManagerBrowserTestBase::SetUp();
   }
 
-  virtual std::string OnMessage(const std::string& name,
-                                const base::Value* value) override;
+  virtual void OnMessage(const std::string& name,
+                         const base::Value& value,
+                         std::string* output) override;
 
   virtual const char* GetTestManifestName() const override {
     return "gallery_test_manifest.json";
@@ -1250,15 +1248,17 @@
   std::string test_case_name_;
 };
 
-template<GuestMode M>
-std::string GalleryBrowserTestBase<M>::OnMessage(const std::string& name,
-                                                 const base::Value* value) {
+template <GuestMode M>
+void GalleryBrowserTestBase<M>::OnMessage(const std::string& name,
+                                          const base::Value& value,
+                                          std::string* output) {
   if (name == "getScripts") {
     std::string jsonString;
-    base::JSONWriter::Write(&scripts_, &jsonString);
-    return jsonString;
+    base::JSONWriter::Write(&scripts_, output);
+    return;
   }
-  return FileManagerBrowserTestBase::OnMessage(name, value);
+
+  FileManagerBrowserTestBase::OnMessage(name, value, output);
 }
 
 typedef GalleryBrowserTestBase<NOT_IN_GUEST_MODE> GalleryBrowserTest;
@@ -1437,8 +1437,9 @@
     FileManagerBrowserTestBase::SetUpCommandLine(command_line);
   }
 
-  virtual std::string OnMessage(const std::string& name,
-                                const base::Value* value) override;
+  virtual void OnMessage(const std::string& name,
+                         const base::Value& value,
+                         std::string* output) override;
 
   virtual const char* GetTestManifestName() const override {
     return "video_player_test_manifest.json";
@@ -1458,15 +1459,17 @@
   std::string test_case_name_;
 };
 
-template<GuestMode M>
-std::string VideoPlayerBrowserTestBase<M>::OnMessage(const std::string& name,
-                                                     const base::Value* value) {
+template <GuestMode M>
+void VideoPlayerBrowserTestBase<M>::OnMessage(const std::string& name,
+                                              const base::Value& value,
+                                              std::string* output) {
   if (name == "getScripts") {
     std::string jsonString;
-    base::JSONWriter::Write(&scripts_, &jsonString);
-    return jsonString;
+    base::JSONWriter::Write(&scripts_, output);
+    return;
   }
-  return FileManagerBrowserTestBase::OnMessage(name, value);
+
+  FileManagerBrowserTestBase::OnMessage(name, value, output);
 }
 
 typedef VideoPlayerBrowserTestBase<NOT_IN_GUEST_MODE> VideoPlayerBrowserTest;
diff --git a/chrome/browser/chromeos/file_manager/fileapi_util.cc b/chrome/browser/chromeos/file_manager/fileapi_util.cc
index 38d00a5..15550c5 100644
--- a/chrome/browser/chromeos/file_manager/fileapi_util.cc
+++ b/chrome/browser/chromeos/file_manager/fileapi_util.cc
@@ -394,13 +394,16 @@
   // Returns a result to the |callback_|.
   void NotifyComplete(Lifetime /* lifetime */) {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
-    callback_.Run(chooser_info_list_.Pass());
+    callback_.Run(*chooser_info_list_);
+    // Reset the list so that the file systems are not revoked at the
+    // destructor.
+    chooser_info_list_.reset();
   }
 
   // Returns an empty list to the |callback_|.
   void NotifyError(Lifetime /* lifetime */) {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
-    callback_.Run(make_scoped_ptr<FileChooserFileInfoList>(NULL));
+    callback_.Run(FileChooserFileInfoList());
   }
 
   scoped_refptr<storage::FileSystemContext> context_;
diff --git a/chrome/browser/chromeos/file_manager/fileapi_util.h b/chrome/browser/chromeos/file_manager/fileapi_util.h
index 55f6994..3756c7b 100644
--- a/chrome/browser/chromeos/file_manager/fileapi_util.h
+++ b/chrome/browser/chromeos/file_manager/fileapi_util.h
@@ -73,7 +73,7 @@
 // The callback used by
 // ConvertFileSelectedInfoListToFileChooserFileInfoList. Returns the result of
 // the conversion as a list.
-typedef base::Callback<void(scoped_ptr<FileChooserFileInfoList>)>
+typedef base::Callback<void(const FileChooserFileInfoList&)>
     FileChooserFileInfoListCallback;
 
 // Returns a file system context associated with the given profile and the
diff --git a/chrome/browser/chromeos/file_manager/fileapi_util_unittest.cc b/chrome/browser/chromeos/file_manager/fileapi_util_unittest.cc
index 0ad49e5..0b837e2 100644
--- a/chrome/browser/chromeos/file_manager/fileapi_util_unittest.cc
+++ b/chrome/browser/chromeos/file_manager/fileapi_util_unittest.cc
@@ -24,9 +24,9 @@
 namespace {
 
 // Passes the |result| to the |output| pointer.
-void PassFileChooserFileInfoList(scoped_ptr<FileChooserFileInfoList>* output,
-                                 scoped_ptr<FileChooserFileInfoList> result) {
-  *output = result.Pass();
+void PassFileChooserFileInfoList(FileChooserFileInfoList* output,
+                                 const FileChooserFileInfoList& result) {
+  *output = result;
 }
 
 // Creates the drive integration service for the |profile|.
@@ -106,7 +106,7 @@
   }
 
   // Run the test target.
-  scoped_ptr<FileChooserFileInfoList> result;
+  FileChooserFileInfoList result;
   ConvertSelectedFileInfoListToFileChooserFileInfoList(
       context,
       GURL("http://example.com"),
@@ -115,30 +115,28 @@
   content::RunAllBlockingPoolTasksUntilIdle();
 
   // Check the result.
-  ASSERT_TRUE(result);
-  ASSERT_EQ(3u, result->size());
+  ASSERT_EQ(3u, result.size());
 
-  EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("/native/File 1.txt")),
-            result->at(0).file_path);
-  EXPECT_EQ("display_name", result->at(0).display_name);
-  EXPECT_FALSE(result->at(0).file_system_url.is_valid());
+  EXPECT_EQ(FILE_PATH_LITERAL("/native/File 1.txt"),
+            result[0].file_path.value());
+  EXPECT_EQ("display_name", result[0].display_name);
+  EXPECT_FALSE(result[0].file_system_url.is_valid());
 
-  EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("/native/cache/xxx")),
-            result->at(1).file_path);
-  EXPECT_EQ("display_name", result->at(1).display_name);
-  EXPECT_FALSE(result->at(1).file_system_url.is_valid());
+  EXPECT_EQ(FILE_PATH_LITERAL("/native/cache/xxx"),
+            result[1].file_path.value());
+  EXPECT_EQ("display_name", result[1].display_name);
+  EXPECT_FALSE(result[1].file_system_url.is_valid());
 
-  EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL(
-                "/special/drive-test-user-hash/root/File 1.txt")),
-            result->at(2).file_path);
-  EXPECT_TRUE(result->at(2).display_name.empty());
-  EXPECT_TRUE(result->at(2).file_system_url.is_valid());
+  EXPECT_EQ(FILE_PATH_LITERAL("/special/drive-test-user-hash/root/File 1.txt"),
+            result[2].file_path.value());
+  EXPECT_TRUE(result[2].display_name.empty());
+  EXPECT_TRUE(result[2].file_system_url.is_valid());
   const storage::FileSystemURL url =
-      context->CrackURL(result->at(2).file_system_url);
+      context->CrackURL(result[2].file_system_url);
   EXPECT_EQ(GURL("http://example.com"), url.origin());
   EXPECT_EQ(storage::kFileSystemTypeIsolated, url.mount_type());
   EXPECT_EQ(storage::kFileSystemTypeDrive, url.type());
-  EXPECT_EQ(26u, result->at(2).length);
+  EXPECT_EQ(26u, result[2].length);
 }
 
 }  // namespace
diff --git a/chrome/browser/chromeos/first_run/first_run_view.cc b/chrome/browser/chromeos/first_run/first_run_view.cc
index d3aecb62..0a586de 100644
--- a/chrome/browser/chromeos/first_run/first_run_view.cc
+++ b/chrome/browser/chromeos/first_run/first_run_view.cc
@@ -31,7 +31,8 @@
   extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
       web_contents);
 
-  web_contents->GetRenderViewHost()->GetView()->SetBackgroundOpaque(false);
+  web_contents->GetRenderViewHost()->GetView()->SetBackgroundColor(
+      SK_ColorTRANSPARENT);
 }
 
 FirstRunActor* FirstRunView::GetActor() {
diff --git a/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc b/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
index 14ba220..3be6ec7 100644
--- a/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
+++ b/chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.cc
@@ -96,6 +96,7 @@
        IDS_IME_NAME_INPUTMETHOD_HANGUL_AHNMATAE},
       {"__MSG_INPUTMETHOD_HANGUL_ROMAJA__",
        IDS_IME_NAME_INPUTMETHOD_HANGUL_ROMAJA},
+      {"__MSG_INPUTMETHOD_HANGUL__", IDS_IME_NAME_INPUTMETHOD_HANGUL},
       {"__MSG_INPUTMETHOD_MOZC_JP__", IDS_IME_NAME_INPUTMETHOD_MOZC_JP},
       {"__MSG_INPUTMETHOD_MOZC_US__", IDS_IME_NAME_INPUTMETHOD_MOZC_US},
       {"__MSG_INPUTMETHOD_PINYIN__", IDS_IME_NAME_INPUTMETHOD_PINYIN},
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc
index 406a2cd..d7e48fbb 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine.cc
@@ -27,6 +27,7 @@
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/ime/candidate_window.h"
 #include "ui/base/ime/chromeos/ime_keymap.h"
+#include "ui/base/ime/text_input_flags.h"
 #include "ui/events/event.h"
 #include "ui/events/event_processor.h"
 #include "ui/events/keycodes/dom4/keycode_converter.h"
@@ -566,6 +567,13 @@
       break;
   }
 
+  context.auto_correct =
+      !(input_context.flags & ui::TEXT_INPUT_FLAG_AUTOCORRECT_OFF);
+  context.auto_complete =
+      !(input_context.flags & ui::TEXT_INPUT_FLAG_AUTOCOMPLETE_OFF);
+  context.spell_check =
+      !(input_context.flags & ui::TEXT_INPUT_FLAG_SPELLCHECK_OFF);
+
   observer_->OnFocus(context);
 }
 
@@ -585,8 +593,9 @@
   active_component_id_ = component_id;
   observer_->OnActivate(component_id);
   current_input_type_ = IMEBridge::Get()->GetCurrentTextInputType();
-  FocusIn(IMEEngineHandlerInterface::InputContext(
-      current_input_type_, ui::TEXT_INPUT_MODE_DEFAULT));
+  FocusIn(IMEEngineHandlerInterface::InputContext(current_input_type_,
+                                                  ui::TEXT_INPUT_MODE_DEFAULT,
+                                                  ui::TEXT_INPUT_FLAG_NONE));
   EnableInputView();
 }
 
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
index cc4b628..efdebc5 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
@@ -20,6 +20,7 @@
 #include "ui/base/ime/chromeos/ime_bridge.h"
 #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h"
 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
+#include "ui/base/ime/text_input_flags.h"
 #include "ui/events/event.h"
 
 namespace chromeos {
@@ -172,7 +173,8 @@
   // onFocus event should be fired if FocusIn function is called.
   ExtensionTestMessageListener focus_listener("onFocus:text", false);
   IMEEngineHandlerInterface::InputContext context(ui::TEXT_INPUT_TYPE_TEXT,
-                                                  ui::TEXT_INPUT_MODE_DEFAULT);
+                                                  ui::TEXT_INPUT_MODE_DEFAULT,
+                                                  ui::TEXT_INPUT_FLAG_NONE);
   engine_handler->FocusIn(context);
   ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
   ASSERT_TRUE(focus_listener.was_satisfied());
@@ -252,7 +254,8 @@
 
   engine_handler->Enable("APIArgumentIME");
   IMEEngineHandlerInterface::InputContext context(ui::TEXT_INPUT_TYPE_TEXT,
-                                                  ui::TEXT_INPUT_MODE_DEFAULT);
+                                                  ui::TEXT_INPUT_MODE_DEFAULT,
+                                                  ui::TEXT_INPUT_FLAG_NONE);
   engine_handler->FocusIn(context);
 
   {
@@ -929,7 +932,8 @@
     {
       ExtensionTestMessageListener focus_listener("onFocus:text", false);
       IMEEngineHandlerInterface::InputContext context(
-          ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT);
+          ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT,
+          ui::TEXT_INPUT_FLAG_NONE);
       engine_handler->FocusIn(context);
       ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
       ASSERT_TRUE(focus_listener.was_satisfied());
@@ -937,7 +941,8 @@
     {
       ExtensionTestMessageListener focus_listener("onFocus:search", false);
       IMEEngineHandlerInterface::InputContext context(
-          ui::TEXT_INPUT_TYPE_SEARCH, ui::TEXT_INPUT_MODE_DEFAULT);
+          ui::TEXT_INPUT_TYPE_SEARCH, ui::TEXT_INPUT_MODE_DEFAULT,
+          ui::TEXT_INPUT_FLAG_NONE);
       engine_handler->FocusIn(context);
       ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
       ASSERT_TRUE(focus_listener.was_satisfied());
@@ -945,7 +950,8 @@
     {
       ExtensionTestMessageListener focus_listener("onFocus:tel", false);
       IMEEngineHandlerInterface::InputContext context(
-          ui::TEXT_INPUT_TYPE_TELEPHONE, ui::TEXT_INPUT_MODE_DEFAULT);
+          ui::TEXT_INPUT_TYPE_TELEPHONE, ui::TEXT_INPUT_MODE_DEFAULT,
+          ui::TEXT_INPUT_FLAG_NONE);
       engine_handler->FocusIn(context);
       ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
       ASSERT_TRUE(focus_listener.was_satisfied());
@@ -953,7 +959,8 @@
     {
       ExtensionTestMessageListener focus_listener("onFocus:url", false);
       IMEEngineHandlerInterface::InputContext context(
-          ui::TEXT_INPUT_TYPE_URL, ui::TEXT_INPUT_MODE_DEFAULT);
+          ui::TEXT_INPUT_TYPE_URL, ui::TEXT_INPUT_MODE_DEFAULT,
+          ui::TEXT_INPUT_FLAG_NONE);
       engine_handler->FocusIn(context);
       ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
       ASSERT_TRUE(focus_listener.was_satisfied());
@@ -961,7 +968,8 @@
     {
       ExtensionTestMessageListener focus_listener("onFocus:email", false);
       IMEEngineHandlerInterface::InputContext context(
-          ui::TEXT_INPUT_TYPE_EMAIL, ui::TEXT_INPUT_MODE_DEFAULT);
+          ui::TEXT_INPUT_TYPE_EMAIL, ui::TEXT_INPUT_MODE_DEFAULT,
+          ui::TEXT_INPUT_FLAG_NONE);
       engine_handler->FocusIn(context);
       ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
       ASSERT_TRUE(focus_listener.was_satisfied());
@@ -969,7 +977,8 @@
     {
       ExtensionTestMessageListener focus_listener("onFocus:number", false);
       IMEEngineHandlerInterface::InputContext context(
-          ui::TEXT_INPUT_TYPE_NUMBER, ui::TEXT_INPUT_MODE_DEFAULT);
+          ui::TEXT_INPUT_TYPE_NUMBER, ui::TEXT_INPUT_MODE_DEFAULT,
+          ui::TEXT_INPUT_FLAG_NONE);
       engine_handler->FocusIn(context);
       ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
       ASSERT_TRUE(focus_listener.was_satisfied());
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_interface.h b/chrome/browser/chromeos/input_method/input_method_engine_interface.h
index edd0a8c..b7ffe9bd 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_interface.h
+++ b/chrome/browser/chromeos/input_method/input_method_engine_interface.h
@@ -89,6 +89,9 @@
   struct InputContext {
     int id;
     std::string type;
+    bool auto_correct;
+    bool auto_complete;
+    bool spell_check;
   };
 
   struct UsageEntry {
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
index 1edbbf0..0401f41 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -15,6 +15,7 @@
 #include "chromeos/ime/mock_component_extension_ime_manager_delegate.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
+#include "ui/base/ime/text_input_flags.h"
 
 namespace chromeos {
 
@@ -138,7 +139,7 @@
 
   void FocusIn(ui::TextInputType input_type) {
     IMEEngineHandlerInterface::InputContext input_context(
-        input_type, ui::TEXT_INPUT_MODE_DEFAULT);
+        input_type, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE);
     engine_->FocusIn(input_context);
     IMEBridge::Get()->SetCurrentTextInputType(input_type);
   }
diff --git a/chrome/browser/chromeos/login/DEPS b/chrome/browser/chromeos/login/DEPS
index dbb97d3..e8c309f 100644
--- a/chrome/browser/chromeos/login/DEPS
+++ b/chrome/browser/chromeos/login/DEPS
@@ -3,6 +3,7 @@
   "+athena/screen/public",
   "+athena/util",
   "+components/captive_portal",
+  "+components/login",
   "+components/user_manager",
   "+extensions/components/native_app_window",
 
diff --git a/chrome/browser/chromeos/login/auth/chrome_login_performer.cc b/chrome/browser/chromeos/login/auth/chrome_login_performer.cc
new file mode 100644
index 0000000..ef49ec4
--- /dev/null
+++ b/chrome/browser/chromeos/login/auth/chrome_login_performer.cc
@@ -0,0 +1,177 @@
+// 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/chromeos/login/auth/chrome_login_performer.h"
+
+#include "base/bind.h"
+#include "base/thread_task_runner_handle.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.h"
+#include "chrome/browser/chromeos/login/login_utils.h"
+#include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h"
+#include "chrome/browser/chromeos/login/supervised/supervised_user_constants.h"
+#include "chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h"
+#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
+#include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+
+namespace chromeos {
+
+ChromeLoginPerformer::ChromeLoginPerformer(Delegate* delegate)
+    : LoginPerformer(base::ThreadTaskRunnerHandle::Get(), delegate),
+      weak_factory_(this) {
+}
+
+ChromeLoginPerformer::~ChromeLoginPerformer() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ChromeLoginPerformer, public:
+
+bool ChromeLoginPerformer::RunTrustedCheck(const base::Closure& callback) {
+  CrosSettings* cros_settings = CrosSettings::Get();
+
+  CrosSettingsProvider::TrustedStatus status =
+      cros_settings->PrepareTrustedValues(
+          base::Bind(&ChromeLoginPerformer::DidRunTrustedCheck,
+                     weak_factory_.GetWeakPtr(),
+                     callback));
+  // Must not proceed without signature verification.
+  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
+    if (delegate_)
+      delegate_->PolicyLoadFailed();
+    else
+      NOTREACHED();
+    return true;  // Some callback was called.
+  } else if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED) {
+    // Value of AllowNewUser setting is still not verified.
+    // Another attempt will be invoked after verification completion.
+    return false;
+  } else {
+    DCHECK(status == CrosSettingsProvider::TRUSTED);
+    // CrosSettingsProvider::TRUSTED
+    callback.Run();
+    return true;  // Some callback was called.
+  }
+}
+
+void ChromeLoginPerformer::DidRunTrustedCheck(const base::Closure& callback) {
+  CrosSettings* cros_settings = CrosSettings::Get();
+
+  CrosSettingsProvider::TrustedStatus status =
+      cros_settings->PrepareTrustedValues(
+          base::Bind(&ChromeLoginPerformer::DidRunTrustedCheck,
+                     weak_factory_.GetWeakPtr(),
+                     callback));
+  // Must not proceed without signature verification.
+  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
+    if (delegate_)
+      delegate_->PolicyLoadFailed();
+    else
+      NOTREACHED();
+  } else if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED) {
+    // Value of AllowNewUser setting is still not verified.
+    // Another attempt will be invoked after verification completion.
+    return;
+  } else {
+    DCHECK(status == CrosSettingsProvider::TRUSTED);
+    callback.Run();
+  }
+}
+
+bool ChromeLoginPerformer::IsUserWhitelisted(const std::string& user_id,
+                                             bool* wildcard_match) {
+  return LoginUtils::IsWhitelisted(user_id, wildcard_match);
+}
+
+void ChromeLoginPerformer::RunOnlineWhitelistCheck(
+    const std::string& user_id,
+    bool wildcard_match,
+    const base::Closure& success_callback,
+    const base::Closure& failure_callback) {
+  // On enterprise devices, reconfirm login permission with the server.
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
+  if (connector->IsEnterpriseManaged() && wildcard_match &&
+      !connector->IsNonEnterpriseUser(user_id)) {
+    wildcard_login_checker_.reset(new policy::WildcardLoginChecker());
+    wildcard_login_checker_->Start(
+        ProfileHelper::GetSigninProfile()->GetRequestContext(),
+        base::Bind(&ChromeLoginPerformer::OnlineWildcardLoginCheckCompleted,
+                   weak_factory_.GetWeakPtr(),
+                   success_callback,
+                   failure_callback));
+  } else {
+    success_callback.Run();
+  }
+}
+
+scoped_refptr<Authenticator> ChromeLoginPerformer::CreateAuthenticator() {
+  return LoginUtils::Get()->CreateAuthenticator(this);
+}
+
+bool ChromeLoginPerformer::AreSupervisedUsersAllowed() {
+  return user_manager::UserManager::Get()->AreSupervisedUsersAllowed();
+}
+
+bool ChromeLoginPerformer::UseExtendedAuthenticatorForSupervisedUser(
+    const UserContext& user_context) {
+  SupervisedUserAuthentication* authentication =
+      ChromeUserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
+  return authentication->GetPasswordSchema(user_context.GetUserID()) ==
+         SupervisedUserAuthentication::SCHEMA_SALT_HASHED;
+}
+
+UserContext ChromeLoginPerformer::TransformSupervisedKey(
+    const UserContext& context) {
+  SupervisedUserAuthentication* authentication =
+      ChromeUserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
+  return authentication->TransformKey(context);
+}
+
+void ChromeLoginPerformer::SetupSupervisedUserFlow(const std::string& user_id) {
+  SupervisedUserLoginFlow* new_flow = new SupervisedUserLoginFlow(user_id);
+  new_flow->set_host(ChromeUserManager::Get()->GetUserFlow(user_id)->host());
+  ChromeUserManager::Get()->SetUserFlow(user_id, new_flow);
+}
+
+void ChromeLoginPerformer::SetupEasyUnlockUserFlow(const std::string& user_id) {
+  ChromeUserManager::Get()->SetUserFlow(user_id,
+                                        new EasyUnlockUserLoginFlow(user_id));
+}
+
+bool ChromeLoginPerformer::CheckPolicyForUser(const std::string& user_id) {
+  // Login is not allowed if policy could not be loaded for the account.
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
+  policy::DeviceLocalAccountPolicyService* policy_service =
+      connector->GetDeviceLocalAccountPolicyService();
+  return policy_service && policy_service->IsPolicyAvailableForUser(user_id);
+}
+////////////////////////////////////////////////////////////////////////////////
+// ChromeLoginPerformer, private:
+
+content::BrowserContext* ChromeLoginPerformer::GetSigninContext() {
+  return ProfileHelper::GetSigninProfile();
+}
+
+net::URLRequestContextGetter* ChromeLoginPerformer::GetSigninRequestContext() {
+  return ProfileHelper::GetSigninProfile()->GetRequestContext();
+}
+
+void ChromeLoginPerformer::OnlineWildcardLoginCheckCompleted(
+    const base::Closure& success_callback,
+    const base::Closure& failure_callback,
+    policy::WildcardLoginChecker::Result result) {
+  if (result == policy::WildcardLoginChecker::RESULT_ALLOWED) {
+    success_callback.Run();
+  } else {
+    failure_callback.Run();
+  }
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/auth/chrome_login_performer.h b/chrome/browser/chromeos/login/auth/chrome_login_performer.h
new file mode 100644
index 0000000..e29b8dc
--- /dev/null
+++ b/chrome/browser/chromeos/login/auth/chrome_login_performer.h
@@ -0,0 +1,80 @@
+// 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_CHROMEOS_LOGIN_AUTH_CHROME_LOGIN_PERFORMER_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_AUTH_CHROME_LOGIN_PERFORMER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/policy/wildcard_login_checker.h"
+#include "chromeos/login/auth/auth_status_consumer.h"
+#include "chromeos/login/auth/authenticator.h"
+#include "chromeos/login/auth/extended_authenticator.h"
+#include "chromeos/login/auth/login_performer.h"
+#include "chromeos/login/auth/online_attempt_host.h"
+#include "chromeos/login/auth/user_context.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+
+namespace policy {
+class WildcardLoginChecker;
+}
+
+namespace chromeos {
+
+// This class implements chrome-specific elements of Login Performer.
+
+class ChromeLoginPerformer : public LoginPerformer {
+ public:
+  explicit ChromeLoginPerformer(Delegate* delegate);
+  virtual ~ChromeLoginPerformer();
+
+ protected:
+  virtual bool RunTrustedCheck(const base::Closure& callback) override;
+  void DidRunTrustedCheck(const base::Closure& callback);
+  virtual bool IsUserWhitelisted(const std::string& user_id,
+                                 bool* wildcard_match) override;
+
+  virtual void RunOnlineWhitelistCheck(
+      const std::string& user_id,
+      bool wildcard_match,
+      const base::Closure& success_callback,
+      const base::Closure& failure_callback) override;
+  virtual bool AreSupervisedUsersAllowed() override;
+
+  virtual bool UseExtendedAuthenticatorForSupervisedUser(
+      const UserContext& user_context) override;
+
+  virtual UserContext TransformSupervisedKey(
+      const UserContext& context) override;
+
+  virtual void SetupSupervisedUserFlow(const std::string& user_id) override;
+
+  virtual void SetupEasyUnlockUserFlow(const std::string& user_id) override;
+
+  virtual scoped_refptr<Authenticator> CreateAuthenticator() override;
+  virtual bool CheckPolicyForUser(const std::string& user_id) override;
+  virtual content::BrowserContext* GetSigninContext() override;
+  virtual net::URLRequestContextGetter* GetSigninRequestContext() override;
+
+ private:
+  void OnlineWildcardLoginCheckCompleted(
+      const base::Closure& success_callback,
+      const base::Closure& failure_callback,
+      policy::WildcardLoginChecker::Result result);
+
+  // Used to verify logins that matched wildcard on the login whitelist.
+  scoped_ptr<policy::WildcardLoginChecker> wildcard_login_checker_;
+  base::WeakPtrFactory<ChromeLoginPerformer> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeLoginPerformer);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_AUTH_CHROME_LOGIN_PERFORMER_H_
diff --git a/chrome/browser/chromeos/login/auth/login_performer.cc b/chrome/browser/chromeos/login/auth/login_performer.cc
deleted file mode 100644
index 3b07888..0000000
--- a/chrome/browser/chromeos/login/auth/login_performer.cc
+++ /dev/null
@@ -1,372 +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/chromeos/login/auth/login_performer.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/metrics/histogram.h"
-#include "base/prefs/pref_service.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_restrictions.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/boot_times_loader.h"
-#include "chrome/browser/chromeos/login/login_utils.h"
-#include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h"
-#include "chrome/browser/chromeos/login/supervised/supervised_user_constants.h"
-#include "chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h"
-#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
-#include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
-#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
-#include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/common/pref_names.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/session_manager_client.h"
-#include "chromeos/login/user_names.h"
-#include "chromeos/settings/cros_settings_names.h"
-#include "components/user_manager/user_manager.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/browser/user_metrics.h"
-#include "google_apis/gaia/gaia_auth_util.h"
-#include "net/cookies/cookie_monster.h"
-#include "net/cookies/cookie_store.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
-
-using base::UserMetricsAction;
-using content::BrowserThread;
-
-namespace chromeos {
-
-LoginPerformer::LoginPerformer(Delegate* delegate)
-    : online_attempt_host_(this),
-      last_login_failure_(AuthFailure::AuthFailureNone()),
-      delegate_(delegate),
-      password_changed_(false),
-      password_changed_callback_count_(0),
-      auth_mode_(AUTH_MODE_INTERNAL),
-      weak_factory_(this) {
-}
-
-LoginPerformer::~LoginPerformer() {
-  DVLOG(1) << "Deleting LoginPerformer";
-  if (authenticator_.get())
-    authenticator_->SetConsumer(NULL);
-  if (extended_authenticator_.get())
-    extended_authenticator_->SetConsumer(NULL);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// LoginPerformer, AuthStatusConsumer implementation:
-
-void LoginPerformer::OnAuthFailure(const AuthFailure& failure) {
-  content::RecordAction(UserMetricsAction("Login_Failure"));
-  UMA_HISTOGRAM_ENUMERATION("Login.FailureReason",
-                            failure.reason(),
-                            AuthFailure::NUM_FAILURE_REASONS);
-
-  DVLOG(1) << "failure.reason " << failure.reason();
-  DVLOG(1) << "failure.error.state " << failure.error().state();
-
-  last_login_failure_ = failure;
-  if (delegate_) {
-    delegate_->OnAuthFailure(failure);
-    return;
-  } else {
-    // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
-    // happens during offline auth only.
-    NOTREACHED();
-  }
-}
-
-void LoginPerformer::OnRetailModeAuthSuccess(const UserContext& user_context) {
-  content::RecordAction(
-      UserMetricsAction("Login_DemoUserLoginSuccess"));
-  AuthStatusConsumer::OnRetailModeAuthSuccess(user_context);
-}
-
-void LoginPerformer::OnAuthSuccess(const UserContext& user_context) {
-  content::RecordAction(UserMetricsAction("Login_Success"));
-  VLOG(1) << "LoginSuccess hash: " << user_context.GetUserIDHash();
-  DCHECK(delegate_);
-  // After delegate_->OnAuthSuccess(...) is called, delegate_ releases
-  // LoginPerformer ownership. LP now manages it's lifetime on its own.
-  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
-  delegate_->OnAuthSuccess(user_context);
-}
-
-void LoginPerformer::OnOffTheRecordAuthSuccess() {
-  content::RecordAction(
-      UserMetricsAction("Login_GuestLoginSuccess"));
-
-  if (delegate_)
-    delegate_->OnOffTheRecordAuthSuccess();
-  else
-    NOTREACHED();
-}
-
-void LoginPerformer::OnPasswordChangeDetected() {
-  password_changed_ = true;
-  password_changed_callback_count_++;
-  if (delegate_) {
-    delegate_->OnPasswordChangeDetected();
-  } else {
-    NOTREACHED();
-  }
-}
-
-void LoginPerformer::OnChecked(const std::string& username, bool success) {
-  if (!delegate_) {
-    // Delegate is reset in case of successful offline login.
-    // See ExistingUserConstoller::OnAuthSuccess().
-    // Case when user has changed password and enters old password
-    // does not block user from sign in yet.
-    return;
-  }
-  delegate_->OnOnlineChecked(username, success);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// LoginPerformer, public:
-
-void LoginPerformer::PerformLogin(const UserContext& user_context,
-                                  AuthorizationMode auth_mode) {
-  auth_mode_ = auth_mode;
-  user_context_ = user_context;
-
-  CrosSettings* cros_settings = CrosSettings::Get();
-
-  // Whitelist check is always performed during initial login.
-  CrosSettingsProvider::TrustedStatus status =
-      cros_settings->PrepareTrustedValues(
-          base::Bind(&LoginPerformer::PerformLogin,
-                     weak_factory_.GetWeakPtr(),
-                     user_context_, auth_mode));
-  // Must not proceed without signature verification.
-  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
-    if (delegate_)
-      delegate_->PolicyLoadFailed();
-    else
-      NOTREACHED();
-    return;
-  } else if (status != CrosSettingsProvider::TRUSTED) {
-    // Value of AllowNewUser setting is still not verified.
-    // Another attempt will be invoked after verification completion.
-    return;
-  }
-
-  bool wildcard_match = false;
-  std::string email = gaia::CanonicalizeEmail(user_context.GetUserID());
-  bool is_whitelisted = LoginUtils::IsWhitelisted(email, &wildcard_match);
-  if (is_whitelisted) {
-    switch (auth_mode_) {
-      case AUTH_MODE_EXTENSION: {
-        // On enterprise devices, reconfirm login permission with the server.
-        policy::BrowserPolicyConnectorChromeOS* connector =
-            g_browser_process->platform_part()
-                ->browser_policy_connector_chromeos();
-        if (connector->IsEnterpriseManaged() && wildcard_match &&
-            !connector->IsNonEnterpriseUser(email)) {
-          wildcard_login_checker_.reset(new policy::WildcardLoginChecker());
-          wildcard_login_checker_->Start(
-                  ProfileHelper::GetSigninProfile()->GetRequestContext(),
-                  base::Bind(&LoginPerformer::OnlineWildcardLoginCheckCompleted,
-                             weak_factory_.GetWeakPtr()));
-        } else {
-          StartLoginCompletion();
-        }
-        break;
-      }
-      case AUTH_MODE_INTERNAL:
-        StartAuthentication();
-        break;
-    }
-  } else {
-    if (delegate_)
-      delegate_->WhiteListCheckFailed(user_context.GetUserID());
-    else
-      NOTREACHED();
-  }
-}
-
-void LoginPerformer::LoginAsSupervisedUser(
-    const UserContext& user_context) {
-  DCHECK_EQ(chromeos::login::kSupervisedUserDomain,
-            gaia::ExtractDomainName(user_context.GetUserID()));
-
-  CrosSettings* cros_settings = CrosSettings::Get();
-  CrosSettingsProvider::TrustedStatus status =
-        cros_settings->PrepareTrustedValues(
-            base::Bind(&LoginPerformer::LoginAsSupervisedUser,
-                       weak_factory_.GetWeakPtr(),
-                       user_context_));
-  // Must not proceed without signature verification.
-  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
-    if (delegate_)
-      delegate_->PolicyLoadFailed();
-    else
-      NOTREACHED();
-    return;
-  } else if (status != CrosSettingsProvider::TRUSTED) {
-    // Value of kAccountsPrefSupervisedUsersEnabled setting is still not
-    // verified. Another attempt will be invoked after verification completion.
-    return;
-  }
-
-  if (!user_manager::UserManager::Get()->AreSupervisedUsersAllowed()) {
-    LOG(ERROR) << "Login attempt of supervised user detected.";
-    delegate_->WhiteListCheckFailed(user_context.GetUserID());
-    return;
-  }
-
-  SupervisedUserLoginFlow* new_flow =
-      new SupervisedUserLoginFlow(user_context.GetUserID());
-  new_flow->set_host(
-      ChromeUserManager::Get()->GetUserFlow(user_context.GetUserID())->host());
-  ChromeUserManager::Get()->SetUserFlow(user_context.GetUserID(), new_flow);
-
-  SupervisedUserAuthentication* authentication =
-      ChromeUserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
-
-  UserContext user_context_copy = authentication->TransformKey(user_context);
-
-  if (authentication->GetPasswordSchema(user_context.GetUserID()) ==
-      SupervisedUserAuthentication::SCHEMA_SALT_HASHED) {
-    if (extended_authenticator_.get()) {
-      extended_authenticator_->SetConsumer(NULL);
-    }
-    extended_authenticator_ = ExtendedAuthenticator::Create(this);
-    // TODO(antrim) : Replace empty callback with explicit method.
-    // http://crbug.com/351268
-    BrowserThread::PostTask(
-        BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(&ExtendedAuthenticator::AuthenticateToMount,
-                   extended_authenticator_.get(),
-                   user_context_copy,
-                   ExtendedAuthenticator::ResultCallback()));
-
-  } else {
-    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
-    BrowserThread::PostTask(
-        BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(&Authenticator::LoginAsSupervisedUser,
-                   authenticator_.get(),
-                   user_context_copy));
-  }
-}
-
-void LoginPerformer::LoginRetailMode() {
-  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&Authenticator::LoginRetailMode, authenticator_.get()));
-}
-
-void LoginPerformer::LoginOffTheRecord() {
-  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get()));
-}
-
-void LoginPerformer::LoginAsPublicSession(const UserContext& user_context) {
-  // Login is not allowed if policy could not be loaded for the account.
-  policy::BrowserPolicyConnectorChromeOS* connector =
-      g_browser_process->platform_part()->browser_policy_connector_chromeos();
-  policy::DeviceLocalAccountPolicyService* policy_service =
-      connector->GetDeviceLocalAccountPolicyService();
-  if (!policy_service ||
-      !policy_service->IsPolicyAvailableForUser(user_context.GetUserID())) {
-    DCHECK(delegate_);
-    if (delegate_)
-      delegate_->PolicyLoadFailed();
-    return;
-  }
-
-  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&Authenticator::LoginAsPublicSession,
-                 authenticator_.get(),
-                 user_context));
-}
-
-void LoginPerformer::LoginAsKioskAccount(const std::string& app_user_id,
-                                         bool use_guest_mount) {
-  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&Authenticator::LoginAsKioskAccount, authenticator_.get(),
-                 app_user_id, use_guest_mount));
-}
-
-void LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&Authenticator::RecoverEncryptedData, authenticator_.get(),
-                 old_password));
-}
-
-void LoginPerformer::ResyncEncryptedData() {
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get()));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// LoginPerformer, private:
-
-void LoginPerformer::StartLoginCompletion() {
-  DVLOG(1) << "Login completion started";
-  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
-  Profile* profile = ProfileHelper::GetSigninProfile();
-
-  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&Authenticator::CompleteLogin, authenticator_.get(),
-                 profile,
-                 user_context_));
-  user_context_.ClearSecrets();
-}
-
-void LoginPerformer::StartAuthentication() {
-  DVLOG(1) << "Auth started";
-  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
-  Profile* profile = ProfileHelper::GetSigninProfile();
-  if (delegate_) {
-    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(),
-                   profile,
-                   user_context_));
-    // Make unobtrusive online check. It helps to determine password change
-    // state in the case when offline login fails.
-    online_attempt_host_.Check(profile->GetRequestContext(), user_context_);
-  } else {
-    NOTREACHED();
-  }
-  user_context_.ClearSecrets();
-}
-
-void LoginPerformer::OnlineWildcardLoginCheckCompleted(
-    policy::WildcardLoginChecker::Result result) {
-  if (result == policy::WildcardLoginChecker::RESULT_ALLOWED) {
-    StartLoginCompletion();
-  } else {
-    if (delegate_)
-      delegate_->WhiteListCheckFailed(user_context_.GetUserID());
-  }
-}
-
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc
new file mode 100644
index 0000000..afb95e0
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc
@@ -0,0 +1,20 @@
+// 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/chromeos/login/easy_unlock/easy_unlock_metrics.h"
+
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+
+namespace chromeos {
+
+void RecordEasyUnlockLoginEvent(EasyUnlockLoginEvent event) {
+  DCHECK_LT(event, EASY_SIGN_IN_LOGIN_EVENT_COUNT);
+
+  UMA_HISTOGRAM_ENUMERATION("EasyUnlock.SignIn.LoginEvent",
+                            event,
+                            EASY_SIGN_IN_LOGIN_EVENT_COUNT);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h
new file mode 100644
index 0000000..83f94db
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h
@@ -0,0 +1,56 @@
+// 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_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_METRICS_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_METRICS_H_
+
+namespace chromeos {
+
+// Tracking login events for Easy unlock metrics.
+// This enum is used to define the buckets for an enumerated UMA histogram.
+// Hence,
+//   (a) existing enumerated constants should never be deleted or reordered, and
+//   (b) new constants should only be appended at the end of the enumeration.
+enum EasyUnlockLoginEvent {
+  // User is successfully authenticated using Easy Sign-in.
+  EASY_SIGN_IN_SUCCESS = 0,
+  // Easy sign-in failed to authenticate the user.
+  EASY_SIGN_IN_FAILURE = 1,
+
+  // Password is used for sign-in because there is no pairing data.
+  PASSWORD_SIGN_IN_NO_PAIRING = 2,
+  // Password is used for sign-in because pairing data is changed.
+  PASSWORD_SIGN_IN_PAIRING_CHANGED = 3,
+  // Password is used for sign-in because of user hardlock.
+  PASSWORD_SIGN_IN_USER_HARDLOCK = 4,
+  // Password is used for sign-in because Easy unlock service is not active.
+  PASSWORD_SIGN_IN_SERVICE_NOT_ACTIVE = 5,
+  // Password is used for sign-in because Bluetooth is not on.
+  PASSWORD_SIGN_IN_NO_BLUETOOTH = 6,
+  // Password is used for sign-in because Easy unlock is connecting.
+  PASSWORD_SIGN_IN_BLUETOOTH_CONNECTING = 7,
+  // Password is used for sign-in because no eligible phones found.
+  PASSWORD_SIGN_IN_NO_PHONE = 8,
+  // Password is used for sign-in because phone could not be authenticated.
+  PASSWORD_SIGN_IN_PHONE_NOT_AUTHENTICATED = 9,
+  // Password is used for sign-in because phone is locked.
+  PASSWORD_SIGN_IN_PHONE_LOCKED = 10,
+  // Password is used for sign-in because phone does not have lock screen.
+  PASSWORD_SIGN_IN_PHONE_NOT_LOCKABLE = 11,
+  // Password is used for sign-in because phone is not close enough.
+  PASSWORD_SIGN_IN_PHONE_NOT_NEARBY = 12,
+  // Password is used for sign-in because phone is not supported.
+  PASSWORD_SIGN_IN_PHONE_UNSUPPORTED = 13,
+  // Password is used for sign-in because user types in passowrd. This is
+  // unlikely to happen though.
+  PASSWORD_SIGN_IN_WITH_AUTHENTICATED_PHONE = 14,
+
+  EASY_SIGN_IN_LOGIN_EVENT_COUNT  // Must be the last.
+};
+
+void RecordEasyUnlockLoginEvent(EasyUnlockLoginEvent event);
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_METRICS_H_
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc
new file mode 100644
index 0000000..8356c75
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc
@@ -0,0 +1,56 @@
+// 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/chromeos/login/easy_unlock/easy_unlock_user_login_flow.h"
+
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/signin/easy_unlock_service.h"
+
+EasyUnlockUserLoginFlow::EasyUnlockUserLoginFlow(const std::string& user_id)
+    : chromeos::ExtendedUserFlow(user_id) {
+}
+
+EasyUnlockUserLoginFlow::~EasyUnlockUserLoginFlow() {}
+
+bool EasyUnlockUserLoginFlow::CanLockScreen() {
+  return true;
+}
+
+bool EasyUnlockUserLoginFlow::ShouldLaunchBrowser() {
+  return true;
+}
+
+bool EasyUnlockUserLoginFlow::ShouldSkipPostLoginScreens() {
+  return false;
+}
+
+bool EasyUnlockUserLoginFlow::HandleLoginFailure(
+    const chromeos::AuthFailure& failure) {
+  Profile* profile = chromeos::ProfileHelper::GetSigninProfile();
+  EasyUnlockService* service = EasyUnlockService::Get(profile);
+  if (!service)
+    return false;
+  service->HandleAuthFailure(user_id());
+  UnregisterFlowSoon();
+  return true;
+}
+
+void EasyUnlockUserLoginFlow::HandleLoginSuccess(
+    const chromeos::UserContext& context) {
+}
+
+bool EasyUnlockUserLoginFlow::HandlePasswordChangeDetected() {
+  return false;
+}
+
+void EasyUnlockUserLoginFlow::HandleOAuthTokenStatusChange(
+    user_manager::User::OAuthTokenStatus status) {
+}
+
+void EasyUnlockUserLoginFlow::LaunchExtraSteps(Profile* profile) {
+}
+
+bool EasyUnlockUserLoginFlow::SupportsEarlyRestartToApplyFlags() {
+  return true;
+}
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.h b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.h
new file mode 100644
index 0000000..b07e498c
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.h
@@ -0,0 +1,39 @@
+// 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_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_USER_LOGIN_FLOW_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_USER_LOGIN_FLOW_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/login/user_flow.h"
+
+// Handler for login flow initiazted by Easy Signin login attempt.
+// The only difference to the default login flow is hanlding of the auth
+// failure.
+class EasyUnlockUserLoginFlow : public chromeos::ExtendedUserFlow {
+ public:
+  explicit EasyUnlockUserLoginFlow(const std::string& user_id);
+  virtual ~EasyUnlockUserLoginFlow();
+
+ private:
+  // chromeos::ExtendedUserFlow implementation.
+  virtual bool CanLockScreen() override;
+  virtual bool ShouldLaunchBrowser() override;
+  virtual bool ShouldSkipPostLoginScreens() override;
+  virtual bool HandleLoginFailure(
+      const chromeos::AuthFailure& failure) override;
+  virtual void HandleLoginSuccess(
+      const chromeos::UserContext& context) override;
+  virtual bool HandlePasswordChangeDetected() override;
+  virtual void HandleOAuthTokenStatusChange(
+      user_manager::User::OAuthTokenStatus status) override;
+  virtual void LaunchExtraSteps(Profile* profile) override;
+  virtual bool SupportsEarlyRestartToApplyFlags() override;
+
+  DISALLOW_COPY_AND_ASSIGN(EasyUnlockUserLoginFlow);
+};
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_USER_LOGIN_FLOW_H_
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc
index 273bbc4..87f10ac 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc
@@ -8,6 +8,7 @@
 #include "base/bind_helpers.h"
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
 #include "chrome/browser/chromeos/login/screen_manager.h"
 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
@@ -31,7 +32,8 @@
       actor_(actor),
       captive_portal_status_(
           NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN),
-      auto_enrollment_state_(policy::AUTO_ENROLLMENT_STATE_IDLE) {
+      auto_enrollment_state_(policy::AUTO_ENROLLMENT_STATE_IDLE),
+      histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")) {
   if (actor_)
     actor_->SetDelegate(this);
 }
@@ -85,6 +87,7 @@
     Start();
     if (actor_)
       actor_->Show();
+    histogram_helper_->OnScreenShow();
   }
 }
 
@@ -221,6 +224,7 @@
   error_screen->SetErrorState(error_state,
                               network ? network->name() : std::string());
   get_screen_observer()->ShowErrorScreen();
+  histogram_helper_->OnErrorShow(error_state);
 }
 
 void AutoEnrollmentCheckScreen::SignalCompletion() {
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h
index dfc2479..b1f5c54 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h
@@ -15,6 +15,7 @@
 
 namespace chromeos {
 
+class ErrorScreensHistogramHelper;
 class ScreenManager;
 class ScreenObserver;
 
@@ -98,6 +99,8 @@
   NetworkPortalDetector::CaptivePortalStatus captive_portal_status_;
   policy::AutoEnrollmentState auto_enrollment_state_;
 
+  scoped_ptr<ErrorScreensHistogramHelper> histogram_helper_;
+
   DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentCheckScreen);
 };
 
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
index 54d6e6d..3005016 100644
--- a/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
+++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen.cc
@@ -133,9 +133,6 @@
 }
 
 void EnrollmentScreen::EnrollHost(const std::string& auth_token) {
-  // TODO(achuith, zork): Move this to ConfigureHost (crbug.com/419512).
-  StartupUtils::MarkEulaAccepted();
-
   actor_->Show();
   actor_->ShowEnrollmentSpinnerScreen();
   OnOAuthTokenAvailable(auth_token);
diff --git a/chrome/browser/chromeos/login/error_screens_histogram_helper.cc b/chrome/browser/chromeos/login/error_screens_histogram_helper.cc
new file mode 100644
index 0000000..0696859
--- /dev/null
+++ b/chrome/browser/chromeos/login/error_screens_histogram_helper.cc
@@ -0,0 +1,127 @@
+// 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/chromeos/login/error_screens_histogram_helper.h"
+
+#include "base/metrics/histogram.h"
+
+namespace chromeos {
+
+namespace {
+
+static const char kOobeErrorScreensCounterPrefix[] = "OOBE.NetworkErrorShown.";
+static const char kOobeTimeSpentOnErrorScreensPrefix[] =
+    "OOBE.ErrorScreensTime.";
+
+const base::TimeDelta time_min = base::TimeDelta::FromMilliseconds(10);
+const base::TimeDelta time_max = base::TimeDelta::FromMinutes(3);
+const int time_bucket_count = 50;
+
+std::string ErrorToString(ErrorScreen::ErrorState error) {
+  switch (error) {
+    case ErrorScreen::ERROR_STATE_PORTAL:
+      return ".Portal";
+    case ErrorScreen::ERROR_STATE_OFFLINE:
+      return ".Offline";
+    case ErrorScreen::ERROR_STATE_PROXY:
+      return ".Proxy";
+    case ErrorScreen::ERROR_STATE_AUTH_EXT_TIMEOUT:
+      return ".AuthExtTimeout";
+    default:
+      NOTREACHED() << "Invalid ErrorState " << error;
+      return std::string();
+  }
+}
+
+void StoreErrorScreenToHistogram(const std::string& screen_name,
+                                 ErrorScreen::ErrorState error) {
+  if (error <= ErrorScreen::ERROR_STATE_UNKNOWN ||
+      error > ErrorScreen::ERROR_STATE_NONE)
+    return;
+  std::string histogram_name = kOobeErrorScreensCounterPrefix + screen_name;
+  int boundary = ErrorScreen::ERROR_STATE_NONE + 1;
+  // This comes from UMA_HISTOGRAM_ENUMERATION macros. Can't use it because of
+  // non const histogram name.
+  base::HistogramBase* histogram = base::LinearHistogram::FactoryGet(
+      histogram_name,
+      1,
+      boundary,
+      boundary + 1,
+      base::HistogramBase::kUmaTargetedHistogramFlag);
+  histogram->Add(error);
+}
+
+void StoreTimeOnErrorScreenToHistogram(const std::string& screen_name,
+                                       ErrorScreen::ErrorState error,
+                                       const base::TimeDelta& time_delta) {
+  if (error <= ErrorScreen::ERROR_STATE_UNKNOWN ||
+      error > ErrorScreen::ERROR_STATE_NONE)
+    return;
+  std::string histogram_name =
+      kOobeTimeSpentOnErrorScreensPrefix + screen_name + ErrorToString(error);
+
+  // This comes from UMA_HISTOGRAM_MEDIUM_TIMES macros. Can't use it because of
+  // non const histogram name.
+  base::HistogramBase* histogram = base::Histogram::FactoryTimeGet(
+      histogram_name,
+      time_min,
+      time_max,
+      time_bucket_count,
+      base::HistogramBase::kUmaTargetedHistogramFlag);
+
+  histogram->AddTime(time_delta);
+}
+
+}  // namespace
+
+ErrorScreensHistogramHelper::ErrorScreensHistogramHelper(
+    const std::string& screen_name)
+    : screen_name_(screen_name),
+      was_shown_(false),
+      last_error_shown_(ErrorScreen::ERROR_STATE_NONE) {
+}
+
+void ErrorScreensHistogramHelper::OnScreenShow() {
+  was_shown_ = true;
+}
+
+void ErrorScreensHistogramHelper::OnErrorShow(ErrorScreen::ErrorState error) {
+  OnErrorShowTime(error, base::Time::Now());
+}
+
+void ErrorScreensHistogramHelper::OnErrorShowTime(ErrorScreen::ErrorState error,
+                                                  base::Time now) {
+  last_error_shown_ = error;
+  if (error_screen_start_time_.is_null())
+    error_screen_start_time_ = now;
+  StoreErrorScreenToHistogram(screen_name_, error);
+}
+
+void ErrorScreensHistogramHelper::OnErrorHide() {
+  OnErrorHideTime(base::Time::Now());
+}
+
+void ErrorScreensHistogramHelper::OnErrorHideTime(base::Time now) {
+  if (error_screen_start_time_.is_null())
+    return;
+  time_on_error_screens_ += now - error_screen_start_time_;
+  error_screen_start_time_ = base::Time();
+}
+
+ErrorScreensHistogramHelper::~ErrorScreensHistogramHelper() {
+  if (was_shown_) {
+    if (last_error_shown_ == ErrorScreen::ERROR_STATE_NONE) {
+      StoreErrorScreenToHistogram(screen_name_, ErrorScreen::ERROR_STATE_NONE);
+    } else {
+      if (!error_screen_start_time_.is_null()) {
+        time_on_error_screens_ += base::Time::Now() - error_screen_start_time_;
+        error_screen_start_time_ = base::Time();
+      }
+      StoreTimeOnErrorScreenToHistogram(
+          screen_name_, last_error_shown_, time_on_error_screens_);
+    }
+  }
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/error_screens_histogram_helper.h b/chrome/browser/chromeos/login/error_screens_histogram_helper.h
new file mode 100644
index 0000000..dd3a555
--- /dev/null
+++ b/chrome/browser/chromeos/login/error_screens_histogram_helper.h
@@ -0,0 +1,42 @@
+// 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_CHROMEOS_LOGIN_ERROR_SCREENS_HISTOGRAM_HELPER_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_ERROR_SCREENS_HISTOGRAM_HELPER_H_
+
+#include "chrome/browser/chromeos/login/screens/error_screen.h"
+
+namespace chromeos {
+FORWARD_DECLARE_TEST(ErrorScreensHistogramHelperTest, TestShowHideTime);
+FORWARD_DECLARE_TEST(ErrorScreensHistogramHelperTest, TestShowHideShowHideTime);
+FORWARD_DECLARE_TEST(ErrorScreensHistogramHelperTest, TestShowShowHideTime);
+
+class ErrorScreensHistogramHelper {
+ public:
+  explicit ErrorScreensHistogramHelper(const std::string& screen_name);
+  void OnScreenShow();
+  void OnErrorShow(ErrorScreen::ErrorState error);
+  void OnErrorHide();
+  ~ErrorScreensHistogramHelper();
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(ErrorScreensHistogramHelperTest, TestShowHideTime);
+  FRIEND_TEST_ALL_PREFIXES(ErrorScreensHistogramHelperTest,
+                           TestShowHideShowHideTime);
+  FRIEND_TEST_ALL_PREFIXES(ErrorScreensHistogramHelperTest,
+                           TestShowShowHideTime);
+  // functions for testing.
+  void OnErrorShowTime(ErrorScreen::ErrorState error, base::Time now);
+  void OnErrorHideTime(base::Time now);
+
+  std::string screen_name_;
+  bool was_shown_;
+  ErrorScreen::ErrorState last_error_shown_;
+  base::Time error_screen_start_time_;
+  base::TimeDelta time_on_error_screens_;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_ERROR_SCREENS_HISTOGRAM_HELPER_H_
diff --git a/chrome/browser/chromeos/login/error_screens_histogram_helper_unittest.cc b/chrome/browser/chromeos/login/error_screens_histogram_helper_unittest.cc
new file mode 100644
index 0000000..fa6950e0
--- /dev/null
+++ b/chrome/browser/chromeos/login/error_screens_histogram_helper_unittest.cc
@@ -0,0 +1,115 @@
+// 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/chromeos/login/error_screens_histogram_helper.h"
+
+#include "base/metrics/statistics_recorder.h"
+#include "base/test/histogram_tester.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+class ErrorScreensHistogramHelperTest : public testing::Test {
+ public:
+  virtual void SetUp() override {
+    helper_.reset(new ErrorScreensHistogramHelper("TestScreen"));
+    second_helper_.reset(new ErrorScreensHistogramHelper("TestScreen2"));
+  }
+
+  content::TestBrowserThreadBundle thread_bundle_;
+  base::HistogramTester histograms_;
+  scoped_ptr<ErrorScreensHistogramHelper> helper_;
+  scoped_ptr<ErrorScreensHistogramHelper> second_helper_;
+};
+
+// No errors when screen was not shown.
+TEST_F(ErrorScreensHistogramHelperTest, DoesNotShowScreen) {
+  helper_.reset();
+  histograms_.ExpectTotalCount("OOBE.NetworkErrorShown.TestScreen", 0);
+}
+
+// No errors when screen was shown and error was not.
+TEST_F(ErrorScreensHistogramHelperTest, ShowScreenWithoutError) {
+  helper_->OnScreenShow();
+  helper_.reset();
+  second_helper_->OnScreenShow();
+  second_helper_.reset();
+  histograms_.ExpectUniqueSample(
+      "OOBE.NetworkErrorShown.TestScreen", ErrorScreen::ERROR_STATE_NONE, 1);
+  histograms_.ExpectUniqueSample(
+      "OOBE.NetworkErrorShown.TestScreen2", ErrorScreen::ERROR_STATE_NONE, 1);
+}
+
+// Show 3 offline errors and 1 portal error. Make sure in time histograms logged
+// portal error only.
+TEST_F(ErrorScreensHistogramHelperTest, ShowScreenAndError) {
+  helper_->OnScreenShow();
+  second_helper_->OnScreenShow();
+  helper_->OnErrorShow(ErrorScreen::ERROR_STATE_OFFLINE);
+  second_helper_->OnErrorShow(ErrorScreen::ERROR_STATE_PORTAL);
+  helper_->OnErrorShow(ErrorScreen::ERROR_STATE_OFFLINE);
+  helper_->OnErrorHide();
+  second_helper_->OnErrorHide();
+  helper_->OnErrorShow(ErrorScreen::ERROR_STATE_OFFLINE);
+  histograms_.ExpectUniqueSample(
+      "OOBE.NetworkErrorShown.TestScreen", ErrorScreen::ERROR_STATE_OFFLINE, 3);
+  histograms_.ExpectUniqueSample(
+      "OOBE.NetworkErrorShown.TestScreen2", ErrorScreen::ERROR_STATE_PORTAL, 1);
+  helper_->OnErrorShow(ErrorScreen::ERROR_STATE_PORTAL);
+  histograms_.ExpectBucketCount(
+      "OOBE.NetworkErrorShown.TestScreen", ErrorScreen::ERROR_STATE_PORTAL, 1);
+  histograms_.ExpectTotalCount("OOBE.ErrorScreensTime.TestScreen.Portal", 0);
+  helper_.reset();
+  histograms_.ExpectTotalCount("OOBE.ErrorScreensTime.TestScreen.Portal", 1);
+}
+
+// Show error and hide it after 1 sec.
+TEST_F(ErrorScreensHistogramHelperTest, TestShowHideTime) {
+  helper_->OnScreenShow();
+  second_helper_->OnScreenShow();
+  base::Time now = base::Time::Now();
+  helper_->OnErrorShowTime(ErrorScreen::ERROR_STATE_PORTAL, now);
+  now += base::TimeDelta::FromMilliseconds(1000);
+  helper_->OnErrorHideTime(now);
+  helper_.reset();
+  histograms_.ExpectUniqueSample(
+      "OOBE.ErrorScreensTime.TestScreen.Portal", 1000, 1);
+}
+
+// Show, hide, show, hide error with 1 sec interval. Make sure time logged in
+// histogram is 2 sec.
+TEST_F(ErrorScreensHistogramHelperTest, TestShowHideShowHideTime) {
+  helper_->OnScreenShow();
+  second_helper_->OnScreenShow();
+  base::Time now = base::Time::Now();
+  helper_->OnErrorShowTime(ErrorScreen::ERROR_STATE_PROXY, now);
+  now += base::TimeDelta::FromMilliseconds(1000);
+  helper_->OnErrorHideTime(now);
+  now += base::TimeDelta::FromMilliseconds(1000);
+  helper_->OnErrorShowTime(ErrorScreen::ERROR_STATE_PORTAL, now);
+  now += base::TimeDelta::FromMilliseconds(1000);
+  helper_->OnErrorHideTime(now);
+  helper_.reset();
+  histograms_.ExpectUniqueSample(
+      "OOBE.ErrorScreensTime.TestScreen.Portal", 2000, 1);
+}
+
+// Show, show, hide error with 1 sec interval. Make sure time logged in
+// histogram is 2 sec.
+TEST_F(ErrorScreensHistogramHelperTest, TestShowShowHideTime) {
+  helper_->OnScreenShow();
+  second_helper_->OnScreenShow();
+  base::Time now = base::Time::Now();
+  helper_->OnErrorShowTime(ErrorScreen::ERROR_STATE_PROXY, now);
+  now += base::TimeDelta::FromMilliseconds(1000);
+  helper_->OnErrorShowTime(ErrorScreen::ERROR_STATE_PORTAL, now);
+  now += base::TimeDelta::FromMilliseconds(1000);
+  helper_->OnErrorHideTime(now);
+  helper_.reset();
+  histograms_.ExpectUniqueSample(
+      "OOBE.ErrorScreensTime.TestScreen.Portal", 2000, 1);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index e6c79a74..54cf518 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -16,7 +16,6 @@
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "base/version.h"
@@ -24,11 +23,10 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/boot_times_loader.h"
 #include "chrome/browser/chromeos/customization_document.h"
-#include "chrome/browser/chromeos/first_run/first_run.h"
 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
+#include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
 #include "chrome/browser/chromeos/login/helper.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
@@ -42,7 +40,7 @@
 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/prefs/session_startup_pref.h"
+#include "chrome/browser/signin/easy_unlock_service.h"
 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
@@ -53,7 +51,6 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power_manager_client.h"
 #include "chromeos/dbus/session_manager_client.h"
-#include "chromeos/login/auth/user_context.h"
 #include "chromeos/login/user_names.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "components/google/core/browser/google_util.h"
@@ -88,11 +85,6 @@
 const char kCreateAccountURL[] =
     "https://accounts.google.com/NewAccount?service=mail";
 
-// ChromeVox tutorial URL (used in place of "getting started" url when
-// accessibility is enabled).
-const char kChromeVoxTutorialURLPattern[] =
-    "http://www.chromevox.com/tutorial/index.html?lang=%s";
-
 // Delay for transferring the auth cache to the system profile.
 const long int kAuthCacheTransferDelayMs = 2000;
 
@@ -126,6 +118,26 @@
                                    base::Bind(&RefreshPoliciesOnUIThread));
 }
 
+// Record UMA for Easy sign-in outcome.
+void RecordEasySignInOutcome(const std::string& user_id, bool success) {
+  EasyUnlockService* easy_unlock_service =
+      EasyUnlockService::Get(ProfileHelper::GetSigninProfile());
+  if (!easy_unlock_service)
+    return;
+  easy_unlock_service->RecordEasySignInOutcome(user_id, success);
+}
+
+// Record UMA for password login of regular user when Easy sign-in is enabled.
+void RecordPasswordLoginEvent(const UserContext& user_context) {
+  EasyUnlockService* easy_unlock_service =
+      EasyUnlockService::Get(ProfileHelper::GetSigninProfile());
+  if (user_context.GetUserType() == user_manager::USER_TYPE_REGULAR &&
+      user_context.GetAuthFlow() == UserContext::AUTH_FLOW_OFFLINE &&
+      easy_unlock_service) {
+    easy_unlock_service->RecordPasswordLoginEvent(user_context.GetUserID());
+  }
+}
+
 }  // namespace
 
 // static
@@ -136,6 +148,7 @@
 
 ExistingUserController::ExistingUserController(LoginDisplayHost* host)
     : auth_status_consumer_(NULL),
+      last_login_attempt_auth_flow_(UserContext::AUTH_FLOW_OFFLINE),
       host_(host),
       login_display_(host_->CreateLoginDisplay(this)),
       num_login_attempts_(0),
@@ -325,8 +338,7 @@
 
 void ExistingUserController::CancelPasswordChangedFlow() {
   login_performer_.reset(NULL);
-  login_display_->SetUIEnabled(true);
-  StartPublicSessionAutoLoginTimer();
+  PerformLoginFinishedActions(true /* start public session timer */);
 }
 
 void ExistingUserController::CreateAccount() {
@@ -343,11 +355,7 @@
     return;
   }
 
-  // Stop the auto-login timer when attempting login.
-  StopPublicSessionAutoLoginTimer();
-
-  // Disable UI while loading user profile.
-  login_display_->SetUIEnabled(false);
+  PerformPreLoginActions(user_context);
 
   if (!time_init_.is_null()) {
     base::TimeDelta delta = base::Time::Now() - time_init_;
@@ -386,7 +394,7 @@
     // Enable UI for the enrollment screen. SetUIEnabled(true) will post a
     // request to show the sign-in screen again when invoked at the sign-in
     // screen; invoke SetUIEnabled() after navigating to the enrollment screen.
-    login_display_->SetUIEnabled(true);
+    PerformLoginFinishedActions(false /* don't start public session timer */);
   } else {
     PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
   }
@@ -424,69 +432,56 @@
     return;
   }
 
-  if (!user_context.HasCredentials())
+  if (!user_context.HasCredentials()) {
+    // For easy unlock auth, login UI gets disabled prior to attempting login.
+    if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_EASY_UNLOCK)
+      login_display_->SetUIEnabled(true);
     return;
-
-  // Stop the auto-login timer when attempting login.
-  StopPublicSessionAutoLoginTimer();
-
-  // Disable clicking on other windows.
-  login_display_->SetUIEnabled(false);
-
-  if (last_login_attempt_username_ != user_context.GetUserID()) {
-    last_login_attempt_username_ = user_context.GetUserID();
-    num_login_attempts_ = 0;
-    // Also reset state variables, which are used to determine password change.
-    offline_failed_ = false;
-    online_succeeded_for_.clear();
   }
-  num_login_attempts_++;
+
+  PerformPreLoginActions(user_context);
   PerformLogin(user_context, LoginPerformer::AUTH_MODE_INTERNAL);
 }
 
 void ExistingUserController::PerformLogin(
     const UserContext& user_context,
     LoginPerformer::AuthorizationMode auth_mode) {
-  ChromeUserManager::Get()->GetUserFlow(last_login_attempt_username_)->set_host(
+  ChromeUserManager::Get()->GetUserFlow(user_context.GetUserID())->set_host(
       host_);
 
   BootTimesLoader::Get()->RecordLoginAttempted();
 
-  // Disable UI while loading user profile.
-  login_display_->SetUIEnabled(false);
+  last_login_attempt_auth_flow_ = user_context.GetAuthFlow();
 
   // Use the same LoginPerformer for subsequent login as it has state
   // such as Authenticator instance.
   if (!login_performer_.get() || num_login_attempts_ <= 1) {
     // Only one instance of LoginPerformer should exist at a time.
     login_performer_.reset(NULL);
-    login_performer_.reset(new LoginPerformer(this));
+    login_performer_.reset(new ChromeLoginPerformer(this));
   }
 
-  is_login_in_progress_ = true;
   if (gaia::ExtractDomainName(user_context.GetUserID()) ==
       chromeos::login::kSupervisedUserDomain) {
     login_performer_->LoginAsSupervisedUser(user_context);
   } else {
     login_performer_->PerformLogin(user_context, auth_mode);
+    RecordPasswordLoginEvent(user_context);
   }
   SendAccessibilityAlert(
       l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNING_IN));
 }
 
 void ExistingUserController::LoginAsRetailModeUser() {
-  // Stop the auto-login timer when attempting login.
-  StopPublicSessionAutoLoginTimer();
+  PerformPreLoginActions(UserContext(user_manager::USER_TYPE_RETAIL_MODE,
+                                     chromeos::login::kRetailModeUserName));
 
-  // Disable clicking on other windows.
-  login_display_->SetUIEnabled(false);
   // TODO(rkc): Add a CHECK to make sure retail mode logins are allowed once
   // the enterprise policy wiring is done for retail mode.
 
   // Only one instance of LoginPerformer should exist at a time.
   login_performer_.reset(NULL);
-  login_performer_.reset(new LoginPerformer(this));
-  is_login_in_progress_ = true;
+  login_performer_.reset(new ChromeLoginPerformer(this));
   login_performer_->LoginRetailMode();
   SendAccessibilityAlert(
       l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_DEMOUSER));
@@ -498,11 +493,8 @@
     return;
   }
 
-  // Stop the auto-login timer when attempting login.
-  StopPublicSessionAutoLoginTimer();
-
-  // Disable clicking on other windows.
-  login_display_->SetUIEnabled(false);
+  PerformPreLoginActions(UserContext(user_manager::USER_TYPE_GUEST,
+                                     chromeos::login::kGuestUserName));
 
   CrosSettingsProvider::TrustedStatus status =
       cros_settings_->PrepareTrustedValues(
@@ -512,9 +504,7 @@
   if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
     login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1,
                               HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
-    // Reenable clicking on other windows and status area.
-    login_display_->SetUIEnabled(true);
-    StartPublicSessionAutoLoginTimer();
+    PerformLoginFinishedActions(false /* don't start public session timer */);
     display_email_.clear();
     return;
   } else if (status != CrosSettingsProvider::TRUSTED) {
@@ -531,17 +521,14 @@
     // this nicely.
     login_display_->ShowError(IDS_LOGIN_ERROR_WHITELIST, 1,
                               HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
-    // Reenable clicking on other windows and status area.
-    login_display_->SetUIEnabled(true);
-    StartPublicSessionAutoLoginTimer();
+    PerformLoginFinishedActions(true /* start public session timer */);
     display_email_.clear();
     return;
   }
 
   // Only one instance of LoginPerformer should exist at a time.
   login_performer_.reset(NULL);
-  login_performer_.reset(new LoginPerformer(this));
-  is_login_in_progress_ = true;
+  login_performer_.reset(new ChromeLoginPerformer(this));
   login_performer_->LoginOffTheRecord();
   SendAccessibilityAlert(
       l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_OFFRECORD));
@@ -560,11 +547,7 @@
     return;
   }
 
-  // Stop the auto-login timer when attempting login.
-  StopPublicSessionAutoLoginTimer();
-
-  // Disable clicking on other windows.
-  login_display_->SetUIEnabled(false);
+  PerformPreLoginActions(user_context);
 
   CrosSettingsProvider::TrustedStatus status =
       cros_settings_->PrepareTrustedValues(
@@ -576,8 +559,7 @@
   if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
     login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1,
                               HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
-    // Re-enable clicking on other windows.
-    login_display_->SetUIEnabled(true);
+    PerformLoginFinishedActions(false /* don't start public session timer */);
     return;
   }
 
@@ -591,9 +573,7 @@
   const user_manager::User* user =
       user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
   if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
-    // Re-enable clicking on other windows.
-    login_display_->SetUIEnabled(true);
-    StartPublicSessionAutoLoginTimer();
+    PerformLoginFinishedActions(true /* start public session timer */);
     return;
   }
 
@@ -768,16 +748,19 @@
 //
 
 void ExistingUserController::OnAuthFailure(const AuthFailure& failure) {
-  is_login_in_progress_ = false;
   offline_failed_ = true;
-
   guest_mode_url_ = GURL::EmptyGURL();
   std::string error = failure.GetErrorString();
 
+  PerformLoginFinishedActions(false /* don't start public session timer */);
+
+  // TODO(xiyuan): Move into EasyUnlockUserLoginFlow.
+  if (last_login_attempt_auth_flow_ == UserContext::AUTH_FLOW_EASY_UNLOCK)
+    RecordEasySignInOutcome(last_login_attempt_username_, false);
+
   if (ChromeUserManager::Get()
           ->GetUserFlow(last_login_attempt_username_)
           ->HandleLoginFailure(failure)) {
-    login_display_->SetUIEnabled(true);
     return;
   }
 
@@ -816,8 +799,6 @@
           ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
       }
     }
-    // Reenable clicking on other windows and status area.
-    login_display_->SetUIEnabled(true);
     login_display_->ClearAndEnablePassword();
     StartPublicSessionAutoLoginTimer();
   }
@@ -847,6 +828,13 @@
       ->GetUserFlow(user_context.GetUserID())
       ->HandleLoginSuccess(user_context);
 
+  // TODO(xiyuan): Move into EasyUnlockUserLoginFlow.
+  if (last_login_attempt_auth_flow_ == UserContext::AUTH_FLOW_EASY_UNLOCK) {
+    DCHECK_EQ(last_login_attempt_username_, user_context.GetUserID());
+    DCHECK_EQ(last_login_attempt_auth_flow_, user_context.GetAuthFlow());
+    RecordEasySignInOutcome(last_login_attempt_username_, true);
+  }
+
   StopPublicSessionAutoLoginTimer();
 
   const bool has_auth_cookies =
@@ -875,46 +863,20 @@
   }
 }
 
-void ExistingUserController::OnProfilePrepared(Profile* profile) {
+void ExistingUserController::OnProfilePrepared(Profile* profile,
+                                               bool browser_launched) {
   // Reenable clicking on other windows and status area.
   login_display_->SetUIEnabled(true);
 
-  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
-  if (user_manager->IsCurrentUserNew() &&
-      user_manager->IsLoggedInAsSupervisedUser()) {
-    // Supervised users should launch into empty desktop on first run.
-    CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
-  }
-
-  if (user_manager->IsCurrentUserNew() &&
-      !ChromeUserManager::Get()
-           ->GetCurrentUserFlow()
-           ->ShouldSkipPostLoginScreens() &&
-      !WizardController::default_controller()->skip_post_login_screens()) {
-    // Don't specify start URLs if the administrator has configured the start
-    // URLs via policy.
-    if (!SessionStartupPref::TypeIsManaged(profile->GetPrefs()))
-      InitializeStartUrls();
-
-    // Mark the device as registered., i.e. the second part of OOBE as
-    // completed.
-    if (!StartupUtils::IsDeviceRegistered())
-      StartupUtils::MarkDeviceRegistered(base::Closure());
-
-    if (CommandLine::ForCurrentProcess()->HasSwitch(
-          chromeos::switches::kOobeSkipPostLogin)) {
-      LoginUtils::Get()->DoBrowserLaunch(profile, host_);
-      host_ = NULL;
-    } else {
-      ActivateWizard(WizardController::kTermsOfServiceScreenName);
-    }
-  } else {
-    LoginUtils::Get()->DoBrowserLaunch(profile, host_);
+  if (browser_launched)
     host_ = NULL;
-  }
+
   // Inform |auth_status_consumer_| about successful login.
-  if (auth_status_consumer_)
-    auth_status_consumer_->OnAuthSuccess(UserContext());
+  // TODO(nkostylev): Pass UserContext back crbug.com/424550
+  if (auth_status_consumer_) {
+    auth_status_consumer_->
+        OnAuthSuccess(UserContext(last_login_attempt_username_));
+  }
 }
 
 void ExistingUserController::OnOffTheRecordAuthSuccess() {
@@ -968,13 +930,11 @@
 }
 
 void ExistingUserController::WhiteListCheckFailed(const std::string& email) {
-  is_login_in_progress_ = false;
+  PerformLoginFinishedActions(true /* start public session timer */);
   offline_failed_ = false;
 
   ShowError(IDS_LOGIN_ERROR_WHITELIST, email);
 
-  // Reenable clicking on other windows and status area.
-  login_display_->SetUIEnabled(true);
   login_display_->ShowSigninUI(email);
 
   if (auth_status_consumer_) {
@@ -983,22 +943,14 @@
   }
 
   display_email_.clear();
-
-  StartPublicSessionAutoLoginTimer();
 }
 
 void ExistingUserController::PolicyLoadFailed() {
   ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, "");
 
-  // Reenable clicking on other windows and status area.
-  is_login_in_progress_ = false;
+  PerformLoginFinishedActions(false /* don't start public session timer */);
   offline_failed_ = false;
-  login_display_->SetUIEnabled(true);
-
   display_email_.clear();
-
-  // Policy load failure stops login attempts -- restart the timer.
-  StartPublicSessionAutoLoginTimer();
 }
 
 void ExistingUserController::OnOnlineChecked(const std::string& username,
@@ -1023,11 +975,6 @@
   }
 }
 
-void ExistingUserController::ActivateWizard(const std::string& screen_name) {
-  scoped_ptr<base::DictionaryValue> params;
-  host_->StartWizard(screen_name, params.Pass());
-}
-
 LoginPerformer::AuthorizationMode ExistingUserController::auth_mode() const {
   if (login_performer_)
     return login_performer_->auth_mode();
@@ -1122,56 +1069,6 @@
   return host_->GetNativeWindow();
 }
 
-void ExistingUserController::InitializeStartUrls() const {
-  std::vector<std::string> start_urls;
-
-  const base::ListValue *urls;
-  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
-  bool can_show_getstarted_guide =
-      user_manager->GetActiveUser()->GetType() ==
-          user_manager::USER_TYPE_REGULAR &&
-      !user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
-  if (user_manager->IsLoggedInAsDemoUser()) {
-    if (CrosSettings::Get()->GetList(kStartUpUrls, &urls)) {
-      // The retail mode user will get start URLs from a special policy if it is
-      // set.
-      for (base::ListValue::const_iterator it = urls->begin();
-           it != urls->end(); ++it) {
-        std::string url;
-        if ((*it)->GetAsString(&url))
-          start_urls.push_back(url);
-      }
-    }
-    can_show_getstarted_guide = false;
-  // Skip the default first-run behavior for public accounts.
-  } else if (!user_manager->IsLoggedInAsPublicAccount()) {
-    if (AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
-      const char* url = kChromeVoxTutorialURLPattern;
-      PrefService* prefs = g_browser_process->local_state();
-      const std::string current_locale =
-          base::StringToLowerASCII(prefs->GetString(prefs::kApplicationLocale));
-      std::string vox_url = base::StringPrintf(url, current_locale.c_str());
-      start_urls.push_back(vox_url);
-      can_show_getstarted_guide = false;
-    }
-  }
-
-  // Only show getting started guide for a new user.
-  const bool should_show_getstarted_guide = user_manager->IsCurrentUserNew();
-
-  if (can_show_getstarted_guide && should_show_getstarted_guide) {
-    // Don't open default Chrome window if we're going to launch the first-run
-    // app. Because we dont' want the first-run app to be hidden in the
-    // background.
-    CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
-    first_run::MaybeLaunchDialogAfterSessionStart();
-  } else {
-    for (size_t i = 0; i < start_urls.size(); ++i) {
-      CommandLine::ForCurrentProcess()->AppendArg(start_urls[i]);
-    }
-  }
-}
-
 void ExistingUserController::ShowError(int error_id,
                                        const std::string& details) {
   // TODO(dpolukhin): show detailed error info. |details| string contains
@@ -1254,11 +1151,47 @@
     const UserContext& user_context) {
   // Only one instance of LoginPerformer should exist at a time.
   login_performer_.reset(NULL);
-  login_performer_.reset(new LoginPerformer(this));
-  is_login_in_progress_ = true;
+  login_performer_.reset(new ChromeLoginPerformer(this));
   login_performer_->LoginAsPublicSession(user_context);
   SendAccessibilityAlert(
       l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_PUBLIC_ACCOUNT));
 }
 
+void ExistingUserController::PerformPreLoginActions(
+    const UserContext& user_context) {
+  // Disable clicking on other windows and status tray.
+  login_display_->SetUIEnabled(false);
+
+  if (last_login_attempt_username_ != user_context.GetUserID()) {
+    last_login_attempt_username_ = user_context.GetUserID();
+    num_login_attempts_ = 0;
+
+    // Also reset state variables, which are used to determine password change.
+    offline_failed_ = false;
+    online_succeeded_for_.clear();
+  }
+
+  // Guard in cases when we're called twice but login process is still active.
+  // This might happen when login process is paused till signed settings status
+  // is verified which results in Login* method called again as a callback.
+  if (!is_login_in_progress_)
+    num_login_attempts_++;
+
+  is_login_in_progress_ = true;
+
+  // Stop the auto-login timer when attempting login.
+  StopPublicSessionAutoLoginTimer();
+}
+
+void ExistingUserController::PerformLoginFinishedActions(
+    bool start_public_session_timer) {
+  is_login_in_progress_ = false;
+
+  // Reenable clicking on other windows and status area.
+  login_display_->SetUIEnabled(true);
+
+  if (start_public_session_timer)
+    StartPublicSessionAutoLoginTimer();
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h
index cd4e90b..ca01c58 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.h
+++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -17,11 +17,12 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
-#include "chrome/browser/chromeos/login/auth/login_performer.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "chrome/browser/chromeos/login/ui/login_display.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chromeos/login/auth/login_performer.h"
+#include "chromeos/login/auth/user_context.h"
 #include "components/user_manager/user.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -36,7 +37,6 @@
 
 class CrosSettings;
 class LoginDisplayHost;
-class UserContext;
 
 namespace login {
 class NetworkStateHelper;
@@ -156,20 +156,15 @@
       const std::string& username, bool success) override;
 
   // LoginUtils::Delegate implementation:
-  virtual void OnProfilePrepared(Profile* profile) override;
+  virtual void OnProfilePrepared(Profile* profile,
+                                 bool browser_launched) override;
 
   // Called when device settings change.
   void DeviceSettingsChanged();
 
-  // Starts WizardController with the specified screen.
-  void ActivateWizard(const std::string& screen_name);
-
   // Returns corresponding native window.
   gfx::NativeWindow GetNativeWindow() const;
 
-  // Adds first-time login URLs.
-  void InitializeStartUrls() const;
-
   // Show error message. |error_id| error message ID in resources.
   // If |details| string is not empty, it specify additional error text
   // provided by authenticator, it is not localized.
@@ -235,6 +230,14 @@
   // preconditions have been verified.
   void LoginAsPublicSessionInternal(const UserContext& user_context);
 
+  // Performs sets of actions right prior to login has been started.
+  void PerformPreLoginActions(const UserContext& user_context);
+
+  // Performs set of actions when login has been completed or has been
+  // cancelled. If |start_public_session_timer| is true than public session
+  // auto-login timer is started.
+  void PerformLoginFinishedActions(bool start_public_session_timer);
+
   // Public session auto-login timer.
   scoped_ptr<base::OneShotTimer<ExistingUserController> > auto_login_timer_;
 
@@ -254,6 +257,9 @@
   // Username of the last login attempt.
   std::string last_login_attempt_username_;
 
+  // Auth flow of the last login attempt.
+  UserContext::AuthFlow last_login_attempt_auth_flow_;
+
   // OOBE/login display host.
   LoginDisplayHost* host_;
 
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
index af8078cf8..14dfc2d1 100644
--- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -163,6 +163,9 @@
         .WillRepeatedly(Return(false));
     EXPECT_CALL(*mock_user_manager_, Shutdown())
         .Times(1);
+    EXPECT_CALL(*mock_user_manager_, FindUser(_))
+        .Times(AnyNumber())
+        .WillRepeatedly(ReturnNull());
   }
 
   virtual void SetUpOnMainThread() override {
@@ -175,7 +178,8 @@
     profile_prepared_cb_ =
         base::Bind(&ExistingUserController::OnProfilePrepared,
                    base::Unretained(existing_user_controller()),
-                   testing_profile_.get());
+                   testing_profile_.get(),
+                   false);
   }
 
   virtual void TearDownOnMainThread() override {
@@ -232,10 +236,8 @@
 };
 
 IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ExistingUserLogin) {
-  // This is disabled twice: once right after signin but before checking for
-  // auto-enrollment, and again after doing an ownership status check.
   EXPECT_CALL(*mock_login_display_, SetUIEnabled(false))
-      .Times(2);
+      .Times(1);
   UserContext user_context(kUsername);
   user_context.SetKey(Key(kPassword));
   user_context.SetUserIDHash(kUsername);
@@ -246,10 +248,6 @@
       .Times(1)
       .WillOnce(InvokeWithoutArgs(&profile_prepared_cb_,
                                   &base::Callback<void(void)>::Run));
-  EXPECT_CALL(*mock_login_utils_,
-              DoBrowserLaunch(testing_profile_.get(),
-                              mock_login_display_host_.get()))
-      .Times(1);
   EXPECT_CALL(*mock_login_display_, SetUIEnabled(true))
       .Times(1);
   EXPECT_CALL(*mock_login_display_host_,
@@ -294,10 +292,6 @@
               StartWizardPtr(WizardController::kEnrollmentScreenName,
                              _))
       .Times(0);
-  EXPECT_CALL(*mock_login_display_host_,
-              StartWizardPtr(WizardController::kTermsOfServiceScreenName,
-                             NULL))
-      .Times(1);
   UserContext user_context(kNewUsername);
   user_context.SetKey(Key(kPassword));
   user_context.SetUserIDHash(kNewUsername);
@@ -327,7 +321,7 @@
   // This is disabled twice: once right after signin but before checking for
   // auto-enrollment, and again after doing an ownership status check.
   EXPECT_CALL(*mock_login_display_, SetUIEnabled(false))
-      .Times(2)
+      .Times(1)
       .InSequence(uiEnabledSequence);
   EXPECT_CALL(*mock_login_display_, SetUIEnabled(true))
       .Times(1)
@@ -437,10 +431,6 @@
         .Times(1)
         .WillOnce(InvokeWithoutArgs(&profile_prepared_cb_,
                                     &base::Callback<void(void)>::Run));
-    EXPECT_CALL(*mock_login_utils_,
-                DoBrowserLaunch(testing_profile_.get(),
-                                mock_login_display_host_.get()))
-        .Times(1);
     EXPECT_CALL(*mock_login_display_, SetUIEnabled(true))
         .Times(1);
     EXPECT_CALL(*mock_login_display_host_,
diff --git a/chrome/browser/chromeos/login/fake_login_utils.cc b/chrome/browser/chromeos/login/fake_login_utils.cc
index 342ac868..9caab9f 100644
--- a/chrome/browser/chromeos/login/fake_login_utils.cc
+++ b/chrome/browser/chromeos/login/fake_login_utils.cc
@@ -9,6 +9,7 @@
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/user_flow.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
@@ -60,11 +61,11 @@
                                     bool has_cookies,
                                     bool has_active_session,
                                     LoginUtils::Delegate* delegate) {
-  user_manager::UserManager::Get()->UserLoggedIn(
+  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+  user_manager->UserLoggedIn(
       user_context.GetUserID(), user_context.GetUserIDHash(), false);
   user_manager::User* user =
-      user_manager::UserManager::Get()->FindUserAndModify(
-          user_context.GetUserID());
+      user_manager->FindUserAndModify(user_context.GetUserID());
   DCHECK(user);
 
   // Make sure that we get the real Profile instead of the login Profile.
@@ -73,9 +74,8 @@
   profile->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
                                  user_context.GetUserID());
 
-  if (user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser()) {
-    user_manager::User* active_user =
-        user_manager::UserManager::Get()->GetActiveUser();
+  if (user_manager->IsLoggedInAsSupervisedUser()) {
+    user_manager::User* active_user = user_manager->GetActiveUser();
     std::string supervised_user_sync_id =
         ChromeUserManager::Get()->GetSupervisedUserManager()->GetUserSyncId(
             active_user->email());
@@ -89,8 +89,22 @@
       chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
       content::NotificationService::AllSources(),
       content::Details<Profile>(profile));
+
+  // Emulate UserSessionManager::InitializeUserSession() for now till
+  // FakeLoginUtils are deprecated.
+  bool browser_launched = false;
+  if (!user_manager->IsLoggedInAsKioskApp()) {
+    if (user_manager->IsCurrentUserNew()) {
+      NOTREACHED() << "Method not implemented.";
+    } else {
+      browser_launched = true;
+      LoginUtils::Get()->DoBrowserLaunch(profile,
+                                         LoginDisplayHostImpl::default_host());
+    }
+  }
+
   if (delegate)
-    delegate->OnProfilePrepared(profile);
+    delegate->OnProfilePrepared(profile, browser_launched);
 }
 
 void FakeLoginUtils::DelegateDeleted(LoginUtils::Delegate* delegate) {
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc
index ec623c6..bdf1b56b 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -25,7 +25,6 @@
 #include "base/strings/string_util.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/login/auth/login_performer.h"
 #include "chrome/browser/chromeos/login/lock/webui_screen_locker.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
@@ -507,10 +506,6 @@
       desktop_background_controller()->MoveDesktopToLockedContainer();
 #endif
 
-  input_method::InputMethodManager::Get()
-      ->GetActiveIMEState()
-      ->EnableLockScreenLayouts();
-
   bool state = true;
   VLOG(1) << "Emitting SCREEN_LOCK_STATE_CHANGED with state=" << state;
   content::NotificationService::current()->Notify(
@@ -519,6 +514,10 @@
       content::Details<bool>(&state));
   VLOG(1) << "Calling session manager's HandleLockScreenShown D-Bus method";
   DBusThreadManager::Get()->GetSessionManagerClient()->NotifyLockScreenShown();
+
+  input_method::InputMethodManager::Get()
+      ->GetActiveIMEState()
+      ->EnableLockScreenLayouts();
 }
 
 content::WebUI* ScreenLocker::GetAssociatedWebUI() {
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc
index 9618b3e4..46e68039 100644
--- a/chrome/browser/chromeos/login/login_manager_test.cc
+++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -118,14 +118,14 @@
 }
 
 void LoginManagerTest::InitializeWebContents() {
-    LoginDisplayHost* host = LoginDisplayHostImpl::default_host();
-    EXPECT_TRUE(host != NULL);
+  LoginDisplayHost* host = LoginDisplayHostImpl::default_host();
+  EXPECT_TRUE(host != NULL);
 
-    content::WebContents* web_contents =
-        host->GetWebUILoginView()->GetWebContents();
-    EXPECT_TRUE(web_contents != NULL);
-    set_web_contents(web_contents);
-    js_checker_.set_web_contents(web_contents);
-  }
+  content::WebContents* web_contents =
+      host->GetWebUILoginView()->GetWebContents();
+  EXPECT_TRUE(web_contents != NULL);
+  set_web_contents(web_contents);
+  js_checker_.set_web_contents(web_contents);
+}
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
index 9c4e297e8..153400d3 100644
--- a/chrome/browser/chromeos/login/login_utils.cc
+++ b/chrome/browser/chromeos/login/login_utils.cc
@@ -48,6 +48,7 @@
 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
 #include "chrome/browser/chromeos/login/user_flow.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
@@ -200,7 +201,8 @@
                                                    bool early_restart) override;
 
   // UserSessionManager::Delegate implementation:
-  virtual void OnProfilePrepared(Profile* profile) override;
+  virtual void OnProfilePrepared(Profile* profile,
+                                 bool browser_launched) override;
 #if defined(ENABLE_RLZ)
   virtual void OnRlzInitialized() override;
 #endif
@@ -371,12 +373,21 @@
   // as it coexist with SessionManager.
   delegate_ = delegate;
 
+  UserSessionManager::StartSessionType start_session_type =
+      UserAddingScreen::Get()->IsRunning() ?
+          UserSessionManager::SECONDARY_USER_SESSION :
+          UserSessionManager::PRIMARY_USER_SESSION;
+
   // For the transition part LoginUtils will just delegate profile
   // creation and initialization to SessionManager. Later LoginUtils will be
   // removed and all LoginUtils clients will just work with SessionManager
   // directly.
-  UserSessionManager::GetInstance()->StartSession(
-      user_context, authenticator_, has_auth_cookies, has_active_session, this);
+  UserSessionManager::GetInstance()->StartSession(user_context,
+                                                  start_session_type,
+                                                  authenticator_,
+                                                  has_auth_cookies,
+                                                  has_active_session,
+                                                  this);
 }
 
 void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) {
@@ -429,9 +440,10 @@
   return authenticator_;
 }
 
-void LoginUtilsImpl::OnProfilePrepared(Profile* profile) {
+void LoginUtilsImpl::OnProfilePrepared(Profile* profile,
+                                       bool browser_launched) {
   if (delegate_)
-    delegate_->OnProfilePrepared(profile);
+    delegate_->OnProfilePrepared(profile, browser_launched);
 }
 
 #if defined(ENABLE_RLZ)
diff --git a/chrome/browser/chromeos/login/login_utils.h b/chrome/browser/chromeos/login/login_utils.h
index cb84444..61d284a 100644
--- a/chrome/browser/chromeos/login/login_utils.h
+++ b/chrome/browser/chromeos/login/login_utils.h
@@ -29,7 +29,10 @@
   class Delegate {
    public:
     // Called after profile is loaded and prepared for the session.
-    virtual void OnProfilePrepared(Profile* profile) = 0;
+    // |browser_launched| will be true is browser has been launched, otherwise
+    // it will return false and client is responsible on launching browser.
+    virtual void OnProfilePrepared(Profile* profile,
+                                   bool browser_launched) = 0;
 
 #if defined(ENABLE_RLZ)
     // Called after post-profile RLZ initialization.
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index a0e34ba..44e84022 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -575,7 +575,7 @@
   SetSignFormField("Password", "fake_password");
   ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
 
-  EXPECT_EQ(l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_EMAIL),
+  EXPECT_EQ(l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_ACCOUNT_DETAILS),
             WaitForAndGetFatalErrorMessage());
 }
 
diff --git a/chrome/browser/chromeos/login/screens/base_screen.cc b/chrome/browser/chromeos/login/screens/base_screen.cc
index 2178c23..e2276b21 100644
--- a/chrome/browser/chromeos/login/screens/base_screen.cc
+++ b/chrome/browser/chromeos/login/screens/base_screen.cc
@@ -16,7 +16,7 @@
 BaseScreen::~BaseScreen() {
 }
 
-void BaseScreen::Initialize(ScreenContext* context) {
+void BaseScreen::Initialize(::login::ScreenContext* context) {
 }
 
 void BaseScreen::OnShow() {
@@ -44,7 +44,7 @@
 
 }
 
-void BaseScreen::SetContext(ScreenContext* context) {
+void BaseScreen::SetContext(::login::ScreenContext* context) {
 }
 
 void BaseScreen::OnButtonPressed(const std::string& button_id) {
diff --git a/chrome/browser/chromeos/login/screens/base_screen.h b/chrome/browser/chromeos/login/screens/base_screen.h
index 0555451..30ecb31 100644
--- a/chrome/browser/chromeos/login/screens/base_screen.h
+++ b/chrome/browser/chromeos/login/screens/base_screen.h
@@ -14,9 +14,12 @@
 class DictionaryValue;
 }
 
+namespace login {
+class ScreenContext;
+}
+
 namespace chromeos {
 
-class ScreenContext;
 class ScreenObserver;
 
 // Base class for the all OOBE/login/before-session screens.
@@ -50,7 +53,7 @@
   // at this point. Screen can alter context, resulting context will be passed
   // to JS. This method will be called once per instance of the Screen object,
   // unless |IsPermanent()| returns |true|.
-  virtual void Initialize(ScreenContext* context);
+  virtual void Initialize(::login::ScreenContext* context);
 
   // Called when screen appears.
   virtual void OnShow();
@@ -99,7 +102,7 @@
   friend class ScreenManager;
   friend class UpdateScreenTest;
 
-  void SetContext(ScreenContext* context);
+  void SetContext(::login::ScreenContext* context);
 
   ScreenObserver* screen_observer_;
 
diff --git a/chrome/browser/chromeos/login/screens/controller_pairing_screen.cc b/chrome/browser/chromeos/login/screens/controller_pairing_screen.cc
index 79d3b8e..7b7308e0 100644
--- a/chrome/browser/chromeos/login/screens/controller_pairing_screen.cc
+++ b/chrome/browser/chromeos/login/screens/controller_pairing_screen.cc
@@ -75,7 +75,7 @@
   switch (new_stage) {
     case ControllerPairingController::STAGE_DEVICES_DISCOVERY: {
       desired_page = kPageDevicesDiscovery;
-      context_.SetStringList(kContextKeyDevices, StringList());
+      context_.SetStringList(kContextKeyDevices, ::login::StringList());
       context_.SetString(kContextKeySelectedDevice, std::string());
       device_preselected_ = false;
       break;
@@ -98,6 +98,10 @@
                          shark_controller_->GetConfirmationCode());
       break;
     }
+    case ControllerPairingController::STAGE_PAIRING_DONE: {
+      get_screen_observer()->SetHostConfiguration();
+      break;
+    }
     case ControllerPairingController::STAGE_HOST_UPDATE_IN_PROGRESS: {
       desired_page = kPageHostUpdate;
       break;
diff --git a/chrome/browser/chromeos/login/screens/controller_pairing_screen.h b/chrome/browser/chromeos/login/screens/controller_pairing_screen.h
index fcb89de..3b02cfc 100644
--- a/chrome/browser/chromeos/login/screens/controller_pairing_screen.h
+++ b/chrome/browser/chromeos/login/screens/controller_pairing_screen.h
@@ -9,7 +9,7 @@
 
 #include "chrome/browser/chromeos/login/screens/base_screen.h"
 #include "chrome/browser/chromeos/login/screens/controller_pairing_screen_actor.h"
-#include "chrome/browser/chromeos/login/screens/screen_context.h"
+#include "components/login/screens/screen_context.h"
 #include "components/pairing/controller_pairing_controller.h"
 
 namespace chromeos {
@@ -49,7 +49,7 @@
 
   // Context for sharing data between C++ and JS.
   // TODO(dzhioev): move to BaseScreen when possible.
-  ScreenContext context_;
+  ::login::ScreenContext context_;
 
   ControllerPairingScreenActor* actor_;
 
diff --git a/chrome/browser/chromeos/login/screens/device_disabled_screen.cc b/chrome/browser/chromeos/login/screens/device_disabled_screen.cc
new file mode 100644
index 0000000..b84b336f
--- /dev/null
+++ b/chrome/browser/chromeos/login/screens/device_disabled_screen.cc
@@ -0,0 +1,112 @@
+// 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/chromeos/login/screens/device_disabled_screen.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/prefs/pref_service.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/login/screens/screen_observer.h"
+#include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
+#include "chrome/browser/chromeos/policy/server_backed_device_state.h"
+#include "chrome/common/pref_names.h"
+#include "chromeos/chromeos_switches.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
+
+namespace chromeos {
+
+DeviceDisabledScreen::DeviceDisabledScreen(ScreenObserver* observer,
+                                           DeviceDisabledScreenActor* actor)
+    : BaseScreen(observer),
+      showing_(false),
+      actor_(actor),
+      weak_factory_(this) {
+  DCHECK(actor_);
+  if (actor_)
+    actor_->SetDelegate(this);
+}
+
+DeviceDisabledScreen::~DeviceDisabledScreen() {
+  if (actor_)
+    actor_->SetDelegate(nullptr);
+}
+
+void DeviceDisabledScreen::PrepareToShow() {
+}
+
+void DeviceDisabledScreen::Show() {
+  if (!actor_ || showing_)
+    return;
+
+  bool is_device_disabled = false;
+  g_browser_process->local_state()->GetDictionary(
+      prefs::kServerBackedDeviceState)->GetBoolean(policy::kDeviceStateDisabled,
+                                                   &is_device_disabled);
+  if (!is_device_disabled ||
+      CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kDisableDeviceDisabling)) {
+    // Skip the screen if the device is not marked as disabled or device
+    // disabling has been turned off by flag.
+    IndicateDeviceNotDisabled();
+    return;
+  }
+
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
+  if (connector->GetDeviceMode() == policy::DEVICE_MODE_PENDING) {
+    // Ensure that the device mode is known before proceeding.
+    connector->GetInstallAttributes()->ReadImmutableAttributes(
+        base::Bind(&DeviceDisabledScreen::Show,
+                   weak_factory_.GetWeakPtr()));
+    return;
+  }
+
+  if (connector->GetDeviceMode() != policy::DEVICE_MODE_NOT_SET) {
+    // Skip the screen if the device is owned already. The device disabling
+    // screen should only be shown during OOBE.
+    IndicateDeviceNotDisabled();
+    return;
+  }
+
+  showing_ = true;
+
+  std::string message;
+  g_browser_process->local_state()->GetDictionary(
+      prefs::kServerBackedDeviceState)->GetString(
+          policy::kDeviceStateDisabledMessage,
+          &message);
+  actor_->Show(message);
+}
+
+void DeviceDisabledScreen::Hide() {
+  if (!showing_)
+    return;
+  showing_ = false;
+
+  if (actor_)
+    actor_->Hide();
+}
+
+std::string DeviceDisabledScreen::GetName() const {
+  return WizardController::kDeviceDisabledScreenName;
+}
+
+void DeviceDisabledScreen::OnActorDestroyed(DeviceDisabledScreenActor* actor) {
+  if (actor_ == actor)
+    actor_ = nullptr;
+}
+
+void DeviceDisabledScreen::IndicateDeviceNotDisabled() {
+  get_screen_observer()->OnExit(ScreenObserver::DEVICE_NOT_DISABLED);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/device_disabled_screen.h b/chrome/browser/chromeos/login/screens/device_disabled_screen.h
new file mode 100644
index 0000000..12bd2b7
--- /dev/null
+++ b/chrome/browser/chromeos/login/screens/device_disabled_screen.h
@@ -0,0 +1,51 @@
+// 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_CHROMEOS_LOGIN_SCREENS_DEVICE_DISABLED_SCREEN_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_DEVICE_DISABLED_SCREEN_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/login/screens/base_screen.h"
+#include "chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h"
+
+namespace chromeos {
+
+class ScreenObserver;
+
+// Screen informing the user that the device has been disabled by its owner.
+class DeviceDisabledScreen : public BaseScreen,
+                             public DeviceDisabledScreenActor::Delegate {
+ public:
+  DeviceDisabledScreen(ScreenObserver* observer,
+                       DeviceDisabledScreenActor* actor);
+  ~DeviceDisabledScreen() override;
+
+  // BaseScreen:
+  void PrepareToShow() override;
+  void Show() override;
+  void Hide() override;
+  std::string GetName() const override;
+
+  // DeviceDisabledScreenActor::Delegate:
+  void OnActorDestroyed(DeviceDisabledScreenActor* actor) override;
+
+ private:
+  // Indicate to the observer that the screen was skipped because the device is
+  // not disabled.
+  void IndicateDeviceNotDisabled();
+
+  // Whether the screen is currently showing.
+  bool showing_;
+
+  DeviceDisabledScreenActor* actor_;
+
+  base::WeakPtrFactory<DeviceDisabledScreen> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeviceDisabledScreen);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_DEVICE_DISABLED_SCREEN_H_
diff --git a/chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h b/chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h
new file mode 100644
index 0000000..bbfae36cf
--- /dev/null
+++ b/chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h
@@ -0,0 +1,37 @@
+// 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_CHROMEOS_LOGIN_SCREENS_DEVICE_DISABLED_SCREEN_ACTOR_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_DEVICE_DISABLED_SCREEN_ACTOR_H_
+
+#include <string>
+
+namespace chromeos {
+
+// Interface between the device disabled screen and its representation.
+class DeviceDisabledScreenActor {
+ public:
+  // Allows the representation to access information about the screen.
+  class Delegate {
+   public:
+    virtual ~Delegate() {
+    }
+
+    // Called when the actor is being destroyed. Note that if the Delegate is
+    // destroyed first, it must call SetDelegate(nullptr).
+    virtual void OnActorDestroyed(DeviceDisabledScreenActor* actor) = 0;
+  };
+
+  virtual ~DeviceDisabledScreenActor() {
+  }
+
+  virtual void Show(const std::string& message) = 0;
+  virtual void Hide() = 0;
+  virtual void SetDelegate(Delegate* delegate) = 0;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_DEVICE_DISABLED_SCREEN_ACTOR_H_
+
diff --git a/chrome/browser/chromeos/login/screens/device_disabled_screen_unittest.cc b/chrome/browser/chromeos/login/screens/device_disabled_screen_unittest.cc
new file mode 100644
index 0000000..e0fd8db0
--- /dev/null
+++ b/chrome/browser/chromeos/login/screens/device_disabled_screen_unittest.cc
@@ -0,0 +1,205 @@
+// 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/chromeos/login/screens/device_disabled_screen.h"
+
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/prefs/scoped_user_pref_update.h"
+#include "base/prefs/testing_pref_service.h"
+#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h"
+#include "chrome/browser/chromeos/login/screens/screen_observer.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
+#include "chrome/browser/chromeos/policy/server_backed_device_state.h"
+#include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chromeos/chromeos_switches.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+
+namespace chromeos {
+
+namespace {
+
+const char kDisabledMessage[] = "Device disabled.";
+
+}
+
+class DeviceDisabledScreenTest : public testing::Test, public ScreenObserver {
+ public:
+  DeviceDisabledScreenTest();
+  ~DeviceDisabledScreenTest() override;
+
+  // testing::Test:
+  void SetUp() override;
+  void TearDown() override;
+
+  // ScreenObserver:
+  MOCK_METHOD1(OnExit, void(ExitCodes));
+  void ShowCurrentScreen() override;
+  void OnSetUserNamePassword(const std::string& username,
+                             const std::string& password) override;
+  void SetHostConfiguration() override;
+  void ConfigureHost(bool accepted_eula,
+                     const std::string& lang,
+                     const std::string& timezone,
+                     bool send_reports,
+                     const std::string& keyboard_layout) override;
+  ErrorScreen* GetErrorScreen() override;
+  void ShowErrorScreen() override;
+  void HideErrorScreen(BaseScreen* parent_screen) override;
+
+  void SetDeviceDisabled(bool disabled);
+  void SetDeviceMode(policy::DeviceMode device_mode);
+
+  void ExpectScreenToNotShow();
+  void ExpectScreenToShow();
+
+  void TryToShowScreen();
+
+ private:
+  scoped_ptr<DeviceDisabledScreen> screen_;
+  scoped_ptr<MockDeviceDisabledScreenActor> actor_;
+  TestingPrefServiceSimple local_state_;
+  policy::ScopedStubEnterpriseInstallAttributes install_attributes_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeviceDisabledScreenTest);
+};
+
+DeviceDisabledScreenTest::DeviceDisabledScreenTest()
+    : install_attributes_("", "", "", policy::DEVICE_MODE_NOT_SET) {
+}
+
+DeviceDisabledScreenTest::~DeviceDisabledScreenTest() {
+}
+
+void DeviceDisabledScreenTest::SetUp() {
+  TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
+  policy::DeviceCloudPolicyManagerChromeOS::RegisterPrefs(
+      local_state_.registry());
+
+  actor_.reset(new MockDeviceDisabledScreenActor);
+  screen_.reset(new DeviceDisabledScreen(this, actor_.get()));
+}
+
+void DeviceDisabledScreenTest::TearDown() {
+  TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);
+}
+
+void DeviceDisabledScreenTest::ShowCurrentScreen() {
+}
+
+void DeviceDisabledScreenTest::OnSetUserNamePassword(
+    const std::string& username,
+    const std::string& password) {
+}
+
+void DeviceDisabledScreenTest::SetHostConfiguration() {
+}
+
+void DeviceDisabledScreenTest::ConfigureHost(
+    bool accepted_eula,
+    const std::string& lang,
+    const std::string& timezone,
+    bool send_reports,
+    const std::string& keyboard_layout) {
+}
+
+ErrorScreen* DeviceDisabledScreenTest::GetErrorScreen() {
+  return nullptr;
+}
+
+void DeviceDisabledScreenTest::ShowErrorScreen() {
+}
+
+void DeviceDisabledScreenTest::HideErrorScreen(BaseScreen* parent_screen) {
+}
+
+void DeviceDisabledScreenTest::SetDeviceDisabled(bool disabled) {
+  DictionaryPrefUpdate dict(&local_state_, prefs::kServerBackedDeviceState);
+  dict->SetBoolean(policy::kDeviceStateDisabled, disabled);
+  if (disabled)
+    dict->SetString(policy::kDeviceStateDisabledMessage, kDisabledMessage);
+}
+
+void DeviceDisabledScreenTest::SetDeviceMode(policy::DeviceMode device_mode) {
+  reinterpret_cast<policy::StubEnterpriseInstallAttributes*>(
+      TestingBrowserProcess::GetGlobal()->platform_part()->
+          browser_policy_connector_chromeos()->GetInstallAttributes())->
+              SetMode(device_mode);
+}
+
+void DeviceDisabledScreenTest::ExpectScreenToNotShow() {
+  EXPECT_CALL(*actor_, Show(_)).Times(0);
+  EXPECT_CALL(*this, OnExit(ScreenObserver::DEVICE_NOT_DISABLED)).Times(1);
+}
+
+void DeviceDisabledScreenTest::ExpectScreenToShow() {
+  EXPECT_CALL(*actor_, Show(kDisabledMessage)).Times(1);
+  EXPECT_CALL(*this, OnExit(ScreenObserver::DEVICE_NOT_DISABLED)).Times(0);
+}
+
+void DeviceDisabledScreenTest::TryToShowScreen() {
+  screen_->Show();
+}
+
+// Verifies that the device disabled screen is not shown by default.
+TEST_F(DeviceDisabledScreenTest, DoNotShowByDefault) {
+  ExpectScreenToNotShow();
+  TryToShowScreen();
+}
+
+// Verifies that the device disabled screen is not shown when the device is
+// explicitly marked as not disabled.
+TEST_F(DeviceDisabledScreenTest, DoNotShowWhenNotDisabled) {
+  SetDeviceDisabled(false);
+  ExpectScreenToNotShow();
+  TryToShowScreen();
+}
+
+// Verifies that the device disabled screen is not shown when device disabling
+// is turned off by flag, even if the device is marked as disabled.
+TEST_F(DeviceDisabledScreenTest, DoNotShowWhenTurnedOffByFlag) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kDisableDeviceDisabling);
+  SetDeviceDisabled(true);
+  ExpectScreenToNotShow();
+  TryToShowScreen();
+}
+
+// Verifies that the device disabled screen is not shown when the device is
+// already enrolled, even if the device is marked as disabled.
+TEST_F(DeviceDisabledScreenTest, DoNotShowWhenEnterpriseOwned) {
+  SetDeviceMode(policy::DEVICE_MODE_ENTERPRISE);
+  SetDeviceDisabled(true);
+  ExpectScreenToNotShow();
+  TryToShowScreen();
+}
+
+// Verifies that the device disabled screen is not shown when the device is
+// already owned by a consumer, even if the device is marked as disabled.
+TEST_F(DeviceDisabledScreenTest, DoNotShowWhenConsumerOwned) {
+  SetDeviceMode(policy::DEVICE_MODE_CONSUMER);
+  SetDeviceDisabled(true);
+  ExpectScreenToNotShow();
+  TryToShowScreen();
+}
+
+// Verifies that the device disabled screen is shown when the device is marked
+// as disabled, device disabling is not turned off by flag and the device is not
+// owned yet.
+TEST_F(DeviceDisabledScreenTest, ShowWhenDisabledAndNotOwned) {
+  SetDeviceDisabled(true);
+  ExpectScreenToShow();
+  TryToShowScreen();
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/error_screen.cc b/chrome/browser/chromeos/login/screens/error_screen.cc
index ee3d8f3..cff568b 100644
--- a/chrome/browser/chromeos/login/screens/error_screen.cc
+++ b/chrome/browser/chromeos/login/screens/error_screen.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/login/screens/error_screen.h"
 
 #include "base/command_line.h"
+#include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
 #include "chrome/browser/chromeos/login/screens/error_screen_actor.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
@@ -130,6 +131,11 @@
     actor_->SetErrorState(error_state, network);
 }
 
+ErrorScreen::ErrorState ErrorScreen::GetErrorState() const {
+  DCHECK(actor_);
+  return actor_->error_state();
+}
+
 void ErrorScreen::AllowGuestSignin(bool allow) {
   if (actor_)
     actor_->AllowGuestSignin(allow);
@@ -171,7 +177,7 @@
   if (guest_login_performer_)
     return;
 
-  guest_login_performer_.reset(new LoginPerformer(this));
+  guest_login_performer_.reset(new ChromeLoginPerformer(this));
   guest_login_performer_->LoginOffTheRecord();
 }
 
diff --git a/chrome/browser/chromeos/login/screens/error_screen.h b/chrome/browser/chromeos/login/screens/error_screen.h
index 1c61eba..89000531 100644
--- a/chrome/browser/chromeos/login/screens/error_screen.h
+++ b/chrome/browser/chromeos/login/screens/error_screen.h
@@ -9,11 +9,11 @@
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/chromeos/login/auth/login_performer.h"
 #include "chrome/browser/chromeos/login/screens/base_screen.h"
 #include "chrome/browser/chromeos/login/screens/error_screen_actor_delegate.h"
 #include "chrome/browser/chromeos/login/ui/oobe_display.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chromeos/login/auth/login_performer.h"
 
 namespace chromeos {
 
@@ -41,7 +41,10 @@
     ERROR_STATE_OFFLINE,
     ERROR_STATE_PROXY,
     ERROR_STATE_AUTH_EXT_TIMEOUT,
-    ERROR_STATE_KIOSK_ONLINE
+    ERROR_STATE_NONE,
+    // States above are being logged to histograms.
+    // Please keep ERROR_STATE_NONE as the last one of the histogram values.
+    ERROR_STATE_KIOSK_ONLINE,
   };
 
   ErrorScreen(ScreenObserver* screen_observer, ErrorScreenActor* actor);
@@ -87,6 +90,8 @@
   // |error_state|, and |network|.
   void SetErrorState(ErrorState error_state, const std::string& network);
 
+  ErrorState GetErrorState() const;
+
   // Toggles the guest sign-in prompt.
   void AllowGuestSignin(bool allow);
 
diff --git a/chrome/browser/chromeos/login/screens/eula_screen.cc b/chrome/browser/chromeos/login/screens/eula_screen.cc
index 3454e054..1996023 100644
--- a/chrome/browser/chromeos/login/screens/eula_screen.cc
+++ b/chrome/browser/chromeos/login/screens/eula_screen.cc
@@ -27,6 +27,11 @@
     actor_->SetDelegate(NULL);
 }
 
+void EulaScreen::SetDelegate(Delegate* delegate) {
+  DCHECK(delegate);
+  delegate_ = delegate;
+}
+
 void EulaScreen::PrepareToShow() {
   if (actor_)
     actor_->PrepareToShow();
@@ -68,7 +73,8 @@
 }
 
 void EulaScreen::OnExit(bool accepted, bool usage_stats_enabled) {
-  get_screen_observer()->SetUsageStatisticsReporting(usage_stats_enabled);
+  if (delegate_)
+    delegate_->SetUsageStatisticsReporting(usage_stats_enabled);
   get_screen_observer()->OnExit(accepted
                    ? ScreenObserver::EULA_ACCEPTED
                    : ScreenObserver::EULA_BACK);
@@ -90,7 +96,7 @@
 }
 
 bool EulaScreen::IsUsageStatsEnabled() const {
-  return get_screen_observer()->GetUsageStatisticsReporting();
+  return delegate_ && delegate_->GetUsageStatisticsReporting();
 }
 
 void EulaScreen::OnActorDestroyed(EulaScreenActor* actor) {
diff --git a/chrome/browser/chromeos/login/screens/eula_screen.h b/chrome/browser/chromeos/login/screens/eula_screen.h
index d5afbbd6..15fc4d2 100644
--- a/chrome/browser/chromeos/login/screens/eula_screen.h
+++ b/chrome/browser/chromeos/login/screens/eula_screen.h
@@ -21,9 +21,20 @@
                    public EulaScreenActor::Delegate,
                    public TpmPasswordFetcherDelegate {
  public:
+  class Delegate {
+   public:
+    virtual ~Delegate() {}
+
+    // Whether usage statistics reporting is enabled on EULA screen.
+    virtual void SetUsageStatisticsReporting(bool val) = 0;
+    virtual bool GetUsageStatisticsReporting() const = 0;
+  };
+
   EulaScreen(ScreenObserver* observer, EulaScreenActor* actor);
   virtual ~EulaScreen();
 
+  void SetDelegate(Delegate* delegate);
+
   // BaseScreen implementation:
   virtual void PrepareToShow() override;
   virtual void Show() override;
@@ -53,6 +64,8 @@
 
   EulaScreenActor* actor_;
 
+  Delegate* delegate_;
+
   TpmPasswordFetcher password_fetcher_;
 
   DISALLOW_COPY_AND_ASSIGN(EulaScreen);
diff --git a/chrome/browser/chromeos/login/screens/host_pairing_screen.cc b/chrome/browser/chromeos/login/screens/host_pairing_screen.cc
index 0ca2b8e..8eae6ee 100644
--- a/chrome/browser/chromeos/login/screens/host_pairing_screen.cc
+++ b/chrome/browser/chromeos/login/screens/host_pairing_screen.cc
@@ -72,11 +72,6 @@
                          remora_controller_->GetConfirmationCode());
       break;
     }
-    case HostPairingController::STAGE_UPDATING: {
-      remora_controller_->RemoveObserver(this);
-      get_screen_observer()->OnExit(WizardController::HOST_PAIRING_FINISHED);
-      break;
-    }
     default:
       break;
   }
@@ -92,8 +87,14 @@
                                       const std::string& timezone,
                                       bool send_reports,
                                       const std::string& keyboard_layout) {
-  // TODO(zork): Get configuration from UI and send to Host.
-  // (http://crbug.com/405744)
+  VLOG(1) << "ConfigureHostMessage language=" << lang
+          << ", timezone=" << timezone
+          << ", keyboard_layout=" << keyboard_layout;
+
+  remora_controller_->RemoveObserver(this);
+  get_screen_observer()->ConfigureHost(accepted_eula, lang, timezone,
+                                       send_reports, keyboard_layout);
+  get_screen_observer()->OnExit(WizardController::HOST_PAIRING_FINISHED);
 }
 
 void HostPairingScreen::EnrollHost(const std::string& auth_token) {
diff --git a/chrome/browser/chromeos/login/screens/host_pairing_screen.h b/chrome/browser/chromeos/login/screens/host_pairing_screen.h
index 110adad..d1f469d 100644
--- a/chrome/browser/chromeos/login/screens/host_pairing_screen.h
+++ b/chrome/browser/chromeos/login/screens/host_pairing_screen.h
@@ -8,7 +8,7 @@
 #include "base/macros.h"
 #include "chrome/browser/chromeos/login/screens/base_screen.h"
 #include "chrome/browser/chromeos/login/screens/host_pairing_screen_actor.h"
-#include "chrome/browser/chromeos/login/screens/screen_context.h"
+#include "components/login/screens/screen_context.h"
 #include "components/pairing/host_pairing_controller.h"
 
 namespace chromeos {
@@ -47,7 +47,7 @@
 
   // Context for sharing data between C++ and JS.
   // TODO(dzhioev): move to BaseScreen when possible.
-  ScreenContext context_;
+  ::login::ScreenContext context_;
 
   HostPairingScreenActor* actor_;
 
diff --git a/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.cc b/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.cc
new file mode 100644
index 0000000..f852b948
--- /dev/null
+++ b/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.cc
@@ -0,0 +1,29 @@
+// 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/chromeos/login/screens/mock_device_disabled_screen_actor.h"
+
+using ::testing::AtLeast;
+using ::testing::AtMost;
+using ::testing::NotNull;
+
+namespace chromeos {
+
+MockDeviceDisabledScreenActor::MockDeviceDisabledScreenActor()
+    : delegate_(nullptr) {
+  EXPECT_CALL(*this, MockSetDelegate(NotNull())).Times(AtLeast(1));
+  EXPECT_CALL(*this, MockSetDelegate(nullptr)).Times(AtMost(1));
+}
+
+MockDeviceDisabledScreenActor::~MockDeviceDisabledScreenActor() {
+  if (delegate_)
+    delegate_->OnActorDestroyed(this);
+}
+
+void MockDeviceDisabledScreenActor::SetDelegate(Delegate* delegate) {
+  delegate_ = delegate;
+  MockSetDelegate(delegate);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h b/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h
new file mode 100644
index 0000000..3d18683
--- /dev/null
+++ b/chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h
@@ -0,0 +1,31 @@
+// 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_CHROMEOS_LOGIN_SCREENS_MOCK_DEVICE_DISABLED_SCREEN_ACTOR_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_DEVICE_DISABLED_SCREEN_ACTOR_H_
+
+#include "chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace chromeos {
+
+class MockDeviceDisabledScreenActor : public DeviceDisabledScreenActor {
+ public:
+  MockDeviceDisabledScreenActor();
+  ~MockDeviceDisabledScreenActor() override;
+
+  void SetDelegate(Delegate* delegate) override;
+
+  MOCK_METHOD1(Show, void(const std::string&));
+  MOCK_METHOD0(Hide, void());
+
+ private:
+  MOCK_METHOD1(MockSetDelegate, void(Delegate* delegate));
+
+  Delegate* delegate_;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_MOCK_DEVICE_DISABLED_SCREEN_ACTOR_H_
diff --git a/chrome/browser/chromeos/login/screens/mock_network_screen.h b/chrome/browser/chromeos/login/screens/mock_network_screen.h
index 08d8dd7c..4c85ffc6 100644
--- a/chrome/browser/chromeos/login/screens/mock_network_screen.h
+++ b/chrome/browser/chromeos/login/screens/mock_network_screen.h
@@ -34,8 +34,12 @@
   MOCK_METHOD2(ShowConnectingStatus,
                void(bool connecting, const base::string16& network_id));
   MOCK_METHOD1(EnableContinue, void(bool enabled));
-  MOCK_CONST_METHOD0(IsContinueEnabled, bool());
-  MOCK_CONST_METHOD0(IsConnecting, bool());
+  MOCK_CONST_METHOD0(GetApplicationLocale, std::string());
+  MOCK_CONST_METHOD0(GetInputMethod, std::string());
+  MOCK_CONST_METHOD0(GetTimezone, std::string());
+  MOCK_METHOD1(SetApplicationLocale, void(const std::string& locale));
+  MOCK_METHOD1(SetInputMethod, void(const std::string& input_method));
+  MOCK_METHOD1(SetTimezone, void(const std::string& timezone));
 
   private:
    Delegate* delegate_;
diff --git a/chrome/browser/chromeos/login/screens/mock_screen_observer.h b/chrome/browser/chromeos/login/screens/mock_screen_observer.h
index 042bd09..1559402 100644
--- a/chrome/browser/chromeos/login/screens/mock_screen_observer.h
+++ b/chrome/browser/chromeos/login/screens/mock_screen_observer.h
@@ -25,6 +25,12 @@
                void(const std::string&, const std::string&));
   MOCK_METHOD1(SetUsageStatisticsReporting, void(bool));
   MOCK_CONST_METHOD0(GetUsageStatisticsReporting, bool());
+  MOCK_METHOD0(SetHostConfiguration, void());
+  MOCK_METHOD5(ConfigureHost, void(bool accepted_eula,
+                                   const std::string& lang,
+                                   const std::string& timezone,
+                                   bool send_reports,
+                                   const std::string& keyboard_layout));
   MOCK_METHOD0(GetErrorScreen, ErrorScreen*());
   MOCK_METHOD0(ShowErrorScreen, void());
   MOCK_METHOD1(HideErrorScreen, void(BaseScreen*));
diff --git a/chrome/browser/chromeos/login/screens/network_screen_actor.h b/chrome/browser/chromeos/login/screens/network_screen_actor.h
index 3703dc4d..0145580 100644
--- a/chrome/browser/chromeos/login/screens/network_screen_actor.h
+++ b/chrome/browser/chromeos/login/screens/network_screen_actor.h
@@ -47,6 +47,16 @@
 
   // Sets whether continue control is enabled.
   virtual void EnableContinue(bool enabled) = 0;
+
+  // Getters for locale, keyboard layout, timezone.
+  virtual std::string GetApplicationLocale() const = 0;
+  virtual std::string GetInputMethod() const = 0;
+  virtual std::string GetTimezone() const = 0;
+
+  // Setters for locale, keyboard layout and timezone.
+  virtual void SetApplicationLocale(const std::string& locale) = 0;
+  virtual void SetInputMethod(const std::string& input_method) = 0;
+  virtual void SetTimezone(const std::string& timezone) = 0;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/screens/screen_observer.h b/chrome/browser/chromeos/login/screens/screen_observer.h
index a27daf2..7734a5a 100644
--- a/chrome/browser/chromeos/login/screens/screen_observer.h
+++ b/chrome/browser/chromeos/login/screens/screen_observer.h
@@ -49,6 +49,7 @@
     WRONG_HWID_WARNING_SKIPPED = 20,
     CONTROLLER_PAIRING_FINISHED = 21,
     HOST_PAIRING_FINISHED = 22,
+    DEVICE_NOT_DISABLED = 23,
     EXIT_CODES_COUNT  // not a real code, must be the last
   };
 
@@ -63,9 +64,13 @@
   virtual void OnSetUserNamePassword(const std::string& username,
                                      const std::string& password) = 0;
 
-  // Whether usage statistics reporting is enabled on EULA screen.
-  virtual void SetUsageStatisticsReporting(bool val) = 0;
-  virtual bool GetUsageStatisticsReporting() const = 0;
+  // Set remora configuration from shark.
+  virtual void SetHostConfiguration() = 0;
+  virtual void ConfigureHost(bool accepted_eula,
+                             const std::string& lang,
+                             const std::string& timezone,
+                             bool send_reports,
+                             const std::string& keyboard_layout) = 0;
 
   virtual ErrorScreen* GetErrorScreen() = 0;
   virtual void ShowErrorScreen() = 0;
diff --git a/chrome/browser/chromeos/login/screens/update_screen.cc b/chrome/browser/chromeos/login/screens/update_screen.cc
index 940c28f..4541f2a 100644
--- a/chrome/browser/chromeos/login/screens/update_screen.cc
+++ b/chrome/browser/chromeos/login/screens/update_screen.cc
@@ -11,6 +11,7 @@
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread_restrictions.h"
+#include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
 #include "chrome/browser/chromeos/login/screen_manager.h"
 #include "chrome/browser/chromeos/login/screens/error_screen.h"
 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
@@ -107,6 +108,7 @@
       remora_controller_(remora_controller),
       is_first_detection_notification_(true),
       is_first_portal_notification_(true),
+      histogram_helper_(new ErrorScreensHistogramHelper("Update")),
       weak_factory_(this) {
   DCHECK(actor_);
   if (actor_)
@@ -303,6 +305,7 @@
 
 void UpdateScreen::Show() {
   is_shown_ = true;
+  histogram_helper_->OnScreenShow();
   if (actor_) {
     actor_->Show();
     actor_->SetProgress(kBeforeUpdateCheckProgress);
@@ -496,11 +499,13 @@
   state_ = STATE_ERROR;
   GetErrorScreen()->SetUIState(ErrorScreen::UI_STATE_UPDATE);
   get_screen_observer()->ShowErrorScreen();
+  histogram_helper_->OnErrorShow(GetErrorScreen()->GetErrorState());
 }
 
 void UpdateScreen::HideErrorMessage() {
   LOG(WARNING) << "UpdateScreen::HideErrorMessage()";
   get_screen_observer()->HideErrorScreen(this);
+  histogram_helper_->OnErrorHide();
 }
 
 void UpdateScreen::UpdateErrorMessage(
diff --git a/chrome/browser/chromeos/login/screens/update_screen.h b/chrome/browser/chromeos/login/screens/update_screen.h
index f351a575..76b83909 100644
--- a/chrome/browser/chromeos/login/screens/update_screen.h
+++ b/chrome/browser/chromeos/login/screens/update_screen.h
@@ -22,6 +22,7 @@
 namespace chromeos {
 
 class ErrorScreen;
+class ErrorScreensHistogramHelper;
 class NetworkState;
 class ScreenManager;
 class ScreenObserver;
@@ -174,6 +175,8 @@
   // the default network.
   bool is_first_portal_notification_;
 
+  scoped_ptr<ErrorScreensHistogramHelper> histogram_helper_;
+
   base::WeakPtrFactory<UpdateScreen> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(UpdateScreen);
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index de2ea43..374cf3fa 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -15,6 +15,7 @@
 #include "base/prefs/pref_registry_simple.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string16.h"
+#include "base/strings/stringprintf.h"
 #include "base/sys_info.h"
 #include "base/task_runner_util.h"
 #include "base/threading/worker_pool.h"
@@ -23,8 +24,10 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/base/locale_util.h"
 #include "chrome/browser/chromeos/boot_times_loader.h"
+#include "chrome/browser/chromeos/first_run/first_run.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
@@ -35,8 +38,12 @@
 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
+#include "chrome/browser/chromeos/login/user_flow.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
+#include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
@@ -45,9 +52,11 @@
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/net/crl_set_fetcher.h"
 #include "chrome/browser/net/nss_context.h"
+#include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/rlz/rlz.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/easy_unlock_service.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/common/chrome_switches.h"
@@ -67,6 +76,7 @@
 #include "components/component_updater/component_updater_service.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/session_manager/core/session_manager.h"
+#include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/signin_manager_base.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
@@ -79,6 +89,11 @@
 
 namespace {
 
+// ChromeVox tutorial URL (used in place of "getting started" url when
+// accessibility is enabled).
+const char kChromeVoxTutorialURLPattern[] =
+    "http://www.chromevox.com/tutorial/index.html?lang=%s";
+
 void InitLocaleAndInputMethodsForNewUser(
     UserSessionManager* session_manager,
     Profile* profile,
@@ -278,12 +293,14 @@
 
 void UserSessionManager::StartSession(
     const UserContext& user_context,
+    StartSessionType start_session_type,
     scoped_refptr<Authenticator> authenticator,
     bool has_auth_cookies,
     bool has_active_session,
     UserSessionManagerDelegate* delegate) {
   authenticator_ = authenticator;
   delegate_ = delegate;
+  start_session_type_ = start_session_type;
 
   VLOG(1) << "Starting session for " << user_context.GetUserID();
 
@@ -615,9 +632,8 @@
   }
 }
 
-void UserSessionManager::OnProfilePrepared(Profile* profile) {
-  LoginUtils::Get()->DoBrowserLaunch(profile, NULL);  // host_, not needed here
-
+void UserSessionManager::OnProfilePrepared(Profile* profile,
+                                           bool browser_launched) {
   if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
     // Did not log in (we crashed or are debugging), need to restore Sync.
     // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
@@ -731,6 +747,17 @@
     profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
                                    supervised_user_sync_id);
   } else if (user_manager::UserManager::Get()->IsLoggedInAsRegularUser()) {
+    // Prime the account tracker with this combination of gaia id/display email.
+    // Don't do this unless both email and gaia_id are valid.  They may not
+    // be when simply unlocking the profile.
+    if (!user_context.GetGaiaID().empty() &&
+        !user_context.GetUserID().empty()) {
+      AccountTrackerService* account_tracker =
+          AccountTrackerServiceFactory::GetForProfile(profile);
+      account_tracker->SeedAccountInfo(user_context.GetGaiaID(),
+                                       user_context.GetUserID());
+    }
+
     // Make sure that the google service username is properly set (we do this
     // on every sign in, not just the first login, to deal with existing
     // profiles that might not have it set yet).
@@ -743,8 +770,10 @@
 void UserSessionManager::UserProfileInitialized(Profile* profile,
                                                 bool is_incognito_profile,
                                                 const std::string& user_id) {
+  // Demo user signed in.
   if (is_incognito_profile) {
     profile->OnLogin();
+
     // Send the notification before creating the browser so additional objects
     // that need the profile (e.g. the launcher) can be created first.
     content::NotificationService::current()->Notify(
@@ -753,7 +782,7 @@
         content::Details<Profile>(profile));
 
     if (delegate_)
-      delegate_->OnProfilePrepared(profile);
+      delegate_->OnProfilePrepared(profile, false);
 
     return;
   }
@@ -780,14 +809,14 @@
     // transferred unconditionally. If the user authenticated via an auth
     // extension, authentication cookies and channel IDs will be transferred as
     // well when the user's cookie jar is empty. If the cookie jar is not empty,
-    // the authentication states in the login profile and the user's profile
+    // the authentication states in the browser context and the user's profile
     // must be merged using /MergeSession instead. Authentication cookies set by
     // a SAML IdP will also be transferred when the user's cookie jar is not
     // empty if |transfer_saml_auth_cookies_on_subsequent_login| is true.
     const bool transfer_auth_cookies_and_channel_ids_on_first_login =
         has_auth_cookies_;
     ProfileAuthData::Transfer(
-        authenticator_->authentication_profile(),
+        authenticator_->authentication_context(),
         profile,
         transfer_auth_cookies_and_channel_ids_on_first_login,
         transfer_saml_auth_cookies_on_subsequent_login,
@@ -852,6 +881,10 @@
   UpdateEasyUnlockKeys(user_context_);
   user_context_.ClearSecrets();
 
+  // Now that profile is ready, proceed to either alternative login flows or
+  // launch browser.
+  bool browser_launched = InitializeUserSession(profile);
+
   // TODO(nkostylev): This pointer should probably never be NULL, but it looks
   // like LoginUtilsImpl::OnProfileCreated() may be getting called before
   // UserSessionManager::PrepareProfile() has set |delegate_| when Chrome is
@@ -859,7 +892,103 @@
   // this 'if' statement with a CHECK(delegate_) once the underlying issue is
   // resolved.
   if (delegate_)
-    delegate_->OnProfilePrepared(profile);
+    delegate_->OnProfilePrepared(profile, browser_launched);
+}
+
+void UserSessionManager::ActivateWizard(const std::string& screen_name) {
+  LoginDisplayHost* host = LoginDisplayHostImpl::default_host();
+  DCHECK(host);
+  if (host) {
+    scoped_ptr<base::DictionaryValue> params;
+    host->StartWizard(screen_name, params.Pass());
+  }
+}
+
+void UserSessionManager::InitializeStartUrls() const {
+  std::vector<std::string> start_urls;
+
+  const base::ListValue *urls;
+  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+  bool can_show_getstarted_guide =
+      user_manager->GetActiveUser()->GetType() ==
+          user_manager::USER_TYPE_REGULAR &&
+      !user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
+  if (user_manager->IsLoggedInAsDemoUser()) {
+    if (CrosSettings::Get()->GetList(kStartUpUrls, &urls)) {
+      // The retail mode user will get start URLs from a special policy if it is
+      // set.
+      for (base::ListValue::const_iterator it = urls->begin();
+           it != urls->end(); ++it) {
+        std::string url;
+        if ((*it)->GetAsString(&url))
+          start_urls.push_back(url);
+      }
+    }
+    can_show_getstarted_guide = false;
+  // Skip the default first-run behavior for public accounts.
+  } else if (!user_manager->IsLoggedInAsPublicAccount()) {
+    if (AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
+      const char* url = kChromeVoxTutorialURLPattern;
+      PrefService* prefs = g_browser_process->local_state();
+      const std::string current_locale =
+          base::StringToLowerASCII(prefs->GetString(prefs::kApplicationLocale));
+      std::string vox_url = base::StringPrintf(url, current_locale.c_str());
+      start_urls.push_back(vox_url);
+      can_show_getstarted_guide = false;
+    }
+  }
+
+  // Only show getting started guide for a new user.
+  const bool should_show_getstarted_guide = user_manager->IsCurrentUserNew();
+
+  if (can_show_getstarted_guide && should_show_getstarted_guide) {
+    // Don't open default Chrome window if we're going to launch the first-run
+    // app. Because we dont' want the first-run app to be hidden in the
+    // background.
+    CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
+    first_run::MaybeLaunchDialogAfterSessionStart();
+  } else {
+    for (size_t i = 0; i < start_urls.size(); ++i) {
+      CommandLine::ForCurrentProcess()->AppendArg(start_urls[i]);
+    }
+  }
+}
+
+bool UserSessionManager::InitializeUserSession(Profile* profile) {
+  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+
+  // Kiosk apps has their own session initialization pipeline.
+  if (user_manager->IsLoggedInAsKioskApp())
+    return false;
+
+  if (start_session_type_ == PRIMARY_USER_SESSION) {
+    UserFlow* user_flow = ChromeUserManager::Get()->GetCurrentUserFlow();
+    WizardController* oobe_controller = WizardController::default_controller();
+    base::CommandLine* cmdline = CommandLine::ForCurrentProcess();
+    bool skip_post_login_screens =
+        user_flow->ShouldSkipPostLoginScreens() ||
+        (oobe_controller && oobe_controller->skip_post_login_screens()) ||
+        cmdline->HasSwitch(chromeos::switches::kOobeSkipPostLogin);
+
+    if (user_manager->IsCurrentUserNew() && !skip_post_login_screens) {
+      // Don't specify start URLs if the administrator has configured the start
+      // URLs via policy.
+      if (!SessionStartupPref::TypeIsManaged(profile->GetPrefs()))
+        InitializeStartUrls();
+
+      // Mark the device as registered., i.e. the second part of OOBE as
+      // completed.
+      if (!StartupUtils::IsDeviceRegistered())
+        StartupUtils::MarkDeviceRegistered(base::Closure());
+
+      ActivateWizard(WizardController::kTermsOfServiceScreenName);
+      return false;
+    }
+  }
+
+  LoginUtils::Get()->DoBrowserLaunch(profile,
+                                     LoginDisplayHostImpl::default_host());
+  return true;
 }
 
 void UserSessionManager::InitSessionRestoreStrategy() {
@@ -901,9 +1030,10 @@
   }
 }
 
-void UserSessionManager::RestoreAuthSessionImpl(Profile* profile,
-                                            bool restore_from_auth_cookies) {
-  CHECK((authenticator_.get() && authenticator_->authentication_profile()) ||
+void UserSessionManager::RestoreAuthSessionImpl(
+    Profile* profile,
+    bool restore_from_auth_cookies) {
+  CHECK((authenticator_.get() && authenticator_->authentication_context()) ||
         !restore_from_auth_cookies);
 
   if (chrome::IsRunningInForcedAppMode() ||
@@ -921,8 +1051,8 @@
       OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile);
   login_manager->AddObserver(this);
   login_manager->RestoreSession(
-      authenticator_.get() && authenticator_->authentication_profile()
-          ? authenticator_->authentication_profile()->GetRequestContext()
+      authenticator_.get() && authenticator_->authentication_context()
+          ? authenticator_->authentication_context()->GetRequestContext()
           : NULL,
       session_restore_strategy_,
       oauth2_refresh_token_,
@@ -943,7 +1073,7 @@
   }
   // Init the RLZ library.
   int ping_delay = profile->GetPrefs()->GetInteger(
-      first_run::GetPingDelayPrefName().c_str());
+      ::first_run::GetPingDelayPrefName().c_str());
   // Negative ping delay means to send ping immediately after a first search is
   // recorded.
   RLZTracker::InitRlzFromProfileDelayed(
@@ -1042,10 +1172,13 @@
     user_context.SetIsUsingOAuth(false);
 
     // Will call OnProfilePrepared() once profile has been loaded.
+    // Only handling secondary users here since primary user profile
+    // (and session) has been loaded on Chrome startup.
     StartSession(user_context,
+                 SECONDARY_USER_SESSION_AFTER_CRASH,
                  NULL,   // authenticator
                  false,  // has_auth_cookies
-                 true,   // has_active_session
+                 true,   // has_active_session, this is restart after crash
                  this);
   } else {
     RestorePendingUserSessions();
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.h b/chrome/browser/chromeos/login/session/user_session_manager.h
index b319c2b1..bf8841a 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.h
+++ b/chrome/browser/chromeos/login/session/user_session_manager.h
@@ -41,7 +41,10 @@
 class UserSessionManagerDelegate {
  public:
   // Called after profile is loaded and prepared for the session.
-  virtual void OnProfilePrepared(Profile* profile) = 0;
+  // |browser_launched| will be true is browser has been launched, otherwise
+  // it will return false and client is responsible on launching browser.
+  virtual void OnProfilePrepared(Profile* profile,
+                                 bool browser_launched) = 0;
 
 #if defined(ENABLE_RLZ)
   // Called after post-profile RLZ initialization.
@@ -61,10 +64,10 @@
 };
 
 // UserSessionManager is responsible for starting user session which includes:
-// load and initialize Profile (including custom Profile preferences),
-// mark user as logged in and notify observers,
-// initialize OAuth2 authentication session,
-// initialize and launch user session based on the user type.
+// * load and initialize Profile (including custom Profile preferences),
+// * mark user as logged in and notify observers,
+// * initialize OAuth2 authentication session,
+// * initialize and launch user session based on the user type.
 // Also supports restoring active user sessions after browser crash:
 // load profile, restore OAuth authentication session etc.
 class UserSessionManager
@@ -74,6 +77,21 @@
       public UserSessionManagerDelegate,
       public user_manager::UserManager::UserSessionStateObserver {
  public:
+  // Context of StartSession calls.
+  typedef enum {
+    // Starting primary user session, through login UI.
+    PRIMARY_USER_SESSION,
+
+    // Starting secondary user session, through multi-profiles login UI.
+    SECONDARY_USER_SESSION,
+
+    // Starting primary user session after browser crash.
+    PRIMARY_USER_SESSION_AFTER_CRASH,
+
+    // Starting secondary user session after browser crash.
+    SECONDARY_USER_SESSION_AFTER_CRASH,
+  } StartSessionType;
+
   // Returns UserSessionManager instance.
   static UserSessionManager* GetInstance();
 
@@ -91,6 +109,7 @@
   // Start user session given |user_context| and |authenticator| which holds
   // authentication context (profile).
   void StartSession(const UserContext& user_context,
+                    StartSessionType start_session_type,
                     scoped_refptr<Authenticator> authenticator,
                     bool has_auth_cookies,
                     bool has_active_session,
@@ -198,7 +217,8 @@
 
   // UserSessionManagerDelegate overrides:
   // Used when restoring user sessions after crash.
-  virtual void OnProfilePrepared(Profile* profile) override;
+  virtual void OnProfilePrepared(Profile* profile,
+                                 bool browser_launched) override;
 
   void CreateUserSession(const UserContext& user_context,
                          bool has_auth_cookies);
@@ -233,6 +253,18 @@
   // Finalized profile preparation.
   void FinalizePrepareProfile(Profile* profile);
 
+  // Starts out-of-box flow with the specified screen.
+  void ActivateWizard(const std::string& screen_name);
+
+  // Adds first-time login URLs.
+  void InitializeStartUrls() const;
+
+  // Perform session initialization and either move to additional login flows
+  // such as TOS (public sessions), priority pref sync UI (new users) or
+  // launch browser.
+  // Returns true if browser has been launched or false otherwise.
+  bool InitializeUserSession(Profile* profile);
+
   // Initializes member variables needed for session restore process via
   // OAuthLoginManager.
   void InitSessionRestoreStrategy();
@@ -270,6 +302,7 @@
   // Authentication/user context.
   UserContext user_context_;
   scoped_refptr<Authenticator> authenticator_;
+  StartSessionType start_session_type_;
 
   // True if the authentication context's cookie jar contains authentication
   // cookies from the authentication extension login flow.
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
index 721db65..5523b00 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -17,8 +17,6 @@
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
@@ -28,6 +26,8 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/login/auth/key.h"
 #include "chromeos/login/auth/user_context.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
index 97bff3b6..8128dda 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.cc
@@ -13,11 +13,13 @@
 #include "base/strings/string_util.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/chromeos_switches.h"
+#include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_client.h"
 #include "components/signin/core/browser/signin_manager.h"
@@ -166,53 +168,67 @@
 void OAuth2LoginManager::StoreOAuth2Token() {
   const std::string& primary_account_id = GetPrimaryAccountId();
   if (primary_account_id.empty()) {
-    GetAccountIdOfRefreshToken(refresh_token_);
+    GetAccountInfoOfRefreshToken(refresh_token_);
     return;
   }
 
-  OnGetUserEmailResponse(primary_account_id);
+  UpdateCredentials(primary_account_id);
 }
 
-void OAuth2LoginManager::GetAccountIdOfRefreshToken(
+void OAuth2LoginManager::GetAccountInfoOfRefreshToken(
     const std::string& refresh_token) {
   gaia::OAuthClientInfo client_info;
   GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
   client_info.client_id = gaia_urls->oauth2_chrome_client_id();
   client_info.client_secret = gaia_urls->oauth2_chrome_client_secret();
 
-  account_id_fetcher_.reset(new gaia::GaiaOAuthClient(
+  account_info_fetcher_.reset(new gaia::GaiaOAuthClient(
       auth_request_context_.get()));
-  account_id_fetcher_->RefreshToken(client_info, refresh_token,
+  account_info_fetcher_->RefreshToken(client_info, refresh_token,
       std::vector<std::string>(1, kServiceScopeGetUserInfo), kMaxRetries,
       this);
 }
 
-void OAuth2LoginManager::OnRefreshTokenResponse(
-    const std::string& access_token,
-    int expires_in_seconds) {
-  account_id_fetcher_->GetUserEmail(access_token, kMaxRetries, this);
-}
-
-void OAuth2LoginManager::OnGetUserEmailResponse(
-    const std::string& user_email)  {
+void OAuth2LoginManager::UpdateCredentials(const std::string& account_id) {
+  DCHECK(!account_id.empty());
   DCHECK(!refresh_token_.empty());
-  account_id_fetcher_.reset();
-  std::string canonicalized = gaia::CanonicalizeEmail(user_email);
-  GetTokenService()->UpdateCredentials(canonicalized, refresh_token_);
+  // |account_id| is assumed to be already canonicalized if it's an email.
+  GetTokenService()->UpdateCredentials(account_id, refresh_token_);
 
   FOR_EACH_OBSERVER(Observer, observer_list_,
                     OnNewRefreshTokenAvaiable(user_profile_));
 }
 
+void OAuth2LoginManager::OnRefreshTokenResponse(
+    const std::string& access_token,
+    int expires_in_seconds) {
+  account_info_fetcher_->GetUserInfo(access_token, kMaxRetries, this);
+}
+
+void OAuth2LoginManager::OnGetUserInfoResponse(
+    scoped_ptr<base::DictionaryValue> user_info) {
+  account_info_fetcher_.reset();
+
+  std::string gaia_id;
+  std::string email;
+  user_info->GetString("id", &gaia_id);
+  user_info->GetString("email", &email);
+
+  AccountTrackerService* account_tracker =
+      AccountTrackerServiceFactory::GetForProfile(user_profile_);
+  account_tracker->SeedAccountInfo(gaia_id, email);
+  UpdateCredentials(account_tracker->PickAccountIdForAccount(gaia_id, email));
+}
+
 void OAuth2LoginManager::OnOAuthError() {
-  account_id_fetcher_.reset();
-  LOG(ERROR) << "Account id fetch failed!";
+  account_info_fetcher_.reset();
+  LOG(ERROR) << "Account info fetch failed!";
   SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
 }
 
 void OAuth2LoginManager::OnNetworkError(int response_code) {
-  account_id_fetcher_.reset();
-  LOG(ERROR) << "Account id fetch failed! response_code=" << response_code;
+  account_info_fetcher_.reset();
+  LOG(ERROR) << "Account info fetch failed! response_code=" << response_code;
   SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
 }
 
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
index 9543f5d..ab9ccdf 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager.h
@@ -149,8 +149,9 @@
 
   // gaia::GaiaOAuthClient::Delegate overrides.
   void OnRefreshTokenResponse(const std::string& access_token,
-                              int expires_in_seconds) override;
-  void OnGetUserEmailResponse(const std::string& user_email) override;
+                                      int expires_in_seconds) override;
+  void OnGetUserInfoResponse(
+      scoped_ptr<base::DictionaryValue> user_info) override;
   void OnOAuthError() override;
   void OnNetworkError(int response_code) override;
 
@@ -180,12 +181,15 @@
 
   // Records |refresh_token_| to token service. The associated account id is
   // assumed to be the primary account id of the user profile. If the primary
-  // account id is not present, GetAccountIdOfRefreshToken will be called to
-  // retrieve the associated account id.
+  // account id is not present, GetAccountInfoOfRefreshToken will be called to
+  // retrieve the associated account info.
   void StoreOAuth2Token();
 
-  // Get the account id corresponding to the specified refresh token.
-  void GetAccountIdOfRefreshToken(const std::string& refresh_token);
+  // Get the account info corresponding to the specified refresh token.
+  void GetAccountInfoOfRefreshToken(const std::string& refresh_token);
+
+  // Update the token service and inform listeners of a new refresh token.
+  void UpdateCredentials(const std::string& account_id);
 
   // Attempts to fetch OAuth2 tokens by using pre-authenticated cookie jar from
   // provided |auth_profile|.
@@ -230,7 +234,7 @@
 
   scoped_ptr<OAuth2TokenFetcher> oauth2_token_fetcher_;
   scoped_ptr<OAuth2LoginVerifier> login_verifier_;
-  scoped_ptr<gaia::GaiaOAuthClient> account_id_fetcher_;
+  scoped_ptr<gaia::GaiaOAuthClient> account_info_fetcher_;
 
   // OAuth2 refresh token.
   std::string refresh_token_;
diff --git a/chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc b/chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc
index 1d429a0..da71de9 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
@@ -17,6 +18,7 @@
     : BrowserContextKeyedServiceFactory(
         "OAuth2LoginManager",
         BrowserContextDependencyManager::GetInstance()) {
+  DependsOn(AccountTrackerServiceFactory::GetInstance());
   DependsOn(GlobalErrorServiceFactory::GetInstance());
   DependsOn(SigninManagerFactory::GetInstance());
   DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc b/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc
index 5cbb2a4..df68da7 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.cc
@@ -9,6 +9,7 @@
 #include "base/rand_util.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/camera_detector.h"
+#include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/screen_manager.h"
 #include "chrome/browser/chromeos/login/screens/error_screen.h"
@@ -106,6 +107,7 @@
       image_decoder_(NULL),
       apply_photo_after_decoding_(false),
       selected_image_(0),
+      histogram_helper_(new ErrorScreensHistogramHelper("Supervised")),
       weak_factory_(this) {
   DCHECK(actor_);
   if (actor_)
@@ -143,6 +145,7 @@
   if (!on_error_screen_)
     NetworkPortalDetector::Get()->AddAndFireObserver(this);
   on_error_screen_ = false;
+  histogram_helper_->OnScreenShow();
 }
 
 void SupervisedUserCreationScreen::OnPageSelected(const std::string& page) {
@@ -154,12 +157,14 @@
     const NetworkPortalDetector::CaptivePortalState& state)  {
   if (state.status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE) {
     get_screen_observer()->HideErrorScreen(this);
+    histogram_helper_->OnErrorHide();
   } else {
     on_error_screen_ = true;
     ErrorScreen* screen = get_screen_observer()->GetErrorScreen();
     ConfigureErrorScreen(screen, network, state.status);
     screen->SetUIState(ErrorScreen::UI_STATE_SUPERVISED);
     get_screen_observer()->ShowErrorScreen();
+    histogram_helper_->OnErrorShow(screen->GetErrorState());
   }
 }
 
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h b/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h
index a4269886..265857b 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h
@@ -22,6 +22,7 @@
 
 namespace chromeos {
 
+class ErrorScreensHistogramHelper;
 class NetworkState;
 class ScreenManager;
 
@@ -144,6 +145,8 @@
   bool apply_photo_after_decoding_;
   int selected_image_;
 
+  scoped_ptr<ErrorScreensHistogramHelper> histogram_helper_;
+
   base::WeakPtrFactory<SupervisedUserCreationScreen> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SupervisedUserCreationScreen);
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.cc b/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.cc
index 4351e54..bbb7e37 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h"
 
 #include "base/base64.h"
+#include "base/command_line.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_registry_simple.h"
@@ -18,6 +19,7 @@
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/common/chrome_switches.h"
 #include "chromeos/login/auth/key.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_thread.h"
@@ -35,6 +37,14 @@
 
 SupervisedUserLoginFlow::~SupervisedUserLoginFlow() {}
 
+void SupervisedUserLoginFlow::AppendAdditionalCommandLineSwitches() {
+  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+  if (user_manager->IsCurrentUserNew()) {
+    // Supervised users should launch into empty desktop on first run.
+    CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
+  }
+}
+
 bool SupervisedUserLoginFlow::CanLockScreen() {
   return true;
 }
@@ -59,10 +69,6 @@
   return false;
 }
 
-void SupervisedUserLoginFlow::HandleOAuthTokenStatusChange(
-    user_manager::User::OAuthTokenStatus status) {
-}
-
 void SupervisedUserLoginFlow::OnSyncSetupDataLoaded(
     const std::string& token) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h b/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h
index 7de6088a..dbb9784c 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h
@@ -24,6 +24,7 @@
   virtual ~SupervisedUserLoginFlow();
 
   // ExtendedUserFlow overrides.
+  virtual void AppendAdditionalCommandLineSwitches() override;
   virtual bool CanLockScreen() override;
   virtual bool ShouldLaunchBrowser() override;
   virtual bool ShouldSkipPostLoginScreens() override;
@@ -31,8 +32,6 @@
   virtual bool HandleLoginFailure(const AuthFailure& failure) override;
   virtual void HandleLoginSuccess(const UserContext& context) override;
   virtual bool HandlePasswordChangeDetected() override;
-  virtual void HandleOAuthTokenStatusChange(
-      user_manager::User::OAuthTokenStatus status) override;
   virtual void LaunchExtraSteps(Profile* profile) override;
 
   // ExtendedAuthenticator::NewAuthStatusConsumer overrides.
diff --git a/chrome/browser/chromeos/login/test_login_utils.cc b/chrome/browser/chromeos/login/test_login_utils.cc
index 2365630..0f86d4c 100644
--- a/chrome/browser/chromeos/login/test_login_utils.cc
+++ b/chrome/browser/chromeos/login/test_login_utils.cc
@@ -24,8 +24,9 @@
     Delegate* delegate) {
   if (user_context != expected_user_context_)
     NOTREACHED();
+
   // Profile hasn't been loaded.
-  delegate->OnProfilePrepared(NULL);
+  delegate->OnProfilePrepared(NULL, false);
 }
 
 void TestLoginUtils::DelegateDeleted(Delegate* delegate) {
diff --git a/chrome/browser/chromeos/login/ui/oobe_display.h b/chrome/browser/chromeos/login/ui/oobe_display.h
index 6015542..cfd991e 100644
--- a/chrome/browser/chromeos/login/ui/oobe_display.h
+++ b/chrome/browser/chromeos/login/ui/oobe_display.h
@@ -16,6 +16,7 @@
 class AutoEnrollmentCheckScreenActor;
 class CoreOobeActor;
 class ControllerPairingScreenActor;
+class DeviceDisabledScreenActor;
 class EnrollmentScreenActor;
 class ErrorScreenActor;
 class EulaScreenActor;
@@ -60,6 +61,7 @@
     SCREEN_FATAL_ERROR,
     SCREEN_OOBE_CONTROLLER_PAIRING,
     SCREEN_OOBE_HOST_PAIRING,
+    SCREEN_DEVICE_DISABLED,
     SCREEN_UNKNOWN
   };
 
@@ -87,6 +89,7 @@
   virtual AppLaunchSplashScreenActor* GetAppLaunchSplashScreenActor() = 0;
   virtual ControllerPairingScreenActor* GetControllerPairingScreenActor() = 0;
   virtual HostPairingScreenActor* GetHostPairingScreenActor() = 0;
+  virtual DeviceDisabledScreenActor* GetDeviceDisabledScreenActor() = 0;
 
   // Returns if JS side is fully loaded and ready to accept messages.
   // If |false| is returned, then |display_is_ready_callback| is stored
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc
index bae07c01..a6923d75 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_view.cc
+++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -282,7 +282,8 @@
 
   // TODO(nkostylev): Use WebContentsObserver::RenderViewCreated to track
   // when RenderView is created.
-  GetWebContents()->GetRenderViewHost()->GetView()->SetBackgroundOpaque(false);
+  GetWebContents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
+      SK_ColorTRANSPARENT);
 }
 
 content::WebUI* WebUILoginView::GetWebUI() {
diff --git a/chrome/browser/chromeos/login/user_flow.cc b/chrome/browser/chromeos/login/user_flow.cc
index ffec4623..289522f 100644
--- a/chrome/browser/chromeos/login/user_flow.cc
+++ b/chrome/browser/chromeos/login/user_flow.cc
@@ -24,6 +24,9 @@
 
 DefaultUserFlow::~DefaultUserFlow() {}
 
+void DefaultUserFlow::AppendAdditionalCommandLineSwitches() {
+}
+
 bool DefaultUserFlow::CanLockScreen() {
   return true;
 }
@@ -68,10 +71,17 @@
 ExtendedUserFlow::~ExtendedUserFlow() {
 }
 
+void ExtendedUserFlow::AppendAdditionalCommandLineSwitches() {
+}
+
 bool ExtendedUserFlow::ShouldShowSettings() {
   return true;
 }
 
+void ExtendedUserFlow::HandleOAuthTokenStatusChange(
+    user_manager::User::OAuthTokenStatus status) {
+}
+
 void ExtendedUserFlow::UnregisterFlowSoon() {
   std::string id_copy(user_id());
   base::MessageLoop::current()->PostTask(FROM_HERE,
diff --git a/chrome/browser/chromeos/login/user_flow.h b/chrome/browser/chromeos/login/user_flow.h
index ef7955f..d5479365a 100644
--- a/chrome/browser/chromeos/login/user_flow.h
+++ b/chrome/browser/chromeos/login/user_flow.h
@@ -21,6 +21,10 @@
  public:
   UserFlow();
   virtual ~UserFlow() = 0;
+
+  // Provides ability to alter command line before session has started.
+  virtual void AppendAdditionalCommandLineSwitches() = 0;
+
   // Indicates if screen locking should be enabled or disabled for a flow.
   virtual bool CanLockScreen() = 0;
   virtual bool ShouldShowSettings() = 0;
@@ -51,6 +55,7 @@
  public:
   virtual ~DefaultUserFlow();
 
+  virtual void AppendAdditionalCommandLineSwitches() override;
   virtual bool CanLockScreen() override;
   virtual bool ShouldShowSettings() override;
   virtual bool ShouldLaunchBrowser() override;
@@ -70,7 +75,10 @@
   explicit ExtendedUserFlow(const std::string& user_id);
   virtual ~ExtendedUserFlow();
 
+  virtual void AppendAdditionalCommandLineSwitches() override;
   virtual bool ShouldShowSettings() override;
+  virtual void HandleOAuthTokenStatusChange(
+      user_manager::User::OAuthTokenStatus status) override;
 
  protected:
   // Subclasses can call this method to unregister flow in the next event.
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 641a706..5ed4fcc1 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -33,6 +33,7 @@
 #include "chrome/browser/chromeos/login/hwid_checker.h"
 #include "chrome/browser/chromeos/login/login_utils.h"
 #include "chrome/browser/chromeos/login/screens/controller_pairing_screen.h"
+#include "chrome/browser/chromeos/login/screens/device_disabled_screen.h"
 #include "chrome/browser/chromeos/login/screens/error_screen.h"
 #include "chrome/browser/chromeos/login/screens/eula_screen.h"
 #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h"
@@ -166,6 +167,7 @@
 const char WizardController::kControllerPairingScreenName[] =
     "controller-pairing";
 const char WizardController::kHostPairingScreenName[] = "host-pairing";
+const char WizardController::kDeviceDisabledScreenName[] = "device-disabled";
 
 // static
 const int WizardController::kMinAudibleOutputVolumePercent = 10;
@@ -302,7 +304,10 @@
     return new chromeos::UserImageScreen(
         this, oobe_display_->GetUserImageScreenActor());
   } else if (screen_name == kEulaScreenName) {
-    return new chromeos::EulaScreen(this, oobe_display_->GetEulaScreenActor());
+    scoped_ptr<chromeos::EulaScreen> screen(
+        new chromeos::EulaScreen(this, oobe_display_->GetEulaScreenActor()));
+    screen->SetDelegate(this);
+    return screen.release();
   } else if (screen_name == kEnrollmentScreenName) {
     return new chromeos::EnrollmentScreen(
         this, oobe_display_->GetEnrollmentScreenActor());
@@ -347,7 +352,11 @@
     return new HostPairingScreen(this,
                                  oobe_display_->GetHostPairingScreenActor(),
                                  remora_controller_.get());
+  } else if (screen_name == kDeviceDisabledScreenName) {
+    return new chromeos::DeviceDisabledScreen(
+        this, oobe_display_->GetDeviceDisabledScreenActor());
   }
+
   return NULL;
 }
 
@@ -517,12 +526,18 @@
   SetCurrentScreen(GetScreen(kHostPairingScreenName));
 }
 
+void WizardController::ShowDeviceDisabledScreen() {
+  VLOG(1) << "Showing device disabled screen.";
+  SetStatusAreaVisible(true);
+  SetCurrentScreen(GetScreen(kDeviceDisabledScreenName));
+}
+
 void WizardController::SkipToLoginForTesting(
     const LoginScreenContext& context) {
   VLOG(1) << "SkipToLoginForTesting.";
   StartupUtils::MarkEulaAccepted();
   PerformPostEulaActions();
-  OnAutoEnrollmentCheckCompleted();
+  OnDeviceNotDisabled();
 }
 
 void WizardController::AddObserver(Observer* observer) {
@@ -719,15 +734,6 @@
   ResumeLoginScreen();
 }
 
-void WizardController::OnAutoEnrollmentCheckCompleted() {
-  if (ShouldAutoStartEnrollment() || enrollment_recovery_) {
-    ShowEnrollmentScreen();
-  } else {
-    PerformOOBECompletedActions();
-    ShowLoginScreen(LoginScreenContext());
-  }
-}
-
 void WizardController::OnTermsOfServiceDeclined() {
   // If the user declines the Terms of Service, end the session and return to
   // the login screen.
@@ -747,6 +753,17 @@
   InitiateOOBEUpdate();
 }
 
+void WizardController::OnDeviceNotDisabled() {
+  if (skip_update_enroll_after_eula_ ||
+      ShouldAutoStartEnrollment() ||
+      enrollment_recovery_) {
+    ShowEnrollmentScreen();
+  } else {
+    PerformOOBECompletedActions();
+    ShowLoginScreen(LoginScreenContext());
+  }
+}
+
 void WizardController::InitiateOOBEUpdate() {
   VLOG(1) << "InitiateOOBEUpdate";
   PerformPostEulaActions();
@@ -894,6 +911,8 @@
     ShowControllerPairingScreen();
   } else if (screen_name == kHostPairingScreenName) {
     ShowHostPairingScreen();
+  } else if (screen_name == kDeviceDisabledScreenName) {
+    ShowDeviceDisabledScreen();
   } else if (screen_name != kTestNoScreenName) {
     if (is_out_of_box_) {
       time_oobe_started_ = base::Time::Now();
@@ -954,10 +973,7 @@
       ShowNetworkScreen();
       break;
     case ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED:
-      if (skip_update_enroll_after_eula_)
-        ShowEnrollmentScreen();
-      else
-        OnAutoEnrollmentCheckCompleted();
+      ShowDeviceDisabledScreen();
       break;
     case ENTERPRISE_ENROLLMENT_COMPLETED:
       OnEnrollmentDone();
@@ -995,6 +1011,9 @@
     case HOST_PAIRING_FINISHED:
       OnHostPairingFinished();
       break;
+    case DEVICE_NOT_DISABLED:
+      OnDeviceNotDisabled();
+      break;
     default:
       NOTREACHED();
   }
@@ -1006,14 +1025,6 @@
   password_ = password;
 }
 
-void WizardController::SetUsageStatisticsReporting(bool val) {
-  usage_statistics_reporting_ = val;
-}
-
-bool WizardController::GetUsageStatisticsReporting() const {
-  return usage_statistics_reporting_;
-}
-
 void WizardController::ShowErrorScreen() {
   VLOG(1) << "Showing error screen.";
   SetCurrentScreen(GetScreen(kErrorScreenName));
@@ -1025,6 +1036,14 @@
   SetCurrentScreen(parent_screen);
 }
 
+void WizardController::SetUsageStatisticsReporting(bool val) {
+  usage_statistics_reporting_ = val;
+}
+
+bool WizardController::GetUsageStatisticsReporting() const {
+  return usage_statistics_reporting_;
+}
+
 void WizardController::OnAccessibilityStatusChanged(
     const AccessibilityStatusEventDetails& details) {
   enum AccessibilityNotificationType type = details.notification_type;
@@ -1260,4 +1279,33 @@
   ShowHostPairingScreen();
 }
 
+void WizardController::SetHostConfiguration() {
+  if (shark_controller_) {
+    NetworkScreenActor* network_actor = oobe_display_->GetNetworkScreenActor();
+    shark_controller_->SetHostConfiguration(
+        true,  // Eula must be accepted before we get this far.
+        network_actor->GetApplicationLocale(),
+        network_actor->GetTimezone(),
+        GetUsageStatisticsReporting(),
+        network_actor->GetInputMethod());
+  }
+}
+
+void WizardController::ConfigureHost(bool accepted_eula,
+                                     const std::string& lang,
+                                     const std::string& timezone,
+                                     bool send_reports,
+                                     const std::string& keyboard_layout) {
+  VLOG(1) << "ConfigureHost locale=" << lang
+          << ", timezone=" << timezone
+          << ", keyboard_layout=" << keyboard_layout;
+  if (accepted_eula) // Always true.
+    StartupUtils::MarkEulaAccepted();
+  SetUsageStatisticsReporting(send_reports);
+  NetworkScreenActor* network_actor = oobe_display_->GetNetworkScreenActor();
+  network_actor->SetApplicationLocale(lang);
+  network_actor->SetTimezone(timezone);
+  network_actor->SetInputMethod(keyboard_layout);
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h
index ad3b71e..56f87f9 100644
--- a/chrome/browser/chromeos/login/wizard_controller.h
+++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -20,6 +20,7 @@
 #include "base/timer/timer.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/login/screen_manager.h"
+#include "chrome/browser/chromeos/login/screens/eula_screen.h"
 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
 
 class PrefRegistrySimple;
@@ -54,7 +55,9 @@
 
 // Class that manages control flow between wizard screens. Wizard controller
 // interacts with screen controllers to move the user between screens.
-class WizardController : public ScreenObserver, public ScreenManager {
+class WizardController : public ScreenObserver,
+                         public ScreenManager,
+                         public EulaScreen::Delegate {
  public:
   // Observes screen changes.
   class Observer {
@@ -158,6 +161,7 @@
   static const char kHIDDetectionScreenName[];
   static const char kControllerPairingScreenName[];
   static const char kHostPairingScreenName[];
+  static const char kDeviceDisabledScreenName[];
 
   // Volume percent at which spoken feedback is still audible.
   static const int kMinAudibleOutputVolumePercent;
@@ -179,6 +183,7 @@
   void ShowHIDDetectionScreen();
   void ShowControllerPairingScreen();
   void ShowHostPairingScreen();
+  void ShowDeviceDisabledScreen();
 
   // Shows images login screen.
   void ShowLoginScreen(const LoginScreenContext& context);
@@ -207,11 +212,11 @@
   void OnKioskAutolaunchConfirmed();
   void OnKioskEnableCompleted();
   void OnWrongHWIDWarningSkipped();
-  void OnAutoEnrollmentCheckCompleted();
   void OnTermsOfServiceDeclined();
   void OnTermsOfServiceAccepted();
   void OnControllerPairingFinished();
   void OnHostPairingFinished();
+  void OnDeviceNotDisabled();
 
   // Callback function after setting MetricsReporting.
   void InitiateMetricsReportingChangeCallback(bool enabled);
@@ -237,12 +242,20 @@
   virtual void ShowCurrentScreen() override;
   virtual void OnSetUserNamePassword(const std::string& username,
                                      const std::string& password) override;
-  virtual void SetUsageStatisticsReporting(bool val) override;
-  virtual bool GetUsageStatisticsReporting() const override;
+  virtual void SetHostConfiguration() override;
+  virtual void ConfigureHost(bool accepted_eula,
+                             const std::string& lang,
+                             const std::string& timezone,
+                             bool send_reports,
+                             const std::string& keyboard_layout) override;
   virtual ErrorScreen* GetErrorScreen() override;
   virtual void ShowErrorScreen() override;
   virtual void HideErrorScreen(BaseScreen* parent_screen) override;
 
+  // Overridden from EulaScreen::Delegate:
+  virtual void SetUsageStatisticsReporting(bool val) override;
+  virtual bool GetUsageStatisticsReporting() const override;
+
   // Notification of a change in the state of an accessibility setting.
   void OnAccessibilityStatusChanged(
       const AccessibilityStatusEventDetails& details);
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
index 02f1e9d..cb09d208 100644
--- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -25,8 +25,10 @@
 #include "chrome/browser/chromeos/login/enrollment/mock_auto_enrollment_check_screen.h"
 #include "chrome/browser/chromeos/login/enrollment/mock_enrollment_screen.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
+#include "chrome/browser/chromeos/login/screens/device_disabled_screen.h"
 #include "chrome/browser/chromeos/login/screens/error_screen.h"
 #include "chrome/browser/chromeos/login/screens/hid_detection_screen.h"
+#include "chrome/browser/chromeos/login/screens/mock_device_disabled_screen_actor.h"
 #include "chrome/browser/chromeos/login/screens/mock_eula_screen.h"
 #include "chrome/browser/chromeos/login/screens/mock_network_screen.h"
 #include "chrome/browser/chromeos/login/screens/mock_update_screen.h"
@@ -41,6 +43,7 @@
 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
 #include "chrome/browser/chromeos/policy/server_backed_device_state.h"
+#include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/timezone/timezone_request.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
@@ -64,6 +67,7 @@
 #include "chromeos/settings/timezone_settings.h"
 #include "chromeos/system/fake_statistics_provider.h"
 #include "chromeos/system/statistics_provider.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
@@ -77,6 +81,7 @@
 
 using ::testing::Exactly;
 using ::testing::Invoke;
+using ::testing::Mock;
 using ::testing::Return;
 
 namespace chromeos {
@@ -106,6 +111,8 @@
     "    \"timeZoneName\" : \"Pacific Standard Time\"\n"
     "}";
 
+const char kDisabledMessage[] = "This device has been disabled.";
+
 class PrefStoreStub : public TestingPrefStore {
  public:
   // TestingPrefStore overrides:
@@ -390,7 +397,9 @@
     WizardControllerTest::SetUpOnMainThread();
 
     // Make sure that OOBE is run as an "official" build.
-    WizardController::default_controller()->is_official_build_ = true;
+    WizardController* wizard_controller =
+        WizardController::default_controller();
+    wizard_controller->is_official_build_ = true;
 
     // Clear portal list (as it is by default in OOBE).
     NetworkHandler::Get()->network_state_handler()->SetCheckPortalList("");
@@ -416,12 +425,22 @@
          kAutoEnrollmentCheckScreenName,
          MockAutoEnrollmentCheckScreen,
          MockAutoEnrollmentCheckScreenActor);
+    device_disabled_screen_actor_.reset(new MockDeviceDisabledScreenActor);
+    wizard_controller->screens_[WizardController::kDeviceDisabledScreenName] =
+        make_linked_ptr(new DeviceDisabledScreen(
+            wizard_controller,
+            device_disabled_screen_actor_.get()));
+    EXPECT_CALL(*device_disabled_screen_actor_, Show(_)).Times(0);
 
     // Switch to the initial screen.
-    EXPECT_EQ(NULL, WizardController::default_controller()->current_screen());
+    EXPECT_EQ(NULL, wizard_controller->current_screen());
     EXPECT_CALL(*mock_network_screen_, Show()).Times(1);
-    WizardController::default_controller()->AdvanceToScreen(
-        WizardController::kNetworkScreenName);
+    wizard_controller->AdvanceToScreen(WizardController::kNetworkScreenName);
+  }
+
+  void TearDownOnMainThread() override {
+    device_disabled_screen_actor_.reset();
+    WizardControllerTest::TearDownOnMainThread();
   }
 
   virtual void TearDown() {
@@ -488,6 +507,7 @@
       MockEnrollmentScreenActor>* mock_enrollment_screen_;
   MockOutShowHide<MockAutoEnrollmentCheckScreen,
       MockAutoEnrollmentCheckScreenActor>* mock_auto_enrollment_check_screen_;
+  scoped_ptr<MockDeviceDisabledScreenActor> device_disabled_screen_actor_;
 
  private:
   NetworkPortalDetectorTestImpl* network_portal_detector_;
@@ -525,6 +545,7 @@
   InitTimezoneResolver();
   OnExit(ScreenObserver::EULA_ACCEPTED);
   EXPECT_TRUE(GetGeolocationProvider());
+
   // Let update screen smooth time process (time = 0ms).
   content::RunAllPendingInMessageLoop();
 
@@ -534,7 +555,7 @@
   OnExit(ScreenObserver::UPDATE_INSTALLED);
 
   CheckCurrentScreen(WizardController::kAutoEnrollmentCheckScreenName);
-  EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(0);
+  EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(1);
   EXPECT_CALL(*mock_eula_screen_, Show()).Times(0);
   OnExit(ScreenObserver::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED);
 
@@ -562,6 +583,7 @@
   EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1);
   EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
   OnExit(ScreenObserver::EULA_ACCEPTED);
+
   // Let update screen smooth time process (time = 0ms).
   content::RunAllPendingInMessageLoop();
 
@@ -571,7 +593,7 @@
   OnExit(ScreenObserver::UPDATE_ERROR_UPDATING);
 
   CheckCurrentScreen(WizardController::kAutoEnrollmentCheckScreenName);
-  EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(0);
+  EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(1);
   EXPECT_CALL(*mock_eula_screen_, Show()).Times(0);
   OnExit(ScreenObserver::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED);
 
@@ -700,9 +722,13 @@
   EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
 }
 
-class WizardControllerEnrollmentFlowTest : public WizardControllerFlowTest {
+class WizardControllerDeviceStateTest : public WizardControllerFlowTest {
  protected:
-  WizardControllerEnrollmentFlowTest() {
+  WizardControllerDeviceStateTest()
+      : install_attributes_(std::string(),
+                            std::string(),
+                            std::string(),
+                            policy::DEVICE_MODE_NOT_SET) {
     fake_statistics_provider_.SetMachineStatistic("serial_number", "test");
     fake_statistics_provider_.SetMachineStatistic(system::kActivateDateKey,
                                                   "2000-01");
@@ -723,10 +749,12 @@
   system::ScopedFakeStatisticsProvider fake_statistics_provider_;
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(WizardControllerEnrollmentFlowTest);
+  policy::ScopedStubEnterpriseInstallAttributes install_attributes_;
+
+  DISALLOW_COPY_AND_ASSIGN(WizardControllerDeviceStateTest);
 };
 
-IN_PROC_BROWSER_TEST_F(WizardControllerEnrollmentFlowTest,
+IN_PROC_BROWSER_TEST_F(WizardControllerDeviceStateTest,
                        ControlFlowForcedReEnrollment) {
   CheckCurrentScreen(WizardController::kNetworkScreenName);
   EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
@@ -738,6 +766,7 @@
   EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1);
   EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
   OnExit(ScreenObserver::EULA_ACCEPTED);
+
   // Let update screen smooth time process (time = 0ms).
   content::RunAllPendingInMessageLoop();
 
@@ -752,6 +781,7 @@
             WizardController::default_controller()->current_screen());
   EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(1);
   screen->Start();
+
   // Wait for auto-enrollment controller to encounter the connection error.
   WaitForAutoEnrollmentState(policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR);
 
@@ -780,7 +810,7 @@
   EXPECT_TRUE(StartupUtils::IsOobeCompleted());
 }
 
-IN_PROC_BROWSER_TEST_F(WizardControllerEnrollmentFlowTest,
+IN_PROC_BROWSER_TEST_F(WizardControllerDeviceStateTest,
                        ControlFlowNoForcedReEnrollmentOnFirstBoot) {
   fake_statistics_provider_.ClearMachineStatistic(system::kActivateDateKey);
   EXPECT_NE(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT,
@@ -798,6 +828,7 @@
   EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1);
   EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
   OnExit(ScreenObserver::EULA_ACCEPTED);
+
   // Let update screen smooth time process (time = 0ms).
   content::RunAllPendingInMessageLoop();
 
@@ -810,6 +841,7 @@
       AutoEnrollmentCheckScreen::Get(WizardController::default_controller());
   EXPECT_EQ(screen,
             WizardController::default_controller()->current_screen());
+  EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(1);
   screen->Start();
   EXPECT_EQ(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT,
             LoginDisplayHostImpl::default_host()
@@ -817,6 +849,57 @@
                 ->state());
 }
 
+IN_PROC_BROWSER_TEST_F(WizardControllerDeviceStateTest,
+                       ControlFlowDeviceDisabled) {
+  CheckCurrentScreen(WizardController::kNetworkScreenName);
+  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
+  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
+  OnExit(ScreenObserver::NETWORK_CONNECTED);
+
+  CheckCurrentScreen(WizardController::kEulaScreenName);
+  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
+  EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1);
+  EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
+  OnExit(ScreenObserver::EULA_ACCEPTED);
+
+  // Let update screen smooth time process (time = 0ms).
+  content::RunAllPendingInMessageLoop();
+
+  CheckCurrentScreen(WizardController::kUpdateScreenName);
+  EXPECT_CALL(*mock_update_screen_, Hide()).Times(1);
+  EXPECT_CALL(*mock_auto_enrollment_check_screen_, Show()).Times(1);
+  OnExit(ScreenObserver::UPDATE_INSTALLED);
+
+  AutoEnrollmentCheckScreen* screen =
+      AutoEnrollmentCheckScreen::Get(WizardController::default_controller());
+  EXPECT_EQ(screen,
+            WizardController::default_controller()->current_screen());
+  EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(1);
+  screen->Start();
+
+  // Wait for auto-enrollment controller to encounter the connection error.
+  WaitForAutoEnrollmentState(policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR);
+
+  // The error screen shows up if device state could not be retrieved.
+  EXPECT_FALSE(StartupUtils::IsOobeCompleted());
+  EXPECT_EQ(GetErrorScreen(),
+            WizardController::default_controller()->current_screen());
+  base::DictionaryValue device_state;
+  device_state.SetBoolean(policy::kDeviceStateDisabled, true);
+  device_state.SetString(policy::kDeviceStateDisabledMessage, kDisabledMessage);
+  g_browser_process->local_state()->Set(prefs::kServerBackedDeviceState,
+                                        device_state);
+  EXPECT_CALL(*device_disabled_screen_actor_, Show(kDisabledMessage)).Times(1);
+  OnExit(ScreenObserver::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED);
+
+  ResetAutoEnrollmentCheckScreen();
+
+  // Make sure the device disabled screen is shown.
+  CheckCurrentScreen(WizardController::kDeviceDisabledScreenName);
+
+  EXPECT_FALSE(StartupUtils::IsOobeCompleted());
+}
+
 class WizardControllerBrokenLocalStateTest : public WizardControllerTest {
  protected:
   WizardControllerBrokenLocalStateTest()
@@ -845,11 +928,6 @@
     WizardController::default_controller()->is_official_build_ = true;
   }
 
-  virtual void TearDownInProcessBrowserTestFixture() override {
-    WizardControllerTest::TearDownInProcessBrowserTestFixture();
-  }
-
-
   FakeSessionManagerClient* fake_session_manager_client() const {
     return fake_session_manager_client_;
   }
@@ -970,6 +1048,7 @@
   EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1);
   EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
   OnExit(ScreenObserver::EULA_ACCEPTED);
+
   // Let update screen smooth time process (time = 0ms).
   content::RunAllPendingInMessageLoop();
 
@@ -1014,6 +1093,7 @@
   EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1);
   EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
   OnExit(ScreenObserver::EULA_ACCEPTED);
+
   // Let update screen smooth time process (time = 0ms).
   content::RunAllPendingInMessageLoop();
 
@@ -1113,7 +1193,7 @@
 // TODO(dzhioev): Add tests for controller/host pairing flow.
 // http://crbug.com/375191
 
-COMPILE_ASSERT(ScreenObserver::EXIT_CODES_COUNT == 23,
+COMPILE_ASSERT(ScreenObserver::EXIT_CODES_COUNT == 24,
                add_tests_for_new_control_flow_you_just_introduced);
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/options/passphrase_textfield.h b/chrome/browser/chromeos/options/passphrase_textfield.h
index ac6b934..39834ef4 100644
--- a/chrome/browser/chromeos/options/passphrase_textfield.h
+++ b/chrome/browser/chromeos/options/passphrase_textfield.h
@@ -27,6 +27,7 @@
   // Returns the passphrase. If it's unchanged, then returns an empty string.
   std::string GetPassphrase();
 
+  bool changed() const { return changed_; }
   bool show_fake() const { return show_fake_; }
 
  private:
diff --git a/chrome/browser/chromeos/options/wifi_config_view.cc b/chrome/browser/chromeos/options/wifi_config_view.cc
index 2263c2d..77610b9 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.cc
+++ b/chrome/browser/chromeos/options/wifi_config_view.cc
@@ -699,7 +699,7 @@
       }
     } else {
       security = shill::kSecurity8021x;
-      SetEapProperties(&properties);
+      SetEapProperties(&properties, false /* not configured */);
     }
     properties.SetStringWithoutPathExpansion(
         shill::kSecurityProperty, security);
@@ -715,7 +715,7 @@
       return true;  // Close dialog
     }
     if (eap_method_combobox_) {
-      SetEapProperties(&properties);
+      SetEapProperties(&properties, true /* configured */);
       properties.SetBooleanWithoutPathExpansion(
           shill::kSaveCredentialsProperty, GetSaveCredentials());
     } else {
@@ -862,7 +862,8 @@
   return base::UTF16ToUTF8(identity_anonymous_textfield_->text());
 }
 
-void WifiConfigView::SetEapProperties(base::DictionaryValue* properties) {
+void WifiConfigView::SetEapProperties(base::DictionaryValue* properties,
+                                      bool configured) {
   properties->SetStringWithoutPathExpansion(
       shill::kEapIdentityProperty, GetEapIdentity());
   properties->SetStringWithoutPathExpansion(
@@ -878,9 +879,10 @@
 
   properties->SetBooleanWithoutPathExpansion(
       shill::kEapUseSystemCasProperty, GetEapUseSystemCas());
-  properties->SetStringWithoutPathExpansion(
-      shill::kEapPasswordProperty, GetPassphrase());
-
+  if (!configured || passphrase_textfield_->changed()) {
+    properties->SetStringWithoutPathExpansion(
+        shill::kEapPasswordProperty, GetPassphrase());
+  }
   base::ListValue* pem_list = new base::ListValue;
   std::string ca_cert_pem = GetEapServerCaCertPEM();
   if (!ca_cert_pem.empty())
diff --git a/chrome/browser/chromeos/options/wifi_config_view.h b/chrome/browser/chromeos/options/wifi_config_view.h
index c9de05a8..e79156e 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.h
+++ b/chrome/browser/chromeos/options/wifi_config_view.h
@@ -132,8 +132,10 @@
   // certificate or empty properties if no client cert is required.
   void SetEapClientCertProperties(base::DictionaryValue* properties) const;
 
-  // Fill in |properties| with the appropriate values.
-  void SetEapProperties(base::DictionaryValue* properties);
+  // Fill in |properties| with the appropriate values. If |configured| is
+  // true then this is for an already configured network.
+  void SetEapProperties(base::DictionaryValue* properties,
+                        bool configured);
 
   // Returns true if the EAP method requires a user certificate.
   bool UserCertRequired() const;
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
index aa61394b1a..1b3a6f96 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/settings/device_settings_provider.h"
 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -43,8 +44,6 @@
 
 namespace {
 
-DeviceSettingsService* g_device_settings_service_for_testing = NULL;
-
 bool IsOwnerInTests(const std::string& user_id) {
   if (user_id.empty() ||
       !CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestType) ||
@@ -147,23 +146,20 @@
       callback);
 }
 
-DeviceSettingsService* GetDeviceSettingsService() {
-  if (g_device_settings_service_for_testing)
-    return g_device_settings_service_for_testing;
-  return DeviceSettingsService::IsInitialized() ? DeviceSettingsService::Get()
-                                                : NULL;
-}
-
 }  // namespace
 
 OwnerSettingsServiceChromeOS::OwnerSettingsServiceChromeOS(
+    DeviceSettingsService* device_settings_service,
     Profile* profile,
     const scoped_refptr<OwnerKeyUtil>& owner_key_util)
     : ownership::OwnerSettingsService(owner_key_util),
+      device_settings_service_(device_settings_service),
       profile_(profile),
       waiting_for_profile_creation_(true),
       waiting_for_tpm_token_(true),
-      weak_factory_(this) {
+      has_pending_changes_(false),
+      weak_factory_(this),
+      store_settings_factory_(this) {
   if (TPMTokenLoader::IsInitialized()) {
     TPMTokenLoader::TPMTokenStatus tpm_token_status =
         TPMTokenLoader::Get()->IsTPMTokenEnabled(
@@ -178,13 +174,22 @@
     DBusThreadManager::Get()->GetSessionManagerClient()->AddObserver(this);
   }
 
+  if (device_settings_service_)
+    device_settings_service_->AddObserver(this);
+
   registrar_.Add(this,
                  chrome::NOTIFICATION_PROFILE_CREATED,
                  content::Source<Profile>(profile_));
+
+  UpdateFromService();
 }
 
 OwnerSettingsServiceChromeOS::~OwnerSettingsServiceChromeOS() {
   DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (device_settings_service_)
+    device_settings_service_->RemoveObserver(this);
+
   if (DBusThreadManager::IsInitialized() &&
       DBusThreadManager::Get()->GetSessionManagerClient()) {
     DBusThreadManager::Get()->GetSessionManagerClient()->RemoveObserver(this);
@@ -201,19 +206,43 @@
   ReloadKeypair();
 }
 
-void OwnerSettingsServiceChromeOS::SignAndStorePolicyAsync(
-    scoped_ptr<em::PolicyData> policy,
-    const base::Closure& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  SignAndStoreSettingsOperation* operation = new SignAndStoreSettingsOperation(
-      base::Bind(&OwnerSettingsServiceChromeOS::HandleCompletedOperation,
-                 weak_factory_.GetWeakPtr(),
-                 callback),
-      policy.Pass());
-  operation->set_owner_settings_service(weak_factory_.GetWeakPtr());
-  pending_operations_.push_back(operation);
-  if (pending_operations_.front() == operation)
-    StartNextOperation();
+bool OwnerSettingsServiceChromeOS::HandlesSetting(const std::string& setting) {
+  return DeviceSettingsProvider::IsDeviceSetting(setting);
+}
+
+bool OwnerSettingsServiceChromeOS::Set(const std::string& setting,
+                                       const base::Value& value) {
+  if (!IsOwner() && !IsOwnerInTests(user_id_))
+    return false;
+
+  UpdateDeviceSettings(setting, value, device_settings_);
+  em::PolicyData policy_data;
+  policy_data.set_username(user_id_);
+  CHECK(device_settings_.SerializeToString(policy_data.mutable_policy_value()));
+  FOR_EACH_OBSERVER(OwnerSettingsService::Observer,
+                    observers_,
+                    OnTentativeChangesInPolicy(policy_data));
+  has_pending_changes_ = true;
+  StoreDeviceSettings();
+  return true;
+}
+
+bool OwnerSettingsServiceChromeOS::CommitTentativeDeviceSettings(
+    scoped_ptr<enterprise_management::PolicyData> policy) {
+  if (!IsOwner() && !IsOwnerInTests(user_id_))
+    return false;
+  if (policy->username() != user_id_) {
+    LOG(ERROR) << "Username mismatch: " << policy->username() << " vs. "
+               << user_id_;
+    return false;
+  }
+  CHECK(device_settings_.ParseFromString(policy->policy_value()));
+  FOR_EACH_OBSERVER(OwnerSettingsService::Observer,
+                    observers_,
+                    OnTentativeChangesInPolicy(*policy));
+  has_pending_changes_ = true;
+  StoreDeviceSettings();
+  return true;
 }
 
 void OwnerSettingsServiceChromeOS::Observe(
@@ -242,6 +271,16 @@
     ReloadKeypair();
 }
 
+void OwnerSettingsServiceChromeOS::OwnershipStatusChanged() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  StoreDeviceSettings();
+}
+
+void OwnerSettingsServiceChromeOS::DeviceSettingsUpdated() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  StoreDeviceSettings();
+}
+
 // static
 void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync(
     const std::string& user_hash,
@@ -261,10 +300,251 @@
 }
 
 // static
-void OwnerSettingsServiceChromeOS::SetDeviceSettingsServiceForTesting(
-    DeviceSettingsService* device_settings_service) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  g_device_settings_service_for_testing = device_settings_service;
+scoped_ptr<em::PolicyData> OwnerSettingsServiceChromeOS::AssemblePolicy(
+    const std::string& user_id,
+    const em::PolicyData* policy_data,
+    const em::ChromeDeviceSettingsProto* settings) {
+  scoped_ptr<em::PolicyData> policy(new em::PolicyData());
+  if (policy_data) {
+    // Preserve management settings.
+    if (policy_data->has_management_mode())
+      policy->set_management_mode(policy_data->management_mode());
+    if (policy_data->has_request_token())
+      policy->set_request_token(policy_data->request_token());
+    if (policy_data->has_device_id())
+      policy->set_device_id(policy_data->device_id());
+  } else {
+    // If there's no previous policy data, this is the first time the device
+    // setting is set. We set the management mode to NOT_MANAGED initially.
+    policy->set_management_mode(em::PolicyData::NOT_MANAGED);
+  }
+  policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
+  policy->set_timestamp(
+      (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds());
+  policy->set_username(user_id);
+  if (!settings->SerializeToString(policy->mutable_policy_value()))
+    return scoped_ptr<em::PolicyData>();
+
+  return policy.Pass();
+}
+
+// static
+void OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
+    const std::string& path,
+    const base::Value& value,
+    enterprise_management::ChromeDeviceSettingsProto& settings) {
+  if (path == kAccountsPrefAllowNewUser) {
+    em::AllowNewUsersProto* allow = settings.mutable_allow_new_users();
+    bool allow_value;
+    if (value.GetAsBoolean(&allow_value)) {
+      allow->set_allow_new_users(allow_value);
+    } else {
+      NOTREACHED();
+    }
+  } else if (path == kAccountsPrefAllowGuest) {
+    em::GuestModeEnabledProto* guest = settings.mutable_guest_mode_enabled();
+    bool guest_value;
+    if (value.GetAsBoolean(&guest_value))
+      guest->set_guest_mode_enabled(guest_value);
+    else
+      NOTREACHED();
+  } else if (path == kAccountsPrefSupervisedUsersEnabled) {
+    em::SupervisedUsersSettingsProto* supervised =
+        settings.mutable_supervised_users_settings();
+    bool supervised_value;
+    if (value.GetAsBoolean(&supervised_value))
+      supervised->set_supervised_users_enabled(supervised_value);
+    else
+      NOTREACHED();
+  } else if (path == kAccountsPrefShowUserNamesOnSignIn) {
+    em::ShowUserNamesOnSigninProto* show = settings.mutable_show_user_names();
+    bool show_value;
+    if (value.GetAsBoolean(&show_value))
+      show->set_show_user_names(show_value);
+    else
+      NOTREACHED();
+  } else if (path == kAccountsPrefDeviceLocalAccounts) {
+    em::DeviceLocalAccountsProto* device_local_accounts =
+        settings.mutable_device_local_accounts();
+    device_local_accounts->clear_account();
+    const base::ListValue* accounts_list = NULL;
+    if (value.GetAsList(&accounts_list)) {
+      for (base::ListValue::const_iterator entry(accounts_list->begin());
+           entry != accounts_list->end();
+           ++entry) {
+        const base::DictionaryValue* entry_dict = NULL;
+        if ((*entry)->GetAsDictionary(&entry_dict)) {
+          em::DeviceLocalAccountInfoProto* account =
+              device_local_accounts->add_account();
+          std::string account_id;
+          if (entry_dict->GetStringWithoutPathExpansion(
+                  kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) {
+            account->set_account_id(account_id);
+          }
+          int type;
+          if (entry_dict->GetIntegerWithoutPathExpansion(
+                  kAccountsPrefDeviceLocalAccountsKeyType, &type)) {
+            account->set_type(
+                static_cast<em::DeviceLocalAccountInfoProto::AccountType>(
+                    type));
+          }
+          std::string kiosk_app_id;
+          if (entry_dict->GetStringWithoutPathExpansion(
+                  kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
+                  &kiosk_app_id)) {
+            account->mutable_kiosk_app()->set_app_id(kiosk_app_id);
+          }
+        } else {
+          NOTREACHED();
+        }
+      }
+    } else {
+      NOTREACHED();
+    }
+  } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginId) {
+    em::DeviceLocalAccountsProto* device_local_accounts =
+        settings.mutable_device_local_accounts();
+    std::string id;
+    if (value.GetAsString(&id))
+      device_local_accounts->set_auto_login_id(id);
+    else
+      NOTREACHED();
+  } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginDelay) {
+    em::DeviceLocalAccountsProto* device_local_accounts =
+        settings.mutable_device_local_accounts();
+    int delay;
+    if (value.GetAsInteger(&delay))
+      device_local_accounts->set_auto_login_delay(delay);
+    else
+      NOTREACHED();
+  } else if (path == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) {
+    em::DeviceLocalAccountsProto* device_local_accounts =
+        settings.mutable_device_local_accounts();
+    bool enabled;
+    if (value.GetAsBoolean(&enabled))
+      device_local_accounts->set_enable_auto_login_bailout(enabled);
+    else
+      NOTREACHED();
+  } else if (path ==
+             kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) {
+    em::DeviceLocalAccountsProto* device_local_accounts =
+        settings.mutable_device_local_accounts();
+    bool should_prompt;
+    if (value.GetAsBoolean(&should_prompt))
+      device_local_accounts->set_prompt_for_network_when_offline(should_prompt);
+    else
+      NOTREACHED();
+  } else if (path == kSignedDataRoamingEnabled) {
+    em::DataRoamingEnabledProto* roam = settings.mutable_data_roaming_enabled();
+    bool roaming_value = false;
+    if (value.GetAsBoolean(&roaming_value))
+      roam->set_data_roaming_enabled(roaming_value);
+    else
+      NOTREACHED();
+  } else if (path == kReleaseChannel) {
+    em::ReleaseChannelProto* release_channel =
+        settings.mutable_release_channel();
+    std::string channel_value;
+    if (value.GetAsString(&channel_value))
+      release_channel->set_release_channel(channel_value);
+    else
+      NOTREACHED();
+  } else if (path == kStatsReportingPref) {
+    em::MetricsEnabledProto* metrics = settings.mutable_metrics_enabled();
+    bool metrics_value = false;
+    if (value.GetAsBoolean(&metrics_value))
+      metrics->set_metrics_enabled(metrics_value);
+    else
+      NOTREACHED();
+  } else if (path == kAccountsPrefUsers) {
+    em::UserWhitelistProto* whitelist_proto = settings.mutable_user_whitelist();
+    whitelist_proto->clear_user_whitelist();
+    const base::ListValue* users;
+    if (value.GetAsList(&users)) {
+      for (base::ListValue::const_iterator i = users->begin();
+           i != users->end();
+           ++i) {
+        std::string email;
+        if ((*i)->GetAsString(&email))
+          whitelist_proto->add_user_whitelist(email);
+      }
+    }
+  } else if (path == kAccountsPrefEphemeralUsersEnabled) {
+    em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
+        settings.mutable_ephemeral_users_enabled();
+    bool ephemeral_users_enabled_value = false;
+    if (value.GetAsBoolean(&ephemeral_users_enabled_value)) {
+      ephemeral_users_enabled->set_ephemeral_users_enabled(
+          ephemeral_users_enabled_value);
+    } else {
+      NOTREACHED();
+    }
+  } else if (path == kAllowRedeemChromeOsRegistrationOffers) {
+    em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers =
+        settings.mutable_allow_redeem_offers();
+    bool allow_redeem_offers_value;
+    if (value.GetAsBoolean(&allow_redeem_offers_value)) {
+      allow_redeem_offers->set_allow_redeem_offers(allow_redeem_offers_value);
+    } else {
+      NOTREACHED();
+    }
+  } else if (path == kStartUpFlags) {
+    em::StartUpFlagsProto* flags_proto = settings.mutable_start_up_flags();
+    flags_proto->Clear();
+    const base::ListValue* flags;
+    if (value.GetAsList(&flags)) {
+      for (base::ListValue::const_iterator i = flags->begin();
+           i != flags->end();
+           ++i) {
+        std::string flag;
+        if ((*i)->GetAsString(&flag))
+          flags_proto->add_flags(flag);
+      }
+    }
+  } else if (path == kSystemUse24HourClock) {
+    em::SystemUse24HourClockProto* use_24hour_clock_proto =
+        settings.mutable_use_24hour_clock();
+    use_24hour_clock_proto->Clear();
+    bool use_24hour_clock_value;
+    if (value.GetAsBoolean(&use_24hour_clock_value)) {
+      use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value);
+    } else {
+      NOTREACHED();
+    }
+  } else if (path == kAttestationForContentProtectionEnabled) {
+    em::AttestationSettingsProto* attestation_settings =
+        settings.mutable_attestation_settings();
+    bool setting_enabled;
+    if (value.GetAsBoolean(&setting_enabled)) {
+      attestation_settings->set_content_protection_enabled(setting_enabled);
+    } else {
+      NOTREACHED();
+    }
+  } else {
+    // The remaining settings don't support Set(), since they are not
+    // intended to be customizable by the user:
+    //   kAccountsPrefTransferSAMLCookies
+    //   kAppPack
+    //   kDeviceAttestationEnabled
+    //   kDeviceOwner
+    //   kIdleLogoutTimeout
+    //   kIdleLogoutWarningDuration
+    //   kReleaseChannelDelegated
+    //   kReportDeviceActivityTimes
+    //   kReportDeviceBootMode
+    //   kReportDeviceLocation
+    //   kReportDeviceVersionInfo
+    //   kReportDeviceNetworkInterfaces
+    //   kReportDeviceUsers
+    //   kScreenSaverExtensionId
+    //   kScreenSaverTimeout
+    //   kServiceAccountIdentity
+    //   kStartUpUrls
+    //   kSystemTimezonePolicy
+    //   kVariationsRestrictParameter
+
+    LOG(FATAL) << "Device setting " << path << " is read-only.";
+  }
 }
 
 void OwnerSettingsServiceChromeOS::OnPostKeypairLoadedActions() {
@@ -272,8 +552,8 @@
 
   user_id_ = profile_->GetProfileName();
   const bool is_owner = IsOwner() || IsOwnerInTests(user_id_);
-  if (is_owner && GetDeviceSettingsService())
-    GetDeviceSettingsService()->InitOwner(user_id_, weak_factory_.GetWeakPtr());
+  if (is_owner && device_settings_service_)
+    device_settings_service_->InitOwner(user_id_, weak_factory_.GetWeakPtr());
 }
 
 void OwnerSettingsServiceChromeOS::ReloadKeypairImpl(const base::Callback<
@@ -294,44 +574,58 @@
                  callback));
 }
 
-void OwnerSettingsServiceChromeOS::StartNextOperation() {
-  DeviceSettingsService* service = GetDeviceSettingsService();
-  if (!pending_operations_.empty() && service &&
-      service->session_manager_client()) {
-    pending_operations_.front()->Start(
-        service->session_manager_client(), owner_key_util_, public_key_);
-  }
+void OwnerSettingsServiceChromeOS::StoreDeviceSettings() {
+  if (!has_pending_changes_ || store_settings_factory_.HasWeakPtrs())
+    return;
+  if (!UpdateFromService())
+    return;
+  scoped_ptr<em::PolicyData> policy = AssemblePolicy(
+      user_id_, device_settings_service_->policy_data(), &device_settings_);
+  has_pending_changes_ = false;
+  bool rv = AssembleAndSignPolicyAsync(
+      content::BrowserThread::GetBlockingPool(),
+      policy.Pass(),
+      base::Bind(&OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned,
+                 store_settings_factory_.GetWeakPtr()));
+  if (!rv)
+    OnSignedPolicyStored(false /* success */);
 }
 
-void OwnerSettingsServiceChromeOS::HandleCompletedOperation(
-    const base::Closure& callback,
-    SessionManagerOperation* operation,
-    DeviceSettingsService::Status status) {
-  DCHECK_EQ(operation, pending_operations_.front());
-
-  DeviceSettingsService* service = GetDeviceSettingsService();
-  if (status == DeviceSettingsService::STORE_SUCCESS) {
-    service->set_policy_data(operation->policy_data().Pass());
-    service->set_device_settings(operation->device_settings().Pass());
+void OwnerSettingsServiceChromeOS::OnPolicyAssembledAndSigned(
+    scoped_ptr<em::PolicyFetchResponse> policy_response) {
+  if (!policy_response.get()) {
+    OnSignedPolicyStored(false /* success */);
+    return;
   }
+  device_settings_service_->Store(
+      policy_response.Pass(),
+      base::Bind(&OwnerSettingsServiceChromeOS::OnSignedPolicyStored,
+                 store_settings_factory_.GetWeakPtr(),
+                 true /* success */));
+}
 
-  if ((operation->public_key().get() && !public_key_.get()) ||
-      (operation->public_key().get() && public_key_.get() &&
-       operation->public_key()->data() != public_key_->data())) {
-    // Public part changed so we need to reload private part too.
-    ReloadKeypair();
-    content::NotificationService::current()->Notify(
-        chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
-        content::Source<OwnerSettingsServiceChromeOS>(this),
-        content::NotificationService::NoDetails());
+void OwnerSettingsServiceChromeOS::OnSignedPolicyStored(bool success) {
+  store_settings_factory_.InvalidateWeakPtrs();
+  FOR_EACH_OBSERVER(OwnerSettingsService::Observer,
+                    observers_,
+                    OnSignedPolicyStored(success));
+  StoreDeviceSettings();
+  if (!success)
+    has_pending_changes_ = true;
+}
+
+bool OwnerSettingsServiceChromeOS::UpdateFromService() {
+  if (!device_settings_service_ ||
+      device_settings_service_->status() !=
+          DeviceSettingsService::STORE_SUCCESS ||
+      !device_settings_service_->device_settings()) {
+    return false;
   }
-  service->OnSignAndStoreOperationCompleted(status);
-  if (!callback.is_null())
-    callback.Run();
-
-  pending_operations_.pop_front();
-  delete operation;
-  StartNextOperation();
+  enterprise_management::ChromeDeviceSettingsProto settings =
+      *device_settings_service_->device_settings();
+  settings.MergeFrom(device_settings_);
+  device_settings_.Swap(&settings);
+  return true;
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h
index 8f47b4d9..3d0116a4 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h
@@ -5,12 +5,12 @@
 #ifndef CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_CHROMEOS_H_
 #define CHROME_BROWSER_CHROMEOS_OWNERSHIP_OWNER_SETTINGS_SERVICE_CHROMEOS_H_
 
-#include <deque>
+#include <string>
 #include <vector>
 
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -27,8 +27,6 @@
 
 namespace chromeos {
 
-class SessionManagerOperation;
-
 // The class is a profile-keyed service which holds public/private
 // keypair corresponds to a profile. The keypair is reloaded automatically when
 // profile is created and TPM token is ready. Note that the private part of a
@@ -38,16 +36,19 @@
 // (crbug.com/230018).
 class OwnerSettingsServiceChromeOS : public ownership::OwnerSettingsService,
                                      public content::NotificationObserver,
-                                     public SessionManagerClient::Observer {
+                                     public SessionManagerClient::Observer,
+                                     public DeviceSettingsService::Observer {
  public:
   virtual ~OwnerSettingsServiceChromeOS();
 
   void OnTPMTokenReady(bool tpm_token_enabled);
 
   // ownership::OwnerSettingsService implementation:
-  virtual void SignAndStorePolicyAsync(
-      scoped_ptr<enterprise_management::PolicyData> policy,
-      const base::Closure& callback) override;
+  virtual bool HandlesSetting(const std::string& setting) override;
+  virtual bool Set(const std::string& setting,
+                   const base::Value& value) override;
+  virtual bool CommitTentativeDeviceSettings(
+      scoped_ptr<enterprise_management::PolicyData> policy) override;
 
   // NotificationObserver implementation:
   virtual void Observe(int type,
@@ -57,6 +58,10 @@
   // SessionManagerClient::Observer:
   virtual void OwnerKeySet(bool success) override;
 
+  // DeviceSettingsService::Observer:
+  virtual void OwnershipStatusChanged() override;
+  virtual void DeviceSettingsUpdated() override;
+
   // Checks if the user is the device owner, without the user profile having to
   // been initialized. Should be used only if login state is in safe mode.
   static void IsOwnerForSafeModeAsync(
@@ -64,13 +69,26 @@
       const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util,
       const IsOwnerCallback& callback);
 
-  static void SetDeviceSettingsServiceForTesting(
-      DeviceSettingsService* device_settings_service);
+  // Assembles PolicyData based on |settings|, |policy_data| and
+  // |user_id|.
+  static scoped_ptr<enterprise_management::PolicyData> AssemblePolicy(
+      const std::string& user_id,
+      const enterprise_management::PolicyData* policy_data,
+      const enterprise_management::ChromeDeviceSettingsProto* settings);
+
+  // Updates device |settings|.
+  static void UpdateDeviceSettings(
+      const std::string& path,
+      const base::Value& value,
+      enterprise_management::ChromeDeviceSettingsProto& settings);
+
+  bool has_pending_changes() const { return has_pending_changes_; }
 
  private:
   friend class OwnerSettingsServiceChromeOSFactory;
 
   OwnerSettingsServiceChromeOS(
+      DeviceSettingsService* device_settings_service,
       Profile* profile,
       const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util);
 
@@ -85,13 +103,26 @@
   // Possibly notifies DeviceSettingsService that owner's keypair is loaded.
   virtual void OnPostKeypairLoadedActions() override;
 
-  // Performs next operation in the queue.
-  void StartNextOperation();
+  // Tries to sign store current device settings if there're pending
+  // changes in device settings and no active previous call to
+  // DeviceSettingsService::Store().
+  void StoreDeviceSettings();
 
-  // Called when sign-and-store operation completes it's work.
-  void HandleCompletedOperation(const base::Closure& callback,
-                                SessionManagerOperation* operation,
-                                DeviceSettingsService::Status status);
+  // Called when current device settings are successfully signed.
+  // Sends signed settings for storage.
+  void OnPolicyAssembledAndSigned(
+      scoped_ptr<enterprise_management::PolicyFetchResponse> policy_response);
+
+  // Called by DeviceSettingsService when modified and signed device
+  // settings are stored. Notifies observers and tries to store device
+  // settings again.
+  void OnSignedPolicyStored(bool success);
+
+  // Fetches device settings from DeviceSettingsService and merges
+  // them with local device settings.
+  bool UpdateFromService();
+
+  DeviceSettingsService* device_settings_service_;
 
   // Profile this service instance belongs to.
   Profile* profile_;
@@ -105,14 +136,22 @@
   // Whether TPM token still needs to be initialized.
   bool waiting_for_tpm_token_;
 
-  // The queue of pending sign-and-store operations. The first operation on the
-  // queue is currently active; it gets removed and destroyed once it completes.
-  std::deque<SessionManagerOperation*> pending_operations_;
+  // The device settings.  This may be different from the actual
+  // current device settings (which can be obtained from
+  // DeviceSettingsService) in case the device does not have an owner
+  // yet or there are pending changes that have not yet been written
+  // to session_manager.
+  enterprise_management::ChromeDeviceSettingsProto device_settings_;
+
+  // True if some settings were changed but not stored.
+  bool has_pending_changes_;
 
   content::NotificationRegistrar registrar_;
 
   base::WeakPtrFactory<OwnerSettingsServiceChromeOS> weak_factory_;
 
+  base::WeakPtrFactory<OwnerSettingsServiceChromeOS> store_settings_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(OwnerSettingsServiceChromeOS);
 };
 
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc
index b971f34..afe0480 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.cc
@@ -7,6 +7,7 @@
 #include "base/path_service.h"
 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chromeos/chromeos_paths.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -15,6 +16,19 @@
 
 namespace chromeos {
 
+namespace {
+
+DeviceSettingsService* g_device_settings_service_for_testing_ = nullptr;
+
+DeviceSettingsService* GetDeviceSettingsService() {
+  if (g_device_settings_service_for_testing_)
+    return g_device_settings_service_for_testing_;
+  return DeviceSettingsService::IsInitialized() ? DeviceSettingsService::Get()
+                                                : nullptr;
+}
+
+}  // namespace
+
 OwnerSettingsServiceChromeOSFactory::OwnerSettingsServiceChromeOSFactory()
     : BrowserContextKeyedServiceFactory(
           "OwnerSettingsService",
@@ -37,6 +51,12 @@
   return Singleton<OwnerSettingsServiceChromeOSFactory>::get();
 }
 
+// static
+void OwnerSettingsServiceChromeOSFactory::SetDeviceSettingsServiceForTesting(
+    DeviceSettingsService* device_settings_service) {
+  g_device_settings_service_for_testing_ = device_settings_service;
+}
+
 scoped_refptr<ownership::OwnerKeyUtil>
 OwnerSettingsServiceChromeOSFactory::GetOwnerKeyUtil() {
   if (owner_key_util_.get())
@@ -59,8 +79,10 @@
   Profile* profile = static_cast<Profile*>(browser_context);
   if (profile->IsGuestSession() || ProfileHelper::IsSigninProfile(profile))
     return NULL;
-  return new OwnerSettingsServiceChromeOS(profile,
-                                          GetInstance()->GetOwnerKeyUtil());
+  return new OwnerSettingsServiceChromeOS(
+      GetDeviceSettingsService(),
+      profile,
+      GetInstance()->GetOwnerKeyUtil());
 }
 
 bool OwnerSettingsServiceChromeOSFactory::ServiceIsCreatedWithBrowserContext()
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h
index 6352b0a..1774fa7 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h
@@ -20,6 +20,7 @@
 
 namespace chromeos {
 
+class DeviceSettingsService;
 class OwnerSettingsServiceChromeOS;
 
 class OwnerSettingsServiceChromeOSFactory
@@ -29,6 +30,9 @@
 
   static OwnerSettingsServiceChromeOSFactory* GetInstance();
 
+  static void SetDeviceSettingsServiceForTesting(
+      DeviceSettingsService* device_settings_service);
+
   scoped_refptr<ownership::OwnerKeyUtil> GetOwnerKeyUtil();
 
   void SetOwnerKeyUtilForTesting(
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
new file mode 100644
index 0000000..a28b1446
--- /dev/null
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
@@ -0,0 +1,144 @@
+// 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 <queue>
+#include <utility>
+
+#include "base/macros.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_path_override.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
+#include "chrome/browser/chromeos/settings/device_settings_provider.h"
+#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
+#include "chrome/common/chrome_paths.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 "chromeos/settings/cros_settings_names.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+namespace {
+
+void OnPrefChanged(const std::string& /* setting */) {
+}
+
+class PrefsChecker : public ownership::OwnerSettingsService::Observer {
+ public:
+  PrefsChecker(OwnerSettingsServiceChromeOS* service,
+               DeviceSettingsProvider* provider)
+      : service_(service), provider_(provider) {
+    CHECK(service_);
+    CHECK(provider_);
+    service_->AddObserver(this);
+  }
+
+  virtual ~PrefsChecker() { service_->RemoveObserver(this); }
+
+  // OwnerSettingsService::Observer implementation:
+  virtual void OnSignedPolicyStored(bool success) override {
+    CHECK(success);
+
+    if (service_->has_pending_changes())
+      return;
+
+    while (!set_requests_.empty()) {
+      SetRequest request = set_requests_.front();
+      set_requests_.pop();
+      const base::Value* value = provider_->Get(request.first);
+      ASSERT_TRUE(request.second->Equals(value));
+    }
+    loop_.Quit();
+  }
+
+  void Set(const std::string& setting, const base::Value& value) {
+    service_->Set(setting, value);
+    set_requests_.push(
+        SetRequest(setting, linked_ptr<base::Value>(value.DeepCopy())));
+  }
+
+  void Wait() { loop_.Run(); }
+
+ private:
+  OwnerSettingsServiceChromeOS* service_;
+  DeviceSettingsProvider* provider_;
+  base::RunLoop loop_;
+
+  typedef std::pair<std::string, linked_ptr<base::Value>> SetRequest;
+  std::queue<SetRequest> set_requests_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrefsChecker);
+};
+
+}  // namespace
+
+class OwnerSettingsServiceChromeOSTest : public DeviceSettingsTestBase {
+ public:
+  OwnerSettingsServiceChromeOSTest()
+      : local_state_(TestingBrowserProcess::GetGlobal()),
+        user_data_dir_override_(chrome::DIR_USER_DATA) {}
+
+  virtual void SetUp() override {
+    DeviceSettingsTestBase::SetUp();
+    provider_.reset(new DeviceSettingsProvider(base::Bind(&OnPrefChanged),
+                                               &device_settings_service_));
+    owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
+    InitOwner(device_policy_.policy_data().username(), true);
+    FlushDeviceSettings();
+  }
+
+  virtual void TearDown() override { DeviceSettingsTestBase::TearDown(); }
+
+  void TestSingleSet(OwnerSettingsServiceChromeOS* service,
+                     const std::string& setting,
+                     const base::Value& in_value) {
+    PrefsChecker checker(service, provider_.get());
+    checker.Set(setting, in_value);
+    FlushDeviceSettings();
+    checker.Wait();
+  }
+
+  ScopedTestingLocalState local_state_;
+  scoped_ptr<DeviceSettingsProvider> provider_;
+  base::ScopedPathOverride user_data_dir_override_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(OwnerSettingsServiceChromeOSTest);
+};
+
+TEST_F(OwnerSettingsServiceChromeOSTest, SingleSetTest) {
+  OwnerSettingsServiceChromeOS* service =
+      OwnerSettingsServiceChromeOSFactory::GetForProfile(profile_.get());
+  ASSERT_TRUE(service);
+  ASSERT_TRUE(service->IsOwner());
+  TestSingleSet(service, kReleaseChannel, base::StringValue("dev-channel"));
+  TestSingleSet(service, kReleaseChannel, base::StringValue("beta-channel"));
+  TestSingleSet(service, kReleaseChannel, base::StringValue("stable-channel"));
+}
+
+TEST_F(OwnerSettingsServiceChromeOSTest, MultipleSetTest) {
+  OwnerSettingsServiceChromeOS* service =
+      OwnerSettingsServiceChromeOSFactory::GetForProfile(profile_.get());
+  ASSERT_TRUE(service);
+  ASSERT_TRUE(service->IsOwner());
+  base::FundamentalValue allow_guest(false);
+  base::StringValue release_channel("stable-channel");
+  base::FundamentalValue show_user_names(true);
+
+  PrefsChecker checker(service, provider_.get());
+
+  checker.Set(kAccountsPrefAllowGuest, allow_guest);
+  checker.Set(kReleaseChannel, release_channel);
+  checker.Set(kAccountsPrefShowUserNamesOnSignIn, show_user_names);
+
+  FlushDeviceSettings();
+  checker.Wait();
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client.cc b/chrome/browser/chromeos/policy/auto_enrollment_client.cc
index 014db8d..e6e241cd 100644
--- a/chrome/browser/chromeos/policy/auto_enrollment_client.cc
+++ b/chrome/browser/chromeos/policy/auto_enrollment_client.cc
@@ -410,6 +410,17 @@
                  kDeviceStateRestoreMode,
                  !restore_mode.empty(),
                  new base::StringValue(restore_mode));
+
+      UpdateDict(dict.Get(),
+                 kDeviceStateDisabled,
+                 true /* set_or_clear */,
+                 new base::FundamentalValue(
+                     state_response.has_disabled_state()));
+      UpdateDict(dict.Get(),
+                 kDeviceStateDisabledMessage,
+                 state_response.has_disabled_state(),
+                 new base::StringValue(
+                     state_response.disabled_state().message()));
     }
     local_state_->CommitPendingWrite();
     device_state_available_ = true;
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client_unittest.cc b/chrome/browser/chromeos/policy/auto_enrollment_client_unittest.cc
index bdeb712..5a9bb4b0a 100644
--- a/chrome/browser/chromeos/policy/auto_enrollment_client_unittest.cc
+++ b/chrome/browser/chromeos/policy/auto_enrollment_client_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/policy/server_backed_device_state.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
@@ -34,6 +35,7 @@
 const char kStateKeyHash[] =
     "\xde\x74\xcd\xf0\x03\x36\x8c\x21\x79\xba\xb1\x5a\xc4\x32\xee\xd6"
     "\xb3\x4a\x5e\xff\x73\x7e\x92\xd9\xf8\x6e\x72\x44\xd0\x97\xc3\xe6";
+const char kDisabledMessage[] = "This device has been disabled.";
 
 using ::testing::InSequence;
 using ::testing::Mock;
@@ -115,12 +117,18 @@
 
   void ServerWillSendState(
       const std::string& management_domain,
-      em::DeviceStateRetrievalResponse::RestoreMode restore_mode) {
+      em::DeviceStateRetrievalResponse::RestoreMode restore_mode,
+      scoped_ptr<std::string> device_disabled_message) {
     em::DeviceManagementResponse response;
     em::DeviceStateRetrievalResponse* state_response =
         response.mutable_device_state_retrieval_response();
     state_response->set_restore_mode(restore_mode);
     state_response->set_management_domain(management_domain);
+    if (device_disabled_message) {
+      em::DisabledState* disabled_state =
+          state_response->mutable_disabled_state();
+      disabled_state->set_message(*device_disabled_message);
+    }
     EXPECT_CALL(
         *service_,
         CreateJob(DeviceManagementRequestJob::TYPE_DEVICE_STATE_RETRIEVAL, _))
@@ -148,6 +156,50 @@
         local_state_->GetUserPref(prefs::kAutoEnrollmentPowerLimit)));
   }
 
+  bool HasServerBackedState() {
+    return local_state_->GetUserPref(prefs::kServerBackedDeviceState);
+  }
+
+  void VerifyServerBackedState(
+      const std::string& expected_management_domain,
+      const std::string& expected_restore_mode,
+      scoped_ptr<std::string> expected_disabled_message) {
+    const base::Value* state =
+        local_state_->GetUserPref(prefs::kServerBackedDeviceState);
+    ASSERT_TRUE(state);
+    const base::DictionaryValue* state_dict = nullptr;
+    ASSERT_TRUE(state->GetAsDictionary(&state_dict));
+
+    std::string actual_management_domain;
+    EXPECT_TRUE(state_dict->GetString(kDeviceStateManagementDomain,
+                                      &actual_management_domain));
+    EXPECT_EQ(expected_management_domain, actual_management_domain);
+
+    if (!expected_restore_mode.empty()) {
+      std::string actual_restore_mode;
+      EXPECT_TRUE(state_dict->GetString(kDeviceStateRestoreMode,
+                                        &actual_restore_mode));
+      EXPECT_EQ(expected_restore_mode, actual_restore_mode);
+    } else {
+      EXPECT_FALSE(state_dict->HasKey(kDeviceStateRestoreMode));
+    }
+
+    const bool expected_disabled_state = expected_disabled_message;
+    bool actual_disabled_state = false;
+    EXPECT_TRUE(state_dict->GetBoolean(kDeviceStateDisabled,
+                                       &actual_disabled_state));
+    EXPECT_EQ(expected_disabled_state, actual_disabled_state);
+
+    if (expected_disabled_message) {
+      std::string actual_disabled_message;
+      EXPECT_TRUE(state_dict->GetString(kDeviceStateDisabledMessage,
+                                        &actual_disabled_message));
+      EXPECT_EQ(*expected_disabled_message, actual_disabled_message);
+    } else {
+      EXPECT_FALSE(state_dict->HasKey(kDeviceStateDisabledMessage));
+    }
+  }
+
   const em::DeviceAutoEnrollmentRequest& auto_enrollment_request() {
     return last_request_.auto_enrollment_request();
   }
@@ -169,6 +221,7 @@
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, EmptyReply) {
@@ -176,6 +229,7 @@
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_);
   VerifyCachedResult(false, 8);
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, ClientUploadsRightBits) {
@@ -188,6 +242,7 @@
   EXPECT_EQ(16, auto_enrollment_request().modulus());
   EXPECT_EQ(kStateKeyHash[31] & 0xf, auto_enrollment_request().remainder());
   VerifyCachedResult(false, 8);
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, AskForMoreThenFail) {
@@ -197,6 +252,7 @@
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, AskForMoreThenEvenMore) {
@@ -206,6 +262,7 @@
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, AskForLess) {
@@ -214,10 +271,14 @@
   ServerWillReply(-1, true, true);
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
   VerifyCachedResult(true, 8);
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
 }
 
 TEST_F(AutoEnrollmentClientTest, AskForSame) {
@@ -226,10 +287,14 @@
   ServerWillReply(-1, true, true);
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
   VerifyCachedResult(true, 8);
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
 }
 
 TEST_F(AutoEnrollmentClientTest, AskForSameTwice) {
@@ -239,6 +304,7 @@
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, AskForTooMuch) {
@@ -246,6 +312,7 @@
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, AskNonPowerOf2) {
@@ -259,6 +326,7 @@
   EXPECT_EQ(128, auto_enrollment_request().modulus());
   EXPECT_EQ(kStateKeyHash[31] & 0x7f, auto_enrollment_request().remainder());
   VerifyCachedResult(false, 8);
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, ConsumerDevice) {
@@ -266,6 +334,7 @@
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_);
   VerifyCachedResult(false, 8);
+  EXPECT_FALSE(HasServerBackedState());
 
   // Network changes don't trigger retries after obtaining a response from
   // the server.
@@ -273,14 +342,18 @@
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_);
 }
 
-TEST_F(AutoEnrollmentClientTest, EnterpriseDevice) {
+TEST_F(AutoEnrollmentClientTest, ForcedReEnrollment) {
   ServerWillReply(-1, true, true);
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      nullptr);
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
   VerifyCachedResult(true, 8);
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          nullptr);
 
   // Network changes don't trigger retries after obtaining a response from
   // the server.
@@ -288,11 +361,40 @@
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
 }
 
+TEST_F(AutoEnrollmentClientTest, RequestedReEnrollment) {
+  ServerWillReply(-1, true, true);
+  ServerWillSendState(
+      "example.com",
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_REQUESTED,
+      nullptr);
+  client_->Start();
+  EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
+  VerifyCachedResult(true, 8);
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentRequested,
+                          nullptr);
+}
+
+TEST_F(AutoEnrollmentClientTest, DeviceDisabled) {
+  ServerWillReply(-1, true, true);
+  ServerWillSendState(
+      "example.com",
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_NONE,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
+  client_->Start();
+  EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_);
+  VerifyCachedResult(true, 8);
+  VerifyServerBackedState("example.com",
+                          "",
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
+}
+
 TEST_F(AutoEnrollmentClientTest, NoSerial) {
   CreateClient("", true, 4, 8);
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, NoBitsUploaded) {
@@ -305,6 +407,7 @@
   EXPECT_EQ(1, auto_enrollment_request().modulus());
   EXPECT_EQ(0, auto_enrollment_request().remainder());
   VerifyCachedResult(false, 0);
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, ManyBitsUploaded) {
@@ -320,6 +423,7 @@
     EXPECT_EQ(bottom62 % (GG_INT64_C(1) << i),
               auto_enrollment_request().remainder());
     VerifyCachedResult(false, i);
+    EXPECT_FALSE(HasServerBackedState());
   }
 }
 
@@ -330,10 +434,14 @@
   ServerWillReply(-1, true, true);
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
   VerifyCachedResult(true, 37);
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
 }
 
 TEST_F(AutoEnrollmentClientTest, ReuseCachedDecision) {
@@ -344,12 +452,17 @@
                             new base::FundamentalValue(8));
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
   AutoEnrollmentClient::CancelAutoEnrollment();
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_NO_ENROLLMENT, state_);
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 TEST_F(AutoEnrollmentClientTest, RetryIfPowerLargerThanCached) {
@@ -361,9 +474,13 @@
   ServerWillReply(-1, true, true);
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
 }
 
 TEST_F(AutoEnrollmentClientTest, NetworkChangeRetryAfterErrors) {
@@ -372,26 +489,35 @@
   // Don't invoke the callback if there was a network failure.
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
 
   // The client doesn't retry if no new connection became available.
   client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_SERVER_ERROR, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
 
   // Retry once the network is back.
   ServerWillReply(-1, true, true);
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
   client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
   EXPECT_TRUE(HasCachedDecision());
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
 
   // Subsequent network changes don't trigger retries.
   client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
   client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
   EXPECT_TRUE(HasCachedDecision());
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
 }
 
 TEST_F(AutoEnrollmentClientTest, CancelAndDeleteSoonWithPendingRequest) {
@@ -449,9 +575,13 @@
   ServerWillReply(-1, true, true);
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
 
   // The client will delete itself immediately if there are no pending
   // requests.
@@ -482,6 +612,7 @@
   // Callback should signal the connection error.
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_CONNECTION_ERROR, state_);
   EXPECT_FALSE(HasCachedDecision());
+  EXPECT_FALSE(HasServerBackedState());
   Mock::VerifyAndClearExpectations(service_.get());
 
   InSequence sequence;
@@ -494,13 +625,17 @@
   // State download triggers.
   ServerWillSendState(
       "example.com",
-      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED);
+      em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED,
+      make_scoped_ptr(new std::string(kDisabledMessage)));
   EXPECT_CALL(*service_, StartJob(_, _, _, _, _, _, _));
 
   // Trigger a network change event.
   client_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
   EXPECT_TRUE(HasCachedDecision());
+  VerifyServerBackedState("example.com",
+                          kDeviceStateRestoreModeReEnrollmentEnforced,
+                          make_scoped_ptr(new std::string(kDisabledMessage)));
   Mock::VerifyAndClearExpectations(service_.get());
 }
 
@@ -513,6 +648,7 @@
   client_->Start();
   EXPECT_EQ(AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT, state_);
   VerifyCachedResult(true, 8);
+  EXPECT_FALSE(HasServerBackedState());
 }
 
 }  // namespace
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_invalidator_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_invalidator_unittest.cc
index 2fb4124f..4c123dd 100644
--- a/chrome/browser/chromeos/policy/device_cloud_policy_invalidator_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_invalidator_unittest.cc
@@ -100,7 +100,6 @@
  private:
   content::TestBrowserThreadBundle thread_bundle_;
   scoped_refptr<net::URLRequestContextGetter> system_request_context_;
-  TestingProfileManager profile_manager_;
   chromeos::FakeUserManager* fake_user_manager_;
   chromeos::ScopedUserManagerEnabler user_manager_enabler_;
   ScopedStubEnterpriseInstallAttributes install_attributes_;
@@ -108,6 +107,7 @@
       test_device_settings_service_;
   scoped_ptr<chromeos::ScopedTestCrosSettings> test_cros_settings_;
   chromeos::DeviceSettingsTestHelper device_settings_test_helper_;
+  TestingProfileManager profile_manager_;
 
   scoped_ptr<DeviceCloudPolicyInvalidator> invalidator_;
 };
@@ -116,13 +116,13 @@
     : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
       system_request_context_(new net::TestURLRequestContextGetter(
           base::MessageLoopProxy::current())),
-      profile_manager_(TestingBrowserProcess::GetGlobal()),
       fake_user_manager_(new chromeos::FakeUserManager),
       user_manager_enabler_(fake_user_manager_),
       install_attributes_("example.com",
                           "user@example.com",
                           "device_id",
-                          DEVICE_MODE_ENTERPRISE) {
+                          DEVICE_MODE_ENTERPRISE),
+      profile_manager_(TestingBrowserProcess::GetGlobal()) {
 }
 
 DeviceCloudPolicyInvalidatorTest::~DeviceCloudPolicyInvalidatorTest() {
diff --git a/chrome/browser/chromeos/policy/server_backed_device_state.cc b/chrome/browser/chromeos/policy/server_backed_device_state.cc
index 2f023a77c..6f76d7f 100644
--- a/chrome/browser/chromeos/policy/server_backed_device_state.cc
+++ b/chrome/browser/chromeos/policy/server_backed_device_state.cc
@@ -8,6 +8,8 @@
 
 const char kDeviceStateManagementDomain[] = "management_domain";
 const char kDeviceStateRestoreMode[] = "device_mode";
+const char kDeviceStateDisabled[] = "disabled";
+const char kDeviceStateDisabledMessage[] = "disabled_message";
 
 const char kDeviceStateRestoreModeReEnrollmentRequested[] =
     "re-enrollment-requested";
diff --git a/chrome/browser/chromeos/policy/server_backed_device_state.h b/chrome/browser/chromeos/policy/server_backed_device_state.h
index bb6d039..3581617 100644
--- a/chrome/browser/chromeos/policy/server_backed_device_state.h
+++ b/chrome/browser/chromeos/policy/server_backed_device_state.h
@@ -10,6 +10,8 @@
 // Dictionary key constants for prefs::kServerBackedDeviceState.
 extern const char kDeviceStateManagementDomain[];
 extern const char kDeviceStateRestoreMode[];
+extern const char kDeviceStateDisabled[];
+extern const char kDeviceStateDisabledMessage[];
 
 // Values for kDeviceStateRestoreMode.
 extern const char kDeviceStateRestoreModeReEnrollmentEnforced[];
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc
index 1da9fbc..41d55d4 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -13,6 +13,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
@@ -449,6 +450,8 @@
 }
 
 DeviceSettingsProvider::~DeviceSettingsProvider() {
+  if (device_settings_service_->GetOwnerSettingsService())
+    device_settings_service_->GetOwnerSettingsService()->RemoveObserver(this);
   device_settings_service_->RemoveObserver(this);
 }
 
@@ -471,19 +474,51 @@
     return;
   }
 
-  if (IsDeviceSetting(path)) {
-    pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
-    if (!store_callback_factory_.HasWeakPtrs())
-      SetInPolicy();
-  } else {
+  if (!IsDeviceSetting(path)) {
     NOTREACHED() << "Try to set unhandled cros setting " << path;
+    return;
   }
+
+  if (device_settings_service_->HasPrivateOwnerKey()) {
+    // Directly set setting through OwnerSettingsService.
+    ownership::OwnerSettingsService* service =
+        device_settings_service_->GetOwnerSettingsService();
+    if (!service->Set(path, in_value)) {
+      NotifyObservers(path);
+      return;
+    }
+  } else {
+    // Temporary store new setting in
+    // |device_settings_|. |device_settings_| will be stored on a disk
+    // as soon as an ownership of device the will be taken.
+    OwnerSettingsServiceChromeOS::UpdateDeviceSettings(
+        path, in_value, device_settings_);
+    em::PolicyData data;
+    data.set_username(device_settings_service_->GetUsername());
+    CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
+
+    // Set the cache to the updated value.
+    UpdateValuesCache(data, device_settings_, TEMPORARILY_UNTRUSTED);
+
+    if (!device_settings_cache::Store(data, g_browser_process->local_state())) {
+      LOG(ERROR) << "Couldn't store to the temp storage.";
+      NotifyObservers(path);
+      return;
+    }
+  }
+
+  bool metrics_value;
+  if (path == kStatsReportingPref && in_value.GetAsBoolean(&metrics_value))
+    ApplyMetricsSetting(false, metrics_value);
 }
 
 void DeviceSettingsProvider::OwnershipStatusChanged() {
   DeviceSettingsService::OwnershipStatus new_ownership_status =
       device_settings_service_->GetOwnershipStatus();
 
+  if (device_settings_service_->GetOwnerSettingsService())
+    device_settings_service_->GetOwnerSettingsService()->AddObserver(this);
+
   // If the device just became owned, write the settings accumulated in the
   // cache to device settings proper. It is important that writing only happens
   // in this case, as during normal operation, the contents of the cache should
@@ -504,7 +539,14 @@
       new_settings.MergeFrom(device_settings_);
       device_settings_.Swap(&new_settings);
     }
-    StoreDeviceSettings();
+
+    scoped_ptr<em::PolicyData> policy(new em::PolicyData());
+    policy->set_username(device_settings_service_->GetUsername());
+    CHECK(device_settings_.SerializeToString(policy->mutable_policy_value()));
+    if (!device_settings_service_->GetOwnerSettingsService()
+             ->CommitTentativeDeviceSettings(policy.Pass())) {
+      LOG(ERROR) << "Can't store policy";
+    }
   }
 
   // The owner key might have become available, allowing migration to happen.
@@ -518,6 +560,13 @@
     UpdateAndProceedStoring();
 }
 
+void DeviceSettingsProvider::OnTentativeChangesInPolicy(
+    const em::PolicyData& policy_data) {
+  em::ChromeDeviceSettingsProto device_settings;
+  CHECK(device_settings.ParseFromString(policy_data.policy_value()));
+  UpdateValuesCache(policy_data, device_settings, TEMPORARILY_UNTRUSTED);
+}
+
 void DeviceSettingsProvider::RetrieveCachedData() {
   em::PolicyData policy_data;
   if (!device_settings_cache::Retrieve(&policy_data,
@@ -529,261 +578,6 @@
   UpdateValuesCache(policy_data, device_settings_, trusted_status_);
 }
 
-void DeviceSettingsProvider::SetInPolicy() {
-  if (pending_changes_.empty()) {
-    NOTREACHED();
-    return;
-  }
-
-  if (RequestTrustedEntity() != TRUSTED) {
-    // Re-sync device settings before proceeding.
-    device_settings_service_->Load();
-    return;
-  }
-
-  std::string prop(pending_changes_.front().first);
-  scoped_ptr<base::Value> value(pending_changes_.front().second);
-  pending_changes_.pop_front();
-
-  trusted_status_ = TEMPORARILY_UNTRUSTED;
-  if (prop == kAccountsPrefAllowNewUser) {
-    em::AllowNewUsersProto* allow =
-        device_settings_.mutable_allow_new_users();
-    bool allow_value;
-    if (value->GetAsBoolean(&allow_value))
-      allow->set_allow_new_users(allow_value);
-    else
-      NOTREACHED();
-  } else if (prop == kAccountsPrefAllowGuest) {
-    em::GuestModeEnabledProto* guest =
-        device_settings_.mutable_guest_mode_enabled();
-    bool guest_value;
-    if (value->GetAsBoolean(&guest_value))
-      guest->set_guest_mode_enabled(guest_value);
-    else
-      NOTREACHED();
-  } else if (prop == kAccountsPrefSupervisedUsersEnabled) {
-    em::SupervisedUsersSettingsProto* supervised =
-        device_settings_.mutable_supervised_users_settings();
-    bool supervised_value;
-    if (value->GetAsBoolean(&supervised_value))
-      supervised->set_supervised_users_enabled(supervised_value);
-    else
-      NOTREACHED();
-  } else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
-    em::ShowUserNamesOnSigninProto* show =
-        device_settings_.mutable_show_user_names();
-    bool show_value;
-    if (value->GetAsBoolean(&show_value))
-      show->set_show_user_names(show_value);
-    else
-      NOTREACHED();
-  } else if (prop == kAccountsPrefDeviceLocalAccounts) {
-    em::DeviceLocalAccountsProto* device_local_accounts =
-        device_settings_.mutable_device_local_accounts();
-    device_local_accounts->clear_account();
-    const base::ListValue* accounts_list = NULL;
-    if (value->GetAsList(&accounts_list)) {
-      for (base::ListValue::const_iterator entry(accounts_list->begin());
-           entry != accounts_list->end(); ++entry) {
-        const base::DictionaryValue* entry_dict = NULL;
-        if ((*entry)->GetAsDictionary(&entry_dict)) {
-          em::DeviceLocalAccountInfoProto* account =
-              device_local_accounts->add_account();
-          std::string account_id;
-          if (entry_dict->GetStringWithoutPathExpansion(
-                  kAccountsPrefDeviceLocalAccountsKeyId, &account_id)) {
-            account->set_account_id(account_id);
-          }
-          int type;
-          if (entry_dict->GetIntegerWithoutPathExpansion(
-                  kAccountsPrefDeviceLocalAccountsKeyType, &type)) {
-            account->set_type(
-                static_cast<em::DeviceLocalAccountInfoProto::AccountType>(
-                    type));
-          }
-          std::string kiosk_app_id;
-          if (entry_dict->GetStringWithoutPathExpansion(
-                  kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
-                  &kiosk_app_id)) {
-            account->mutable_kiosk_app()->set_app_id(kiosk_app_id);
-          }
-        } else {
-          NOTREACHED();
-        }
-      }
-    } else {
-      NOTREACHED();
-    }
-  } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginId) {
-    em::DeviceLocalAccountsProto* device_local_accounts =
-        device_settings_.mutable_device_local_accounts();
-    std::string id;
-    if (value->GetAsString(&id))
-      device_local_accounts->set_auto_login_id(id);
-    else
-      NOTREACHED();
-  } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginDelay) {
-    em::DeviceLocalAccountsProto* device_local_accounts =
-        device_settings_.mutable_device_local_accounts();
-    int delay;
-    if (value->GetAsInteger(&delay))
-      device_local_accounts->set_auto_login_delay(delay);
-    else
-      NOTREACHED();
-  } else if (prop == kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled) {
-    em::DeviceLocalAccountsProto* device_local_accounts =
-        device_settings_.mutable_device_local_accounts();
-    bool enabled;
-    if (value->GetAsBoolean(&enabled))
-      device_local_accounts->set_enable_auto_login_bailout(enabled);
-    else
-      NOTREACHED();
-  } else if (prop ==
-             kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline) {
-    em::DeviceLocalAccountsProto* device_local_accounts =
-        device_settings_.mutable_device_local_accounts();
-    bool should_prompt;
-    if (value->GetAsBoolean(&should_prompt))
-      device_local_accounts->set_prompt_for_network_when_offline(should_prompt);
-    else
-      NOTREACHED();
-  } else if (prop == kSignedDataRoamingEnabled) {
-    em::DataRoamingEnabledProto* roam =
-        device_settings_.mutable_data_roaming_enabled();
-    bool roaming_value = false;
-    if (value->GetAsBoolean(&roaming_value))
-      roam->set_data_roaming_enabled(roaming_value);
-    else
-      NOTREACHED();
-  } else if (prop == kReleaseChannel) {
-    em::ReleaseChannelProto* release_channel =
-        device_settings_.mutable_release_channel();
-    std::string channel_value;
-    if (value->GetAsString(&channel_value))
-      release_channel->set_release_channel(channel_value);
-    else
-      NOTREACHED();
-  } else if (prop == kStatsReportingPref) {
-    em::MetricsEnabledProto* metrics =
-        device_settings_.mutable_metrics_enabled();
-    bool metrics_value = false;
-    if (value->GetAsBoolean(&metrics_value))
-      metrics->set_metrics_enabled(metrics_value);
-    else
-      NOTREACHED();
-    ApplyMetricsSetting(false, metrics_value);
-  } else if (prop == kAccountsPrefUsers) {
-    em::UserWhitelistProto* whitelist_proto =
-        device_settings_.mutable_user_whitelist();
-    whitelist_proto->clear_user_whitelist();
-    const base::ListValue* users;
-    if (value->GetAsList(&users)) {
-      for (base::ListValue::const_iterator i = users->begin();
-           i != users->end(); ++i) {
-        std::string email;
-        if ((*i)->GetAsString(&email))
-          whitelist_proto->add_user_whitelist(email);
-      }
-    }
-  } else if (prop == kAccountsPrefEphemeralUsersEnabled) {
-    em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
-        device_settings_.mutable_ephemeral_users_enabled();
-    bool ephemeral_users_enabled_value = false;
-    if (value->GetAsBoolean(&ephemeral_users_enabled_value)) {
-      ephemeral_users_enabled->set_ephemeral_users_enabled(
-          ephemeral_users_enabled_value);
-    } else {
-      NOTREACHED();
-    }
-  } else if (prop == kAllowRedeemChromeOsRegistrationOffers) {
-    em::AllowRedeemChromeOsRegistrationOffersProto* allow_redeem_offers =
-        device_settings_.mutable_allow_redeem_offers();
-    bool allow_redeem_offers_value;
-    if (value->GetAsBoolean(&allow_redeem_offers_value)) {
-      allow_redeem_offers->set_allow_redeem_offers(
-          allow_redeem_offers_value);
-    } else {
-      NOTREACHED();
-    }
-  } else if (prop == kStartUpFlags) {
-    em::StartUpFlagsProto* flags_proto =
-        device_settings_.mutable_start_up_flags();
-    flags_proto->Clear();
-    const base::ListValue* flags;
-    if (value->GetAsList(&flags)) {
-      for (base::ListValue::const_iterator i = flags->begin();
-           i != flags->end(); ++i) {
-        std::string flag;
-        if ((*i)->GetAsString(&flag))
-          flags_proto->add_flags(flag);
-      }
-    }
-  } else if (prop == kSystemUse24HourClock) {
-    em::SystemUse24HourClockProto* use_24hour_clock_proto =
-        device_settings_.mutable_use_24hour_clock();
-    use_24hour_clock_proto->Clear();
-    bool use_24hour_clock_value;
-    if (value->GetAsBoolean(&use_24hour_clock_value)) {
-      use_24hour_clock_proto->set_use_24hour_clock(use_24hour_clock_value);
-    } else {
-      NOTREACHED();
-    }
-  } else if (prop == kAttestationForContentProtectionEnabled) {
-    em::AttestationSettingsProto* attestation_settings =
-        device_settings_.mutable_attestation_settings();
-    bool setting_enabled;
-    if (value->GetAsBoolean(&setting_enabled)) {
-      attestation_settings->set_content_protection_enabled(setting_enabled);
-    } else {
-      NOTREACHED();
-    }
-  } else {
-    // The remaining settings don't support Set(), since they are not
-    // intended to be customizable by the user:
-    //   kAccountsPrefTransferSAMLCookies
-    //   kAppPack
-    //   kDeviceAttestationEnabled
-    //   kDeviceOwner
-    //   kIdleLogoutTimeout
-    //   kIdleLogoutWarningDuration
-    //   kReleaseChannelDelegated
-    //   kReportDeviceActivityTimes
-    //   kReportDeviceBootMode
-    //   kReportDeviceLocation
-    //   kReportDeviceVersionInfo
-    //   kReportDeviceNetworkInterfaces
-    //   kReportDeviceUsers
-    //   kScreenSaverExtensionId
-    //   kScreenSaverTimeout
-    //   kServiceAccountIdentity
-    //   kStartUpUrls
-    //   kSystemTimezonePolicy
-    //   kVariationsRestrictParameter
-
-    LOG(FATAL) << "Device setting " << prop << " is read-only.";
-  }
-
-  em::PolicyData data;
-  data.set_username(device_settings_service_->GetUsername());
-  CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
-
-  // Set the cache to the updated value.
-  UpdateValuesCache(data, device_settings_, trusted_status_);
-
-  if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) {
-    StoreDeviceSettings();
-  } else {
-    if (!device_settings_cache::Store(data, g_browser_process->local_state()))
-      LOG(ERROR) << "Couldn't store to the temp storage.";
-
-    // OnStorePolicyCompleted won't get called in this case so proceed with any
-    // pending operations immediately.
-    if (!pending_changes_.empty())
-      SetInPolicy();
-  }
-}
-
 void DeviceSettingsProvider::UpdateValuesCache(
     const em::PolicyData& policy_data,
     const em::ChromeDeviceSettingsProto& settings,
@@ -927,10 +721,6 @@
 void DeviceSettingsProvider::UpdateAndProceedStoring() {
   // Re-sync the cache from the service.
   UpdateFromService();
-
-  // Trigger the next change if necessary.
-  if (trusted_status_ == TRUSTED && !pending_changes_.empty())
-    SetInPolicy();
 }
 
 bool DeviceSettingsProvider::UpdateFromService() {
@@ -994,18 +784,6 @@
   return settings_loaded;
 }
 
-void DeviceSettingsProvider::StoreDeviceSettings() {
-  // Mute all previous callbacks to guarantee the |pending_changes_| queue is
-  // processed serially.
-  store_callback_factory_.InvalidateWeakPtrs();
-
-  device_settings_service_->SignAndStore(
-      scoped_ptr<em::ChromeDeviceSettingsProto>(
-          new em::ChromeDeviceSettingsProto(device_settings_)),
-      base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring,
-                 store_callback_factory_.GetWeakPtr()));
-}
-
 void DeviceSettingsProvider::AttemptMigration() {
   if (device_settings_service_->HasPrivateOwnerKey()) {
     PrefValueMap::const_iterator i;
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.h b/chrome/browser/chromeos/settings/device_settings_provider.h
index c8b952e..9ffeb6ff 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider.h
+++ b/chrome/browser/chromeos/settings/device_settings_provider.h
@@ -5,9 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_PROVIDER_H_
 #define CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_PROVIDER_H_
 
-#include <deque>
 #include <string>
-#include <utility>
 #include <vector>
 
 #include "base/basictypes.h"
@@ -18,6 +16,7 @@
 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chromeos/settings/cros_settings_provider.h"
+#include "components/ownership/owner_settings_service.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 
 namespace base {
@@ -31,8 +30,13 @@
 namespace chromeos {
 
 // CrosSettingsProvider implementation that works with device settings.
-class DeviceSettingsProvider : public CrosSettingsProvider,
-                               public DeviceSettingsService::Observer {
+//
+// Note that the write path is in the process of being migrated to
+// OwnerSettingsServiceChromeOS (crbug.com/230018).
+class DeviceSettingsProvider
+    : public CrosSettingsProvider,
+      public DeviceSettingsService::Observer,
+      public ownership::OwnerSettingsService::Observer {
  public:
   // The callback type that is called to get the device mode.
   typedef base::Callback<policy::DeviceMode(void)> GetDeviceModeCallback;
@@ -59,16 +63,15 @@
   virtual void OwnershipStatusChanged() override;
   virtual void DeviceSettingsUpdated() override;
 
+  // ownership::OwnerSettingsService::Observer implementation:
+  virtual void OnTentativeChangesInPolicy(
+      const enterprise_management::PolicyData& policy_data) override;
+
   // Populates in-memory cache from the local_state cache that is used to store
   // device settings before the device is owned and to speed up policy
   // availability before the policy blob is fetched on boot.
   void RetrieveCachedData();
 
-  // Stores a value from the |pending_changes_| queue in the device settings.
-  // If the device is not owned yet the data ends up only in the local_state
-  // cache and is serialized once ownership is acquired.
-  void SetInPolicy();
-
   // Parses the policy data and fills in |values_cache_|.
   void UpdateValuesCache(
       const enterprise_management::PolicyData& policy_data,
@@ -107,10 +110,6 @@
   // if new settings have been loaded.
   bool UpdateFromService();
 
-  // Sends |device_settings_| to |device_settings_service_| for signing and
-  // storage in session_manager.
-  void StoreDeviceSettings();
-
   // Checks the current ownership status to see whether the device owner is
   // logged in and writes the data accumulated in |migration_values_| to proper
   // device settings.
@@ -125,22 +124,19 @@
   TrustedStatus trusted_status_;
   DeviceSettingsService::OwnershipStatus ownership_status_;
 
-  // The device settings as currently reported through the CrosSettingsProvider
-  // interface. This may be different from the actual current device settings
-  // (which can be obtained from |device_settings_service_|) in case the device
-  // does not have an owner yet or there are pending changes that have not yet
-  // been written to session_manager.
+  // The device settings as currently reported through the
+  // CrosSettingsProvider interface. This may be different from the
+  // actual current device settings (which can be obtained from
+  // |device_settings_service_|) in case the device does not have an
+  // owner yet. As soon as ownership of the device will be taken,
+  // |device_settings_| will stored on disk and won't be used.
   enterprise_management::ChromeDeviceSettingsProto device_settings_;
 
   // A cache of values, indexed by the settings keys served through the
-  // CrosSettingsProvider interface. This is always kept in sync with the raw
-  // data found in |device_settings_|.
+  // CrosSettingsProvider interface. This is always kept in sync with the
+  // current device settings.
   PrefValueMap values_cache_;
 
-  // This is a queue for set requests, because those need to be sequential.
-  typedef std::pair<std::string, base::Value*> PendingQueueElement;
-  std::deque<PendingQueueElement> pending_changes_;
-
   // Weak pointer factory for creating store operation callbacks.
   base::WeakPtrFactory<DeviceSettingsProvider> store_callback_factory_;
 
diff --git a/chrome/browser/chromeos/settings/device_settings_service.cc b/chrome/browser/chromeos/settings/device_settings_service.cc
index 53b2a561..9c2669a 100644
--- a/chrome/browser/chromeos/settings/device_settings_service.cc
+++ b/chrome/browser/chromeos/settings/device_settings_service.cc
@@ -10,6 +10,7 @@
 #include "base/stl_util.h"
 #include "base/time/time.h"
 #include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
 #include "chrome/browser/chromeos/settings/session_manager_operation.h"
 #include "components/ownership/owner_key_util.h"
@@ -35,36 +36,6 @@
 // of retry time.
 int kMaxLoadRetries = (1000 * 60 * 10) / kLoadRetryDelayMs;
 
-// Assembles PolicyData based on |settings|, |policy_data| and
-// |user_id|.
-scoped_ptr<em::PolicyData> AssemblePolicy(
-    const std::string& user_id,
-    const em::PolicyData* policy_data,
-    const em::ChromeDeviceSettingsProto* settings) {
-  scoped_ptr<em::PolicyData> policy(new em::PolicyData());
-  if (policy_data) {
-    // Preserve management settings.
-    if (policy_data->has_management_mode())
-      policy->set_management_mode(policy_data->management_mode());
-    if (policy_data->has_request_token())
-      policy->set_request_token(policy_data->request_token());
-    if (policy_data->has_device_id())
-      policy->set_device_id(policy_data->device_id());
-  } else {
-    // If there's no previous policy data, this is the first time the device
-    // setting is set. We set the management mode to NOT_MANAGED initially.
-    policy->set_management_mode(em::PolicyData::NOT_MANAGED);
-  }
-  policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
-  policy->set_timestamp(
-      (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds());
-  policy->set_username(user_id);
-  if (!settings->SerializeToString(policy->mutable_policy_value()))
-    return scoped_ptr<em::PolicyData>();
-
-  return policy.Pass();
-}
-
 // Returns true if it is okay to transfer from the current mode to the new
 // mode. This function should be called in SetManagementMode().
 bool CheckManagementModeTransition(em::PolicyData::ManagementMode current_mode,
@@ -151,8 +122,6 @@
 }
 
 void DeviceSettingsService::UnsetSessionManager() {
-  STLDeleteContainerPointers(pending_operations_.begin(),
-                             pending_operations_.end());
   pending_operations_.clear();
 
   if (session_manager_client_)
@@ -172,18 +141,10 @@
 void DeviceSettingsService::SignAndStore(
     scoped_ptr<em::ChromeDeviceSettingsProto> new_settings,
     const base::Closure& callback) {
-  if (!owner_settings_service_) {
-    HandleError(STORE_KEY_UNAVAILABLE, callback);
-    return;
-  }
   scoped_ptr<em::PolicyData> policy =
-      AssemblePolicy(GetUsername(), policy_data(), new_settings.get());
-  if (!policy) {
-    HandleError(STORE_POLICY_ERROR, callback);
-    return;
-  }
-
-  owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback);
+      OwnerSettingsServiceChromeOS::AssemblePolicy(
+          GetUsername(), policy_data(), new_settings.get());
+  EnqueueSignAndStore(policy.Pass(), callback);
 }
 
 void DeviceSettingsService::SetManagementSettings(
@@ -208,7 +169,8 @@
   }
 
   scoped_ptr<em::PolicyData> policy =
-      AssemblePolicy(GetUsername(), policy_data(), device_settings());
+      OwnerSettingsServiceChromeOS::AssemblePolicy(
+          GetUsername(), policy_data(), device_settings());
   if (!policy) {
     HandleError(DeviceSettingsService::STORE_POLICY_ERROR, callback);
     return;
@@ -218,17 +180,16 @@
   policy->set_request_token(request_token);
   policy->set_device_id(device_id);
 
-  owner_settings_service_->SignAndStorePolicyAsync(policy.Pass(), callback);
+  EnqueueSignAndStore(policy.Pass(), callback);
 }
 
 void DeviceSettingsService::Store(scoped_ptr<em::PolicyFetchResponse> policy,
                                   const base::Closure& callback) {
-  Enqueue(
-      new StoreSettingsOperation(
-          base::Bind(&DeviceSettingsService::HandleCompletedOperation,
-                     weak_factory_.GetWeakPtr(),
-                     callback),
-          policy.Pass()));
+  Enqueue(linked_ptr<SessionManagerOperation>(new StoreSettingsOperation(
+      base::Bind(&DeviceSettingsService::HandleCompletedOperation,
+                 weak_factory_.GetWeakPtr(),
+                 callback),
+      policy.Pass())));
 }
 
 DeviceSettingsService::OwnershipStatus
@@ -276,6 +237,11 @@
   return username_;
 }
 
+ownership::OwnerSettingsService*
+DeviceSettingsService::GetOwnerSettingsService() const {
+  return owner_settings_service_.get();
+}
+
 void DeviceSettingsService::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
 }
@@ -303,24 +269,37 @@
   EnsureReload(false);
 }
 
-void DeviceSettingsService::Enqueue(SessionManagerOperation* operation) {
+void DeviceSettingsService::Enqueue(
+    const linked_ptr<SessionManagerOperation>& operation) {
   pending_operations_.push_back(operation);
-  if (pending_operations_.front() == operation)
+  if (pending_operations_.front().get() == operation.get())
     StartNextOperation();
 }
 
 void DeviceSettingsService::EnqueueLoad(bool force_key_load) {
-  SessionManagerOperation* operation =
-      new LoadSettingsOperation(
-          base::Bind(&DeviceSettingsService::HandleCompletedOperation,
-                     weak_factory_.GetWeakPtr(),
-                     base::Closure()));
+  linked_ptr<SessionManagerOperation> operation(new LoadSettingsOperation(
+      base::Bind(&DeviceSettingsService::HandleCompletedOperation,
+                 weak_factory_.GetWeakPtr(),
+                 base::Closure())));
   operation->set_force_key_load(force_key_load);
   operation->set_username(username_);
   operation->set_owner_settings_service(owner_settings_service_);
   Enqueue(operation);
 }
 
+void DeviceSettingsService::EnqueueSignAndStore(
+    scoped_ptr<enterprise_management::PolicyData> policy,
+    const base::Closure& callback) {
+  linked_ptr<SessionManagerOperation> operation(
+      new SignAndStoreSettingsOperation(
+          base::Bind(&DeviceSettingsService::HandleCompletedOperation,
+                     weak_factory_.GetWeakPtr(),
+                     callback),
+          policy.Pass()));
+  operation->set_owner_settings_service(owner_settings_service_);
+  Enqueue(operation);
+}
+
 void DeviceSettingsService::EnsureReload(bool force_key_load) {
   if (!pending_operations_.empty()) {
     pending_operations_.front()->set_username(username_);
@@ -333,8 +312,7 @@
 }
 
 void DeviceSettingsService::StartNextOperation() {
-  if (!pending_operations_.empty() &&
-      session_manager_client_ &&
+  if (!pending_operations_.empty() && session_manager_client_ &&
       owner_key_util_.get()) {
     pending_operations_.front()->Start(
         session_manager_client_, owner_key_util_, public_key_);
@@ -345,7 +323,7 @@
     const base::Closure& callback,
     SessionManagerOperation* operation,
     Status status) {
-  DCHECK_EQ(operation, pending_operations_.front());
+  DCHECK_EQ(operation, pending_operations_.front().get());
   store_status_ = status;
 
   OwnershipStatus ownership_status = OWNERSHIP_UNKNOWN;
@@ -412,7 +390,6 @@
   // Only remove the pending operation here, so new operations triggered by any
   // of the callbacks above are queued up properly.
   pending_operations_.pop_front();
-  delete operation;
 
   StartNextOperation();
 }
@@ -431,11 +408,6 @@
     callback.Run();
 }
 
-void DeviceSettingsService::OnSignAndStoreOperationCompleted(Status status) {
-  store_status_ = status;
-  FOR_EACH_OBSERVER(Observer, observers_, DeviceSettingsUpdated());
-}
-
 ScopedTestDeviceSettingsService::ScopedTestDeviceSettingsService() {
   DeviceSettingsService::Initialize();
 }
diff --git a/chrome/browser/chromeos/settings/device_settings_service.h b/chrome/browser/chromeos/settings/device_settings_service.h
index 6f2ebdf8..ef24d19 100644
--- a/chrome/browser/chromeos/settings/device_settings_service.h
+++ b/chrome/browser/chromeos/settings/device_settings_service.h
@@ -12,6 +12,7 @@
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/memory/linked_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/observer_list.h"
@@ -138,6 +139,9 @@
       const base::Closure& callback);
 
   // Sets the management related settings in PolicyData.
+  //
+  // TODO (ygorshenin@, crbug.com/230018): move this to the
+  // OwnerSettingsService.
   void SetManagementSettings(
       enterprise_management::PolicyData::ManagementMode management_mode,
       const std::string& request_token,
@@ -169,6 +173,8 @@
 
   const std::string& GetUsername() const;
 
+  ownership::OwnerSettingsService* GetOwnerSettingsService() const;
+
   // Adds an observer.
   void AddObserver(Observer* observer);
   // Removes an observer.
@@ -183,11 +189,15 @@
 
   // Enqueues a new operation. Takes ownership of |operation| and starts it
   // right away if there is no active operation currently.
-  void Enqueue(SessionManagerOperation* operation);
+  void Enqueue(const linked_ptr<SessionManagerOperation>& operation);
 
   // Enqueues a load operation.
   void EnqueueLoad(bool force_key_load);
 
+  // Enqueues a sign and store operation.
+  void EnqueueSignAndStore(scoped_ptr<enterprise_management::PolicyData> policy,
+                           const base::Closure& callback);
+
   // Makes sure there's a reload operation so changes to the settings (and key,
   // in case force_key_load is set) are getting picked up.
   void EnsureReload(bool force_key_load);
@@ -204,19 +214,6 @@
   // Updates status and invokes the callback immediately.
   void HandleError(Status status, const base::Closure& callback);
 
-  // Called by OwnerSettingsService when sign-and-store operation completes.
-  void OnSignAndStoreOperationCompleted(Status status);
-
-  void set_policy_data(
-      scoped_ptr<enterprise_management::PolicyData> policy_data) {
-    policy_data_ = policy_data.Pass();
-  }
-
-  void set_device_settings(scoped_ptr<
-      enterprise_management::ChromeDeviceSettingsProto> device_settings) {
-    device_settings_ = device_settings.Pass();
-  }
-
   SessionManagerClient* session_manager_client_;
   scoped_refptr<ownership::OwnerKeyUtil> owner_key_util_;
 
@@ -233,9 +230,9 @@
 
   // The queue of pending operations. The first operation on the queue is
   // currently active; it gets removed and destroyed once it completes.
-  std::deque<SessionManagerOperation*> pending_operations_;
+  std::deque<linked_ptr<SessionManagerOperation>> pending_operations_;
 
-  ObserverList<Observer, true> observers_;
+  ObserverList<Observer> observers_;
 
   // For recoverable load errors how many retries are left before we give up.
   int load_retries_left_;
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.cc b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
index 24e5886..fed7034 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.cc
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.cc
@@ -197,6 +197,8 @@
     : user_manager_(new FakeUserManager()),
       user_manager_enabler_(user_manager_),
       owner_key_util_(new ownership::MockOwnerKeyUtil()) {
+  OwnerSettingsServiceChromeOSFactory::SetDeviceSettingsServiceForTesting(
+      &device_settings_service_);
   OwnerSettingsServiceChromeOSFactory::GetInstance()->SetOwnerKeyUtilForTesting(
       owner_key_util_);
 }
@@ -218,13 +220,11 @@
   device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
   device_settings_service_.SetSessionManager(&device_settings_test_helper_,
                                              owner_key_util_);
-  OwnerSettingsServiceChromeOS::SetDeviceSettingsServiceForTesting(
-      &device_settings_service_);
   profile_.reset(new TestingProfile());
 }
 
 void DeviceSettingsTestBase::TearDown() {
-  OwnerSettingsServiceChromeOS::SetDeviceSettingsServiceForTesting(NULL);
+  OwnerSettingsServiceChromeOSFactory::SetDeviceSettingsServiceForTesting(NULL);
   FlushDeviceSettings();
   device_settings_service_.UnsetSessionManager();
   DBusThreadManager::Shutdown();
diff --git a/chrome/browser/chromeos/settings/device_settings_test_helper.h b/chrome/browser/chromeos/settings/device_settings_test_helper.h
index cac6fc9..8100563 100644
--- a/chrome/browser/chromeos/settings/device_settings_test_helper.h
+++ b/chrome/browser/chromeos/settings/device_settings_test_helper.h
@@ -185,11 +185,11 @@
   // tested classes depend on implicitly.
   FakeUserManager* user_manager_;
   ScopedUserManagerEnabler user_manager_enabler_;
-  scoped_ptr<TestingProfile> profile_;
   scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_;
   // Local DeviceSettingsService instance for tests. Avoid using in combination
   // with the global instance (DeviceSettingsService::Get()).
   DeviceSettingsService device_settings_service_;
+  scoped_ptr<TestingProfile> profile_;
 
   scoped_ptr<DBusThreadManagerSetter> dbus_setter_;
 
diff --git a/chrome/browser/chromeos/settings/session_manager_operation.cc b/chrome/browser/chromeos/settings/session_manager_operation.cc
index 8947c37..6a7ed980 100644
--- a/chrome/browser/chromeos/settings/session_manager_operation.cc
+++ b/chrome/browser/chromeos/settings/session_manager_operation.cc
@@ -245,12 +245,15 @@
     : SessionManagerOperation(callback),
       new_policy_(new_policy.Pass()),
       weak_factory_(this) {
-  DCHECK(new_policy_);
 }
 
 SignAndStoreSettingsOperation::~SignAndStoreSettingsOperation() {}
 
 void SignAndStoreSettingsOperation::Run() {
+  if (!new_policy_) {
+    ReportResult(DeviceSettingsService::STORE_POLICY_ERROR);
+    return;
+  }
   if (!owner_settings_service_) {
     ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
     return;
@@ -269,7 +272,7 @@
   bool rv = owner_settings_service_->AssembleAndSignPolicyAsync(
       content::BrowserThread::GetBlockingPool(),
       new_policy_.Pass(),
-      base::Bind(&SignAndStoreSettingsOperation::StoreDeviceSettingsBlob,
+      base::Bind(&SignAndStoreSettingsOperation::StoreDeviceSettings,
                  weak_factory_.GetWeakPtr()));
   if (!rv) {
     ReportResult(DeviceSettingsService::STORE_KEY_UNAVAILABLE);
@@ -277,15 +280,15 @@
   }
 }
 
-void SignAndStoreSettingsOperation::StoreDeviceSettingsBlob(
-    std::string device_settings_blob) {
-  if (device_settings_blob.empty()) {
+void SignAndStoreSettingsOperation::StoreDeviceSettings(
+    scoped_ptr<em::PolicyFetchResponse> policy_response) {
+  if (!policy_response.get()) {
     ReportResult(DeviceSettingsService::STORE_POLICY_ERROR);
     return;
   }
 
   session_manager_client()->StoreDevicePolicy(
-      device_settings_blob,
+      policy_response->SerializeAsString(),
       base::Bind(&SignAndStoreSettingsOperation::HandleStoreResult,
                  weak_factory_.GetWeakPtr()));
 }
diff --git a/chrome/browser/chromeos/settings/session_manager_operation.h b/chrome/browser/chromeos/settings/session_manager_operation.h
index 03aaf80..356025e 100644
--- a/chrome/browser/chromeos/settings/session_manager_operation.h
+++ b/chrome/browser/chromeos/settings/session_manager_operation.h
@@ -189,7 +189,8 @@
   void StartSigning(bool has_private_key);
 
   // Stores the signed device settings blob.
-  void StoreDeviceSettingsBlob(std::string device_settings_blob);
+  void StoreDeviceSettings(
+      scoped_ptr<enterprise_management::PolicyFetchResponse> policy_response);
 
   // Handles the result of the store operation and triggers the load.
   void HandleStoreResult(bool success);
diff --git a/chrome/browser/content_settings/content_settings_default_provider.cc b/chrome/browser/content_settings/content_settings_default_provider.cc
index d615b77..4dc313df 100644
--- a/chrome/browser/content_settings/content_settings_default_provider.cc
+++ b/chrome/browser/content_settings/content_settings_default_provider.cc
@@ -20,11 +20,8 @@
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/browser/browser_thread.h"
 #include "url/gurl.h"
 
-using content::BrowserThread;
-
 namespace {
 
 // The default setting for each content type.
@@ -185,7 +182,7 @@
     ContentSettingsType content_type,
     const ResourceIdentifier& resource_identifier,
     base::Value* in_value) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
   DCHECK(prefs_);
 
   // Ignore non default settings
@@ -264,7 +261,7 @@
 }
 
 void DefaultProvider::ShutdownOnUIThread() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
   DCHECK(prefs_);
   RemoveAllObservers();
   pref_change_registrar_.RemoveAll();
@@ -272,7 +269,7 @@
 }
 
 void DefaultProvider::OnPreferenceChanged(const std::string& name) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
   if (updating_preferences_)
     return;
 
diff --git a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc
index c0a2f63c..0572fa6 100644
--- a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc
@@ -11,26 +11,21 @@
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
-#include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
 using ::testing::_;
-using content::BrowserThread;
 
 class DefaultProviderTest : public testing::Test {
  public:
   DefaultProviderTest()
-      : ui_thread_(BrowserThread::UI, &message_loop_),
-        provider_(profile_.GetPrefs(), false) {
+      : provider_(profile_.GetPrefs(), false) {
   }
   virtual ~DefaultProviderTest() {
     provider_.ShutdownOnUIThread();
   }
 
  protected:
-  base::MessageLoop message_loop_;
-  content::TestBrowserThread ui_thread_;
   TestingProfile profile_;
   content_settings::DefaultProvider provider_;
 };
diff --git a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
index 6e65b80..ab4f54d1 100644
--- a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
+++ b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
@@ -10,7 +10,6 @@
 #include "components/content_settings/core/browser/content_settings_rule.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
-#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "extensions/browser/extension_host.h"
@@ -155,7 +154,7 @@
 }
 
 void InternalExtensionProvider::ShutdownOnUIThread() {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
   RemoveAllObservers();
   registrar_.reset();
 }
diff --git a/chrome/browser/content_settings/content_settings_override_provider.cc b/chrome/browser/content_settings/content_settings_override_provider.cc
index d068285..659096a4 100644
--- a/chrome/browser/content_settings/content_settings_override_provider.cc
+++ b/chrome/browser/content_settings/content_settings_override_provider.cc
@@ -16,9 +16,6 @@
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/browser/browser_thread.h"
-
-using content::BrowserThread;
 
 namespace content_settings {
 
@@ -94,7 +91,7 @@
 
 void OverrideProvider::SetOverrideSetting(ContentSettingsType content_type,
                                           bool enabled) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(prefs_);
 
   // Disallow incognito to change the state.
@@ -120,7 +117,6 @@
 }
 
 void OverrideProvider::ReadOverrideSettings() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   const base::DictionaryValue* blocked_settings_dictionary =
       prefs_->GetDictionary(prefs::kOverrideContentSettings);
 
diff --git a/chrome/browser/content_settings/content_settings_override_provider.h b/chrome/browser/content_settings/content_settings_override_provider.h
index 98ddbe27..9fd6598 100644
--- a/chrome/browser/content_settings/content_settings_override_provider.h
+++ b/chrome/browser/content_settings/content_settings_override_provider.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
 #include "components/content_settings/core/browser/content_settings_provider.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 
@@ -68,6 +69,8 @@
   // guarantee thread safety.
   mutable base::Lock lock_;
 
+  base::ThreadChecker thread_checker_;
+
   DISALLOW_COPY_AND_ASSIGN(OverrideProvider);
 };
 
diff --git a/chrome/browser/content_settings/content_settings_policy_provider.cc b/chrome/browser/content_settings/content_settings_policy_provider.cc
index 27ab259..9beba38 100644
--- a/chrome/browser/content_settings/content_settings_policy_provider.cc
+++ b/chrome/browser/content_settings/content_settings_policy_provider.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <vector>
 
+#include "base/bind.h"
 #include "base/json/json_reader.h"
 #include "base/prefs/pref_service.h"
 #include "base/values.h"
@@ -15,9 +16,6 @@
 #include "components/content_settings/core/browser/content_settings_rule.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/browser/browser_thread.h"
-
-using content::BrowserThread;
 
 namespace {
 
@@ -443,7 +441,7 @@
 }
 
 void PolicyProvider::ShutdownOnUIThread() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
   RemoveAllObservers();
   if (!prefs_)
     return;
@@ -452,7 +450,7 @@
 }
 
 void PolicyProvider::OnPreferenceChanged(const std::string& name) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
 
   if (name == prefs::kManagedDefaultCookiesSetting) {
     UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES);
diff --git a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc
index 0497b0c..5533af6 100644
--- a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc
@@ -19,33 +19,16 @@
 #include "chrome/test/base/testing_pref_service_syncable.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/browser/content_settings_rule.h"
-#include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
 using ::testing::_;
-using content::BrowserThread;
 
 namespace content_settings {
 
 typedef std::vector<Rule> Rules;
 
-class PolicyProviderTest : public testing::Test {
- public:
-  PolicyProviderTest()
-      : ui_thread_(BrowserThread::UI, &message_loop_) {
-  }
-
- protected:
-  // TODO(markusheintz): Check if it's possible to derive the provider class
-  // from NonThreadSafe and to use native thread identifiers instead of
-  // BrowserThread IDs. Then we could get rid of the message_loop and ui_thread
-  // fields.
-  base::MessageLoop message_loop_;
-  content::TestBrowserThread ui_thread_;
-};
-
-TEST_F(PolicyProviderTest, DefaultGeolocationContentSetting) {
+TEST(PolicyProviderTest, DefaultGeolocationContentSetting) {
   TestingProfile profile;
   TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
   PolicyProvider provider(prefs);
@@ -79,7 +62,7 @@
   provider.ShutdownOnUIThread();
 }
 
-TEST_F(PolicyProviderTest, ManagedDefaultContentSettings) {
+TEST(PolicyProviderTest, ManagedDefaultContentSettings) {
   TestingProfile profile;
   TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
   PolicyProvider provider(prefs);
@@ -106,7 +89,7 @@
 // When a default-content-setting is set to a managed setting a
 // CONTENT_SETTINGS_CHANGED notification should be fired. The same should happen
 // if the managed setting is removed.
-TEST_F(PolicyProviderTest, ObserveManagedSettingsChange) {
+TEST(PolicyProviderTest, ObserveManagedSettingsChange) {
   TestingProfile profile;
   TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
   PolicyProvider provider(prefs);
@@ -133,7 +116,7 @@
   provider.ShutdownOnUIThread();
 }
 
-TEST_F(PolicyProviderTest, GettingManagedContentSettings) {
+TEST(PolicyProviderTest, GettingManagedContentSettings) {
   TestingProfile profile;
   TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
 
@@ -205,7 +188,7 @@
   provider.ShutdownOnUIThread();
 }
 
-TEST_F(PolicyProviderTest, ResourceIdentifier) {
+TEST(PolicyProviderTest, ResourceIdentifier) {
   TestingProfile profile;
   TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
 
@@ -242,7 +225,7 @@
   provider.ShutdownOnUIThread();
 }
 
-TEST_F(PolicyProviderTest, AutoSelectCertificateList) {
+TEST(PolicyProviderTest, AutoSelectCertificateList) {
   TestingProfile profile;
   TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
 
diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc
index 09469670..afcf4ab 100644
--- a/chrome/browser/content_settings/content_settings_pref_provider.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/auto_reset.h"
+#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram.h"
@@ -19,17 +20,13 @@
 #include "base/time/default_clock.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/content_settings/core/browser/content_settings_rule.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/browser/browser_thread.h"
 #include "url/gurl.h"
 
-using content::BrowserThread;
-
 namespace {
 
 typedef std::pair<std::string, std::string> StringPair;
@@ -124,7 +121,7 @@
     ContentSettingsType content_type,
     const ResourceIdentifier& resource_identifier,
     base::Value* in_value) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
   DCHECK(prefs_);
   // Default settings are set using a wildcard pattern for both
   // |primary_pattern| and |secondary_pattern|. Don't store default settings in
@@ -178,7 +175,7 @@
 
 void PrefProvider::ClearAllContentSettingsRules(
     ContentSettingsType content_type) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
   DCHECK(prefs_);
 
   OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
@@ -489,7 +486,7 @@
 }
 
 void PrefProvider::OnContentSettingsPatternPairsChanged() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
 
   if (updating_preferences_)
     return;
@@ -559,7 +556,7 @@
 }
 
 void PrefProvider::ShutdownOnUIThread() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(CalledOnValidThread());
   DCHECK(prefs_);
   RemoveAllObservers();
   pref_change_registrar_.RemoveAll();
diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
index 5daa947..682f0f7 100644
--- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -28,12 +28,10 @@
 #include "chrome/test/base/testing_pref_service_syncable.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/test/test_browser_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
 using ::testing::_;
-using content::BrowserThread;
 
 namespace content_settings {
 
@@ -92,18 +90,7 @@
   DISALLOW_COPY_AND_ASSIGN(DeadlockCheckerObserver);
 };
 
-class PrefProviderTest : public testing::Test {
- public:
-  PrefProviderTest() : ui_thread_(
-      BrowserThread::UI, &message_loop_) {
-  }
-
- protected:
-  base::MessageLoop message_loop_;
-  content::TestBrowserThread ui_thread_;
-};
-
-TEST_F(PrefProviderTest, Observer) {
+TEST(PrefProviderTest, Observer) {
   TestingProfile profile;
   PrefProvider pref_content_settings_provider(profile.GetPrefs(), false);
 
@@ -130,7 +117,7 @@
 
 // Test for regression in which the PrefProvider modified the user pref store
 // of the OTR unintentionally: http://crbug.com/74466.
-TEST_F(PrefProviderTest, Incognito) {
+TEST(PrefProviderTest, Incognito) {
   PersistentPrefStore* user_prefs = new TestingPrefStore();
   OverlayUserPrefStore* otr_user_prefs =
       new OverlayUserPrefStore(user_prefs);
@@ -197,7 +184,7 @@
   pref_content_settings_provider_incognito.ShutdownOnUIThread();
 }
 
-TEST_F(PrefProviderTest, GetContentSettingsValue) {
+TEST(PrefProviderTest, GetContentSettingsValue) {
   TestingProfile testing_profile;
   PrefProvider provider(testing_profile.GetPrefs(), false);
 
@@ -259,7 +246,7 @@
   provider.ShutdownOnUIThread();
 }
 
-TEST_F(PrefProviderTest, Patterns) {
+TEST(PrefProviderTest, Patterns) {
   TestingProfile testing_profile;
   PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
                                               false);
@@ -348,7 +335,7 @@
   pref_content_settings_provider.ShutdownOnUIThread();
 }
 
-TEST_F(PrefProviderTest, ResourceIdentifier) {
+TEST(PrefProviderTest, ResourceIdentifier) {
   TestingProfile testing_profile;
   PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
                                               false);
@@ -384,7 +371,7 @@
   pref_content_settings_provider.ShutdownOnUIThread();
 }
 
-TEST_F(PrefProviderTest, AutoSubmitCertificateContentSetting) {
+TEST(PrefProviderTest, AutoSubmitCertificateContentSetting) {
   TestingProfile profile;
   TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
   GURL primary_url("https://www.example.com");
@@ -418,7 +405,7 @@
 }
 
 // http://crosbug.com/17760
-TEST_F(PrefProviderTest, Deadlock) {
+TEST(PrefProviderTest, Deadlock) {
   TestingPrefServiceSyncable prefs;
   PrefProvider::RegisterProfilePrefs(prefs.registry());
 
@@ -441,7 +428,7 @@
   provider.ShutdownOnUIThread();
 }
 
-TEST_F(PrefProviderTest, LastUsage) {
+TEST(PrefProviderTest, LastUsage) {
   TestingProfile testing_profile;
   PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
                                               false);
diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc
index d0bb869c..31ac0a5 100644
--- a/chrome/browser/content_settings/host_content_settings_map.cc
+++ b/chrome/browser/content_settings/host_content_settings_map.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/content_settings/content_settings_policy_provider.h"
 #include "chrome/browser/content_settings/content_settings_pref_provider.h"
 #include "chrome/browser/content_settings/content_settings_utils.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "components/content_settings/core/browser/content_settings_details.h"
@@ -26,7 +25,6 @@
 #include "components/content_settings/core/browser/content_settings_rule.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/pref_registry/pref_registry_syncable.h"
-#include "content/public/browser/browser_thread.h"
 #include "net/base/net_errors.h"
 #include "net/base/static_cookie_policy.h"
 #include "url/gurl.h"
@@ -35,8 +33,6 @@
 #include "extensions/common/constants.h"
 #endif
 
-using content::BrowserThread;
-
 namespace {
 
 typedef std::vector<content_settings::Rule> Rules;
@@ -98,11 +94,6 @@
 
   content_settings_providers_[OVERRIDE_PROVIDER] =
       new content_settings::OverrideProvider(prefs_, is_off_the_record_);
-
-  if (!is_off_the_record_) {
-    // Migrate obsolete preferences.
-    MigrateObsoleteClearOnExitPref();
-  }
 }
 
 // static
@@ -112,10 +103,6 @@
       prefs::kContentSettingsWindowLastTabIndex,
       0,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
-  registry->RegisterBooleanPref(
-      prefs::kContentSettingsClearOnExitMigrated,
-      false,
-      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
 
   // Register the prefs for the content settings providers.
   content_settings::DefaultProvider::RegisterProfilePrefs(registry);
@@ -327,7 +314,7 @@
     const GURL& secondary_url,
     ContentSettingsType content_type,
     const std::string& resource_identifier) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(thread_checker_.CalledOnValidThread());
 
   ContentSetting setting = GetContentSetting(
       primary_url, secondary_url, content_type, resource_identifier);
@@ -576,7 +563,7 @@
 }
 
 void HostContentSettingsMap::ShutdownOnUIThread() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(prefs_);
   prefs_ = NULL;
   for (ProviderIterator it = content_settings_providers_.begin();
@@ -586,55 +573,6 @@
   }
 }
 
-void HostContentSettingsMap::MigrateObsoleteClearOnExitPref() {
-  // Don't migrate more than once.
-  if (prefs_->HasPrefPath(prefs::kContentSettingsClearOnExitMigrated) &&
-      prefs_->GetBoolean(prefs::kContentSettingsClearOnExitMigrated)) {
-    return;
-  }
-
-  if (!prefs_->GetBoolean(prefs::kClearSiteDataOnExit)) {
-    // Nothing to be done
-    prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true);
-    return;
-  }
-
-  // Change the default cookie settings:
-  //  old              new
-  //  ---------------- ----------------
-  //  ALLOW            SESSION_ONLY
-  //  SESSION_ONLY     SESSION_ONLY
-  //  BLOCK            BLOCK
-  ContentSetting default_setting = GetDefaultContentSettingFromProvider(
-      CONTENT_SETTINGS_TYPE_COOKIES,
-      content_settings_providers_[DEFAULT_PROVIDER]);
-  if (default_setting == CONTENT_SETTING_ALLOW) {
-    SetDefaultContentSetting(
-        CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_SESSION_ONLY);
-  }
-
-  // Change the exceptions using the same rules.
-  ContentSettingsForOneType exceptions;
-  AddSettingsForOneType(content_settings_providers_[PREF_PROVIDER],
-                        PREF_PROVIDER,
-                        CONTENT_SETTINGS_TYPE_COOKIES,
-                        std::string(),
-                        &exceptions,
-                        false);
-  for (ContentSettingsForOneType::iterator it = exceptions.begin();
-       it != exceptions.end(); ++it) {
-    if (it->setting != CONTENT_SETTING_ALLOW)
-      continue;
-    SetWebsiteSetting(it->primary_pattern,
-                      it->secondary_pattern,
-                      CONTENT_SETTINGS_TYPE_COOKIES,
-                      std::string(),
-                      new base::FundamentalValue(CONTENT_SETTING_SESSION_ONLY));
-  }
-
-  prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true);
-}
-
 void HostContentSettingsMap::AddSettingsForOneType(
     const content_settings::ProviderInterface* provider,
     ProviderType provider_type,
diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h
index efd3f99..f60fd6a 100644
--- a/chrome/browser/content_settings/host_content_settings_map.h
+++ b/chrome/browser/content_settings/host_content_settings_map.h
@@ -17,6 +17,7 @@
 #include "base/observer_list.h"
 #include "base/prefs/pref_change_registrar.h"
 #include "base/threading/platform_thread.h"
+#include "base/threading/thread_checker.h"
 #include "base/tuple.h"
 #include "chrome/browser/content_settings/content_settings_override_provider.h"
 #include "components/content_settings/core/browser/content_settings_observer.h"
@@ -61,6 +62,8 @@
     NUM_PROVIDER_TYPES,
   };
 
+  // This should be called on the UI thread, otherwise |thread_checker_| handles
+  // CalledOnValidThread() wrongly.
   HostContentSettingsMap(PrefService* prefs, bool incognito);
 
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
@@ -298,9 +301,6 @@
       ContentSettingsType content_type,
       content_settings::ProviderInterface* provider) const;
 
-  // Migrate the Clear on exit pref into equivalent content settings.
-  void MigrateObsoleteClearOnExitPref();
-
   // Adds content settings for |content_type| and |resource_identifier|,
   // provided by |provider|, into |settings|. If |incognito| is true, adds only
   // the content settings which are applicable to the incognito mode and differ
@@ -353,6 +353,8 @@
   // before any other uses of it.
   ProviderMap content_settings_providers_;
 
+  base::ThreadChecker thread_checker_;
+
   ObserverList<content_settings::Observer> observers_;
 
   DISALLOW_COPY_AND_ASSIGN(HostContentSettingsMap);
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
index e0e65d3..9be6879 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/content_settings/cookie_settings.h"
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/content_settings/mock_settings_observer.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
@@ -948,47 +947,6 @@
                    extension, http_host, CONTENT_SETTINGS_TYPE_COOKIES));
 }
 
-TEST_F(HostContentSettingsMapTest, MigrateClearOnExit) {
-  TestingProfile profile;
-  TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
-
-  prefs->SetBoolean(prefs::kClearSiteDataOnExit, true);
-
-  scoped_ptr<base::Value> patterns(base::JSONReader::Read(
-      "{\"[*.]example.com,*\":{\"cookies\": 1},"
-      " \"[*.]other.com,*\":{\"cookies\": 2},"
-      " \"[*.]third.com,*\":{\"cookies\": 4}}"));
-  profile.GetPrefs()->Set(prefs::kContentSettingsPatternPairs, *patterns);
-
-  scoped_ptr<base::Value> defaults(base::JSONReader::Read("{\"cookies\": 1}"));
-  profile.GetPrefs()->Set(prefs::kDefaultContentSettings, *defaults);
-
-  HostContentSettingsMap* host_content_settings_map =
-      profile.GetHostContentSettingsMap();
-
-  EXPECT_EQ(CONTENT_SETTING_SESSION_ONLY,
-            host_content_settings_map->GetDefaultContentSetting(
-                CONTENT_SETTINGS_TYPE_COOKIES, NULL));
-  EXPECT_EQ(CONTENT_SETTING_SESSION_ONLY,
-            host_content_settings_map->GetContentSetting(
-                GURL("http://example.com"),
-                GURL("http://example.com"),
-                CONTENT_SETTINGS_TYPE_COOKIES,
-                std::string()));
-  EXPECT_EQ(CONTENT_SETTING_BLOCK,
-            host_content_settings_map->GetContentSetting(
-                GURL("http://other.com"),
-                GURL("http://other.com"),
-                CONTENT_SETTINGS_TYPE_COOKIES,
-                std::string()));
-  EXPECT_EQ(CONTENT_SETTING_SESSION_ONLY,
-            host_content_settings_map->GetContentSetting(
-                GURL("http://third.com"),
-                GURL("http://third.com"),
-                CONTENT_SETTINGS_TYPE_COOKIES,
-                std::string()));
-}
-
 TEST_F(HostContentSettingsMapTest, AddContentSettingsObserver) {
   TestingProfile profile;
   HostContentSettingsMap* host_content_settings_map =
diff --git a/chrome/browser/copresence/chrome_whispernet_client.cc b/chrome/browser/copresence/chrome_whispernet_client.cc
index 6cffe03..35b22f7 100644
--- a/chrome/browser/copresence/chrome_whispernet_client.cc
+++ b/chrome/browser/copresence/chrome_whispernet_client.cc
@@ -63,7 +63,7 @@
 
 // Fire an event to request a token encode.
 void ChromeWhispernetClient::EncodeToken(const std::string& token,
-                                         bool audible) {
+                                         copresence::AudioType type) {
   DCHECK(extension_loaded_);
   DCHECK(browser_context_);
   DCHECK(extensions::EventRouter::Get(browser_context_));
@@ -71,7 +71,7 @@
   scoped_ptr<extensions::Event> event(new extensions::Event(
       extensions::api::copresence_private::OnEncodeTokenRequest::kEventName,
       extensions::api::copresence_private::OnEncodeTokenRequest::Create(
-          token, audible),
+          token, type == copresence::AUDIBLE),
       browser_context_));
 
   extensions::EventRouter::Get(browser_context_)
@@ -79,15 +79,22 @@
 }
 
 // Fire an event to request a decode for the given samples.
-void ChromeWhispernetClient::DecodeSamples(const std::string& samples) {
+void ChromeWhispernetClient::DecodeSamples(copresence::AudioType type,
+                                           const std::string& samples) {
   DCHECK(extension_loaded_);
   DCHECK(browser_context_);
   DCHECK(extensions::EventRouter::Get(browser_context_));
 
+  extensions::api::copresence_private::DecodeSamplesParameters request_type;
+  request_type.decode_audible =
+      type == copresence::AUDIBLE || type == copresence::BOTH;
+  request_type.decode_inaudible =
+      type == copresence::INAUDIBLE || type == copresence::BOTH;
+
   scoped_ptr<extensions::Event> event(new extensions::Event(
       extensions::api::copresence_private::OnDecodeSamplesRequest::kEventName,
       extensions::api::copresence_private::OnDecodeSamplesRequest::Create(
-          samples),
+          samples, request_type),
       browser_context_));
 
   extensions::EventRouter::Get(browser_context_)
diff --git a/chrome/browser/copresence/chrome_whispernet_client.h b/chrome/browser/copresence/chrome_whispernet_client.h
index 3cdcf4b..ab86274 100644
--- a/chrome/browser/copresence/chrome_whispernet_client.h
+++ b/chrome/browser/copresence/chrome_whispernet_client.h
@@ -10,6 +10,7 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
+#include "components/copresence/public/copresence_constants.h"
 #include "components/copresence/public/whispernet_client.h"
 
 namespace content {
@@ -30,7 +31,7 @@
 
 // This class is responsible for communication with our ledger_proxy extension
 // that talks to the whispernet audio library.
-class ChromeWhispernetClient : public copresence::WhispernetClient {
+class ChromeWhispernetClient final : public copresence::WhispernetClient {
  public:
   // The browser context needs to outlive this class.
   explicit ChromeWhispernetClient(content::BrowserContext* browser_context);
@@ -40,8 +41,10 @@
   void Initialize(const SuccessCallback& init_callback) override;
   void Shutdown() override;
 
-  void EncodeToken(const std::string& token, bool audible) override;
-  void DecodeSamples(const std::string& samples) override;
+  void EncodeToken(const std::string& token,
+                   copresence::AudioType type) override;
+  void DecodeSamples(copresence::AudioType type,
+                     const std::string& samples) override;
   void DetectBroadcast() override;
 
   void RegisterTokensCallback(const TokensCallback& tokens_callback) override;
diff --git a/chrome/browser/copresence/chrome_whispernet_client_browsertest.cc b/chrome/browser/copresence/chrome_whispernet_client_browsertest.cc
index 43e75dd..0384bb5 100644
--- a/chrome/browser/copresence/chrome_whispernet_client_browsertest.cc
+++ b/chrome/browser/copresence/chrome_whispernet_client_browsertest.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "components/copresence/public/copresence_constants.h"
 #include "media/base/audio_bus.h"
 
 namespace {
@@ -73,7 +74,8 @@
     expected_token_ = kSixZeros;
     expected_audible_ = audible;
 
-    client->EncodeToken(kSixZeros, audible);
+    client->EncodeToken(kSixZeros,
+                        audible ? copresence::AUDIBLE : copresence::INAUDIBLE);
     run_loop_->Run();
 
     EXPECT_GT(saved_samples_->frames(), 0);
@@ -102,7 +104,9 @@
            saved_samples_->channel(0),
            sizeof(float) * saved_samples_->frames());
 
-    client->DecodeSamples(AudioBusToString(samples_bus));
+    client->DecodeSamples(
+        expect_audible ? copresence::AUDIBLE : copresence::INAUDIBLE,
+        AudioBusToString(samples_bus));
     run_loop_->Run();
   }
 
@@ -128,10 +132,10 @@
 
   void SamplesCallback(
       const std::string& token,
-      bool audible,
+      copresence::AudioType type,
       const scoped_refptr<media::AudioBusRefCounted>& samples) {
     EXPECT_EQ(expected_token_, token);
-    EXPECT_EQ(expected_audible_, audible);
+    EXPECT_EQ(expected_audible_, type == copresence::AUDIBLE);
     saved_samples_ = samples;
     ASSERT_TRUE(run_loop_);
     run_loop_->Quit();
diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc
index df99de7..458bb9d 100644
--- a/chrome/browser/devtools/device/android_device_manager.cc
+++ b/chrome/browser/devtools/device/android_device_manager.cc
@@ -326,7 +326,7 @@
 
 void AndroidDeviceManager::Device::QueryDeviceInfo(
     const DeviceInfoCallback& callback) {
-  device_message_loop_->PostTask(
+  message_loop_proxy_->PostTask(
       FROM_HERE,
       base::Bind(&DeviceProvider::QueryDeviceInfo,
                  provider_,
@@ -338,7 +338,7 @@
 
 void AndroidDeviceManager::Device::OpenSocket(const std::string& socket_name,
                                               const SocketCallback& callback) {
-  device_message_loop_->PostTask(
+  message_loop_proxy_->PostTask(
       FROM_HERE,
       base::Bind(&DeviceProvider::OpenSocket,
                  provider_,
@@ -351,7 +351,7 @@
     const std::string& socket_name,
     const std::string& request,
     const CommandCallback& callback) {
-  device_message_loop_->PostTask(
+  message_loop_proxy_->PostTask(
       FROM_HERE,
       base::Bind(&DeviceProvider::SendJsonRequest,
                  provider_,
@@ -366,7 +366,7 @@
 void AndroidDeviceManager::Device::HttpUpgrade(const std::string& socket_name,
                                                const std::string& url,
                                                const SocketCallback& callback) {
-  device_message_loop_->PostTask(
+  message_loop_proxy_->PostTask(
       FROM_HERE,
       base::Bind(&DeviceProvider::HttpUpgrade,
                  provider_,
@@ -382,17 +382,21 @@
     scoped_refptr<base::MessageLoopProxy> device_message_loop,
     scoped_refptr<DeviceProvider> provider,
     const std::string& serial)
-    : device_message_loop_(device_message_loop),
+    : message_loop_proxy_(device_message_loop),
       provider_(provider),
       serial_(serial),
       weak_factory_(this) {
 }
 
 AndroidDeviceManager::Device::~Device() {
+  std::set<AndroidWebSocket*> sockets_copy(sockets_);
+  for (AndroidWebSocket* socket : sockets_copy)
+    socket->OnSocketClosed();
+
   provider_->AddRef();
   DeviceProvider* raw_ptr = provider_.get();
   provider_ = NULL;
-  device_message_loop_->PostTask(
+  message_loop_proxy_->PostTask(
       FROM_HERE,
       base::Bind(&ReleaseDeviceAndProvider,
                  base::Unretained(raw_ptr),
diff --git a/chrome/browser/devtools/device/android_device_manager.h b/chrome/browser/devtools/device/android_device_manager.h
index fbc00cd..ec65e03 100644
--- a/chrome/browser/devtools/device/android_device_manager.h
+++ b/chrome/browser/devtools/device/android_device_manager.h
@@ -53,6 +53,7 @@
   };
 
   typedef base::Callback<void(const DeviceInfo&)> DeviceInfoCallback;
+  class Device;
 
   class AndroidWebSocket {
    public:
@@ -66,9 +67,29 @@
       virtual ~Delegate() {}
     };
 
-    virtual ~AndroidWebSocket() {}
+    ~AndroidWebSocket();
 
-    virtual void SendFrame(const std::string& message) = 0;
+    void SendFrame(const std::string& message);
+
+   private:
+    friend class Device;
+    class WebSocketImpl;
+
+    AndroidWebSocket(
+        scoped_refptr<Device> device,
+        const std::string& socket_name,
+        const std::string& url,
+        AndroidWebSocket::Delegate* delegate);
+    void Connected(int result, scoped_ptr<net::StreamSocket> socket);
+    void OnFrameRead(const std::string& message);
+    void OnSocketClosed();
+    void Terminate();
+
+    Device* device_;
+    WebSocketImpl* socket_impl_;
+    Delegate* delegate_;
+    base::WeakPtrFactory<AndroidWebSocket> weak_factory_;
+    DISALLOW_COPY_AND_ASSIGN(AndroidWebSocket);
   };
 
   class DeviceProvider;
@@ -76,10 +97,6 @@
   class Device : public base::RefCountedThreadSafe<Device>,
                  public base::NonThreadSafe {
    public:
-    typedef AndroidDeviceManager::DeviceInfoCallback DeviceInfoCallback;
-    typedef AndroidDeviceManager::CommandCallback CommandCallback;
-    typedef AndroidDeviceManager::SocketCallback SocketCallback;
-
     void QueryDeviceInfo(const DeviceInfoCallback& callback);
 
     void OpenSocket(const std::string& socket_name,
@@ -92,7 +109,6 @@
     void HttpUpgrade(const std::string& socket_name,
                      const std::string& url,
                      const SocketCallback& callback);
-
     AndroidWebSocket* CreateWebSocket(
         const std::string& socket_name,
         const std::string& url,
@@ -101,17 +117,20 @@
     std::string serial() { return serial_; }
 
    private:
+    friend class base::RefCountedThreadSafe<Device>;
     friend class AndroidDeviceManager;
+    friend class AndroidWebSocket;
+
     Device(scoped_refptr<base::MessageLoopProxy> device_message_loop,
            scoped_refptr<DeviceProvider> provider,
            const std::string& serial);
 
-    friend class base::RefCountedThreadSafe<Device>;
     virtual ~Device();
 
-    scoped_refptr<base::MessageLoopProxy> device_message_loop_;
+    scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
     scoped_refptr<DeviceProvider> provider_;
     std::string serial_;
+    std::set<AndroidWebSocket*> sockets_;
     base::WeakPtrFactory<Device> weak_factory_;
 
     DISALLOW_COPY_AND_ASSIGN(Device);
diff --git a/chrome/browser/devtools/device/android_web_socket.cc b/chrome/browser/devtools/device/android_web_socket.cc
index 0e45830..7f9f5b7b 100644
--- a/chrome/browser/devtools/device/android_web_socket.cc
+++ b/chrome/browser/devtools/device/android_web_socket.cc
@@ -19,21 +19,107 @@
 
 const int kBufferSize = 16 * 1024;
 
-class WebSocketImpl {
- public:
-  typedef AndroidDeviceManager::AndroidWebSocket::Delegate Delegate;
+}  // namespace
 
-  WebSocketImpl(Delegate* delegate,
-                scoped_ptr<net::StreamSocket> socket);
-  void StartListening();
-  void SendFrame(const std::string& message);
+class AndroidDeviceManager::AndroidWebSocket::WebSocketImpl {
+ public:
+   WebSocketImpl(scoped_refptr<base::MessageLoopProxy> response_message_loop,
+                 base::WeakPtr<AndroidWebSocket> weak_socket,
+                 scoped_ptr<net::StreamSocket> socket)
+                 : response_message_loop_(response_message_loop),
+                   weak_socket_(weak_socket),
+                   socket_(socket.Pass()) {
+    thread_checker_.DetachFromThread();
+  }
+
+  void StartListening() {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    DCHECK(socket_);
+    scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
+    Read(buffer);
+  }
+
+  void SendFrame(const std::string& message) {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    if (!socket_)
+      return;
+    int mask = base::RandInt(0, 0x7FFFFFFF);
+    std::string encoded_frame = WebSocket::EncodeFrameHybi17(message, mask);
+    request_buffer_ += encoded_frame;
+    if (request_buffer_.length() == encoded_frame.length())
+      SendPendingRequests(0);
+  }
 
  private:
-  void OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer, int result);
-  void SendPendingRequests(int result);
-  void Disconnect();
+  void Read(scoped_refptr<net::IOBuffer> response_buffer) {
+    int result = socket_->Read(
+        response_buffer.get(),
+        kBufferSize,
+        base::Bind(&WebSocketImpl::OnBytesRead,
+                   base::Unretained(this), response_buffer));
+    if (result != net::ERR_IO_PENDING)
+      OnBytesRead(response_buffer, result);
+  }
 
-  Delegate* delegate_;
+  void OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer, int result) {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    if (result <= 0) {
+      Disconnect();
+      return;
+    }
+    response_buffer_.append(response_buffer->data(), result);
+
+    int bytes_consumed;
+    std::string output;
+    WebSocket::ParseResult parse_result = WebSocket::DecodeFrameHybi17(
+        response_buffer_, false, &bytes_consumed, &output);
+
+    while (parse_result == WebSocket::FRAME_OK) {
+      response_buffer_ = response_buffer_.substr(bytes_consumed);
+      response_message_loop_->PostTask(
+          FROM_HERE,
+          base::Bind(&AndroidWebSocket::OnFrameRead, weak_socket_, output));
+      parse_result = WebSocket::DecodeFrameHybi17(
+          response_buffer_, false, &bytes_consumed, &output);
+    }
+
+    if (parse_result == WebSocket::FRAME_ERROR ||
+        parse_result == WebSocket::FRAME_CLOSE) {
+      Disconnect();
+      return;
+    }
+    Read(response_buffer);
+  }
+
+  void SendPendingRequests(int result) {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    if (result < 0) {
+      Disconnect();
+      return;
+    }
+    request_buffer_ = request_buffer_.substr(result);
+    if (request_buffer_.empty())
+      return;
+
+    scoped_refptr<net::StringIOBuffer> buffer =
+        new net::StringIOBuffer(request_buffer_);
+    result = socket_->Write(buffer.get(), buffer->size(),
+                            base::Bind(&WebSocketImpl::SendPendingRequests,
+                                       base::Unretained(this)));
+    if (result != net::ERR_IO_PENDING)
+      SendPendingRequests(result);
+  }
+
+  void Disconnect() {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    socket_.reset();
+    response_message_loop_->PostTask(
+        FROM_HERE,
+        base::Bind(&AndroidWebSocket::OnSocketClosed, weak_socket_));
+  }
+
+  scoped_refptr<base::MessageLoopProxy> response_message_loop_;
+  base::WeakPtr<AndroidWebSocket> weak_socket_;
   scoped_ptr<net::StreamSocket> socket_;
   std::string response_buffer_;
   std::string request_buffer_;
@@ -41,240 +127,87 @@
   DISALLOW_COPY_AND_ASSIGN(WebSocketImpl);
 };
 
-class DelegateWrapper
-    : public AndroidDeviceManager::AndroidWebSocket::Delegate {
- public:
-  DelegateWrapper(base::WeakPtr<Delegate> weak_delegate,
-                  scoped_refptr<base::MessageLoopProxy> message_loop)
-      : weak_delegate_(weak_delegate),
-        message_loop_(message_loop) {
-  }
-
-  ~DelegateWrapper() override {}
-
-  // AndroidWebSocket::Delegate implementation
-  void OnSocketOpened() override {
-    message_loop_->PostTask(FROM_HERE,
-        base::Bind(&Delegate::OnSocketOpened, weak_delegate_));
-  }
-
-  void OnFrameRead(const std::string& message) override {
-    message_loop_->PostTask(FROM_HERE,
-        base::Bind(&Delegate::OnFrameRead, weak_delegate_, message));
-  }
-
-  void OnSocketClosed() override {
-    message_loop_->PostTask(FROM_HERE,
-        base::Bind(&Delegate::OnSocketClosed, weak_delegate_));
-  }
-
- private:
-  base::WeakPtr<Delegate> weak_delegate_;
-  scoped_refptr<base::MessageLoopProxy> message_loop_;
-};
-
-class AndroidWebSocketImpl
-    : public AndroidDeviceManager::AndroidWebSocket,
-      public AndroidDeviceManager::AndroidWebSocket::Delegate {
- public:
-  typedef AndroidDeviceManager::Device Device;
-  AndroidWebSocketImpl(
-      scoped_refptr<base::MessageLoopProxy> device_message_loop,
-      scoped_refptr<Device> device,
-      const std::string& socket_name,
-      const std::string& url,
-      AndroidWebSocket::Delegate* delegate);
-
-  ~AndroidWebSocketImpl() override;
-
-  // AndroidWebSocket implementation
-  void SendFrame(const std::string& message) override;
-
-  // AndroidWebSocket::Delegate implementation
-  void OnSocketOpened() override;
-  void OnFrameRead(const std::string& message) override;
-  void OnSocketClosed() override;
-
- private:
-  void Connected(int result, scoped_ptr<net::StreamSocket> socket);
-
-  scoped_refptr<base::MessageLoopProxy> device_message_loop_;
-  scoped_refptr<Device> device_;
-  std::string socket_name_;
-  std::string url_;
-  WebSocketImpl* connection_;
-  DelegateWrapper* delegate_wrapper_;
-  AndroidWebSocket::Delegate* delegate_;
-  base::WeakPtrFactory<AndroidWebSocketImpl> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(AndroidWebSocketImpl);
-};
-
-AndroidWebSocketImpl::AndroidWebSocketImpl(
-    scoped_refptr<base::MessageLoopProxy> device_message_loop,
+AndroidDeviceManager::AndroidWebSocket::AndroidWebSocket(
     scoped_refptr<Device> device,
     const std::string& socket_name,
     const std::string& url,
-    AndroidWebSocket::Delegate* delegate)
-    : device_message_loop_(device_message_loop),
-      device_(device),
-      socket_name_(socket_name),
-      url_(url),
+    Delegate* delegate)
+    : device_(device.get()),
+      socket_impl_(nullptr),
       delegate_(delegate),
       weak_factory_(this) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   DCHECK(delegate_);
+  DCHECK(device_);
+  device_->sockets_.insert(this);
   device_->HttpUpgrade(
-      socket_name_, url_,
-      base::Bind(&AndroidWebSocketImpl::Connected, weak_factory_.GetWeakPtr()));
+      socket_name, url,
+      base::Bind(&AndroidWebSocket::Connected, weak_factory_.GetWeakPtr()));
 }
 
-void AndroidWebSocketImpl::SendFrame(const std::string& message) {
+AndroidDeviceManager::AndroidWebSocket::~AndroidWebSocket() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  device_message_loop_->PostTask(
+  Terminate();
+}
+
+void AndroidDeviceManager::AndroidWebSocket::SendFrame(
+    const std::string& message) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(socket_impl_);
+  DCHECK(device_);
+  device_->message_loop_proxy_->PostTask(
       FROM_HERE,
       base::Bind(&WebSocketImpl::SendFrame,
-                 base::Unretained(connection_), message));
+                 base::Unretained(socket_impl_), message));
 }
 
-void WebSocketImpl::SendFrame(const std::string& message) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (!socket_)
-    return;
-  int mask = base::RandInt(0, 0x7FFFFFFF);
-  std::string encoded_frame = WebSocket::EncodeFrameHybi17(message, mask);
-  request_buffer_ += encoded_frame;
-  if (request_buffer_.length() == encoded_frame.length())
-    SendPendingRequests(0);
-}
-
-AndroidWebSocketImpl::~AndroidWebSocketImpl() {
+void AndroidDeviceManager::AndroidWebSocket::Connected(
+    int result,
+    scoped_ptr<net::StreamSocket> socket) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  device_message_loop_->DeleteSoon(FROM_HERE, connection_);
-  device_message_loop_->DeleteSoon(FROM_HERE, delegate_wrapper_);
-}
-
-WebSocketImpl::WebSocketImpl(Delegate* delegate,
-                             scoped_ptr<net::StreamSocket> socket)
-                             : delegate_(delegate),
-                               socket_(socket.Pass()) {
-  thread_checker_.DetachFromThread();
-}
-
-void AndroidWebSocketImpl::Connected(int result,
-                                     scoped_ptr<net::StreamSocket> socket) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  if (result != net::OK || socket == NULL) {
+  if (result != net::OK || !socket.get()) {
     OnSocketClosed();
     return;
   }
-  delegate_wrapper_ = new DelegateWrapper(weak_factory_.GetWeakPtr(),
-                                          base::MessageLoopProxy::current());
-  connection_ = new WebSocketImpl(delegate_wrapper_, socket.Pass());
-  device_message_loop_->PostTask(
+  socket_impl_ = new WebSocketImpl(base::MessageLoopProxy::current(),
+                                   weak_factory_.GetWeakPtr(),
+                                   socket.Pass());
+  device_->message_loop_proxy_->PostTask(
       FROM_HERE,
       base::Bind(&WebSocketImpl::StartListening,
-                 base::Unretained(connection_)));
-  OnSocketOpened();
-}
-
-void WebSocketImpl::StartListening() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(socket_);
-  scoped_refptr<net::IOBuffer> response_buffer =
-      new net::IOBuffer(kBufferSize);
-  int result = socket_->Read(
-      response_buffer.get(),
-      kBufferSize,
-      base::Bind(&WebSocketImpl::OnBytesRead,
-                 base::Unretained(this), response_buffer));
-  if (result != net::ERR_IO_PENDING)
-    OnBytesRead(response_buffer, result);
-}
-
-void WebSocketImpl::OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer,
-                                int result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (result <= 0) {
-    Disconnect();
-    return;
-  }
-
-  response_buffer_.append(response_buffer->data(), result);
-
-  int bytes_consumed;
-  std::string output;
-  WebSocket::ParseResult parse_result = WebSocket::DecodeFrameHybi17(
-      response_buffer_, false, &bytes_consumed, &output);
-
-  while (parse_result == WebSocket::FRAME_OK) {
-    response_buffer_ = response_buffer_.substr(bytes_consumed);
-    delegate_->OnFrameRead(output);
-    parse_result = WebSocket::DecodeFrameHybi17(
-        response_buffer_, false, &bytes_consumed, &output);
-  }
-
-  if (parse_result == WebSocket::FRAME_ERROR ||
-      parse_result == WebSocket::FRAME_CLOSE) {
-    Disconnect();
-    return;
-  }
-
-  result = socket_->Read(
-      response_buffer.get(),
-      kBufferSize,
-      base::Bind(&WebSocketImpl::OnBytesRead,
-                 base::Unretained(this), response_buffer));
-  if (result != net::ERR_IO_PENDING)
-    OnBytesRead(response_buffer, result);
-}
-
-void WebSocketImpl::SendPendingRequests(int result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (result < 0) {
-    Disconnect();
-    return;
-  }
-  request_buffer_ = request_buffer_.substr(result);
-  if (request_buffer_.empty())
-    return;
-
-  scoped_refptr<net::StringIOBuffer> buffer =
-      new net::StringIOBuffer(request_buffer_);
-  result = socket_->Write(buffer.get(), buffer->size(),
-                          base::Bind(&WebSocketImpl::SendPendingRequests,
-                                     base::Unretained(this)));
-  if (result != net::ERR_IO_PENDING)
-    SendPendingRequests(result);
-}
-
-void WebSocketImpl::Disconnect() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  socket_.reset();
-  delegate_->OnSocketClosed();
-}
-
-void AndroidWebSocketImpl::OnSocketOpened() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+                 base::Unretained(socket_impl_)));
   delegate_->OnSocketOpened();
 }
 
-void AndroidWebSocketImpl::OnFrameRead(const std::string& message) {
+void AndroidDeviceManager::AndroidWebSocket::OnFrameRead(
+    const std::string& message) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   delegate_->OnFrameRead(message);
 }
 
-void AndroidWebSocketImpl::OnSocketClosed() {
+void AndroidDeviceManager::AndroidWebSocket::OnSocketClosed() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  Terminate();
   delegate_->OnSocketClosed();
 }
 
-}  // namespace
+void AndroidDeviceManager::AndroidWebSocket::Terminate() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  if (socket_impl_) {
+    DCHECK(device_);
+    device_->message_loop_proxy_->DeleteSoon(FROM_HERE, socket_impl_);
+    socket_impl_ = nullptr;
+  }
+  if (device_) {
+    device_->sockets_.erase(this);
+    device_ = nullptr;
+  }
+}
 
 AndroidDeviceManager::AndroidWebSocket*
 AndroidDeviceManager::Device::CreateWebSocket(
-    const std::string& socket,
+    const std::string& socket_name,
     const std::string& url,
-    AndroidDeviceManager::AndroidWebSocket::Delegate* delegate) {
-  return new AndroidWebSocketImpl(
-      device_message_loop_, this, socket, url, delegate);
+    AndroidWebSocket::Delegate* delegate) {
+  return new AndroidWebSocket(this, socket_name, url, delegate);
 }
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc
index 3b05ecb..b9f3070c 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.cc
+++ b/chrome/browser/devtools/device/devtools_android_bridge.cc
@@ -12,6 +12,7 @@
 #include "base/compiler_specific.h"
 #include "base/json/json_reader.h"
 #include "base/lazy_instance.h"
+#include "base/memory/singleton.h"
 #include "base/message_loop/message_loop.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_number_conversions.h"
@@ -308,6 +309,7 @@
   bool socket_opened_;
   bool is_web_view_;
   std::vector<std::string> pending_messages_;
+  scoped_refptr<AndroidDeviceManager::Device> device_;
   scoped_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_;
   content::DevToolsAgentHost* agent_host_;
   content::DevToolsExternalAgentProxy* proxy_;
@@ -361,12 +363,19 @@
   proxy_ = proxy;
   content::RecordAction(base::UserMetricsAction(is_web_view_ ?
       "DevTools_InspectAndroidWebView" : "DevTools_InspectAndroidPage"));
+
+  // Retain the device so it's not released until AgentHost is detached.
+  device_ = bridge_->FindDevice(browser_id_.first);
+  if (!device_.get())
+    return;
+
   web_socket_.reset(
-      bridge_->CreateWebSocket(browser_id_, debug_url_, this));
+      device_->CreateWebSocket(browser_id_.second, debug_url_, this));
 }
 
 void DevToolsAndroidBridge::AgentHostDelegate::Detach() {
   web_socket_.reset();
+  device_ = nullptr;
 }
 
 void DevToolsAndroidBridge::AgentHostDelegate::SendMessageToBackend(
@@ -594,12 +603,13 @@
     const BrowserId& browser_id,
     const std::string& request,
     const JsonRequestCallback& callback) {
-  DeviceMap::iterator it = device_map_.find(browser_id.first);
-  if (it == device_map_.end()) {
+  scoped_refptr<AndroidDeviceManager::Device> device(
+      FindDevice(browser_id.first));
+  if (!device.get()) {
     callback.Run(net::ERR_FAILED, std::string());
     return;
   }
-  it->second->SendJsonRequest(browser_id.second, request, callback);
+  device->SendJsonRequest(browser_id.second, request, callback);
 }
 
 void DevToolsAndroidBridge::SendProtocolCommand(
@@ -611,13 +621,14 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (debug_url.empty())
     return;
-  DeviceMap::iterator it = device_map_.find(browser_id.first);
-  if (it == device_map_.end()) {
+  scoped_refptr<AndroidDeviceManager::Device> device(
+      FindDevice(browser_id.first));
+  if (!device.get()) {
     callback.Run();
     return;
   }
   DevToolsProtocol::Command command(1, method, params);
-  new ProtocolCommand(it->second, browser_id.second, debug_url,
+  new ProtocolCommand(device, browser_id.second, debug_url,
                       command.Serialize(), callback);
 }
 
@@ -632,16 +643,10 @@
       browser->IsWebView());
 }
 
-AndroidDeviceManager::AndroidWebSocket*
-DevToolsAndroidBridge::CreateWebSocket(
-    const BrowserId& browser_id,
-    const std::string& url,
-    AndroidDeviceManager::AndroidWebSocket::Delegate* delegate) {
-  DeviceMap::iterator it = device_map_.find(browser_id.first);
-  if (it == device_map_.end())
-    return NULL;
-
-  return it->second->CreateWebSocket(browser_id.second, url, delegate);
+scoped_refptr<AndroidDeviceManager::Device> DevToolsAndroidBridge::FindDevice(
+    const std::string& serial) {
+  DeviceMap::iterator it = device_map_.find(serial);
+  return it == device_map_.end() ? nullptr : it->second;
 }
 
 void DevToolsAndroidBridge::RespondToOpenOnUIThread(
@@ -760,7 +765,7 @@
     : profile_(profile),
       device_manager_(AndroidDeviceManager::Create()),
       task_scheduler_(base::Bind(&DevToolsAndroidBridge::ScheduleTaskDefault)),
-      port_forwarding_controller_(new PortForwardingController(profile)) {
+      port_forwarding_controller_(new PortForwardingController(profile, this)) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   pref_change_registrar_.Init(profile_->GetPrefs());
   pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled,
@@ -881,7 +886,7 @@
     (*it)->DeviceListChanged(remote_devices);
 
   ForwardingStatus status =
-      port_forwarding_controller_->DeviceListChanged(complete_devices);
+      port_forwarding_controller_->DeviceListChanged(remote_devices);
   PortForwardingListeners forwarding_listeners(port_forwarding_listeners_);
   for (PortForwardingListeners::iterator it = forwarding_listeners.begin();
        it != forwarding_listeners.end(); ++it) {
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.h b/chrome/browser/devtools/device/devtools_android_bridge.h
index 2310600c..a64dc1f 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.h
+++ b/chrome/browser/devtools/device/devtools_android_bridge.h
@@ -226,17 +226,13 @@
 
   scoped_refptr<content::DevToolsAgentHost> GetBrowserAgentHost(
       scoped_refptr<RemoteBrowser> browser);
-
-  typedef std::pair<scoped_refptr<AndroidDeviceManager::Device>,
-                    scoped_refptr<RemoteDevice>> CompleteDevice;
-  typedef std::vector<CompleteDevice> CompleteDevices;
-  typedef base::Callback<void(const CompleteDevices&)> DeviceListCallback;
-
  private:
   friend struct content::BrowserThread::DeleteOnThread<
       content::BrowserThread::UI>;
   friend class base::DeleteHelper<DevToolsAndroidBridge>;
 
+  friend class PortForwardingController;
+
   class AgentHostDelegate;
   class DiscoveryRequest;
   class RemotePageTarget;
@@ -247,8 +243,12 @@
   void StopDeviceListPolling();
   bool NeedsDeviceListPolling();
 
-  void RequestDeviceList(const DeviceListCallback& callback);
+  typedef std::pair<scoped_refptr<AndroidDeviceManager::Device>,
+                    scoped_refptr<RemoteDevice>> CompleteDevice;
+  typedef std::vector<CompleteDevice> CompleteDevices;
+  typedef base::Callback<void(const CompleteDevices&)> DeviceListCallback;
 
+  void RequestDeviceList(const DeviceListCallback& callback);
   void ReceivedDeviceList(const CompleteDevices& complete_devices);
 
   void StartDeviceCountPolling();
@@ -270,10 +270,8 @@
                            base::DictionaryValue* params,
                            const base::Closure callback);
 
-  AndroidDeviceManager::AndroidWebSocket* CreateWebSocket(
-      const BrowserId& browser_id,
-      const std::string& url,
-      AndroidDeviceManager::AndroidWebSocket::Delegate* delegate);
+  scoped_refptr<AndroidDeviceManager::Device> FindDevice(
+      const std::string& serial);
 
   void PageCreatedOnUIThread(scoped_refptr<RemoteBrowser> browser,
                              const RemotePageCallback& callback,
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.cc b/chrome/browser/devtools/device/port_forwarding_controller.cc
index d19e9ff..eb82daa 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.cc
+++ b/chrome/browser/devtools/device/port_forwarding_controller.cc
@@ -254,8 +254,7 @@
 class PortForwardingController::Connection
     : public AndroidDeviceManager::AndroidWebSocket::Delegate {
  public:
-  Connection(Registry* registry,
-             scoped_refptr<AndroidDeviceManager::Device> device,
+  Connection(PortForwardingController* controller,
              scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
              const ForwardingMap& forwarding_map);
   ~Connection() override;
@@ -273,9 +272,7 @@
       content::BrowserThread::UI>;
   friend class base::DeleteHelper<Connection>;
 
-
   typedef std::map<int, std::string> ForwardingMap;
-
   typedef base::Callback<void(PortStatus)> CommandCallback;
   typedef std::map<int, CommandCallback> CommandCallbackMap;
 
@@ -298,8 +295,7 @@
   void OnFrameRead(const std::string& message) override;
   void OnSocketClosed() override;
 
-  PortForwardingController::Registry* registry_;
-  scoped_refptr<AndroidDeviceManager::Device> device_;
+  PortForwardingController* controller_;
   scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_;
   scoped_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_;
   int command_id_;
@@ -313,29 +309,30 @@
 };
 
 PortForwardingController::Connection::Connection(
-    Registry* registry,
-    scoped_refptr<AndroidDeviceManager::Device> device,
+    PortForwardingController* controller,
     scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
     const ForwardingMap& forwarding_map)
-    : registry_(registry),
-      device_(device),
+    : controller_(controller),
       browser_(browser),
       command_id_(0),
       connected_(false),
       forwarding_map_(forwarding_map),
       weak_factory_(this) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  (*registry_)[device_->serial()] = this;
+  controller_->registry_[browser->serial()] = this;
+  scoped_refptr<AndroidDeviceManager::Device> device(
+      controller_->bridge_->FindDevice(browser->serial()));
+  DCHECK(device.get());
   web_socket_.reset(
-      device_->CreateWebSocket(browser->socket(),
-                               kDevToolsRemoteBrowserTarget, this));
+      device->CreateWebSocket(browser->socket(),
+                              kDevToolsRemoteBrowserTarget, this));
 }
 
 PortForwardingController::Connection::~Connection() {
-
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(registry_->find(device_->serial()) != registry_->end());
-  registry_->erase(device_->serial());
+  DCHECK(controller_->registry_.find(browser_->serial()) !=
+         controller_->registry_.end());
+  controller_->registry_.erase(browser_->serial());
 }
 
 void PortForwardingController::Connection::UpdateForwardingMap(
@@ -515,7 +512,10 @@
       base::Bind(&Connection::UpdateSocketCountOnHandlerThread,
                  weak_factory_.GetWeakPtr(), port);
 
-  device_->OpenSocket(
+  scoped_refptr<AndroidDeviceManager::Device> device(
+      controller_->bridge_->FindDevice(browser_->serial()));
+  DCHECK(device.get());
+  device->OpenSocket(
       connection_id.c_str(),
       base::Bind(&SocketTunnel::StartTunnel,
                  destination_host,
@@ -523,8 +523,11 @@
                  callback));
 }
 
-PortForwardingController::PortForwardingController(Profile* profile)
+PortForwardingController::PortForwardingController(
+    Profile* profile,
+    DevToolsAndroidBridge* bridge)
     : profile_(profile),
+      bridge_(bridge),
       pref_service_(profile->GetPrefs()) {
   pref_change_registrar_.Init(pref_service_);
   base::Closure callback = base::Bind(
@@ -538,23 +541,20 @@
 
 PortForwardingController::ForwardingStatus
 PortForwardingController::DeviceListChanged(
-    const DevToolsAndroidBridge::CompleteDevices& complete_devices) {
+    const DevToolsAndroidBridge::RemoteDevices& devices) {
   ForwardingStatus status;
   if (forwarding_map_.empty())
     return status;
 
-  for (const auto& pair : complete_devices) {
-    scoped_refptr<AndroidDeviceManager::Device> device(pair.first);
-    scoped_refptr<DevToolsAndroidBridge::RemoteDevice> remote_device(
-        pair.second);
-    if (!remote_device->is_connected())
+  for (const auto& device : devices) {
+    if (!device->is_connected())
       continue;
-    Registry::iterator rit = registry_.find(remote_device->serial());
+    Registry::iterator rit = registry_.find(device->serial());
     if (rit == registry_.end()) {
       scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser(
-          FindBestBrowserForTethering(remote_device->browsers()));
+          FindBestBrowserForTethering(device->browsers()));
       if (browser.get())
-        new Connection(&registry_, device, browser, forwarding_map_);
+        new Connection(this, browser, forwarding_map_);
     } else {
       status.push_back(std::make_pair(rit->second->browser(),
                                       rit->second->GetPortStatusMap()));
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.h b/chrome/browser/devtools/device/port_forwarding_controller.h
index ab75a48..19736fc 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.h
+++ b/chrome/browser/devtools/device/port_forwarding_controller.h
@@ -22,12 +22,13 @@
   typedef DevToolsAndroidBridge::BrowserStatus BrowserStatus;
   typedef DevToolsAndroidBridge::ForwardingStatus ForwardingStatus;
 
-  explicit PortForwardingController(Profile* profile);
+  explicit PortForwardingController(Profile* profile,
+                                    DevToolsAndroidBridge* bridge);
 
   virtual ~PortForwardingController();
 
   ForwardingStatus DeviceListChanged(
-      const DevToolsAndroidBridge::CompleteDevices& complete_devices);
+      const DevToolsAndroidBridge::RemoteDevices& devices);
 
  private:
   class Connection;
@@ -38,6 +39,7 @@
   void UpdateConnections();
 
   Profile* profile_;
+  DevToolsAndroidBridge* bridge_;
   PrefService* pref_service_;
   PrefChangeRegistrar pref_change_registrar_;
   Registry registry_;
diff --git a/chrome/browser/devtools/devtools_file_system_indexer.cc b/chrome/browser/devtools/devtools_file_system_indexer.cc
index d0b0b8c..de03d68 100644
--- a/chrome/browser/devtools/devtools_file_system_indexer.cc
+++ b/chrome/browser/devtools/devtools_file_system_indexer.cc
@@ -44,14 +44,9 @@
     kTrigramCharacterCount * kTrigramCharacterCount * kTrigramCharacterCount;
 const int kMaxReadLength = 10 * 1024;
 const TrigramChar kUndefinedTrigramChar = -1;
+const TrigramChar kBinaryTrigramChar = -2;
 const Trigram kUndefinedTrigram = -1;
 
-base::LazyInstance<vector<bool> >::Leaky g_is_binary_char =
-    LAZY_INSTANCE_INITIALIZER;
-
-base::LazyInstance<vector<TrigramChar> >::Leaky g_trigram_chars =
-    LAZY_INSTANCE_INITIALIZER;
-
 class Index {
  public:
   Index();
@@ -82,47 +77,42 @@
 
 base::LazyInstance<Index>::Leaky g_trigram_index = LAZY_INSTANCE_INITIALIZER;
 
-void InitIsBinaryCharMap() {
-  for (size_t i = 0; i < 256; ++i) {
-    unsigned char ch = i;
-    bool is_binary_char = ch < 9 || (ch >= 14 && ch < 32) || ch == 127;
-    g_is_binary_char.Get().push_back(is_binary_char);
-  }
-}
-
-bool IsBinaryChar(char c) {
-  unsigned char uc = static_cast<unsigned char>(c);
-  return g_is_binary_char.Get()[uc];
-}
-
-void InitTrigramCharsMap() {
-  for (size_t i = 0; i < 256; ++i) {
-    if (i > 127) {
-      g_trigram_chars.Get().push_back(kUndefinedTrigramChar);
-      continue;
-    }
-    char ch = i;
-    if (ch == '\t')
-      ch = ' ';
-    if (ch >= 'A' && ch <= 'Z')
-      ch = ch - 'A' + 'a';
-    if ((IsBinaryChar(ch)) || (ch < ' ')) {
-      g_trigram_chars.Get().push_back(kUndefinedTrigramChar);
-      continue;
-    }
-
-    if (ch >= 'Z')
-      ch = ch - 'Z' - 1 + 'A';
-    ch -= ' ';
-    char signed_trigram_char_count = static_cast<char>(kTrigramCharacterCount);
-    CHECK(ch >= 0 && ch < signed_trigram_char_count);
-    g_trigram_chars.Get().push_back(ch);
-  }
-}
-
 TrigramChar TrigramCharForChar(char c) {
+  static TrigramChar* trigram_chars = nullptr;
+  if (!trigram_chars) {
+    trigram_chars = new TrigramChar[256];
+    for (size_t i = 0; i < 256; ++i) {
+      if (i > 127) {
+        trigram_chars[i] = kUndefinedTrigramChar;
+        continue;
+      }
+      char ch = static_cast<char>(i);
+      if (ch == '\t')
+        ch = ' ';
+      if (ch >= 'A' && ch <= 'Z')
+        ch = ch - 'A' + 'a';
+
+      bool is_binary_char = ch < 9 || (ch >= 14 && ch < 32) || ch == 127;
+      if (is_binary_char) {
+        trigram_chars[i] = kBinaryTrigramChar;
+        continue;
+      }
+
+      if (ch < ' ') {
+        trigram_chars[i] = kUndefinedTrigramChar;
+        continue;
+      }
+
+      if (ch >= 'Z')
+        ch = ch - 'Z' - 1 + 'A';
+      ch -= ' ';
+      char signed_trigram_count = static_cast<char>(kTrigramCharacterCount);
+      CHECK(ch >= 0 && ch < signed_trigram_count);
+      trigram_chars[i] = ch;
+    }
+  }
   unsigned char uc = static_cast<unsigned char>(c);
-  return g_trigram_chars.Get()[uc];
+  return trigram_chars[uc];
 }
 
 Trigram TrigramAtIndex(const vector<TrigramChar>& trigram_chars, size_t index) {
@@ -173,8 +163,12 @@
   const char* data = query.c_str();
   vector<TrigramChar> trigram_chars;
   trigram_chars.reserve(query.size());
-  for (size_t i = 0; i < query.size(); ++i)
-      trigram_chars.push_back(TrigramCharForChar(data[i]));
+  for (size_t i = 0; i < query.size(); ++i) {
+      TrigramChar trigram_char = TrigramCharForChar(data[i]);
+      if (trigram_char == kBinaryTrigramChar)
+        trigram_char = kUndefinedTrigramChar;
+      trigram_chars.push_back(trigram_char);
+  }
   vector<Trigram> trigrams;
   for (size_t i = 0; i + 2 < query.size(); ++i) {
     Trigram trigram = TrigramAtIndex(trigram_chars, i);
@@ -377,12 +371,13 @@
   vector<TrigramChar> trigram_chars;
   trigram_chars.reserve(size);
   for (size_t i = 0; i < size; ++i) {
-    if (IsBinaryChar(data[i])) {
+    TrigramChar trigram_char = TrigramCharForChar(data[i]);
+    if (trigram_char == kBinaryTrigramChar) {
       current_trigrams_.clear();
       FinishFileIndexing(true);
       return;
     }
-    trigram_chars.push_back(TrigramCharForChar(data[i]));
+    trigram_chars.push_back(trigram_char);
   }
 
   for (size_t i = 0; i + 2 < size; ++i) {
@@ -436,12 +431,6 @@
 }
 
 DevToolsFileSystemIndexer::DevToolsFileSystemIndexer() {
-  static bool maps_initialized = false;
-  if (!maps_initialized) {
-    InitIsBinaryCharMap();
-    InitTrigramCharsMap();
-    maps_initialized = true;
-  }
 }
 
 DevToolsFileSystemIndexer::~DevToolsFileSystemIndexer() {}
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc
index eb7d5612..64de7c7 100644
--- a/chrome/browser/devtools/devtools_sanity_browsertest.cc
+++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -21,8 +21,6 @@
 #include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_iterator.h"
@@ -34,6 +32,8 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/test_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "content/public/browser/child_process_data.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/devtools_agent_host.h"
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index 1ff661a6..9724be0 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -877,10 +877,9 @@
   // In the DEBUG_DEVTOOLS mode, the DocumentOnLoadCompletedInMainFrame event
   // arrives before the LoadCompleted event, thus it should not trigger the
   // frontend load handling.
-#if defined(DEBUG_DEVTOOLS)
-  return;
-#endif
+#if !defined(DEBUG_DEVTOOLS)
   FrontendLoaded();
+#endif
 }
 
 void DevToolsUIBindings::DidNavigateMainFrame() {
diff --git a/chrome/browser/devtools/frontend/devtools_discovery_page.html b/chrome/browser/devtools/frontend/devtools_discovery_page.html
index 63a0b44f..9d9fc57 100644
--- a/chrome/browser/devtools/frontend/devtools_discovery_page.html
+++ b/chrome/browser/devtools/frontend/devtools_discovery_page.html
@@ -3,82 +3,81 @@
 <title>Inspectable pages</title>
 <style>
 body {
-  background-color: rgb(245, 245, 245);
+  color: #222;
   font-family: Helvetica, Arial, sans-serif;
+  margin: 0;
   text-shadow: rgba(255, 255, 255, 0.496094) 0px 1px 0px;
 }
 
 #caption {
-  color: black;
   font-size: 16px;
-  margin-top: 30px;
-  margin-bottom: 0px;
-  margin-left: 70px;
+  margin-top: 15px;
+  margin-bottom: 10px;
+  margin-left: 20px;
   height: 20px;
   text-align: left;
 }
 
 #items {
-  display: -webkit-box;
-  margin-left: 60px;
-  margin-right: 60px;
-  -webkit-box-orient: horizontal;
-  -webkit-box-lines: multiple;
+  display: flex;
+  flex-direction: column;
+  margin: 10px;
 }
 
-.frontend_ref {
-  color: black;
-  text-decoration: initial;
+.item {
+  color: #222;
+  display: flex;
+  flex-direction: row;
+  text-decoration: none;
+  padding: 10px;
+  -webkit-transition-property: background-color, border-color;
+  -webkit-transition: background-color 0.15s, 0.15s;
+  -webkit-transition-delay: 0, 0;
 }
 
 .thumbnail {
   background-attachment: scroll;
   background-origin: padding-box;
   background-repeat: no-repeat;
-  border: 4px solid rgba(184, 184, 184, 1);
-  border-radius: 5px;
+  border: 1px solid rgba(184, 184, 184, 1);
+  flex: none;
   height: 132px;
   width: 212px;
-  -webkit-transition-property: background-color, border-color;
-  -webkit-transition: background-color 0.15s, 0.15s;
-  -webkit-transition-delay: 0, 0;
 }
 
-.thumbnail:hover {
+.item:not(.connected):hover {
   background-color: rgba(242, 242, 242, 1);
   border-color: rgba(110, 116, 128, 1);
   color: black;
 }
 
-.thumbnail.connected {
+.item.connected .thumbnail {
   opacity: 0.5;
 }
 
-.thumbnail.connected:hover {
+.item.connected:hover {
   border-color: rgba(184, 184, 184, 1);
   color: rgb(110, 116, 128);
 }
 
-.item {
-  display: inline-block;
-  margin: 5px;
-  margin-top: 15px;
-  height: 162px;
-  vertical-align: top;
-  width: 222px;
+.description {
+  display: flex;
+  flex-direction: column;
 }
 
-.text {
-  background: no-repeat 0;
-  background-size: 16px;
-  font-size: 12px;
-  margin: 4px 0px 0px 4px;
+.title, .subtitle {
+  font-size: 13px;
+  margin: 4px 0px 0px 6px;
   overflow: hidden;
-  padding: 2px 0px 0px 20px;
-  text-align: left;
-  text-overflow: ellipsis;
-  white-space: nowrap;
+  padding-left: 20px;
 }
+
+.title {
+  background-repeat: no-repeat;
+  background-size: 16px;
+  font-size: 15px;
+}
+
 </style>
 
 <script>
@@ -112,44 +111,49 @@
 }
 
 function appendItem(item_object) {
-  var frontend_ref;
+  var item_element;
   if (item_object.devtoolsFrontendUrl) {
-    frontend_ref = document.createElement('a');
-    frontend_ref.href = overrideFrontendUrl(item_object);
-    frontend_ref.title = item_object.title;
+    item_element = document.createElement('a');
+    item_element.href = overrideFrontendUrl(item_object);
+    item_element.title = item_object.title;
   } else {
-    frontend_ref = document.createElement('div');
-    frontend_ref.title = 'The tab already has an active debug session';
+    item_element = document.createElement('div');
+    item_element.className = 'connected';
+    item_element.title = 'The tab already has an active debug session';
   }
-  frontend_ref.className = 'frontend_ref';
+  item_element.classList.add('item');
 
   var thumbnail = document.createElement('div');
-  thumbnail.className = item_object.devtoolsFrontendUrl ?
-                        'thumbnail' : 'thumbnail connected';
+  thumbnail.className = 'thumbnail';
   thumbnail.style.cssText = 'background-image:url(' +
-                        item_object.thumbnailUrl +
-                        ')';
-  frontend_ref.appendChild(thumbnail);
+      item_object.thumbnailUrl + ')';
+  item_element.appendChild(thumbnail);
 
-  var text = document.createElement('div');
-  text.className = 'text';
-  text.innerText = item_object.description || item_object.title;
-  text.style.cssText = 'background-image:url(' +
-                       item_object.faviconUrl + ')';
-  frontend_ref.appendChild(text);
+  var description = document.createElement('div');
+  description.className = 'description';
 
-  var item = document.createElement('p');
-  item.className = 'item';
-  item.appendChild(frontend_ref);
+  var title = document.createElement('div');
+  title.className = 'title';
+  title.textContent = item_object.description || item_object.title;
+  title.style.cssText = 'background-image:url(' +
+      item_object.faviconUrl + ')';
+  description.appendChild(title);
 
-  document.getElementById('items').appendChild(item);
+  var subtitle = document.createElement('div');
+  subtitle.className = 'subtitle';
+  subtitle.textContent = (item_object.url || '').substring(0, 300);
+  description.appendChild(subtitle);
+
+  item_element.appendChild(description);
+
+  document.getElementById('items').appendChild(item_element);
 }
 </script>
 </head>
 <body onload='onLoad()'>
   <div id='caption'>Inspectable pages</div>
+  <hr>
   <div id='items'>
   </div>
-  <hr>
 </body>
 </html>
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index db952c5..c2d95a6 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -560,13 +560,9 @@
 
   EXPECT_TRUE(base::PathExists(full_file_name));
   EXPECT_TRUE(base::PathExists(dir));
-#if 0
-  // Disabled until the following Blink CL is relanded and rolled:
-  // https://codereview.chromium.org/649413002
   EXPECT_TRUE(base::TextContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved1.htm"),
       full_file_name));
-#endif
   EXPECT_TRUE(base::ContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
       dir.AppendASCII("1.png")));
@@ -660,13 +656,9 @@
 
   EXPECT_TRUE(base::PathExists(full_file_name));
   EXPECT_TRUE(base::PathExists(dir));
-#if 0
-  // Disabled until the following Blink CL is relanded and rolled:
-  // https://codereview.chromium.org/649413002
   EXPECT_TRUE(base::TextContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("b.saved2.htm"),
       full_file_name));
-#endif
   EXPECT_TRUE(base::ContentsEqual(
       test_dir_.Append(base::FilePath(kTestDir)).AppendASCII("1.png"),
       dir.AppendASCII("1.png")));
diff --git a/chrome/browser/extensions/alert_apitest.cc b/chrome/browser/extensions/alert_apitest.cc
index 893a9b4..dbd7c55 100644
--- a/chrome/browser/extensions/alert_apitest.cc
+++ b/chrome/browser/extensions/alert_apitest.cc
@@ -5,9 +5,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
 #include "content/public/browser/render_frame_host.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/browser/extension_system.h"
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
index 6748fcb..a340802 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -9,7 +9,6 @@
 #include "base/lazy_instance.h"
 #include "base/memory/linked_ptr.h"
 #include "base/prefs/pref_service.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -272,11 +271,6 @@
 
 void BookmarkManagerPrivateAPI::OnListenerAdded(
     const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "BookmarkManagerPrivateAPI::OnListenerAdded"));
-
   EventRouter::Get(browser_context_)->UnregisterObserver(this);
   event_router_.reset(new BookmarkManagerPrivateEventRouter(
       browser_context_,
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc
index a1460489..2eee449 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc
@@ -32,7 +32,7 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile);
   ChromeBookmarkClient* client =
       ChromeBookmarkClientFactory::GetForProfile(profile);
-  test::WaitForBookmarkModelToLoad(model);
+  bookmarks::test::WaitForBookmarkModelToLoad(model);
 
   base::ListValue list;
   base::DictionaryValue* node = new base::DictionaryValue();
@@ -56,7 +56,7 @@
   // Provide some testing data here, since bookmark editing will be disabled
   // within the extension.
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile);
-  test::WaitForBookmarkModelToLoad(model);
+  bookmarks::test::WaitForBookmarkModelToLoad(model);
   const BookmarkNode* bar = model->bookmark_bar_node();
   const BookmarkNode* folder =
       model->AddFolder(bar, 0, base::ASCIIToUTF16("Folder"));
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc
index 0852e68..2982099 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers_unittest.cc
@@ -35,7 +35,7 @@
     profile_.CreateBookmarkModel(false);
     model_ = BookmarkModelFactory::GetForProfile(&profile_);
     client_ = ChromeBookmarkClientFactory::GetForProfile(&profile_);
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
 
     node_ = model_->AddURL(model_->other_node(), 0, base::ASCIIToUTF16("Digg"),
                            GURL("http://www.reddit.com"));
diff --git a/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc b/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc
index 56b75e7..815ba10 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmark_apitest.cc
@@ -28,7 +28,7 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile);
   ChromeBookmarkClient* client =
       ChromeBookmarkClientFactory::GetForProfile(profile);
-  test::WaitForBookmarkModelToLoad(model);
+  bookmarks::test::WaitForBookmarkModelToLoad(model);
 
   base::ListValue list;
   base::DictionaryValue* node = new base::DictionaryValue();
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
index 51d7b7f..e1fbce3 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.cc
@@ -12,7 +12,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/path_service.h"
 #include "base/prefs/pref_service.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/sha1.h"
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
@@ -99,14 +98,7 @@
     return true;
   }
 
-  bool success = RunOnReady();
-  if (success) {
-    content::NotificationService::current()->Notify(
-        extensions::NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED,
-        content::Source<const Extension>(extension()),
-        content::Details<const BookmarksFunction>(this));
-  }
-  SendResponse(success);
+  RunAndSendResponse();
   return true;
 }
 
@@ -230,10 +222,21 @@
 void BookmarksFunction::BookmarkModelLoaded(BookmarkModel* model,
                                             bool ids_reassigned) {
   model->RemoveObserver(this);
-  RunOnReady();
+  RunAndSendResponse();
   Release();  // Balanced in RunOnReady().
 }
 
+void BookmarksFunction::RunAndSendResponse() {
+  bool success = RunOnReady();
+  if (success) {
+    content::NotificationService::current()->Notify(
+      extensions::NOTIFICATION_EXTENSION_BOOKMARKS_API_INVOKED,
+      content::Source<const Extension>(extension()),
+      content::Details<const BookmarksFunction>(this));
+  }
+  SendResponse(success);
+}
+
 BookmarkEventRouter::BookmarkEventRouter(Profile* profile)
     : browser_context_(profile),
       model_(BookmarkModelFactory::GetForProfile(profile)),
@@ -397,10 +400,6 @@
 }
 
 void BookmarksAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("BookmarksAPI::OnListenerAdded"));
-
   bookmark_event_router_.reset(
       new BookmarkEventRouter(Profile::FromBrowserContext(browser_context_)));
   EventRouter::Get(browser_context_)->UnregisterObserver(this);
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
index e799c5b3..c24a65d 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
@@ -162,6 +162,8 @@
   // BaseBookmarkModelObserver:
   void BookmarkModelChanged() override;
   void BookmarkModelLoaded(BookmarkModel* model, bool ids_reassigned) override;
+
+  void RunAndSendResponse();
 };
 
 class BookmarksGetFunction : public BookmarksFunction {
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.cc b/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.cc
index f5d8e50..cd2e5d9 100644
--- a/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.cc
+++ b/chrome/browser/extensions/api/braille_display_private/braille_display_private_api.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/extensions/api/braille_display_private/braille_display_private_api.h"
 
 #include "base/lazy_instance.h"
-#include "base/profiler/scoped_profile.h"
 #include "chrome/browser/extensions/api/braille_display_private/braille_controller.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -104,11 +103,6 @@
 
 void BrailleDisplayPrivateAPI::OnListenerAdded(
     const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "BrailleDisplayPrivateAPI::OnListenerAdded"));
-
   BrailleController* braille_controller = BrailleController::GetInstance();
   if (!scoped_observer_.IsObserving(braille_controller))
     scoped_observer_.Add(braille_controller);
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.cc b/chrome/browser/extensions/api/cookies/cookies_api.cc
index d030557..d059071 100644
--- a/chrome/browser/extensions/api/cookies/cookies_api.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_api.cc
@@ -13,7 +13,6 @@
 #include "base/lazy_instance.h"
 #include "base/memory/linked_ptr.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/chrome_notification_types.h"
@@ -581,10 +580,6 @@
 
 void CookiesAPI::OnListenerAdded(
     const extensions::EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("CookiesAPI::OnListenerAdded"));
-
   cookies_event_router_.reset(new CookiesEventRouter(browser_context_));
   EventRouter::Get(browser_context_)->UnregisterObserver(this);
 }
diff --git a/chrome/browser/extensions/api/copresence/copresence_api.h b/chrome/browser/extensions/api/copresence/copresence_api.h
index 7960132..6cf87a9 100644
--- a/chrome/browser/extensions/api/copresence/copresence_api.h
+++ b/chrome/browser/extensions/api/copresence/copresence_api.h
@@ -17,6 +17,8 @@
 #include "components/copresence/public/copresence_delegate.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
 
+class ChromeWhispernetClient;
+
 namespace copresence {
 class CopresenceManager;
 class WhispernetClient;
@@ -74,7 +76,7 @@
   std::string api_key_;
 
   scoped_ptr<copresence::CopresenceManager> manager_;
-  scoped_ptr<copresence::WhispernetClient> whispernet_client_;
+  scoped_ptr<ChromeWhispernetClient> whispernet_client_;
 
   DISALLOW_COPY_AND_ASSIGN(CopresenceService);
 };
diff --git a/chrome/browser/extensions/api/copresence/copresence_api_unittest.cc b/chrome/browser/extensions/api/copresence/copresence_api_unittest.cc
index 4e1ffb9..2287361 100644
--- a/chrome/browser/extensions/api/copresence/copresence_api_unittest.cc
+++ b/chrome/browser/extensions/api/copresence/copresence_api_unittest.cc
@@ -12,7 +12,7 @@
 #include "components/copresence/public/copresence_manager.h"
 
 using base::ListValue;
-using copresence::AUDIBLE;
+using copresence::AUDIO_CONFIGURATION_AUDIBLE;
 using copresence::AUDIO_CONFIGURATION_UNKNOWN;
 using copresence::BROADCAST_ONLY;
 using copresence::CopresenceDelegate;
@@ -193,7 +193,7 @@
   copresence::BroadcastScanConfiguration broadcast_scan =
       subscription.token_exchange_strategy().broadcast_scan_configuration();
   EXPECT_EQ(BROADCAST_ONLY, broadcast_scan);
-  EXPECT_EQ(AUDIBLE,
+  EXPECT_EQ(AUDIO_CONFIGURATION_AUDIBLE,
             subscription.token_exchange_strategy().audio_configuration());
 }
 
diff --git a/chrome/browser/extensions/api/copresence/copresence_translations.cc b/chrome/browser/extensions/api/copresence/copresence_translations.cc
index 5fecde2..6eb38a9 100644
--- a/chrome/browser/extensions/api/copresence/copresence_translations.cc
+++ b/chrome/browser/extensions/api/copresence/copresence_translations.cc
@@ -9,7 +9,7 @@
 #include "components/copresence/proto/enums.pb.h"
 #include "components/copresence/proto/rpcs.pb.h"
 
-using copresence::AUDIBLE;
+using copresence::AUDIO_CONFIGURATION_AUDIBLE;
 using copresence::AUDIO_CONFIGURATION_UNKNOWN;
 using copresence::BROADCAST_AND_SCAN;
 using copresence::BROADCAST_ONLY;
@@ -57,8 +57,8 @@
         config == BROADCAST_SCAN_CONFIGURATION_UNKNOWN ?
         default_config : config);
     strategy_proto->set_audio_configuration(
-        strategy->audible && *strategy->audible ?
-        AUDIBLE : AUDIO_CONFIGURATION_UNKNOWN);
+        strategy->audible && *strategy->audible ? AUDIO_CONFIGURATION_AUDIBLE
+                                                : AUDIO_CONFIGURATION_UNKNOWN);
   } else {
     strategy_proto->set_broadcast_scan_configuration(default_config);
     strategy_proto->set_audio_configuration(AUDIO_CONFIGURATION_UNKNOWN);
diff --git a/chrome/browser/extensions/api/copresence_private/copresence_private_api.cc b/chrome/browser/extensions/api/copresence_private/copresence_private_api.cc
index b9aed0d..c7f7762 100644
--- a/chrome/browser/extensions/api/copresence_private/copresence_private_api.cc
+++ b/chrome/browser/extensions/api/copresence_private/copresence_private_api.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/copresence/chrome_whispernet_client.h"
 #include "chrome/browser/extensions/api/copresence/copresence_api.h"
 #include "chrome/common/extensions/api/copresence_private.h"
+#include "components/copresence/public/copresence_constants.h"
 #include "components/copresence/public/whispernet_client.h"
 #include "media/base/audio_bus.h"
 
@@ -63,7 +64,9 @@
          params->samples.size());
 
   GetWhispernetClient()->GetSamplesCallback().Run(
-      params->token.token, params->token.audible, samples);
+      params->token.token,
+      params->token.audible ? copresence::AUDIBLE : copresence::INAUDIBLE,
+      samples);
   return RespondNow(NoArguments());
 }
 
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index a3cfa67..de6e61b 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -13,7 +13,6 @@
 #include "base/files/file_util.h"
 #include "base/i18n/file_util_icu.h"
 #include "base/lazy_instance.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -311,10 +310,6 @@
 
 void DeveloperPrivateAPI::OnListenerAdded(
     const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("DeveloperPrivateAPI::OnListenerAdded"));
-
   if (!developer_private_event_router_) {
     developer_private_event_router_.reset(
         new DeveloperPrivateEventRouter(profile_));
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
index 1137332..e3e893a3 100644
--- a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
+++ b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc
@@ -8,7 +8,6 @@
 #include "base/memory/linked_ptr.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/local_discovery/cloud_device_list.h"
 #include "chrome/browser/local_discovery/cloud_print_printer_list.h"
@@ -275,10 +274,6 @@
 }
 
 void GcdPrivateAPIImpl::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("GcdPrivateAPIImpl::OnListenerAdded"));
-
   if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
       details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
     num_device_listeners_++;
diff --git a/chrome/browser/extensions/api/history/history_api.cc b/chrome/browser/extensions/api/history/history_api.cc
index 886d1a1..6b0659c 100644
--- a/chrome/browser/extensions/api/history/history_api.cc
+++ b/chrome/browser/extensions/api/history/history_api.cc
@@ -13,7 +13,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/prefs/pref_service.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/cancelable_task_tracker.h"
@@ -223,10 +222,6 @@
 }
 
 void HistoryAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("HistoryAPI::OnListenerAdded"));
-
   Profile* profile = Profile::FromBrowserContext(browser_context_);
   history_event_router_.reset(new HistoryEventRouter(
       profile,
diff --git a/chrome/browser/extensions/api/idle/idle_manager.cc b/chrome/browser/extensions/api/idle/idle_manager.cc
index c00bcc3..bd88cbc 100644
--- a/chrome/browser/extensions/api/idle/idle_manager.cc
+++ b/chrome/browser/extensions/api/idle/idle_manager.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "base/profiler/scoped_profile.h"
 #include "base/stl_util.h"
 #include "chrome/browser/extensions/api/idle/idle_api_constants.h"
 #include "chrome/browser/profiles/profile.h"
@@ -148,10 +147,6 @@
 }
 
 void IdleManager::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("IdleManager::OnListenerAdded"));
-
   DCHECK(thread_checker_.CalledOnValidThread());
 
   ++GetMonitor(details.extension_id)->listeners;
diff --git a/chrome/browser/extensions/api/image_writer_private/DEPS b/chrome/browser/extensions/api/image_writer_private/DEPS
new file mode 100644
index 0000000..911cdbe
--- /dev/null
+++ b/chrome/browser/extensions/api/image_writer_private/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+device/udev_linux",
+]
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
index 787fbdc..cd218b82ef 100644
--- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
+++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
@@ -8,13 +8,14 @@
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h"
 #include "content/public/browser/browser_thread.h"
+#include "device/udev_linux/scoped_udev.h"
 
 namespace extensions {
 // TODO(haven): Udev code may be duplicated in the Chrome codebase.
 // https://code.google.com/p/chromium/issues/detail?id=284898
 
 // Returns the integer contained in |attr|.  Returns 0 on error.
-static uint64 get_int_attr(const char* attr){
+static uint64 get_int_attr(const char* attr) {
   uint64 result = 0;
   // In error cases, StringToInt will set result to 0
   base::StringToUint64(attr, &result);
@@ -26,8 +27,8 @@
   std::string device = file_path.BaseName().value();
 
   base::FilePath info_file_path = base::FilePath("/sys/block")
-                                  .Append(device)
-                                  .Append("queue/logical_block_size");
+                                      .Append(device)
+                                      .Append("queue/logical_block_size");
 
   std::string file_contents;
   int blk_size;
@@ -43,35 +44,34 @@
 
 bool RemovableStorageProvider::PopulateDeviceList(
     scoped_refptr<StorageDeviceList> device_list) {
-  struct udev* udev;
-  struct udev_enumerate* enumerate;
-  struct udev_list_entry* devices, *dev_list_entry;
-  struct udev_device* dev, *parent;
-
-  udev = udev_new();
+  device::ScopedUdevPtr udev(udev_new());
   if (!udev) {
     DLOG(ERROR) << "Can't create udev";
     return false;
   }
 
   /* Create a list of the devices in the 'block' subsystem. */
-  enumerate = udev_enumerate_new(udev);
+  device::ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev.get()));
 
-  udev_enumerate_add_match_subsystem(enumerate, "block");
-  udev_enumerate_scan_devices(enumerate);
-  devices = udev_enumerate_get_list_entry(enumerate);
+  udev_enumerate_add_match_subsystem(enumerate.get(), "block");
+  udev_enumerate_scan_devices(enumerate.get());
+  udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate.get());
 
+  udev_list_entry* dev_list_entry;
   udev_list_entry_foreach(dev_list_entry, devices) {
     const char* path = udev_list_entry_get_name(dev_list_entry);
-    dev = udev_device_new_from_syspath(udev, path);
+    device::ScopedUdevDevicePtr cur_device(
+        udev_device_new_from_syspath(udev.get(), path));
 
-    const char* partition = udev_device_get_sysattr_value(dev, "partition");
-    if (partition && get_int_attr(partition)){
+    const char* partition =
+        udev_device_get_sysattr_value(cur_device.get(), "partition");
+    if (partition && get_int_attr(partition)) {
       // This is a partition of a device, not the device itself
       continue;
     }
 
-    const char* removable = udev_device_get_sysattr_value(dev, "removable");
+    const char* removable =
+        udev_device_get_sysattr_value(cur_device.get(), "removable");
     if (!removable || !get_int_attr(removable)) {
       // This is not a removable storage device.
       continue;
@@ -80,34 +80,29 @@
     /* Get the parent SCSI device that contains the model
        and manufacturer.  You can look at the hierarchy with
        udevadm info -a -n /dev/<device> */
-    parent = udev_device_get_parent_with_subsystem_devtype(
-           dev,
-           "scsi",
-           NULL);
-    if (!parent) {
+    udev_device* parent_device = udev_device_get_parent_with_subsystem_devtype(
+        cur_device.get(), "scsi", NULL);
+    if (!parent_device) {
       // this is not a usb device
       continue;
     }
 
-    linked_ptr<api::image_writer_private::RemovableStorageDevice> device(
-      new api::image_writer_private::RemovableStorageDevice());
-    device->vendor = udev_device_get_sysattr_value(parent, "vendor");
-    device->model = udev_device_get_sysattr_value(parent, "model");
+    linked_ptr<api::image_writer_private::RemovableStorageDevice> device_item(
+        new api::image_writer_private::RemovableStorageDevice());
+    device_item->vendor =
+        udev_device_get_sysattr_value(parent_device, "vendor");
+    device_item->model = udev_device_get_sysattr_value(parent_device, "model");
     // TODO (smaskell): Don't expose raw device path
-    device->storage_unit_id = udev_device_get_devnode(dev);
-    device->capacity = get_int_attr(udev_device_get_sysattr_value(dev, "size"))
-      * get_device_blk_size(device->storage_unit_id);
-    device->removable = removable;
+    device_item->storage_unit_id = udev_device_get_devnode(cur_device.get());
+    device_item->capacity =
+        get_int_attr(udev_device_get_sysattr_value(cur_device.get(), "size")) *
+        get_device_blk_size(device_item->storage_unit_id);
+    device_item->removable = removable;
 
-    device_list->data.push_back(device);
-
-    udev_device_unref(dev);
+    device_list->data.push_back(device_item);
   }
-  /* Free the enumerator object */
-  udev_enumerate_unref(enumerate);
-  udev_unref(udev);
 
   return true;
 }
 
-} // namespace extensions
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
index b1ea501..0d0dea34 100644
--- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc
+++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
 
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
@@ -136,6 +135,9 @@
     input_ime::InputContext context_value;
     context_value.context_id = context.id;
     context_value.type = input_ime::InputContext::ParseType(context.type);
+    context_value.auto_correct = context.auto_correct;
+    context_value.auto_complete = context.auto_complete;
+    context_value.spell_check = context.spell_check;
 
     scoped_ptr<base::ListValue> args(input_ime::OnFocus::Create(context_value));
 
@@ -852,10 +854,6 @@
 }
 
 void InputImeAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("InputImeAPI::OnListenerAdded"));
-
   InputMethodEngineInterface* engine =
       input_ime_event_router()->GetActiveEngine(details.extension_id);
   // Notifies the IME extension for IME ready with onActivate/onFocus events.
diff --git a/chrome/browser/extensions/api/management/management_api.cc b/chrome/browser/extensions/api/management/management_api.cc
index f13f883..1f6a8ce2 100644
--- a/chrome/browser/extensions/api/management/management_api.cc
+++ b/chrome/browser/extensions/api/management/management_api.cc
@@ -15,7 +15,6 @@
 #include "base/memory/linked_ptr.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/metrics/histogram.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -25,7 +24,6 @@
 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/launch_util.h"
-#include "chrome/browser/extensions/window_controller.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_dialogs.h"
@@ -621,10 +619,10 @@
   if (auto_confirm_for_test == DO_NOT_SKIP) {
     if (show_confirm_dialog) {
       AddRef();  // Balanced in ExtensionUninstallAccepted/Canceled
-      extensions::WindowController* controller = GetExtensionWindowController();
+      content::WebContents* web_contents = GetAssociatedWebContents();
       extension_uninstall_dialog_.reset(ExtensionUninstallDialog::Create(
           GetProfile(),
-          controller ? controller->window()->GetNativeWindow() : NULL,
+          web_contents ? web_contents->GetTopLevelNativeWindow() : NULL,
           this));
       if (extension_id() != target_extension_id) {
         extension_uninstall_dialog_->ConfirmProgrammaticUninstall(
@@ -1018,10 +1016,6 @@
 }
 
 void ManagementAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("ManagementAPI::OnListenerAdded"));
-
   management_event_router_.reset(new ManagementEventRouter(browser_context_));
   EventRouter::Get(browser_context_)->UnregisterObserver(this);
 }
diff --git a/chrome/browser/extensions/api/mdns/mdns_api.cc b/chrome/browser/extensions/api/mdns/mdns_api.cc
index 572ae1e..9bc7fb3f 100644
--- a/chrome/browser/extensions/api/mdns/mdns_api.cc
+++ b/chrome/browser/extensions/api/mdns/mdns_api.cc
@@ -7,7 +7,6 @@
 #include <vector>
 
 #include "base/lazy_instance.h"
-#include "base/profiler/scoped_profile.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/common/extensions/api/mdns.h"
 
@@ -70,10 +69,6 @@
 }
 
 void MDnsAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("MDnsAPI::OnListenerAdded"));
-
   DCHECK(thread_checker_.CalledOnValidThread());
   UpdateMDnsListeners(details);
 }
diff --git a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
index f3f0a81..3159d3bd 100644
--- a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
+++ b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.cc
@@ -10,7 +10,6 @@
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/prefs/pref_service.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/api/media_galleries_private/gallery_watch_manager.h"
@@ -116,11 +115,6 @@
 
 void MediaGalleriesPrivateAPI::OnListenerAdded(
     const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "MediaGalleriesPrivateAPI::OnListenerAdded"));
-
   // Make sure MediaGalleriesPreferences is initialized. After that,
   // try to initialize the event router for the listener.
   // This method is called synchronously with the message handler for the
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_event_router_nonchromeos.cc b/chrome/browser/extensions/api/networking_private/networking_private_event_router_nonchromeos.cc
index b774546..e9885dee 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_event_router_nonchromeos.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_event_router_nonchromeos.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/extensions/api/networking_private/networking_private_event_router.h"
 
-#include "base/profiler/scoped_profile.h"
 #include "chrome/browser/extensions/api/networking_private/networking_private_api.h"
 #include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h"
 #include "chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h"
@@ -88,11 +87,6 @@
 
 void NetworkingPrivateEventRouterImpl::OnListenerAdded(
     const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "NetworkingPrivateEventRouterImpl::OnListenerAdded"));
-
   // Start listening to events from the network state handler.
   StartOrStopListeningForNetworkChanges();
 }
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc
index 520f4fa..4d39671 100644
--- a/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc
@@ -9,7 +9,6 @@
 #include "base/lazy_instance.h"
 #include "base/prefs/pref_change_registrar.h"
 #include "base/prefs/pref_service.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/extensions/api/preference/preference_api_constants.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -94,11 +93,6 @@
 
 // EventRouter::Observer implementation.
 void ChromeDirectSettingAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "ChromeDirectSettingAPI::OnListenerAdded"));
-
   EventRouter::Get(profile_)->UnregisterObserver(this);
   registrar_.Init(profile_->GetPrefs());
   preference_whitelist.Get().RegisterPropertyListeners(
diff --git a/chrome/browser/extensions/api/preference/preference_api.cc b/chrome/browser/extensions/api/preference/preference_api.cc
index b5e6716..1c6a729 100644
--- a/chrome/browser/extensions/api/preference/preference_api.cc
+++ b/chrome/browser/extensions/api/preference/preference_api.cc
@@ -10,7 +10,6 @@
 #include "base/lazy_instance.h"
 #include "base/memory/singleton.h"
 #include "base/prefs/pref_service.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
@@ -450,10 +449,6 @@
 }
 
 void PreferenceAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("PreferenceAPI::OnListenerAdded"));
-
   preference_event_router_.reset(new PreferenceEventRouter(profile_));
   EventRouter::Get(profile_)->UnregisterObserver(this);
 }
diff --git a/chrome/browser/extensions/api/processes/processes_api.cc b/chrome/browser/extensions/api/processes/processes_api.cc
index cf4fd39..56a7cb7 100644
--- a/chrome/browser/extensions/api/processes/processes_api.cc
+++ b/chrome/browser/extensions/api/processes/processes_api.cc
@@ -9,7 +9,6 @@
 #include "base/lazy_instance.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -519,10 +518,6 @@
 }
 
 void ProcessesAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("ProcessesAPI::OnListenerAdded"));
-
   // We lazily tell the TaskManager to start updating when listeners to the
   // processes.onUpdated or processes.onUpdatedWithMemory events arrive.
   processes_event_router()->ListenerAdded();
diff --git a/chrome/browser/extensions/api/sessions/sessions_api.cc b/chrome/browser/extensions/api/sessions/sessions_api.cc
index 0342ed2..0b7a1a7 100644
--- a/chrome/browser/extensions/api/sessions/sessions_api.cc
+++ b/chrome/browser/extensions/api/sessions/sessions_api.cc
@@ -9,7 +9,6 @@
 #include "base/i18n/rtl.h"
 #include "base/lazy_instance.h"
 #include "base/prefs/pref_service.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -81,25 +80,29 @@
     const Extension* extension) {
   scoped_ptr<tabs::Tab> tab_struct(new tabs::Tab);
 
-  GURL gurl = current_navigation.virtual_url();
+  const GURL& url = current_navigation.virtual_url();
   std::string title = base::UTF16ToUTF8(current_navigation.title());
 
   tab_struct->session_id.reset(new std::string(session_id));
-  tab_struct->url.reset(new std::string(gurl.spec()));
+  tab_struct->url.reset(new std::string(url.spec()));
+  tab_struct->fav_icon_url.reset(
+      new std::string(current_navigation.favicon_url().spec()));
   if (!title.empty()) {
     tab_struct->title.reset(new std::string(title));
   } else {
     const std::string languages =
         profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
-    tab_struct->title.reset(new std::string(base::UTF16ToUTF8(
-        net::FormatUrl(gurl, languages))));
+    tab_struct->title.reset(
+        new std::string(base::UTF16ToUTF8(net::FormatUrl(url, languages))));
   }
   tab_struct->index = index;
   tab_struct->pinned = pinned;
-  tab_struct->selected = index == selected_index;
-  tab_struct->active = false;
-  tab_struct->highlighted = false;
-  tab_struct->incognito = false;
+  // Note: |selected_index| from the sync sessions model is what we call
+  // "active" in extensions terminology.  "selected" is deprecated because it's
+  // not clear whether it means "active" (user can see) or "highlighted" (user
+  // has highlighted, since you can select tabs without bringing them into the
+  // foreground).
+  tab_struct->active = index == selected_index;
   ExtensionTabUtil::ScrubTabForExtension(extension, tab_struct.get());
   return tab_struct.Pass();
 }
@@ -645,10 +648,6 @@
 }
 
 void SessionsAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("SessionsAPI::OnListenerAdded"));
-
   sessions_event_router_.reset(
       new SessionsEventRouter(Profile::FromBrowserContext(browser_context_)));
   EventRouter::Get(browser_context_)->UnregisterObserver(this);
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
index b505229..6182c14 100644
--- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc
+++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -37,9 +37,10 @@
 
 namespace {
 
-// If more sessions are added to session tags, num sessions should be updated.
+// Fake session tabs (used to construct arbitrary device info) and tab IDs
+// (used to construct arbitrary tab info) to use in all tests.
 const char* kSessionTags[] = {"tag0", "tag1", "tag2", "tag3", "tag4"};
-const size_t kNumSessions = 5;
+const SessionID::id_type kTabIDs[] = {5, 10, 13, 17};
 
 void BuildSessionSpecifics(const std::string& tag,
                            sync_pb::SessionSpecifics* meta) {
@@ -63,7 +64,8 @@
   }
 }
 
-void BuildTabSpecifics(const std::string& tag, int window_id, int tab_id,
+void BuildTabSpecifics(const std::string& tag,
+                       int tab_id,
                        sync_pb::SessionSpecifics* tab_base) {
   tab_base->set_session_tag(tag);
   tab_base->set_tab_node_id(0);
@@ -75,13 +77,12 @@
   tab->set_extension_app_id("app_id");
   sync_pb::TabNavigation* navigation = tab->add_navigation();
   navigation->set_virtual_url("http://foo/1");
-  navigation->set_referrer("referrer");
-  navigation->set_title("title");
+  navigation->set_favicon_url("http://foo/favicon.ico");
+  navigation->set_referrer("MyReferrer");
+  navigation->set_title("MyTitle");
   navigation->set_page_transition(sync_pb::SyncEnums_PageTransition_TYPED);
 }
 
-} // namespace
-
 class ExtensionSessionsTest : public InProcessBrowserTest {
  public:
   void SetUpCommandLine(CommandLine* command_line) override;
@@ -186,18 +187,16 @@
 
 void ExtensionSessionsTest::CreateSessionModels() {
   syncer::SyncDataList initial_data;
-  for (size_t index = 0; index < kNumSessions; ++index) {
+  for (size_t index = 0; index < arraysize(kSessionTags); ++index) {
     // Fill an instance of session specifics with a foreign session's data.
     sync_pb::SessionSpecifics meta;
     BuildSessionSpecifics(kSessionTags[index], &meta);
-    SessionID::id_type tab_nums1[] = {5, 10, 13, 17};
-    std::vector<SessionID::id_type> tab_list1(
-        tab_nums1, tab_nums1 + arraysize(tab_nums1));
-    BuildWindowSpecifics(index, tab_list1, &meta);
-    std::vector<sync_pb::SessionSpecifics> tabs1;
-    tabs1.resize(tab_list1.size());
-    for (size_t i = 0; i < tab_list1.size(); ++i) {
-      BuildTabSpecifics(kSessionTags[index], 0, tab_list1[i], &tabs1[i]);
+    std::vector<SessionID::id_type> tab_list(kTabIDs,
+                                             kTabIDs + arraysize(kTabIDs));
+    BuildWindowSpecifics(index, tab_list, &meta);
+    std::vector<sync_pb::SessionSpecifics> tabs(tab_list.size());
+    for (size_t i = 0; i < tab_list.size(); ++i) {
+      BuildTabSpecifics(kSessionTags[index], tab_list[i], &tabs[i]);
     }
 
     sync_pb::EntitySpecifics entity;
@@ -208,9 +207,9 @@
         base::Time(),
         syncer::AttachmentIdList(),
         syncer::AttachmentServiceProxyForTest::Create()));
-    for (size_t i = 0; i < tabs1.size(); i++) {
+    for (size_t i = 0; i < tabs.size(); i++) {
       sync_pb::EntitySpecifics entity;
-      entity.mutable_session()->CopyFrom(tabs1[i]);
+      entity.mutable_session()->CopyFrom(tabs[i]);
       initial_data.push_back(syncer::SyncData::CreateRemoteData(
           i + 2,
           entity,
@@ -229,48 +228,74 @@
           new syncer::SyncErrorFactoryMock()));
 }
 
+testing::AssertionResult CheckSessionModels(const base::ListValue& devices,
+                                            size_t num_sessions) {
+  EXPECT_EQ(5u, devices.GetSize());
+  const base::DictionaryValue* device = NULL;
+  const base::ListValue* sessions = NULL;
+  for (size_t i = 0; i < devices.GetSize(); ++i) {
+    EXPECT_TRUE(devices.GetDictionary(i, &device));
+    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "info"));
+    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "deviceName"));
+    EXPECT_TRUE(device->GetList("sessions", &sessions));
+    EXPECT_EQ(num_sessions, sessions->GetSize());
+    // Because this test is hurried, really there are only ever 0 or 1
+    // sessions, and if 1, that will be a Window. Grab it.
+    if (num_sessions == 0)
+      continue;
+    const base::DictionaryValue* session = NULL;
+    EXPECT_TRUE(sessions->GetDictionary(0, &session));
+    const base::DictionaryValue* window = NULL;
+    EXPECT_TRUE(session->GetDictionary("window", &window));
+    // Only the tabs are interesting.
+    const base::ListValue* tabs = NULL;
+    EXPECT_TRUE(window->GetList("tabs", &tabs));
+    EXPECT_EQ(arraysize(kTabIDs), tabs->GetSize());
+    for (size_t j = 0; j < tabs->GetSize(); ++j) {
+      const base::DictionaryValue* tab = NULL;
+      EXPECT_TRUE(tabs->GetDictionary(j, &tab));
+      EXPECT_FALSE(tab->HasKey("id"));  // sessions API does not give tab IDs
+      EXPECT_EQ(static_cast<int>(j), utils::GetInteger(tab, "index"));
+      EXPECT_EQ(0, utils::GetInteger(tab, "windowId"));
+      // Test setup code always sets tab 0 to selected (which means active in
+      // extension terminology).
+      EXPECT_EQ(j == 0, utils::GetBoolean(tab, "active"));
+      // While selected/highlighted are different to active, and should always
+      // be false.
+      EXPECT_FALSE(utils::GetBoolean(tab, "selected"));
+      EXPECT_FALSE(utils::GetBoolean(tab, "highlighted"));
+      EXPECT_FALSE(utils::GetBoolean(tab, "incognito"));
+      EXPECT_TRUE(utils::GetBoolean(tab, "pinned"));
+      EXPECT_EQ("http://foo/1", utils::GetString(tab, "url"));
+      EXPECT_EQ("MyTitle", utils::GetString(tab, "title"));
+      EXPECT_EQ("http://foo/favicon.ico", utils::GetString(tab, "favIconUrl"));
+      EXPECT_EQ(base::StringPrintf("%s.%d", kSessionTags[i], kTabIDs[j]),
+                utils::GetString(tab, "sessionId"));
+    }
+  }
+  return testing::AssertionSuccess();
+}
+
 IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevices) {
   CreateSessionModels();
-
   scoped_ptr<base::ListValue> result(utils::ToList(
       utils::RunFunctionAndReturnSingleResult(
           CreateFunction<SessionsGetDevicesFunction>(true).get(),
           "[{\"maxResults\": 0}]",
           browser_)));
   ASSERT_TRUE(result);
-  base::ListValue* devices = result.get();
-  EXPECT_EQ(5u, devices->GetSize());
-  base::DictionaryValue* device = NULL;
-  base::ListValue* sessions = NULL;
-  for (size_t i = 0; i < devices->GetSize(); ++i) {
-    EXPECT_TRUE(devices->GetDictionary(i, &device));
-    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "info"));
-    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "deviceName"));
-    EXPECT_TRUE(device->GetList("sessions", &sessions));
-    EXPECT_EQ(0u, sessions->GetSize());
-  }
+  EXPECT_TRUE(CheckSessionModels(*result, 0u));
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevicesMaxResults) {
   CreateSessionModels();
-
   scoped_ptr<base::ListValue> result(utils::ToList(
       utils::RunFunctionAndReturnSingleResult(
           CreateFunction<SessionsGetDevicesFunction>(true).get(),
           "[]",
           browser_)));
   ASSERT_TRUE(result);
-  base::ListValue* devices = result.get();
-  EXPECT_EQ(5u, devices->GetSize());
-  base::DictionaryValue* device = NULL;
-  base::ListValue* sessions = NULL;
-  for (size_t i = 0; i < devices->GetSize(); ++i) {
-    EXPECT_TRUE(devices->GetDictionary(i, &device));
-    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "info"));
-    EXPECT_EQ(kSessionTags[i], utils::GetString(device, "deviceName"));
-    EXPECT_TRUE(device->GetList("sessions", &sessions));
-    EXPECT_EQ(1u, sessions->GetSize());
-  }
+  EXPECT_TRUE(CheckSessionModels(*result, 1u));
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionSessionsTest, GetDevicesListEmpty) {
@@ -367,4 +392,6 @@
                                   "sessions.html")) << message_;
 }
 
+}  // namespace
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc
index b1945f4..0e8cc265 100644
--- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc
+++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc
@@ -11,7 +11,6 @@
 #include "base/memory/linked_ptr.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/values.h"
 #include "chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -118,11 +117,6 @@
 
 void SignedInDevicesManager::OnListenerAdded(
     const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "SignedInDevicesManager::OnListenerAdded"));
-
   for (ScopedVector<SignedInDevicesChangeObserver>::const_iterator it =
            change_observers_.begin();
            it != change_observers_.end();
diff --git a/chrome/browser/extensions/api/system_display/system_display_apitest.cc b/chrome/browser/extensions/api/system_display/system_display_apitest.cc
index b91648d..27716b26 100644
--- a/chrome/browser/extensions/api/system_display/system_display_apitest.cc
+++ b/chrome/browser/extensions/api/system_display/system_display_apitest.cc
@@ -73,7 +73,6 @@
 
  protected:
   // Overridden from gfx::Screen:
-  bool IsDIPEnabled() override { return true; }
   gfx::Point GetCursorScreenPoint() override { return gfx::Point(); }
   gfx::NativeWindow GetWindowUnderCursor() override {
     return gfx::NativeWindow();
diff --git a/chrome/browser/extensions/api/tabs/tabs_windows_api.cc b/chrome/browser/extensions/api/tabs/tabs_windows_api.cc
index 5f84141..641aad7 100644
--- a/chrome/browser/extensions/api/tabs/tabs_windows_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_windows_api.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
 
 #include "base/lazy_instance.h"
-#include "base/profiler/scoped_profile.h"
 #include "chrome/browser/extensions/api/tabs/tabs_event_router.h"
 #include "chrome/browser/extensions/api/tabs/windows_event_router.h"
 #include "chrome/browser/profiles/profile.h"
@@ -79,10 +78,6 @@
 }
 
 void TabsWindowsAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("TabsWindowsAPI::OnListenerAdded"));
-
   // Initialize the event routers.
   tabs_event_router();
   windows_event_router();
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
index 586dc32..24a4de3 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -7,7 +7,6 @@
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
 
 #include "base/lazy_instance.h"
-#include "base/profiler/scoped_profile.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_constants.h"
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h"
@@ -772,10 +771,6 @@
 }
 
 void WebNavigationAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("WebNavigationAPI::OnListenerAdded"));
-
   web_navigation_event_router_.reset(new WebNavigationEventRouter(
       Profile::FromBrowserContext(browser_context_)));
   EventRouter::Get(browser_context_)->UnregisterObserver(this);
diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc
index b92920c..142df57e 100644
--- a/chrome/browser/extensions/bookmark_app_helper.cc
+++ b/chrome/browser/extensions/bookmark_app_helper.cc
@@ -117,6 +117,22 @@
 namespace extensions {
 
 // static
+void BookmarkAppHelper::UpdateWebAppInfoFromManifest(
+    const content::Manifest& manifest,
+    WebApplicationInfo* web_app_info) {
+  if (!manifest.short_name.is_null())
+    web_app_info->title = manifest.short_name.string();
+
+  // Give the full length name priority.
+  if (!manifest.name.is_null())
+    web_app_info->title = manifest.name.string();
+
+  // Set the url based on the manifest value, if any.
+  if (manifest.start_url.is_valid())
+    web_app_info->app_url = manifest.start_url;
+}
+
+// static
 std::map<int, SkBitmap> BookmarkAppHelper::ConstrainBitmapsToSizes(
     const std::vector<SkBitmap>& bitmaps,
     const std::set<int>& sizes) {
@@ -170,7 +186,8 @@
 BookmarkAppHelper::BookmarkAppHelper(ExtensionService* service,
                                      WebApplicationInfo web_app_info,
                                      content::WebContents* contents)
-    : web_app_info_(web_app_info),
+    : contents_(contents),
+      web_app_info_(web_app_info),
       crx_installer_(extensions::CrxInstaller::CreateSilent(service)) {
   registrar_.Add(this,
                  extensions::NOTIFICATION_CRX_INSTALLER_DONE,
@@ -207,10 +224,22 @@
 void BookmarkAppHelper::Create(const CreateBookmarkAppCallback& callback) {
   callback_ = callback;
 
-  if (favicon_downloader_.get())
-    favicon_downloader_->Start();
-  else
+  if (contents_) {
+    contents_->GetManifest(base::Bind(&BookmarkAppHelper::OnDidGetManifest,
+                                     base::Unretained(this)));
+  } else {
     OnIconsDownloaded(true, std::map<GURL, std::vector<SkBitmap> >());
+  }
+}
+
+void BookmarkAppHelper::OnDidGetManifest(const content::Manifest& manifest) {
+  if (contents_->IsBeingDestroyed())
+    return;
+
+  UpdateWebAppInfoFromManifest(manifest, &web_app_info_);
+
+  DCHECK(favicon_downloader_.get());
+  favicon_downloader_->Start();
 }
 
 void BookmarkAppHelper::OnIconsDownloaded(
diff --git a/chrome/browser/extensions/bookmark_app_helper.h b/chrome/browser/extensions/bookmark_app_helper.h
index 08b8536..434def6 100644
--- a/chrome/browser/extensions/bookmark_app_helper.h
+++ b/chrome/browser/extensions/bookmark_app_helper.h
@@ -15,6 +15,7 @@
 #include "chrome/common/web_application_info.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
+#include "content/public/common/manifest.h"
 
 class ExtensionService;
 class FaviconDownloader;
@@ -44,6 +45,10 @@
                     content::WebContents* contents);
   ~BookmarkAppHelper() override;
 
+  // Update the given WebApplicationInfo with information from the manifest.
+  static void UpdateWebAppInfoFromManifest(const content::Manifest& manifest,
+                                           WebApplicationInfo* web_app_info);
+
   // This finds the closest not-smaller bitmap in |bitmaps| for each size in
   // |sizes| and resizes it to that size. This returns a map of sizes to bitmaps
   // which contains only bitmaps of a size in |sizes| and at most one bitmap of
@@ -66,6 +71,11 @@
  private:
   friend class TestBookmarkAppHelper;
 
+  // Called by the WebContents when the manifest has been downloaded. If there
+  // is no manifest, or the WebContents is destroyed before the manifest could
+  // be downloaded, this is called with an empty manifest.
+  void OnDidGetManifest(const content::Manifest& manifest);
+
   // Performs post icon download tasks including installing the bookmark app.
   void OnIconsDownloaded(bool success,
                          const std::map<GURL, std::vector<SkBitmap> >& bitmaps);
@@ -75,6 +85,9 @@
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override;
 
+  // The web contents that the bookmark app is being created for.
+  content::WebContents* contents_;
+
   // The WebApplicationInfo that the bookmark app is being created for.
   WebApplicationInfo web_app_info_;
 
diff --git a/chrome/browser/extensions/bookmark_app_helper_unittest.cc b/chrome/browser/extensions/bookmark_app_helper_unittest.cc
index f6ba05c..5d73ed7 100644
--- a/chrome/browser/extensions/bookmark_app_helper_unittest.cc
+++ b/chrome/browser/extensions/bookmark_app_helper_unittest.cc
@@ -23,7 +23,9 @@
 namespace {
 
 const char kAppUrl[] = "http://www.chromium.org";
+const char kAlternativeAppUrl[] = "http://www.notchromium.org";
 const char kAppTitle[] = "Test title";
+const char kAppShortName[] = "Test short name";
 const char kAlternativeAppTitle[] = "Different test title";
 const char kAppDescription[] = "Test description";
 
@@ -129,6 +131,10 @@
     extension_ = extension;
   }
 
+  void CompleteGetManifest(const content::Manifest& manifest) {
+    BookmarkAppHelper::OnDidGetManifest(manifest);
+  }
+
   void CompleteIconDownload(
       bool success,
       const std::map<GURL, std::vector<SkBitmap> >& bitmaps) {
@@ -175,6 +181,34 @@
           extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY).empty());
 }
 
+TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkAppWithManifest) {
+  WebApplicationInfo web_app_info;
+
+  scoped_ptr<content::WebContents> contents(
+      content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
+  TestBookmarkAppHelper helper(service_, web_app_info, contents.get());
+  helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
+                           base::Unretained(&helper)));
+
+  content::Manifest manifest;
+  manifest.start_url = GURL(kAppUrl);
+  manifest.name = base::NullableString16(base::UTF8ToUTF16(kAppTitle), false);
+  helper.CompleteGetManifest(manifest);
+
+  std::map<GURL, std::vector<SkBitmap> > icon_map;
+  helper.CompleteIconDownload(true, icon_map);
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(helper.extension());
+  const Extension* extension =
+      service_->GetInstalledExtension(helper.extension()->id());
+  EXPECT_TRUE(extension);
+  EXPECT_EQ(1u, service_->extensions()->size());
+  EXPECT_TRUE(extension->from_bookmark());
+  EXPECT_EQ(kAppTitle, extension->name());
+  EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
+}
+
 TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkAppNoContents) {
   WebApplicationInfo web_app_info;
   web_app_info.app_url = GURL(kAppUrl);
@@ -286,6 +320,26 @@
   run_loop.Run();
 }
 
+TEST_F(BookmarkAppHelperTest, UpdateWebAppInfoFromManifest) {
+  WebApplicationInfo web_app_info;
+  web_app_info.title = base::UTF8ToUTF16(kAlternativeAppTitle);
+  web_app_info.app_url = GURL(kAlternativeAppUrl);
+
+  content::Manifest manifest;
+  manifest.start_url = GURL(kAppUrl);
+  manifest.short_name = base::NullableString16(base::UTF8ToUTF16(kAppShortName),
+                                               false);
+
+  BookmarkAppHelper::UpdateWebAppInfoFromManifest(manifest, &web_app_info);
+  EXPECT_EQ(base::UTF8ToUTF16(kAppShortName), web_app_info.title);
+  EXPECT_EQ(GURL(kAppUrl), web_app_info.app_url);
+
+  // Test that |manifest.name| takes priority over |manifest.short_name|
+  manifest.name = base::NullableString16(base::UTF8ToUTF16(kAppTitle), false);
+  BookmarkAppHelper::UpdateWebAppInfoFromManifest(manifest, &web_app_info);
+  EXPECT_EQ(base::UTF8ToUTF16(kAppTitle), web_app_info.title);
+}
+
 TEST_F(BookmarkAppHelperTest, ConstrainBitmapsToSizes) {
   std::set<int> desired_sizes;
   desired_sizes.insert(16);
diff --git a/chrome/browser/extensions/browser_action_test_util.h b/chrome/browser/extensions/browser_action_test_util.h
index 784cd12..87ad497 100644
--- a/chrome/browser/extensions/browser_action_test_util.h
+++ b/chrome/browser/extensions/browser_action_test_util.h
@@ -29,9 +29,6 @@
   // Returns the number of browser action currently visible.
   int VisibleBrowserActions();
 
-  // Returns the ExtensionAction for the given index.
-  ExtensionAction* GetExtensionAction(int index);
-
   // Inspects the extension popup for the action at the given index.
   void InspectPopup(int index);
 
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 9402445..731c8ef 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -486,14 +486,8 @@
       Version version_required(i->minimum_version);
       const Extension* imported_module =
           service->GetExtensionById(i->extension_id, true);
-      if (!imported_module) {
-        ReportFailureFromUIThread(CrxInstallerError(l10n_util::GetStringFUTF16(
-            IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_FOUND,
-            base::ASCIIToUTF16(i->extension_id),
-            base::ASCIIToUTF16(i->minimum_version))));
-        return;
-      } else if (imported_module &&
-                 !SharedModuleInfo::IsSharedModule(imported_module)) {
+      if (imported_module &&
+          !SharedModuleInfo::IsSharedModule(imported_module)) {
         ReportFailureFromUIThread(CrxInstallerError(l10n_util::GetStringFUTF16(
             IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_SHARED_MODULE,
             base::UTF8ToUTF16(imported_module->name()))));
@@ -508,8 +502,8 @@
             base::ASCIIToUTF16(imported_module->version()->GetString()))));
         return;
       } else if (imported_module &&
-          !SharedModuleInfo::IsExportAllowedByWhitelist(imported_module,
-                                                        extension()->id())) {
+                 !SharedModuleInfo::IsExportAllowedByWhitelist(
+                     imported_module, extension()->id())) {
         ReportFailureFromUIThread(CrxInstallerError(l10n_util::GetStringFUTF16(
             IDS_EXTENSION_INSTALL_DEPENDENCY_NOT_WHITELISTED,
             base::UTF8ToUTF16(extension()->name()),
diff --git a/chrome/browser/extensions/extension_function_test_utils.cc b/chrome/browser/extensions/extension_function_test_utils.cc
index dbc5863..b05098e 100644
--- a/chrome/browser/extensions/extension_function_test_utils.cc
+++ b/chrome/browser/extensions/extension_function_test_utils.cc
@@ -67,21 +67,22 @@
   return dict;
 }
 
-bool GetBoolean(base::DictionaryValue* val, const std::string& key) {
+bool GetBoolean(const base::DictionaryValue* val, const std::string& key) {
   bool result = false;
   if (!val->GetBoolean(key, &result))
       ADD_FAILURE() << key << " does not exist or is not a boolean.";
   return result;
 }
 
-int GetInteger(base::DictionaryValue* val, const std::string& key) {
+int GetInteger(const base::DictionaryValue* val, const std::string& key) {
   int result = 0;
   if (!val->GetInteger(key, &result))
     ADD_FAILURE() << key << " does not exist or is not an integer.";
   return result;
 }
 
-std::string GetString(base::DictionaryValue* val, const std::string& key) {
+std::string GetString(const base::DictionaryValue* val,
+                      const std::string& key) {
   std::string result;
   if (!val->GetString(key, &result))
     ADD_FAILURE() << key << " does not exist or is not a string.";
diff --git a/chrome/browser/extensions/extension_function_test_utils.h b/chrome/browser/extensions/extension_function_test_utils.h
index b86b0a5..aa340e4 100644
--- a/chrome/browser/extensions/extension_function_test_utils.h
+++ b/chrome/browser/extensions/extension_function_test_utils.h
@@ -38,9 +38,9 @@
 // Get |key| from |val| as the specified type. If |key| does not exist, or is
 // not of the specified type, adds a failure to the current test and returns
 // false, 0, empty string, etc.
-bool GetBoolean(base::DictionaryValue* val, const std::string& key);
-int GetInteger(base::DictionaryValue* val, const std::string& key);
-std::string GetString(base::DictionaryValue* val, const std::string& key);
+bool GetBoolean(const base::DictionaryValue* val, const std::string& key);
+int GetInteger(const base::DictionaryValue* val, const std::string& key);
+std::string GetString(const base::DictionaryValue* val, const std::string& key);
 
 // If |val| is a dictionary, return it as one, otherwise NULL.
 base::DictionaryValue* ToDictionary(base::Value* val);
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc
index 24bd6a0..d692d9e 100644
--- a/chrome/browser/extensions/extension_install_prompt.cc
+++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -614,17 +614,16 @@
 }
 
 ExtensionInstallPrompt::ShowParams::ShowParams(content::WebContents* contents)
-    : parent_web_contents(contents),
-      parent_window(NativeWindowForWebContents(contents)),
-      navigator(contents) {
+    : profile(ProfileForWebContents(contents)),
+      parent_web_contents(contents),
+      parent_window(NativeWindowForWebContents(contents)) {
 }
 
-ExtensionInstallPrompt::ShowParams::ShowParams(
-    gfx::NativeWindow window,
-    content::PageNavigator* navigator)
-    : parent_web_contents(NULL),
-      parent_window(window),
-      navigator(navigator) {
+ExtensionInstallPrompt::ShowParams::ShowParams(Profile* profile,
+                                               gfx::NativeWindow window)
+    : profile(profile),
+      parent_web_contents(NULL),
+      parent_window(window) {
 }
 
 // static
@@ -669,16 +668,14 @@
       delegate_(NULL) {
 }
 
-ExtensionInstallPrompt::ExtensionInstallPrompt(
-    Profile* profile,
-    gfx::NativeWindow native_window,
-    content::PageNavigator* navigator)
+ExtensionInstallPrompt::ExtensionInstallPrompt(Profile* profile,
+                                               gfx::NativeWindow native_window)
     : profile_(profile),
       ui_loop_(base::MessageLoop::current()),
       extension_(NULL),
       bundle_(NULL),
       install_ui_(extensions::CreateExtensionInstallUI(profile)),
-      show_params_(native_window, navigator),
+      show_params_(profile, native_window),
       delegate_(NULL) {
 }
 
diff --git a/chrome/browser/extensions/extension_install_prompt.h b/chrome/browser/extensions/extension_install_prompt.h
index c50216f..dca96db 100644
--- a/chrome/browser/extensions/extension_install_prompt.h
+++ b/chrome/browser/extensions/extension_install_prompt.h
@@ -30,7 +30,6 @@
 }  // namespace base
 
 namespace content {
-class PageNavigator;
 class WebContents;
 }
 
@@ -282,18 +281,18 @@
 
   // Parameters to show a prompt dialog. Two sets of the
   // parameters are supported: either use a parent WebContents or use a
-  // parent NativeWindow + a PageNavigator.
+  // parent NativeWindow + a Profile.
   struct ShowParams {
     explicit ShowParams(content::WebContents* contents);
-    ShowParams(gfx::NativeWindow window, content::PageNavigator* navigator);
+    ShowParams(Profile* profile, gfx::NativeWindow window);
+
+    Profile* profile;
 
     // Parent web contents of the install UI dialog. This can be NULL.
     content::WebContents* parent_web_contents;
 
-    // NativeWindow parent and navigator. If initialized using a parent web
-    // contents, these are derived from it.
+    // NativeWindow parent.
     gfx::NativeWindow parent_window;
-    content::PageNavigator* navigator;
   };
 
   typedef base::Callback<void(const ExtensionInstallPrompt::ShowParams&,
@@ -318,10 +317,10 @@
   // Creates a prompt with a parent web content.
   explicit ExtensionInstallPrompt(content::WebContents* contents);
 
-  // Creates a prompt with a profile, a native window and a page navigator.
-  ExtensionInstallPrompt(Profile* profile,
-                         gfx::NativeWindow native_window,
-                         content::PageNavigator* navigator);
+  // Creates a prompt with a profile and a native window. The most recently
+  // active browser window (or a new browser window if there are no browser
+  // windows) is used if a new tab needs to be opened.
+  ExtensionInstallPrompt(Profile* profile, gfx::NativeWindow native_window);
 
   virtual ~ExtensionInstallPrompt();
 
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index deb7e58..2d0b391 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -1896,6 +1896,7 @@
 
 void ExtensionService::RegisterContentSettings(
     HostContentSettingsMap* host_content_settings_map) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   host_content_settings_map->RegisterProvider(
       HostContentSettingsMap::INTERNAL_EXTENSION_PROVIDER,
       scoped_ptr<content_settings::ObservableProvider>(
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc
index ac47329..c8e110d 100644
--- a/chrome/browser/extensions/extension_toolbar_model.cc
+++ b/chrome/browser/extensions/extension_toolbar_model.cc
@@ -80,19 +80,21 @@
   observers_.RemoveObserver(observer);
 }
 
-void ExtensionToolbarModel::MoveExtensionIcon(const Extension* extension,
+void ExtensionToolbarModel::MoveExtensionIcon(const std::string& id,
                                               size_t index) {
-  ExtensionList::iterator pos = std::find(toolbar_items_.begin(),
-      toolbar_items_.end(), extension);
+  ExtensionList::iterator pos = toolbar_items_.begin();
+  while (pos != toolbar_items_.end() && (*pos)->id() != id)
+    ++pos;
   if (pos == toolbar_items_.end()) {
     NOTREACHED();
     return;
   }
+  scoped_refptr<const Extension> extension = *pos;
   toolbar_items_.erase(pos);
 
   ExtensionIdList::iterator pos_id = std::find(last_known_positions_.begin(),
                                                last_known_positions_.end(),
-                                               extension->id());
+                                               id);
   if (pos_id != last_known_positions_.end())
     last_known_positions_.erase(pos_id);
 
@@ -104,19 +106,19 @@
     last_known_positions_.insert(std::find(last_known_positions_.begin(),
                                            last_known_positions_.end(),
                                            (*iter)->id()),
-                                 extension->id());
+                                 id);
     toolbar_items_.insert(iter, extension);
   } else {
     // Otherwise, put |extension| at the end.
     DCHECK_EQ(toolbar_items_.size(), index);
     index = toolbar_items_.size();
-    toolbar_items_.push_back(make_scoped_refptr(extension));
-    last_known_positions_.push_back(extension->id());
+    toolbar_items_.push_back(extension);
+    last_known_positions_.push_back(id);
   }
 
   FOR_EACH_OBSERVER(
-      Observer, observers_, ToolbarExtensionMoved(extension, index));
-  MaybeUpdateVisibilityPref(extension, index);
+      Observer, observers_, ToolbarExtensionMoved(extension.get(), index));
+  MaybeUpdateVisibilityPref(extension.get(), index);
   UpdatePrefs();
 }
 
@@ -228,7 +230,7 @@
       new_index = new_size;
     }
     SetVisibleIconCount(new_size);
-    MoveExtensionIcon(extension, new_index);
+    MoveExtensionIcon(extension->id(), new_index);
   } else {  // Don't include all extensions.
     if (visible)
       AddExtension(extension);
@@ -602,7 +604,7 @@
          extension != toolbar_items_.end(); ++extension) {
       if ((*extension)->id() == (*it)) {
         if (extension - toolbar_items_.begin() >= visible_icon_count_)
-          MoveExtensionIcon(extension->get(), 0);
+          MoveExtensionIcon((*extension)->id(), 0);
         break;
       }
     }
diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h
index 17a76a4..950366e7 100644
--- a/chrome/browser/extensions/extension_toolbar_model.h
+++ b/chrome/browser/extensions/extension_toolbar_model.h
@@ -93,7 +93,7 @@
   void RemoveObserver(Observer* observer);
 
   // Moves the given |extension|'s icon to the given |index|.
-  void MoveExtensionIcon(const Extension* extension, size_t index);
+  void MoveExtensionIcon(const std::string& id, size_t index);
 
   // Sets the number of extension icons that should be visible.
   // If count == size(), this will set the visible icon count to -1, meaning
diff --git a/chrome/browser/extensions/extension_toolbar_model_unittest.cc b/chrome/browser/extensions/extension_toolbar_model_unittest.cc
index ff9d791b..e1d1c69e 100644
--- a/chrome/browser/extensions/extension_toolbar_model_unittest.cc
+++ b/chrome/browser/extensions/extension_toolbar_model_unittest.cc
@@ -326,7 +326,7 @@
   EXPECT_EQ(extension2.get(), GetExtensionAtIndex(0u));
 
   // Should be a no-op, but still fires the events.
-  toolbar_model()->MoveExtensionIcon(extension2.get(), 0);
+  toolbar_model()->MoveExtensionIcon(extension2->id(), 0);
   EXPECT_EQ(1u, observer()->moved_count());
   EXPECT_EQ(1u, num_toolbar_items());
   EXPECT_EQ(extension2.get(), GetExtensionAtIndex(0u));
@@ -352,7 +352,7 @@
   EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
 
   // Order is now A, B, C. Let's put C first.
-  toolbar_model()->MoveExtensionIcon(browser_action_c(), 0);
+  toolbar_model()->MoveExtensionIcon(browser_action_c()->id(), 0);
   EXPECT_EQ(1u, observer()->moved_count());
   EXPECT_EQ(3u, num_toolbar_items());
   EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
@@ -360,7 +360,7 @@
   EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(2u));
 
   // Order is now C, A, B. Let's put A last.
-  toolbar_model()->MoveExtensionIcon(browser_action_a(), 2);
+  toolbar_model()->MoveExtensionIcon(browser_action_a()->id(), 2);
   EXPECT_EQ(2u, observer()->moved_count());
   EXPECT_EQ(3u, num_toolbar_items());
   EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
@@ -389,13 +389,13 @@
   EXPECT_EQ(2u, num_toolbar_items());
 
   // Order is now C, A. Flip it.
-  toolbar_model()->MoveExtensionIcon(browser_action_a(), 0);
+  toolbar_model()->MoveExtensionIcon(browser_action_a()->id(), 0);
   EXPECT_EQ(3u, observer()->moved_count());
   EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
   EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
 
   // Move A to the location it already occupies.
-  toolbar_model()->MoveExtensionIcon(browser_action_a(), 0);
+  toolbar_model()->MoveExtensionIcon(browser_action_a()->id(), 0);
   EXPECT_EQ(4u, observer()->moved_count());
   EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
   EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
@@ -465,7 +465,7 @@
   EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
 
   // Move browser_action_b() to be first.
-  toolbar_model()->MoveExtensionIcon(browser_action_b(), 0);
+  toolbar_model()->MoveExtensionIcon(browser_action_b()->id(), 0);
   EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(0u));
 
   // Uninstall Extension B.
@@ -783,7 +783,7 @@
   extension_prefs->SetIsIncognitoEnabled(browser_action_c()->id(), true);
 
   // Move C to the second index.
-  toolbar_model()->MoveExtensionIcon(browser_action_c(), 1u);
+  toolbar_model()->MoveExtensionIcon(browser_action_c()->id(), 1u);
   // Set visible count to 2 so that c is overflowed. State is A C [B].
   toolbar_model()->SetVisibleIconCount(2);
   EXPECT_EQ(1u, observer()->moved_count());
@@ -819,7 +819,7 @@
 
   // Moving icons in the incognito toolbar should not affect the regular
   // toolbar. Incognito currently has C B...
-  incognito_model->MoveExtensionIcon(browser_action_b(), 0u);
+  incognito_model->MoveExtensionIcon(browser_action_b()->id(), 0u);
   // So now it should be B C...
   EXPECT_EQ(1u, incognito_observer.moved_count());
   EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(0u, incognito_model));
@@ -835,7 +835,7 @@
 
   // And performing moves on the regular model should have no effect on the
   // incognito model or its observers.
-  toolbar_model()->MoveExtensionIcon(browser_action_c(), 2u);
+  toolbar_model()->MoveExtensionIcon(browser_action_c()->id(), 2u);
   EXPECT_EQ(2u, observer()->moved_count());
   EXPECT_EQ(1u, incognito_observer.moved_count());
 }
diff --git a/chrome/browser/extensions/external_install_error.cc b/chrome/browser/extensions/external_install_error.cc
index 73ce2e8..2cb0d06 100644
--- a/chrome/browser/extensions/external_install_error.cc
+++ b/chrome/browser/extensions/external_install_error.cc
@@ -366,8 +366,7 @@
   // to pass ones which may be invalidated.
   install_ui_.reset(
       new ExtensionInstallPrompt(Profile::FromBrowserContext(browser_context_),
-                                 NULL,    // NULL native window.
-                                 NULL));  // NULL navigator.
+                                 NULL));  // NULL native window.
 
   install_ui_->ConfirmExternalInstall(
       this,
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc
index bd9af90..509db41 100644
--- a/chrome/browser/extensions/lazy_background_page_apitest.cc
+++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -11,13 +11,13 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/lazy_background_page_test_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/location_bar/location_bar.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/browser/bookmark_utils.h"
 #include "components/bookmarks/test/bookmark_test_helpers.h"
@@ -385,7 +385,7 @@
                            page2_complete(incognito_browser->profile());
     BookmarkModel* bookmark_model =
         BookmarkModelFactory::GetForProfile(browser()->profile());
-    test::WaitForBookmarkModelToLoad(bookmark_model);
+    bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
     const BookmarkNode* parent = bookmark_model->bookmark_bar_node();
     bookmark_model->AddURL(
         parent, 0, base::ASCIIToUTF16("Title"), GURL("about:blank"));
@@ -503,7 +503,7 @@
   // Send an event by making a bookmark.
   BookmarkModel* bookmark_model =
       BookmarkModelFactory::GetForProfile(browser()->profile());
-  test::WaitForBookmarkModelToLoad(bookmark_model);
+  bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
   bookmarks::AddIfNotBookmarked(bookmark_model,
                                 GURL("http://www.google.com"),
                                 base::UTF8ToUTF16("Google"));
diff --git a/chrome/browser/extensions/standard_management_policy_provider.cc b/chrome/browser/extensions/standard_management_policy_provider.cc
index 02ac085..b99fe65 100644
--- a/chrome/browser/extensions/standard_management_policy_provider.cc
+++ b/chrome/browser/extensions/standard_management_policy_provider.cc
@@ -76,6 +76,12 @@
   if (Manifest::IsComponentLocation(extension->location()))
     return true;
 
+  // Shared modules are always allowed too: they only contain resources that
+  // are used by other extensions. The extension that depends on the shared
+  // module may be filtered by policy.
+  if (extension->is_shared_module())
+    return true;
+
   ExtensionManagement::InstallationMode installation_mode =
       settings_->GetInstallationMode(extension->id());
 
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc
index 4b0417d..38a08c4 100644
--- a/chrome/browser/extensions/tab_helper.cc
+++ b/chrome/browser/extensions/tab_helper.cc
@@ -119,6 +119,9 @@
 
 void TabHelper::CreateApplicationShortcuts() {
   DCHECK(CanCreateApplicationShortcuts());
+  if (pending_web_app_action_ != NONE)
+    return;
+
   // Start fetching web app info for CreateApplicationShortcut dialog and show
   // the dialog when the data is available in OnDidGetApplicationInfo.
   GetApplicationInfo(CREATE_SHORTCUT);
@@ -126,6 +129,9 @@
 
 void TabHelper::CreateHostedAppFromWebContents() {
   DCHECK(CanCreateBookmarkApp());
+  if (pending_web_app_action_ != NONE)
+    return;
+
   // Start fetching web app info for CreateApplicationShortcut dialog and show
   // the dialog when the data is available in OnDidGetApplicationInfo.
   GetApplicationInfo(CREATE_HOSTED_APP);
@@ -135,8 +141,7 @@
 #if defined(OS_MACOSX)
   return false;
 #else
-  return web_app::IsValidUrl(web_contents()->GetURL()) &&
-      pending_web_app_action_ == NONE;
+  return web_app::IsValidUrl(web_contents()->GetURL());
 #endif
 }
 
@@ -144,8 +149,7 @@
 #if defined(OS_MACOSX)
   return false;
 #else
-  return IsValidBookmarkAppUrl(web_contents()->GetURL()) &&
-         pending_web_app_action_ == NONE;
+  return IsValidBookmarkAppUrl(web_contents()->GetURL());
 #endif
 }
 
diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc
index 0c72346e..11a54870 100644
--- a/chrome/browser/extensions/unpacked_installer.cc
+++ b/chrome/browser/extensions/unpacked_installer.cc
@@ -72,7 +72,7 @@
   scoped_ptr<extensions::ExtensionInstallUI> ui(
       extensions::CreateExtensionInstallUI(profile));
   install_ui_.reset(new ExtensionInstallPrompt(
-      profile, ui->GetDefaultInstallDialogParent(), NULL));
+      profile, ui->GetDefaultInstallDialogParent()));
 }
 
 SimpleExtensionLoadPrompt::~SimpleExtensionLoadPrompt() {
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc
index db09bc09..4625fd19 100644
--- a/chrome/browser/extensions/updater/extension_updater.cc
+++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -614,6 +614,8 @@
   ping_data->rollcall_days = CalculatePingDays(
       extension_prefs_->LastPingDay(id));
   ping_data->is_enabled = service_->IsExtensionEnabled(id);
+  if (!ping_data->is_enabled)
+    ping_data->disable_reasons = extension_prefs_->GetDisableReasons(id);
   ping_data->active_days =
       CalculateActivePingDays(extension_prefs_->LastActivePingDay(id),
                               extension_prefs_->GetActiveBit(id));
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index 29c4b1b3..04b4d973 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -135,7 +135,10 @@
 const char kFakeOAuth2Token[] = "ce n'est pas un jeton";
 
 const ManifestFetchData::PingData kNeverPingedData(
-    ManifestFetchData::kNeverPinged, ManifestFetchData::kNeverPinged, true);
+    ManifestFetchData::kNeverPinged,
+    ManifestFetchData::kNeverPinged,
+    true,
+    0);
 
 class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
  public:
@@ -289,8 +292,8 @@
   explicit MockService(TestExtensionPrefs* prefs)
       : prefs_(prefs),
         pending_extension_manager_(&profile_),
-        downloader_delegate_override_(NULL) {
-  }
+        downloader_delegate_override_(NULL),
+        enable_metrics_(false) {}
 
   ~MockService() override {}
 
@@ -314,6 +317,10 @@
     return fake_token_service_.get();
   }
 
+  // Controls whether metrics (enable/disabled state, etc.) are sent in the
+  // autoupdate ping requests.
+  void set_enable_metrics(bool enable) { enable_metrics_ = enable; }
+
   // Creates test extensions and inserts them into list. The name and
   // version are all based on their index. If |update_url| is non-null, it
   // will be used as the update_url for each extension.
@@ -359,10 +366,14 @@
  private:
   scoped_ptr<ExtensionDownloader> CreateExtensionDownloader(
       ExtensionDownloaderDelegate* delegate) {
-    return ChromeExtensionDownloaderFactory::CreateForRequestContext(
-        request_context(),
-        downloader_delegate_override_ ? downloader_delegate_override_
-                                      : delegate);
+    scoped_ptr<ExtensionDownloader> downloader =
+        ChromeExtensionDownloaderFactory::CreateForRequestContext(
+            request_context(),
+            downloader_delegate_override_ ? downloader_delegate_override_
+                                          : delegate);
+    if (enable_metrics_)
+      downloader->set_enable_extra_update_metrics(true);
+    return downloader.Pass();
   }
 
   scoped_ptr<ExtensionDownloader> CreateExtensionDownloaderWithIdentity(
@@ -384,6 +395,8 @@
 
   ExtensionDownloaderDelegate* downloader_delegate_override_;
 
+  bool enable_metrics_;
+
   DISALLOW_COPY_AND_ASSIGN(MockService);
 };
 
@@ -560,6 +573,50 @@
   }
 }
 
+// Helper function to extract the ping data param values for each extension in
+// a manifest fetch url, returned in a map keyed by extension id.
+// E.g. for "x=id%3Dabcdef%26ping%3Ddr%253D1%2526dr%253D1024" we'd return
+// {"abcdef": {"dr": set("1", "1024")}}
+typedef std::map<std::string, std::set<std::string>> ParamsMap;
+static std::map<std::string, ParamsMap> GetPingDataFromURL(
+    const GURL& manifest_url) {
+  std::map<std::string, ParamsMap> result;
+
+  base::StringPairs toplevel_params;
+  base::SplitStringIntoKeyValuePairs(
+      manifest_url.query(), '=', '&', &toplevel_params);
+  for (const auto& param : toplevel_params) {
+    if (param.first != "x")
+      continue;
+
+    // We've found "x=<something>", now unescape <something> and look for
+    // the "id=<id>&ping=<ping_value>" parameters within.
+    std::string unescaped = net::UnescapeURLComponent(
+        param.second, net::UnescapeRule::URL_SPECIAL_CHARS);
+    base::StringPairs extension_params;
+    base::SplitStringIntoKeyValuePairs(unescaped, '=', '&', &extension_params);
+    std::multimap<std::string, std::string> param_map;
+    param_map.insert(extension_params.begin(), extension_params.end());
+    if (ContainsKey(param_map, "id") && ContainsKey(param_map, "ping")) {
+      std::string id = param_map.find("id")->second;
+      result[id] = ParamsMap();
+
+      // Pull the key=value pairs out of the ping parameter for this id and
+      // put into the result.
+      std::string ping = net::UnescapeURLComponent(
+          param_map.find("ping")->second, net::UnescapeRule::URL_SPECIAL_CHARS);
+      base::StringPairs ping_params;
+      base::SplitStringIntoKeyValuePairs(ping, '=', '&', &ping_params);
+      for (const auto& ping_param : ping_params) {
+        if (!ContainsKey(result[id], ping_param.first))
+          result[id][ping_param.first] = std::set<std::string>();
+        result[id][ping_param.first].insert(ping_param.second);
+      }
+    }
+  }
+  return result;
+}
+
 static void VerifyQueryAndExtractParameters(
     const std::string& query,
     std::map<std::string, std::string>* result) {
@@ -890,7 +947,7 @@
     scoped_ptr<ManifestFetchData> fetch2(CreateManifestFetchData(kUpdateUrl));
     scoped_ptr<ManifestFetchData> fetch3(CreateManifestFetchData(kUpdateUrl));
     scoped_ptr<ManifestFetchData> fetch4(CreateManifestFetchData(kUpdateUrl));
-    ManifestFetchData::PingData zeroDays(0, 0, true);
+    ManifestFetchData::PingData zeroDays(0, 0, true, 0);
     fetch1->AddExtension(
         "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
     fetch2->AddExtension(
@@ -1027,7 +1084,7 @@
     GURL kUpdateUrl("http://localhost/manifest1");
 
     scoped_ptr<ManifestFetchData> fetch(CreateManifestFetchData(kUpdateUrl));
-    ManifestFetchData::PingData zeroDays(0, 0, true);
+    ManifestFetchData::PingData zeroDays(0, 0, true, 0);
     fetch->AddExtension(
         "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
 
@@ -1703,7 +1760,7 @@
                              service.pref_service(),
                              service.profile(),
                              kUpdateFrequencySecs,
-                             NULL,
+                             nullptr,
                              service.GetDownloaderFactory());
     updater.Start();
     updater.EnsureDownloaderCreated();
@@ -1728,6 +1785,126 @@
     EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
   }
 
+  // This lets us run a test with some enabled and some disabled
+  // extensions. The |num_enabled| value specifies how many enabled extensions
+  // to have, and |disabled| is a vector of DisableReason bitmasks for each
+  // disabled extension we want. |enable_metrics| specifies whether we should
+  // have enabled/disable reason information in the ping parameter.
+  void TestPingMetrics(bool enable_metrics,
+                       int num_enabled,
+                       const std::vector<int>& disabled) {
+    ServiceForManifestTests service(prefs_.get());
+    service.set_enable_metrics(enable_metrics);
+
+    ExtensionList enabled_extensions;
+    ExtensionList disabled_extensions;
+
+    std::string update_url = extension_urls::GetWebstoreUpdateUrl().spec();
+    if (num_enabled > 0)
+      service.CreateTestExtensions(
+          1, num_enabled, &enabled_extensions, &update_url, Manifest::INTERNAL);
+    if (disabled.size() > 0)
+      service.CreateTestExtensions(2,
+                                   disabled.size(),
+                                   &disabled_extensions,
+                                   &update_url,
+                                   Manifest::INTERNAL);
+
+    service.set_extensions(enabled_extensions, disabled_extensions);
+
+    ExtensionPrefs* prefs = prefs_->prefs();
+
+    for (size_t i = 0; i < disabled.size(); i++) {
+      int reasons = disabled[i];
+      const std::string& id = disabled_extensions[i]->id();
+      // Iterate over the DisableReason values, marking that reason in prefs
+      // for this id if it is set.
+      for (int reason = 1; reason < Extension::DISABLE_REASON_LAST;
+           reason <<= 1) {
+        if (reasons & reason)
+          prefs->AddDisableReason(
+              id, static_cast<Extension::DisableReason>(reason));
+      }
+    }
+
+    // Create the extension updater, make it issue an update, and capture the
+    // URL that it tried to fetch.
+    net::TestURLFetcherFactory factory;
+    ExtensionUpdater updater(&service,
+                             service.extension_prefs(),
+                             service.pref_service(),
+                             service.profile(),
+                             kUpdateFrequencySecs,
+                             nullptr,
+                             service.GetDownloaderFactory());
+    updater.Start();
+    SimulateTimerFired(&updater);
+    net::TestURLFetcher* fetcher =
+        factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
+    ASSERT_NE(nullptr, fetcher);
+    const GURL& url = fetcher->GetOriginalURL();
+    EXPECT_FALSE(url.is_empty());
+    EXPECT_TRUE(url.is_valid());
+    EXPECT_TRUE(url.has_query());
+
+    std::map<std::string, ParamsMap> all_pings = GetPingDataFromURL(url);
+
+    // Make sure that all the enabled extensions have "e=1" in their ping
+    // parameter if metrics are turned on, or don't have it if metrics are
+    // off.
+    for (const auto& ext : enabled_extensions) {
+      ASSERT_TRUE(ContainsKey(all_pings, ext->id()));
+      ParamsMap& ping = all_pings[ext->id()];
+      if (!enable_metrics) {
+        EXPECT_FALSE(ContainsKey(ping, "e"));
+        EXPECT_FALSE(ContainsKey(ping, "dr"));
+        continue;
+      }
+      EXPECT_FALSE(ContainsKey(ping, "dr"));
+      ASSERT_TRUE(ContainsKey(ping, "e")) << url;
+      std::set<std::string> e = ping["e"];
+      ASSERT_EQ(1u, e.size()) << url;
+      EXPECT_EQ(std::string("1"), *e.begin()) << url;
+      EXPECT_FALSE(ContainsKey(ping, "dr"));
+    }
+
+    // Make sure that all the disable extensions have the appropriate
+    // "dr=<num>" values in their ping parameter if metrics are on, or omit
+    // it otherwise.
+    ASSERT_EQ(disabled_extensions.size(), disabled.size());
+    for (size_t i = 0; i < disabled.size(); i++) {
+      scoped_refptr<const Extension>& ext = disabled_extensions[i];
+      int disable_reasons = disabled[i];
+      ASSERT_TRUE(ContainsKey(all_pings, ext->id())) << url;
+      ParamsMap& ping = all_pings[ext->id()];
+
+      if (!enable_metrics) {
+        EXPECT_FALSE(ContainsKey(ping, "e"));
+        EXPECT_FALSE(ContainsKey(ping, "dr"));
+        continue;
+      }
+      ASSERT_TRUE(ContainsKey(ping, "e")) << url;
+      std::set<std::string> e = ping["e"];
+      ASSERT_EQ(1u, e.size()) << url;
+      EXPECT_EQ(std::string("0"), *e.begin()) << url;
+
+      if (disable_reasons == 0) {
+        EXPECT_FALSE(ContainsKey(ping, "dr"));
+      } else {
+        ASSERT_TRUE(ContainsKey(ping, "dr"));
+        int found_reasons = 0;
+        for (const auto& reason_string : ping["dr"]) {
+          int reason = 0;
+          ASSERT_TRUE(base::StringToInt(reason_string, &reason));
+          // Make sure it's a power of 2.
+          ASSERT_TRUE(reason < 2 || !(reason & (reason - 1))) << reason;
+          found_reasons |= reason;
+        }
+        EXPECT_EQ(disable_reasons, found_reasons);
+      }
+    }
+  }
+
  protected:
   scoped_ptr<TestExtensionPrefs> prefs_;
 
@@ -2057,6 +2234,28 @@
   EXPECT_FALSE(updater.WillCheckSoon());
 }
 
+TEST_F(ExtensionUpdaterTest, TestDisabledReasons1) {
+  std::vector<int> disabled;
+  disabled.push_back(Extension::DISABLE_USER_ACTION);
+  disabled.push_back(Extension::DISABLE_PERMISSIONS_INCREASE |
+                     Extension::DISABLE_CORRUPTED);
+  TestPingMetrics(true, 1, disabled);
+  TestPingMetrics(false, 1, disabled);
+}
+
+TEST_F(ExtensionUpdaterTest, TestDisabledReasons2) {
+  std::vector<int> disabled;
+  TestPingMetrics(true, 1, disabled);
+  TestPingMetrics(false, 1, disabled);
+}
+
+TEST_F(ExtensionUpdaterTest, TestDisabledReasons3) {
+  std::vector<int> disabled;
+  disabled.push_back(0);
+  TestPingMetrics(true, 0, disabled);
+  TestPingMetrics(false, 0, disabled);
+}
+
 // TODO(asargent) - (http://crbug.com/12780) add tests for:
 // -prodversionmin (shouldn't update if browser version too old)
 // -manifests & updates arriving out of order / interleaved
diff --git a/chrome/browser/extensions/webstore_install_with_prompt.cc b/chrome/browser/extensions/webstore_install_with_prompt.cc
index 4e69d8d..f66acc1 100644
--- a/chrome/browser/extensions/webstore_install_with_prompt.cc
+++ b/chrome/browser/extensions/webstore_install_with_prompt.cc
@@ -6,8 +6,6 @@
 
 #include "chrome/browser/extensions/webstore_installer.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "content/public/browser/web_contents.h"
 
 using content::WebContents;
@@ -62,8 +60,7 @@
 WebstoreInstallWithPrompt::CreateInstallUI() {
   // Create an ExtensionInstallPrompt. If the parent window is NULL, the dialog
   // will be placed in the middle of the screen.
-  return make_scoped_ptr(
-      new ExtensionInstallPrompt(profile(), parent_window_, this));
+  return make_scoped_ptr(new ExtensionInstallPrompt(profile(), parent_window_));
 }
 
 bool WebstoreInstallWithPrompt::ShouldShowPostInstallUI() const {
@@ -94,11 +91,4 @@
   return true;
 }
 
-content::WebContents* WebstoreInstallWithPrompt::OpenURL(
-    const content::OpenURLParams& params) {
-  chrome::ScopedTabbedBrowserDisplayer displayer(profile(),
-                                                 chrome::GetActiveDesktop());
-  return displayer.browser()->OpenURL(params);
-}
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/webstore_install_with_prompt.h b/chrome/browser/extensions/webstore_install_with_prompt.h
index afb1512..189ec97 100644
--- a/chrome/browser/extensions/webstore_install_with_prompt.h
+++ b/chrome/browser/extensions/webstore_install_with_prompt.h
@@ -8,7 +8,6 @@
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/extensions/webstore_standalone_installer.h"
-#include "content/public/browser/page_navigator.h"
 #include "ui/gfx/native_widget_types.h"
 #include "url/gurl.h"
 
@@ -28,8 +27,7 @@
 // Clients of this class must be trusted, as verification of the requestor is
 // skipped. This class stubs out many WebstoreStandaloneInstaller abstract
 // methods and can be used as a base class.
-class WebstoreInstallWithPrompt : public WebstoreStandaloneInstaller,
-                                  public content::PageNavigator {
+class WebstoreInstallWithPrompt : public WebstoreStandaloneInstaller {
  public:
   // Use this constructor when there is no parent window. The install dialog
   // will be centered on the screen.
@@ -64,9 +62,6 @@
   bool CheckRequestorPermitted(const base::DictionaryValue& webstore_data,
                                std::string* error) const override;
 
-  // content::PageNavigator overrides:
-  content::WebContents* OpenURL(const content::OpenURLParams& params) override;
-
  private:
   bool show_post_install_ui_;
 
diff --git a/chrome/browser/file_select_helper.cc b/chrome/browser/file_select_helper.cc
index ddb0811f..37f85fb 100644
--- a/chrome/browser/file_select_helper.cc
+++ b/chrome/browser/file_select_helper.cc
@@ -249,7 +249,7 @@
         web_contents_->GetSiteInstance()->GetSiteURL(),
         files,
         base::Bind(
-            &FileSelectHelper::ProcessSelectedFilesChromeOSAfterConversion,
+            &FileSelectHelper::NotifyRenderViewHostAndEndAfterConversion,
             this));
     return;
   }
@@ -262,26 +262,19 @@
     chooser_file.display_name = file.display_name;
     chooser_files.push_back(chooser_file);
   }
-  render_view_host_->FilesSelectedInChooser(chooser_files, dialog_mode_);
+
+  NotifyRenderViewHostAndEndAfterConversion(chooser_files);
+}
+
+void FileSelectHelper::NotifyRenderViewHostAndEndAfterConversion(
+    const std::vector<content::FileChooserFileInfo>& list) {
+  if (render_view_host_)
+    render_view_host_->FilesSelectedInChooser(list, dialog_mode_);
 
   // No members should be accessed from here on.
   RunFileChooserEnd();
 }
 
-#if defined(OS_CHROMEOS)
-void FileSelectHelper::ProcessSelectedFilesChromeOSAfterConversion(
-    scoped_ptr<std::vector<content::FileChooserFileInfo>> list) {
-  if (render_view_host_) {
-    render_view_host_->FilesSelectedInChooser(
-        list ? *list : std::vector<content::FileChooserFileInfo>(),
-        dialog_mode_);
-  }
-
-  // No members should be accessed from here on.
-  RunFileChooserEnd();
-}
-#endif  // defined(OS_CHROMEOS)
-
 void FileSelectHelper::DeleteTemporaryFiles() {
   BrowserThread::PostTask(BrowserThread::FILE,
                           FROM_HERE,
@@ -413,6 +406,7 @@
 void FileSelectHelper::RunFileChooserOnFileThread(
     const FileChooserParams& params) {
   select_file_types_ = GetFileTypesFromAcceptType(params.accept_types);
+  select_file_types_->support_drive = !params.need_local_path;
 
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
diff --git a/chrome/browser/file_select_helper.h b/chrome/browser/file_select_helper.h
index c94e411..06672ba8 100644
--- a/chrome/browser/file_select_helper.h
+++ b/chrome/browser/file_select_helper.h
@@ -146,11 +146,10 @@
   // file chooser.
   void NotifyRenderViewHostAndEnd(
       const std::vector<ui::SelectedFileInfo>& files);
-#if defined(OS_CHROMEOS)
+
   // Sends the result to the render process, and call |RunFileChooserEnd|.
-  void ProcessSelectedFilesChromeOSAfterConversion(
-      scoped_ptr<std::vector<content::FileChooserFileInfo>> list);
-#endif  // defined(OS_CHROMEOS)
+  void NotifyRenderViewHostAndEndAfterConversion(
+      const std::vector<content::FileChooserFileInfo>& list);
 
   // Schedules the deletion of the files in |temporary_files_| and clears the
   // vector.
diff --git a/chrome/browser/guest_view/extension_options/chrome_extension_options_guest_delegate.cc b/chrome/browser/guest_view/extension_options/chrome_extension_options_guest_delegate.cc
index 8753c0d..b572716 100644
--- a/chrome/browser/guest_view/extension_options/chrome_extension_options_guest_delegate.cc
+++ b/chrome/browser/guest_view/extension_options/chrome_extension_options_guest_delegate.cc
@@ -22,7 +22,7 @@
 }
 
 void ChromeExtensionOptionsGuestDelegate::DidInitialize() {
-  extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
+  ChromeExtensionWebContentsObserver::CreateForWebContents(
       extension_options_guest()->web_contents());
 }
 
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.cc b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.cc
index 46b0952b..f4c32e1 100644
--- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.cc
+++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.cc
@@ -5,8 +5,10 @@
 #include "chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h"
 
 #include "chrome/browser/chrome_page_zoom.h"
+#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
 #include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h"
 #include "components/pdf/browser/pdf_web_contents_helper.h"
+#include "components/renderer_context_menu/context_menu_delegate.h"
 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
 
 #if defined(ENABLE_PRINTING)
@@ -18,9 +20,11 @@
 #endif  // defined(ENABLE_FULL_PRINTING)
 #endif  // defined(ENABLE_PRINTING)
 
+namespace extensions {
+
 ChromeMimeHandlerViewGuestDelegate::ChromeMimeHandlerViewGuestDelegate(
-    extensions::MimeHandlerViewGuest* guest)
-    : extensions::MimeHandlerViewGuestDelegate(guest), guest_(guest) {
+    MimeHandlerViewGuest* guest)
+    : MimeHandlerViewGuestDelegate(guest), guest_(guest) {
 }
 
 ChromeMimeHandlerViewGuestDelegate::~ChromeMimeHandlerViewGuestDelegate() {
@@ -50,3 +54,18 @@
       guest_->embedder_web_contents(),
       zoom_in ? content::PAGE_ZOOM_IN : content::PAGE_ZOOM_OUT);
 }
+
+bool ChromeMimeHandlerViewGuestDelegate::HandleContextMenu(
+    content::WebContents* web_contents,
+    const content::ContextMenuParams& params) {
+  ContextMenuDelegate* menu_delegate =
+      ContextMenuDelegate::FromWebContents(web_contents);
+  DCHECK(menu_delegate);
+
+  scoped_ptr<RenderViewContextMenu> menu =
+      menu_delegate->BuildMenu(web_contents, params);
+  menu_delegate->ShowMenu(menu.Pass());
+  return true;
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h
index 93a38a3f..eaa88bf 100644
--- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h
+++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_guest_delegate.h
@@ -9,23 +9,28 @@
 
 namespace content {
 class WebContents;
+struct ContextMenuParams;
 }  // namespace content
 
-class ChromeMimeHandlerViewGuestDelegate
-    : public extensions::MimeHandlerViewGuestDelegate {
+namespace extensions {
+
+class ChromeMimeHandlerViewGuestDelegate : public MimeHandlerViewGuestDelegate {
  public:
-  explicit ChromeMimeHandlerViewGuestDelegate(
-      extensions::MimeHandlerViewGuest* guest);
+  explicit ChromeMimeHandlerViewGuestDelegate(MimeHandlerViewGuest* guest);
   ~ChromeMimeHandlerViewGuestDelegate() override;
 
   // MimeHandlerViewGuestDelegate.
   void AttachHelpers() override;
+  bool HandleContextMenu(content::WebContents* web_contents,
+                         const content::ContextMenuParams& params) override;
   void ChangeZoom(bool zoom_in) override;
 
  private:
-  extensions::MimeHandlerViewGuest* guest_;  // Owns us.
+  MimeHandlerViewGuest* guest_;  // Owns us.
 
   DISALLOW_COPY_AND_ASSIGN(ChromeMimeHandlerViewGuestDelegate);
 };
 
+}  // namespace extensions
+
 #endif  // CHROME_BROWSER_GUEST_VIEW_MIME_HANDLER_VIEW_CHROME_MIME_HANDLER_VIEW_GUEST_DELEGATE_H_
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
index 2a96809..5b5de3f 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
@@ -26,8 +26,10 @@
 #endif  // defined(ENABLE_FULL_PRINTING)
 #endif  // defined(ENABLE_PRINTING)
 
+namespace extensions {
+
 ChromeWebViewGuestDelegate::ChromeWebViewGuestDelegate(
-    extensions::WebViewGuest* web_view_guest)
+    WebViewGuest* web_view_guest)
     : pending_context_menu_request_id_(0),
       chromevox_injected_(false),
       current_zoom_factor_(1.0),
@@ -58,8 +60,7 @@
   args->Set(webview::kContextMenuItems, items.release());
   args->SetInteger(webview::kRequestId, request_id);
   web_view_guest()->DispatchEventToEmbedder(
-      new extensions::GuestViewBase::Event(
-          webview::kEventContextMenu, args.Pass()));
+      new GuestViewBase::Event(webview::kEventContextMenu, args.Pass()));
   return true;
 }
 
@@ -76,8 +77,7 @@
   ZoomController::CreateForWebContents(contents);
 
   FaviconTabHelper::CreateForWebContents(contents);
-  extensions::ChromeExtensionWebContentsObserver::
-      CreateForWebContents(contents);
+  ChromeExtensionWebContentsObserver::CreateForWebContents(contents);
 #if defined(ENABLE_PRINTING)
 #if defined(ENABLE_FULL_PRINTING)
   printing::PrintViewManager::CreateForWebContents(contents);
@@ -142,11 +142,23 @@
   zoom_controller->SetZoomMode(ZoomController::ZOOM_MODE_ISOLATED);
 }
 
+void ChromeWebViewGuestDelegate::OnEmbedderWillBeDestroyed() {
+  content::WebContents* embedder_web_contents =
+      web_view_guest()->embedder_web_contents();
+  if (!embedder_web_contents)
+    return;
+
+  ZoomController* zoom_controller =
+      ZoomController::FromWebContents(embedder_web_contents);
+  if (zoom_controller)
+    zoom_controller->RemoveObserver(this);
+}
+
 void ChromeWebViewGuestDelegate::OnGuestDestroyed() {
   // Clean up custom context menu items for this guest.
-  extensions::MenuManager* menu_manager = extensions::MenuManager::Get(
+  MenuManager* menu_manager = MenuManager::Get(
       Profile::FromBrowserContext(web_view_guest()->browser_context()));
-  menu_manager->RemoveAllContextItems(extensions::MenuItem::ExtensionKey(
+  menu_manager->RemoveAllContextItems(MenuItem::ExtensionKey(
       web_view_guest()->embedder_extension_id(),
       web_view_guest()->view_instance_id()));
 }
@@ -178,8 +190,7 @@
   args->SetDouble(webview::kOldZoomFactor, current_zoom_factor_);
   args->SetDouble(webview::kNewZoomFactor, zoom_factor);
   web_view_guest()->DispatchEventToEmbedder(
-      new extensions::GuestViewBase::Event(
-          webview::kEventZoomChange, args.Pass()));
+      new GuestViewBase::Event(webview::kEventZoomChange, args.Pass()));
   current_zoom_factor_ = zoom_factor;
 }
 
@@ -235,3 +246,5 @@
   ZoomController::FromWebContents(guest_web_contents())->
       SetZoomLevel(data.new_zoom_level);
 }
+
+}  // namespace extensions
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
index 9b9dca59..2a0d9d6 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
@@ -20,11 +20,12 @@
 class SimpleMenuModel;
 }  // namespace ui
 
-class ChromeWebViewGuestDelegate : public extensions::WebViewGuestDelegate,
+namespace extensions {
+
+class ChromeWebViewGuestDelegate : public WebViewGuestDelegate,
                                    public ZoomObserver {
  public :
-  explicit ChromeWebViewGuestDelegate(
-      extensions::WebViewGuest* web_view_guest);
+  explicit ChromeWebViewGuestDelegate(WebViewGuest* web_view_guest);
   ~ChromeWebViewGuestDelegate() override;
 
   // WebViewGuestDelegate implementation.
@@ -37,6 +38,7 @@
   void OnDocumentLoadedInFrame(
       content::RenderFrameHost* render_frame_host) override;
   void OnGuestReady() override;
+  void OnEmbedderWillBeDestroyed() override;
   void OnGuestDestroyed() override;
   void OnSetZoom(double zoom_factor) override;
   void OnShowContextMenu(int request_id, const MenuItemVector* items) override;
@@ -44,7 +46,7 @@
   // ZoomObserver implementation.
   void OnZoomChanged(const ZoomController::ZoomChangedEventData& data) override;
 
-  extensions::WebViewGuest* web_view_guest() const { return web_view_guest_; }
+  WebViewGuest* web_view_guest() const { return web_view_guest_; }
 
  private:
   content::WebContents* guest_web_contents() const {
@@ -83,7 +85,7 @@
       accessibility_subscription_;
 #endif
 
-  extensions::WebViewGuest* const web_view_guest_;
+  WebViewGuest* const web_view_guest_;
 
   // This is used to ensure pending tasks will not fire after this object is
   // destroyed.
@@ -92,5 +94,7 @@
   DISALLOW_COPY_AND_ASSIGN(ChromeWebViewGuestDelegate);
 };
 
+}  // namespace extensions
+
 #endif  // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_CHROME_WEB_VIEW_GUEST_DELEGATE_H_
 
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
index 1acc8a3..61da9d5d 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.cc
@@ -17,8 +17,10 @@
 #include "extensions/browser/guest_view/web_view/web_view_constants.h"
 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
 
+namespace extensions {
+
 ChromeWebViewPermissionHelperDelegate::ChromeWebViewPermissionHelperDelegate(
-    extensions::WebViewPermissionHelper* web_view_permission_helper)
+    WebViewPermissionHelper* web_view_permission_helper)
     : WebViewPermissionHelperDelegate(web_view_permission_helper),
       weak_factory_(this) {
 }
@@ -188,7 +190,7 @@
   // It is safe to hold an unretained pointer to
   // ChromeWebViewPermissionHelperDelegate because this callback is called from
   // ChromeWebViewPermissionHelperDelegate::SetPermission.
-  const extensions::WebViewPermissionHelper::PermissionResponseCallback
+  const WebViewPermissionHelper::PermissionResponseCallback
       permission_callback =
       base::Bind(&ChromeWebViewPermissionHelperDelegate::
                      OnGeolocationPermissionResponse,
@@ -346,3 +348,5 @@
                                                                   allowed);
   Send(reply_msg);
 }
+
+}  // namespace extensions
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h
index ae6e00b..6a8cda47 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_permission_helper_delegate.h
@@ -10,13 +10,12 @@
 
 namespace extensions {
 class WebViewGuest;
-}
 
 class ChromeWebViewPermissionHelperDelegate :
-  public extensions::WebViewPermissionHelperDelegate {
+  public WebViewPermissionHelperDelegate {
  public:
   explicit ChromeWebViewPermissionHelperDelegate(
-      extensions::WebViewPermissionHelper* web_view_permission_helper);
+      WebViewPermissionHelper* web_view_permission_helper);
   ~ChromeWebViewPermissionHelperDelegate() override;
 
   // WebViewPermissionHelperDelegate implementation.
@@ -115,7 +114,7 @@
                                       IPC::Message* reply_msg,
                                       bool allowed);
 
-  extensions::WebViewGuest* web_view_guest() {
+  WebViewGuest* web_view_guest() {
     return web_view_permission_helper()->web_view_guest();
   }
 
@@ -126,4 +125,6 @@
   DISALLOW_COPY_AND_ASSIGN(ChromeWebViewPermissionHelperDelegate);
 };
 
+}  // namespace extensions
+
 #endif  // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_CHROME_WEB_VIEW_PERMISSION_HELPER_DELEGATE_H_
diff --git a/chrome/browser/history/android/android_history_provider_service_unittest.cc b/chrome/browser/history/android/android_history_provider_service_unittest.cc
index 949bb4c..e2f7ccc 100644
--- a/chrome/browser/history/android/android_history_provider_service_unittest.cc
+++ b/chrome/browser/history/android/android_history_provider_service_unittest.cc
@@ -54,7 +54,7 @@
         chrome::kInitialProfile);
 
     testing_profile_->CreateBookmarkModel(true);
-    test::WaitForBookmarkModelToLoad(
+    bookmarks::test::WaitForBookmarkModelToLoad(
         BookmarkModelFactory::GetForProfile(testing_profile_));
     ASSERT_TRUE(testing_profile_->CreateHistoryService(true, false));
     service_.reset(new AndroidHistoryProviderService(testing_profile_));
diff --git a/chrome/browser/history/android/android_provider_backend_unittest.cc b/chrome/browser/history/android/android_provider_backend_unittest.cc
index e5cac63f..5fa1567 100644
--- a/chrome/browser/history/android/android_provider_backend_unittest.cc
+++ b/chrome/browser/history/android/android_provider_backend_unittest.cc
@@ -145,7 +145,7 @@
     bookmark_model_ = BookmarkModelFactory::GetForProfile(testing_profile);
     history_client_ =
         ChromeHistoryClientFactory::GetForProfile(testing_profile);
-    test::WaitForBookmarkModelToLoad(bookmark_model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model_);
     ASSERT_TRUE(bookmark_model_);
 
     // Get the BookmarkModel from LastUsedProfile, this is the same way that
diff --git a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
index 7ed29f8..55fcd8a 100644
--- a/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
+++ b/chrome/browser/history/android/bookmark_model_sql_handler_unittest.cc
@@ -47,7 +47,7 @@
     // Create the BookmarkModel that doesn't need to invoke load().
     testing_profile->CreateBookmarkModel(true);
     bookmark_model_ = BookmarkModelFactory::GetForProfile(testing_profile);
-    test::WaitForBookmarkModelToLoad(bookmark_model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model_);
     ASSERT_TRUE(bookmark_model_);
     // Get the BookmarkModel from LastUsedProfile, this is the same way that
     // how the BookmarkModelSQLHandler gets the BookmarkModel.
diff --git a/chrome/browser/history/android/sqlite_cursor_unittest.cc b/chrome/browser/history/android/sqlite_cursor_unittest.cc
index 9559cf7..6660fd9d 100644
--- a/chrome/browser/history/android/sqlite_cursor_unittest.cc
+++ b/chrome/browser/history/android/sqlite_cursor_unittest.cc
@@ -65,7 +65,7 @@
         chrome::kInitialProfile);
 
     testing_profile_->CreateBookmarkModel(true);
-    test::WaitForBookmarkModelToLoad(
+    bookmarks::test::WaitForBookmarkModelToLoad(
         BookmarkModelFactory::GetForProfile(testing_profile_));
 
     testing_profile_->CreateFaviconService();
diff --git a/chrome/browser/history/chrome_history_client.h b/chrome/browser/history/chrome_history_client.h
index 13ef081..38f80f80 100644
--- a/chrome/browser/history/chrome_history_client.h
+++ b/chrome/browser/history/chrome_history_client.h
@@ -27,7 +27,7 @@
   explicit ChromeHistoryClient(BookmarkModel* bookmark_model,
                                Profile* profile,
                                history::TopSites* top_sites);
-  virtual ~ChromeHistoryClient();
+  ~ChromeHistoryClient() override;
 
   // TODO(sdefresne): once NOTIFICATION_HISTORY_URL* notifications are no
   // longer used, remove this reference to the HistoryService from the
@@ -35,19 +35,18 @@
   void SetHistoryService(HistoryService* history_service);
 
   // history::HistoryClient:
-  virtual void BlockUntilBookmarksLoaded() override;
-  virtual bool IsBookmarked(const GURL& url) override;
-  virtual void GetBookmarks(
-      std::vector<history::URLAndTitle>* bookmarks) override;
-  virtual void NotifyProfileError(sql::InitStatus init_status) override;
-  virtual bool ShouldReportDatabaseError() override;
+  void BlockUntilBookmarksLoaded() override;
+  bool IsBookmarked(const GURL& url) override;
+  void GetBookmarks(std::vector<history::URLAndTitle>* bookmarks) override;
+  void NotifyProfileError(sql::InitStatus init_status) override;
+  bool ShouldReportDatabaseError() override;
 
   // KeyedService:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // TopSitesObserver:
-  virtual void TopSitesLoaded(history::TopSites* top_sites) override;
-  virtual void TopSitesChanged(history::TopSites* top_sites) override;
+  void TopSitesLoaded(history::TopSites* top_sites) override;
+  void TopSitesChanged(history::TopSites* top_sites) override;
 
  private:
   // The BookmarkModel, this should outlive ChromeHistoryClient.
diff --git a/chrome/browser/history/chrome_history_client_factory.h b/chrome/browser/history/chrome_history_client_factory.h
index 01eb7f4..9b8a32f 100644
--- a/chrome/browser/history/chrome_history_client_factory.h
+++ b/chrome/browser/history/chrome_history_client_factory.h
@@ -30,14 +30,14 @@
   friend struct DefaultSingletonTraits<ChromeHistoryClientFactory>;
 
   ChromeHistoryClientFactory();
-  virtual ~ChromeHistoryClientFactory();
+  ~ChromeHistoryClientFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsNULLWhileTesting() const override;
 };
 
 #endif  // CHROME_BROWSER_HISTORY_CHROME_HISTORY_CLIENT_FACTORY_H_
diff --git a/chrome/browser/history/delete_directive_handler.cc b/chrome/browser/history/delete_directive_handler.cc
index 1a42b88..405cc7d 100644
--- a/chrome/browser/history/delete_directive_handler.cc
+++ b/chrome/browser/history/delete_directive_handler.cc
@@ -124,12 +124,12 @@
        post_processing_action_(post_processing_action) {}
 
   // Implements HistoryDBTask.
-  virtual bool RunOnDBThread(history::HistoryBackend* backend,
-                             history::HistoryDatabase* db) override;
-  virtual void DoneRunOnMainThread() override;
+  bool RunOnDBThread(history::HistoryBackend* backend,
+                     history::HistoryDatabase* db) override;
+  void DoneRunOnMainThread() override;
 
  private:
-  virtual ~DeleteDirectiveTask() {}
+  ~DeleteDirectiveTask() override {}
 
   // Process a list of global Id directives. Delete all visits to a URL in
   // time ranges of directives if the timestamp of one visit matches with one
diff --git a/chrome/browser/history/expire_history_backend.cc b/chrome/browser/history/expire_history_backend.cc
index b4791d9..a7c9528 100644
--- a/chrome/browser/history/expire_history_backend.cc
+++ b/chrome/browser/history/expire_history_backend.cc
@@ -44,10 +44,10 @@
 // time. This is the most general reader.
 class AllVisitsReader : public ExpiringVisitsReader {
  public:
-  virtual bool Read(base::Time end_time,
-                    HistoryDatabase* db,
-                    VisitVector* visits,
-                    int max_visits) const override {
+  bool Read(base::Time end_time,
+            HistoryDatabase* db,
+            VisitVector* visits,
+            int max_visits) const override {
     DCHECK(db) << "must have a database to operate upon";
     DCHECK(visits) << "visit vector has to exist in order to populate it";
 
@@ -66,10 +66,10 @@
 //   but not past the current time.
 class AutoSubframeVisitsReader : public ExpiringVisitsReader {
  public:
-  virtual bool Read(base::Time end_time,
-                    HistoryDatabase* db,
-                    VisitVector* visits,
-                    int max_visits) const override {
+  bool Read(base::Time end_time,
+            HistoryDatabase* db,
+            VisitVector* visits,
+            int max_visits) const override {
     DCHECK(db) << "must have a database to operate upon";
     DCHECK(visits) << "visit vector has to exist in order to populate it";
 
diff --git a/chrome/browser/history/expire_history_backend_unittest.cc b/chrome/browser/history/expire_history_backend_unittest.cc
index 2de4b391..e7439cb6 100644
--- a/chrome/browser/history/expire_history_backend_unittest.cc
+++ b/chrome/browser/history/expire_history_backend_unittest.cc
@@ -148,17 +148,16 @@
   }
 
   // BroadcastNotificationDelegate:
-  virtual void BroadcastNotifications(
-      int type,
-      scoped_ptr<HistoryDetails> details) override {
+  void BroadcastNotifications(int type,
+                              scoped_ptr<HistoryDetails> details) override {
     // This gets called when there are notifications to broadcast. Instead, we
     // store them so we can tell that the correct notifications were sent.
     notifications_.push_back(std::make_pair(type, details.release()));
   }
-  virtual void NotifySyncURLsModified(URLRows* rows) override {}
-  virtual void NotifySyncURLsDeleted(bool all_history,
-                                     bool expired,
-                                     URLRows* rows) override {}
+  void NotifySyncURLsModified(URLRows* rows) override {}
+  void NotifySyncURLsDeleted(bool all_history,
+                             bool expired,
+                             URLRows* rows) override {}
 };
 
 // The example data consists of 4 visits. The middle two visits are to the
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index eff5b9a6..cfd46ca8 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -710,7 +710,7 @@
 void HistoryBackend::OnMemoryPressure(
     base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
   bool trim_aggressively = memory_pressure_level ==
-      base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL;
+      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
   if (db_)
     db_->TrimMemory(trim_aggressively);
   if (thumbnail_db_)
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index 6a7a5da..90cfb6d 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -517,7 +517,7 @@
   }
 
  protected:
-  virtual ~HistoryBackend();
+  ~HistoryBackend() override;
 
   // Notify HistoryBackendObserver that |transition| to |row| occurred at
   // |visit_time| following |redirects| (empty if there is no redirects).
@@ -795,13 +795,12 @@
   // to be invoked again if there are more tasks that need to run.
   void ProcessDBTaskImpl();
 
-  virtual void BroadcastNotifications(
-      int type,
-      scoped_ptr<HistoryDetails> details) override;
-  virtual void NotifySyncURLsModified(URLRows* rows) override;
-  virtual void NotifySyncURLsDeleted(bool all_history,
-                                     bool expired,
-                                     URLRows* rows) override;
+  void BroadcastNotifications(int type,
+                              scoped_ptr<HistoryDetails> details) override;
+  void NotifySyncURLsModified(URLRows* rows) override;
+  void NotifySyncURLsDeleted(bool all_history,
+                             bool expired,
+                             URLRows* rows) override;
 
   // Deleting all history ------------------------------------------------------
 
diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc
index c29075b..78b0b59b 100644
--- a/chrome/browser/history/history_backend_unittest.cc
+++ b/chrome/browser/history/history_backend_unittest.cc
@@ -114,19 +114,17 @@
   explicit HistoryBackendTestDelegate(HistoryBackendTestBase* test)
       : test_(test) {}
 
-  virtual void NotifyProfileError(sql::InitStatus init_status) override {}
-  virtual void SetInMemoryBackend(
-      scoped_ptr<InMemoryHistoryBackend> backend) override;
-  virtual void NotifyAddVisit(const BriefVisitInfo& info) override {}
-  virtual void NotifyFaviconChanged(const std::set<GURL>& urls) override;
-  virtual void NotifyURLVisited(ui::PageTransition transition,
-                                const URLRow& row,
-                                const RedirectList& redirects,
-                                base::Time visit_time) override;
-  virtual void BroadcastNotifications(
-      int type,
-      scoped_ptr<HistoryDetails> details) override;
-  virtual void DBLoaded() override;
+  void NotifyProfileError(sql::InitStatus init_status) override {}
+  void SetInMemoryBackend(scoped_ptr<InMemoryHistoryBackend> backend) override;
+  void NotifyAddVisit(const BriefVisitInfo& info) override {}
+  void NotifyFaviconChanged(const std::set<GURL>& urls) override;
+  void NotifyURLVisited(ui::PageTransition transition,
+                        const URLRow& row,
+                        const RedirectList& redirects,
+                        base::Time visit_time) override;
+  void BroadcastNotifications(int type,
+                              scoped_ptr<HistoryDetails> details) override;
+  void DBLoaded() override;
 
  private:
   // Not owned by us.
diff --git a/chrome/browser/history/history_browsertest.cc b/chrome/browser/history/history_browsertest.cc
index 0321a182..90fd7db 100644
--- a/chrome/browser/history/history_browsertest.cc
+++ b/chrome/browser/history/history_browsertest.cc
@@ -43,17 +43,15 @@
  public:
   WaitForHistoryTask() {}
 
-  virtual bool RunOnDBThread(history::HistoryBackend* backend,
-                             history::HistoryDatabase* db) override {
+  bool RunOnDBThread(history::HistoryBackend* backend,
+                     history::HistoryDatabase* db) override {
     return true;
   }
 
-  virtual void DoneRunOnMainThread() override {
-    base::MessageLoop::current()->Quit();
-  }
+  void DoneRunOnMainThread() override { base::MessageLoop::current()->Quit(); }
 
  private:
-  virtual ~WaitForHistoryTask() {}
+  ~WaitForHistoryTask() override {}
 
   DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask);
 };
@@ -62,7 +60,7 @@
 
 class HistoryBrowserTest : public InProcessBrowserTest {
  protected:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     command_line->AppendSwitch(switches::kEnableFileCookies);
   }
 
diff --git a/chrome/browser/history/history_database.h b/chrome/browser/history/history_database.h
index ccc0db93..d0d79a9 100644
--- a/chrome/browser/history/history_database.h
+++ b/chrome/browser/history/history_database.h
@@ -65,7 +65,7 @@
   // database cleanup.
   HistoryDatabase();
 
-  virtual ~HistoryDatabase();
+  ~HistoryDatabase() override;
 
   // Call before Init() to set the error callback to be used for the
   // underlying database connection.
@@ -162,7 +162,7 @@
   friend class InMemoryURLIndexTest;
 
   // Overridden from URLDatabase:
-  virtual sql::Connection& GetDB() override;
+  sql::Connection& GetDB() override;
 
   // Migration -----------------------------------------------------------------
 
diff --git a/chrome/browser/history/history_notifications.h b/chrome/browser/history/history_notifications.h
index fc21e7c2..6178b99 100644
--- a/chrome/browser/history/history_notifications.h
+++ b/chrome/browser/history/history_notifications.h
@@ -19,7 +19,7 @@
 // Details for NOTIFICATION_HISTORY_TYPED_URLS_MODIFIED.
 struct URLsModifiedDetails : public HistoryDetails {
   URLsModifiedDetails();
-  virtual ~URLsModifiedDetails();
+  ~URLsModifiedDetails() override;
 
   // Lists the information for each of the URLs affected. The rows will have the
   // IDs that are currently in effect in the main history database.
@@ -29,7 +29,7 @@
 // Details for NOTIFICATION_HISTORY_URLS_DELETED.
 struct URLsDeletedDetails : public HistoryDetails {
   URLsDeletedDetails();
-  virtual ~URLsDeletedDetails();
+  ~URLsDeletedDetails() override;
 
   // Set when all history was deleted. False means just a subset was deleted.
   bool all_history;
@@ -54,7 +54,7 @@
   KeywordSearchUpdatedDetails(const URLRow& url_row,
                               KeywordID keyword_id,
                               const base::string16& term);
-  virtual ~KeywordSearchUpdatedDetails();
+  ~KeywordSearchUpdatedDetails() override;
 
   // The affected URLRow. The ID will be set to the value that is currently in
   // effect in the main history database.
@@ -66,7 +66,7 @@
 // Details for HISTORY_KEYWORD_SEARCH_TERM_DELETED.
 struct KeywordSearchDeletedDetails : public HistoryDetails {
   explicit KeywordSearchDeletedDetails(URLID url_row_id);
-  virtual ~KeywordSearchDeletedDetails();
+  ~KeywordSearchDeletedDetails() override;
 
   // The ID of the corresponding URLRow in the main history database.
   URLID url_row_id;
diff --git a/chrome/browser/history/history_service.cc b/chrome/browser/history/history_service.cc
index 88e88c5..45e62ca 100644
--- a/chrome/browser/history/history_service.cc
+++ b/chrome/browser/history/history_service.cc
@@ -102,13 +102,9 @@
         end_(url_rows.end()) {
   }
 
-  virtual const GURL& NextURL() override {
-    return (itr_++)->url();
-  }
+  const GURL& NextURL() override { return (itr_++)->url(); }
 
-  virtual bool HasNextURL() const override {
-    return itr_ != end_;
-  }
+  bool HasNextURL() const override { return itr_ != end_; }
 
  private:
   history::URLRows::const_iterator itr_;
@@ -142,7 +138,7 @@
         profile_(profile) {
   }
 
-  virtual void NotifyProfileError(sql::InitStatus init_status) override {
+  void NotifyProfileError(sql::InitStatus init_status) override {
     // Send to the history service on the main thread.
     service_task_runner_->PostTask(
         FROM_HERE,
@@ -150,7 +146,7 @@
                    init_status));
   }
 
-  virtual void SetInMemoryBackend(
+  void SetInMemoryBackend(
       scoped_ptr<history::InMemoryHistoryBackend> backend) override {
     // Send the backend to the history service on the main thread.
     service_task_runner_->PostTask(
@@ -159,13 +155,13 @@
                    base::Passed(&backend)));
   }
 
-  virtual void NotifyAddVisit(const history::BriefVisitInfo& info) override {
+  void NotifyAddVisit(const history::BriefVisitInfo& info) override {
     service_task_runner_->PostTask(
         FROM_HERE,
         base::Bind(&HistoryService::NotifyAddVisit, history_service_, info));
   }
 
-  virtual void NotifyFaviconChanged(const std::set<GURL>& urls) override {
+  void NotifyFaviconChanged(const std::set<GURL>& urls) override {
     // Send the notification to the history service on the main thread.
     service_task_runner_->PostTask(
         FROM_HERE,
@@ -173,10 +169,10 @@
             &HistoryService::NotifyFaviconChanged, history_service_, urls));
   }
 
-  virtual void NotifyURLVisited(ui::PageTransition transition,
-                                const history::URLRow& row,
-                                const history::RedirectList& redirects,
-                                base::Time visit_time) override {
+  void NotifyURLVisited(ui::PageTransition transition,
+                        const history::URLRow& row,
+                        const history::RedirectList& redirects,
+                        base::Time visit_time) override {
     service_task_runner_->PostTask(FROM_HERE,
                                    base::Bind(&HistoryService::NotifyURLVisited,
                                               history_service_,
@@ -186,7 +182,7 @@
                                               visit_time));
   }
 
-  virtual void BroadcastNotifications(
+  void BroadcastNotifications(
       int type,
       scoped_ptr<history::HistoryDetails> details) override {
     // Send the notification on the history thread.
@@ -202,7 +198,7 @@
                    history_service_, type, base::Passed(&details)));
   }
 
-  virtual void DBLoaded() override {
+  void DBLoaded() override {
     service_task_runner_->PostTask(
         FROM_HERE,
         base::Bind(&HistoryService::OnDBLoaded, history_service_));
diff --git a/chrome/browser/history/history_service.h b/chrome/browser/history/history_service.h
index dc3f2b7..7e7eb10 100644
--- a/chrome/browser/history/history_service.h
+++ b/chrome/browser/history/history_service.h
@@ -97,7 +97,7 @@
   // The empty constructor is provided only for testing.
   HistoryService();
 
-  virtual ~HistoryService();
+  ~HistoryService() override;
 
   // Initializes the history service, returning true on success. On false, do
   // not call any other functions. The given directory will be used for storing
@@ -151,7 +151,7 @@
   }
 
   // KeyedService:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // Navigation ----------------------------------------------------------------
 
@@ -502,15 +502,14 @@
   base::WeakPtr<HistoryService> AsWeakPtr();
 
   // syncer::SyncableService implementation.
-  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
+  syncer::SyncMergeResult MergeDataAndStartSyncing(
       syncer::ModelType type,
       const syncer::SyncDataList& initial_sync_data,
       scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
       scoped_ptr<syncer::SyncErrorFactory> error_handler) override;
-  virtual void StopSyncing(syncer::ModelType type) override;
-  virtual syncer::SyncDataList GetAllSyncData(
-      syncer::ModelType type) const override;
-  virtual syncer::SyncError ProcessSyncChanges(
+  void StopSyncing(syncer::ModelType type) override;
+  syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override;
+  syncer::SyncError ProcessSyncChanges(
       const tracked_objects::Location& from_here,
       const syncer::SyncChangeList& change_list) override;
 
@@ -556,13 +555,12 @@
   void Cleanup();
 
   // Implementation of content::NotificationObserver.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Implementation of visitedlink::VisitedLinkDelegate.
-  virtual void RebuildTable(
-      const scoped_refptr<URLEnumerator>& enumerator) override;
+  void RebuildTable(const scoped_refptr<URLEnumerator>& enumerator) override;
 
   // Low-level Init().  Same as the public version, but adds a |no_db| parameter
   // that is only set by unittests which causes the backend to not init its DB.
diff --git a/chrome/browser/history/history_service_factory.h b/chrome/browser/history/history_service_factory.h
index 2908df6..06fcc24 100644
--- a/chrome/browser/history/history_service_factory.h
+++ b/chrome/browser/history/history_service_factory.h
@@ -36,14 +36,14 @@
   friend struct DefaultSingletonTraits<HistoryServiceFactory>;
 
   HistoryServiceFactory();
-  virtual ~HistoryServiceFactory();
+  ~HistoryServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsNULLWhileTesting() const override;
 };
 
 #endif  // CHROME_BROWSER_HISTORY_HISTORY_SERVICE_FACTORY_H_
diff --git a/chrome/browser/history/history_tab_helper.h b/chrome/browser/history/history_tab_helper.h
index 7df8f5d3..9f576d3 100644
--- a/chrome/browser/history/history_tab_helper.h
+++ b/chrome/browser/history/history_tab_helper.h
@@ -19,7 +19,7 @@
 class HistoryTabHelper : public content::WebContentsObserver,
                          public content::WebContentsUserData<HistoryTabHelper> {
  public:
-  virtual ~HistoryTabHelper();
+  ~HistoryTabHelper() override;
 
   // Updates history with the specified navigation. This is called by
   // OnMsgNavigate to update history state.
@@ -43,16 +43,14 @@
   friend class content::WebContentsUserData<HistoryTabHelper>;
 
   // content::WebContentsObserver implementation.
-  virtual void DidNavigateMainFrame(
+  void DidNavigateMainFrame(
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) override;
-  virtual void DidNavigateAnyFrame(
-      content::RenderFrameHost* render_frame_host,
-      const content::LoadCommittedDetails& details,
-      const content::FrameNavigateParams& params) override;
-  virtual void TitleWasSet(content::NavigationEntry* entry,
-                           bool explicit_set) override;
-  virtual void WebContentsDestroyed() override;
+  void DidNavigateAnyFrame(content::RenderFrameHost* render_frame_host,
+                           const content::LoadCommittedDetails& details,
+                           const content::FrameNavigateParams& params) override;
+  void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
+  void WebContentsDestroyed() override;
 
   // Helper function to return the history service.  May return NULL.
   HistoryService* GetHistoryService();
diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc
index dc58c8a..99adfed 100644
--- a/chrome/browser/history/history_unittest.cc
+++ b/chrome/browser/history/history_unittest.cc
@@ -93,19 +93,17 @@
       : history_test_(history_test) {
   }
 
-  virtual void NotifyProfileError(sql::InitStatus init_status) override {}
-  virtual void SetInMemoryBackend(
-      scoped_ptr<InMemoryHistoryBackend> backend) override;
-  virtual void NotifyAddVisit(const BriefVisitInfo& info) override {}
-  virtual void NotifyFaviconChanged(const std::set<GURL>& url) override {}
-  virtual void NotifyURLVisited(ui::PageTransition transition,
-                                const URLRow& row,
-                                const RedirectList& redirects,
-                                base::Time visit_time) override {}
-  virtual void BroadcastNotifications(
-      int type,
-      scoped_ptr<HistoryDetails> details) override;
-  virtual void DBLoaded() override {}
+  void NotifyProfileError(sql::InitStatus init_status) override {}
+  void SetInMemoryBackend(scoped_ptr<InMemoryHistoryBackend> backend) override;
+  void NotifyAddVisit(const BriefVisitInfo& info) override {}
+  void NotifyFaviconChanged(const std::set<GURL>& url) override {}
+  void NotifyURLVisited(ui::PageTransition transition,
+                        const URLRow& row,
+                        const RedirectList& redirects,
+                        base::Time visit_time) override {}
+  void BroadcastNotifications(int type,
+                              scoped_ptr<HistoryDetails> details) override;
+  void DBLoaded() override {}
 
  private:
   HistoryBackendDBTest* history_test_;
@@ -1507,12 +1505,11 @@
   HistoryDBTaskImpl(int* invoke_count, bool* done_invoked)
       : invoke_count_(invoke_count), done_invoked_(done_invoked) {}
 
-  virtual bool RunOnDBThread(HistoryBackend* backend,
-                             HistoryDatabase* db) override {
+  bool RunOnDBThread(HistoryBackend* backend, HistoryDatabase* db) override {
     return (++*invoke_count_ == kWantInvokeCount);
   }
 
-  virtual void DoneRunOnMainThread() override {
+  void DoneRunOnMainThread() override {
     *done_invoked_ = true;
     base::MessageLoop::current()->Quit();
   }
@@ -1521,7 +1518,7 @@
   bool* done_invoked_;
 
  private:
-  virtual ~HistoryDBTaskImpl() {}
+  ~HistoryDBTaskImpl() override {}
 
   DISALLOW_COPY_AND_ASSIGN(HistoryDBTaskImpl);
 };
diff --git a/chrome/browser/history/in_memory_history_backend.h b/chrome/browser/history/in_memory_history_backend.h
index ec469a5..793d9d68 100644
--- a/chrome/browser/history/in_memory_history_backend.h
+++ b/chrome/browser/history/in_memory_history_backend.h
@@ -51,7 +51,7 @@
                                public content::NotificationObserver {
  public:
   InMemoryHistoryBackend();
-  virtual ~InMemoryHistoryBackend();
+  ~InMemoryHistoryBackend() override;
 
   // Initializes the backend from the history database pointed to by the
   // full path in |history_filename|.
@@ -74,16 +74,16 @@
   }
 
   // HistoryServiceObserver:
-  virtual void OnURLVisited(HistoryService* history_service,
-                            ui::PageTransition transition,
-                            const URLRow& row,
-                            const RedirectList& redirects,
-                            base::Time visit_time) override;
+  void OnURLVisited(HistoryService* history_service,
+                    ui::PageTransition transition,
+                    const URLRow& row,
+                    const RedirectList& redirects,
+                    base::Time visit_time) override;
 
   // Notification callback.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteAll);
diff --git a/chrome/browser/history/in_memory_url_index.h b/chrome/browser/history/in_memory_url_index.h
index 74b5b92..f7806c3 100644
--- a/chrome/browser/history/in_memory_url_index.h
+++ b/chrome/browser/history/in_memory_url_index.h
@@ -106,7 +106,7 @@
                    const base::FilePath& history_dir,
                    const std::string& languages,
                    HistoryClient* client);
-  virtual ~InMemoryURLIndex();
+  ~InMemoryURLIndex() override;
 
   // Opens and prepares the index of historical URL visits. If the index private
   // data cannot be restored from its cache file then it is rebuilt from the
@@ -163,12 +163,12 @@
         const std::string& languages,
         const std::set<std::string>& scheme_whitelist);
 
-    virtual bool RunOnDBThread(HistoryBackend* backend,
-                               history::HistoryDatabase* db) override;
-    virtual void DoneRunOnMainThread() override;
+    bool RunOnDBThread(HistoryBackend* backend,
+                       history::HistoryDatabase* db) override;
+    void DoneRunOnMainThread() override;
 
    private:
-    virtual ~RebuildPrivateDataFromHistoryDBTask();
+    ~RebuildPrivateDataFromHistoryDBTask() override;
 
     InMemoryURLIndex* index_;  // Call back to this index at completion.
     std::string languages_;  // Languages for word-breaking.
@@ -235,16 +235,16 @@
   void OnCacheSaveDone(bool succeeded);
 
   // Handles notifications of history changes.
-  virtual void Observe(int notification_type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int notification_type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // HistoryServiceObserver:
-  virtual void OnURLVisited(HistoryService* history_service,
-                            ui::PageTransition transition,
-                            const URLRow& row,
-                            const RedirectList& redirects,
-                            base::Time visit_time) override;
+  void OnURLVisited(HistoryService* history_service,
+                    ui::PageTransition transition,
+                    const URLRow& row,
+                    const RedirectList& redirects,
+                    base::Time visit_time) override;
 
   // Notification handlers.
   void OnURLsModified(const URLsModifiedDetails* details);
diff --git a/chrome/browser/history/in_memory_url_index_unittest.cc b/chrome/browser/history/in_memory_url_index_unittest.cc
index d21d294..941a94d 100644
--- a/chrome/browser/history/in_memory_url_index_unittest.cc
+++ b/chrome/browser/history/in_memory_url_index_unittest.cc
@@ -65,7 +65,7 @@
 
  private:
   // SaveCacheObserver implementation.
-  virtual void OnCacheSaveFinished(bool succeeded) override;
+  void OnCacheSaveFinished(bool succeeded) override;
 
   base::Closure task_;
   bool succeeded_;
@@ -203,7 +203,7 @@
   // We cannot access the database until the backend has been loaded.
   ASSERT_TRUE(profile_.CreateHistoryService(true, false));
   profile_.CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(
+  bookmarks::test::WaitForBookmarkModelToLoad(
       BookmarkModelFactory::GetForProfile(&profile_));
   profile_.BlockUntilHistoryProcessesPendingRequests();
   profile_.BlockUntilHistoryIndexIsRefreshed();
@@ -433,7 +433,7 @@
 
 class LimitedInMemoryURLIndexTest : public InMemoryURLIndexTest {
  protected:
-  virtual base::FilePath::StringType TestDBName() const override;
+  base::FilePath::StringType TestDBName() const override;
 };
 
 base::FilePath::StringType LimitedInMemoryURLIndexTest::TestDBName() const {
diff --git a/chrome/browser/history/top_sites.h b/chrome/browser/history/top_sites.h
index 898bf27..3f5260f 100644
--- a/chrome/browser/history/top_sites.h
+++ b/chrome/browser/history/top_sites.h
@@ -178,7 +178,7 @@
  protected:
   void NotifyTopSitesLoaded();
   void NotifyTopSitesChanged();
-  virtual ~TopSites();
+  ~TopSites() override;
 
  private:
   ObserverList<TopSitesObserver> observer_list_;
diff --git a/chrome/browser/history/top_sites_impl.h b/chrome/browser/history/top_sites_impl.h
index f71b6b1c3..cea6f84d 100644
--- a/chrome/browser/history/top_sites_impl.h
+++ b/chrome/browser/history/top_sites_impl.h
@@ -53,44 +53,38 @@
   // Initializes TopSitesImpl.
   void Init(const base::FilePath& db_name);
 
-  virtual bool SetPageThumbnail(const GURL& url,
-                                const gfx::Image& thumbnail,
-                                const ThumbnailScore& score) override;
-  virtual bool SetPageThumbnailToJPEGBytes(
-      const GURL& url,
-      const base::RefCountedMemory* memory,
-      const ThumbnailScore& score) override;
-  virtual void GetMostVisitedURLs(
-      const GetMostVisitedURLsCallback& callback,
-      bool include_forced_urls) override;
-  virtual bool GetPageThumbnail(
-      const GURL& url,
-      bool prefix_match,
-      scoped_refptr<base::RefCountedMemory>* bytes) override;
-  virtual bool GetPageThumbnailScore(const GURL& url,
-                                     ThumbnailScore* score) override;
-  virtual bool GetTemporaryPageThumbnailScore(const GURL& url,
-                                              ThumbnailScore* score) override;
-  virtual void SyncWithHistory() override;
-  virtual bool HasBlacklistedItems() const override;
-  virtual void AddBlacklistedURL(const GURL& url) override;
-  virtual void RemoveBlacklistedURL(const GURL& url) override;
-  virtual bool IsBlacklisted(const GURL& url) override;
-  virtual void ClearBlacklistedURLs() override;
-  virtual void Shutdown() override;
-  virtual base::CancelableTaskTracker::TaskId StartQueryForMostVisited()
-      override;
-  virtual bool IsKnownURL(const GURL& url) override;
-  virtual const std::string& GetCanonicalURLString(
-      const GURL& url) const override;
-  virtual bool IsNonForcedFull() override;
-  virtual bool IsForcedFull() override;
-  virtual MostVisitedURLList GetPrepopulatePages() override;
-  virtual bool loaded() const override;
-  virtual bool AddForcedURL(const GURL& url, const base::Time& time) override;
+  bool SetPageThumbnail(const GURL& url,
+                        const gfx::Image& thumbnail,
+                        const ThumbnailScore& score) override;
+  bool SetPageThumbnailToJPEGBytes(const GURL& url,
+                                   const base::RefCountedMemory* memory,
+                                   const ThumbnailScore& score) override;
+  void GetMostVisitedURLs(const GetMostVisitedURLsCallback& callback,
+                          bool include_forced_urls) override;
+  bool GetPageThumbnail(const GURL& url,
+                        bool prefix_match,
+                        scoped_refptr<base::RefCountedMemory>* bytes) override;
+  bool GetPageThumbnailScore(const GURL& url, ThumbnailScore* score) override;
+  bool GetTemporaryPageThumbnailScore(const GURL& url,
+                                      ThumbnailScore* score) override;
+  void SyncWithHistory() override;
+  bool HasBlacklistedItems() const override;
+  void AddBlacklistedURL(const GURL& url) override;
+  void RemoveBlacklistedURL(const GURL& url) override;
+  bool IsBlacklisted(const GURL& url) override;
+  void ClearBlacklistedURLs() override;
+  void Shutdown() override;
+  base::CancelableTaskTracker::TaskId StartQueryForMostVisited() override;
+  bool IsKnownURL(const GURL& url) override;
+  const std::string& GetCanonicalURLString(const GURL& url) const override;
+  bool IsNonForcedFull() override;
+  bool IsForcedFull() override;
+  MostVisitedURLList GetPrepopulatePages() override;
+  bool loaded() const override;
+  bool AddForcedURL(const GURL& url, const base::Time& time) override;
 
  protected:
-  virtual ~TopSitesImpl();
+  ~TopSitesImpl() override;
 
  private:
   friend class TopSitesImplTest;
@@ -180,9 +174,9 @@
   base::TimeDelta GetUpdateDelay();
 
   // Implementation of content::NotificationObserver.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Updates URLs in |cache_| and the db (in the background).
   // The non-forced URLs in |new_top_sites| replace those in |cache_|.
diff --git a/chrome/browser/history/top_sites_impl_unittest.cc b/chrome/browser/history/top_sites_impl_unittest.cc
index 59e0c6a..6514019 100644
--- a/chrome/browser/history/top_sites_impl_unittest.cc
+++ b/chrome/browser/history/top_sites_impl_unittest.cc
@@ -34,8 +34,8 @@
   explicit TestTopSitesObserver(Profile* profile, history::TopSites* top_sites);
   virtual ~TestTopSitesObserver();
   // TopSitesObserver:
-  virtual void TopSitesLoaded(history::TopSites* top_sites) override;
-  virtual void TopSitesChanged(history::TopSites* top_sites) override;
+  void TopSitesLoaded(history::TopSites* top_sites) override;
+  void TopSitesChanged(history::TopSites* top_sites) override;
 
  private:
   Profile* profile_;
@@ -76,17 +76,14 @@
  public:
   WaitForHistoryTask() {}
 
-  virtual bool RunOnDBThread(HistoryBackend* backend,
-                             HistoryDatabase* db) override {
+  bool RunOnDBThread(HistoryBackend* backend, HistoryDatabase* db) override {
     return true;
   }
 
-  virtual void DoneRunOnMainThread() override {
-    base::MessageLoop::current()->Quit();
-  }
+  void DoneRunOnMainThread() override { base::MessageLoop::current()->Quit(); }
 
  private:
-  virtual ~WaitForHistoryTask() {}
+  ~WaitForHistoryTask() override {}
 
   DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask);
 };
diff --git a/chrome/browser/history/typed_url_syncable_service.h b/chrome/browser/history/typed_url_syncable_service.h
index d342c20..a0303a9 100644
--- a/chrome/browser/history/typed_url_syncable_service.h
+++ b/chrome/browser/history/typed_url_syncable_service.h
@@ -38,20 +38,19 @@
 class TypedUrlSyncableService : public syncer::SyncableService {
  public:
   explicit TypedUrlSyncableService(HistoryBackend* history_backend);
-  virtual ~TypedUrlSyncableService();
+  ~TypedUrlSyncableService() override;
 
   static syncer::ModelType model_type() { return syncer::TYPED_URLS; }
 
   // syncer::SyncableService implementation.
-  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
+  syncer::SyncMergeResult MergeDataAndStartSyncing(
       syncer::ModelType type,
       const syncer::SyncDataList& initial_sync_data,
       scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
       scoped_ptr<syncer::SyncErrorFactory> error_handler) override;
-  virtual void StopSyncing(syncer::ModelType type) override;
-  virtual syncer::SyncDataList GetAllSyncData(
-      syncer::ModelType type) const override;
-  virtual syncer::SyncError ProcessSyncChanges(
+  void StopSyncing(syncer::ModelType type) override;
+  syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override;
+  syncer::SyncError ProcessSyncChanges(
       const tracked_objects::Location& from_here,
       const syncer::SyncChangeList& change_list) override;
 
diff --git a/chrome/browser/history/typed_url_syncable_service_unittest.cc b/chrome/browser/history/typed_url_syncable_service_unittest.cc
index ac4f1add..a8d3ba5f33 100644
--- a/chrome/browser/history/typed_url_syncable_service_unittest.cc
+++ b/chrome/browser/history/typed_url_syncable_service_unittest.cc
@@ -41,14 +41,13 @@
   TestHistoryBackend() : HistoryBackend(base::FilePath(), NULL, NULL) {}
 
   // HistoryBackend test implementation.
-  virtual bool IsExpiredVisitTime(const base::Time& time) override {
+  bool IsExpiredVisitTime(const base::Time& time) override {
     return time.ToInternalValue() == EXPIRED_VISIT;
   }
 
-  virtual bool GetMostRecentVisitsForURL(
-      URLID id,
-      int max_visits,
-      VisitVector* visits) override {
+  bool GetMostRecentVisitsForURL(URLID id,
+                                 int max_visits,
+                                 VisitVector* visits) override {
     if (local_db_visits_[id].empty())
       return false;
 
@@ -74,7 +73,7 @@
   }
 
  private:
-  virtual ~TestHistoryBackend() {}
+  ~TestHistoryBackend() override {}
 
   // Mock of visit table in local db.
   std::map<URLID, VisitVector> local_db_visits_;
diff --git a/chrome/browser/history/url_index_private_data.cc b/chrome/browser/history/url_index_private_data.cc
index fe6d1dd..cff1849 100644
--- a/chrome/browser/history/url_index_private_data.cc
+++ b/chrome/browser/history/url_index_private_data.cc
@@ -84,12 +84,12 @@
       URLIndexPrivateData* private_data,
       URLID url_id);
 
-  virtual bool RunOnDBThread(HistoryBackend* backend,
-                             history::HistoryDatabase* db) override;
-  virtual void DoneRunOnMainThread() override;
+  bool RunOnDBThread(HistoryBackend* backend,
+                     history::HistoryDatabase* db) override;
+  void DoneRunOnMainThread() override;
 
  private:
-  virtual ~UpdateRecentVisitsFromHistoryDBTask();
+  ~UpdateRecentVisitsFromHistoryDBTask() override;
 
   // The URLIndexPrivateData that gets updated after the historyDB
   // task returns.
diff --git a/chrome/browser/history/visit_database_unittest.cc b/chrome/browser/history/visit_database_unittest.cc
index 04fc4d3..c158d91 100644
--- a/chrome/browser/history/visit_database_unittest.cc
+++ b/chrome/browser/history/visit_database_unittest.cc
@@ -61,9 +61,7 @@
   }
 
   // Provided for URL/VisitDatabase.
-  virtual sql::Connection& GetDB() override {
-    return db_;
-  }
+  sql::Connection& GetDB() override { return db_; }
 
   base::ScopedTempDir temp_dir_;
   sql::Connection db_;
diff --git a/chrome/browser/history/web_history_service.cc b/chrome/browser/history/web_history_service.cc
index 1587daf..e5a8014d 100644
--- a/chrome/browser/history/web_history_service.cc
+++ b/chrome/browser/history/web_history_service.cc
@@ -49,8 +49,7 @@
                     private OAuth2TokenService::Consumer,
                     private net::URLFetcherDelegate {
  public:
-  virtual ~RequestImpl() {
-  }
+  ~RequestImpl() override {}
 
   // Returns the response code received from the server, which will only be
   // valid if the request succeeded.
@@ -59,7 +58,7 @@
   // Returns the contents of the response body received from the server.
   const std::string& response_body() { return response_body_; }
 
-  virtual bool is_pending() override { return is_pending_; }
+  bool is_pending() override { return is_pending_; }
 
  private:
   friend class history::WebHistoryService;
@@ -93,7 +92,7 @@
   }
 
   // content::URLFetcherDelegate interface.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override {
+  void OnURLFetchComplete(const net::URLFetcher* source) override {
     DCHECK_EQ(source, url_fetcher_.get());
     response_code_ = url_fetcher_->GetResponseCode();
 
@@ -128,10 +127,9 @@
   }
 
   // OAuth2TokenService::Consumer interface.
-  virtual void OnGetTokenSuccess(
-      const OAuth2TokenService::Request* request,
-      const std::string& access_token,
-      const base::Time& expiration_time) override {
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override {
     token_request_.reset();
     DCHECK(!access_token.empty());
     access_token_ = access_token;
@@ -143,9 +141,8 @@
     url_fetcher_->Start();
   }
 
-  virtual void OnGetTokenFailure(
-      const OAuth2TokenService::Request* request,
-      const GoogleServiceAuthError& error) override {
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override {
     token_request_.reset();
     is_pending_ = false;
 
diff --git a/chrome/browser/history/web_history_service.h b/chrome/browser/history/web_history_service.h
index 2e7c7e9..692efbb0 100644
--- a/chrome/browser/history/web_history_service.h
+++ b/chrome/browser/history/web_history_service.h
@@ -51,7 +51,7 @@
   typedef base::Callback<void(bool success)> ExpireWebHistoryCallback;
 
   explicit WebHistoryService(Profile* profile);
-  virtual ~WebHistoryService();
+  ~WebHistoryService() override;
 
   // Searches synced history for visits matching |text_query|. The timeframe to
   // search, along with other options, is specified in |options|. If
diff --git a/chrome/browser/history/web_history_service_factory.h b/chrome/browser/history/web_history_service_factory.h
index 1a6ee1e5..41b68dc 100644
--- a/chrome/browser/history/web_history_service_factory.h
+++ b/chrome/browser/history/web_history_service_factory.h
@@ -25,14 +25,14 @@
 
  protected:
   // Overridden from BrowserContextKeyedServiceFactory.
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
 
  private:
   friend struct DefaultSingletonTraits<WebHistoryServiceFactory>;
 
   explicit WebHistoryServiceFactory();
-  virtual ~WebHistoryServiceFactory();
+  ~WebHistoryServiceFactory() override;
 
   DISALLOW_COPY_AND_ASSIGN(WebHistoryServiceFactory);
 };
diff --git a/chrome/browser/icon_loader_win.cc b/chrome/browser/icon_loader_win.cc
index d0d77dc2..1368dffc 100644
--- a/chrome/browser/icon_loader_win.cc
+++ b/chrome/browser/icon_loader_win.cc
@@ -61,8 +61,7 @@
     scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(
         file_info.hIcon));
     if (bitmap.get()) {
-      gfx::ImageSkia image_skia(gfx::ImageSkiaRep(
-          *bitmap, gfx::win::GetDeviceScaleFactor()));
+      gfx::ImageSkia image_skia(gfx::ImageSkiaRep(*bitmap, gfx::GetDPIScale()));
       image_skia.MakeThreadSafe();
       image_.reset(new gfx::Image(image_skia));
       DestroyIcon(file_info.hIcon);
diff --git a/chrome/browser/importer/in_process_importer_bridge.cc b/chrome/browser/importer/in_process_importer_bridge.cc
index 22cd547..3bd1fde 100644
--- a/chrome/browser/importer/in_process_importer_bridge.cc
+++ b/chrome/browser/importer/in_process_importer_bridge.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/importer/in_process_importer_bridge.h"
 
 #include "base/bind.h"
-#include "base/debug/dump_without_crashing.h"
 #include "base/files/file_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -63,15 +62,6 @@
   return history::SOURCE_SYNCED;
 }
 
-// http://crbug.com/404012. Let's see where the empty fields come from.
-void CheckForEmptyUsernameAndPassword(const autofill::PasswordForm& form) {
-  if (form.username_value.empty() &&
-      form.password_value.empty() &&
-      !form.blacklisted_by_user) {
-    base::debug::DumpWithoutCrashing();
-  }
-}
-
 }  // namespace
 
 using content::BrowserThread;
@@ -261,7 +251,6 @@
 
 void InProcessImporterBridge::SetPasswordForm(
     const autofill::PasswordForm& form) {
-  CheckForEmptyUsernameAndPassword(form);
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::Bind(&ProfileWriter::AddPasswordForm, writer_, form));
diff --git a/chrome/browser/importer/profile_writer_unittest.cc b/chrome/browser/importer/profile_writer_unittest.cc
index afe24e6..f1327729 100644
--- a/chrome/browser/importer/profile_writer_unittest.cc
+++ b/chrome/browser/importer/profile_writer_unittest.cc
@@ -141,7 +141,7 @@
 
   BookmarkModel* bookmark_model2 =
       BookmarkModelFactory::GetForProfile(&profile2);
-  test::WaitForBookmarkModelToLoad(bookmark_model2);
+  bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model2);
   bookmarks::AddIfNotBookmarked(
       bookmark_model2, GURL("http://www.bing.com"), base::ASCIIToUTF16("Bing"));
   TestingProfile profile1;
@@ -150,7 +150,7 @@
   CreateImportedBookmarksEntries();
   BookmarkModel* bookmark_model1 =
       BookmarkModelFactory::GetForProfile(&profile1);
-  test::WaitForBookmarkModelToLoad(bookmark_model1);
+  bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model1);
 
   scoped_refptr<TestProfileWriter> profile_writer(
       new TestProfileWriter(&profile1));
@@ -174,7 +174,7 @@
   CreateImportedBookmarksEntries();
   BookmarkModel* bookmark_model =
       BookmarkModelFactory::GetForProfile(&profile);
-  test::WaitForBookmarkModelToLoad(bookmark_model);
+  bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
 
   scoped_refptr<TestProfileWriter> profile_writer(
       new TestProfileWriter(&profile));
diff --git a/chrome/browser/lifetime/browser_close_manager_browsertest.cc b/chrome/browser/lifetime/browser_close_manager_browsertest.cc
index dd5fae9..c0768e7 100644
--- a/chrome/browser/lifetime/browser_close_manager_browsertest.cc
+++ b/chrome/browser/lifetime/browser_close_manager_browsertest.cc
@@ -21,8 +21,6 @@
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_iterator.h"
@@ -32,6 +30,8 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/download_manager.h"
@@ -49,50 +49,22 @@
 
 namespace {
 
-class AppModalDialogObserver {
- public:
-  AppModalDialogObserver() {}
+NativeAppModalDialog* GetNextDialog() {
+  AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
+  EXPECT_TRUE(dialog->IsJavaScriptModalDialog());
+  JavaScriptAppModalDialog* js_dialog =
+      static_cast<JavaScriptAppModalDialog*>(dialog);
+  CHECK(js_dialog->native_dialog());
+  return js_dialog->native_dialog();
+}
 
-  void Start() {
-    observer_.reset(new content::WindowedNotificationObserver(
-        chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
-        content::NotificationService::AllSources()));
-  }
+void AcceptClose() {
+  GetNextDialog()->AcceptAppModalDialog();
+}
 
-  void AcceptClose() {
-    NativeAppModalDialog* dialog = GetNextDialog();
-    ASSERT_TRUE(dialog);
-    dialog->AcceptAppModalDialog();
-  }
-
-  void CancelClose() {
-    NativeAppModalDialog* dialog = GetNextDialog();
-    ASSERT_TRUE(dialog);
-    dialog->CancelAppModalDialog();
-  }
-
- private:
-  NativeAppModalDialog* GetNextDialog() {
-    DCHECK(observer_);
-    observer_->Wait();
-    if (observer_->source() == content::NotificationService::AllSources())
-      return NULL;
-
-    AppModalDialog* dialog =
-        content::Source<AppModalDialog>(observer_->source()).ptr();
-    EXPECT_TRUE(dialog->IsJavaScriptModalDialog());
-    JavaScriptAppModalDialog* js_dialog =
-        static_cast<JavaScriptAppModalDialog*>(dialog);
-    observer_.reset(new content::WindowedNotificationObserver(
-        chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
-        content::NotificationService::AllSources()));
-    return js_dialog->native_dialog();
-  }
-
-  scoped_ptr<content::WindowedNotificationObserver> observer_;
-
-  DISALLOW_COPY_AND_ASSIGN(AppModalDialogObserver);
-};
+void CancelClose() {
+  GetNextDialog()->CancelAppModalDialog();
+}
 
 class RepeatedNotificationObserver : public content::NotificationObserver {
  public:
@@ -242,7 +214,6 @@
     SessionStartupPref::SetStartupPref(
         browser()->profile(), SessionStartupPref(SessionStartupPref::LAST));
     browsers_.push_back(browser());
-    dialogs_.Start();
     content::BrowserThread::PostTask(
         content::BrowserThread::IO,
         FROM_HERE,
@@ -273,7 +244,6 @@
   }
 
   std::vector<Browser*> browsers_;
-  AppModalDialogObserver dialogs_;
 };
 
 IN_PROC_BROWSER_TEST_P(BrowserCloseManagerBrowserTest, TestSingleTabShutdown) {
@@ -283,7 +253,7 @@
   RepeatedNotificationObserver cancel_observer(
       chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
@@ -291,7 +261,7 @@
   RepeatedNotificationObserver close_observer(
       chrome::NOTIFICATION_BROWSER_CLOSED, 1);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
@@ -306,7 +276,7 @@
       chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
   chrome::CloseAllBrowsersAndQuit();
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
@@ -315,7 +285,7 @@
       chrome::NOTIFICATION_BROWSER_CLOSED, 1);
   chrome::CloseAllBrowsersAndQuit();
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
@@ -331,7 +301,7 @@
   RepeatedNotificationObserver cancel_observer(
       chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
 
@@ -344,7 +314,7 @@
                                    GURL(chrome::kChromeUIVersionURL),
                                    CURRENT_TAB,
                                    ui_test_utils::BROWSER_TEST_NONE));
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   navigation_observer.Wait();
 
   RepeatedNotificationObserver close_observer(
@@ -381,7 +351,7 @@
     RepeatedNotificationObserver cancel_observer(
         chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
     chrome::CloseAllBrowsersAndQuit();
-    ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+    ASSERT_NO_FATAL_FAILURE(CancelClose());
     cancel_observer.Wait();
   }
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
@@ -393,8 +363,8 @@
     RepeatedNotificationObserver cancel_observer(
         chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
     chrome::CloseAllBrowsersAndQuit();
-    ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-    ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+    ASSERT_NO_FATAL_FAILURE(AcceptClose());
+    ASSERT_NO_FATAL_FAILURE(CancelClose());
     cancel_observer.Wait();
   }
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
@@ -405,8 +375,8 @@
   RepeatedNotificationObserver close_observer(
       chrome::NOTIFICATION_BROWSER_CLOSED, 2);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
@@ -438,7 +408,7 @@
   RepeatedNotificationObserver cancel_observer(
       chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 1);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   // All tabs should still be open.
@@ -447,7 +417,7 @@
   RepeatedNotificationObserver close_observer(
       chrome::NOTIFICATION_BROWSER_CLOSED, 1);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
@@ -471,7 +441,7 @@
   RepeatedNotificationObserver cancel_observer(
       chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   // All windows should still be open.
@@ -482,7 +452,7 @@
   RepeatedNotificationObserver close_observer(
       chrome::NOTIFICATION_BROWSER_CLOSED, 3);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
@@ -499,7 +469,7 @@
       chrome::NOTIFICATION_BROWSER_CLOSED, 2);
   chrome::CloseAllBrowsersAndQuit();
   browsers_.push_back(CreateBrowser(browser()->profile()));
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
@@ -519,8 +489,8 @@
   browsers_.push_back(CreateBrowser(browser()->profile()));
   ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
       browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
@@ -530,8 +500,8 @@
   RepeatedNotificationObserver close_observer(
       chrome::NOTIFICATION_BROWSER_CLOSED, 2);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
@@ -550,10 +520,10 @@
   RepeatedNotificationObserver close_observer(
       chrome::NOTIFICATION_BROWSER_CLOSED, 2);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   AddBlankTabAndShow(browsers_[0]);
   AddBlankTabAndShow(browsers_[1]);
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
@@ -572,15 +542,15 @@
   RepeatedNotificationObserver cancel_observer(
       chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, 2);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   AddBlankTabAndShow(browsers_[0]);
   ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
       browsers_[0], embedded_test_server()->GetURL("/beforeunload.html")));
   AddBlankTabAndShow(browsers_[1]);
   ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
       browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   EXPECT_EQ(2, browsers_[0]->tab_strip_model()->count());
@@ -589,10 +559,10 @@
   RepeatedNotificationObserver close_observer(
       chrome::NOTIFICATION_BROWSER_CLOSED, 2);
   chrome::CloseAllBrowsersAndQuit();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
 
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
@@ -612,8 +582,8 @@
   ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
       browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
   browsers_[1]->tab_strip_model()->CloseAllTabs();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
@@ -623,8 +593,8 @@
       chrome::NOTIFICATION_BROWSER_CLOSED, 2);
   chrome::CloseAllBrowsersAndQuit();
   browsers_[1]->tab_strip_model()->CloseAllTabs();
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
 
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
@@ -652,8 +622,8 @@
   ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(
       browsers_[1], embedded_test_server()->GetURL("/beforeunload.html")));
   ASSERT_FALSE(browsers_[1]->ShouldCloseWindow());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
@@ -663,8 +633,8 @@
       chrome::NOTIFICATION_BROWSER_CLOSED, 2);
   chrome::CloseAllBrowsersAndQuit();
   ASSERT_FALSE(browsers_[1]->ShouldCloseWindow());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
 
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
@@ -684,7 +654,7 @@
   chrome::CloseAllBrowsersAndQuit();
 
   ASSERT_FALSE(browsers_[0]->ShouldCloseWindow());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.CancelClose());
+  ASSERT_NO_FATAL_FAILURE(CancelClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
   EXPECT_EQ(1, browsers_[0]->tab_strip_model()->count());
@@ -694,8 +664,8 @@
       chrome::NOTIFICATION_BROWSER_CLOSED, 2);
   chrome::CloseAllBrowsersAndQuit();
   ASSERT_FALSE(browsers_[0]->ShouldCloseWindow());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
 
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
@@ -871,7 +841,7 @@
       content::NotificationService::AllSources());
   TestBrowserCloseManager::AttemptClose(
       TestBrowserCloseManager::USER_CHOICE_USER_CANCELS_CLOSE);
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   cancel_observer.Wait();
   EXPECT_FALSE(browser_shutdown::IsTryingToQuit());
 
@@ -879,7 +849,7 @@
       chrome::NOTIFICATION_BROWSER_CLOSED, 1);
   TestBrowserCloseManager::AttemptClose(
       TestBrowserCloseManager::USER_CHOICE_USER_ALLOWS_CLOSE);
-  ASSERT_NO_FATAL_FAILURE(dialogs_.AcceptClose());
+  ASSERT_NO_FATAL_FAILURE(AcceptClose());
   close_observer.Wait();
   EXPECT_TRUE(browser_shutdown::IsTryingToQuit());
   EXPECT_TRUE(chrome::BrowserIterator().done());
diff --git a/chrome/browser/local_discovery/cloud_device_list.h b/chrome/browser/local_discovery/cloud_device_list.h
index baff562..1f75efd 100644
--- a/chrome/browser/local_discovery/cloud_device_list.h
+++ b/chrome/browser/local_discovery/cloud_device_list.h
@@ -20,14 +20,13 @@
   typedef DeviceList::const_iterator iterator;
 
   explicit CloudDeviceList(CloudDeviceListDelegate* delegate);
-  virtual ~CloudDeviceList();
+  ~CloudDeviceList() override;
 
-  virtual void OnGCDAPIFlowError(GCDApiFlow::Status status) override;
+  void OnGCDAPIFlowError(GCDApiFlow::Status status) override;
 
-  virtual void OnGCDAPIFlowComplete(
-      const base::DictionaryValue& value) override;
+  void OnGCDAPIFlowComplete(const base::DictionaryValue& value) override;
 
-  virtual GURL GetURL() override;
+  GURL GetURL() override;
 
  private:
   bool FillDeviceDetails(const base::DictionaryValue& value,
diff --git a/chrome/browser/local_discovery/cloud_print_printer_list.h b/chrome/browser/local_discovery/cloud_print_printer_list.h
index 343fa48..f4858eeb 100644
--- a/chrome/browser/local_discovery/cloud_print_printer_list.h
+++ b/chrome/browser/local_discovery/cloud_print_printer_list.h
@@ -17,14 +17,13 @@
 class CloudPrintPrinterList : public CloudPrintApiFlowRequest {
  public:
   explicit CloudPrintPrinterList(CloudDeviceListDelegate* delegate);
-  virtual ~CloudPrintPrinterList();
+  ~CloudPrintPrinterList() override;
 
-  virtual void OnGCDAPIFlowError(GCDApiFlow::Status status) override;
+  void OnGCDAPIFlowError(GCDApiFlow::Status status) override;
 
-  virtual void OnGCDAPIFlowComplete(
-      const base::DictionaryValue& value) override;
+  void OnGCDAPIFlowComplete(const base::DictionaryValue& value) override;
 
-  virtual GURL GetURL() override;
+  GURL GetURL() override;
 
  private:
   bool FillPrinterDetails(const base::DictionaryValue& printer_value,
diff --git a/chrome/browser/local_discovery/gcd_api_flow.h b/chrome/browser/local_discovery/gcd_api_flow.h
index 42807fd..6892a2c1 100644
--- a/chrome/browser/local_discovery/gcd_api_flow.h
+++ b/chrome/browser/local_discovery/gcd_api_flow.h
@@ -70,11 +70,11 @@
 class GCDApiFlowRequest : public GCDApiFlow::Request {
  public:
   GCDApiFlowRequest();
-  virtual ~GCDApiFlowRequest();
+  ~GCDApiFlowRequest() override;
 
   // GCDApiFlowRequest implementation
-  virtual std::string GetOAuthScope() override;
-  virtual std::vector<std::string> GetExtraRequestHeaders() override;
+  std::string GetOAuthScope() override;
+  std::vector<std::string> GetExtraRequestHeaders() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(GCDApiFlowRequest);
@@ -83,11 +83,11 @@
 class CloudPrintApiFlowRequest : public GCDApiFlow::Request {
  public:
   CloudPrintApiFlowRequest();
-  virtual ~CloudPrintApiFlowRequest();
+  ~CloudPrintApiFlowRequest() override;
 
   // GCDApiFlowRequest implementation
-  virtual std::string GetOAuthScope() override;
-  virtual std::vector<std::string> GetExtraRequestHeaders() override;
+  std::string GetOAuthScope() override;
+  std::vector<std::string> GetExtraRequestHeaders() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CloudPrintApiFlowRequest);
diff --git a/chrome/browser/local_discovery/gcd_api_flow_impl.h b/chrome/browser/local_discovery/gcd_api_flow_impl.h
index f206e937..6786e23e 100644
--- a/chrome/browser/local_discovery/gcd_api_flow_impl.h
+++ b/chrome/browser/local_discovery/gcd_api_flow_impl.h
@@ -24,19 +24,19 @@
                  OAuth2TokenService* token_service,
                  const std::string& account_id);
 
-  virtual ~GCDApiFlowImpl();
+  ~GCDApiFlowImpl() override;
 
-  virtual void Start(scoped_ptr<Request> request) override;
+  void Start(scoped_ptr<Request> request) override;
 
   // net::URLFetcherDelegate implementation:
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // OAuth2TokenService::Consumer implementation:
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
  private:
   void CreateRequest(const GURL& url);
diff --git a/chrome/browser/local_discovery/gcd_registration_ticket_request.h b/chrome/browser/local_discovery/gcd_registration_ticket_request.h
index 3956e4d..d109eb0 100644
--- a/chrome/browser/local_discovery/gcd_registration_ticket_request.h
+++ b/chrome/browser/local_discovery/gcd_registration_ticket_request.h
@@ -21,16 +21,15 @@
                               const std::string& device_id)> ResponseCallback;
 
   explicit GCDRegistrationTicketRequest(const ResponseCallback& callback);
-  virtual ~GCDRegistrationTicketRequest();
+  ~GCDRegistrationTicketRequest() override;
 
   // GCDApiFlowImpl::Request implementation.
-  virtual void GetUploadData(std::string* upload_type,
-                             std::string* upload_data) override;
-  virtual net::URLFetcher::RequestType GetRequestType() override;
-  virtual void OnGCDAPIFlowError(GCDApiFlow::Status status) override;
-  virtual void OnGCDAPIFlowComplete(
-      const base::DictionaryValue& value) override;
-  virtual GURL GetURL() override;
+  void GetUploadData(std::string* upload_type,
+                     std::string* upload_data) override;
+  net::URLFetcher::RequestType GetRequestType() override;
+  void OnGCDAPIFlowError(GCDApiFlow::Status status) override;
+  void OnGCDAPIFlowComplete(const base::DictionaryValue& value) override;
+  GURL GetURL() override;
 
  private:
   ResponseCallback callback_;
diff --git a/chrome/browser/local_discovery/privet_confirm_api_flow.h b/chrome/browser/local_discovery/privet_confirm_api_flow.h
index de1e8d31a..5107247 100644
--- a/chrome/browser/local_discovery/privet_confirm_api_flow.h
+++ b/chrome/browser/local_discovery/privet_confirm_api_flow.h
@@ -22,14 +22,13 @@
   PrivetConfirmApiCallFlow(const std::string& token,
                            const ResponseCallback& callback);
 
-  virtual ~PrivetConfirmApiCallFlow();
+  ~PrivetConfirmApiCallFlow() override;
 
-  virtual void OnGCDAPIFlowError(GCDApiFlow::Status status) override;
-  virtual void OnGCDAPIFlowComplete(
-      const base::DictionaryValue& value) override;
-  virtual net::URLFetcher::RequestType GetRequestType() override;
+  void OnGCDAPIFlowError(GCDApiFlow::Status status) override;
+  void OnGCDAPIFlowComplete(const base::DictionaryValue& value) override;
+  net::URLFetcher::RequestType GetRequestType() override;
 
-  virtual GURL GetURL() override;
+  GURL GetURL() override;
 
  private:
   ResponseCallback callback_;
diff --git a/chrome/browser/local_discovery/privet_device_lister_impl.h b/chrome/browser/local_discovery/privet_device_lister_impl.h
index 22927185..2a41009 100644
--- a/chrome/browser/local_discovery/privet_device_lister_impl.h
+++ b/chrome/browser/local_discovery/privet_device_lister_impl.h
@@ -26,17 +26,16 @@
       ServiceDiscoveryClient* service_discovery_client,
       PrivetDeviceLister::Delegate* delegate);
 
-  virtual ~PrivetDeviceListerImpl();
+  ~PrivetDeviceListerImpl() override;
 
-  virtual void Start() override;
-  virtual void DiscoverNewDevices(bool force_update) override;
+  void Start() override;
+  void DiscoverNewDevices(bool force_update) override;
 
  protected:
-  virtual void OnDeviceChanged(
-      bool added,
-      const ServiceDescription& service_description) override;
-  virtual void OnDeviceRemoved(const std::string& service_name) override;
-  virtual void OnDeviceCacheFlushed() override;
+  void OnDeviceChanged(bool added,
+                       const ServiceDescription& service_description) override;
+  void OnDeviceRemoved(const std::string& service_name) override;
+  void OnDeviceCacheFlushed() override;
 
  private:
   PrivetDeviceLister::Delegate* delegate_;
diff --git a/chrome/browser/local_discovery/privet_http_asynchronous_factory_mac.h b/chrome/browser/local_discovery/privet_http_asynchronous_factory_mac.h
index 4d54648..ba7c96b 100644
--- a/chrome/browser/local_discovery/privet_http_asynchronous_factory_mac.h
+++ b/chrome/browser/local_discovery/privet_http_asynchronous_factory_mac.h
@@ -14,9 +14,9 @@
  public:
   explicit PrivetHTTPAsynchronousFactoryMac(
       net::URLRequestContextGetter* request_context);
-  virtual ~PrivetHTTPAsynchronousFactoryMac();
+  ~PrivetHTTPAsynchronousFactoryMac() override;
 
-  virtual scoped_ptr<PrivetHTTPResolution> CreatePrivetHTTP(
+  scoped_ptr<PrivetHTTPResolution> CreatePrivetHTTP(
       const std::string& name,
       const net::HostPortPair& address,
       const ResultCallback& callback) override;
@@ -28,10 +28,10 @@
                   const std::string& name,
                   const net::HostPortPair& host_port,
                   const ResultCallback& callback);
-    virtual ~ResolutionMac();
+    ~ResolutionMac() override;
 
-    virtual void Start() override;
-    virtual const std::string& GetName() override;
+    void Start() override;
+    const std::string& GetName() override;
 
    private:
     net::URLRequestContextGetter* request_context_;
diff --git a/chrome/browser/local_discovery/privet_http_impl.h b/chrome/browser/local_discovery/privet_http_impl.h
index cfcef7b..acd13c0 100644
--- a/chrome/browser/local_discovery/privet_http_impl.h
+++ b/chrome/browser/local_discovery/privet_http_impl.h
@@ -29,17 +29,17 @@
  public:
   PrivetInfoOperationImpl(PrivetHTTPClient* privet_client,
                           const PrivetJSONOperation::ResultCallback& callback);
-  virtual ~PrivetInfoOperationImpl();
+  ~PrivetInfoOperationImpl() override;
 
-  virtual void Start() override;
+  void Start() override;
 
-  virtual PrivetHTTPClient* GetHTTPClient() override;
+  PrivetHTTPClient* GetHTTPClient() override;
 
-  virtual void OnError(PrivetURLFetcher* fetcher,
-                       PrivetURLFetcher::ErrorType error) override;
-  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
-                            const base::DictionaryValue& value,
-                            bool has_error) override;
+  void OnError(PrivetURLFetcher* fetcher,
+               PrivetURLFetcher::ErrorType error) override;
+  void OnParsedJson(PrivetURLFetcher* fetcher,
+                    const base::DictionaryValue& value,
+                    bool has_error) override;
 
  private:
   PrivetHTTPClient* privet_client_;
@@ -55,36 +55,37 @@
   PrivetRegisterOperationImpl(PrivetHTTPClient* privet_client,
                               const std::string& user,
                               PrivetRegisterOperation::Delegate* delegate);
-  virtual ~PrivetRegisterOperationImpl();
+  ~PrivetRegisterOperationImpl() override;
 
-  virtual void Start() override;
-  virtual void Cancel() override;
-  virtual void CompleteRegistration() override;
+  void Start() override;
+  void Cancel() override;
+  void CompleteRegistration() override;
 
-  virtual void OnError(PrivetURLFetcher* fetcher,
-                       PrivetURLFetcher::ErrorType error) override;
+  void OnError(PrivetURLFetcher* fetcher,
+               PrivetURLFetcher::ErrorType error) override;
 
-  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
-                            const base::DictionaryValue& value,
-                            bool has_error) override;
+  void OnParsedJson(PrivetURLFetcher* fetcher,
+                    const base::DictionaryValue& value,
+                    bool has_error) override;
 
-  virtual void OnNeedPrivetToken(
+  void OnNeedPrivetToken(
       PrivetURLFetcher* fetcher,
       const PrivetURLFetcher::TokenCallback& callback) override;
 
-  virtual PrivetHTTPClient* GetHTTPClient() override;
+  PrivetHTTPClient* GetHTTPClient() override;
+
  private:
   class Cancelation : public PrivetURLFetcher::Delegate {
    public:
     Cancelation(PrivetHTTPClient* privet_client, const std::string& user);
-    virtual ~Cancelation();
+    ~Cancelation() override;
 
-    virtual void OnError(PrivetURLFetcher* fetcher,
-                         PrivetURLFetcher::ErrorType error) override;
+    void OnError(PrivetURLFetcher* fetcher,
+                 PrivetURLFetcher::ErrorType error) override;
 
-    virtual void OnParsedJson(PrivetURLFetcher* fetcher,
-                              const base::DictionaryValue& value,
-                              bool has_error) override;
+    void OnParsedJson(PrivetURLFetcher* fetcher,
+                      const base::DictionaryValue& value,
+                      bool has_error) override;
 
     void Cleanup();
 
@@ -126,17 +127,17 @@
                           const std::string& path,
                           const std::string& query_params,
                           const PrivetJSONOperation::ResultCallback& callback);
-  virtual ~PrivetJSONOperationImpl();
-  virtual void Start() override;
+  ~PrivetJSONOperationImpl() override;
+  void Start() override;
 
-  virtual PrivetHTTPClient* GetHTTPClient() override;
+  PrivetHTTPClient* GetHTTPClient() override;
 
-  virtual void OnError(PrivetURLFetcher* fetcher,
-                       PrivetURLFetcher::ErrorType error) override;
-  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
-                            const base::DictionaryValue& value,
-                            bool has_error) override;
-  virtual void OnNeedPrivetToken(
+  void OnError(PrivetURLFetcher* fetcher,
+               PrivetURLFetcher::ErrorType error) override;
+  void OnParsedJson(PrivetURLFetcher* fetcher,
+                    const base::DictionaryValue& value,
+                    bool has_error) override;
+  void OnNeedPrivetToken(
       PrivetURLFetcher* fetcher,
       const PrivetURLFetcher::TokenCallback& callback) override;
 
@@ -157,28 +158,28 @@
       const std::string& path,
       const std::string& query_params,
       const PrivetDataReadOperation::ResultCallback& callback);
-  virtual ~PrivetDataReadOperationImpl();
+  ~PrivetDataReadOperationImpl() override;
 
-  virtual void Start() override;
+  void Start() override;
 
-  virtual void SetDataRange(int range_start, int range_end) override;
+  void SetDataRange(int range_start, int range_end) override;
 
-  virtual void SaveDataToFile() override;
+  void SaveDataToFile() override;
 
-  virtual PrivetHTTPClient* GetHTTPClient() override;
+  PrivetHTTPClient* GetHTTPClient() override;
 
-  virtual void OnError(PrivetURLFetcher* fetcher,
-                       PrivetURLFetcher::ErrorType error) override;
-  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
-                            const base::DictionaryValue& value,
-                            bool has_error) override;
-  virtual void OnNeedPrivetToken(
+  void OnError(PrivetURLFetcher* fetcher,
+               PrivetURLFetcher::ErrorType error) override;
+  void OnParsedJson(PrivetURLFetcher* fetcher,
+                    const base::DictionaryValue& value,
+                    bool has_error) override;
+  void OnNeedPrivetToken(
       PrivetURLFetcher* fetcher,
       const PrivetURLFetcher::TokenCallback& callback) override;
-  virtual bool OnRawData(PrivetURLFetcher* fetcher,
-                         bool is_file,
-                         const std::string& data_str,
-                         const base::FilePath& file_path) override;
+  bool OnRawData(PrivetURLFetcher* fetcher,
+                 bool is_file,
+                 const std::string& data_str,
+                 const base::FilePath& file_path) override;
 
  private:
   PrivetHTTPClient* privet_client_;
@@ -202,35 +203,34 @@
   PrivetLocalPrintOperationImpl(PrivetHTTPClient* privet_client,
                                 PrivetLocalPrintOperation::Delegate* delegate);
 
-  virtual ~PrivetLocalPrintOperationImpl();
-  virtual void Start() override;
+  ~PrivetLocalPrintOperationImpl() override;
+  void Start() override;
 
-  virtual void SetData(
-      const scoped_refptr<base::RefCountedBytes>& data) override;
+  void SetData(const scoped_refptr<base::RefCountedBytes>& data) override;
 
-  virtual void SetCapabilities(const std::string& capabilities) override;
+  void SetCapabilities(const std::string& capabilities) override;
 
-  virtual void SetTicket(const std::string& ticket) override;
+  void SetTicket(const std::string& ticket) override;
 
-  virtual void SetUsername(const std::string& user) override;
+  void SetUsername(const std::string& user) override;
 
-  virtual void SetJobname(const std::string& jobname) override;
+  void SetJobname(const std::string& jobname) override;
 
-  virtual void SetOffline(bool offline) override;
+  void SetOffline(bool offline) override;
 
-  virtual void SetPageSize(const gfx::Size& page_size) override;
+  void SetPageSize(const gfx::Size& page_size) override;
 
-  virtual void SetPWGRasterConverterForTesting(
+  void SetPWGRasterConverterForTesting(
       scoped_ptr<PWGRasterConverter> pwg_raster_converter) override;
 
-  virtual PrivetHTTPClient* GetHTTPClient() override;
+  PrivetHTTPClient* GetHTTPClient() override;
 
-  virtual void OnError(PrivetURLFetcher* fetcher,
-                       PrivetURLFetcher::ErrorType error) override;
-  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
-                            const base::DictionaryValue& value,
-                            bool has_error) override;
-  virtual void OnNeedPrivetToken(
+  void OnError(PrivetURLFetcher* fetcher,
+               PrivetURLFetcher::ErrorType error) override;
+  void OnParsedJson(PrivetURLFetcher* fetcher,
+                    const base::DictionaryValue& value,
+                    bool has_error) override;
+  void OnNeedPrivetToken(
       PrivetURLFetcher* fetcher,
       const PrivetURLFetcher::TokenCallback& callback) override;
 
@@ -292,17 +292,17 @@
       const std::string& name,
       const net::HostPortPair& host_port,
       net::URLRequestContextGetter* request_context);
-  virtual ~PrivetHTTPClientImpl();
+  ~PrivetHTTPClientImpl() override;
 
   // PrivetHTTPClient implementation.
-  virtual const std::string& GetName() override;
-  virtual scoped_ptr<PrivetJSONOperation> CreateInfoOperation(
+  const std::string& GetName() override;
+  scoped_ptr<PrivetJSONOperation> CreateInfoOperation(
       const PrivetJSONOperation::ResultCallback& callback) override;
-  virtual scoped_ptr<PrivetURLFetcher> CreateURLFetcher(
+  scoped_ptr<PrivetURLFetcher> CreateURLFetcher(
       const GURL& url,
       net::URLFetcher::RequestType request_type,
       PrivetURLFetcher::Delegate* delegate) override;
-  virtual void RefreshPrivetToken(
+  void RefreshPrivetToken(
       const PrivetURLFetcher::TokenCallback& token_callback) override;
 
  private:
@@ -323,17 +323,17 @@
 class PrivetV1HTTPClientImpl : public PrivetV1HTTPClient {
  public:
   explicit PrivetV1HTTPClientImpl(scoped_ptr<PrivetHTTPClient> info_client);
-  virtual ~PrivetV1HTTPClientImpl();
+  ~PrivetV1HTTPClientImpl() override;
 
-  virtual const std::string& GetName() override;
-  virtual scoped_ptr<PrivetJSONOperation> CreateInfoOperation(
+  const std::string& GetName() override;
+  scoped_ptr<PrivetJSONOperation> CreateInfoOperation(
       const PrivetJSONOperation::ResultCallback& callback) override;
-  virtual scoped_ptr<PrivetRegisterOperation> CreateRegisterOperation(
+  scoped_ptr<PrivetRegisterOperation> CreateRegisterOperation(
       const std::string& user,
       PrivetRegisterOperation::Delegate* delegate) override;
-  virtual scoped_ptr<PrivetJSONOperation> CreateCapabilitiesOperation(
+  scoped_ptr<PrivetJSONOperation> CreateCapabilitiesOperation(
       const PrivetJSONOperation::ResultCallback& callback) override;
-  virtual scoped_ptr<PrivetLocalPrintOperation> CreateLocalPrintOperation(
+  scoped_ptr<PrivetLocalPrintOperation> CreateLocalPrintOperation(
       PrivetLocalPrintOperation::Delegate* delegate) override;
 
  private:
diff --git a/chrome/browser/local_discovery/privet_http_unittest.cc b/chrome/browser/local_discovery/privet_http_unittest.cc
index 44fbd24..a3f04af 100644
--- a/chrome/browser/local_discovery/privet_http_unittest.cc
+++ b/chrome/browser/local_discovery/privet_http_unittest.cc
@@ -762,13 +762,12 @@
   FakePWGRasterConverter() {
   }
 
-  virtual ~FakePWGRasterConverter() {
-  }
+  ~FakePWGRasterConverter() override {}
 
-  virtual void Start(base::RefCountedMemory* data,
-                     const printing::PdfRenderSettings& conversion_settings,
-                     const printing::PwgRasterSettings& bitmap_settings,
-                     const ResultCallback& callback) override {
+  void Start(base::RefCountedMemory* data,
+             const printing::PdfRenderSettings& conversion_settings,
+             const printing::PwgRasterSettings& bitmap_settings,
+             const ResultCallback& callback) override {
     bitmap_settings_ = bitmap_settings;
     std::string data_str(data->front_as<char>(), data->size());
     callback.Run(true, base::FilePath().AppendASCII(data_str + "test.pdf"));
diff --git a/chrome/browser/local_discovery/privet_local_printer_lister.h b/chrome/browser/local_discovery/privet_local_printer_lister.h
index 037d7d15..cdb99e90 100644
--- a/chrome/browser/local_discovery/privet_local_printer_lister.h
+++ b/chrome/browser/local_discovery/privet_local_printer_lister.h
@@ -45,11 +45,11 @@
   const DeviceDescription* GetDeviceDescription(const std::string& name);
 
   // PrivetDeviceLister::Delegate implementation.
-  virtual void DeviceChanged(bool added,
-                             const std::string& name,
-                             const DeviceDescription& description) override;
-  virtual void DeviceRemoved(const std::string& name) override;
-  virtual void DeviceCacheFlushed() override;
+  void DeviceChanged(bool added,
+                     const std::string& name,
+                     const DeviceDescription& description) override;
+  void DeviceRemoved(const std::string& name) override;
+  void DeviceCacheFlushed() override;
 
  private:
   struct DeviceContext;
diff --git a/chrome/browser/local_discovery/privet_notifications.h b/chrome/browser/local_discovery/privet_notifications.h
index aae7cdd5..f71f71b 100644
--- a/chrome/browser/local_discovery/privet_notifications.h
+++ b/chrome/browser/local_discovery/privet_notifications.h
@@ -95,18 +95,19 @@
       public base::SupportsWeakPtr<PrivetNotificationService> {
  public:
   explicit PrivetNotificationService(content::BrowserContext* profile);
-  virtual ~PrivetNotificationService();
+  ~PrivetNotificationService() override;
 
   // PrivetDeviceLister::Delegate implementation:
-  virtual void DeviceChanged(bool added, const std::string& name,
-                             const DeviceDescription& description) override;
-  virtual void DeviceRemoved(const std::string& name) override;
+  void DeviceChanged(bool added,
+                     const std::string& name,
+                     const DeviceDescription& description) override;
+  void DeviceRemoved(const std::string& name) override;
 
   // PrivetNotificationListener::Delegate implementation:
-  virtual void PrivetNotify(bool has_multiple, bool added) override;
+  void PrivetNotify(bool has_multiple, bool added) override;
 
-  virtual void PrivetRemoveNotification() override;
-  virtual void DeviceCacheFlushed() override;
+  void PrivetRemoveNotification() override;
+  void DeviceCacheFlushed() override;
 
   static bool IsEnabled();
   static bool IsForced();
@@ -132,18 +133,18 @@
   explicit PrivetNotificationDelegate(content::BrowserContext* profile);
 
   // NotificationDelegate implementation.
-  virtual std::string id() const override;
-  virtual void Display() override;
-  virtual void Error() override;
-  virtual void Close(bool by_user) override;
-  virtual void Click() override;
-  virtual void ButtonClick(int button_index) override;
+  std::string id() const override;
+  void Display() override;
+  void Error() override;
+  void Close(bool by_user) override;
+  void Click() override;
+  void ButtonClick(int button_index) override;
 
  private:
   void OpenTab(const GURL& url);
   void DisableNotifications();
 
-  virtual ~PrivetNotificationDelegate();
+  ~PrivetNotificationDelegate() override;
 
   content::BrowserContext* profile_;
 };
diff --git a/chrome/browser/local_discovery/privet_notifications_factory.h b/chrome/browser/local_discovery/privet_notifications_factory.h
index b6d62d3..5946a37 100644
--- a/chrome/browser/local_discovery/privet_notifications_factory.h
+++ b/chrome/browser/local_discovery/privet_notifications_factory.h
@@ -20,13 +20,13 @@
   friend struct DefaultSingletonTraits<PrivetNotificationServiceFactory>;
 
   PrivetNotificationServiceFactory();
-  virtual ~PrivetNotificationServiceFactory();
+  ~PrivetNotificationServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
+  bool ServiceIsNULLWhileTesting() const override;
 };
 
 }  // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_url_fetcher.h b/chrome/browser/local_discovery/privet_url_fetcher.h
index 8bae4a7..e8644bd 100644
--- a/chrome/browser/local_discovery/privet_url_fetcher.h
+++ b/chrome/browser/local_discovery/privet_url_fetcher.h
@@ -71,10 +71,10 @@
       net::URLRequestContextGetter* request_context,
       Delegate* delegate);
 
-  virtual ~PrivetURLFetcher();
+  ~PrivetURLFetcher() override;
 
   // net::URLFetcherDelegate methods.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   static void SetTokenForHost(const std::string& host,
                               const std::string& token);
diff --git a/chrome/browser/local_discovery/privetv3_crypto_provider.cc b/chrome/browser/local_discovery/privetv3_crypto_provider.cc
index 12bbcc8..819df06b 100644
--- a/chrome/browser/local_discovery/privetv3_crypto_provider.cc
+++ b/chrome/browser/local_discovery/privetv3_crypto_provider.cc
@@ -20,19 +20,18 @@
 class PrivetV3CryptoProviderEmpty : public PrivetV3CryptoProvider {
  public:
   PrivetV3CryptoProviderEmpty();
-  virtual ~PrivetV3CryptoProviderEmpty();
+  ~PrivetV3CryptoProviderEmpty() override;
 
   // PrivetV3CryptoProvider implementation.
-  virtual HandshakeState GetState() override;
-  virtual std::string GetAuthMethod() override;
-  virtual HandshakeState GetNextStep(int* step, std::string* package) override;
-  virtual HandshakeState SetStepResponse(int step,
-                                         const std::string& state,
-                                         const std::string& package) override;
-  virtual std::string GetVerificationCode() override;
-  virtual HandshakeState AcceptVerificationCode() override;
-  virtual bool EncryptData(const std::string& input,
-                           std::string* output) override;
+  HandshakeState GetState() override;
+  std::string GetAuthMethod() override;
+  HandshakeState GetNextStep(int* step, std::string* package) override;
+  HandshakeState SetStepResponse(int step,
+                                 const std::string& state,
+                                 const std::string& package) override;
+  std::string GetVerificationCode() override;
+  HandshakeState AcceptVerificationCode() override;
+  bool EncryptData(const std::string& input, std::string* output) override;
 
  private:
   HandshakeState state_;
diff --git a/chrome/browser/local_discovery/privetv3_session.cc b/chrome/browser/local_discovery/privetv3_session.cc
index cb619a9..ceee47c 100644
--- a/chrome/browser/local_discovery/privetv3_session.cc
+++ b/chrome/browser/local_discovery/privetv3_session.cc
@@ -31,17 +31,17 @@
  public:
   FetcherDelegate(const base::WeakPtr<PrivetV3Session>& session,
                   Request* request);
-  virtual ~FetcherDelegate();
+  ~FetcherDelegate() override;
 
   // PrivetURLFetcher::Delegate methods.
-  virtual void OnNeedPrivetToken(
+  void OnNeedPrivetToken(
       PrivetURLFetcher* fetcher,
       const PrivetURLFetcher::TokenCallback& callback) override;
-  virtual void OnError(PrivetURLFetcher* fetcher,
-                       PrivetURLFetcher::ErrorType error) override;
-  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
-                            const base::DictionaryValue& value,
-                            bool has_error) override;
+  void OnError(PrivetURLFetcher* fetcher,
+               PrivetURLFetcher::ErrorType error) override;
+  void OnParsedJson(PrivetURLFetcher* fetcher,
+                    const base::DictionaryValue& value,
+                    bool has_error) override;
 
  private:
   friend class PrivetV3Session;
diff --git a/chrome/browser/local_discovery/privetv3_setup_flow.cc b/chrome/browser/local_discovery/privetv3_setup_flow.cc
index 8750128c..e122e8f 100644
--- a/chrome/browser/local_discovery/privetv3_setup_flow.cc
+++ b/chrome/browser/local_discovery/privetv3_setup_flow.cc
@@ -19,14 +19,14 @@
 class SetupRequest : public PrivetV3Session::Request {
  public:
   explicit SetupRequest(PrivetV3SetupFlow* setup_flow);
-  virtual ~SetupRequest();
+  ~SetupRequest() override;
 
-  virtual std::string GetName() override { return "/privet/v3/setup/start"; }
-  virtual const base::DictionaryValue& GetInput() override;
+  std::string GetName() override { return "/privet/v3/setup/start"; }
+  const base::DictionaryValue& GetInput() override;
 
-  virtual void OnError() override;
-  virtual void OnParsedJson(const base::DictionaryValue& value,
-                            bool has_error) override;
+  void OnError() override;
+  void OnParsedJson(const base::DictionaryValue& value,
+                    bool has_error) override;
 
   void SetWiFiCridentials(const std::string& ssid, const std::string& password);
 
diff --git a/chrome/browser/local_discovery/privetv3_setup_flow.h b/chrome/browser/local_discovery/privetv3_setup_flow.h
index 925ee8ae..33959682 100644
--- a/chrome/browser/local_discovery/privetv3_setup_flow.h
+++ b/chrome/browser/local_discovery/privetv3_setup_flow.h
@@ -62,7 +62,7 @@
   };
 
   explicit PrivetV3SetupFlow(Delegate* delegate);
-  virtual ~PrivetV3SetupFlow();
+  ~PrivetV3SetupFlow() override;
 
   // Starts registration.
   void Register(const std::string& service_name);
@@ -72,12 +72,10 @@
 #endif  // ENABLE_WIFI_BOOTSTRAPPING
 
   // PrivetV3Session::Delegate implementation.
-  virtual void OnSetupConfirmationNeeded(
-      const std::string& confirmation_code,
-      extensions::api::gcd_private::ConfirmationType confirmation_type)
-      override;
-  virtual void OnSessionStatus(
-      extensions::api::gcd_private::Status status) override;
+  void OnSetupConfirmationNeeded(const std::string& confirmation_code,
+                                 extensions::api::gcd_private::ConfirmationType
+                                     confirmation_type) override;
+  void OnSessionStatus(extensions::api::gcd_private::Status status) override;
 
   void OnSetupError();
   void OnDeviceRegistered();
diff --git a/chrome/browser/local_discovery/privetv3_setup_flow_unittest.cc b/chrome/browser/local_discovery/privetv3_setup_flow_unittest.cc
index 5cf3e28..89ac398 100644
--- a/chrome/browser/local_discovery/privetv3_setup_flow_unittest.cc
+++ b/chrome/browser/local_discovery/privetv3_setup_flow_unittest.cc
@@ -75,7 +75,7 @@
    public:
     explicit MockGCDApiFlow(MockDelegate* delegate) : delegate_(delegate) {}
 
-    virtual void Start(scoped_ptr<Request> request) override {
+    void Start(scoped_ptr<Request> request) override {
       ASSERT_FALSE(delegate_->gcd_request_);
       delegate_->gcd_request_ = request.Pass();
       delegate_->ReplyWithToken();
diff --git a/chrome/browser/local_discovery/pwg_raster_converter.cc b/chrome/browser/local_discovery/pwg_raster_converter.cc
index 75b6756..40f3b0e 100644
--- a/chrome/browser/local_discovery/pwg_raster_converter.cc
+++ b/chrome/browser/local_discovery/pwg_raster_converter.cc
@@ -109,11 +109,11 @@
                const PWGRasterConverter::ResultCallback& callback);
 
   // UtilityProcessHostClient implementation.
-  virtual void OnProcessCrashed(int exit_code) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OnProcessCrashed(int exit_code) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
  private:
-  virtual ~PwgUtilityProcessHostClient();
+  ~PwgUtilityProcessHostClient() override;
 
   // Message handlers.
   void OnProcessStarted();
@@ -243,12 +243,12 @@
  public:
   PWGRasterConverterImpl();
 
-  virtual ~PWGRasterConverterImpl();
+  ~PWGRasterConverterImpl() override;
 
-  virtual void Start(base::RefCountedMemory* data,
-                     const printing::PdfRenderSettings& conversion_settings,
-                     const printing::PwgRasterSettings& bitmap_settings,
-                     const ResultCallback& callback) override;
+  void Start(base::RefCountedMemory* data,
+             const printing::PdfRenderSettings& conversion_settings,
+             const printing::PwgRasterSettings& bitmap_settings,
+             const ResultCallback& callback) override;
 
  private:
   scoped_refptr<PwgUtilityProcessHostClient> utility_client_;
diff --git a/chrome/browser/local_discovery/service_discovery_client_mac.h b/chrome/browser/local_discovery/service_discovery_client_mac.h
index bc67de4..17f19cf5 100644
--- a/chrome/browser/local_discovery/service_discovery_client_mac.h
+++ b/chrome/browser/local_discovery/service_discovery_client_mac.h
@@ -32,16 +32,16 @@
   ServiceDiscoveryClientMac();
 
  private:
-  virtual ~ServiceDiscoveryClientMac();
+  ~ServiceDiscoveryClientMac() override;
 
   // ServiceDiscoveryClient implementation.
-  virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher(
+  scoped_ptr<ServiceWatcher> CreateServiceWatcher(
       const std::string& service_type,
       const ServiceWatcher::UpdatedCallback& callback) override;
-  virtual scoped_ptr<ServiceResolver> CreateServiceResolver(
+  scoped_ptr<ServiceResolver> CreateServiceResolver(
       const std::string& service_name,
       const ServiceResolver::ResolveCompleteCallback& callback) override;
-  virtual scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver(
+  scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver(
       const std::string& domain,
       net::AddressFamily address_family,
       const LocalDomainResolver::IPAddressCallback& callback) override;
@@ -100,13 +100,12 @@
                         const std::string& service);
 
  private:
-  virtual ~ServiceWatcherImplMac();
+  ~ServiceWatcherImplMac() override;
 
-  virtual void Start() override;
-  virtual void DiscoverNewServices(bool force_update) override;
-  virtual void SetActivelyRefreshServices(
-      bool actively_refresh_services) override;
-  virtual std::string GetServiceType() const override;
+  void Start() override;
+  void DiscoverNewServices(bool force_update) override;
+  void SetActivelyRefreshServices(bool actively_refresh_services) override;
+  std::string GetServiceType() const override;
 
   std::string service_type_;
   ServiceWatcher::UpdatedCallback callback_;
@@ -168,10 +167,10 @@
   NetServiceContainer* GetContainerForTesting();
 
  private:
-  virtual ~ServiceResolverImplMac();
+  ~ServiceResolverImplMac() override;
 
-  virtual void StartResolving() override;
-  virtual std::string GetName() const override;
+  void StartResolving() override;
+  std::string GetName() const override;
 
   void OnResolveComplete(RequestStatus status,
                          const ServiceDescription& description);
diff --git a/chrome/browser/local_discovery/service_discovery_shared_client.h b/chrome/browser/local_discovery/service_discovery_shared_client.h
index 14dd12f..c0b7d41 100644
--- a/chrome/browser/local_discovery/service_discovery_shared_client.h
+++ b/chrome/browser/local_discovery/service_discovery_shared_client.h
@@ -21,7 +21,7 @@
 
  protected:
   ServiceDiscoverySharedClient();
-  virtual ~ServiceDiscoverySharedClient();
+  ~ServiceDiscoverySharedClient() override;
 
  private:
   friend class base::RefCounted<ServiceDiscoverySharedClient>;
diff --git a/chrome/browser/local_discovery/wifi/bootstrapping_device_lister.h b/chrome/browser/local_discovery/wifi/bootstrapping_device_lister.h
index 5c2dd28..c2ca45e 100644
--- a/chrome/browser/local_discovery/wifi/bootstrapping_device_lister.h
+++ b/chrome/browser/local_discovery/wifi/bootstrapping_device_lister.h
@@ -42,7 +42,7 @@
 
   BootstrappingDeviceLister(WifiManager* wifi_manager,
                             const UpdateCallback& update_callback);
-  virtual ~BootstrappingDeviceLister();
+  ~BootstrappingDeviceLister() override;
 
   void Start();
 
@@ -51,7 +51,7 @@
       std::pair<std::string /*ssid*/, std::string /*internal_name*/> >
       ActiveDeviceList;
 
-  virtual void OnNetworkListChanged(
+  void OnNetworkListChanged(
       const std::vector<NetworkProperties>& ssids) override;
 
   void UpdateChangedSSIDs(bool available,
diff --git a/chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.cc b/chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.cc
index 8077c3a..88620d3 100644
--- a/chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.cc
+++ b/chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.cc
@@ -55,7 +55,7 @@
   explicit WifiServiceWrapper(
       base::WeakPtr<WifiManagerNonChromeos> wifi_manager);
 
-  virtual ~WifiServiceWrapper();
+  ~WifiServiceWrapper() override;
 
   void Start();
 
@@ -79,7 +79,7 @@
 
  private:
   // net::NetworkChangeNotifier::NetworkChangeObserver implementation.
-  virtual void OnNetworkChanged(
+  void OnNetworkChanged(
       net::NetworkChangeNotifier::ConnectionType type) override;
 
   void GetSSIDListInternal(NetworkPropertiesList* ssid_list);
diff --git a/chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.h b/chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.h
index 61b9d6b..20d432f 100644
--- a/chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.h
+++ b/chrome/browser/local_discovery/wifi/wifi_manager_nonchromeos.h
@@ -22,24 +22,21 @@
 class WifiManagerNonChromeos : public WifiManager {
  public:
   WifiManagerNonChromeos();
-  virtual ~WifiManagerNonChromeos();
+  ~WifiManagerNonChromeos() override;
 
   // WifiManager implementation.
-  virtual void Start() override;
-  virtual void GetSSIDList(const SSIDListCallback& callback) override;
-  virtual void RequestScan() override;
-  virtual void ConfigureAndConnectNetwork(
-      const std::string& ssid,
-      const WifiCredentials& credentials,
-      const SuccessCallback& callback) override;
-  virtual void ConnectToNetworkByID(const std::string& internal_id,
-                                    const SuccessCallback& callback) override;
-  virtual void RequestNetworkCredentials(
-      const std::string& ssid,
-      const CredentialsCallback& callback) override;
-  virtual void AddNetworkListObserver(NetworkListObserver* observer) override;
-  virtual void RemoveNetworkListObserver(
-      NetworkListObserver* observer) override;
+  void Start() override;
+  void GetSSIDList(const SSIDListCallback& callback) override;
+  void RequestScan() override;
+  void ConfigureAndConnectNetwork(const std::string& ssid,
+                                  const WifiCredentials& credentials,
+                                  const SuccessCallback& callback) override;
+  void ConnectToNetworkByID(const std::string& internal_id,
+                            const SuccessCallback& callback) override;
+  void RequestNetworkCredentials(const std::string& ssid,
+                                 const CredentialsCallback& callback) override;
+  void AddNetworkListObserver(NetworkListObserver* observer) override;
+  void RemoveNetworkListObserver(NetworkListObserver* observer) override;
 
  private:
   class WifiServiceWrapper;
diff --git a/chrome/browser/media/cast_transport_host_filter.h b/chrome/browser/media/cast_transport_host_filter.h
index 3a419cc5..265cffa 100644
--- a/chrome/browser/media/cast_transport_host_filter.h
+++ b/chrome/browser/media/cast_transport_host_filter.h
@@ -25,7 +25,7 @@
  public:
   CastTransportHostFilter();
  private:
-  virtual ~CastTransportHostFilter();
+  ~CastTransportHostFilter() override;
 
   void NotifyStatusChange(
       int32 channel_id,
@@ -40,7 +40,7 @@
                        const media::cast::RtcpCastMessage& cast_message);
 
   // BrowserMessageFilter implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // Forwarding functions.
   void OnInitializeAudio(
diff --git a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
index ba6fded..d1e44e9b 100644
--- a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
+++ b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
@@ -37,7 +37,7 @@
   virtual ~MediaStreamInfoBarTest() {}
 
   // InProcessBrowserTest:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // This test expects to run with fake devices but real UI.
     command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
     EXPECT_FALSE(command_line->HasSwitch(switches::kUseFakeUIForMediaStream))
diff --git a/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc b/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc
index 863887c..9a93a99 100644
--- a/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc
@@ -48,7 +48,7 @@
         firefox_(base::kNullProcessHandle) {
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     EXPECT_FALSE(command_line->HasSwitch(switches::kUseFakeUIForMediaStream));
 
     // The video playback will not work without a GPU, so force its use here.
diff --git a/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc b/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
index 6e3671a..56f33ba 100644
--- a/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc
@@ -109,11 +109,11 @@
 class WebRtcAudioQualityBrowserTest : public WebRtcTestBase {
  public:
   WebRtcAudioQualityBrowserTest() {}
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // This test expects real device handling and requires a real webcam / audio
     // device; it will not work with fake devices.
     EXPECT_FALSE(command_line->HasSwitch(
diff --git a/chrome/browser/media/chrome_webrtc_browsertest.cc b/chrome/browser/media/chrome_webrtc_browsertest.cc
index 8000da0..7ec473c 100644
--- a/chrome/browser/media/chrome_webrtc_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_browsertest.cc
@@ -24,11 +24,11 @@
 // system.
 class WebRtcBrowserTest : public WebRtcTestBase {
  public:
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // Ensure the infobar is enabled, since we expect that in this test.
     EXPECT_FALSE(command_line->HasSwitch(switches::kUseFakeUIForMediaStream));
 
diff --git a/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc b/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc
index e6210f7e..a3dfab9 100644
--- a/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc
@@ -31,11 +31,11 @@
   WebRtcDisableEncryptionFlagBrowserTest() {}
   virtual ~WebRtcDisableEncryptionFlagBrowserTest() {}
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // This test should run with fake devices.
     command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
 
diff --git a/chrome/browser/media/chrome_webrtc_getmediadevices_browsertest.cc b/chrome/browser/media/chrome_webrtc_getmediadevices_browsertest.cc
index 7510841..bca404e 100644
--- a/chrome/browser/media/chrome_webrtc_getmediadevices_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_getmediadevices_browsertest.cc
@@ -43,11 +43,11 @@
       : has_audio_output_devices_initialized_(false),
         has_audio_output_devices_(false) {}
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // Ensure the infobar is enabled, since we expect that in this test.
     EXPECT_FALSE(command_line->HasSwitch(switches::kUseFakeUIForMediaStream));
 
diff --git a/chrome/browser/media/chrome_webrtc_perf_browsertest.cc b/chrome/browser/media/chrome_webrtc_perf_browsertest.cc
index ed21ee67..71d5358 100644
--- a/chrome/browser/media/chrome_webrtc_perf_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_perf_browsertest.cc
@@ -33,11 +33,11 @@
 // solution (which is only available on WebRTC internal bots).
 class WebRtcPerfBrowserTest : public WebRtcTestBase {
  public:
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // Ensure the infobar is enabled, since we expect that in this test.
     EXPECT_FALSE(command_line->HasSwitch(switches::kUseFakeUIForMediaStream));
 
diff --git a/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc b/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
index 3961d35..bc0728c 100644
--- a/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc
@@ -102,13 +102,13 @@
     test_config_ = GetParam();
   }
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
 
     ASSERT_TRUE(temp_working_dir_.CreateUniqueTempDir());
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // Set up the command line option with the expected file name. We will check
     // its existence in HasAllRequiredResources().
     webrtc_reference_video_y4m_ = test::GetReferenceFilesDir()
diff --git a/chrome/browser/media/chrome_webrtc_webcam_browsertest.cc b/chrome/browser/media/chrome_webrtc_webcam_browsertest.cc
index 70fa610e02..6363531 100644
--- a/chrome/browser/media/chrome_webrtc_webcam_browsertest.cc
+++ b/chrome/browser/media/chrome_webrtc_webcam_browsertest.cc
@@ -39,7 +39,7 @@
 class WebRtcWebcamBrowserTest : public WebRtcTestBase,
     public testing::WithParamInterface<const char*> {
  public:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     EXPECT_FALSE(command_line->HasSwitch(
         switches::kUseFakeDeviceForMediaStream));
     EXPECT_FALSE(command_line->HasSwitch(
@@ -49,7 +49,7 @@
   }
 
  protected:
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     DetectErrorsInJavaScript();  // Look for errors in our rather complex js.
   }
 
diff --git a/chrome/browser/media/desktop_media_list_ash.h b/chrome/browser/media/desktop_media_list_ash.h
index 2386026..2f35ea0a 100644
--- a/chrome/browser/media/desktop_media_list_ash.h
+++ b/chrome/browser/media/desktop_media_list_ash.h
@@ -37,16 +37,15 @@
   };
 
   explicit DesktopMediaListAsh(int source_types);
-  virtual ~DesktopMediaListAsh();
+  ~DesktopMediaListAsh() override;
 
   // DesktopMediaList interface.
-  virtual void SetUpdatePeriod(base::TimeDelta period) override;
-  virtual void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
-  virtual void StartUpdating(DesktopMediaListObserver* observer) override;
-  virtual int GetSourceCount() const override;
-  virtual const Source& GetSource(int index) const override;
-  virtual void SetViewDialogWindowId(
-      content::DesktopMediaID::Id dialog_id) override;
+  void SetUpdatePeriod(base::TimeDelta period) override;
+  void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
+  void StartUpdating(DesktopMediaListObserver* observer) override;
+  int GetSourceCount() const override;
+  const Source& GetSource(int index) const override;
+  void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) override;
 
  private:
   // Struct used to represent sources list the model gets from the Worker.
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index bd6cd7d..15bfc130 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -228,13 +228,13 @@
   scoped_ptr<TestLicenseServer> license_server_;
 
   // We want to fail quickly when a test fails because an error is encountered.
-  virtual void AddWaitForTitles(content::TitleWatcher* title_watcher) override {
+  void AddWaitForTitles(content::TitleWatcher* title_watcher) override {
     MediaBrowserTest::AddWaitForTitles(title_watcher);
     title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(kEmeNotSupportedError));
     title_watcher->AlsoWaitForTitle(base::ASCIIToUTF16(kEmeKeyError));
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
 #if defined(OS_ANDROID)
     command_line->AppendSwitch(
         switches::kDisableGestureRequirementForMediaPlayback);
@@ -326,8 +326,21 @@
   }
 
  protected:
+  void SetUpCommandLine(CommandLine* command_line) override {
+    EncryptedMediaTestBase::SetUpCommandLine(command_line);
+    SetUpCommandLineForKeySystem(kExternalClearKeyKeySystem, command_line);
+  }
+};
+
+// Tests encrypted media playback using ExternalClearKey key system in
+// decrypt-and-decode mode for unprefixed EME.
+// TODO(jrummell): Merge with ECKEncryptedMediaTest once unprefixed is
+// enabled by default.
+class ECKUnprefixedEncryptedMediaTest : public EncryptedMediaTestBase {
+ protected:
   virtual void SetUpCommandLine(CommandLine* command_line) override {
     EncryptedMediaTestBase::SetUpCommandLine(command_line);
+    command_line->AppendSwitch(switches::kEnableEncryptedMedia);
     SetUpCommandLineForKeySystem(kExternalClearKeyKeySystem, command_line);
   }
 };
@@ -418,7 +431,7 @@
   }
 
  protected:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     EncryptedMediaTestBase::SetUpCommandLine(command_line);
     SetUpCommandLineForKeySystem(CurrentKeySystem(), command_line);
 
@@ -666,4 +679,29 @@
                         false,
                         kEmeKeyError);
 }
+
+IN_PROC_BROWSER_TEST_F(ECKUnprefixedEncryptedMediaTest, LoadLoadableSession) {
+  RunEncryptedMediaTest(kDefaultEmePlayer,
+                        "bear-320x240-v_enc-v.webm",
+                        kWebMVideoOnly,
+                        kExternalClearKeyKeySystem,
+                        SRC,
+                        UNPREFIXED,
+                        kLoadableSession,
+                        false,
+                        kEnded);
+}
+
+IN_PROC_BROWSER_TEST_F(ECKUnprefixedEncryptedMediaTest, LoadUnknownSession) {
+  // TODO(xhwang): Add a specific error for this failure, e.g. kSessionNotFound.
+  RunEncryptedMediaTest(kDefaultEmePlayer,
+                        "bear-320x240-v_enc-v.webm",
+                        kWebMVideoOnly,
+                        kExternalClearKeyKeySystem,
+                        SRC,
+                        UNPREFIXED,
+                        kUnknownSession,
+                        false,
+                        kEmeKeyError);
+}
 #endif  // defined(ENABLE_PEPPER_CDMS)
diff --git a/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc b/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc
index e6f115e6..91b725e 100644
--- a/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_istypesupported_browsertest.cc
@@ -325,7 +325,7 @@
     : public EncryptedMediaIsTypeSupportedTest {
 #if defined(ENABLE_PEPPER_CDMS)
  protected:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // Platform-specific filename relative to the chrome executable.
     const char adapter_file_name[] =
 #if defined(OS_MACOSX)
@@ -371,7 +371,7 @@
 class EncryptedMediaIsTypeSupportedClearKeyCDMRegisteredWithWrongPathTest
     : public EncryptedMediaIsTypeSupportedTest {
  protected:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
    RegisterPepperCdm(command_line,
                      "clearkeycdmadapterwrongname.dll",
                      "application/x-ppapi-clearkey-cdm",
@@ -383,7 +383,7 @@
 class EncryptedMediaIsTypeSupportedWidevineCDMRegisteredWithWrongPathTest
     : public EncryptedMediaIsTypeSupportedTest {
  protected:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
    RegisterPepperCdm(command_line,
                      "widevinecdmadapterwrongname.dll",
                      "application/x-ppapi-widevine-cdm",
diff --git a/chrome/browser/media/fake_desktop_media_list.h b/chrome/browser/media/fake_desktop_media_list.h
index 32113b8..4adce06 100644
--- a/chrome/browser/media/fake_desktop_media_list.h
+++ b/chrome/browser/media/fake_desktop_media_list.h
@@ -12,7 +12,7 @@
 class FakeDesktopMediaList : public DesktopMediaList {
  public:
   FakeDesktopMediaList();
-  virtual ~FakeDesktopMediaList();
+  ~FakeDesktopMediaList() override;
 
   void AddSource(int id);
   void RemoveSource(int index);
@@ -21,13 +21,12 @@
   void SetSourceName(int index, base::string16 name);
 
   // DesktopMediaList implementation:
-  virtual void SetUpdatePeriod(base::TimeDelta period) override;
-  virtual void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
-  virtual void SetViewDialogWindowId(
-      content::DesktopMediaID::Id dialog_id) override;
-  virtual void StartUpdating(DesktopMediaListObserver* observer) override;
-  virtual int GetSourceCount() const override;
-  virtual const Source& GetSource(int index) const override;
+  void SetUpdatePeriod(base::TimeDelta period) override;
+  void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
+  void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) override;
+  void StartUpdating(DesktopMediaListObserver* observer) override;
+  int GetSourceCount() const override;
+  const Source& GetSource(int index) const override;
 
  private:
   std::vector<Source> sources_;
diff --git a/chrome/browser/media/media_browsertest.h b/chrome/browser/media/media_browsertest.h
index 995f7b11..67a62a11 100644
--- a/chrome/browser/media/media_browsertest.h
+++ b/chrome/browser/media/media_browsertest.h
@@ -48,8 +48,8 @@
 
   // Fails test and sets document title to kPluginCrashed when a plugin crashes.
   // If IgnorePluginCrash(true) is called then plugin crash is ignored.
-  virtual void PluginCrashed(const base::FilePath& plugin_path,
-                             base::ProcessId plugin_pid) override;
+  void PluginCrashed(const base::FilePath& plugin_path,
+                     base::ProcessId plugin_pid) override;
 
   // When called, the test will ignore any plugin crashes and not fail the test.
   void IgnorePluginCrash();
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.cc b/chrome/browser/media/media_capture_devices_dispatcher.cc
index 47ba3dc..eebf9c026 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.cc
+++ b/chrome/browser/media/media_capture_devices_dispatcher.cc
@@ -42,8 +42,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/media_stream_request.h"
 #include "extensions/common/constants.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/permissions/permissions_data.h"
 #include "media/audio/audio_manager_base.h"
 #include "media/base/media_switches.h"
 #include "net/base/net_util.h"
@@ -54,13 +52,14 @@
 #include "ash/shell.h"
 #endif  // defined(OS_CHROMEOS)
 
-
 #if defined(ENABLE_EXTENSIONS)
 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "extensions/browser/app_window/app_window.h"
 #include "extensions/browser/app_window/app_window_registry.h"
 #include "extensions/browser/extension_system.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/permissions/permissions_data.h"
 #endif
 
 using content::BrowserThread;
@@ -92,6 +91,7 @@
   return NULL;
 }
 
+#if defined(ENABLE_EXTENSIONS)
 // This is a short-term solution to grant camera and/or microphone access to
 // extensions:
 // 1. Virtual keyboard extension.
@@ -132,6 +132,7 @@
       // Google Cast Stable
       origin.spec() == "chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/";
 }
+#endif  // defined(ENABLE_EXTENSIONS)
 
 // Helper to get title of the calling application shown in the screen capture
 // notification.
@@ -140,13 +141,15 @@
   // Use extension name as title for extensions and host/origin for drive-by
   // web.
   std::string title;
+#if defined(ENABLE_EXTENSIONS)
   if (extension) {
     title = extension->name();
-  } else {
-    GURL url = web_contents->GetURL();
-    title = url.SchemeIsSecure() ? net::GetHostAndOptionalPort(url)
-                                 : url.GetOrigin().spec();
+    return base::UTF8ToUTF16(title);
   }
+#endif
+  GURL url = web_contents->GetURL();
+  title = url.SchemeIsSecure() ? net::GetHostAndOptionalPort(url)
+                               : url.GetOrigin().spec();
   return base::UTF8ToUTF16(title);
 }
 
@@ -154,7 +157,7 @@
 // Registers to display notification if |display_notification| is true.
 // Returns an instance of MediaStreamUI to be passed to content layer.
 scoped_ptr<content::MediaStreamUI> GetDevicesForDesktopCapture(
-    content::MediaStreamDevices& devices,
+    content::MediaStreamDevices* devices,
     content::DesktopMediaID media_id,
     bool capture_audio,
     bool display_notification,
@@ -164,11 +167,11 @@
   scoped_ptr<content::MediaStreamUI> ui;
 
   // Add selected desktop source to the list.
-  devices.push_back(content::MediaStreamDevice(
+  devices->push_back(content::MediaStreamDevice(
       content::MEDIA_DESKTOP_VIDEO_CAPTURE, media_id.ToString(), "Screen"));
   if (capture_audio) {
     // Use the special loopback device ID for system audio capture.
-    devices.push_back(content::MediaStreamDevice(
+    devices->push_back(content::MediaStreamDevice(
         content::MEDIA_LOOPBACK_AUDIO_CAPTURE,
         media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio"));
   }
@@ -212,10 +215,10 @@
 }
 #endif
 
+#if defined(ENABLE_EXTENSIONS)
 const extensions::Extension* GetExtensionForOrigin(
     Profile* profile,
     const GURL& security_origin) {
-#if defined(ENABLE_EXTENSIONS)
   if (!security_origin.SchemeIs(extensions::kExtensionScheme))
     return NULL;
 
@@ -225,10 +228,8 @@
       extensions_service->extensions()->GetByID(security_origin.host());
   DCHECK(extension);
   return extension;
-#else
-  return NULL;
-#endif
 }
+#endif
 
 }  // namespace
 
@@ -336,12 +337,18 @@
              request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) {
     ProcessTabCaptureAccessRequest(
         web_contents, request, callback, extension);
-  } else if (extension && (extension->is_platform_app() ||
-                           IsMediaRequestWhitelistedForExtension(extension))) {
-    // For extensions access is approved based on extension permissions.
-    ProcessMediaAccessRequestFromPlatformAppOrExtension(
-        web_contents, request, callback, extension);
   } else {
+#if defined(ENABLE_EXTENSIONS)
+    bool is_whitelisted =
+        extension && (extension->is_platform_app() ||
+                      IsMediaRequestWhitelistedForExtension(extension));
+    if (is_whitelisted) {
+      // For extensions access is approved based on extension permissions.
+      ProcessMediaAccessRequestFromPlatformAppOrExtension(
+          web_contents, request, callback, extension);
+      return;
+    }
+#endif
     ProcessRegularMediaAccessRequest(web_contents, request, callback);
   }
 }
@@ -355,6 +362,7 @@
          type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
 
   Profile* profile = Profile::FromBrowserContext(browser_context);
+#if defined(ENABLE_EXTENSIONS)
   const extensions::Extension* extension =
       GetExtensionForOrigin(profile, security_origin);
 
@@ -365,6 +373,7 @@
             ? extensions::APIPermission::kAudioCapture
             : extensions::APIPermission::kVideoCapture);
   }
+#endif
 
   if (CheckAllowAllMediaStreamContentForOrigin(profile, security_origin))
     return true;
@@ -521,7 +530,7 @@
        loopback_audio_supported);
 
   ui = GetDevicesForDesktopCapture(
-      devices, media_id, capture_audio, true,
+      &devices, media_id, capture_audio, true,
       GetApplicationTitle(web_contents, extension),
       base::UTF8ToUTF16(original_extension_name));
 
@@ -544,14 +553,20 @@
   loopback_audio_supported = true;
 #endif
 
-  const bool component_extension =
+  bool component_extension = false;
+#if defined(ENABLE_EXTENSIONS)
+  component_extension =
       extension && extension->location() == extensions::Manifest::COMPONENT;
+#endif
 
-  const bool screen_capture_enabled =
-      CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableUserMediaScreenCapturing) ||
+  bool screen_capture_enabled =
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableUserMediaScreenCapturing);
+#if defined(ENABLE_EXTENSIONS)
+  screen_capture_enabled |=
       IsOriginForCasting(request.security_origin) ||
       IsBuiltInExtension(request.security_origin);
+#endif
 
   const bool origin_is_secure =
       request.security_origin.SchemeIsSecure() ||
@@ -589,8 +604,12 @@
     // For component extensions, bypass message box.
     bool user_approved = false;
     if (!component_extension) {
-      base::string16 application_name = base::UTF8ToUTF16(
-          extension ? extension->name() : request.security_origin.spec());
+      base::string16 application_name =
+          base::UTF8ToUTF16(request.security_origin.spec());
+#if defined(ENABLE_EXTENSIONS)
+      if (extension)
+        application_name = base::UTF8ToUTF16(extension->name());
+#endif
       base::string16 confirmation_text = l10n_util::GetStringFUTF16(
           request.audio_type == content::MEDIA_NO_SERVICE ?
               IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TEXT :
@@ -624,7 +643,7 @@
       // display the notification for stream capture.
       bool display_notification = !component_extension;
 
-      ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio,
+      ui = GetDevicesForDesktopCapture(&devices, screen_id, capture_audio,
                                        display_notification, application_title,
                                        application_title);
       DCHECK(!devices.empty());
@@ -690,6 +709,7 @@
 #endif  // defined(ENABLE_EXTENSIONS)
 }
 
+#if defined(ENABLE_EXTENSIONS)
 void MediaCaptureDevicesDispatcher::
     ProcessMediaAccessRequestFromPlatformAppOrExtension(
         content::WebContents* web_contents,
@@ -773,6 +793,7 @@
 
   callback.Run(devices, result, ui.Pass());
 }
+#endif
 
 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest(
     content::WebContents* web_contents,
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.h b/chrome/browser/media/media_capture_devices_dispatcher.h
index ab8f431..3523d46 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.h
+++ b/chrome/browser/media/media_capture_devices_dispatcher.h
@@ -132,17 +132,16 @@
   void DisableDeviceEnumerationForTesting();
 
   // Overridden from content::MediaObserver:
-  virtual void OnAudioCaptureDevicesChanged() override;
-  virtual void OnVideoCaptureDevicesChanged() override;
-  virtual void OnMediaRequestStateChanged(
-      int render_process_id,
-      int render_frame_id,
-      int page_request_id,
-      const GURL& security_origin,
-      content::MediaStreamType stream_type,
-      content::MediaRequestState state) override;
-  virtual void OnCreatingAudioStream(int render_process_id,
-                                     int render_frame_id) override;
+  void OnAudioCaptureDevicesChanged() override;
+  void OnVideoCaptureDevicesChanged() override;
+  void OnMediaRequestStateChanged(int render_process_id,
+                                  int render_frame_id,
+                                  int page_request_id,
+                                  const GURL& security_origin,
+                                  content::MediaStreamType stream_type,
+                                  content::MediaRequestState state) override;
+  void OnCreatingAudioStream(int render_process_id,
+                             int render_frame_id) override;
 
   scoped_refptr<MediaStreamCaptureIndicator> GetMediaStreamCaptureIndicator();
 
@@ -171,12 +170,12 @@
   typedef std::map<content::WebContents*, RequestsQueue> RequestsQueues;
 
   MediaCaptureDevicesDispatcher();
-  virtual ~MediaCaptureDevicesDispatcher();
+  ~MediaCaptureDevicesDispatcher() override;
 
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Helpers for ProcessMediaAccessRequest().
   void ProcessDesktopCaptureAccessRequest(
@@ -194,11 +193,13 @@
       const content::MediaStreamRequest& request,
       const content::MediaResponseCallback& callback,
       const extensions::Extension* extension);
+#if defined(ENABLE_EXTENSIONS)
   void ProcessMediaAccessRequestFromPlatformAppOrExtension(
       content::WebContents* web_contents,
       const content::MediaStreamRequest& request,
       const content::MediaResponseCallback& callback,
       const extensions::Extension* extension);
+#endif
   void ProcessRegularMediaAccessRequest(
       content::WebContents* web_contents,
       const content::MediaStreamRequest& request,
diff --git a/chrome/browser/media/media_stream_capture_indicator.cc b/chrome/browser/media/media_stream_capture_indicator.cc
index f7b4ead..bcf96be 100644
--- a/chrome/browser/media/media_stream_capture_indicator.cc
+++ b/chrome/browser/media/media_stream_capture_indicator.cc
@@ -156,7 +156,7 @@
 
  private:
   // content::WebContentsObserver overrides.
-  virtual void WebContentsDestroyed() override {
+  void WebContentsDestroyed() override {
     indicator_->UnregisterWebContents(web_contents());
     delete this;
   }
@@ -187,15 +187,14 @@
     DCHECK(!devices_.empty());
   }
 
-  virtual ~UIDelegate() {
+  ~UIDelegate() override {
     if (started_ && device_usage_.get())
       device_usage_->RemoveDevices(devices_);
   }
 
  private:
   // content::MediaStreamUI interface.
-  virtual gfx::NativeViewId OnStarted(const base::Closure& close_callback)
-      override {
+  gfx::NativeViewId OnStarted(const base::Closure& close_callback) override {
     DCHECK(!started_);
     started_ = true;
     if (device_usage_.get())
diff --git a/chrome/browser/media/media_stream_capture_indicator.h b/chrome/browser/media/media_stream_capture_indicator.h
index cb06962..13ebfbab 100644
--- a/chrome/browser/media/media_stream_capture_indicator.h
+++ b/chrome/browser/media/media_stream_capture_indicator.h
@@ -41,7 +41,7 @@
       const content::MediaStreamDevices& devices);
 
   // Overrides from StatusIconMenuModel::Delegate implementation.
-  virtual void ExecuteCommand(int command_id, int event_flags) override;
+  void ExecuteCommand(int command_id, int event_flags) override;
 
   // Returns true if the |web_contents| is capturing user media (e.g., webcam or
   // microphone input).
@@ -63,7 +63,7 @@
   friend class WebContentsDeviceUsage;
 
   friend class base::RefCountedThreadSafe<MediaStreamCaptureIndicator>;
-  virtual ~MediaStreamCaptureIndicator();
+  ~MediaStreamCaptureIndicator() override;
 
   // Following functions/variables are executed/accessed only on UI thread.
 
diff --git a/chrome/browser/media/media_stream_devices_controller.h b/chrome/browser/media/media_stream_devices_controller.h
index 1650c3f9..6bdbde69 100644
--- a/chrome/browser/media/media_stream_devices_controller.h
+++ b/chrome/browser/media/media_stream_devices_controller.h
@@ -50,7 +50,7 @@
                                const content::MediaStreamRequest& request,
                                const content::MediaResponseCallback& callback);
 
-  virtual ~MediaStreamDevicesController();
+  ~MediaStreamDevicesController() override;
 
   // TODO(tommi): Clean up all the policy code and integrate with
   // HostContentSettingsMap instead.  This will make creating the UI simpler
@@ -73,15 +73,15 @@
             content::MediaStreamRequestResult result);
 
   // PermissionBubbleRequest:
-  virtual int GetIconID() const override;
-  virtual base::string16 GetMessageText() const override;
-  virtual base::string16 GetMessageTextFragment() const override;
-  virtual bool HasUserGesture() const override;
-  virtual GURL GetRequestingHostname() const override;
-  virtual void PermissionGranted() override;
-  virtual void PermissionDenied() override;
-  virtual void Cancelled() override;
-  virtual void RequestFinished() override;
+  int GetIconID() const override;
+  base::string16 GetMessageText() const override;
+  base::string16 GetMessageTextFragment() const override;
+  bool HasUserGesture() const override;
+  GURL GetRequestingHostname() const override;
+  void PermissionGranted() override;
+  void PermissionDenied() override;
+  void Cancelled() override;
+  void RequestFinished() override;
 
  private:
   // Returns true if the origin of the request has been granted the media
diff --git a/chrome/browser/media/media_stream_infobar_delegate.h b/chrome/browser/media/media_stream_infobar_delegate.h
index 8855e47..75214a624 100644
--- a/chrome/browser/media/media_stream_infobar_delegate.h
+++ b/chrome/browser/media/media_stream_infobar_delegate.h
@@ -19,7 +19,7 @@
 // to them.
 class MediaStreamInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
-  virtual ~MediaStreamInfoBarDelegate();
+  ~MediaStreamInfoBarDelegate() override;
 
   // Handles a permission request (in |request|) for |web_contents|.  If this
   // involves prompting the user, creates a media stream infobar and delegate,
@@ -37,16 +37,16 @@
       scoped_ptr<MediaStreamDevicesController> controller);
 
   // ConfirmInfoBarDelegate:
-  virtual void InfoBarDismissed() override;
-  virtual int GetIconID() const override;
-  virtual Type GetInfoBarType() const override;
-  virtual MediaStreamInfoBarDelegate* AsMediaStreamInfoBarDelegate() override;
-  virtual base::string16 GetMessageText() const override;
-  virtual base::string16 GetButtonLabel(InfoBarButton button) const override;
-  virtual bool Accept() override;
-  virtual bool Cancel() override;
-  virtual base::string16 GetLinkText() const override;
-  virtual bool LinkClicked(WindowOpenDisposition disposition) override;
+  void InfoBarDismissed() override;
+  int GetIconID() const override;
+  Type GetInfoBarType() const override;
+  MediaStreamInfoBarDelegate* AsMediaStreamInfoBarDelegate() override;
+  base::string16 GetMessageText() const override;
+  base::string16 GetButtonLabel(InfoBarButton button) const override;
+  bool Accept() override;
+  bool Cancel() override;
+  base::string16 GetLinkText() const override;
+  bool LinkClicked(WindowOpenDisposition disposition) override;
 
   scoped_ptr<MediaStreamDevicesController> controller_;
 
diff --git a/chrome/browser/media/midi_permission_context.h b/chrome/browser/media/midi_permission_context.h
index b15db7060..1a357c2 100644
--- a/chrome/browser/media/midi_permission_context.h
+++ b/chrome/browser/media/midi_permission_context.h
@@ -13,14 +13,14 @@
 class MidiPermissionContext : public PermissionContextBase {
  public:
   explicit MidiPermissionContext(Profile* profile);
-  virtual ~MidiPermissionContext();
+  ~MidiPermissionContext() override;
 
  private:
 
   // PermissionContextBase:
-  virtual void UpdateTabContext(const PermissionRequestID& id,
-                                const GURL& requesting_frame,
-                                bool allowed) override;
+  void UpdateTabContext(const PermissionRequestID& id,
+                        const GURL& requesting_frame,
+                        bool allowed) override;
 
   DISALLOW_COPY_AND_ASSIGN(MidiPermissionContext);
 };
diff --git a/chrome/browser/media/midi_permission_context_factory.h b/chrome/browser/media/midi_permission_context_factory.h
index 61305dc..53edae6 100644
--- a/chrome/browser/media/midi_permission_context_factory.h
+++ b/chrome/browser/media/midi_permission_context_factory.h
@@ -21,12 +21,12 @@
   friend struct DefaultSingletonTraits<MidiPermissionContextFactory>;
 
   MidiPermissionContextFactory();
-  virtual ~MidiPermissionContextFactory();
+  ~MidiPermissionContextFactory() override;
 
   // BrowserContextKeyedBaseFactory methods:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
 
   DISALLOW_COPY_AND_ASSIGN(MidiPermissionContextFactory);
diff --git a/chrome/browser/media/midi_permission_infobar_delegate.h b/chrome/browser/media/midi_permission_infobar_delegate.h
index 25f670b..0eb1eaa 100644
--- a/chrome/browser/media/midi_permission_infobar_delegate.h
+++ b/chrome/browser/media/midi_permission_infobar_delegate.h
@@ -34,11 +34,11 @@
                                 int contents_unique_id,
                                 const std::string& display_languages,
                                 ContentSettingsType type);
-  virtual ~MidiPermissionInfoBarDelegate();
+  ~MidiPermissionInfoBarDelegate() override;
 
   // ConfirmInfoBarDelegate:
-  virtual base::string16 GetMessageText() const override;
-  virtual int GetIconID() const override;
+  base::string16 GetMessageText() const override;
+  int GetIconID() const override;
 
   GURL requesting_frame_;
   std::string display_languages_;
diff --git a/chrome/browser/media/native_desktop_media_list.cc b/chrome/browser/media/native_desktop_media_list.cc
index b2f036ed..49bfb53 100644
--- a/chrome/browser/media/native_desktop_media_list.cc
+++ b/chrome/browser/media/native_desktop_media_list.cc
@@ -88,7 +88,7 @@
   Worker(base::WeakPtr<NativeDesktopMediaList> media_list,
          scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
          scoped_ptr<webrtc::WindowCapturer> window_capturer);
-  virtual ~Worker();
+  ~Worker() override;
 
   void Refresh(const gfx::Size& thumbnail_size,
                content::DesktopMediaID::Id view_dialog_id);
@@ -97,8 +97,8 @@
   typedef std::map<DesktopMediaID, uint32> ImageHashesMap;
 
   // webrtc::DesktopCapturer::Callback interface.
-  virtual webrtc::SharedMemory* CreateSharedMemory(size_t size) override;
-  virtual void OnCaptureCompleted(webrtc::DesktopFrame* frame) override;
+  webrtc::SharedMemory* CreateSharedMemory(size_t size) override;
+  void OnCaptureCompleted(webrtc::DesktopFrame* frame) override;
 
   base::WeakPtr<NativeDesktopMediaList> media_list_;
 
diff --git a/chrome/browser/media/native_desktop_media_list.h b/chrome/browser/media/native_desktop_media_list.h
index f64560c..81bd3215 100644
--- a/chrome/browser/media/native_desktop_media_list.h
+++ b/chrome/browser/media/native_desktop_media_list.h
@@ -28,16 +28,15 @@
   NativeDesktopMediaList(
       scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
       scoped_ptr<webrtc::WindowCapturer> window_capturer);
-  virtual ~NativeDesktopMediaList();
+  ~NativeDesktopMediaList() override;
 
   // DesktopMediaList interface.
-  virtual void SetUpdatePeriod(base::TimeDelta period) override;
-  virtual void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
-  virtual void StartUpdating(DesktopMediaListObserver* observer) override;
-  virtual int GetSourceCount() const override;
-  virtual const Source& GetSource(int index) const override;
-  virtual void SetViewDialogWindowId(
-      content::DesktopMediaID::Id dialog_id) override;
+  void SetUpdatePeriod(base::TimeDelta period) override;
+  void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
+  void StartUpdating(DesktopMediaListObserver* observer) override;
+  int GetSourceCount() const override;
+  const Source& GetSource(int index) const override;
+  void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) override;
 
  private:
   class Worker;
diff --git a/chrome/browser/media/native_desktop_media_list_unittest.cc b/chrome/browser/media/native_desktop_media_list_unittest.cc
index 460a8519..403e8e0 100644
--- a/chrome/browser/media/native_desktop_media_list_unittest.cc
+++ b/chrome/browser/media/native_desktop_media_list_unittest.cc
@@ -32,14 +32,12 @@
 class FakeScreenCapturer : public webrtc::ScreenCapturer {
  public:
   FakeScreenCapturer() {}
-  virtual ~FakeScreenCapturer() {}
+  ~FakeScreenCapturer() override {}
 
   // webrtc::ScreenCapturer implementation.
-  virtual void Start(Callback* callback) override {
-    callback_ = callback;
-  }
+  void Start(Callback* callback) override { callback_ = callback; }
 
-  virtual void Capture(const webrtc::DesktopRegion& region) override {
+  void Capture(const webrtc::DesktopRegion& region) override {
     DCHECK(callback_);
     webrtc::DesktopFrame* frame =
         new webrtc::BasicDesktopFrame(webrtc::DesktopSize(10, 10));
@@ -47,19 +45,19 @@
     callback_->OnCaptureCompleted(frame);
   }
 
-  virtual void SetMouseShapeObserver(
+  void SetMouseShapeObserver(
       MouseShapeObserver* mouse_shape_observer) override {
     NOTIMPLEMENTED();
   }
 
-  virtual bool GetScreenList(ScreenList* screens) override {
+  bool GetScreenList(ScreenList* screens) override {
     webrtc::ScreenCapturer::Screen screen;
     screen.id = 0;
     screens->push_back(screen);
     return true;
   }
 
-  virtual bool SelectScreen(webrtc::ScreenId id) override {
+  bool SelectScreen(webrtc::ScreenId id) override {
     EXPECT_EQ(0, id);
     return true;
   }
@@ -75,7 +73,7 @@
   FakeWindowCapturer()
       : callback_(NULL) {
   }
-  virtual ~FakeWindowCapturer() {}
+  ~FakeWindowCapturer() override {}
 
   void SetWindowList(const WindowList& list) {
     base::AutoLock lock(window_list_lock_);
@@ -90,11 +88,9 @@
   }
 
   // webrtc::WindowCapturer implementation.
-  virtual void Start(Callback* callback) override {
-    callback_ = callback;
-  }
+  void Start(Callback* callback) override { callback_ = callback; }
 
-  virtual void Capture(const webrtc::DesktopRegion& region) override {
+  void Capture(const webrtc::DesktopRegion& region) override {
     DCHECK(callback_);
 
     base::AutoLock lock(frame_values_lock_);
@@ -108,20 +104,18 @@
     callback_->OnCaptureCompleted(frame);
   }
 
-  virtual bool GetWindowList(WindowList* windows) override {
+  bool GetWindowList(WindowList* windows) override {
     base::AutoLock lock(window_list_lock_);
     *windows = window_list_;
     return true;
   }
 
-  virtual bool SelectWindow(WindowId id) override {
+  bool SelectWindow(WindowId id) override {
     selected_window_id_ = id;
     return true;
   }
 
-  virtual bool BringSelectedWindowToFront() override {
-    return true;
-  }
+  bool BringSelectedWindowToFront() override { return true; }
 
  private:
   Callback* callback_;
diff --git a/chrome/browser/media/webrtc_log_uploader.h b/chrome/browser/media/webrtc_log_uploader.h
index ae65c27f..dd9c916e 100644
--- a/chrome/browser/media/webrtc_log_uploader.h
+++ b/chrome/browser/media/webrtc_log_uploader.h
@@ -48,12 +48,13 @@
 class WebRtcLogUploader : public net::URLFetcherDelegate {
  public:
   WebRtcLogUploader();
-  virtual ~WebRtcLogUploader();
+  ~WebRtcLogUploader() override;
 
   // net::URLFetcherDelegate implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
-  virtual void OnURLFetchUploadProgress(const net::URLFetcher* source,
-                                        int64 current, int64 total) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchUploadProgress(const net::URLFetcher* source,
+                                int64 current,
+                                int64 total) override;
 
   // Returns true is number of logs limit is not reached yet. Increases log
   // count if true is returned. Must be called before UploadLog().
diff --git a/chrome/browser/media/webrtc_logging_handler_host.h b/chrome/browser/media/webrtc_logging_handler_host.h
index 9b8398d..9bf5db2 100644
--- a/chrome/browser/media/webrtc_logging_handler_host.h
+++ b/chrome/browser/media/webrtc_logging_handler_host.h
@@ -120,12 +120,12 @@
   friend class content::BrowserThread;
   friend class base::DeleteHelper<WebRtcLoggingHandlerHost>;
 
-  virtual ~WebRtcLoggingHandlerHost();
+  ~WebRtcLoggingHandlerHost() override;
 
   // BrowserMessageFilter implementation.
-  virtual void OnChannelClosing() override;
-  virtual void OnDestruct() const override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OnChannelClosing() override;
+  void OnDestruct() const override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // Handles log message requests from renderer process.
   void OnAddLogMessages(const std::vector<WebRtcLoggingMessageData>& messages);
diff --git a/chrome/browser/media/webrtc_rtp_dump_handler_unittest.cc b/chrome/browser/media/webrtc_rtp_dump_handler_unittest.cc
index 78ad5bee..eed30b5 100644
--- a/chrome/browser/media/webrtc_rtp_dump_handler_unittest.cc
+++ b/chrome/browser/media/webrtc_rtp_dump_handler_unittest.cc
@@ -28,17 +28,17 @@
         max_size_reached_callback_(max_size_reached_callback),
         end_dump_success_(end_dump_success) {}
 
-  virtual void WriteRtpPacket(const uint8* packet_header,
-                              size_t header_length,
-                              size_t packet_length,
-                              bool incoming) override {
+  void WriteRtpPacket(const uint8* packet_header,
+                      size_t header_length,
+                      size_t packet_length,
+                      bool incoming) override {
     current_dump_size_ += header_length;
     if (current_dump_size_ > max_dump_size_)
       max_size_reached_callback_.Run();
   }
 
-  virtual void EndDump(RtpDumpType type,
-                       const EndDumpCallback& finished_callback) override {
+  void EndDump(RtpDumpType type,
+               const EndDumpCallback& finished_callback) override {
     bool incoming_sucess = end_dump_success_;
     bool outgoing_success = end_dump_success_;
 
diff --git a/chrome/browser/media/wv_test_license_server_config.h b/chrome/browser/media/wv_test_license_server_config.h
index 60e12c8..f7901bd 100644
--- a/chrome/browser/media/wv_test_license_server_config.h
+++ b/chrome/browser/media/wv_test_license_server_config.h
@@ -11,13 +11,13 @@
 class WVTestLicenseServerConfig : public TestLicenseServerConfig {
  public:
   WVTestLicenseServerConfig();
-  virtual ~WVTestLicenseServerConfig();
+  ~WVTestLicenseServerConfig() override;
 
-  virtual std::string GetServerURL() override;
+  std::string GetServerURL() override;
 
-  virtual bool GetServerCommandLine(base::CommandLine* command_line) override;
+  bool GetServerCommandLine(base::CommandLine* command_line) override;
 
-  virtual bool IsPlatformSupported() override;
+  bool IsPlatformSupported() override;
 
  private:
   // Server port. The port value should be set by calling SelectServerPort().
diff --git a/chrome/browser/media_galleries/fileapi/av_scanning_file_validator.h b/chrome/browser/media_galleries/fileapi/av_scanning_file_validator.h
index 6144550c..262aac7 100644
--- a/chrome/browser/media_galleries/fileapi/av_scanning_file_validator.h
+++ b/chrome/browser/media_galleries/fileapi/av_scanning_file_validator.h
@@ -15,13 +15,12 @@
 // This class supports AV scanning on post write validation.
 class AVScanningFileValidator : public storage::CopyOrMoveFileValidator {
  public:
-  virtual ~AVScanningFileValidator();
+  ~AVScanningFileValidator() override;
 
   // Runs AV checks on the resulting file (Windows-only).
   // Subclasses will not typically override this method.
-  virtual void StartPostWriteValidation(
-      const base::FilePath& dest_platform_path,
-      const ResultCallback& result_callback) override;
+  void StartPostWriteValidation(const base::FilePath& dest_platform_path,
+                                const ResultCallback& result_callback) override;
 
  protected:
   AVScanningFileValidator();
diff --git a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
index 270b056f..ebfd6b8 100644
--- a/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
+++ b/chrome/browser/media_galleries/fileapi/device_media_async_file_util.h
@@ -29,7 +29,7 @@
 
 class DeviceMediaAsyncFileUtil : public storage::AsyncFileUtil {
  public:
-  virtual ~DeviceMediaAsyncFileUtil();
+  ~DeviceMediaAsyncFileUtil() override;
 
   // Returns an instance of DeviceMediaAsyncFileUtil.
   static scoped_ptr<DeviceMediaAsyncFileUtil> Create(
@@ -39,69 +39,60 @@
   bool SupportsStreaming(const storage::FileSystemURL& url);
 
   // AsyncFileUtil overrides.
-  virtual void CreateOrOpen(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      int file_flags,
-      const CreateOrOpenCallback& callback) override;
-  virtual void EnsureFileExists(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const EnsureFileExistsCallback& callback) override;
-  virtual void CreateDirectory(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      bool exclusive,
-      bool recursive,
-      const StatusCallback& callback) override;
-  virtual void GetFileInfo(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const GetFileInfoCallback& callback) override;
-  virtual void ReadDirectory(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const ReadDirectoryCallback& callback) override;
-  virtual void Touch(scoped_ptr<storage::FileSystemOperationContext> context,
-                     const storage::FileSystemURL& url,
-                     const base::Time& last_access_time,
-                     const base::Time& last_modified_time,
-                     const StatusCallback& callback) override;
-  virtual void Truncate(scoped_ptr<storage::FileSystemOperationContext> context,
+  void CreateOrOpen(scoped_ptr<storage::FileSystemOperationContext> context,
+                    const storage::FileSystemURL& url,
+                    int file_flags,
+                    const CreateOrOpenCallback& callback) override;
+  void EnsureFileExists(scoped_ptr<storage::FileSystemOperationContext> context,
                         const storage::FileSystemURL& url,
-                        int64 length,
-                        const StatusCallback& callback) override;
-  virtual void CopyFileLocal(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& src_url,
-      const storage::FileSystemURL& dest_url,
-      CopyOrMoveOption option,
-      const CopyFileProgressCallback& progress_callback,
-      const StatusCallback& callback) override;
-  virtual void MoveFileLocal(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& src_url,
-      const storage::FileSystemURL& dest_url,
-      CopyOrMoveOption option,
-      const StatusCallback& callback) override;
-  virtual void CopyInForeignFile(
+                        const EnsureFileExistsCallback& callback) override;
+  void CreateDirectory(scoped_ptr<storage::FileSystemOperationContext> context,
+                       const storage::FileSystemURL& url,
+                       bool exclusive,
+                       bool recursive,
+                       const StatusCallback& callback) override;
+  void GetFileInfo(scoped_ptr<storage::FileSystemOperationContext> context,
+                   const storage::FileSystemURL& url,
+                   const GetFileInfoCallback& callback) override;
+  void ReadDirectory(scoped_ptr<storage::FileSystemOperationContext> context,
+                     const storage::FileSystemURL& url,
+                     const ReadDirectoryCallback& callback) override;
+  void Touch(scoped_ptr<storage::FileSystemOperationContext> context,
+             const storage::FileSystemURL& url,
+             const base::Time& last_access_time,
+             const base::Time& last_modified_time,
+             const StatusCallback& callback) override;
+  void Truncate(scoped_ptr<storage::FileSystemOperationContext> context,
+                const storage::FileSystemURL& url,
+                int64 length,
+                const StatusCallback& callback) override;
+  void CopyFileLocal(scoped_ptr<storage::FileSystemOperationContext> context,
+                     const storage::FileSystemURL& src_url,
+                     const storage::FileSystemURL& dest_url,
+                     CopyOrMoveOption option,
+                     const CopyFileProgressCallback& progress_callback,
+                     const StatusCallback& callback) override;
+  void MoveFileLocal(scoped_ptr<storage::FileSystemOperationContext> context,
+                     const storage::FileSystemURL& src_url,
+                     const storage::FileSystemURL& dest_url,
+                     CopyOrMoveOption option,
+                     const StatusCallback& callback) override;
+  void CopyInForeignFile(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const base::FilePath& src_file_path,
       const storage::FileSystemURL& dest_url,
       const StatusCallback& callback) override;
-  virtual void DeleteFile(
+  void DeleteFile(scoped_ptr<storage::FileSystemOperationContext> context,
+                  const storage::FileSystemURL& url,
+                  const StatusCallback& callback) override;
+  void DeleteDirectory(scoped_ptr<storage::FileSystemOperationContext> context,
+                       const storage::FileSystemURL& url,
+                       const StatusCallback& callback) override;
+  void DeleteRecursively(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const StatusCallback& callback) override;
-  virtual void DeleteDirectory(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const StatusCallback& callback) override;
-  virtual void DeleteRecursively(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const StatusCallback& callback) override;
-  virtual void CreateSnapshotFile(
+  void CreateSnapshotFile(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const CreateSnapshotFileCallback& callback) override;
diff --git a/chrome/browser/media_galleries/fileapi/iphoto_data_provider.h b/chrome/browser/media_galleries/fileapi/iphoto_data_provider.h
index 3c78704..26f0ccc9 100644
--- a/chrome/browser/media_galleries/fileapi/iphoto_data_provider.h
+++ b/chrome/browser/media_galleries/fileapi/iphoto_data_provider.h
@@ -28,11 +28,11 @@
 class IPhotoDataProvider : public iapps::IAppsDataProvider {
  public:
   explicit IPhotoDataProvider(const base::FilePath& library_path);
-  virtual ~IPhotoDataProvider();
+  ~IPhotoDataProvider() override;
 
   // Parse the library xml file.
-  virtual void DoParseLibrary(const base::FilePath& library_path,
-                              const ReadyCallback& ready_callback) override;
+  void DoParseLibrary(const base::FilePath& library_path,
+                      const ReadyCallback& ready_callback) override;
 
   virtual std::vector<std::string> GetAlbumNames() const;
   virtual std::map<std::string, base::FilePath> GetAlbumContents(
diff --git a/chrome/browser/media_galleries/fileapi/iphoto_data_provider_browsertest.cc b/chrome/browser/media_galleries/fileapi/iphoto_data_provider_browsertest.cc
index e85143b..6c16b0c8 100644
--- a/chrome/browser/media_galleries/fileapi/iphoto_data_provider_browsertest.cc
+++ b/chrome/browser/media_galleries/fileapi/iphoto_data_provider_browsertest.cc
@@ -34,11 +34,10 @@
       : IPhotoDataProvider(xml_library_path),
         callback_(callback) {
   }
-  virtual ~TestIPhotoDataProvider() {}
+  ~TestIPhotoDataProvider() override {}
 
  private:
-  virtual void OnLibraryChanged(const base::FilePath& path,
-                                bool error) override {
+  void OnLibraryChanged(const base::FilePath& path, bool error) override {
     IPhotoDataProvider::OnLibraryChanged(path, error);
     callback_.Run();
   }
@@ -158,7 +157,7 @@
   IPhotoDataProviderBasicTest() {}
   virtual ~IPhotoDataProviderBasicTest() {}
 
-  virtual std::string GetLibraryString() override {
+  std::string GetLibraryString() override {
     return "<plist><dict>\n"
       "<key>List of Albums</key>\n"
       "<array>"
@@ -268,7 +267,7 @@
       "</dict></plist>\n";
   }
 
-  virtual void StartTest(bool parse_success) override {
+  void StartTest(bool parse_success) override {
     EXPECT_TRUE(parse_success);
 
     std::vector<std::string> names = data_provider()->GetAlbumNames();
@@ -346,7 +345,7 @@
 
   std::string another_album;
 
-  virtual std::string GetLibraryString() override {
+  std::string GetLibraryString() override {
     return "<plist><dict>\n"
       "<key>List of Albums</key>\n"
       "<array>"
@@ -381,7 +380,7 @@
       "</dict></plist>\n";
   }
 
-  virtual void StartTest(bool parse_success) override {
+  void StartTest(bool parse_success) override {
     EXPECT_TRUE(parse_success);
 
     EXPECT_EQ(FilePath("/vol/path1.jpg"),
@@ -443,7 +442,7 @@
   IPhotoDataProviderInvalidTest() {}
   virtual ~IPhotoDataProviderInvalidTest() {}
 
-  virtual void StartTest(bool parse_success) override {
+  void StartTest(bool parse_success) override {
     EXPECT_TRUE(parse_success);
 
     SetLibraryChangeCallback(
diff --git a/chrome/browser/media_galleries/fileapi/iphoto_file_util.h b/chrome/browser/media_galleries/fileapi/iphoto_file_util.h
index d9362817..1318442 100644
--- a/chrome/browser/media_galleries/fileapi/iphoto_file_util.h
+++ b/chrome/browser/media_galleries/fileapi/iphoto_file_util.h
@@ -32,38 +32,37 @@
 class IPhotoFileUtil : public NativeMediaFileUtil {
  public:
   explicit IPhotoFileUtil(MediaPathFilter* media_path_filter);
-  virtual ~IPhotoFileUtil();
+  ~IPhotoFileUtil() override;
 
  protected:
   // NativeMediaFileUtil overrides.
-  virtual void GetFileInfoOnTaskRunnerThread(
+  void GetFileInfoOnTaskRunnerThread(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const GetFileInfoCallback& callback) override;
-  virtual void ReadDirectoryOnTaskRunnerThread(
+  void ReadDirectoryOnTaskRunnerThread(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const ReadDirectoryCallback& callback) override;
-  virtual void CreateSnapshotFileOnTaskRunnerThread(
+  void CreateSnapshotFileOnTaskRunnerThread(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const CreateSnapshotFileCallback& callback) override;
-  virtual base::File::Error GetFileInfoSync(
+  base::File::Error GetFileInfoSync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       base::File::Info* file_info,
       base::FilePath* platform_path) override;
-  virtual base::File::Error ReadDirectorySync(
+  base::File::Error ReadDirectorySync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       EntryList* file_list) override;
-  virtual base::File::Error DeleteDirectorySync(
+  base::File::Error DeleteDirectorySync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url) override;
-  virtual base::File::Error DeleteFileSync(
-      storage::FileSystemOperationContext* context,
-      const storage::FileSystemURL& url) override;
-  virtual base::File::Error GetLocalFilePath(
+  base::File::Error DeleteFileSync(storage::FileSystemOperationContext* context,
+                                   const storage::FileSystemURL& url) override;
+  base::File::Error GetLocalFilePath(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       base::FilePath* local_file_path) override;
diff --git a/chrome/browser/media_galleries/fileapi/iphoto_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/iphoto_file_util_unittest.cc
index 8d1fe9d..ff55be7 100644
--- a/chrome/browser/media_galleries/fileapi/iphoto_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/iphoto_file_util_unittest.cc
@@ -73,44 +73,44 @@
     EXPECT_TRUE(fake_auto_add_dir_.CreateUniqueTempDir());
   }
 
-  virtual ~TestIPhotoDataProvider() {}
+  ~TestIPhotoDataProvider() override {}
 
-  virtual void RefreshData(const ReadyCallback& ready_callback) override {
+  void RefreshData(const ReadyCallback& ready_callback) override {
     ready_callback.Run(true /* success */);
   }
 
-  virtual std::vector<std::string> GetAlbumNames() const override {
+  std::vector<std::string> GetAlbumNames() const override {
     std::vector<std::string> names;
     names.push_back("Album1");
     names.push_back("has_originals");
     return names;
   }
 
-  virtual std::map<std::string, base::FilePath> GetAlbumContents(
+  std::map<std::string, base::FilePath> GetAlbumContents(
       const std::string& album) const override {
     std::map<std::string, base::FilePath> contents;
     contents["a.jpg"] = library_path().AppendASCII("a.jpg");
     return contents;
   }
 
-  virtual base::FilePath GetPhotoLocationInAlbum(
+  base::FilePath GetPhotoLocationInAlbum(
       const std::string& album,
       const std::string& filename) const override {
     return library_path().AppendASCII("a.jpg");
   }
 
-  virtual bool HasOriginals(const std::string& album) const override {
+  bool HasOriginals(const std::string& album) const override {
     return (album == "has_originals");
   }
 
-  virtual std::map<std::string, base::FilePath> GetOriginals(
+  std::map<std::string, base::FilePath> GetOriginals(
       const std::string& album) const override {
     std::map<std::string, base::FilePath> contents;
     contents["a.jpg"] = library_path().AppendASCII("orig.jpg");
     return contents;
   }
 
-  virtual base::FilePath GetOriginalPhotoLocation(
+  base::FilePath GetOriginalPhotoLocation(
       const std::string& album,
       const std::string& filename) const override {
     return library_path().AppendASCII("orig.jpg");
@@ -127,12 +127,10 @@
       : IPhotoFileUtil(media_path_filter),
         data_provider_(data_provider) {
   }
-  virtual ~TestIPhotoFileUtil() {}
+  ~TestIPhotoFileUtil() override {}
 
  private:
-  virtual IPhotoDataProvider* GetDataProvider() override {
-    return data_provider_;
-  }
+  IPhotoDataProvider* GetDataProvider() override { return data_provider_; }
 
   IPhotoDataProvider* data_provider_;
 };
@@ -146,7 +144,7 @@
             MediaFileSystemBackend::MediaTaskRunner().get()),
         test_file_util_(iphoto_file_util) {}
 
-  virtual storage::AsyncFileUtil* GetAsyncFileUtil(
+  storage::AsyncFileUtil* GetAsyncFileUtil(
       storage::FileSystemType type) override {
     if (type != storage::kFileSystemTypeIphoto)
       return NULL;
diff --git a/chrome/browser/media_galleries/fileapi/itunes_data_provider.h b/chrome/browser/media_galleries/fileapi/itunes_data_provider.h
index 893d9a6..788d4785 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_data_provider.h
+++ b/chrome/browser/media_galleries/fileapi/itunes_data_provider.h
@@ -32,7 +32,7 @@
   typedef std::map<TrackName, base::FilePath> Album;
 
   explicit ITunesDataProvider(const base::FilePath& library_path);
-  virtual ~ITunesDataProvider();
+  ~ITunesDataProvider() override;
 
   // Get the platform path for the auto-add directory.
   virtual const base::FilePath& auto_add_path() const;
@@ -65,8 +65,8 @@
   typedef std::map<ArtistName, Artist> Library;
 
   // Parse the library xml file.
-  virtual void DoParseLibrary(const base::FilePath& library_path,
-                              const ReadyCallback& ready_callback) override;
+  void DoParseLibrary(const base::FilePath& library_path,
+                      const ReadyCallback& ready_callback) override;
 
   // Called when the utility process finishes parsing the library XML file.
   void OnLibraryParsed(const ReadyCallback& ready_callback,
diff --git a/chrome/browser/media_galleries/fileapi/itunes_data_provider_browsertest.cc b/chrome/browser/media_galleries/fileapi/itunes_data_provider_browsertest.cc
index d71ff0c..916bcb14 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_data_provider_browsertest.cc
+++ b/chrome/browser/media_galleries/fileapi/itunes_data_provider_browsertest.cc
@@ -54,11 +54,10 @@
       : ITunesDataProvider(xml_library_path),
         callback_(callback) {
   }
-  virtual ~TestITunesDataProvider() {}
+  ~TestITunesDataProvider() override {}
 
  private:
-  virtual void OnLibraryChanged(const base::FilePath& path,
-                                bool error) override {
+  void OnLibraryChanged(const base::FilePath& path, bool error) override {
     ITunesDataProvider::OnLibraryChanged(path, error);
     callback_.Run();
   }
@@ -217,14 +216,14 @@
   ITunesDataProviderBasicTest() {}
   virtual ~ITunesDataProviderBasicTest() {}
 
-  virtual std::vector<LibraryEntry> SetUpLibrary() override {
+  std::vector<LibraryEntry> SetUpLibrary() override {
     base::FilePath track = library_dir().AppendASCII("Track.mp3");
     std::vector<LibraryEntry> entries;
     entries.push_back(LibraryEntry("Artist", "Album", track));
     return entries;
   }
 
-  virtual void StartTest(bool parse_success) override {
+  void StartTest(bool parse_success) override {
     EXPECT_TRUE(parse_success);
 
     // KnownArtist
@@ -285,14 +284,14 @@
   ITunesDataProviderRefreshTest() {}
   virtual ~ITunesDataProviderRefreshTest() {}
 
-  virtual std::vector<LibraryEntry> SetUpLibrary() override {
+  std::vector<LibraryEntry> SetUpLibrary() override {
     base::FilePath track = library_dir().AppendASCII("Track.mp3");
     std::vector<LibraryEntry> entries;
     entries.push_back(LibraryEntry("Artist", "Album", track));
     return entries;
   }
 
-  virtual void StartTest(bool parse_success) override {
+  void StartTest(bool parse_success) override {
     EXPECT_TRUE(parse_success);
 
     // Initial contents.
@@ -335,14 +334,14 @@
   ITunesDataProviderInvalidTest() {}
   virtual ~ITunesDataProviderInvalidTest() {}
 
-  virtual std::vector<LibraryEntry> SetUpLibrary() override {
+  std::vector<LibraryEntry> SetUpLibrary() override {
     base::FilePath track = library_dir().AppendASCII("Track.mp3");
     std::vector<LibraryEntry> entries;
     entries.push_back(LibraryEntry("Artist", "Album", track));
     return entries;
   }
 
-  virtual void StartTest(bool parse_success) override {
+  void StartTest(bool parse_success) override {
     EXPECT_TRUE(parse_success);
 
     SetLibraryChangeCallback(
@@ -367,7 +366,7 @@
   ITunesDataProviderUniqueNameTest() {}
   virtual ~ITunesDataProviderUniqueNameTest() {}
 
-  virtual std::vector<LibraryEntry> SetUpLibrary() override {
+  std::vector<LibraryEntry> SetUpLibrary() override {
     base::FilePath track = library_dir().AppendASCII("Track.mp3");
     std::vector<LibraryEntry> entries;
     // Dupe album names should get uniquified with the track id, which in the
@@ -378,7 +377,7 @@
     return entries;
   }
 
-  virtual void StartTest(bool parse_success) override {
+  void StartTest(bool parse_success) override {
     EXPECT_TRUE(parse_success);
 
     base::FilePath track =
@@ -411,7 +410,7 @@
   ITunesDataProviderEscapeTest() {}
   virtual ~ITunesDataProviderEscapeTest() {}
 
-  virtual std::vector<LibraryEntry> SetUpLibrary() override {
+  std::vector<LibraryEntry> SetUpLibrary() override {
     base::FilePath track = library_dir().AppendASCII("Track:1.mp3");
     std::vector<LibraryEntry> entries;
     entries.push_back(LibraryEntry("Artist:/name", "Album:name/", track));
@@ -421,7 +420,7 @@
     return entries;
   }
 
-  virtual void StartTest(bool parse_success) override {
+  void StartTest(bool parse_success) override {
     EXPECT_TRUE(parse_success);
 
     base::FilePath track =
diff --git a/chrome/browser/media_galleries/fileapi/itunes_file_util.h b/chrome/browser/media_galleries/fileapi/itunes_file_util.h
index 8905977..9c068e5 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_file_util.h
+++ b/chrome/browser/media_galleries/fileapi/itunes_file_util.h
@@ -23,44 +23,43 @@
 class ITunesFileUtil : public NativeMediaFileUtil {
  public:
   explicit ITunesFileUtil(MediaPathFilter* media_path_filter);
-  virtual ~ITunesFileUtil();
+  ~ITunesFileUtil() override;
 
  protected:
   // NativeMediaFileUtil overrides.
-  virtual void GetFileInfoOnTaskRunnerThread(
+  void GetFileInfoOnTaskRunnerThread(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const GetFileInfoCallback& callback) override;
-  virtual void ReadDirectoryOnTaskRunnerThread(
+  void ReadDirectoryOnTaskRunnerThread(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const ReadDirectoryCallback& callback) override;
-  virtual void CreateSnapshotFileOnTaskRunnerThread(
+  void CreateSnapshotFileOnTaskRunnerThread(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const CreateSnapshotFileCallback& callback) override;
-  virtual base::File::Error GetFileInfoSync(
+  base::File::Error GetFileInfoSync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       base::File::Info* file_info,
       base::FilePath* platform_path) override;
-  virtual base::File::Error ReadDirectorySync(
+  base::File::Error ReadDirectorySync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       EntryList* file_list) override;
-  virtual base::File::Error DeleteDirectorySync(
+  base::File::Error DeleteDirectorySync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url) override;
-  virtual base::File::Error DeleteFileSync(
-      storage::FileSystemOperationContext* context,
-      const storage::FileSystemURL& url) override;
-  virtual base::File::Error CreateSnapshotFileSync(
+  base::File::Error DeleteFileSync(storage::FileSystemOperationContext* context,
+                                   const storage::FileSystemURL& url) override;
+  base::File::Error CreateSnapshotFileSync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       base::File::Info* file_info,
       base::FilePath* platform_path,
       scoped_refptr<storage::ShareableFileReference>* file_ref) override;
-  virtual base::File::Error GetLocalFilePath(
+  base::File::Error GetLocalFilePath(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       base::FilePath* local_file_path) override;
diff --git a/chrome/browser/media_galleries/fileapi/itunes_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/itunes_file_util_unittest.cc
index d6bb474..e2f301b 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/itunes_file_util_unittest.cc
@@ -71,13 +71,13 @@
     EXPECT_TRUE(fake_auto_add_dir_.CreateUniqueTempDir());
   }
 
-  virtual ~TestITunesDataProvider() {}
+  ~TestITunesDataProvider() override {}
 
-  virtual void RefreshData(const ReadyCallback& ready_callback) override {
+  void RefreshData(const ReadyCallback& ready_callback) override {
     ready_callback.Run(true /* success */);
   }
 
-  virtual const base::FilePath& auto_add_path() const override {
+  const base::FilePath& auto_add_path() const override {
     return fake_auto_add_dir_.path();
   }
 
@@ -101,12 +101,10 @@
       : ITunesFileUtil(media_path_filter),
         data_provider_(data_provider) {
   }
-  virtual ~TestITunesFileUtil() {}
+  ~TestITunesFileUtil() override {}
 
  private:
-  virtual ITunesDataProvider* GetDataProvider() override {
-    return data_provider_;
-  }
+  ITunesDataProvider* GetDataProvider() override { return data_provider_; }
 
   ITunesDataProvider* data_provider_;
 };
@@ -120,7 +118,7 @@
             MediaFileSystemBackend::MediaTaskRunner().get()),
         test_file_util_(itunes_file_util) {}
 
-  virtual storage::AsyncFileUtil* GetAsyncFileUtil(
+  storage::AsyncFileUtil* GetAsyncFileUtil(
       storage::FileSystemType type) override {
     if (type != storage::kFileSystemTypeItunes)
       return NULL;
diff --git a/chrome/browser/media_galleries/fileapi/media_file_system_backend.h b/chrome/browser/media_galleries/fileapi/media_file_system_backend.h
index aa164d0..061c1272 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_system_backend.h
+++ b/chrome/browser/media_galleries/fileapi/media_file_system_backend.h
@@ -37,7 +37,7 @@
   MediaFileSystemBackend(
       const base::FilePath& profile_path,
       base::SequencedTaskRunner* media_task_runner);
-  virtual ~MediaFileSystemBackend();
+  ~MediaFileSystemBackend() override;
 
   static bool CurrentlyOnMediaTaskRunnerThread();
   static scoped_refptr<base::SequencedTaskRunner> MediaTaskRunner();
@@ -55,42 +55,41 @@
       const base::Callback<void(base::File::Error result)>& callback);
 
   // FileSystemBackend implementation.
-  virtual bool CanHandleType(storage::FileSystemType type) const override;
-  virtual void Initialize(storage::FileSystemContext* context) override;
-  virtual void ResolveURL(const storage::FileSystemURL& url,
-                          storage::OpenFileSystemMode mode,
-                          const OpenFileSystemCallback& callback) override;
-  virtual storage::AsyncFileUtil* GetAsyncFileUtil(
+  bool CanHandleType(storage::FileSystemType type) const override;
+  void Initialize(storage::FileSystemContext* context) override;
+  void ResolveURL(const storage::FileSystemURL& url,
+                  storage::OpenFileSystemMode mode,
+                  const OpenFileSystemCallback& callback) override;
+  storage::AsyncFileUtil* GetAsyncFileUtil(
       storage::FileSystemType type) override;
-  virtual storage::WatcherManager* GetWatcherManager(
+  storage::WatcherManager* GetWatcherManager(
       storage::FileSystemType type) override;
-  virtual storage::CopyOrMoveFileValidatorFactory*
-      GetCopyOrMoveFileValidatorFactory(storage::FileSystemType type,
-                                        base::File::Error* error_code) override;
-  virtual storage::FileSystemOperation* CreateFileSystemOperation(
+  storage::CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
+      storage::FileSystemType type,
+      base::File::Error* error_code) override;
+  storage::FileSystemOperation* CreateFileSystemOperation(
       const storage::FileSystemURL& url,
       storage::FileSystemContext* context,
       base::File::Error* error_code) const override;
-  virtual bool SupportsStreaming(
-      const storage::FileSystemURL& url) const override;
-  virtual bool HasInplaceCopyImplementation(
+  bool SupportsStreaming(const storage::FileSystemURL& url) const override;
+  bool HasInplaceCopyImplementation(
       storage::FileSystemType type) const override;
-  virtual scoped_ptr<storage::FileStreamReader> CreateFileStreamReader(
+  scoped_ptr<storage::FileStreamReader> CreateFileStreamReader(
       const storage::FileSystemURL& url,
       int64 offset,
       int64 max_bytes_to_read,
       const base::Time& expected_modification_time,
       storage::FileSystemContext* context) const override;
-  virtual scoped_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
+  scoped_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
       const storage::FileSystemURL& url,
       int64 offset,
       storage::FileSystemContext* context) const override;
-  virtual storage::FileSystemQuotaUtil* GetQuotaUtil() override;
-  virtual const storage::UpdateObserverList* GetUpdateObservers(
+  storage::FileSystemQuotaUtil* GetQuotaUtil() override;
+  const storage::UpdateObserverList* GetUpdateObservers(
       storage::FileSystemType type) const override;
-  virtual const storage::ChangeObserverList* GetChangeObservers(
+  const storage::ChangeObserverList* GetChangeObservers(
       storage::FileSystemType type) const override;
-  virtual const storage::AccessObserverList* GetAccessObservers(
+  const storage::AccessObserverList* GetAccessObservers(
       storage::FileSystemType type) const override;
 
  private:
diff --git a/chrome/browser/media_galleries/fileapi/media_file_validator_factory.cc b/chrome/browser/media_galleries/fileapi/media_file_validator_factory.cc
index 5965eb7..608f49f 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_validator_factory.cc
+++ b/chrome/browser/media_galleries/fileapi/media_file_validator_factory.cc
@@ -14,14 +14,14 @@
 
 class InvalidFileValidator : public storage::CopyOrMoveFileValidator {
  public:
-  virtual ~InvalidFileValidator() {}
-  virtual void StartPreWriteValidation(
+  ~InvalidFileValidator() override {}
+  void StartPreWriteValidation(
       const storage::CopyOrMoveFileValidator::ResultCallback& result_callback)
       override {
     result_callback.Run(base::File::FILE_ERROR_SECURITY);
   }
 
-  virtual void StartPostWriteValidation(
+  void StartPostWriteValidation(
       const base::FilePath& dest_platform_path,
       const storage::CopyOrMoveFileValidator::ResultCallback& result_callback)
       override {
diff --git a/chrome/browser/media_galleries/fileapi/media_file_validator_factory.h b/chrome/browser/media_galleries/fileapi/media_file_validator_factory.h
index b351d92..a18b7e0 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_validator_factory.h
+++ b/chrome/browser/media_galleries/fileapi/media_file_validator_factory.h
@@ -23,10 +23,10 @@
     : public storage::CopyOrMoveFileValidatorFactory {
  public:
   MediaFileValidatorFactory();
-  virtual ~MediaFileValidatorFactory();
+  ~MediaFileValidatorFactory() override;
 
   // CopyOrMoveFileValidatorFactory implementation.
-  virtual storage::CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
+  storage::CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
       const storage::FileSystemURL& src,
       const base::FilePath& platform_path) override;
 
diff --git a/chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h b/chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h
index 7fcfcacf..59ba5cbd 100644
--- a/chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h
+++ b/chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h
@@ -30,13 +30,13 @@
                       const base::Time& expected_modification_time,
                       bool do_media_header_validation);
 
-  virtual ~MTPFileStreamReader();
+  ~MTPFileStreamReader() override;
 
   // FileStreamReader overrides.
-  virtual int Read(net::IOBuffer* buf, int buf_len,
-                   const net::CompletionCallback& callback) override;
-  virtual int64 GetLength(
-      const net::Int64CompletionCallback& callback) override;
+  int Read(net::IOBuffer* buf,
+           int buf_len,
+           const net::CompletionCallback& callback) override;
+  int64 GetLength(const net::Int64CompletionCallback& callback) override;
 
  private:
   void FinishValidateMediaHeader(
diff --git a/chrome/browser/media_galleries/fileapi/native_media_file_util.h b/chrome/browser/media_galleries/fileapi/native_media_file_util.h
index 457543968..778b72dd 100644
--- a/chrome/browser/media_galleries/fileapi/native_media_file_util.h
+++ b/chrome/browser/media_galleries/fileapi/native_media_file_util.h
@@ -21,7 +21,7 @@
 class NativeMediaFileUtil : public storage::AsyncFileUtil {
  public:
   explicit NativeMediaFileUtil(MediaPathFilter* media_path_filter);
-  virtual ~NativeMediaFileUtil();
+  ~NativeMediaFileUtil() override;
 
   // Uses the MIME sniffer code, which actually looks into the file,
   // to determine if it is really a media file (to avoid exposing
@@ -42,69 +42,60 @@
       const scoped_refptr<storage::ShareableFileReference>& file_ref);
 
   // AsyncFileUtil overrides.
-  virtual void CreateOrOpen(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      int file_flags,
-      const CreateOrOpenCallback& callback) override;
-  virtual void EnsureFileExists(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const EnsureFileExistsCallback& callback) override;
-  virtual void CreateDirectory(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      bool exclusive,
-      bool recursive,
-      const StatusCallback& callback) override;
-  virtual void GetFileInfo(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const GetFileInfoCallback& callback) override;
-  virtual void ReadDirectory(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const ReadDirectoryCallback& callback) override;
-  virtual void Touch(scoped_ptr<storage::FileSystemOperationContext> context,
-                     const storage::FileSystemURL& url,
-                     const base::Time& last_access_time,
-                     const base::Time& last_modified_time,
-                     const StatusCallback& callback) override;
-  virtual void Truncate(scoped_ptr<storage::FileSystemOperationContext> context,
+  void CreateOrOpen(scoped_ptr<storage::FileSystemOperationContext> context,
+                    const storage::FileSystemURL& url,
+                    int file_flags,
+                    const CreateOrOpenCallback& callback) override;
+  void EnsureFileExists(scoped_ptr<storage::FileSystemOperationContext> context,
                         const storage::FileSystemURL& url,
-                        int64 length,
-                        const StatusCallback& callback) override;
-  virtual void CopyFileLocal(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& src_url,
-      const storage::FileSystemURL& dest_url,
-      CopyOrMoveOption option,
-      const CopyFileProgressCallback& progress_callback,
-      const StatusCallback& callback) override;
-  virtual void MoveFileLocal(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& src_url,
-      const storage::FileSystemURL& dest_url,
-      CopyOrMoveOption option,
-      const StatusCallback& callback) override;
-  virtual void CopyInForeignFile(
+                        const EnsureFileExistsCallback& callback) override;
+  void CreateDirectory(scoped_ptr<storage::FileSystemOperationContext> context,
+                       const storage::FileSystemURL& url,
+                       bool exclusive,
+                       bool recursive,
+                       const StatusCallback& callback) override;
+  void GetFileInfo(scoped_ptr<storage::FileSystemOperationContext> context,
+                   const storage::FileSystemURL& url,
+                   const GetFileInfoCallback& callback) override;
+  void ReadDirectory(scoped_ptr<storage::FileSystemOperationContext> context,
+                     const storage::FileSystemURL& url,
+                     const ReadDirectoryCallback& callback) override;
+  void Touch(scoped_ptr<storage::FileSystemOperationContext> context,
+             const storage::FileSystemURL& url,
+             const base::Time& last_access_time,
+             const base::Time& last_modified_time,
+             const StatusCallback& callback) override;
+  void Truncate(scoped_ptr<storage::FileSystemOperationContext> context,
+                const storage::FileSystemURL& url,
+                int64 length,
+                const StatusCallback& callback) override;
+  void CopyFileLocal(scoped_ptr<storage::FileSystemOperationContext> context,
+                     const storage::FileSystemURL& src_url,
+                     const storage::FileSystemURL& dest_url,
+                     CopyOrMoveOption option,
+                     const CopyFileProgressCallback& progress_callback,
+                     const StatusCallback& callback) override;
+  void MoveFileLocal(scoped_ptr<storage::FileSystemOperationContext> context,
+                     const storage::FileSystemURL& src_url,
+                     const storage::FileSystemURL& dest_url,
+                     CopyOrMoveOption option,
+                     const StatusCallback& callback) override;
+  void CopyInForeignFile(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const base::FilePath& src_file_path,
       const storage::FileSystemURL& dest_url,
       const StatusCallback& callback) override;
-  virtual void DeleteFile(
+  void DeleteFile(scoped_ptr<storage::FileSystemOperationContext> context,
+                  const storage::FileSystemURL& url,
+                  const StatusCallback& callback) override;
+  void DeleteDirectory(scoped_ptr<storage::FileSystemOperationContext> context,
+                       const storage::FileSystemURL& url,
+                       const StatusCallback& callback) override;
+  void DeleteRecursively(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const StatusCallback& callback) override;
-  virtual void DeleteDirectory(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const StatusCallback& callback) override;
-  virtual void DeleteRecursively(
-      scoped_ptr<storage::FileSystemOperationContext> context,
-      const storage::FileSystemURL& url,
-      const StatusCallback& callback) override;
-  virtual void CreateSnapshotFile(
+  void CreateSnapshotFile(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const CreateSnapshotFileCallback& callback) override;
diff --git a/chrome/browser/media_galleries/fileapi/picasa_data_provider_browsertest.cc b/chrome/browser/media_galleries/fileapi/picasa_data_provider_browsertest.cc
index 31b1982..e4a47f0 100644
--- a/chrome/browser/media_galleries/fileapi/picasa_data_provider_browsertest.cc
+++ b/chrome/browser/media_galleries/fileapi/picasa_data_provider_browsertest.cc
@@ -103,7 +103,7 @@
         file_watch_request_returned_(false)  {
   }
 
-  virtual ~TestPicasaDataProvider() {}
+  ~TestPicasaDataProvider() override {}
 
   // |ready_callback| called with true if and when the file watch is started
   // successfully. If the file watch fails, it's called with false.
@@ -137,7 +137,7 @@
     invalidate_callback_ = callback;
   }
 
-  virtual void InvalidateData() override {
+  void InvalidateData() override {
     PicasaDataProvider::InvalidateData();
 
     if (!invalidate_callback_.is_null()) {
@@ -153,7 +153,7 @@
   }
 
  private:
-  virtual void OnTempDirWatchStarted(
+  void OnTempDirWatchStarted(
       scoped_ptr<base::FilePathWatcher> temp_dir_watcher) override {
     PicasaDataProvider::OnTempDirWatchStarted(temp_dir_watcher.Pass());
 
@@ -279,10 +279,10 @@
 
 class PicasaDataProviderNoDatabaseGetListTest : public PicasaDataProviderTest {
  protected:
-  virtual PicasaDataProvider::DataType RequestedDataType() const override {
+  PicasaDataProvider::DataType RequestedDataType() const override {
     return PicasaDataProvider::LIST_OF_ALBUMS_AND_FOLDERS_DATA;
   }
-  virtual void VerifyRefreshResults(bool parse_success) override {
+  void VerifyRefreshResults(bool parse_success) override {
     EXPECT_FALSE(parse_success);
     TestDone();
   }
@@ -296,10 +296,10 @@
 class PicasaDataProviderNoDatabaseGetAlbumsImagesTest
     : public PicasaDataProviderTest {
  protected:
-  virtual PicasaDataProvider::DataType RequestedDataType() const override {
+  PicasaDataProvider::DataType RequestedDataType() const override {
     return PicasaDataProvider::ALBUMS_IMAGES_DATA;
   }
-  virtual void VerifyRefreshResults(bool parse_success) override {
+  void VerifyRefreshResults(bool parse_success) override {
     EXPECT_FALSE(parse_success);
     TestDone();
   }
@@ -312,16 +312,16 @@
 
 class PicasaDataProviderGetListTest : public PicasaDataProviderTest {
  protected:
-  virtual void InitializeTestData() override {
+  void InitializeTestData() override {
     WriteTestAlbumTable(GetColumnFileDestination(), test_folder_1_path(),
                         test_folder_2_path());
   }
 
-  virtual PicasaDataProvider::DataType RequestedDataType() const override {
+  PicasaDataProvider::DataType RequestedDataType() const override {
     return PicasaDataProvider::LIST_OF_ALBUMS_AND_FOLDERS_DATA;
   }
 
-  virtual void VerifyRefreshResults(bool parse_success) override {
+  void VerifyRefreshResults(bool parse_success) override {
     ASSERT_TRUE(parse_success);
     VerifyTestAlbumTable(
         data_provider(), test_folder_1_path(), test_folder_2_path());
@@ -335,17 +335,17 @@
 
 class PicasaDataProviderGetAlbumsImagesTest : public PicasaDataProviderTest {
  protected:
-  virtual void InitializeTestData() override {
+  void InitializeTestData() override {
     WriteTestAlbumTable(GetColumnFileDestination(), test_folder_1_path(),
                         test_folder_2_path());
     WriteTestAlbumsImagesIndex(test_folder_1_path(), test_folder_2_path());
   }
 
-  virtual PicasaDataProvider::DataType RequestedDataType() const override {
+  PicasaDataProvider::DataType RequestedDataType() const override {
     return PicasaDataProvider::ALBUMS_IMAGES_DATA;
   }
 
-  virtual void VerifyRefreshResults(bool parse_success) override {
+  void VerifyRefreshResults(bool parse_success) override {
     ASSERT_TRUE(parse_success);
     VerifyTestAlbumTable(
         data_provider(), test_folder_1_path(), test_folder_2_path());
@@ -366,13 +366,13 @@
   PicasaDataProviderMultipleMixedCallbacksTest()
       : list_callbacks_called_(0), albums_images_callbacks_called_(0) {}
 
-  virtual void InitializeTestData() override {
+  void InitializeTestData() override {
     WriteTestAlbumTable(GetColumnFileDestination(), test_folder_1_path(),
                         test_folder_2_path());
     WriteTestAlbumsImagesIndex(test_folder_1_path(), test_folder_2_path());
   }
 
-  virtual PicasaDataProvider::DataType RequestedDataType() const override {
+  PicasaDataProvider::DataType RequestedDataType() const override {
     return PicasaDataProvider::ALBUMS_IMAGES_DATA;
   }
 
@@ -404,7 +404,7 @@
       TestDone();
   }
 
-  virtual void StartTestOnMediaTaskRunner() override {
+  void StartTestOnMediaTaskRunner() override {
     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
 
     data_provider()->RefreshData(
@@ -466,12 +466,12 @@
     data_provider()->MoveTempFilesToDatabase();
   }
 
-  virtual base::FilePath GetColumnFileDestination() const override {
+  base::FilePath GetColumnFileDestination() const override {
     return GetTempDirPath();
   }
 
  private:
-  virtual void StartTestOnMediaTaskRunner() override {
+  void StartTestOnMediaTaskRunner() override {
     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
 
     // Refresh before moving album table to database dir, guaranteeing failure.
@@ -492,10 +492,10 @@
     : public PicasaDataProviderGetListTest {
  protected:
   // Don't write the database files until later.
-  virtual void InitializeTestData() override {}
+  void InitializeTestData() override {}
 
  private:
-  virtual void StartTestOnMediaTaskRunner() override {
+  void StartTestOnMediaTaskRunner() override {
     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
 
     // Refresh before the database files have been written.
@@ -541,7 +541,7 @@
   }
 
  private:
-  virtual void StartTestOnMediaTaskRunner() override {
+  void StartTestOnMediaTaskRunner() override {
     DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
 
     data_provider()->RefreshData(
diff --git a/chrome/browser/media_galleries/fileapi/picasa_file_util.h b/chrome/browser/media_galleries/fileapi/picasa_file_util.h
index 279d093..8d1a1669 100644
--- a/chrome/browser/media_galleries/fileapi/picasa_file_util.h
+++ b/chrome/browser/media_galleries/fileapi/picasa_file_util.h
@@ -28,34 +28,33 @@
 class PicasaFileUtil : public NativeMediaFileUtil {
  public:
   explicit PicasaFileUtil(MediaPathFilter* media_path_filter);
-  virtual ~PicasaFileUtil();
+  ~PicasaFileUtil() override;
 
  protected:
   // NativeMediaFileUtil overrides.
-  virtual void GetFileInfoOnTaskRunnerThread(
+  void GetFileInfoOnTaskRunnerThread(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const GetFileInfoCallback& callback) override;
-  virtual void ReadDirectoryOnTaskRunnerThread(
+  void ReadDirectoryOnTaskRunnerThread(
       scoped_ptr<storage::FileSystemOperationContext> context,
       const storage::FileSystemURL& url,
       const ReadDirectoryCallback& callback) override;
-  virtual base::File::Error GetFileInfoSync(
+  base::File::Error GetFileInfoSync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       base::File::Info* file_info,
       base::FilePath* platform_path) override;
-  virtual base::File::Error ReadDirectorySync(
+  base::File::Error ReadDirectorySync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       EntryList* file_list) override;
-  virtual base::File::Error DeleteDirectorySync(
+  base::File::Error DeleteDirectorySync(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url) override;
-  virtual base::File::Error DeleteFileSync(
-      storage::FileSystemOperationContext* context,
-      const storage::FileSystemURL& url) override;
-  virtual base::File::Error GetLocalFilePath(
+  base::File::Error DeleteFileSync(storage::FileSystemOperationContext* context,
+                                   const storage::FileSystemURL& url) override;
+  base::File::Error GetLocalFilePath(
       storage::FileSystemOperationContext* context,
       const storage::FileSystemURL& url,
       base::FilePath* local_file_path) override;
diff --git a/chrome/browser/media_galleries/fileapi/picasa_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/picasa_file_util_unittest.cc
index b773ee3..c81bb46c 100644
--- a/chrome/browser/media_galleries/fileapi/picasa_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/picasa_file_util_unittest.cc
@@ -190,11 +190,10 @@
       : PicasaFileUtil(media_path_filter),
         data_provider_(data_provider) {
   }
-  virtual ~TestPicasaFileUtil() {}
+  ~TestPicasaFileUtil() override {}
+
  private:
-  virtual PicasaDataProvider* GetDataProvider() override {
-    return data_provider_;
-  }
+  PicasaDataProvider* GetDataProvider() override { return data_provider_; }
 
   PicasaDataProvider* data_provider_;
 };
@@ -207,7 +206,7 @@
                                MediaFileSystemBackend::MediaTaskRunner().get()),
         test_file_util_(picasa_file_util) {}
 
-  virtual storage::AsyncFileUtil* GetAsyncFileUtil(
+  storage::AsyncFileUtil* GetAsyncFileUtil(
       storage::FileSystemType type) override {
     if (type != storage::kFileSystemTypePicasa)
       return NULL;
diff --git a/chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h b/chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h
index e3ea73a..4a35d8f 100644
--- a/chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h
+++ b/chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h
@@ -18,13 +18,13 @@
   // Takes ownership of |source|.
   explicit ReadaheadFileStreamReader(storage::FileStreamReader* source);
 
-  virtual ~ReadaheadFileStreamReader();
+  ~ReadaheadFileStreamReader() override;
 
   // FileStreamReader overrides.
-  virtual int Read(net::IOBuffer* buf, int buf_len,
-                   const net::CompletionCallback& callback) override;
-  virtual int64 GetLength(
-      const net::Int64CompletionCallback& callback) override;
+  int Read(net::IOBuffer* buf,
+           int buf_len,
+           const net::CompletionCallback& callback) override;
+  int64 GetLength(const net::Int64CompletionCallback& callback) override;
 
  private:
   // Returns the number of bytes consumed from the internal cache into |sink|.
diff --git a/chrome/browser/media_galleries/fileapi/safe_audio_video_checker.h b/chrome/browser/media_galleries/fileapi/safe_audio_video_checker.h
index b548349..9a1fac17 100644
--- a/chrome/browser/media_galleries/fileapi/safe_audio_video_checker.h
+++ b/chrome/browser/media_galleries/fileapi/safe_audio_video_checker.h
@@ -39,7 +39,7 @@
     FINISHED_STATE
   };
 
-  virtual ~SafeAudioVideoChecker();
+  ~SafeAudioVideoChecker() override;
 
   // Starts validation once the utility process has been started.
   virtual void OnProcessStarted();
@@ -48,8 +48,8 @@
   void OnCheckingFinished(bool valid);
 
   // UtilityProcessHostClient implementation.
-  virtual void OnProcessCrashed(int exit_code) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OnProcessCrashed(int exit_code) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   State state_;
 
diff --git a/chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h b/chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h
index 91a9069..4d940e1 100644
--- a/chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h
+++ b/chrome/browser/media_galleries/fileapi/safe_iapps_library_parser.h
@@ -59,7 +59,7 @@
   };
 
   // content::UtilityProcessHostClient is ref-counted.
-  virtual ~SafeIAppsLibraryParser();
+  ~SafeIAppsLibraryParser() override;
 
   // Posts a task to start the XML parsing in the utility process.
   void Start();
@@ -91,8 +91,8 @@
 
   // UtilityProcessHostClient implementation.
   // Runs on the IO thread.
-  virtual void OnProcessCrashed(int exit_code) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OnProcessCrashed(int exit_code) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   base::FilePath library_file_path_;
 
diff --git a/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h b/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h
index 1e5b8a7..ac18b80 100644
--- a/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h
+++ b/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h
@@ -53,7 +53,7 @@
   };
 
   // Private because content::UtilityProcessHostClient is ref-counted.
-  virtual ~SafeMediaMetadataParser();
+  ~SafeMediaMetadataParser() override;
 
   // Launches the utility process.  Must run on the IO thread.
   void StartWorkOnIOThread(const DoneCallback& callback);
@@ -77,8 +77,8 @@
 
   // UtilityProcessHostClient implementation.
   // Runs on the IO thread.
-  virtual void OnProcessCrashed(int exit_code) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OnProcessCrashed(int exit_code) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // All member variables are only accessed on the IO thread.
   Profile* const profile_;
diff --git a/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h b/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h
index 82845ae..139f17f9 100644
--- a/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h
+++ b/chrome/browser/media_galleries/fileapi/safe_picasa_album_table_reader.h
@@ -50,7 +50,7 @@
   };
 
   // Private because content::UtilityProcessHostClient is ref-counted.
-  virtual ~SafePicasaAlbumTableReader();
+  ~SafePicasaAlbumTableReader() override;
 
   // Launches the utility process.  Must run on the IO thread.
   void StartWorkOnIOThread();
@@ -69,8 +69,8 @@
 
   // UtilityProcessHostClient implementation.
   // Runs on the IO thread.
-  virtual void OnProcessCrashed(int exit_code) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OnProcessCrashed(int exit_code) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   AlbumTableFiles album_table_files_;
 
diff --git a/chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.h b/chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.h
index e9b1317..45ac9b9 100644
--- a/chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.h
+++ b/chrome/browser/media_galleries/fileapi/safe_picasa_albums_indexer.h
@@ -47,7 +47,7 @@
   };
 
   // Private because content::UtilityProcessHostClient is ref-counted.
-  virtual ~SafePicasaAlbumsIndexer();
+  ~SafePicasaAlbumsIndexer() override;
 
   // Processes a batch of folders. Reposts itself until done, then starts IPC.
   void ProcessFoldersBatch();
@@ -62,8 +62,8 @@
 
   // UtilityProcessHostClient implementation.
   // Runs on the IO thread.
-  virtual void OnProcessCrashed(int exit_code) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OnProcessCrashed(int exit_code) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   AlbumUIDSet album_uids_;
 
diff --git a/chrome/browser/media_galleries/fileapi/supported_audio_video_checker.h b/chrome/browser/media_galleries/fileapi/supported_audio_video_checker.h
index 6ed5ceb..031b36c 100644
--- a/chrome/browser/media_galleries/fileapi/supported_audio_video_checker.h
+++ b/chrome/browser/media_galleries/fileapi/supported_audio_video_checker.h
@@ -21,12 +21,11 @@
 // this class does not make the file safe to use in the browser process.
 class SupportedAudioVideoChecker : public AVScanningFileValidator {
  public:
-  virtual ~SupportedAudioVideoChecker();
+  ~SupportedAudioVideoChecker() override;
 
   static bool SupportsFileType(const base::FilePath& path);
 
-  virtual void StartPreWriteValidation(
-      const ResultCallback& result_callback) override;
+  void StartPreWriteValidation(const ResultCallback& result_callback) override;
 
  private:
   friend class MediaFileValidatorFactory;
diff --git a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
index 0b43513..460a563b 100644
--- a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
+++ b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
@@ -61,13 +61,13 @@
   }
 
   // ImageDecoder::Delegate methods.
-  virtual void OnImageDecoded(const ImageDecoder* /*decoder*/,
-                              const SkBitmap& /*decoded_image*/) override {
+  void OnImageDecoded(const ImageDecoder* /*decoder*/,
+                      const SkBitmap& /*decoded_image*/) override {
     callback_.Run(base::File::FILE_OK);
     delete this;
   }
 
-  virtual void OnDecodeImageFailed(const ImageDecoder* /*decoder*/) override {
+  void OnDecodeImageFailed(const ImageDecoder* /*decoder*/) override {
     callback_.Run(base::File::FILE_ERROR_SECURITY);
     delete this;
   }
diff --git a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.h b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.h
index 6edbf17..28924e8 100644
--- a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.h
+++ b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.h
@@ -19,12 +19,11 @@
 // image files supported by Chrome.
 class SupportedImageTypeValidator : public AVScanningFileValidator {
  public:
-  virtual ~SupportedImageTypeValidator();
+  ~SupportedImageTypeValidator() override;
 
   static bool SupportsFileType(const base::FilePath& path);
 
-  virtual void StartPreWriteValidation(
-      const ResultCallback& result_callback) override;
+  void StartPreWriteValidation(const ResultCallback& result_callback) override;
 
  private:
   friend class MediaFileValidatorFactory;
diff --git a/chrome/browser/media_galleries/gallery_watch_manager.h b/chrome/browser/media_galleries/gallery_watch_manager.h
index fdcac72..5ad691f 100644
--- a/chrome/browser/media_galleries/gallery_watch_manager.h
+++ b/chrome/browser/media_galleries/gallery_watch_manager.h
@@ -45,7 +45,7 @@
   static const char kCouldNotWatchGalleryError[];
 
   GalleryWatchManager();
-  virtual ~GalleryWatchManager();
+  ~GalleryWatchManager() override;
 
   // Add or remove observer of change events - this is the only way to
   // get the result of the file watches. There can only be one observer per
@@ -123,14 +123,14 @@
   void OnFilePathChanged(const base::FilePath& path, bool error);
 
   // MediaGalleriesPreferences::GalleryChangeObserver implementation.
-  virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref,
-                                   const std::string& extension_id,
-                                   MediaGalleryPrefId pref_id) override;
-  virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref,
-                                MediaGalleryPrefId pref_id) override;
+  void OnPermissionRemoved(MediaGalleriesPreferences* pref,
+                           const std::string& extension_id,
+                           MediaGalleryPrefId pref_id) override;
+  void OnGalleryRemoved(MediaGalleriesPreferences* pref,
+                        MediaGalleryPrefId pref_id) override;
 
   // storage_monitor::RemovableStorageObserver implementation.
-  virtual void OnRemovableStorageDetached(
+  void OnRemovableStorageDetached(
       const storage_monitor::StorageInfo& info) override;
 
   // True if the we are already observing the storage monitor.
diff --git a/chrome/browser/media_galleries/gallery_watch_manager_unittest.cc b/chrome/browser/media_galleries/gallery_watch_manager_unittest.cc
index 2a6a0ea..fcdba3d 100644
--- a/chrome/browser/media_galleries/gallery_watch_manager_unittest.cc
+++ b/chrome/browser/media_galleries/gallery_watch_manager_unittest.cc
@@ -148,14 +148,14 @@
 
  private:
   // GalleryWatchManagerObserver implementation.
-  virtual void OnGalleryChanged(const std::string& extension_id,
-                                MediaGalleryPrefId gallery_id) override {
+  void OnGalleryChanged(const std::string& extension_id,
+                        MediaGalleryPrefId gallery_id) override {
     EXPECT_TRUE(expect_gallery_changed_);
     pending_loop_->Quit();
   }
 
-  virtual void OnGalleryWatchDropped(const std::string& extension_id,
-                                     MediaGalleryPrefId gallery_id) override {
+  void OnGalleryWatchDropped(const std::string& extension_id,
+                             MediaGalleryPrefId gallery_id) override {
     EXPECT_TRUE(expect_gallery_watch_dropped_);
     pending_loop_->Quit();
   }
diff --git a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h
index 106a647..0440fbd 100644
--- a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h
+++ b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.h
@@ -32,31 +32,29 @@
   // MTPDeviceAsyncDelegate implementation. These functions are called on the
   // IO thread by the async filesystem file util. They forward to
   // similarly-named methods on the UI thread.
-  virtual void GetFileInfo(
-      const base::FilePath& file_path,
-      const GetFileInfoSuccessCallback& success_callback,
-      const ErrorCallback& error_callback) override;
+  void GetFileInfo(const base::FilePath& file_path,
+                   const GetFileInfoSuccessCallback& success_callback,
+                   const ErrorCallback& error_callback) override;
 
   // Note: passed absolute paths, but expects relative paths in reply.
-  virtual void ReadDirectory(
-      const base::FilePath& root,
-      const ReadDirectorySuccessCallback& success_callback,
-      const ErrorCallback& error_callback) override;
+  void ReadDirectory(const base::FilePath& root,
+                     const ReadDirectorySuccessCallback& success_callback,
+                     const ErrorCallback& error_callback) override;
 
   // Note: passed absolute paths.
-  virtual void CreateSnapshotFile(
+  void CreateSnapshotFile(
       const base::FilePath& device_file_path,
       const base::FilePath& local_path,
       const CreateSnapshotFileSuccessCallback& success_callback,
       const ErrorCallback& error_callback) override;
-  virtual bool IsStreaming() override;
-  virtual void ReadBytes(const base::FilePath& device_file_path,
-                         const scoped_refptr<net::IOBuffer>& buf,
-                         int64 offset,
-                         int buf_len,
-                         const ReadBytesSuccessCallback& success_callback,
-                         const ErrorCallback& error_callback) override;
-  virtual void CancelPendingTasksAndDeleteDelegate() override;
+  bool IsStreaming() override;
+  void ReadBytes(const base::FilePath& device_file_path,
+                 const scoped_refptr<net::IOBuffer>& buf,
+                 int64 offset,
+                 int buf_len,
+                 const ReadBytesSuccessCallback& success_callback,
+                 const ErrorCallback& error_callback) override;
+  void CancelPendingTasksAndDeleteDelegate() override;
 
   // Forward delegates for ImageCaptureDeviceListener. These are
   // invoked in callbacks of the ImageCapture library on the UI thread.
@@ -74,7 +72,7 @@
  private:
   class DeviceListener;
 
-  virtual ~MTPDeviceDelegateImplMac();
+  ~MTPDeviceDelegateImplMac() override;
 
   // Delegate for GetFileInfo, called on the UI thread.
   void GetFileInfoImpl(const base::FilePath& file_path,
diff --git a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm
index da9f06a9..9c54cc7 100644
--- a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm
+++ b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac.mm
@@ -38,7 +38,7 @@
  public:
   DeviceListener(MTPDeviceDelegateImplMac* delegate)
       : delegate_(delegate) {}
-  virtual ~DeviceListener() {}
+  ~DeviceListener() override {}
 
   void OpenCameraSession(const std::string& device_id);
   void CloseCameraSessionAndDelete();
@@ -46,12 +46,12 @@
   void DownloadFile(const std::string& name, const base::FilePath& local_path);
 
   // ImageCaptureDeviceListener
-  virtual void ItemAdded(const std::string& name,
-                         const base::File::Info& info) override;
-  virtual void NoMoreItems() override;
-  virtual void DownloadedFile(const std::string& name,
-                              base::File::Error error) override;
-  virtual void DeviceRemoved() override;
+  void ItemAdded(const std::string& name,
+                 const base::File::Info& info) override;
+  void NoMoreItems() override;
+  void DownloadedFile(const std::string& name,
+                      base::File::Error error) override;
+  void DeviceRemoved() override;
 
   // Used during delegate destruction to ensure there are no more calls
   // to the delegate by the listener.
diff --git a/chrome/browser/media_galleries/media_file_system_registry.cc b/chrome/browser/media_galleries/media_file_system_registry.cc
index cd4cd13b..9d7be17b 100644
--- a/chrome/browser/media_galleries/media_file_system_registry.cc
+++ b/chrome/browser/media_galleries/media_file_system_registry.cc
@@ -86,8 +86,8 @@
 
    private:
     // content::WebContentsObserver
-    virtual void WebContentsDestroyed() override;
-    virtual void NavigationEntryCommitted(
+    void WebContentsDestroyed() override;
+    void NavigationEntryCommitted(
         const content::LoadCommittedDetails& load_details) override;
 
     RPHReferenceManager* manager_;
@@ -96,7 +96,7 @@
   class RPHObserver : public content::RenderProcessHostObserver {
    public:
     RPHObserver(RPHReferenceManager* manager, RenderProcessHost* host);
-    virtual ~RPHObserver();
+    ~RPHObserver() override;
 
     void AddWebContentsObserver(WebContents* web_contents);
     void RemoveWebContentsObserver(WebContents* web_contents);
@@ -105,7 +105,7 @@
     }
 
    private:
-    virtual void RenderProcessHostDestroyed(RenderProcessHost* host) override;
+    void RenderProcessHostDestroyed(RenderProcessHost* host) override;
 
     RPHReferenceManager* manager_;
     RenderProcessHost* host_;
@@ -635,11 +635,11 @@
     : public MediaFileSystemContext {
  public:
   MediaFileSystemContextImpl() {}
-  virtual ~MediaFileSystemContextImpl() {}
+  ~MediaFileSystemContextImpl() override {}
 
-  virtual bool RegisterFileSystem(const std::string& device_id,
-                                  const std::string& fs_name,
-                                  const base::FilePath& path) override {
+  bool RegisterFileSystem(const std::string& device_id,
+                          const std::string& fs_name,
+                          const base::FilePath& path) override {
     if (StorageInfo::IsMassStorageDevice(device_id)) {
       return RegisterFileSystemForMassStorage(device_id, fs_name, path);
     } else {
@@ -647,7 +647,7 @@
     }
   }
 
-  virtual void RevokeFileSystem(const std::string& fs_name) override {
+  void RevokeFileSystem(const std::string& fs_name) override {
     ImportedMediaGalleryRegistry* imported_registry =
         ImportedMediaGalleryRegistry::GetInstance();
     if (imported_registry->RevokeImportedFilesystemOnUIThread(fs_name))
@@ -661,8 +661,7 @@
         fs_name));
   }
 
-  virtual base::FilePath GetRegisteredPath(
-      const std::string& fs_name) const override {
+  base::FilePath GetRegisteredPath(const std::string& fs_name) const override {
     base::FilePath result;
     if (!ExternalMountPoints::GetSystemInstance()->GetRegisteredPath(fs_name,
                                                                      &result)) {
diff --git a/chrome/browser/media_galleries/media_file_system_registry.h b/chrome/browser/media_galleries/media_file_system_registry.h
index 6398e34b..2b38233 100644
--- a/chrome/browser/media_galleries/media_file_system_registry.h
+++ b/chrome/browser/media_galleries/media_file_system_registry.h
@@ -73,7 +73,7 @@
       public MediaGalleriesPreferences::GalleryChangeObserver {
  public:
   MediaFileSystemRegistry();
-  virtual ~MediaFileSystemRegistry();
+  ~MediaFileSystemRegistry() override;
 
   // Passes to |callback| the list of media filesystem IDs and paths for a
   // given RVH.
@@ -99,7 +99,7 @@
   GalleryWatchManager* gallery_watch_manager();
 
   // RemovableStorageObserver implementation.
-  virtual void OnRemovableStorageDetached(
+  void OnRemovableStorageDetached(
       const storage_monitor::StorageInfo& info) override;
 
  private:
@@ -115,11 +115,11 @@
   // Map a profile and extension to the ExtensionGalleriesHost.
   typedef std::map<Profile*, ExtensionHostMap> ExtensionGalleriesHostMap;
 
-  virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref,
-                                   const std::string& extension_id,
-                                   MediaGalleryPrefId pref_id) override;
-  virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref,
-                                MediaGalleryPrefId pref_id) override;
+  void OnPermissionRemoved(MediaGalleriesPreferences* pref,
+                           const std::string& extension_id,
+                           MediaGalleryPrefId pref_id) override;
+  void OnGalleryRemoved(MediaGalleriesPreferences* pref,
+                        MediaGalleryPrefId pref_id) override;
 
   // Look up or create the extension gallery host.
   ExtensionGalleriesHost* GetExtensionGalleryHost(
diff --git a/chrome/browser/media_galleries/media_file_system_registry_unittest.cc b/chrome/browser/media_galleries/media_file_system_registry_unittest.cc
index e63ce00..e7eb9511 100644
--- a/chrome/browser/media_galleries/media_file_system_registry_unittest.cc
+++ b/chrome/browser/media_galleries/media_file_system_registry_unittest.cc
@@ -75,17 +75,16 @@
   };
 
   explicit TestMediaFileSystemContext(MediaFileSystemRegistry* registry);
-  virtual ~TestMediaFileSystemContext() {}
+  ~TestMediaFileSystemContext() override {}
 
   // MediaFileSystemContext implementation.
-  virtual bool RegisterFileSystem(const std::string& device_id,
-                                  const std::string& fs_name,
-                                  const base::FilePath& path) override;
+  bool RegisterFileSystem(const std::string& device_id,
+                          const std::string& fs_name,
+                          const base::FilePath& path) override;
 
-  virtual void RevokeFileSystem(const std::string& fs_name) override;
+  void RevokeFileSystem(const std::string& fs_name) override;
 
-  virtual base::FilePath GetRegisteredPath(
-      const std::string& fs_name) const override;
+  base::FilePath GetRegisteredPath(const std::string& fs_name) const override;
 
   MediaFileSystemRegistry* registry() { return registry_; }
 
@@ -192,14 +191,14 @@
     : public content::RenderProcessHostFactory {
  public:
   MockProfileSharedRenderProcessHostFactory() {}
-  virtual ~MockProfileSharedRenderProcessHostFactory();
+  ~MockProfileSharedRenderProcessHostFactory() override;
 
   // RPH created with this factory are owned by it.  If the RPH is destroyed
   // for testing purposes, it must be removed from the factory first.
   content::MockRenderProcessHost* ReleaseRPH(
       content::BrowserContext* browser_context);
 
-  virtual content::RenderProcessHost* CreateRenderProcessHost(
+  content::RenderProcessHost* CreateRenderProcessHost(
       content::BrowserContext* browser_context,
       content::SiteInstance* site_instance) const override;
 
diff --git a/chrome/browser/media_galleries/media_galleries_dialog_controller_test_util.h b/chrome/browser/media_galleries/media_galleries_dialog_controller_test_util.h
index a829b4b..2c9f571a 100644
--- a/chrome/browser/media_galleries/media_galleries_dialog_controller_test_util.h
+++ b/chrome/browser/media_galleries/media_galleries_dialog_controller_test_util.h
@@ -13,17 +13,17 @@
   typedef base::Callback<void(int update_count)> DialogDestroyedCallback;
 
   explicit MockMediaGalleriesDialog(const DialogDestroyedCallback& callback);
-  virtual ~MockMediaGalleriesDialog();
+  ~MockMediaGalleriesDialog() override;
 
   // MediaGalleriesDialog implementation.
-  virtual void UpdateGalleries() override;
+  void UpdateGalleries() override;
 
   // Number up times UpdateResults has been called.
   int update_count() const;
 
  private:
   // MediaGalleriesDialog implementation.
-  virtual void AcceptDialogForTesting() override;
+  void AcceptDialogForTesting() override;
 
   int update_count_;
 
diff --git a/chrome/browser/media_galleries/media_galleries_permission_controller.h b/chrome/browser/media_galleries/media_galleries_permission_controller.h
index 46bedbf..f23205e 100644
--- a/chrome/browser/media_galleries/media_galleries_permission_controller.h
+++ b/chrome/browser/media_galleries/media_galleries_permission_controller.h
@@ -55,23 +55,22 @@
                                      const base::Closure& on_finish);
 
   // MediaGalleriesDialogController implementation.
-  virtual base::string16 GetHeader() const override;
-  virtual base::string16 GetSubtext() const override;
-  virtual bool IsAcceptAllowed() const override;
-  virtual bool ShouldShowFolderViewer(const Entry& entry) const override;
-  virtual std::vector<base::string16> GetSectionHeaders() const override;
-  virtual Entries GetSectionEntries(size_t index) const override;
+  base::string16 GetHeader() const override;
+  base::string16 GetSubtext() const override;
+  bool IsAcceptAllowed() const override;
+  bool ShouldShowFolderViewer(const Entry& entry) const override;
+  std::vector<base::string16> GetSectionHeaders() const override;
+  Entries GetSectionEntries(size_t index) const override;
   // Auxiliary button for this dialog is the 'Add Folder' button.
-  virtual base::string16 GetAuxiliaryButtonText() const override;
-  virtual void DidClickAuxiliaryButton() override;
-  virtual void DidToggleEntry(GalleryDialogId gallery_id,
-                              bool selected) override;
-  virtual void DidClickOpenFolderViewer(GalleryDialogId gallery_id) override;
-  virtual void DidForgetEntry(GalleryDialogId gallery_id) override;
-  virtual base::string16 GetAcceptButtonText() const override;
-  virtual void DialogFinished(bool accepted) override;
-  virtual ui::MenuModel* GetContextMenu(GalleryDialogId gallery_id) override;
-  virtual content::WebContents* WebContents() override;
+  base::string16 GetAuxiliaryButtonText() const override;
+  void DidClickAuxiliaryButton() override;
+  void DidToggleEntry(GalleryDialogId gallery_id, bool selected) override;
+  void DidClickOpenFolderViewer(GalleryDialogId gallery_id) override;
+  void DidForgetEntry(GalleryDialogId gallery_id) override;
+  base::string16 GetAcceptButtonText() const override;
+  void DialogFinished(bool accepted) override;
+  ui::MenuModel* GetContextMenu(GalleryDialogId gallery_id) override;
+  content::WebContents* WebContents() override;
 
  protected:
   friend class MediaGalleriesPermissionControllerTest;
@@ -86,7 +85,7 @@
       const CreateDialogCallback& create_dialog_callback,
       const base::Closure& on_finish);
 
-  virtual ~MediaGalleriesPermissionController();
+  ~MediaGalleriesPermissionController() override;
 
  private:
   // This type keeps track of media galleries already known to the prefs system.
@@ -112,31 +111,31 @@
   void OnPreferencesInitialized();
 
   // SelectFileDialog::Listener implementation:
-  virtual void FileSelected(const base::FilePath& path,
-                            int index,
-                            void* params) override;
+  void FileSelected(const base::FilePath& path,
+                    int index,
+                    void* params) override;
 
   // RemovableStorageObserver implementation.
   // Used to keep dialog in sync with removable device status.
-  virtual void OnRemovableStorageAttached(
+  void OnRemovableStorageAttached(
       const storage_monitor::StorageInfo& info) override;
-  virtual void OnRemovableStorageDetached(
+  void OnRemovableStorageDetached(
       const storage_monitor::StorageInfo& info) override;
 
   // MediaGalleriesPreferences::GalleryChangeObserver implementations.
   // Used to keep the dialog in sync when the preferences change.
-  virtual void OnPermissionAdded(MediaGalleriesPreferences* pref,
-                                 const std::string& extension_id,
-                                 MediaGalleryPrefId pref_id) override;
-  virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref,
-                                   const std::string& extension_id,
-                                   MediaGalleryPrefId pref_id) override;
-  virtual void OnGalleryAdded(MediaGalleriesPreferences* pref,
-                              MediaGalleryPrefId pref_id) override;
-  virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref,
-                                MediaGalleryPrefId pref_id) override;
-  virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
-                                    MediaGalleryPrefId pref_id) override;
+  void OnPermissionAdded(MediaGalleriesPreferences* pref,
+                         const std::string& extension_id,
+                         MediaGalleryPrefId pref_id) override;
+  void OnPermissionRemoved(MediaGalleriesPreferences* pref,
+                           const std::string& extension_id,
+                           MediaGalleryPrefId pref_id) override;
+  void OnGalleryAdded(MediaGalleriesPreferences* pref,
+                      MediaGalleryPrefId pref_id) override;
+  void OnGalleryRemoved(MediaGalleriesPreferences* pref,
+                        MediaGalleryPrefId pref_id) override;
+  void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
+                            MediaGalleryPrefId pref_id) override;
 
   // Populates |known_galleries_| from |preferences_|. Subsequent calls merge
   // into |known_galleries_| and do not change permissions for user toggled
diff --git a/chrome/browser/media_galleries/media_galleries_permissions_unittest.cc b/chrome/browser/media_galleries/media_galleries_permissions_unittest.cc
index f64ad16..487daeb 100644
--- a/chrome/browser/media_galleries/media_galleries_permissions_unittest.cc
+++ b/chrome/browser/media_galleries/media_galleries_permissions_unittest.cc
@@ -57,7 +57,7 @@
     testing::Test::TearDown();
   }
 
-  virtual void Initialize() override {
+  void Initialize() override {
     file_thread_.Start();
 
     ASSERT_TRUE(storage_monitor::TestStorageMonitor::CreateAndInstall());
@@ -110,7 +110,7 @@
     Verify();
   }
 
-  virtual void Verify() override {
+  void Verify() override {
     struct TestData {
       std::string* id;
       std::vector<MediaGalleryPermission>* expectation;
diff --git a/chrome/browser/media_galleries/media_galleries_preferences.h b/chrome/browser/media_galleries/media_galleries_preferences.h
index 6ed8da5..5c40399 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences.h
+++ b/chrome/browser/media_galleries/media_galleries_preferences.h
@@ -179,7 +179,7 @@
   };
 
   explicit MediaGalleriesPreferences(Profile* profile);
-  virtual ~MediaGalleriesPreferences();
+  ~MediaGalleriesPreferences() override;
 
   // Ensures that the preferences is initialized. The provided callback, if
   // non-null, will be called when initialization is complete. If initialization
@@ -200,7 +200,7 @@
   void RemoveGalleryChangeObserver(GalleryChangeObserver* observer);
 
   // RemovableStorageObserver implementation.
-  virtual void OnRemovableStorageAttached(
+  void OnRemovableStorageAttached(
       const storage_monitor::StorageInfo& info) override;
 
   // Lookup a media gallery and fill in information about it and return true if
@@ -277,7 +277,7 @@
   void SetLastScanCompletionTime(const base::Time& time);
 
   // KeyedService implementation:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
diff --git a/chrome/browser/media_galleries/media_galleries_preferences_factory.h b/chrome/browser/media_galleries/media_galleries_preferences_factory.h
index e0445225..6abf1fa 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences_factory.h
+++ b/chrome/browser/media_galleries/media_galleries_preferences_factory.h
@@ -27,14 +27,14 @@
   friend struct DefaultSingletonTraits<MediaGalleriesPreferencesFactory>;
 
   MediaGalleriesPreferencesFactory();
-  virtual ~MediaGalleriesPreferencesFactory();
+  ~MediaGalleriesPreferencesFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
 
   DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPreferencesFactory);
diff --git a/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc b/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc
index e9edc4b0..a93bc8ad 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc
+++ b/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc
@@ -55,40 +55,40 @@
   explicit MockGalleryChangeObserver(MediaGalleriesPreferences* pref)
       : pref_(pref),
         notifications_(0) {}
-  virtual ~MockGalleryChangeObserver() {}
+  ~MockGalleryChangeObserver() override {}
 
   int notifications() const { return notifications_;}
 
  private:
   // MediaGalleriesPreferences::GalleryChangeObserver implementation.
-  virtual void OnPermissionAdded(MediaGalleriesPreferences* pref,
-                                 const std::string& extension_id,
-                                 MediaGalleryPrefId pref_id) override {
+  void OnPermissionAdded(MediaGalleriesPreferences* pref,
+                         const std::string& extension_id,
+                         MediaGalleryPrefId pref_id) override {
     EXPECT_EQ(pref_, pref);
     ++notifications_;
   }
 
-  virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref,
-                                   const std::string& extension_id,
-                                   MediaGalleryPrefId pref_id) override {
+  void OnPermissionRemoved(MediaGalleriesPreferences* pref,
+                           const std::string& extension_id,
+                           MediaGalleryPrefId pref_id) override {
     EXPECT_EQ(pref_, pref);
     ++notifications_;
   }
 
-  virtual void OnGalleryAdded(MediaGalleriesPreferences* pref,
-                              MediaGalleryPrefId pref_id) override {
+  void OnGalleryAdded(MediaGalleriesPreferences* pref,
+                      MediaGalleryPrefId pref_id) override {
     EXPECT_EQ(pref_, pref);
     ++notifications_;
   }
 
-  virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref,
-                                MediaGalleryPrefId pref_id) override {
+  void OnGalleryRemoved(MediaGalleriesPreferences* pref,
+                        MediaGalleryPrefId pref_id) override {
     EXPECT_EQ(pref_, pref);
     ++notifications_;
   }
 
-  virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
-                                    MediaGalleryPrefId pref_id) override {
+  void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
+                            MediaGalleryPrefId pref_id) override {
     EXPECT_EQ(pref_, pref);
     ++notifications_;
   }
diff --git a/chrome/browser/media_galleries/media_galleries_scan_result_controller.h b/chrome/browser/media_galleries/media_galleries_scan_result_controller.h
index 41afc21..b918ddd 100644
--- a/chrome/browser/media_galleries/media_galleries_scan_result_controller.h
+++ b/chrome/browser/media_galleries/media_galleries_scan_result_controller.h
@@ -52,21 +52,21 @@
       const base::Closure& on_finish);
 
   // MediaGalleriesDialogController implementation.
-  virtual base::string16 GetHeader() const override;
-  virtual base::string16 GetSubtext() const override;
-  virtual bool IsAcceptAllowed() const override;
-  virtual bool ShouldShowFolderViewer(const Entry& entry) const override;
-  virtual std::vector<base::string16> GetSectionHeaders() const override;
-  virtual Entries GetSectionEntries(size_t index) const override;
-  virtual base::string16 GetAuxiliaryButtonText() const override;
-  virtual void DidClickAuxiliaryButton() override;
-  virtual void DidToggleEntry(MediaGalleryPrefId id, bool selected) override;
-  virtual void DidClickOpenFolderViewer(MediaGalleryPrefId id) override;
-  virtual void DidForgetEntry(MediaGalleryPrefId id) override;
-  virtual base::string16 GetAcceptButtonText() const override;
-  virtual void DialogFinished(bool accepted) override;
-  virtual ui::MenuModel* GetContextMenu(MediaGalleryPrefId id) override;
-  virtual content::WebContents* WebContents() override;
+  base::string16 GetHeader() const override;
+  base::string16 GetSubtext() const override;
+  bool IsAcceptAllowed() const override;
+  bool ShouldShowFolderViewer(const Entry& entry) const override;
+  std::vector<base::string16> GetSectionHeaders() const override;
+  Entries GetSectionEntries(size_t index) const override;
+  base::string16 GetAuxiliaryButtonText() const override;
+  void DidClickAuxiliaryButton() override;
+  void DidToggleEntry(MediaGalleryPrefId id, bool selected) override;
+  void DidClickOpenFolderViewer(MediaGalleryPrefId id) override;
+  void DidForgetEntry(MediaGalleryPrefId id) override;
+  base::string16 GetAcceptButtonText() const override;
+  void DialogFinished(bool accepted) override;
+  ui::MenuModel* GetContextMenu(MediaGalleryPrefId id) override;
+  content::WebContents* WebContents() override;
 
  protected:
   typedef base::Callback<MediaGalleriesDialog* (
@@ -88,7 +88,7 @@
       const CreateDialogCallback& create_dialog_callback,
       const base::Closure& on_finish);
 
-  virtual ~MediaGalleriesScanResultController();
+  ~MediaGalleriesScanResultController() override;
 
  private:
   friend class MediaGalleriesScanResultControllerTest;
@@ -108,25 +108,25 @@
 
   // RemovableStorageObserver implementation.
   // Used to keep dialog in sync with removable device status.
-  virtual void OnRemovableStorageAttached(
+  void OnRemovableStorageAttached(
       const storage_monitor::StorageInfo& info) override;
-  virtual void OnRemovableStorageDetached(
+  void OnRemovableStorageDetached(
       const storage_monitor::StorageInfo& info) override;
 
   // MediaGalleriesPreferences::GalleryChangeObserver implementations.
   // Used to keep the dialog in sync when the preferences change.
-  virtual void OnPermissionAdded(MediaGalleriesPreferences* pref,
-                                 const std::string& extension_id,
-                                 MediaGalleryPrefId pref_id) override;
-  virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref,
-                                   const std::string& extension_id,
-                                   MediaGalleryPrefId pref_id) override;
-  virtual void OnGalleryAdded(MediaGalleriesPreferences* pref,
-                              MediaGalleryPrefId pref_id) override;
-  virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref,
-                                MediaGalleryPrefId pref_id) override;
-  virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
-                                    MediaGalleryPrefId pref_id) override;
+  void OnPermissionAdded(MediaGalleriesPreferences* pref,
+                         const std::string& extension_id,
+                         MediaGalleryPrefId pref_id) override;
+  void OnPermissionRemoved(MediaGalleriesPreferences* pref,
+                           const std::string& extension_id,
+                           MediaGalleryPrefId pref_id) override;
+  void OnGalleryAdded(MediaGalleriesPreferences* pref,
+                      MediaGalleryPrefId pref_id) override;
+  void OnGalleryRemoved(MediaGalleriesPreferences* pref,
+                        MediaGalleryPrefId pref_id) override;
+  void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
+                            MediaGalleryPrefId pref_id) override;
 
   // The web contents from which the request originated.
   content::WebContents* web_contents_;
diff --git a/chrome/browser/media_galleries/media_gallery_context_menu.h b/chrome/browser/media_galleries/media_gallery_context_menu.h
index 0c87f90..05fcf99 100644
--- a/chrome/browser/media_galleries/media_gallery_context_menu.h
+++ b/chrome/browser/media_galleries/media_gallery_context_menu.h
@@ -17,19 +17,19 @@
       ForgetGalleryCallback;
 
   explicit MediaGalleryContextMenu(const ForgetGalleryCallback& callback);
-  virtual ~MediaGalleryContextMenu();
+  ~MediaGalleryContextMenu() override;
 
   void set_pref_id(MediaGalleryPrefId pref_id) {
     pref_id_ = pref_id;
   }
 
   // ui::SimpleMenuModel::Delegate overrides:
-  virtual bool IsCommandIdChecked(int command_id) const override;
-  virtual bool IsCommandIdEnabled(int command_id) const override;
-  virtual bool IsCommandIdVisible(int command_id) const override;
-  virtual bool GetAcceleratorForCommandId(
-      int command_id, ui::Accelerator* accelerator) override;
-  virtual void ExecuteCommand(int command_id, int event_flags) override;
+  bool IsCommandIdChecked(int command_id) const override;
+  bool IsCommandIdEnabled(int command_id) const override;
+  bool IsCommandIdVisible(int command_id) const override;
+  bool GetAcceleratorForCommandId(int command_id,
+                                  ui::Accelerator* accelerator) override;
+  void ExecuteCommand(int command_id, int event_flags) override;
 
  private:
   MediaGalleryPrefId pref_id_;
diff --git a/chrome/browser/media_galleries/media_scan_manager.h b/chrome/browser/media_galleries/media_scan_manager.h
index 80509ce..bbfc10c 100644
--- a/chrome/browser/media_galleries/media_scan_manager.h
+++ b/chrome/browser/media_galleries/media_scan_manager.h
@@ -34,7 +34,7 @@
 class MediaScanManager : public extensions::ExtensionRegistryObserver {
  public:
   MediaScanManager();
-  virtual ~MediaScanManager();
+  ~MediaScanManager() override;
 
   // There can only be ever one observer registered per profile. Does not take
   // ownership of |observer|. An observer must be registered before scanning.
@@ -76,7 +76,7 @@
   typedef std::map<Profile*, ScanObservers> ScanObserverMap;
 
   // extensions::ExtensionRegistryObserver implementation.
-  virtual void OnExtensionUnloaded(
+  void OnExtensionUnloaded(
       content::BrowserContext* browser_context,
       const extensions::Extension* extension,
       extensions::UnloadedExtensionInfo::Reason reason) override;
diff --git a/chrome/browser/media_galleries/media_scan_manager_unittest.cc b/chrome/browser/media_galleries/media_scan_manager_unittest.cc
index 1f445ccc..0fa33a5 100644
--- a/chrome/browser/media_galleries/media_scan_manager_unittest.cc
+++ b/chrome/browser/media_galleries/media_scan_manager_unittest.cc
@@ -56,13 +56,9 @@
         destruction_callback_(destruction_callback),
         callback_(callback) {
   }
-  virtual ~MockMediaFolderFinder() {
-    destruction_callback_.Run();
-  }
+  ~MockMediaFolderFinder() override { destruction_callback_.Run(); }
 
-  virtual void StartScan() override {
-    started_callback_.Run(callback_);
-  }
+  void StartScan() override { started_callback_.Run(callback_); }
 
  private:
   FindFoldersStartedCallback started_callback_;
@@ -83,7 +79,7 @@
   explicit TestMediaScanManager(const MediaFolderFinderFactory& factory) {
     SetMediaFolderFinderFactory(factory);
   }
-  virtual ~TestMediaScanManager() {}
+  ~TestMediaScanManager() override {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestMediaScanManager);
@@ -231,10 +227,9 @@
   }
 
   // MediaScanManagerObserver implementation.
-  virtual void OnScanFinished(
-      const std::string& extension_id,
-      int gallery_count,
-      const MediaGalleryScanResult& file_counts) override {
+  void OnScanFinished(const std::string& extension_id,
+                      int gallery_count,
+                      const MediaGalleryScanResult& file_counts) override {
     EXPECT_EQ(extension_->id(), extension_id);
     EXPECT_EQ(expected_gallery_count_, gallery_count);
     EXPECT_EQ(expected_file_counts_.audio_count, file_counts.audio_count);
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index 64c01a7..c7e2d411 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -72,6 +72,7 @@
   UMA_LINUX_WINDOW_MANAGER_RATPOISON,
   UMA_LINUX_WINDOW_MANAGER_STUMPWM,
   UMA_LINUX_WINDOW_MANAGER_WMII,
+  UMA_LINUX_WINDOW_MANAGER_FLUXBOX,
   // NOTE: Append new window managers to the list above this line (i.e. don't
   // renumber) and update LinuxWindowManagerName in
   // tools/metrics/histograms/histograms.xml accordingly.
@@ -156,6 +157,8 @@
       return UMA_LINUX_WINDOW_MANAGER_COMPIZ;
     case ui::WM_ENLIGHTENMENT:
       return UMA_LINUX_WINDOW_MANAGER_ENLIGHTENMENT;
+    case ui::WM_FLUXBOX:
+      return UMA_LINUX_WINDOW_MANAGER_FLUXBOX;
     case ui::WM_I3:
       return UMA_LINUX_WINDOW_MANAGER_I3;
     case ui::WM_ICE_WM:
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc
index cfda275..2cd3fb9 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -294,7 +294,7 @@
           new ExtensionsMetricsProvider(metrics_state_manager_)));
 #endif
   metrics_service_->RegisterMetricsProvider(
-      scoped_ptr<metrics::MetricsProvider>(new NetworkMetricsProvider(
+      scoped_ptr<metrics::MetricsProvider>(new metrics::NetworkMetricsProvider(
           content::BrowserThread::GetBlockingPool())));
   metrics_service_->RegisterMetricsProvider(
       scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider));
diff --git a/chrome/browser/metrics/metric_event_duration_details.h b/chrome/browser/metrics/metric_event_duration_details.h
deleted file mode 100644
index 3e2feec7a..0000000
--- a/chrome/browser/metrics/metric_event_duration_details.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2009 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_METRICS_METRIC_EVENT_DURATION_DETAILS_H_
-#define CHROME_BROWSER_METRICS_METRIC_EVENT_DURATION_DETAILS_H_
-
-#include <string>
-
-// Used when sending a notification about an event that occurred that we want
-// to time.
-struct MetricEventDurationDetails {
-  MetricEventDurationDetails(const std::string& e, int d)
-      : event_name(e), duration_ms(d) {}
-
-  std::string event_name;
-  int duration_ms;
-};
-
-#endif  // CHROME_BROWSER_METRICS_METRIC_EVENT_DURATION_DETAILS_H_
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc
index e3e36f1f..9f6b7baf 100644
--- a/chrome/browser/metrics/thread_watcher.cc
+++ b/chrome/browser/metrics/thread_watcher.cc
@@ -920,13 +920,6 @@
   // alarming.
   explicit StartupWatchDogThread(const base::TimeDelta& duration)
       : base::Watchdog(duration, "Startup watchdog thread", true) {
-#if defined(OS_ANDROID)
-    // TODO(rtenneti): Delete this code, after getting data.
-    start_time_clock_= base::Time::Now();
-    start_time_monotonic_ = base::TimeTicks::Now();
-    start_time_thread_now_ = base::TimeTicks::IsThreadNowSupported()
-        ? base::TimeTicks::ThreadNow() : base::TimeTicks::Now();
-#endif  // OS_ANDROID
   }
 
   // Alarm is called if the time expires after an Arm() without someone calling
@@ -939,29 +932,12 @@
 #elif !defined(OS_ANDROID)
     WatchDogThread::PostTask(FROM_HERE, base::Bind(&StartupHang));
     return;
-#else  // Android release: gather stats to figure out when to crash.
-    // TODO(rtenneti): Delete this code, after getting data.
-    UMA_HISTOGRAM_TIMES("StartupTimeBomb.Alarm.TimeDuration",
-                        base::Time::Now() - start_time_clock_);
-    UMA_HISTOGRAM_TIMES("StartupTimeBomb.Alarm.TimeTicksDuration",
-                        base::TimeTicks::Now() - start_time_monotonic_);
-    if (base::TimeTicks::IsThreadNowSupported()) {
-      UMA_HISTOGRAM_TIMES(
-          "StartupTimeBomb.Alarm.ThreadNowDuration",
-          base::TimeTicks::ThreadNow() - start_time_thread_now_);
-    }
-    return;
+#else
+    // TODO(rtenneti): Enable crashing for Android.
 #endif  // OS_ANDROID
   }
 
  private:
-#if defined(OS_ANDROID)
-  // TODO(rtenneti): Delete this code, after getting data.
-  base::Time start_time_clock_;
-  base::TimeTicks start_time_monotonic_;
-  base::TimeTicks start_time_thread_now_;
-#endif  // OS_ANDROID
-
   DISALLOW_COPY_AND_ASSIGN(StartupWatchDogThread);
 };
 
diff --git a/chrome/browser/metrics/variations/variations_registry_syncer_win.cc b/chrome/browser/metrics/variations/variations_registry_syncer_win.cc
index a6516fc4..dcfd5e2 100644
--- a/chrome/browser/metrics/variations/variations_registry_syncer_win.cc
+++ b/chrome/browser/metrics/variations/variations_registry_syncer_win.cc
@@ -8,37 +8,24 @@
 #include "base/metrics/field_trial.h"
 #include "base/path_service.h"
 #include "base/strings/string16.h"
+#include "base/threading/thread_restrictions.h"
 #include "chrome/common/variations/experiment_labels.h"
 #include "chrome/installer/util/google_update_settings.h"
 #include "chrome/installer/util/install_util.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace chrome_variations {
 
 namespace {
 
 // Delay before performing a registry sync, in seconds.
 const int kRegistrySyncDelaySeconds = 5;
 
-}  // namespace
+// Performs the actual synchronization process with the registry, which should
+// be done on a blocking pool thread.
+void SyncWithRegistryOnBlockingPool() {
+  base::ThreadRestrictions::AssertIOAllowed();
 
-namespace chrome_variations {
-
-VariationsRegistrySyncer::VariationsRegistrySyncer() {
-}
-
-VariationsRegistrySyncer::~VariationsRegistrySyncer() {
-}
-
-void VariationsRegistrySyncer::RequestRegistrySync() {
-  if (timer_.IsRunning()) {
-    timer_.Reset();
-    return;
-  }
-
-  timer_.Start(FROM_HERE,
-               base::TimeDelta::FromSeconds(kRegistrySyncDelaySeconds),
-               this, &VariationsRegistrySyncer::SyncWithRegistry);
-}
-
-void VariationsRegistrySyncer::SyncWithRegistry() {
   // Note that all registry operations are done here on the UI thread as there
   // are no threading restrictions on them.
   base::FilePath chrome_exe;
@@ -81,4 +68,31 @@
   }
 }
 
+}  // namespace
+
+VariationsRegistrySyncer::VariationsRegistrySyncer() {
+}
+
+VariationsRegistrySyncer::~VariationsRegistrySyncer() {
+}
+
+void VariationsRegistrySyncer::RequestRegistrySync() {
+  if (timer_.IsRunning()) {
+    timer_.Reset();
+    return;
+  }
+
+  timer_.Start(FROM_HERE,
+               base::TimeDelta::FromSeconds(kRegistrySyncDelaySeconds),
+               this,
+               &VariationsRegistrySyncer::StartRegistrySync);
+}
+
+void VariationsRegistrySyncer::StartRegistrySync() {
+  // Do the work on a blocking pool thread, as chrome://profiler has shown
+  // that it can cause jank if done on the UI thrread.
+  content::BrowserThread::GetBlockingPool()->PostTask(
+      FROM_HERE, base::Bind(&SyncWithRegistryOnBlockingPool));
+}
+
 }  // namespace chrome_variations
diff --git a/chrome/browser/metrics/variations/variations_registry_syncer_win.h b/chrome/browser/metrics/variations/variations_registry_syncer_win.h
index 18ad9d5a..32487c49 100644
--- a/chrome/browser/metrics/variations/variations_registry_syncer_win.h
+++ b/chrome/browser/metrics/variations/variations_registry_syncer_win.h
@@ -22,8 +22,9 @@
   void RequestRegistrySync();
 
  private:
-  // Perform the actual synchronization process with the registry.
-  void SyncWithRegistry();
+  // Starts the actual synchronization process with the registry. Posts a task
+  // to do it on the blocking pool to avoid jank.
+  void StartRegistrySync();
 
   // A timer used to delay the writes to the registry. This is done to optimize
   // the case where lazy-loaded features start their field trials some time
diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
index 1217e2a..e1c5498 100644
--- a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
+++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
@@ -8,7 +8,9 @@
 #include "base/strings/string_split.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
+#if defined(ENABLE_EXTENSIONS)
 #include "chrome/browser/extensions/extension_service.h"
+#endif
 #include "chrome/browser/nacl_host/nacl_infobar_delegate.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -19,12 +21,14 @@
 #include "chrome/common/logging_chrome.h"
 #include "chrome/common/pepper_permission_util.h"
 #include "content/public/browser/browser_thread.h"
+#if defined(ENABLE_EXTENSIONS)
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/info_map.h"
 #include "extensions/browser/process_manager.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/url_pattern.h"
+#endif
 #include "ppapi/c/private/ppb_nacl_private.h"
 #include "url/gurl.h"
 
diff --git a/chrome/browser/net/about_protocol_handler.h b/chrome/browser/net/about_protocol_handler.h
index 7a3b449d..7ac4988 100644
--- a/chrome/browser/net/about_protocol_handler.h
+++ b/chrome/browser/net/about_protocol_handler.h
@@ -15,10 +15,10 @@
 class AboutProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
  public:
   AboutProtocolHandler();
-  virtual net::URLRequestJob* MaybeCreateJob(
+  net::URLRequestJob* MaybeCreateJob(
       net::URLRequest* request,
       net::NetworkDelegate* network_delegate) const override;
-  virtual bool IsSafeRedirectTarget(const GURL& location) const override;
+  bool IsSafeRedirectTarget(const GURL& location) const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AboutProtocolHandler);
diff --git a/chrome/browser/net/chrome_extensions_network_delegate.cc b/chrome/browser/net/chrome_extensions_network_delegate.cc
index 118631d0..2932d7a 100644
--- a/chrome/browser/net/chrome_extensions_network_delegate.cc
+++ b/chrome/browser/net/chrome_extensions_network_delegate.cc
@@ -83,35 +83,34 @@
  public:
   explicit ChromeExtensionsNetworkDelegateImpl(
       extensions::EventRouterForwarder* event_router);
-  virtual ~ChromeExtensionsNetworkDelegateImpl();
+  ~ChromeExtensionsNetworkDelegateImpl() override;
 
  private:
   // ChromeExtensionsNetworkDelegate implementation.
-  virtual void ForwardProxyErrors(net::URLRequest* request) override;
-  virtual void ForwardStartRequestStatus(net::URLRequest* request) override;
-  virtual void ForwardDoneRequestStatus(net::URLRequest* request) override;
-  virtual int OnBeforeURLRequest(net::URLRequest* request,
-                                 const net::CompletionCallback& callback,
-                                 GURL* new_url) override;
-  virtual int OnBeforeSendHeaders(net::URLRequest* request,
-                                  const net::CompletionCallback& callback,
-                                  net::HttpRequestHeaders* headers) override;
-  virtual void OnSendHeaders(net::URLRequest* request,
-                             const net::HttpRequestHeaders& headers) override;
-  virtual int OnHeadersReceived(
+  void ForwardProxyErrors(net::URLRequest* request) override;
+  void ForwardStartRequestStatus(net::URLRequest* request) override;
+  void ForwardDoneRequestStatus(net::URLRequest* request) override;
+  int OnBeforeURLRequest(net::URLRequest* request,
+                         const net::CompletionCallback& callback,
+                         GURL* new_url) override;
+  int OnBeforeSendHeaders(net::URLRequest* request,
+                          const net::CompletionCallback& callback,
+                          net::HttpRequestHeaders* headers) override;
+  void OnSendHeaders(net::URLRequest* request,
+                     const net::HttpRequestHeaders& headers) override;
+  int OnHeadersReceived(
       net::URLRequest* request,
       const net::CompletionCallback& callback,
       const net::HttpResponseHeaders* original_response_headers,
       scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
       GURL* allowed_unsafe_redirect_url) override;
-  virtual void OnBeforeRedirect(net::URLRequest* request,
-                                const GURL& new_location) override;
-  virtual void OnResponseStarted(net::URLRequest* request) override;
-  virtual void OnCompleted(net::URLRequest* request, bool started) override;
-  virtual void OnURLRequestDestroyed(net::URLRequest* request) override;
-  virtual void OnPACScriptError(int line_number,
-                                const base::string16& error) override;
-  virtual net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
+  void OnBeforeRedirect(net::URLRequest* request,
+                        const GURL& new_location) override;
+  void OnResponseStarted(net::URLRequest* request) override;
+  void OnCompleted(net::URLRequest* request, bool started) override;
+  void OnURLRequestDestroyed(net::URLRequest* request) override;
+  void OnPACScriptError(int line_number, const base::string16& error) override;
+  net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
       net::URLRequest* request,
       const net::AuthChallengeInfo& auth_info,
       const AuthCallback& callback,
diff --git a/chrome/browser/net/chrome_extensions_network_delegate.h b/chrome/browser/net/chrome_extensions_network_delegate.h
index 7650cd96..d7927a76 100644
--- a/chrome/browser/net/chrome_extensions_network_delegate.h
+++ b/chrome/browser/net/chrome_extensions_network_delegate.h
@@ -22,7 +22,7 @@
   static ChromeExtensionsNetworkDelegate* Create(
       extensions::EventRouterForwarder* event_router);
 
-  virtual ~ChromeExtensionsNetworkDelegate();
+  ~ChromeExtensionsNetworkDelegate() override;
 
   // Not inlined because we assign a scoped_refptr, which requires us to include
   // the header file.
@@ -44,28 +44,27 @@
   virtual void ForwardDoneRequestStatus(net::URLRequest* request);
 
   // NetworkDelegate implementation.
-  virtual int OnBeforeURLRequest(net::URLRequest* request,
-                                 const net::CompletionCallback& callback,
-                                 GURL* new_url) override;
-  virtual int OnBeforeSendHeaders(net::URLRequest* request,
-                                  const net::CompletionCallback& callback,
-                                  net::HttpRequestHeaders* headers) override;
-  virtual void OnSendHeaders(net::URLRequest* request,
-                             const net::HttpRequestHeaders& headers) override;
-  virtual int OnHeadersReceived(
+  int OnBeforeURLRequest(net::URLRequest* request,
+                         const net::CompletionCallback& callback,
+                         GURL* new_url) override;
+  int OnBeforeSendHeaders(net::URLRequest* request,
+                          const net::CompletionCallback& callback,
+                          net::HttpRequestHeaders* headers) override;
+  void OnSendHeaders(net::URLRequest* request,
+                     const net::HttpRequestHeaders& headers) override;
+  int OnHeadersReceived(
       net::URLRequest* request,
       const net::CompletionCallback& callback,
       const net::HttpResponseHeaders* original_response_headers,
       scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
       GURL* allowed_unsafe_redirect_url) override;
-  virtual void OnBeforeRedirect(net::URLRequest* request,
-                                const GURL& new_location) override;
-  virtual void OnResponseStarted(net::URLRequest* request) override;
-  virtual void OnCompleted(net::URLRequest* request, bool started) override;
-  virtual void OnURLRequestDestroyed(net::URLRequest* request) override;
-  virtual void OnPACScriptError(int line_number,
-                                const base::string16& error) override;
-  virtual net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
+  void OnBeforeRedirect(net::URLRequest* request,
+                        const GURL& new_location) override;
+  void OnResponseStarted(net::URLRequest* request) override;
+  void OnCompleted(net::URLRequest* request, bool started) override;
+  void OnURLRequestDestroyed(net::URLRequest* request) override;
+  void OnPACScriptError(int line_number, const base::string16& error) override;
+  net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
       net::URLRequest* request,
       const net::AuthChallengeInfo& auth_info,
       const AuthCallback& callback,
diff --git a/chrome/browser/net/chrome_fraudulent_certificate_reporter.h b/chrome/browser/net/chrome_fraudulent_certificate_reporter.h
index 24ee4057..c987476 100644
--- a/chrome/browser/net/chrome_fraudulent_certificate_reporter.h
+++ b/chrome/browser/net/chrome_fraudulent_certificate_reporter.h
@@ -24,7 +24,7 @@
   explicit ChromeFraudulentCertificateReporter(
       net::URLRequestContext* request_context);
 
-  virtual ~ChromeFraudulentCertificateReporter();
+  ~ChromeFraudulentCertificateReporter() override;
 
   // Allows users of this class to override this and set their own URLRequest
   // type. Used by SendReport.
@@ -32,13 +32,12 @@
       net::URLRequestContext* context);
 
   // net::FraudulentCertificateReporter
-  virtual void SendReport(const std::string& hostname,
-                          const net::SSLInfo& ssl_info) override;
+  void SendReport(const std::string& hostname,
+                  const net::SSLInfo& ssl_info) override;
 
   // net::URLRequest::Delegate
-  virtual void OnResponseStarted(net::URLRequest* request) override;
-  virtual void OnReadCompleted(net::URLRequest* request,
-                               int bytes_read) override;
+  void OnResponseStarted(net::URLRequest* request) override;
+  void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
 
  protected:
   net::URLRequestContext* const request_context_;
diff --git a/chrome/browser/net/chrome_fraudulent_certificate_reporter_unittest.cc b/chrome/browser/net/chrome_fraudulent_certificate_reporter_unittest.cc
index 11b613f..6aff918 100644
--- a/chrome/browser/net/chrome_fraudulent_certificate_reporter_unittest.cc
+++ b/chrome/browser/net/chrome_fraudulent_certificate_reporter_unittest.cc
@@ -82,14 +82,14 @@
 
   // Passes if invoked with a good SSLInfo and for a hostname that is a Google
   // pinned property.
-  virtual void SendReport(const std::string& hostname,
-                          const SSLInfo& ssl_info) override {
+  void SendReport(const std::string& hostname,
+                  const SSLInfo& ssl_info) override {
     EXPECT_TRUE(IsGoodSSLInfo(ssl_info));
     EXPECT_TRUE(net::TransportSecurityState::IsGooglePinnedProperty(hostname));
     passed_ = true;
   }
 
-  virtual ~SendingTestReporter() {
+  ~SendingTestReporter() override {
     // If the object is destroyed without having its SendReport method invoked,
     // we failed.
     EXPECT_TRUE(passed_);
@@ -105,8 +105,8 @@
 
   // Passes if invoked with a bad SSLInfo and for a hostname that is not a
   // Google pinned property.
-  virtual void SendReport(const std::string& hostname,
-                          const SSLInfo& ssl_info) override {
+  void SendReport(const std::string& hostname,
+                  const SSLInfo& ssl_info) override {
     EXPECT_FALSE(IsGoodSSLInfo(ssl_info));
     EXPECT_FALSE(net::TransportSecurityState::IsGooglePinnedProperty(hostname));
   }
@@ -119,7 +119,7 @@
   explicit MockReporter(net::URLRequestContext* request_context)
     : ChromeFraudulentCertificateReporter(request_context) {}
 
-  virtual scoped_ptr<net::URLRequest> CreateURLRequest(
+  scoped_ptr<net::URLRequest> CreateURLRequest(
       net::URLRequestContext* context) override {
     return context->CreateRequest(GURL(std::string()),
                                   net::DEFAULT_PRIORITY,
@@ -127,9 +127,8 @@
                                   NULL);
   }
 
-  virtual void SendReport(
-      const std::string& hostname,
-      const net::SSLInfo& ssl_info) override {
+  void SendReport(const std::string& hostname,
+                  const net::SSLInfo& ssl_info) override {
     DCHECK(!hostname.empty());
     DCHECK(ssl_info.is_valid());
     ChromeFraudulentCertificateReporter::SendReport(hostname, ssl_info);
diff --git a/chrome/browser/net/chrome_http_user_agent_settings.h b/chrome/browser/net/chrome_http_user_agent_settings.h
index feb0900..8612b3c 100644
--- a/chrome/browser/net/chrome_http_user_agent_settings.h
+++ b/chrome/browser/net/chrome_http_user_agent_settings.h
@@ -21,13 +21,13 @@
   // Must be called on the UI thread.
   explicit ChromeHttpUserAgentSettings(PrefService* prefs);
   // Must be called on the IO thread.
-  virtual ~ChromeHttpUserAgentSettings();
+  ~ChromeHttpUserAgentSettings() override;
 
   void CleanupOnUIThread();
 
   // net::HttpUserAgentSettings implementation
-  virtual std::string GetAcceptLanguage() const override;
-  virtual std::string GetUserAgent() const override;
+  std::string GetAcceptLanguage() const override;
+  std::string GetUserAgent() const override;
 
  private:
   StringPrefMember pref_accept_language_;
diff --git a/chrome/browser/net/chrome_net_log.h b/chrome/browser/net/chrome_net_log.h
index c0b2ee6..f55bbdb6 100644
--- a/chrome/browser/net/chrome_net_log.h
+++ b/chrome/browser/net/chrome_net_log.h
@@ -23,7 +23,7 @@
 class ChromeNetLog : public net::NetLog {
  public:
   ChromeNetLog();
-  virtual ~ChromeNetLog();
+  ~ChromeNetLog() override;
 
   NetLogTempFile* net_log_temp_file() {
     return net_log_temp_file_.get();
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index d295cc06..515568b3 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/base_paths.h"
+#include "base/debug/alias.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/debug/trace_event.h"
 #include "base/logging.h"
@@ -53,7 +54,6 @@
 #include "net/proxy/proxy_info.h"
 #include "net/proxy/proxy_retry_info.h"
 #include "net/proxy/proxy_server.h"
-#include "net/socket_stream/socket_stream.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
 
@@ -232,6 +232,13 @@
                                const GURL& referrer_url) {
   base::RecordAction(
       base::UserMetricsAction("Net.URLRequest_StartJob_InvalidReferrer"));
+  // http://crbug.com/422871
+  char url_buf[128];
+  char referrer_buf[128];
+  base::strlcpy(url_buf, target_url.spec().c_str(), arraysize(url_buf));
+  base::strlcpy(referrer_buf, referrer_url.spec().c_str(), arraysize(url_buf));
+  base::debug::Alias(url_buf);
+  base::debug::Alias(referrer_buf);
   base::debug::DumpWithoutCrashing();
   NOTREACHED();
 }
@@ -803,23 +810,6 @@
   return privacy_mode;
 }
 
-int ChromeNetworkDelegate::OnBeforeSocketStreamConnect(
-    net::SocketStream* socket,
-    const net::CompletionCallback& callback) {
-#if defined(ENABLE_CONFIGURATION_POLICY)
-  if (url_blacklist_manager_ &&
-      url_blacklist_manager_->IsURLBlocked(socket->url())) {
-    // URL access blocked by policy.
-    socket->net_log()->AddEvent(
-        net::NetLog::TYPE_CHROME_POLICY_ABORTED_REQUEST,
-        net::NetLog::StringCallback("url",
-                                    &socket->url().possibly_invalid_spec()));
-    return net::ERR_BLOCKED_BY_ADMINISTRATOR;
-  }
-#endif
-  return net::OK;
-}
-
 bool ChromeNetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
     const net::URLRequest& request,
     const GURL& target_url,
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h
index aea058a..e017996b 100644
--- a/chrome/browser/net/chrome_network_delegate.h
+++ b/chrome/browser/net/chrome_network_delegate.h
@@ -91,7 +91,7 @@
   // responsible for cleaning them up at shutdown.
   ChromeNetworkDelegate(extensions::EventRouterForwarder* event_router,
                         BooleanPrefMember* enable_referrers);
-  virtual ~ChromeNetworkDelegate();
+  ~ChromeNetworkDelegate() override;
 
   // Pass through to ChromeExtensionsNetworkDelegate::set_extension_info_map().
   void set_extension_info_map(extensions::InfoMap* extension_info_map);
@@ -216,61 +216,53 @@
   friend class ChromeNetworkDelegateTest;
 
   // NetworkDelegate implementation.
-  virtual int OnBeforeURLRequest(net::URLRequest* request,
-                                 const net::CompletionCallback& callback,
-                                 GURL* new_url) override;
-  virtual void OnResolveProxy(
-      const GURL& url,
-      int load_flags,
-      const net::ProxyService& proxy_service,
-      net::ProxyInfo* result) override;
-  virtual void OnProxyFallback(const net::ProxyServer& bad_proxy,
-                               int net_error) override;
-  virtual int OnBeforeSendHeaders(net::URLRequest* request,
-                                  const net::CompletionCallback& callback,
-                                  net::HttpRequestHeaders* headers) override;
-  virtual void OnBeforeSendProxyHeaders(
-      net::URLRequest* request,
-      const net::ProxyInfo& proxy_info,
-      net::HttpRequestHeaders* headers) override;
-  virtual void OnSendHeaders(net::URLRequest* request,
-                             const net::HttpRequestHeaders& headers) override;
-  virtual int OnHeadersReceived(
+  int OnBeforeURLRequest(net::URLRequest* request,
+                         const net::CompletionCallback& callback,
+                         GURL* new_url) override;
+  void OnResolveProxy(const GURL& url,
+                      int load_flags,
+                      const net::ProxyService& proxy_service,
+                      net::ProxyInfo* result) override;
+  void OnProxyFallback(const net::ProxyServer& bad_proxy,
+                       int net_error) override;
+  int OnBeforeSendHeaders(net::URLRequest* request,
+                          const net::CompletionCallback& callback,
+                          net::HttpRequestHeaders* headers) override;
+  void OnBeforeSendProxyHeaders(net::URLRequest* request,
+                                const net::ProxyInfo& proxy_info,
+                                net::HttpRequestHeaders* headers) override;
+  void OnSendHeaders(net::URLRequest* request,
+                     const net::HttpRequestHeaders& headers) override;
+  int OnHeadersReceived(
       net::URLRequest* request,
       const net::CompletionCallback& callback,
       const net::HttpResponseHeaders* original_response_headers,
       scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
       GURL* allowed_unsafe_redirect_url) override;
-  virtual void OnBeforeRedirect(net::URLRequest* request,
-                                const GURL& new_location) override;
-  virtual void OnResponseStarted(net::URLRequest* request) override;
-  virtual void OnRawBytesRead(const net::URLRequest& request,
-                              int bytes_read) override;
-  virtual void OnCompleted(net::URLRequest* request, bool started) override;
-  virtual void OnURLRequestDestroyed(net::URLRequest* request) override;
-  virtual void OnPACScriptError(int line_number,
-                                const base::string16& error) override;
-  virtual net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
+  void OnBeforeRedirect(net::URLRequest* request,
+                        const GURL& new_location) override;
+  void OnResponseStarted(net::URLRequest* request) override;
+  void OnRawBytesRead(const net::URLRequest& request, int bytes_read) override;
+  void OnCompleted(net::URLRequest* request, bool started) override;
+  void OnURLRequestDestroyed(net::URLRequest* request) override;
+  void OnPACScriptError(int line_number, const base::string16& error) override;
+  net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
       net::URLRequest* request,
       const net::AuthChallengeInfo& auth_info,
       const AuthCallback& callback,
       net::AuthCredentials* credentials) override;
-  virtual bool OnCanGetCookies(const net::URLRequest& request,
-                               const net::CookieList& cookie_list) override;
-  virtual bool OnCanSetCookie(const net::URLRequest& request,
-                              const std::string& cookie_line,
-                              net::CookieOptions* options) override;
-  virtual bool OnCanAccessFile(const net::URLRequest& request,
-                               const base::FilePath& path) const override;
-  virtual bool OnCanThrottleRequest(
-      const net::URLRequest& request) const override;
-  virtual bool OnCanEnablePrivacyMode(
+  bool OnCanGetCookies(const net::URLRequest& request,
+                       const net::CookieList& cookie_list) override;
+  bool OnCanSetCookie(const net::URLRequest& request,
+                      const std::string& cookie_line,
+                      net::CookieOptions* options) override;
+  bool OnCanAccessFile(const net::URLRequest& request,
+                       const base::FilePath& path) const override;
+  bool OnCanThrottleRequest(const net::URLRequest& request) const override;
+  bool OnCanEnablePrivacyMode(
       const GURL& url,
       const GURL& first_party_for_cookies) const override;
-  virtual int OnBeforeSocketStreamConnect(
-      net::SocketStream* stream,
-      const net::CompletionCallback& callback) override;
-  virtual bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
+  bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
       const net::URLRequest& request,
       const GURL& target_url,
       const GURL& referrer_url) const override;
diff --git a/chrome/browser/net/chrome_url_request_context_getter.cc b/chrome/browser/net/chrome_url_request_context_getter.cc
index b8f7083..ab3ed5d1 100644
--- a/chrome/browser/net/chrome_url_request_context_getter.cc
+++ b/chrome/browser/net/chrome_url_request_context_getter.cc
@@ -48,7 +48,7 @@
     std::swap(protocol_handlers_, *protocol_handlers);
   }
 
-  virtual net::URLRequestContext* Create() override {
+  net::URLRequestContext* Create() override {
     profile_io_data_->Init(&protocol_handlers_, request_interceptors_.Pass());
     return profile_io_data_->GetMainRequestContext();
   }
@@ -65,7 +65,7 @@
   explicit FactoryForExtensions(const ProfileIOData* profile_io_data)
       : profile_io_data_(profile_io_data) {}
 
-  virtual net::URLRequestContext* Create() override {
+  net::URLRequestContext* Create() override {
     return profile_io_data_->GetExtensionsRequestContext();
   }
 
@@ -92,7 +92,7 @@
     std::swap(protocol_handlers_, *protocol_handlers);
   }
 
-  virtual net::URLRequestContext* Create() override {
+  net::URLRequestContext* Create() override {
     // We will copy most of the state from the main request context.
     //
     // Note that this factory is one-shot.  After Create() is called once, the
@@ -129,7 +129,7 @@
       partition_descriptor_(partition_descriptor),
       app_context_getter_(app_context) {}
 
-  virtual net::URLRequestContext* Create() override {
+  net::URLRequestContext* Create() override {
     // We will copy most of the state from the corresopnding app's
     // request context. We expect to have the same lifetime as
     // the associated |app_context_getter_| so we can just reuse
@@ -153,7 +153,7 @@
       : profile_io_data_(profile_io_data) {
   }
 
-  virtual net::URLRequestContext* Create() override {
+  net::URLRequestContext* Create() override {
     return profile_io_data_->GetMediaRequestContext();
   }
 
diff --git a/chrome/browser/net/chrome_url_request_context_getter.h b/chrome/browser/net/chrome_url_request_context_getter.h
index 7b56c34..d9cff50 100644
--- a/chrome/browser/net/chrome_url_request_context_getter.h
+++ b/chrome/browser/net/chrome_url_request_context_getter.h
@@ -37,9 +37,9 @@
   // GetIOMessageLoopProxy however can be called from any thread.
   //
   // net::URLRequestContextGetter implementation.
-  virtual net::URLRequestContext* GetURLRequestContext() override;
-  virtual scoped_refptr<base::SingleThreadTaskRunner>
-      GetNetworkTaskRunner() const override;
+  net::URLRequestContext* GetURLRequestContext() override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+      const override;
 
   // Create an instance for use with an 'original' (non-OTR) profile. This is
   // expected to get called on the UI thread.
@@ -84,7 +84,7 @@
   void Invalidate();
 
  private:
-  virtual ~ChromeURLRequestContextGetter();
+  ~ChromeURLRequestContextGetter() override;
 
   // Deferred logic for creating a URLRequestContext.
   // Access only from the IO thread.
diff --git a/chrome/browser/net/connection_tester.cc b/chrome/browser/net/connection_tester.cc
index 703eefa..ae905e0 100644
--- a/chrome/browser/net/connection_tester.cc
+++ b/chrome/browser/net/connection_tester.cc
@@ -59,9 +59,7 @@
         storage_(this),
         weak_factory_(this) {}
 
-  virtual ~ExperimentURLRequestContext() {
-    AssertNoURLRequests();
-  }
+  ~ExperimentURLRequestContext() override { AssertNoURLRequests(); }
 
   // Creates a proxy config service for |experiment|. On success returns net::OK
   // and fills |config_service| with a new pointer. Otherwise returns a network
@@ -318,9 +316,8 @@
   void Run(const Experiment& experiment);
 
   // Overridden from net::URLRequest::Delegate:
-  virtual void OnResponseStarted(net::URLRequest* request) override;
-  virtual void OnReadCompleted(net::URLRequest* request,
-                               int bytes_read) override;
+  void OnResponseStarted(net::URLRequest* request) override;
+  void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
   // TODO(eroman): handle cases requiring authentication.
 
  private:
diff --git a/chrome/browser/net/connection_tester_unittest.cc b/chrome/browser/net/connection_tester_unittest.cc
index 4c4836b..ff5fe67c 100644
--- a/chrome/browser/net/connection_tester_unittest.cc
+++ b/chrome/browser/net/connection_tester_unittest.cc
@@ -40,22 +40,22 @@
        completed_connection_test_suite_count_(0) {
   }
 
-  virtual void OnStartConnectionTestSuite() override {
+  void OnStartConnectionTestSuite() override {
     start_connection_test_suite_count_++;
   }
 
-  virtual void OnStartConnectionTestExperiment(
+  void OnStartConnectionTestExperiment(
       const ConnectionTester::Experiment& experiment) override {
     start_connection_test_experiment_count_++;
   }
 
-  virtual void OnCompletedConnectionTestExperiment(
+  void OnCompletedConnectionTestExperiment(
       const ConnectionTester::Experiment& experiment,
       int result) override {
     completed_connection_test_experiment_count_++;
   }
 
-  virtual void OnCompletedConnectionTestSuite() override {
+  void OnCompletedConnectionTestSuite() override {
     completed_connection_test_suite_count_++;
     base::MessageLoop::current()->Quit();
   }
diff --git a/chrome/browser/net/cookie_store_util.cc b/chrome/browser/net/cookie_store_util.cc
index 10cd52c..7bd65a0d 100644
--- a/chrome/browser/net/cookie_store_util.cc
+++ b/chrome/browser/net/cookie_store_util.cc
@@ -41,7 +41,7 @@
   }
 
   // net::CookieMonster::Delegate implementation.
-  virtual void OnCookieChanged(
+  void OnCookieChanged(
       const net::CanonicalCookie& cookie,
       bool removed,
       net::CookieMonster::Delegate::ChangeCause cause) override {
@@ -51,7 +51,7 @@
                    this, cookie, removed, cause));
   }
 
-  virtual void OnLoaded() override {
+  void OnLoaded() override {
     BrowserThread::PostTask(
         BrowserThread::UI, FROM_HERE,
         base::Bind(&ChromeCookieMonsterDelegate::OnLoadedAsyncHelper,
@@ -59,7 +59,7 @@
   }
 
  private:
-  virtual ~ChromeCookieMonsterDelegate() {}
+  ~ChromeCookieMonsterDelegate() override {}
 
   static Profile* GetProfileOnUI(ProfileManager* profile_manager,
                                  Profile* profile) {
@@ -129,10 +129,10 @@
 // OSCrypt::UseMockKeychain or will hang waiting for user input.
 class CookieOSCryptoDelegate : public content::CookieCryptoDelegate {
  public:
-  virtual bool EncryptString(const std::string& plaintext,
-                             std::string* ciphertext) override;
-  virtual bool DecryptString(const std::string& ciphertext,
-                             std::string* plaintext) override;
+  bool EncryptString(const std::string& plaintext,
+                     std::string* ciphertext) override;
+  bool DecryptString(const std::string& ciphertext,
+                     std::string* plaintext) override;
 };
 
 bool CookieOSCryptoDelegate::EncryptString(const std::string& plaintext,
diff --git a/chrome/browser/net/crl_set_fetcher.h b/chrome/browser/net/crl_set_fetcher.h
index a938c115..d6e74d7 100644
--- a/chrome/browser/net/crl_set_fetcher.h
+++ b/chrome/browser/net/crl_set_fetcher.h
@@ -33,16 +33,16 @@
   void DeleteFromDisk(const base::FilePath& path);
 
   // ComponentInstaller interface
-  virtual void OnUpdateError(int error) override;
-  virtual bool Install(const base::DictionaryValue& manifest,
-                       const base::FilePath& unpack_path) override;
-  virtual bool GetInstalledFile(const std::string& file,
-                                base::FilePath* installed_file) override;
+  void OnUpdateError(int error) override;
+  bool Install(const base::DictionaryValue& manifest,
+               const base::FilePath& unpack_path) override;
+  bool GetInstalledFile(const std::string& file,
+                        base::FilePath* installed_file) override;
 
  private:
   friend class base::RefCountedThreadSafe<CRLSetFetcher>;
 
-  virtual ~CRLSetFetcher();
+  ~CRLSetFetcher() override;
 
   // GetCRLSetbase::FilePath gets the path of the CRL set file in the user data
   // dir.
diff --git a/chrome/browser/net/disk_cache_dir_policy_handler.h b/chrome/browser/net/disk_cache_dir_policy_handler.h
index 40a5fd2..02519c5 100644
--- a/chrome/browser/net/disk_cache_dir_policy_handler.h
+++ b/chrome/browser/net/disk_cache_dir_policy_handler.h
@@ -15,11 +15,11 @@
 class DiskCacheDirPolicyHandler : public TypeCheckingPolicyHandler {
  public:
   DiskCacheDirPolicyHandler();
-  virtual ~DiskCacheDirPolicyHandler();
+  ~DiskCacheDirPolicyHandler() override;
 
   // ConfigurationPolicyHandler methods:
-  virtual void ApplyPolicySettings(const PolicyMap& policies,
-                                   PrefValueMap* prefs) override;
+  void ApplyPolicySettings(const PolicyMap& policies,
+                           PrefValueMap* prefs) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DiskCacheDirPolicyHandler);
diff --git a/chrome/browser/net/dns_probe_browsertest.cc b/chrome/browser/net/dns_probe_browsertest.cc
index 8fc3b4aa..b5029d1 100644
--- a/chrome/browser/net/dns_probe_browsertest.cc
+++ b/chrome/browser/net/dns_probe_browsertest.cc
@@ -78,11 +78,9 @@
  public:
   DelayingDnsProbeService() {}
 
-  virtual ~DelayingDnsProbeService() {
-    EXPECT_TRUE(delayed_probes_.empty());
-  }
+  ~DelayingDnsProbeService() override { EXPECT_TRUE(delayed_probes_.empty()); }
 
-  virtual void ProbeDns(const ProbeCallback& callback) override {
+  void ProbeDns(const ProbeCallback& callback) override {
     delayed_probes_.push_back(callback);
   }
 
@@ -143,7 +141,7 @@
         start_delayed_(false),
         destruction_callback_(destruction_callback) {}
 
-  virtual void Start() override {
+  void Start() override {
     if (should_delay_) {
       DCHECK(!start_delayed_);
       start_delayed_ = true;
@@ -152,7 +150,7 @@
     URLRequestFailedJob::Start();
   }
 
-  virtual void Resume() override {
+  void Resume() override {
     DCHECK(should_delay_);
     should_delay_ = false;
     if (start_delayed_) {
@@ -162,7 +160,7 @@
   }
 
  private:
-  virtual ~DelayableURLRequestFailedJob() {
+  ~DelayableURLRequestFailedJob() override {
     if (should_delay_)
       destruction_callback_.Run(this);
   }
@@ -191,7 +189,7 @@
         start_delayed_(false),
         destruction_callback_(destruction_callback) {}
 
-  virtual void Start() override {
+  void Start() override {
     if (should_delay_) {
       DCHECK(!start_delayed_);
       start_delayed_ = true;
@@ -200,7 +198,7 @@
     URLRequestMockHTTPJob::Start();
   }
 
-  virtual void Resume() override {
+  void Resume() override {
     DCHECK(should_delay_);
     should_delay_ = false;
     if (start_delayed_) {
@@ -210,7 +208,7 @@
   }
 
  private:
-  virtual ~DelayableURLRequestMockHTTPJob() {
+  ~DelayableURLRequestMockHTTPJob() override {
     if (should_delay_)
       destruction_callback_.Run(this);
   }
@@ -235,12 +233,12 @@
                        base::Unretained(this))) {
   }
 
-  virtual ~BreakableCorrectionInterceptor() {
+  ~BreakableCorrectionInterceptor() override {
     // All delayed requests should have been resumed or cancelled by this point.
     EXPECT_TRUE(delayed_requests_.empty());
   }
 
-  virtual URLRequestJob* MaybeInterceptRequest(
+  URLRequestJob* MaybeInterceptRequest(
       URLRequest* request,
       NetworkDelegate* network_delegate) const override {
     if (net_error_ != net::OK) {
@@ -433,8 +431,8 @@
   DnsProbeBrowserTest();
   virtual ~DnsProbeBrowserTest();
 
-  virtual void SetUpOnMainThread() override;
-  virtual void TearDownOnMainThread() override;
+  void SetUpOnMainThread() override;
+  void TearDownOnMainThread() override;
 
  protected:
   // Sets the browser object that other methods apply to, and that has the
diff --git a/chrome/browser/net/dns_probe_service.h b/chrome/browser/net/dns_probe_service.h
index ef1d0304..37a294a2 100644
--- a/chrome/browser/net/dns_probe_service.h
+++ b/chrome/browser/net/dns_probe_service.h
@@ -33,12 +33,12 @@
       ProbeCallback;
 
   DnsProbeService();
-  virtual ~DnsProbeService();
+  ~DnsProbeService() override;
 
   virtual void ProbeDns(const ProbeCallback& callback);
 
   // NetworkChangeNotifier::DNSObserver implementation:
-  virtual void OnDNSChanged() override;
+  void OnDNSChanged() override;
 
   void SetSystemClientForTesting(scoped_ptr<net::DnsClient> system_client);
   void SetPublicClientForTesting(scoped_ptr<net::DnsClient> public_client);
diff --git a/chrome/browser/net/evicted_domain_cookie_counter.cc b/chrome/browser/net/evicted_domain_cookie_counter.cc
index ebfc6a48..fa30864 100644
--- a/chrome/browser/net/evicted_domain_cookie_counter.cc
+++ b/chrome/browser/net/evicted_domain_cookie_counter.cc
@@ -28,10 +28,9 @@
   DelegateImpl();
 
   // EvictedDomainCookieCounter::Delegate implementation.
-  virtual void Report(
-      const EvictedDomainCookieCounter::EvictedCookie& evicted_cookie,
-      const Time& reinstatement_time) override;
-  virtual Time CurrentTime() const override;
+  void Report(const EvictedDomainCookieCounter::EvictedCookie& evicted_cookie,
+              const Time& reinstatement_time) override;
+  Time CurrentTime() const override;
 };
 
 DelegateImpl::DelegateImpl() {}
diff --git a/chrome/browser/net/evicted_domain_cookie_counter.h b/chrome/browser/net/evicted_domain_cookie_counter.h
index fb9c52ce..e2d8f770 100644
--- a/chrome/browser/net/evicted_domain_cookie_counter.h
+++ b/chrome/browser/net/evicted_domain_cookie_counter.h
@@ -87,10 +87,10 @@
   size_t GetStorageSize() const;
 
   // CookieMonster::Delegate implementation.
-  virtual void OnCookieChanged(const net::CanonicalCookie& cookie,
-                               bool removed,
-                               ChangeCause cause) override;
-  virtual void OnLoaded() override;
+  void OnCookieChanged(const net::CanonicalCookie& cookie,
+                       bool removed,
+                       ChangeCause cause) override;
+  void OnLoaded() override;
 
  private:
   // Identifier of an evicted cookie.
@@ -99,7 +99,7 @@
   // Storage class of evicted cookie.
   typedef std::map<EvictedCookieKey, EvictedCookie*> EvictedCookieMap;
 
-  virtual ~EvictedDomainCookieCounter();
+  ~EvictedDomainCookieCounter() override;
 
   // Computes key for |cookie| compatible with CanonicalCookie::IsEquivalent(),
   // i.e., IsEquivalent(a, b) ==> GetKey(a) == GetKey(b).
diff --git a/chrome/browser/net/evicted_domain_cookie_counter_unittest.cc b/chrome/browser/net/evicted_domain_cookie_counter_unittest.cc
index 45d832b..85882c1a 100644
--- a/chrome/browser/net/evicted_domain_cookie_counter_unittest.cc
+++ b/chrome/browser/net/evicted_domain_cookie_counter_unittest.cc
@@ -35,10 +35,9 @@
     explicit MockDelegate(EvictedDomainCookieCounterTest* tester);
 
     // EvictedDomainCookieCounter::Delegate implementation.
-    virtual void Report(
-        const EvictedDomainCookieCounter::EvictedCookie& evicted_cookie,
-        const Time& reinstatement_time) override;
-    virtual Time CurrentTime() const override;
+    void Report(const EvictedDomainCookieCounter::EvictedCookie& evicted_cookie,
+                const Time& reinstatement_time) override;
+    Time CurrentTime() const override;
 
    private:
     EvictedDomainCookieCounterTest* tester_;
@@ -184,16 +183,16 @@
    public:
     explicit ChangedDelegateDummy(int* result) : result_(result) {}
 
-    virtual void OnCookieChanged(const net::CanonicalCookie& cookie,
-                                 bool removed,
-                                 ChangeCause cause) override {
+    void OnCookieChanged(const net::CanonicalCookie& cookie,
+                         bool removed,
+                         ChangeCause cause) override {
       ++(*result_);
     }
 
-    virtual void OnLoaded() override {}
+    void OnLoaded() override {}
 
    private:
-    virtual ~ChangedDelegateDummy() {}
+    ~ChangedDelegateDummy() override {}
 
     int* result_;
   };
diff --git a/chrome/browser/net/load_timing_browsertest.cc b/chrome/browser/net/load_timing_browsertest.cc
index dea5da6..1900954 100644
--- a/chrome/browser/net/load_timing_browsertest.cc
+++ b/chrome/browser/net/load_timing_browsertest.cc
@@ -129,7 +129,7 @@
         weak_factory_(this) {}
 
   // net::URLRequestFileJob implementation:
-  virtual void Start() override {
+  void Start() override {
     base::TimeDelta time_to_wait;
     start_time_ = base::TimeTicks::Now();
     if (!load_timing_deltas_.receive_headers_end.is_null()) {
@@ -146,8 +146,7 @@
         time_to_wait);
   }
 
-  virtual void GetLoadTimingInfo(
-      net::LoadTimingInfo* load_timing_info) const override {
+  void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override {
     // Make sure enough time has elapsed since start was called.  If this
     // fails, the test fixture itself is flaky.
     if (!load_timing_deltas_.receive_headers_end.is_null()) {
@@ -199,7 +198,7 @@
 
  private:
   // Parent class is reference counted, so need to have a private destructor.
-  virtual ~MockUrlRequestJobWithTiming() {}
+  ~MockUrlRequestJobWithTiming() override {}
 
   void DelayedStart() {
     net::URLRequestFileJob::Start();
@@ -225,7 +224,7 @@
     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
   }
 
-  virtual ~TestInterceptor() {
+  ~TestInterceptor() override {
     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
   }
 
@@ -245,7 +244,7 @@
   }
 
   // net::URLRequestJobFactory::ProtocolHandler implementation:
-  virtual net::URLRequestJob* MaybeInterceptRequest(
+  net::URLRequestJob* MaybeInterceptRequest(
       net::URLRequest* request,
       net::NetworkDelegate* network_delegate) const override {
     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
diff --git a/chrome/browser/net/net_error_tab_helper.h b/chrome/browser/net/net_error_tab_helper.h
index 564f37bb..2c4d226 100644
--- a/chrome/browser/net/net_error_tab_helper.h
+++ b/chrome/browser/net/net_error_tab_helper.h
@@ -33,7 +33,7 @@
   typedef base::Callback<void(chrome_common_net::DnsProbeStatus)>
       DnsProbeStatusSnoopCallback;
 
-  virtual ~NetErrorTabHelper();
+  ~NetErrorTabHelper() override;
 
   static void set_state_for_testing(TestingState testing_state);
 
@@ -46,26 +46,25 @@
   }
 
   // content::WebContentsObserver implementation.
-  virtual void DidStartNavigationToPendingEntry(
+  void DidStartNavigationToPendingEntry(
       const GURL& url,
       content::NavigationController::ReloadType reload_type) override;
 
-  virtual void DidStartProvisionalLoadForFrame(
+  void DidStartProvisionalLoadForFrame(
       content::RenderFrameHost* render_frame_host,
       const GURL& validated_url,
       bool is_error_page,
       bool is_iframe_srcdoc) override;
 
-  virtual void DidCommitProvisionalLoadForFrame(
+  void DidCommitProvisionalLoadForFrame(
       content::RenderFrameHost* render_frame_host,
       const GURL& url,
       ui::PageTransition transition_type) override;
 
-  virtual void DidFailProvisionalLoad(
-      content::RenderFrameHost* render_frame_host,
-      const GURL& validated_url,
-      int error_code,
-      const base::string16& error_description) override;
+  void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
+                              const GURL& validated_url,
+                              int error_code,
+                              const base::string16& error_description) override;
 
  protected:
   // |contents| is the WebContents of the tab this NetErrorTabHelper is
diff --git a/chrome/browser/net/net_error_tab_helper_unittest.cc b/chrome/browser/net/net_error_tab_helper_unittest.cc
index 7589bda..cc54335 100644
--- a/chrome/browser/net/net_error_tab_helper_unittest.cc
+++ b/chrome/browser/net/net_error_tab_helper_unittest.cc
@@ -33,12 +33,12 @@
   int mock_sent_count() const { return mock_sent_count_; }
 
  private:
-  virtual void StartDnsProbe() override {
+  void StartDnsProbe() override {
     EXPECT_FALSE(mock_probe_running_);
     mock_probe_running_ = true;
   }
 
-  virtual void SendInfo() override {
+  void SendInfo() override {
     last_status_sent_ = dns_probe_status();
     mock_sent_count_++;
   }
diff --git a/chrome/browser/net/net_log_temp_file_unittest.cc b/chrome/browser/net/net_log_temp_file_unittest.cc
index efa72c9..7e8eaef 100644
--- a/chrome/browser/net/net_log_temp_file_unittest.cc
+++ b/chrome/browser/net/net_log_temp_file_unittest.cc
@@ -25,13 +25,13 @@
   }
 
   // NetLogTempFile implementation:
-  virtual bool GetNetExportLogDirectory(base::FilePath* path) override {
+  bool GetNetExportLogDirectory(base::FilePath* path) override {
     if (lie_about_net_export_log_directory_)
       return false;
     return NetLogTempFile::GetNetExportLogDirectory(path);
   }
 
-  virtual bool NetExportLogExists() override {
+  bool NetExportLogExists() override {
     if (lie_about_file_existence_)
       return false;
     return NetLogTempFile::NetExportLogExists();
diff --git a/chrome/browser/net/predictor.h b/chrome/browser/net/predictor.h
index 474976061..08ac322 100644
--- a/chrome/browser/net/predictor.h
+++ b/chrome/browser/net/predictor.h
@@ -619,18 +619,18 @@
  public:
   explicit SimplePredictor(bool preconnect_enabled, bool predictor_enabled)
       : Predictor(preconnect_enabled, predictor_enabled) {}
-  virtual ~SimplePredictor() {}
-  virtual void InitNetworkPredictor(
-      PrefService* user_prefs,
-      PrefService* local_state,
-      IOThread* io_thread,
-      net::URLRequestContextGetter* getter,
-      ProfileIOData* profile_io_data) override;
-  virtual void ShutdownOnUIThread() override;
+  ~SimplePredictor() override {}
+  void InitNetworkPredictor(PrefService* user_prefs,
+                            PrefService* local_state,
+                            IOThread* io_thread,
+                            net::URLRequestContextGetter* getter,
+                            ProfileIOData* profile_io_data) override;
+  void ShutdownOnUIThread() override;
+
  private:
   // These member functions return True for unittests.
-  virtual bool CanPrefetchAndPrerender() const override;
-  virtual bool CanPreresolveAndPreconnect() const override;
+  bool CanPrefetchAndPrerender() const override;
+  bool CanPreresolveAndPreconnect() const override;
 };
 
 }  // namespace chrome_browser_net
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc
index d7ac2a2..219f288 100644
--- a/chrome/browser/net/predictor_browsertest.cc
+++ b/chrome/browser/net/predictor_browsertest.cc
@@ -29,11 +29,11 @@
         is_waiting_for_hostname_(false) {
   }
 
-  virtual int Resolve(const std::string& host,
-                      net::AddressFamily address_family,
-                      net::HostResolverFlags host_resolver_flags,
-                      net::AddressList* addrlist,
-                      int* os_error) override {
+  int Resolve(const std::string& host,
+              net::AddressFamily address_family,
+              net::HostResolverFlags host_resolver_flags,
+              net::AddressList* addrlist,
+              int* os_error) override {
     BrowserThread::PostTask(
         BrowserThread::UI,
         FROM_HERE,
@@ -61,7 +61,7 @@
   }
 
  private:
-  virtual ~HostResolutionRequestRecorder() {}
+  ~HostResolutionRequestRecorder() override {}
 
   void AddToHistory(const std::string& hostname) {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -102,13 +102,13 @@
   }
 
  protected:
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     scoped_host_resolver_proc_.reset(new net::ScopedDefaultHostResolverProc(
         host_resolution_request_recorder_.get()));
     InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
   }
 
-  virtual void TearDownInProcessBrowserTestFixture() override {
+  void TearDownInProcessBrowserTestFixture() override {
     InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
     scoped_host_resolver_proc_.reset();
   }
diff --git a/chrome/browser/net/predictor_tab_helper.h b/chrome/browser/net/predictor_tab_helper.h
index 059d3920..a7351af 100644
--- a/chrome/browser/net/predictor_tab_helper.h
+++ b/chrome/browser/net/predictor_tab_helper.h
@@ -16,10 +16,10 @@
     : public content::WebContentsObserver,
       public content::WebContentsUserData<PredictorTabHelper> {
  public:
-  virtual ~PredictorTabHelper();
+  ~PredictorTabHelper() override;
 
   // content::WebContentsObserver implementation
-  virtual void DidStartNavigationToPendingEntry(
+  void DidStartNavigationToPendingEntry(
       const GURL& url,
       content::NavigationController::ReloadType reload_type) override;
 
diff --git a/chrome/browser/net/predictor_unittest.cc b/chrome/browser/net/predictor_unittest.cc
index 51883c1..3674923 100644
--- a/chrome/browser/net/predictor_unittest.cc
+++ b/chrome/browser/net/predictor_unittest.cc
@@ -705,10 +705,10 @@
 class TestPredictorObserver : public PredictorObserver {
  public:
   // PredictorObserver implementation:
-  virtual void OnPreconnectUrl(const GURL& url,
-                               const GURL& first_party_for_cookies,
-                               UrlInfo::ResolutionMotivation motivation,
-                               int count) override {
+  void OnPreconnectUrl(const GURL& url,
+                       const GURL& first_party_for_cookies,
+                       UrlInfo::ResolutionMotivation motivation,
+                       int count) override {
     preconnected_urls_.push_back(url);
   }
 
diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl.h b/chrome/browser/net/pref_proxy_config_tracker_impl.h
index 57f4981..f09cfef3 100644
--- a/chrome/browser/net/pref_proxy_config_tracker_impl.h
+++ b/chrome/browser/net/pref_proxy_config_tracker_impl.h
@@ -35,16 +35,13 @@
   // GetLatestProxyConfig returns ConfigAvailability::CONFIG_PENDING until
   // UpdateProxyConfig has been called.
   explicit ChromeProxyConfigService(net::ProxyConfigService* base_service);
-  virtual ~ChromeProxyConfigService();
+  ~ChromeProxyConfigService() override;
 
   // ProxyConfigService implementation:
-  virtual void AddObserver(
-      net::ProxyConfigService::Observer* observer) override;
-  virtual void RemoveObserver(
-      net::ProxyConfigService::Observer* observer) override;
-  virtual ConfigAvailability GetLatestProxyConfig(
-      net::ProxyConfig* config) override;
-  virtual void OnLazyPoll() override;
+  void AddObserver(net::ProxyConfigService::Observer* observer) override;
+  void RemoveObserver(net::ProxyConfigService::Observer* observer) override;
+  ConfigAvailability GetLatestProxyConfig(net::ProxyConfig* config) override;
+  void OnLazyPoll() override;
 
   // Method on IO thread that receives the preference proxy settings pushed from
   // PrefProxyConfigTrackerImpl.
@@ -53,8 +50,8 @@
 
  private:
   // ProxyConfigService::Observer implementation:
-  virtual void OnProxyConfigChanged(const net::ProxyConfig& config,
-                                    ConfigAvailability availability) override;
+  void OnProxyConfigChanged(const net::ProxyConfig& config,
+                            ConfigAvailability availability) override;
 
   // Makes sure that the observer registration with the base service is set up.
   void RegisterObserver();
@@ -85,15 +82,15 @@
 class PrefProxyConfigTrackerImpl : public PrefProxyConfigTracker {
  public:
   explicit PrefProxyConfigTrackerImpl(PrefService* pref_service);
-  virtual ~PrefProxyConfigTrackerImpl();
+  ~PrefProxyConfigTrackerImpl() override;
 
   // PrefProxyConfigTracker implementation:
-  virtual scoped_ptr<net::ProxyConfigService> CreateTrackingProxyConfigService(
+  scoped_ptr<net::ProxyConfigService> CreateTrackingProxyConfigService(
       scoped_ptr<net::ProxyConfigService> base_service) override;
 
   // Notifies the tracker that the pref service passed upon construction is
   // about to go away. This must be called from the UI thread.
-  virtual void DetachFromPrefService() override;
+  void DetachFromPrefService() override;
 
   // Determines if |config_state| takes precedence regardless, which happens if
   // config is from policy or extension or other-precede.
diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc b/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc
index 7aa7c52..93b1327 100644
--- a/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc
+++ b/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc
@@ -43,17 +43,15 @@
   }
 
  private:
-  virtual void AddObserver(
-      net::ProxyConfigService::Observer* observer) override {
+  void AddObserver(net::ProxyConfigService::Observer* observer) override {
     observers_.AddObserver(observer);
   }
 
-  virtual void RemoveObserver(
-      net::ProxyConfigService::Observer* observer) override {
+  void RemoveObserver(net::ProxyConfigService::Observer* observer) override {
     observers_.RemoveObserver(observer);
   }
 
-  virtual net::ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
+  net::ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
       net::ProxyConfig* config) override {
     *config = config_;
     return availability_;
diff --git a/chrome/browser/net/proxy_browsertest.cc b/chrome/browser/net/proxy_browsertest.cc
index 2800d61..0a630cf 100644
--- a/chrome/browser/net/proxy_browsertest.cc
+++ b/chrome/browser/net/proxy_browsertest.cc
@@ -52,9 +52,9 @@
  public:
   LoginPromptObserver() : auth_handled_(false) {}
 
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override {
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {
     if (type == chrome::NOTIFICATION_AUTH_NEEDED) {
       LoginNotificationDetails* login_details =
           content::Details<LoginNotificationDetails>(details).ptr();
@@ -87,7 +87,7 @@
     InProcessBrowserTest::SetUp();
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     command_line->AppendSwitchASCII(switches::kProxyServer,
                                     proxy_server_.host_port_pair().ToString());
   }
@@ -157,7 +157,7 @@
     InProcessBrowserTest::SetUp();
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     base::FilePath pac_script_path(FILE_PATH_LITERAL("files"));
     command_line->AppendSwitchASCII(switches::kProxyPacUrl, http_server_.GetURL(
         pac_script_path.Append(kPACScript).MaybeAsASCII()).spec());
@@ -179,7 +179,7 @@
   FileProxyScriptBrowserTest() {}
   virtual ~FileProxyScriptBrowserTest() {}
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     command_line->AppendSwitchASCII(switches::kProxyPacUrl,
         ui_test_utils::GetTestUrl(
             base::FilePath(base::FilePath::kCurrentDirectory),
@@ -209,7 +209,7 @@
     InProcessBrowserTest::SetUp();
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     base::FilePath pac_script_path(kPACScript);
     command_line->AppendSwitchASCII(
         switches::kProxyPacUrl,
@@ -232,7 +232,7 @@
   DataProxyScriptBrowserTest() {}
   virtual ~DataProxyScriptBrowserTest() {}
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     std::string contents;
     // Read in kPACScript contents.
     ASSERT_TRUE(base::ReadFileToString(ui_test_utils::GetTestFilePath(
diff --git a/chrome/browser/net/proxy_policy_handler.h b/chrome/browser/net/proxy_policy_handler.h
index f9d416c..08a1c37 100644
--- a/chrome/browser/net/proxy_policy_handler.h
+++ b/chrome/browser/net/proxy_policy_handler.h
@@ -37,13 +37,13 @@
   };
 
   ProxyPolicyHandler();
-  virtual ~ProxyPolicyHandler();
+  ~ProxyPolicyHandler() override;
 
   // ConfigurationPolicyHandler methods:
-  virtual bool CheckPolicySettings(const PolicyMap& policies,
-                                   PolicyErrorMap* errors) override;
-  virtual void ApplyPolicySettings(const PolicyMap& policies,
-                                   PrefValueMap* prefs) override;
+  bool CheckPolicySettings(const PolicyMap& policies,
+                           PolicyErrorMap* errors) override;
+  void ApplyPolicySettings(const PolicyMap& policies,
+                           PrefValueMap* prefs) override;
 
  private:
   const base::Value* GetProxyPolicyValue(const PolicyMap& policies,
diff --git a/chrome/browser/net/quota_policy_channel_id_store.h b/chrome/browser/net/quota_policy_channel_id_store.h
index 5d32be6f..a2966f8 100644
--- a/chrome/browser/net/quota_policy_channel_id_store.h
+++ b/chrome/browser/net/quota_policy_channel_id_store.h
@@ -42,17 +42,17 @@
           special_storage_policy);
 
   // net::DefaultChannelIDStore::PersistentStore:
-  virtual void Load(const LoadedCallback& loaded_callback) override;
-  virtual void AddChannelID(
+  void Load(const LoadedCallback& loaded_callback) override;
+  void AddChannelID(
       const net::DefaultChannelIDStore::ChannelID& channel_id) override;
-  virtual void DeleteChannelID(
+  void DeleteChannelID(
       const net::DefaultChannelIDStore::ChannelID& channel_id) override;
-  virtual void SetForceKeepSessionState() override;
+  void SetForceKeepSessionState() override;
 
  private:
   typedef ScopedVector<net::DefaultChannelIDStore::ChannelID> ChannelIDVector;
 
-  virtual ~QuotaPolicyChannelIDStore();
+  ~QuotaPolicyChannelIDStore() override;
 
   void OnLoad(const LoadedCallback& loaded_callback,
               scoped_ptr<ChannelIDVector> channel_ids);
diff --git a/chrome/browser/net/sdch_browsertest.cc b/chrome/browser/net/sdch_browsertest.cc
index 49abbaf..0dce279 100644
--- a/chrome/browser/net/sdch_browsertest.cc
+++ b/chrome/browser/net/sdch_browsertest.cc
@@ -520,7 +520,7 @@
   }
 
   // InProcessBrowserTest
-  virtual void SetUpCommandLine(base::CommandLine* command_line) override {
+  void SetUpCommandLine(base::CommandLine* command_line) override {
     command_line->AppendSwitchASCII(
         switches::kHostResolverRules,
         "MAP " + std::string(kTestHost) + " 127.0.0.1");
@@ -530,7 +530,7 @@
 #endif
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     test_server_.RegisterRequestHandler(
         base::Bind(&SdchResponseHandler::HandleRequest,
                    base::Unretained(&response_handler_)));
@@ -538,12 +538,12 @@
     url_request_context_getter_ = browser()->profile()->GetRequestContext();
   }
 
-  virtual void TearDownOnMainThread() override {
+  void TearDownOnMainThread() override {
     CHECK(test_server_.ShutdownAndWaitUntilComplete());
   }
 
   // URLFetcherDelegate
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override {
+  void OnURLFetchComplete(const net::URLFetcher* source) override {
     url_fetch_complete_ = true;
     if (waiting_)
       base::MessageLoopForUI::current()->Quit();
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.h
index 613f0d5..72051708 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.h
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_configurator.h
@@ -30,26 +30,26 @@
   explicit DataReductionProxyChromeConfigurator(
       PrefService* prefs,
       scoped_refptr<base::SequencedTaskRunner> network_task_runner);
-  virtual ~DataReductionProxyChromeConfigurator();
+  ~DataReductionProxyChromeConfigurator() override;
 
-  virtual void Enable(bool primary_restricted,
-                      bool fallback_restricted,
-                      const std::string& primary_origin,
-                      const std::string& fallback_origin,
-                      const std::string& ssl_origin) override;
-  virtual void Disable() override;
+  void Enable(bool primary_restricted,
+              bool fallback_restricted,
+              const std::string& primary_origin,
+              const std::string& fallback_origin,
+              const std::string& ssl_origin) override;
+  void Disable() override;
 
   // Add a host pattern to bypass. This should follow the same syntax used
   // in net::ProxyBypassRules; that is, a hostname pattern, a hostname suffix
   // pattern, an IP literal, a CIDR block, or the magic string '<local>'.
   // Bypass settings persist for the life of this object and are applied
   // each time the proxy is enabled, but are not updated while it is enabled.
-  virtual void AddHostPatternToBypass(const std::string& pattern) override;
+  void AddHostPatternToBypass(const std::string& pattern) override;
 
   // Add a URL pattern to bypass the proxy. The base implementation strips
   // everything in |pattern| after the first single slash and then treats it
   // as a hostname pattern. Subclasses may implement other semantics.
-  virtual void AddURLPatternToBypass(const std::string& pattern) override;
+  void AddURLPatternToBypass(const std::string& pattern) override;
 
   // Updates the config for use on the IO thread.
   void UpdateProxyConfigOnIO(const net::ProxyConfig& config);
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h
index 0820359..9c33879 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h
@@ -37,7 +37,7 @@
       data_reduction_proxy::DataReductionProxyParams* params);
 
   // Destructs the settings object.
-  virtual ~DataReductionProxyChromeSettings();
+  ~DataReductionProxyChromeSettings() override;
 
   // Initialize the settings object with the given configurator, prefs services,
   // and request context.
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h
index 19830d6..43c8010 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h
@@ -5,8 +5,6 @@
 #ifndef CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_CHROME_SETTINGS_FACTORY_H_
 #define CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_CHROME_SETTINGS_FACTORY_H_
 
-#include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
-
 #include "base/compiler_specific.h"
 #include "base/memory/singleton.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_params.h"
@@ -36,10 +34,10 @@
 
   DataReductionProxyChromeSettingsFactory();
 
-  virtual ~DataReductionProxyChromeSettingsFactory();
+  ~DataReductionProxyChromeSettingsFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
 
   DISALLOW_COPY_AND_ASSIGN(DataReductionProxyChromeSettingsFactory);
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_infobar_delegate.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_infobar_delegate.h
index 13a4dd1..85516b9f 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_infobar_delegate.h
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_infobar_delegate.h
@@ -23,7 +23,7 @@
   static void Create(content::WebContents* web_contents,
                      const std::string& link_url);
 
-  virtual ~DataReductionProxyInfoBarDelegate();
+  ~DataReductionProxyInfoBarDelegate() override;
 
  private:
   explicit DataReductionProxyInfoBarDelegate(const std::string& link_url);
@@ -33,10 +33,10 @@
       scoped_ptr<DataReductionProxyInfoBarDelegate> delegate);
 
   // ConfirmInfoBarDelegate
-  virtual base::string16 GetMessageText() const override;
-  virtual int GetButtons() const override;
-  virtual bool ShouldExpire(const NavigationDetails& details) const override;
-  virtual bool LinkClicked(WindowOpenDisposition disposition) override;
+  base::string16 GetMessageText() const override;
+  int GetButtons() const override;
+  bool ShouldExpire(const NavigationDetails& details) const override;
+  bool LinkClicked(WindowOpenDisposition disposition) override;
 
   std::string link_url_;
 
diff --git a/chrome/browser/net/spdyproxy/proxy_advisor.h b/chrome/browser/net/spdyproxy/proxy_advisor.h
index a18c8bf2..61b779a 100644
--- a/chrome/browser/net/spdyproxy/proxy_advisor.h
+++ b/chrome/browser/net/spdyproxy/proxy_advisor.h
@@ -38,12 +38,11 @@
  public:
   ProxyAdvisor(PrefService* pref_service,
                net::URLRequestContextGetter* context_getter);
-  virtual ~ProxyAdvisor();
+  ~ProxyAdvisor() override;
 
   // net::URLRequest::Delegate callbacks.
-  virtual void OnResponseStarted(net::URLRequest* request) override;
-  virtual void OnReadCompleted(net::URLRequest* request,
-                               int bytes_read) override;
+  void OnResponseStarted(net::URLRequest* request) override;
+  void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
 
   // Tell the advisor that |url| is being preconnected or pre-resolved and why.
   // If |url| would be proxied (according to WouldProxyURL()), the ProxyAdvisor
diff --git a/chrome/browser/net/ssl_config_service_manager_pref.cc b/chrome/browser/net/ssl_config_service_manager_pref.cc
index 61e0786..740c696 100644
--- a/chrome/browser/net/ssl_config_service_manager_pref.cc
+++ b/chrome/browser/net/ssl_config_service_manager_pref.cc
@@ -109,13 +109,13 @@
   SSLConfigServicePref() {}
 
   // Store SSL config settings in |config|. Must only be called from IO thread.
-  virtual void GetSSLConfig(net::SSLConfig* config) override;
+  void GetSSLConfig(net::SSLConfig* config) override;
 
  private:
   // Allow the pref watcher to update our internal state.
   friend class SSLConfigServiceManagerPref;
 
-  virtual ~SSLConfigServicePref() {}
+  ~SSLConfigServicePref() override {}
 
   // This method is posted to the IO thread from the browser thread to carry the
   // new config information.
@@ -146,12 +146,12 @@
     : public SSLConfigServiceManager {
  public:
   explicit SSLConfigServiceManagerPref(PrefService* local_state);
-  virtual ~SSLConfigServiceManagerPref() {}
+  ~SSLConfigServiceManagerPref() override {}
 
   // Register local_state SSL preferences.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
-  virtual net::SSLConfigService* Get() override;
+  net::SSLConfigService* Get() override;
 
  private:
   // Callback for preference changes.  This will post the changes to the IO
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc
index 9adf29a..7aee438 100644
--- a/chrome/browser/net/websocket_browsertest.cc
+++ b/chrome/browser/net/websocket_browsertest.cc
@@ -55,14 +55,14 @@
   }
 
   // Prepare the title watcher.
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     watcher_.reset(new content::TitleWatcher(
         browser()->tab_strip_model()->GetActiveWebContents(),
         base::ASCIIToUTF16("PASS")));
     watcher_->AlsoWaitForTitle(base::ASCIIToUTF16("FAIL"));
   }
 
-  virtual void TearDownOnMainThread() override { watcher_.reset(); }
+  void TearDownOnMainThread() override { watcher_.reset(); }
 
   std::string WaitAndGetTitle() {
     return base::UTF16ToUTF8(watcher_->WaitAndGetTitle());
@@ -90,7 +90,7 @@
   // The title watcher and HTTP server are set up automatically by the test
   // framework. Each test case still needs to configure and start the
   // WebSocket server(s) it needs.
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     WebSocketBrowserTest::SetUpOnMainThread();
     ASSERT_TRUE(http_server_.StartInBackground());
   }
@@ -127,9 +127,9 @@
   }
 
   // NotificationObserver implementation
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override {
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {
     DCHECK_EQ(chrome::NOTIFICATION_AUTH_NEEDED, type);
     scoped_refptr<LoginHandler> login_handler =
         content::Details<LoginNotificationDetails>(details)->handler();
diff --git a/chrome/browser/notifications/desktop_notification_infobar_delegate.h b/chrome/browser/notifications/desktop_notification_infobar_delegate.h
index 4f5b876..7d029426 100644
--- a/chrome/browser/notifications/desktop_notification_infobar_delegate.h
+++ b/chrome/browser/notifications/desktop_notification_infobar_delegate.h
@@ -25,11 +25,11 @@
                                      const GURL& requesting_frame,
                                      int contents_unique_id,
                                      const std::string& display_languages);
-  virtual ~DesktopNotificationInfoBarDelegate();
+  ~DesktopNotificationInfoBarDelegate() override;
 
   // PermissionInfoBarDelegate:
-  virtual base::string16 GetMessageText() const override;
-  virtual int GetIconID() const override;
+  base::string16 GetMessageText() const override;
+  int GetIconID() const override;
 
   GURL requesting_frame_;
   std::string display_languages_;
diff --git a/chrome/browser/notifications/desktop_notification_service.h b/chrome/browser/notifications/desktop_notification_service.h
index f337c9f..e323d1a5 100644
--- a/chrome/browser/notifications/desktop_notification_service.h
+++ b/chrome/browser/notifications/desktop_notification_service.h
@@ -80,7 +80,7 @@
                                          Profile* profile);
 
   explicit DesktopNotificationService(Profile* profile);
-  virtual ~DesktopNotificationService();
+  ~DesktopNotificationService() override;
 
   // Requests Web Notification permission for |requesting_frame|. The |callback|
   // will be invoked after the user has made a decision.
@@ -133,16 +133,15 @@
 
 #if defined(ENABLE_EXTENSIONS)
   // extensions::ExtensionRegistryObserver:
-  virtual void OnExtensionUninstalled(
-      content::BrowserContext* browser_context,
-      const extensions::Extension* extension,
-      extensions::UninstallReason reason) override;
+  void OnExtensionUninstalled(content::BrowserContext* browser_context,
+                              const extensions::Extension* extension,
+                              extensions::UninstallReason reason) override;
 #endif
 
   // PermissionContextBase:
-  virtual void UpdateContentSetting(const GURL& requesting_origin,
-                                    const GURL& embedder_origin,
-                                    bool allowed) override;
+  void UpdateContentSetting(const GURL& requesting_origin,
+                            const GURL& embedder_origin,
+                            bool allowed) override;
 
   // The profile which owns this object.
   Profile* profile_;
diff --git a/chrome/browser/notifications/desktop_notification_service_factory.h b/chrome/browser/notifications/desktop_notification_service_factory.h
index 63bcc1c5..8f06900 100644
--- a/chrome/browser/notifications/desktop_notification_service_factory.h
+++ b/chrome/browser/notifications/desktop_notification_service_factory.h
@@ -28,12 +28,12 @@
   friend struct DefaultSingletonTraits<DesktopNotificationServiceFactory>;
 
   DesktopNotificationServiceFactory();
-  virtual ~DesktopNotificationServiceFactory();
+  ~DesktopNotificationServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
 };
 
diff --git a/chrome/browser/notifications/extension_welcome_notification.cc b/chrome/browser/notifications/extension_welcome_notification.cc
index 1963c3b..c061dd8a 100644
--- a/chrome/browser/notifications/extension_welcome_notification.cc
+++ b/chrome/browser/notifications/extension_welcome_notification.cc
@@ -47,10 +47,10 @@
   }
 
   // Overridden from NotificationDelegate:
-  virtual void Display() override {}
-  virtual void Error() override {}
+  void Display() override {}
+  void Error() override {}
 
-  virtual void Close(bool by_user) override {
+  void Close(bool by_user) override {
     if (by_user) {
       // Setting the preference here may cause the notification erasing
       // to reenter. Posting a task avoids this issue.
@@ -60,8 +60,8 @@
     }
   }
 
-  virtual void Click() override {}
-  virtual void ButtonClick(int index) override {
+  void Click() override {}
+  void ButtonClick(int index) override {
     if (index == 0) {
       OpenNotificationLearnMoreTab();
     } else if (index == 1) {
@@ -98,7 +98,7 @@
         notifier, false);
   }
 
-  virtual ~NotificationCallbacks() {}
+  ~NotificationCallbacks() override {}
 
   Profile* const profile_;
 
@@ -116,17 +116,14 @@
  public:
   DefaultDelegate() {}
 
-  virtual message_center::MessageCenter* GetMessageCenter() override {
+  message_center::MessageCenter* GetMessageCenter() override {
     return g_browser_process->message_center();
   }
 
-  virtual base::Time GetCurrentTime() override {
-    return base::Time::Now();
-  }
+  base::Time GetCurrentTime() override { return base::Time::Now(); }
 
-  virtual void PostTask(
-      const tracked_objects::Location& from_here,
-      const base::Closure& task) override {
+  void PostTask(const tracked_objects::Location& from_here,
+                const base::Closure& task) override {
     base::MessageLoop::current()->PostTask(from_here, task);
   }
 
diff --git a/chrome/browser/notifications/extension_welcome_notification.h b/chrome/browser/notifications/extension_welcome_notification.h
index fd26c078..8a46fb9 100644
--- a/chrome/browser/notifications/extension_welcome_notification.h
+++ b/chrome/browser/notifications/extension_welcome_notification.h
@@ -64,7 +64,7 @@
   // The extension Id associated with the Google Now extension.
   static const char kChromeNowExtensionID[];
 
-  virtual ~ExtensionWelcomeNotification();
+  ~ExtensionWelcomeNotification() override;
 
   // To workaround the lack of delegating constructors prior to C++11, we use
   // static Create methods.
@@ -76,7 +76,7 @@
                                               Delegate* const delegate);
 
   // PrefServiceSyncableObserver
-  virtual void OnIsSyncingChanged() override;
+  void OnIsSyncingChanged() override;
 
   // Adds in the welcome notification if required for components built
   // into Chrome that show notifications like Chrome Now.
diff --git a/chrome/browser/notifications/extension_welcome_notification_factory.h b/chrome/browser/notifications/extension_welcome_notification_factory.h
index 194e8dc..e51a9acd 100644
--- a/chrome/browser/notifications/extension_welcome_notification_factory.h
+++ b/chrome/browser/notifications/extension_welcome_notification_factory.h
@@ -25,12 +25,12 @@
   friend struct DefaultSingletonTraits<ExtensionWelcomeNotificationFactory>;
 
   ExtensionWelcomeNotificationFactory();
-  virtual ~ExtensionWelcomeNotificationFactory();
+  ~ExtensionWelcomeNotificationFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
 };
 
diff --git a/chrome/browser/notifications/extension_welcome_notification_unittest.cc b/chrome/browser/notifications/extension_welcome_notification_unittest.cc
index 4e6917b..2c4544da 100644
--- a/chrome/browser/notifications/extension_welcome_notification_unittest.cc
+++ b/chrome/browser/notifications/extension_welcome_notification_unittest.cc
@@ -38,14 +38,14 @@
   }
 
   // message_center::FakeMessageCenter Overrides
-  virtual message_center::Notification* FindVisibleNotificationById(
+  message_center::Notification* FindVisibleNotificationById(
       const std::string& id) override {
     if (last_notification.get() && last_notification->id() == id)
       return last_notification.get();
     return NULL;
   }
 
-  virtual void AddNotification(
+  void AddNotification(
       scoped_ptr<message_center::Notification> notification) override {
     EXPECT_FALSE(last_notification.get());
     last_notification.swap(notification);
@@ -54,8 +54,7 @@
       notifications_with_shown_as_popup_++;
   }
 
-  virtual void RemoveNotification(const std::string& id,
-                                  bool by_user) override {
+  void RemoveNotification(const std::string& id, bool by_user) override {
     EXPECT_TRUE(last_notification.get());
     last_notification.reset();
     remove_notification_calls_++;
@@ -85,17 +84,14 @@
   }
 
   // ExtensionWelcomeNotification::Delegate
-  virtual message_center::MessageCenter* GetMessageCenter() override {
+  message_center::MessageCenter* GetMessageCenter() override {
     return message_center_.get();
   }
 
-  virtual base::Time GetCurrentTime() override {
-    return start_time_ + elapsed_time_;
-  }
+  base::Time GetCurrentTime() override { return start_time_ + elapsed_time_; }
 
-  virtual void PostTask(
-      const tracked_objects::Location& from_here,
-      const base::Closure& task) override {
+  void PostTask(const tracked_objects::Location& from_here,
+                const base::Closure& task) override {
     EXPECT_TRUE(pending_task_.is_null());
     pending_task_ = task;
   }
@@ -209,16 +205,16 @@
     explicit TestNotificationDelegate(const std::string& id) : id_(id) {}
 
     // Overridden from NotificationDelegate:
-    virtual void Display() override {}
-    virtual void Error() override {}
-    virtual void Close(bool by_user) override {}
-    virtual void Click() override {}
-    virtual void ButtonClick(int index) override {}
+    void Display() override {}
+    void Error() override {}
+    void Close(bool by_user) override {}
+    void Click() override {}
+    void ButtonClick(int index) override {}
 
-    virtual std::string id() const override { return id_; }
+    std::string id() const override { return id_; }
 
    private:
-    virtual ~TestNotificationDelegate() {}
+    ~TestNotificationDelegate() override {}
 
     const std::string id_;
 
diff --git a/chrome/browser/notifications/fullscreen_notification_blocker.h b/chrome/browser/notifications/fullscreen_notification_blocker.h
index de51ec0..439e766 100644
--- a/chrome/browser/notifications/fullscreen_notification_blocker.h
+++ b/chrome/browser/notifications/fullscreen_notification_blocker.h
@@ -17,20 +17,20 @@
  public:
   explicit FullscreenNotificationBlocker(
       message_center::MessageCenter* message_center);
-  virtual ~FullscreenNotificationBlocker();
+  ~FullscreenNotificationBlocker() override;
 
   bool is_fullscreen_mode() const { return is_fullscreen_mode_; }
 
   // message_center::NotificationBlocker overrides:
-  virtual void CheckState() override;
-  virtual bool ShouldShowNotificationAsPopup(
+  void CheckState() override;
+  bool ShouldShowNotificationAsPopup(
       const message_center::NotifierId& notifier_id) const override;
 
  private:
   // content::NotificationObserver override.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   bool is_fullscreen_mode_;
 
diff --git a/chrome/browser/notifications/google_now_notification_stats_collector.h b/chrome/browser/notifications/google_now_notification_stats_collector.h
index 3ead046..9ce460b 100644
--- a/chrome/browser/notifications/google_now_notification_stats_collector.h
+++ b/chrome/browser/notifications/google_now_notification_stats_collector.h
@@ -18,14 +18,14 @@
  public:
   explicit GoogleNowNotificationStatsCollector(
       message_center::MessageCenter* message_center);
-  virtual ~GoogleNowNotificationStatsCollector();
+  ~GoogleNowNotificationStatsCollector() override;
 
  private:
   // MessageCenterObserver
-  virtual void OnNotificationDisplayed(
+  void OnNotificationDisplayed(
       const std::string& notification_id,
       const message_center::DisplaySource source) override;
-  virtual void OnCenterVisibilityChanged(
+  void OnCenterVisibilityChanged(
       message_center::Visibility visibility) override;
 
   // Counts the number of Google Now Notifications in the message center.
diff --git a/chrome/browser/notifications/message_center_notification_manager.h b/chrome/browser/notifications/message_center_notification_manager.h
index e3c5929c..443c89b 100644
--- a/chrome/browser/notifications/message_center_notification_manager.h
+++ b/chrome/browser/notifications/message_center_notification_manager.h
@@ -45,33 +45,30 @@
       message_center::MessageCenter* message_center,
       PrefService* local_state,
       scoped_ptr<message_center::NotifierSettingsProvider> settings_provider);
-  virtual ~MessageCenterNotificationManager();
+  ~MessageCenterNotificationManager() override;
 
   // Registers preferences.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
   // NotificationUIManager
-  virtual void Add(const Notification& notification,
-                   Profile* profile) override;
-  virtual bool Update(const Notification& notification,
-                      Profile* profile) override;
-  virtual const Notification* FindById(const std::string& delegate_id,
-                                       ProfileID profile_id) const override;
-  virtual bool CancelById(const std::string& delegate_id,
-                          ProfileID profile_id) override;
-  virtual std::set<std::string> GetAllIdsByProfileAndSourceOrigin(
+  void Add(const Notification& notification, Profile* profile) override;
+  bool Update(const Notification& notification, Profile* profile) override;
+  const Notification* FindById(const std::string& delegate_id,
+                               ProfileID profile_id) const override;
+  bool CancelById(const std::string& delegate_id,
+                  ProfileID profile_id) override;
+  std::set<std::string> GetAllIdsByProfileAndSourceOrigin(
       Profile* profile,
       const GURL& source) override;
-  virtual bool CancelAllBySourceOrigin(const GURL& source_origin) override;
-  virtual bool CancelAllByProfile(ProfileID profile_id) override;
-  virtual void CancelAll() override;
+  bool CancelAllBySourceOrigin(const GURL& source_origin) override;
+  bool CancelAllByProfile(ProfileID profile_id) override;
+  void CancelAll() override;
 
   // MessageCenterObserver
-  virtual void OnNotificationRemoved(const std::string& notification_id,
-                                     bool by_user) override;
-  virtual void OnCenterVisibilityChanged(message_center::Visibility) override;
-  virtual void OnNotificationUpdated(const std::string& notification_id)
-      override;
+  void OnNotificationRemoved(const std::string& notification_id,
+                             bool by_user) override;
+  void OnCenterVisibilityChanged(message_center::Visibility) override;
+  void OnNotificationUpdated(const std::string& notification_id) override;
 
   void EnsureMessageCenterClosed();
 
diff --git a/chrome/browser/notifications/message_center_notifications_browsertest.cc b/chrome/browser/notifications/message_center_notifications_browsertest.cc
index 87c00c4..e11f906 100644
--- a/chrome/browser/notifications/message_center_notifications_browsertest.cc
+++ b/chrome/browser/notifications/message_center_notifications_browsertest.cc
@@ -29,16 +29,16 @@
     message_center_->AddObserver(this);
   }
 
-  virtual ~TestAddObserver() { message_center_->RemoveObserver(this); }
+  ~TestAddObserver() override { message_center_->RemoveObserver(this); }
 
-  virtual void OnNotificationAdded(const std::string& id) override {
+  void OnNotificationAdded(const std::string& id) override {
     std::string log = logs_[id];
     if (log != "")
       log += "_";
     logs_[id] = log + "add-" + id;
   }
 
-  virtual void OnNotificationUpdated(const std::string& id) override {
+  void OnNotificationUpdated(const std::string& id) override {
     std::string log = logs_[id];
     if (log != "")
       log += "_";
@@ -72,23 +72,23 @@
    public:
     explicit TestDelegate(const std::string& id) : id_(id) {}
 
-    virtual void Display() override { log_ += "Display_"; }
-    virtual void Error() override { log_ += "Error_"; }
-    virtual void Close(bool by_user) override {
+    void Display() override { log_ += "Display_"; }
+    void Error() override { log_ += "Error_"; }
+    void Close(bool by_user) override {
       log_ += "Close_";
       log_ += ( by_user ? "by_user_" : "programmatically_");
     }
-    virtual void Click() override { log_ += "Click_"; }
-    virtual void ButtonClick(int button_index) override {
+    void Click() override { log_ += "Click_"; }
+    void ButtonClick(int button_index) override {
       log_ += "ButtonClick_";
       log_ += base::IntToString(button_index) + "_";
     }
-    virtual std::string id() const override { return id_; }
+    std::string id() const override { return id_; }
 
     const std::string& log() { return log_; }
 
    private:
-    virtual ~TestDelegate() {}
+    ~TestDelegate() override {}
     std::string id_;
     std::string log_;
 
diff --git a/chrome/browser/notifications/message_center_settings_controller.h b/chrome/browser/notifications/message_center_settings_controller.h
index 408db71..78346ae9 100644
--- a/chrome/browser/notifications/message_center_settings_controller.h
+++ b/chrome/browser/notifications/message_center_settings_controller.h
@@ -53,28 +53,26 @@
  public:
   explicit MessageCenterSettingsController(
       ProfileInfoCache* profile_info_cache);
-  virtual ~MessageCenterSettingsController();
+  ~MessageCenterSettingsController() override;
 
   // Overridden from message_center::NotifierSettingsProvider.
-  virtual void AddObserver(
+  void AddObserver(message_center::NotifierSettingsObserver* observer) override;
+  void RemoveObserver(
       message_center::NotifierSettingsObserver* observer) override;
-  virtual void RemoveObserver(
-      message_center::NotifierSettingsObserver* observer) override;
-  virtual size_t GetNotifierGroupCount() const override;
-  virtual const message_center::NotifierGroup& GetNotifierGroupAt(
+  size_t GetNotifierGroupCount() const override;
+  const message_center::NotifierGroup& GetNotifierGroupAt(
       size_t index) const override;
-  virtual bool IsNotifierGroupActiveAt(size_t index) const override;
-  virtual void SwitchToNotifierGroup(size_t index) override;
-  virtual const message_center::NotifierGroup& GetActiveNotifierGroup() const
-      override;
-  virtual void GetNotifierList(
+  bool IsNotifierGroupActiveAt(size_t index) const override;
+  void SwitchToNotifierGroup(size_t index) override;
+  const message_center::NotifierGroup& GetActiveNotifierGroup() const override;
+  void GetNotifierList(
       std::vector<message_center::Notifier*>* notifiers) override;
-  virtual void SetNotifierEnabled(const message_center::Notifier& notifier,
-                                  bool enabled) override;
-  virtual void OnNotifierSettingsClosing() override;
-  virtual bool NotifierHasAdvancedSettings(
+  void SetNotifierEnabled(const message_center::Notifier& notifier,
+                          bool enabled) override;
+  void OnNotifierSettingsClosing() override;
+  bool NotifierHasAdvancedSettings(
       const message_center::NotifierId& notifier_id) const override;
-  virtual void OnNotifierAdvancedSettingsRequested(
+  void OnNotifierAdvancedSettingsRequested(
       const message_center::NotifierId& notifier_id,
       const std::string* notification_id) override;
 
@@ -85,14 +83,13 @@
 #endif
 
   // Overridden from extensions::AppIconLoader::Delegate.
-  virtual void SetAppImage(const std::string& id,
-                           const gfx::ImageSkia& image) override;
+  void SetAppImage(const std::string& id, const gfx::ImageSkia& image) override;
 
  private:
   // Overridden from content::NotificationObserver.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   void OnFaviconLoaded(const GURL& url,
                        const favicon_base::FaviconImageResult& favicon_result);
diff --git a/chrome/browser/notifications/message_center_stats_collector.h b/chrome/browser/notifications/message_center_stats_collector.h
index a64765e..f5808d0 100644
--- a/chrome/browser/notifications/message_center_stats_collector.h
+++ b/chrome/browser/notifications/message_center_stats_collector.h
@@ -39,7 +39,7 @@
 
   explicit MessageCenterStatsCollector(
       message_center::MessageCenter* message_center);
-  virtual ~MessageCenterStatsCollector();
+  ~MessageCenterStatsCollector() override;
 
  private:
   // Represents the aggregate stats for each notification.
@@ -63,21 +63,19 @@
   };
 
   // MessageCenterObserver
-  virtual void OnNotificationAdded(const std::string& notification_id) override;
-  virtual void OnNotificationRemoved(const std::string& notification_id,
-                                     bool by_user) override;
-  virtual void OnNotificationUpdated(
-      const std::string& notification_id) override;
-  virtual void OnNotificationClicked(
-      const std::string& notification_id) override;
-  virtual void OnNotificationButtonClicked(const std::string& notification_id,
-                                           int button_index) override;
-  virtual void OnNotificationDisplayed(
+  void OnNotificationAdded(const std::string& notification_id) override;
+  void OnNotificationRemoved(const std::string& notification_id,
+                             bool by_user) override;
+  void OnNotificationUpdated(const std::string& notification_id) override;
+  void OnNotificationClicked(const std::string& notification_id) override;
+  void OnNotificationButtonClicked(const std::string& notification_id,
+                                   int button_index) override;
+  void OnNotificationDisplayed(
       const std::string& notification_id,
       const message_center::DisplaySource source) override;
-  virtual void OnCenterVisibilityChanged(
+  void OnCenterVisibilityChanged(
       message_center::Visibility visibility) override;
-  virtual void OnQuietModeChanged(bool in_quiet_mode) override;
+  void OnQuietModeChanged(bool in_quiet_mode) override;
 
   // Weak, global.
   message_center::MessageCenter* message_center_;
diff --git a/chrome/browser/notifications/notification.h b/chrome/browser/notifications/notification.h
index dbf3898..363ece7 100644
--- a/chrome/browser/notifications/notification.h
+++ b/chrome/browser/notifications/notification.h
@@ -48,7 +48,7 @@
   Notification(const std::string& id, const Notification& notification);
 
   Notification(const Notification& notification);
-  virtual ~Notification();
+  ~Notification() override;
   Notification& operator=(const Notification& notification);
 
   // The origin URL of the script which requested the notification.
diff --git a/chrome/browser/notifications/notification_browsertest.cc b/chrome/browser/notifications/notification_browsertest.cc
index fbbaecae..2b0545be 100644
--- a/chrome/browser/notifications/notification_browsertest.cc
+++ b/chrome/browser/notifications/notification_browsertest.cc
@@ -72,12 +72,12 @@
     message_center::MessageCenter::Get()->AddObserver(this);
   }
 
-  virtual ~MessageCenterChangeObserver() {
+  ~MessageCenterChangeObserver() override {
     message_center::MessageCenter::Get()->RemoveObserver(this);
   }
 
   // NotificationChangeObserver:
-  virtual bool Wait() override {
+  bool Wait() override {
     if (notification_received_)
       return true;
 
@@ -87,18 +87,16 @@
   }
 
   // message_center::MessageCenterObserver:
-  virtual void OnNotificationAdded(
-      const std::string& notification_id) override {
+  void OnNotificationAdded(const std::string& notification_id) override {
     OnMessageCenterChanged();
   }
 
-  virtual void OnNotificationRemoved(const std::string& notification_id,
-                                     bool by_user) override {
+  void OnNotificationRemoved(const std::string& notification_id,
+                             bool by_user) override {
     OnMessageCenterChanged();
   }
 
-  virtual void OnNotificationUpdated(
-      const std::string& notification_id) override {
+  void OnNotificationUpdated(const std::string& notification_id) override {
     OnMessageCenterChanged();
   }
 
diff --git a/chrome/browser/notifications/notification_delegate.h b/chrome/browser/notifications/notification_delegate.h
index afd3911..c4788694 100644
--- a/chrome/browser/notifications/notification_delegate.h
+++ b/chrome/browser/notifications/notification_delegate.h
@@ -23,7 +23,7 @@
   virtual std::string id() const = 0;
 
  protected:
-  virtual ~NotificationDelegate() {}
+  ~NotificationDelegate() override {}
 };
 
 #endif  // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DELEGATE_H_
diff --git a/chrome/browser/notifications/notification_object_proxy.h b/chrome/browser/notifications/notification_object_proxy.h
index 937c535f..df82d54c 100644
--- a/chrome/browser/notifications/notification_object_proxy.h
+++ b/chrome/browser/notifications/notification_object_proxy.h
@@ -28,16 +28,16 @@
       scoped_ptr<content::DesktopNotificationDelegate> delegate);
 
   // NotificationDelegate implementation.
-  virtual void Display() override;
-  virtual void Error() override;
-  virtual void Close(bool by_user) override;
-  virtual void Click() override;
-  virtual std::string id() const override;
+  void Display() override;
+  void Error() override;
+  void Close(bool by_user) override;
+  void Click() override;
+  std::string id() const override;
 
  protected:
   friend class base::RefCountedThreadSafe<NotificationObjectProxy>;
 
-  virtual ~NotificationObjectProxy();
+  ~NotificationObjectProxy() override;
 
  private:
   scoped_ptr<content::DesktopNotificationDelegate> delegate_;
diff --git a/chrome/browser/notifications/notification_system_observer.h b/chrome/browser/notifications/notification_system_observer.h
index 88ea169c..7b5fe88c 100644
--- a/chrome/browser/notifications/notification_system_observer.h
+++ b/chrome/browser/notifications/notification_system_observer.h
@@ -15,13 +15,13 @@
 class NotificationSystemObserver : public content::NotificationObserver {
  public:
   explicit NotificationSystemObserver(NotificationUIManager* ui_manager);
-  virtual ~NotificationSystemObserver();
+  ~NotificationSystemObserver() override;
 
  protected:
   // content::NotificationObserver override.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
  private:
   // Registrar for the other kind of notifications (event signaling).
diff --git a/chrome/browser/notifications/notification_test_util.h b/chrome/browser/notifications/notification_test_util.h
index c01634a9..eba7834 100644
--- a/chrome/browser/notifications/notification_test_util.h
+++ b/chrome/browser/notifications/notification_test_util.h
@@ -22,14 +22,14 @@
   explicit MockNotificationDelegate(const std::string& id);
 
   // NotificationDelegate interface.
-  virtual void Display() override {}
-  virtual void Error() override {}
-  virtual void Close(bool by_user) override {}
-  virtual void Click() override {}
-  virtual std::string id() const override;
+  void Display() override {}
+  void Error() override {}
+  void Close(bool by_user) override {}
+  void Click() override {}
+  std::string id() const override;
 
  private:
-  virtual ~MockNotificationDelegate();
+  ~MockNotificationDelegate() override;
 
   std::string id_;
 
@@ -79,39 +79,38 @@
 class StubNotificationUIManager : public NotificationUIManager {
  public:
   explicit StubNotificationUIManager(const GURL& welcome_origin);
-  virtual ~StubNotificationUIManager();
+  ~StubNotificationUIManager() override;
 
   // Adds a notification to be displayed. Virtual for unit test override.
-  virtual void Add(const Notification& notification, Profile* profile) override;
-  virtual bool Update(const Notification& notification,
-                      Profile* profile) override;
+  void Add(const Notification& notification, Profile* profile) override;
+  bool Update(const Notification& notification, Profile* profile) override;
 
   // Returns NULL if no notifications match the supplied ID, either currently
   // displayed or in the queue.
-  virtual const Notification* FindById(const std::string& delegate_id,
-                                       ProfileID profile_id) const override;
+  const Notification* FindById(const std::string& delegate_id,
+                               ProfileID profile_id) const override;
 
   // Removes any notifications matching the supplied ID, either currently
   // displayed or in the queue.  Returns true if anything was removed.
-  virtual bool CancelById(const std::string& delegate_id,
-                          ProfileID profile_id) override;
+  bool CancelById(const std::string& delegate_id,
+                  ProfileID profile_id) override;
 
   // Adds the delegate_id for each outstanding notification to the set
   // |delegate_ids| (must not be NULL).
-  virtual std::set<std::string> GetAllIdsByProfileAndSourceOrigin(
+  std::set<std::string> GetAllIdsByProfileAndSourceOrigin(
       Profile* profile,
       const GURL& source) override;
 
   // Removes notifications matching the |source_origin| (which could be an
   // extension ID). Returns true if anything was removed.
-  virtual bool CancelAllBySourceOrigin(const GURL& source_origin) override;
+  bool CancelAllBySourceOrigin(const GURL& source_origin) override;
 
   // Removes notifications matching |profile|. Returns true if any were removed.
-  virtual bool CancelAllByProfile(ProfileID profile_id) override;
+  bool CancelAllByProfile(ProfileID profile_id) override;
 
   // Cancels all pending notifications and closes anything currently showing.
   // Used when the app is terminating.
-  virtual void CancelAll() override;
+  void CancelAll() override;
 
   // Test hook to get the notification so we can check it
   const Notification& notification() const { return notification_; }
diff --git a/chrome/browser/notifications/screen_lock_notification_blocker.h b/chrome/browser/notifications/screen_lock_notification_blocker.h
index 8c5c944..698ba28 100644
--- a/chrome/browser/notifications/screen_lock_notification_blocker.h
+++ b/chrome/browser/notifications/screen_lock_notification_blocker.h
@@ -16,13 +16,13 @@
  public:
   explicit ScreenLockNotificationBlocker(
       message_center::MessageCenter* message_center);
-  virtual ~ScreenLockNotificationBlocker();
+  ~ScreenLockNotificationBlocker() override;
 
   bool is_locked() const { return is_locked_; }
 
   // message_center::NotificationBlocker overrides:
-  virtual void CheckState() override;
-  virtual bool ShouldShowNotificationAsPopup(
+  void CheckState() override;
+  bool ShouldShowNotificationAsPopup(
       const message_center::NotifierId& notifier_id) const override;
 
  private:
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_service.h b/chrome/browser/notifications/sync_notifier/chrome_notifier_service.h
index 824203a..0daf4c32 100644
--- a/chrome/browser/notifications/sync_notifier/chrome_notifier_service.h
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_service.h
@@ -24,10 +24,10 @@
 class ChromeNotifierService : public KeyedService {
  public:
   explicit ChromeNotifierService(Profile* profile);
-  virtual ~ChromeNotifierService();
+  ~ChromeNotifierService() override;
 
   // KeyedService implementation.
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // Returns the SyncableService for syncer::SYNCED_NOTIFICATIONS and
   // syncer::SYNCED_NOTIFICATION_APP_INFO
diff --git a/chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h b/chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h
index 2cbf326..66d36cf 100644
--- a/chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h
+++ b/chrome/browser/notifications/sync_notifier/chrome_notifier_service_factory.h
@@ -34,10 +34,10 @@
   friend struct DefaultSingletonTraits<ChromeNotifierServiceFactory>;
 
   ChromeNotifierServiceFactory();
-  virtual ~ChromeNotifierServiceFactory();
+  ~ChromeNotifierServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
 };
 
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index 1060151..f3a2ed0 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -37,34 +37,32 @@
       public content::WebContentsObserver,
       public content::WebContentsUserData<ChromePasswordManagerClient> {
  public:
-  virtual ~ChromePasswordManagerClient();
+  ~ChromePasswordManagerClient() override;
 
   // PasswordManagerClient implementation.
-  virtual bool IsAutomaticPasswordSavingEnabled() const override;
-  virtual bool IsPasswordManagerEnabledForCurrentPage() const override;
-  virtual bool ShouldFilterAutofillResult(
-      const autofill::PasswordForm& form) override;
-  virtual bool IsSyncAccountCredential(
-      const std::string& username, const std::string& origin) const override;
-  virtual void AutofillResultsComputed() override;
-  virtual bool PromptUserToSavePassword(
+  bool IsAutomaticPasswordSavingEnabled() const override;
+  bool IsPasswordManagerEnabledForCurrentPage() const override;
+  bool ShouldFilterAutofillResult(const autofill::PasswordForm& form) override;
+  bool IsSyncAccountCredential(const std::string& username,
+                               const std::string& origin) const override;
+  void AutofillResultsComputed() override;
+  bool PromptUserToSavePassword(
       scoped_ptr<password_manager::PasswordFormManager> form_to_save) override;
-  virtual void AutomaticPasswordSave(
-      scoped_ptr<password_manager::PasswordFormManager> saved_form_manager)
-      override;
-  virtual void PasswordWasAutofilled(
+  void AutomaticPasswordSave(scoped_ptr<password_manager::PasswordFormManager>
+                                 saved_form_manager) override;
+  void PasswordWasAutofilled(
       const autofill::PasswordFormMap& best_matches) const override;
-  virtual void PasswordAutofillWasBlocked(
+  void PasswordAutofillWasBlocked(
       const autofill::PasswordFormMap& best_matches) const override;
-  virtual PrefService* GetPrefs() override;
-  virtual password_manager::PasswordStore* GetPasswordStore() override;
-  virtual password_manager::PasswordManagerDriver* GetDriver() override;
-  virtual base::FieldTrial::Probability GetProbabilityForExperiment(
+  PrefService* GetPrefs() override;
+  password_manager::PasswordStore* GetPasswordStore() override;
+  password_manager::PasswordManagerDriver* GetDriver() override;
+  base::FieldTrial::Probability GetProbabilityForExperiment(
       const std::string& experiment_name) override;
-  virtual bool IsPasswordSyncEnabled() override;
-  virtual void OnLogRouterAvailabilityChanged(bool router_can_be_used) override;
-  virtual void LogSavePasswordProgress(const std::string& text) override;
-  virtual bool IsLoggingActive() const override;
+  bool IsPasswordSyncEnabled() override;
+  void OnLogRouterAvailabilityChanged(bool router_can_be_used) override;
+  void LogSavePasswordProgress(const std::string& text) override;
+  bool IsLoggingActive() const override;
 
   // Hides any visible generation UI.
   void HidePasswordGenerationPopup();
@@ -108,7 +106,7 @@
   friend class content::WebContentsUserData<ChromePasswordManagerClient>;
 
   // content::WebContentsObserver overrides.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // Given |bounds| in the renderers coordinate system, return the same bounds
   // in the screens coordinate system.
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index a07ad6de..57438e5 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -40,11 +40,10 @@
   explicit TestChromePasswordManagerClient(content::WebContents* web_contents)
       : ChromePasswordManagerClient(web_contents, NULL),
         is_sync_account_credential_(false) {}
-  virtual ~TestChromePasswordManagerClient() {}
+  ~TestChromePasswordManagerClient() override {}
 
-  virtual bool IsSyncAccountCredential(
-      const std::string& username,
-      const std::string& origin) const override {
+  bool IsSyncAccountCredential(const std::string& username,
+                               const std::string& origin) const override {
     return is_sync_account_credential_;
   }
 
diff --git a/chrome/browser/password_manager/mock_password_store_service.h b/chrome/browser/password_manager/mock_password_store_service.h
index 3f0fda5..bad233ee 100644
--- a/chrome/browser/password_manager/mock_password_store_service.h
+++ b/chrome/browser/password_manager/mock_password_store_service.h
@@ -23,7 +23,7 @@
   explicit MockPasswordStoreService(
       scoped_refptr<password_manager::PasswordStore> password_store);
 
-  virtual ~MockPasswordStoreService();
+  ~MockPasswordStoreService() override;
 
   DISALLOW_COPY_AND_ASSIGN(MockPasswordStoreService);
 };
diff --git a/chrome/browser/password_manager/null_password_store_service.h b/chrome/browser/password_manager/null_password_store_service.h
index cbb1803..a1ed9784 100644
--- a/chrome/browser/password_manager/null_password_store_service.h
+++ b/chrome/browser/password_manager/null_password_store_service.h
@@ -20,7 +20,7 @@
  private:
   NullPasswordStoreService();
 
-  virtual ~NullPasswordStoreService();
+  ~NullPasswordStoreService() override;
 
   DISALLOW_COPY_AND_ASSIGN(NullPasswordStoreService);
 };
diff --git a/chrome/browser/password_manager/password_generation_interactive_uitest.cc b/chrome/browser/password_manager/password_generation_interactive_uitest.cc
index 97458e3..76bda7d 100644
--- a/chrome/browser/password_manager/password_generation_interactive_uitest.cc
+++ b/chrome/browser/password_manager/password_generation_interactive_uitest.cc
@@ -29,14 +29,12 @@
         password_visible_(false) {}
   virtual ~TestPopupObserver() {}
 
-  virtual void OnPopupShown(bool password_visible) override {
+  void OnPopupShown(bool password_visible) override {
     popup_showing_ = true;
     password_visible_ = password_visible;
   }
 
-  virtual void OnPopupHidden() override {
-    popup_showing_ = false;
-  }
+  void OnPopupHidden() override { popup_showing_ = false; }
 
   bool popup_showing() { return popup_showing_; }
   bool password_visible() { return password_visible_; }
@@ -50,7 +48,7 @@
 
 class PasswordGenerationInteractiveTest : public InProcessBrowserTest {
  public:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // Make sure the feature is enabled.
     command_line->AppendSwitch(autofill::switches::kEnablePasswordGeneration);
 
@@ -59,7 +57,7 @@
         autofill::switches::kLocalHeuristicsOnlyForPasswordGeneration);
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     // Disable Autofill requesting access to AddressBook data. This will cause
     // the tests to hang on Mac.
     autofill::test::DisableSystemServices(browser()->profile()->GetPrefs());
@@ -74,7 +72,7 @@
     ui_test_utils::NavigateToURL(browser(), url);
   }
 
-  virtual void TearDownOnMainThread() override {
+  void TearDownOnMainThread() override {
     // Clean up UI.
     ChromePasswordManagerClient* client =
         ChromePasswordManagerClient::FromWebContents(GetWebContents());
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index 8f173de8..1d93e85 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -67,7 +67,7 @@
       : content::WebContentsObserver(web_contents),
         message_loop_runner_(new content::MessageLoopRunner) {}
 
-  virtual ~NavigationObserver() {}
+  ~NavigationObserver() override {}
 
   // Normally Wait() will not return until a main frame navigation occurs.
   // If a path is set, Wait() will return after this path has been seen,
@@ -77,8 +77,8 @@
   }
 
   // content::WebContentsObserver:
-  virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host,
-                             const GURL& validated_url) override {
+  void DidFinishLoad(content::RenderFrameHost* render_frame_host,
+                     const GURL& validated_url) override {
     if (!wait_for_path_.empty()) {
       if (validated_url.path() == wait_for_path_)
         message_loop_runner_->Quit();
@@ -138,18 +138,16 @@
     infobar_service_->AddObserver(this);
   }
 
-  virtual ~InfoBarObserver() {
+  ~InfoBarObserver() override {
     if (infobar_service_)
       infobar_service_->RemoveObserver(this);
   }
 
  private:
   // PromptObserver:
-  virtual bool IsShowingPrompt() const override {
-    return infobar_is_being_shown_;
-  }
+  bool IsShowingPrompt() const override { return infobar_is_being_shown_; }
 
-  virtual void AcceptImpl() const override {
+  void AcceptImpl() const override {
     EXPECT_EQ(1u, infobar_service_->infobar_count());
     if (!infobar_service_->infobar_count())
       return;  // Let the test finish to gather possibly more diagnostics.
@@ -165,17 +163,15 @@
   }
 
   // infobars::InfoBarManager::Observer:
-  virtual void OnInfoBarAdded(infobars::InfoBar* infobar) override {
+  void OnInfoBarAdded(infobars::InfoBar* infobar) override {
     infobar_is_being_shown_ = true;
   }
 
-  virtual void OnInfoBarRemoved(infobars::InfoBar* infobar,
-                                bool animate) override {
+  void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override {
     infobar_is_being_shown_ = false;
   }
 
-  virtual void OnManagerShuttingDown(
-      infobars::InfoBarManager* manager) override {
+  void OnManagerShuttingDown(infobars::InfoBarManager* manager) override {
     ASSERT_EQ(infobar_service_, manager);
     infobar_service_->RemoveObserver(this);
     infobar_service_ = NULL;
@@ -193,15 +189,15 @@
       : ui_controller_(
             ManagePasswordsUIController::FromWebContents(web_contents)) {}
 
-  virtual ~BubbleObserver() {}
+  ~BubbleObserver() override {}
 
  private:
   // PromptObserver:
-  virtual bool IsShowingPrompt() const override {
+  bool IsShowingPrompt() const override {
     return ui_controller_->PasswordPendingUserDecision();
   }
 
-  virtual void AcceptImpl() const override {
+  void AcceptImpl() const override {
     ui_controller_->SavePassword();
     EXPECT_FALSE(IsShowingPrompt());
   }
@@ -264,7 +260,7 @@
   virtual ~PasswordManagerBrowserTest() {}
 
   // InProcessBrowserTest:
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     // Use TestPasswordStore to remove a possible race. Normally the
     // PasswordStore does its database manipulation on the DB thread, which
     // creates a possible race during navigation. Specifically the
@@ -277,7 +273,7 @@
         password_manager::switches::kEnableAutomaticPasswordSaving));
   }
 
-  virtual void TearDownOnMainThread() override {
+  void TearDownOnMainThread() override {
     ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
   }
 
@@ -669,6 +665,27 @@
   EXPECT_TRUE(prompt_observer->IsShowingPrompt());
 }
 
+IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest,
+                       PromptForXHRWithNewPasswordsWithoutOnSubmit) {
+  NavigateToFile("/password/password_xhr_submit.html");
+
+  // Verify that if XHR navigation occurs and the form is properly filled out,
+  // we try and save the password even though onsubmit hasn't been called.
+  // Specifically verify that the password form saving new passwords is treated
+  // the same as a login form.
+  NavigationObserver observer(WebContents());
+  scoped_ptr<PromptObserver> prompt_observer(
+      PromptObserver::Create(WebContents()));
+  std::string fill_and_navigate =
+      "document.getElementById('signup_username_field').value = 'temp';"
+      "document.getElementById('signup_password_field').value = 'random';"
+      "document.getElementById('confirmation_password_field').value = 'random';"
+      "send_xhr()";
+  ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), fill_and_navigate));
+  observer.Wait();
+  EXPECT_TRUE(prompt_observer->IsShowingPrompt());
+}
+
 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, NoPromptIfLinkClicked) {
   NavigateToFile("/password/password_form.html");
 
diff --git a/chrome/browser/password_manager/password_store_factory.h b/chrome/browser/password_manager/password_store_factory.h
index 2a26765..6014140 100644
--- a/chrome/browser/password_manager/password_store_factory.h
+++ b/chrome/browser/password_manager/password_store_factory.h
@@ -32,12 +32,12 @@
   // Init() was already called successfully on it.
   explicit PasswordStoreService(
       scoped_refptr<password_manager::PasswordStore> password_store);
-  virtual ~PasswordStoreService();
+  ~PasswordStoreService() override;
 
   scoped_refptr<password_manager::PasswordStore> GetPasswordStore();
 
   // KeyedService implementation.
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
  private:
   scoped_refptr<password_manager::PasswordStore> password_store_;
@@ -58,20 +58,20 @@
   friend struct DefaultSingletonTraits<PasswordStoreFactory>;
 
   PasswordStoreFactory();
-  virtual ~PasswordStoreFactory();
+  ~PasswordStoreFactory() override;
 
 #if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) && defined(OS_POSIX)
   LocalProfileId GetLocalProfileId(PrefService* prefs) const;
 #endif
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsNULLWhileTesting() const override;
 
   DISALLOW_COPY_AND_ASSIGN(PasswordStoreFactory);
 };
diff --git a/chrome/browser/password_manager/password_store_mac.h b/chrome/browser/password_manager/password_store_mac.h
index 0e1be3d..f539e36 100644
--- a/chrome/browser/password_manager/password_store_mac.h
+++ b/chrome/browser/password_manager/password_store_mac.h
@@ -37,42 +37,40 @@
       password_manager::LoginDatabase* login_db);
 
   // Initializes |thread_|.
-  virtual bool Init(
-      const syncer::SyncableService::StartSyncFlare& flare,
-      const std::string& sync_username) override;
+  bool Init(const syncer::SyncableService::StartSyncFlare& flare,
+            const std::string& sync_username) override;
 
   // Stops |thread_|.
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
  protected:
-  virtual ~PasswordStoreMac();
+  ~PasswordStoreMac() override;
 
-  virtual scoped_refptr<base::SingleThreadTaskRunner>
-      GetBackgroundTaskRunner() override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner()
+      override;
 
  private:
-  virtual void ReportMetricsImpl(const std::string& sync_username) override;
-  virtual password_manager::PasswordStoreChangeList AddLoginImpl(
+  void ReportMetricsImpl(const std::string& sync_username) override;
+  password_manager::PasswordStoreChangeList AddLoginImpl(
       const autofill::PasswordForm& form) override;
-  virtual password_manager::PasswordStoreChangeList UpdateLoginImpl(
+  password_manager::PasswordStoreChangeList UpdateLoginImpl(
       const autofill::PasswordForm& form) override;
-  virtual password_manager::PasswordStoreChangeList RemoveLoginImpl(
+  password_manager::PasswordStoreChangeList RemoveLoginImpl(
       const autofill::PasswordForm& form) override;
-  virtual password_manager::PasswordStoreChangeList
-      RemoveLoginsCreatedBetweenImpl(base::Time delete_begin,
-                                     base::Time delete_end) override;
-  virtual password_manager::PasswordStoreChangeList
-      RemoveLoginsSyncedBetweenImpl(base::Time delete_begin,
-                                    base::Time delete_end) override;
-  virtual void GetLoginsImpl(
-      const autofill::PasswordForm& form,
-      AuthorizationPromptPolicy prompt_policy,
-      const ConsumerCallbackRunner& callback_runner) override;
-  virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) override;
-  virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) override;
-  virtual bool FillAutofillableLogins(
+  password_manager::PasswordStoreChangeList RemoveLoginsCreatedBetweenImpl(
+      base::Time delete_begin,
+      base::Time delete_end) override;
+  password_manager::PasswordStoreChangeList RemoveLoginsSyncedBetweenImpl(
+      base::Time delete_begin,
+      base::Time delete_end) override;
+  void GetLoginsImpl(const autofill::PasswordForm& form,
+                     AuthorizationPromptPolicy prompt_policy,
+                     const ConsumerCallbackRunner& callback_runner) override;
+  void GetAutofillableLoginsImpl(GetLoginsRequest* request) override;
+  void GetBlacklistLoginsImpl(GetLoginsRequest* request) override;
+  bool FillAutofillableLogins(
       std::vector<autofill::PasswordForm*>* forms) override;
-  virtual bool FillBlacklistLogins(
+  bool FillBlacklistLogins(
       std::vector<autofill::PasswordForm*>* forms) override;
 
   // Adds the given form to the Keychain if it's something we want to store
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc
index 2675899..e14b71c 100644
--- a/chrome/browser/password_manager/password_store_mac_unittest.cc
+++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -77,7 +77,7 @@
   using PasswordStoreMac::GetBackgroundTaskRunner;
 
  private:
-  virtual ~TestPasswordStoreMac() {}
+  ~TestPasswordStoreMac() override {}
 
   DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreMac);
 };
diff --git a/chrome/browser/password_manager/save_password_infobar_delegate.h b/chrome/browser/password_manager/save_password_infobar_delegate.h
index cc8f7fa..96b0fd1 100644
--- a/chrome/browser/password_manager/save_password_infobar_delegate.h
+++ b/chrome/browser/password_manager/save_password_infobar_delegate.h
@@ -42,21 +42,21 @@
       scoped_ptr<password_manager::PasswordFormManager> form_to_save,
       const std::string& uma_histogram_suffix);
 
-  virtual ~SavePasswordInfoBarDelegate();
+  ~SavePasswordInfoBarDelegate() override;
 
   // InfoBarDelegate
-  virtual bool ShouldExpire(const NavigationDetails& details) const override;
+  bool ShouldExpire(const NavigationDetails& details) const override;
 
   // ConfirmInfoBarDelegate
-  virtual int GetIconID() const override;
-  virtual Type GetInfoBarType() const override;
-  virtual base::string16 GetMessageText() const override;
-  virtual base::string16 GetButtonLabel(InfoBarButton button) const override;
-  virtual bool Accept() override;
-  virtual bool Cancel() override;
-  virtual void InfoBarDismissed() override;
+  int GetIconID() const override;
+  Type GetInfoBarType() const override;
+  base::string16 GetMessageText() const override;
+  base::string16 GetButtonLabel(InfoBarButton button) const override;
+  bool Accept() override;
+  bool Cancel() override;
+  void InfoBarDismissed() override;
 
-  virtual InfoBarAutomationType GetInfoBarAutomationType() const override;
+  InfoBarAutomationType GetInfoBarAutomationType() const override;
 
   // The PasswordFormManager managing the form we're asking the user about,
   // and should update as per her decision.
diff --git a/chrome/browser/password_manager/test_password_store_service.h b/chrome/browser/password_manager/test_password_store_service.h
index b628faf..9e28cc7 100644
--- a/chrome/browser/password_manager/test_password_store_service.h
+++ b/chrome/browser/password_manager/test_password_store_service.h
@@ -23,7 +23,7 @@
   explicit TestPasswordStoreService(
       scoped_refptr<password_manager::PasswordStore> password_store);
 
-  virtual ~TestPasswordStoreService();
+  ~TestPasswordStoreService() override;
 
   DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreService);
 };
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.h b/chrome/browser/plugins/chrome_plugin_service_filter.h
index c4eb2c83..bab42e0 100644
--- a/chrome/browser/plugins/chrome_plugin_service_filter.h
+++ b/chrome/browser/plugins/chrome_plugin_service_filter.h
@@ -71,19 +71,17 @@
   bool IsPluginRestricted(const base::FilePath& plugin_path);
 
   // PluginServiceFilter implementation:
-  virtual bool IsPluginAvailable(
-      int render_process_id,
-      int render_frame_id,
-      const void* context,
-      const GURL& url,
-      const GURL& policy_url,
-      content::WebPluginInfo* plugin) override;
+  bool IsPluginAvailable(int render_process_id,
+                         int render_frame_id,
+                         const void* context,
+                         const GURL& url,
+                         const GURL& policy_url,
+                         content::WebPluginInfo* plugin) override;
 
   // CanLoadPlugin always grants permission to the browser
   // (render_process_id == 0)
-  virtual bool CanLoadPlugin(
-      int render_process_id,
-      const base::FilePath& path) override;
+  bool CanLoadPlugin(int render_process_id,
+                     const base::FilePath& path) override;
 
  private:
   friend struct DefaultSingletonTraits<ChromePluginServiceFilter>;
@@ -106,12 +104,12 @@
   };
 
   ChromePluginServiceFilter();
-  virtual ~ChromePluginServiceFilter();
+  ~ChromePluginServiceFilter() override;
 
   // content::NotificationObserver implementation:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   ProcessDetails* GetOrRegisterProcess(int render_process_id);
   const ProcessDetails* GetProcess(int render_process_id) const;
diff --git a/chrome/browser/plugins/plugin_info_message_filter.h b/chrome/browser/plugins/plugin_info_message_filter.h
index 2c8d919..6819a0b 100644
--- a/chrome/browser/plugins/plugin_info_message_filter.h
+++ b/chrome/browser/plugins/plugin_info_message_filter.h
@@ -78,15 +78,15 @@
   PluginInfoMessageFilter(int render_process_id, Profile* profile);
 
   // content::BrowserMessageFilter methods:
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
-  virtual void OnDestruct() const override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+  void OnDestruct() const override;
 
  private:
   friend struct content::BrowserThread::DeleteOnThread<
       content::BrowserThread::UI>;
   friend class base::DeleteHelper<PluginInfoMessageFilter>;
 
-  virtual ~PluginInfoMessageFilter();
+  ~PluginInfoMessageFilter() override;
 
   void OnGetPluginInfo(int render_frame_id,
                        const GURL& url,
diff --git a/chrome/browser/plugins/plugin_info_message_filter_unittest.cc b/chrome/browser/plugins/plugin_info_message_filter_unittest.cc
index e9c0b980..62c1fe9f 100644
--- a/chrome/browser/plugins/plugin_info_message_filter_unittest.cc
+++ b/chrome/browser/plugins/plugin_info_message_filter_unittest.cc
@@ -34,17 +34,17 @@
 class FakePluginServiceFilter : public content::PluginServiceFilter {
  public:
   FakePluginServiceFilter() {}
-  virtual ~FakePluginServiceFilter() {}
+  ~FakePluginServiceFilter() override {}
 
-  virtual bool IsPluginAvailable(int render_process_id,
-                                 int render_view_id,
-                                 const void* context,
-                                 const GURL& url,
-                                 const GURL& policy_url,
-                                 content::WebPluginInfo* plugin) override;
+  bool IsPluginAvailable(int render_process_id,
+                         int render_view_id,
+                         const void* context,
+                         const GURL& url,
+                         const GURL& policy_url,
+                         content::WebPluginInfo* plugin) override;
 
-  virtual bool CanLoadPlugin(int render_process_id,
-                             const base::FilePath& path) override;
+  bool CanLoadPlugin(int render_process_id,
+                     const base::FilePath& path) override;
 
   void set_plugin_enabled(const base::FilePath& plugin_path, bool enabled) {
     plugin_state_[plugin_path] = enabled;
diff --git a/chrome/browser/plugins/plugin_infobar_delegates.h b/chrome/browser/plugins/plugin_infobar_delegates.h
index 6e7a278c..e5ff2113 100644
--- a/chrome/browser/plugins/plugin_infobar_delegates.h
+++ b/chrome/browser/plugins/plugin_infobar_delegates.h
@@ -25,10 +25,10 @@
 class PluginInfoBarDelegate : public ConfirmInfoBarDelegate {
  protected:
   explicit PluginInfoBarDelegate(const std::string& identifier);
-  virtual ~PluginInfoBarDelegate();
+  ~PluginInfoBarDelegate() override;
 
   // ConfirmInfoBarDelegate:
-  virtual bool LinkClicked(WindowOpenDisposition disposition) override;
+  bool LinkClicked(WindowOpenDisposition disposition) override;
 
   virtual std::string GetLearnMoreURL() const = 0;
 
@@ -36,8 +36,8 @@
 
  private:
   // ConfirmInfoBarDelegate:
-  virtual int GetIconID() const override;
-  virtual base::string16 GetLinkText() const override;
+  int GetIconID() const override;
+  base::string16 GetLinkText() const override;
 
   std::string identifier_;
 
@@ -58,16 +58,16 @@
   UnauthorizedPluginInfoBarDelegate(HostContentSettingsMap* content_settings,
                                     const base::string16& name,
                                     const std::string& identifier);
-  virtual ~UnauthorizedPluginInfoBarDelegate();
+  ~UnauthorizedPluginInfoBarDelegate() override;
 
   // PluginInfoBarDelegate:
-  virtual base::string16 GetMessageText() const override;
-  virtual base::string16 GetButtonLabel(InfoBarButton button) const override;
-  virtual bool Accept() override;
-  virtual bool Cancel() override;
-  virtual void InfoBarDismissed() override;
-  virtual bool LinkClicked(WindowOpenDisposition disposition) override;
-  virtual std::string GetLearnMoreURL() const override;
+  base::string16 GetMessageText() const override;
+  base::string16 GetButtonLabel(InfoBarButton button) const override;
+  bool Accept() override;
+  bool Cancel() override;
+  void InfoBarDismissed() override;
+  bool LinkClicked(WindowOpenDisposition disposition) override;
+  std::string GetLearnMoreURL() const override;
 
   HostContentSettingsMap* content_settings_;
   base::string16 name_;
@@ -90,25 +90,25 @@
   OutdatedPluginInfoBarDelegate(PluginInstaller* installer,
                                 scoped_ptr<PluginMetadata> metadata,
                                 const base::string16& message);
-  virtual ~OutdatedPluginInfoBarDelegate();
+  ~OutdatedPluginInfoBarDelegate() override;
 
   // PluginInfoBarDelegate:
-  virtual base::string16 GetMessageText() const override;
-  virtual base::string16 GetButtonLabel(InfoBarButton button) const override;
-  virtual bool Accept() override;
-  virtual bool Cancel() override;
-  virtual void InfoBarDismissed() override;
-  virtual bool LinkClicked(WindowOpenDisposition disposition) override;
-  virtual std::string GetLearnMoreURL() const override;
+  base::string16 GetMessageText() const override;
+  base::string16 GetButtonLabel(InfoBarButton button) const override;
+  bool Accept() override;
+  bool Cancel() override;
+  void InfoBarDismissed() override;
+  bool LinkClicked(WindowOpenDisposition disposition) override;
+  std::string GetLearnMoreURL() const override;
 
   // PluginInstallerObserver:
-  virtual void DownloadStarted() override;
-  virtual void DownloadError(const std::string& message) override;
-  virtual void DownloadCancelled() override;
-  virtual void DownloadFinished() override;
+  void DownloadStarted() override;
+  void DownloadError(const std::string& message) override;
+  void DownloadCancelled() override;
+  void DownloadFinished() override;
 
   // WeakPluginInstallerObserver:
-  virtual void OnlyWeakObserversLeft() override;
+  void OnlyWeakObserversLeft() override;
 
   // Replaces this infobar with one showing |message|. The new infobar will
   // not have any buttons (and not call the callback).
@@ -151,25 +151,25 @@
                                  const InstallCallback& callback,
                                  bool new_install,
                                  const base::string16& message);
-  virtual ~PluginInstallerInfoBarDelegate();
+  ~PluginInstallerInfoBarDelegate() override;
 
   // ConfirmInfoBarDelegate:
-  virtual int GetIconID() const override;
-  virtual base::string16 GetMessageText() const override;
-  virtual int GetButtons() const override;
-  virtual base::string16 GetButtonLabel(InfoBarButton button) const override;
-  virtual bool Accept() override;
-  virtual base::string16 GetLinkText() const override;
-  virtual bool LinkClicked(WindowOpenDisposition disposition) override;
+  int GetIconID() const override;
+  base::string16 GetMessageText() const override;
+  int GetButtons() const override;
+  base::string16 GetButtonLabel(InfoBarButton button) const override;
+  bool Accept() override;
+  base::string16 GetLinkText() const override;
+  bool LinkClicked(WindowOpenDisposition disposition) override;
 
   // PluginInstallerObserver:
-  virtual void DownloadStarted() override;
-  virtual void DownloadError(const std::string& message) override;
-  virtual void DownloadCancelled() override;
-  virtual void DownloadFinished() override;
+  void DownloadStarted() override;
+  void DownloadError(const std::string& message) override;
+  void DownloadCancelled() override;
+  void DownloadFinished() override;
 
   // WeakPluginInstallerObserver:
-  virtual void OnlyWeakObserversLeft() override;
+  void OnlyWeakObserversLeft() override;
 
   // Replaces this infobar with one showing |message|. The new infobar will
   // not have any buttons (and not call the callback).
diff --git a/chrome/browser/plugins/plugin_installer.h b/chrome/browser/plugins/plugin_installer.h
index 06ffaf4..7095daf 100644
--- a/chrome/browser/plugins/plugin_installer.h
+++ b/chrome/browser/plugins/plugin_installer.h
@@ -31,10 +31,10 @@
   };
 
   PluginInstaller();
-  virtual ~PluginInstaller();
+  ~PluginInstaller() override;
 
-  virtual void OnDownloadUpdated(content::DownloadItem* download) override;
-  virtual void OnDownloadDestroyed(content::DownloadItem* download) override;
+  void OnDownloadUpdated(content::DownloadItem* download) override;
+  void OnDownloadDestroyed(content::DownloadItem* download) override;
 
   void AddObserver(PluginInstallerObserver* observer);
   void RemoveObserver(PluginInstallerObserver* observer);
diff --git a/chrome/browser/plugins/plugin_installer_observer.h b/chrome/browser/plugins/plugin_installer_observer.h
index e767bc1..58c5e89 100644
--- a/chrome/browser/plugins/plugin_installer_observer.h
+++ b/chrome/browser/plugins/plugin_installer_observer.h
@@ -35,7 +35,7 @@
 class WeakPluginInstallerObserver : public PluginInstallerObserver {
  public:
   explicit WeakPluginInstallerObserver(PluginInstaller* installer);
-  virtual ~WeakPluginInstallerObserver();
+  ~WeakPluginInstallerObserver() override;
 
  private:
   friend class PluginInstaller;
diff --git a/chrome/browser/plugins/plugin_installer_unittest.cc b/chrome/browser/plugins/plugin_installer_unittest.cc
index 468a6f73..e784654 100644
--- a/chrome/browser/plugins/plugin_installer_unittest.cc
+++ b/chrome/browser/plugins/plugin_installer_unittest.cc
@@ -68,12 +68,12 @@
   const std::string& download_error() const { return download_error_; }
 
  private:
-  virtual void DownloadStarted() override { download_started_ = true; }
-  virtual void DownloadFinished() override { download_finished_ = true; }
-  virtual void DownloadError(const std::string& message) override {
+  void DownloadStarted() override { download_started_ = true; }
+  void DownloadFinished() override { download_finished_ = true; }
+  void DownloadError(const std::string& message) override {
     download_error_ = message;
   }
-  virtual void DownloadCancelled() override { download_cancelled_ = true; }
+  void DownloadCancelled() override { download_cancelled_ = true; }
 
   bool download_started_;
   bool download_finished_;
diff --git a/chrome/browser/plugins/plugin_observer.cc b/chrome/browser/plugins/plugin_observer.cc
index 2572b29d..913633fa 100644
--- a/chrome/browser/plugins/plugin_observer.cc
+++ b/chrome/browser/plugins/plugin_observer.cc
@@ -64,15 +64,15 @@
                                scoped_ptr<PluginMetadata> plugin_metadata);
 
   // TabModalConfirmDialogDelegate methods:
-  virtual base::string16 GetTitle() override;
-  virtual base::string16 GetDialogMessage() override;
-  virtual base::string16 GetAcceptButtonTitle() override;
-  virtual void OnAccepted() override;
-  virtual void OnCanceled() override;
+  base::string16 GetTitle() override;
+  base::string16 GetDialogMessage() override;
+  base::string16 GetAcceptButtonTitle() override;
+  void OnAccepted() override;
+  void OnCanceled() override;
 
   // WeakPluginInstallerObserver methods:
-  virtual void DownloadStarted() override;
-  virtual void OnlyWeakObserversLeft() override;
+  void DownloadStarted() override;
+  void OnlyWeakObserversLeft() override;
 
  private:
   content::WebContents* web_contents_;
@@ -131,14 +131,14 @@
  private:
   ReloadPluginInfoBarDelegate(content::NavigationController* controller,
                               const base::string16& message);
-  virtual ~ReloadPluginInfoBarDelegate();
+  ~ReloadPluginInfoBarDelegate() override;
 
   // ConfirmInfobarDelegate:
-  virtual int GetIconID() const override;
-  virtual base::string16 GetMessageText() const override;
-  virtual int GetButtons() const override;
-  virtual base::string16 GetButtonLabel(InfoBarButton button) const override;
-  virtual bool Accept() override;
+  int GetIconID() const override;
+  base::string16 GetMessageText() const override;
+  int GetButtons() const override;
+  base::string16 GetButtonLabel(InfoBarButton button) const override;
+  bool Accept() override;
 
   content::NavigationController* controller_;
   base::string16 message_;
@@ -214,19 +214,19 @@
   }
 
   // PluginInstallerObserver methods:
-  virtual void DownloadStarted() override {
+  void DownloadStarted() override {
     observer_->Send(new ChromeViewMsg_StartedDownloadingPlugin(routing_id_));
   }
 
-  virtual void DownloadError(const std::string& msg) override {
+  void DownloadError(const std::string& msg) override {
     observer_->Send(new ChromeViewMsg_ErrorDownloadingPlugin(routing_id_, msg));
   }
 
-  virtual void DownloadCancelled() override {
+  void DownloadCancelled() override {
     observer_->Send(new ChromeViewMsg_CancelledDownloadingPlugin(routing_id_));
   }
 
-  virtual void DownloadFinished() override {
+  void DownloadFinished() override {
     observer_->Send(new ChromeViewMsg_FinishedDownloadingPlugin(routing_id_));
   }
 
diff --git a/chrome/browser/plugins/plugin_observer.h b/chrome/browser/plugins/plugin_observer.h
index a0cab5b..a084bb1 100644
--- a/chrome/browser/plugins/plugin_observer.h
+++ b/chrome/browser/plugins/plugin_observer.h
@@ -34,17 +34,15 @@
 class PluginObserver : public content::WebContentsObserver,
                        public content::WebContentsUserData<PluginObserver> {
  public:
-  virtual ~PluginObserver();
+  ~PluginObserver() override;
 
   // content::WebContentsObserver implementation.
-  virtual void RenderFrameCreated(
-      content::RenderFrameHost* render_frame_host) override;
-  virtual void PluginCrashed(const base::FilePath& plugin_path,
-                             base::ProcessId plugin_pid) override;
-  virtual bool OnMessageReceived(
-      const IPC::Message& message,
-      content::RenderFrameHost* render_frame_host) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
+  void PluginCrashed(const base::FilePath& plugin_path,
+                     base::ProcessId plugin_pid) override;
+  bool OnMessageReceived(const IPC::Message& message,
+                         content::RenderFrameHost* render_frame_host) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
  private:
   explicit PluginObserver(content::WebContents* web_contents);
diff --git a/chrome/browser/plugins/plugin_prefs.h b/chrome/browser/plugins/plugin_prefs.h
index 68132071..7a797c0 100644
--- a/chrome/browser/plugins/plugin_prefs.h
+++ b/chrome/browser/plugins/plugin_prefs.h
@@ -75,7 +75,7 @@
   void set_profile(Profile* profile) { profile_ = profile; }
 
   // RefCountedProfileKeyedBase method override.
-  virtual void ShutdownOnUIThread() override;
+  void ShutdownOnUIThread() override;
 
  private:
   friend class base::RefCountedThreadSafe<PluginPrefs>;
@@ -100,7 +100,7 @@
     std::map<base::FilePath, bool> state_;
   };
 
-  virtual ~PluginPrefs();
+  ~PluginPrefs() override;
 
   // Called to update one of the policy_xyz patterns below when a
   // preference changes.
diff --git a/chrome/browser/plugins/plugin_prefs_factory.h b/chrome/browser/plugins/plugin_prefs_factory.h
index 4ad3f48d..a4dd05b 100644
--- a/chrome/browser/plugins/plugin_prefs_factory.h
+++ b/chrome/browser/plugins/plugin_prefs_factory.h
@@ -27,19 +27,19 @@
       content::BrowserContext* profile);
 
   PluginPrefsFactory();
-  virtual ~PluginPrefsFactory();
+  ~PluginPrefsFactory() override;
 
   // RefcountedBrowserContextKeyedServiceFactory methods:
-  virtual scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
+  scoped_refptr<RefcountedKeyedService> BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
 
   // BrowserContextKeyedServiceFactory methods:
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
+  bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
 };
 
 #endif  // CHROME_BROWSER_PLUGINS_PLUGIN_PREFS_FACTORY_H_
diff --git a/chrome/browser/plugins/plugin_status_pref_setter.h b/chrome/browser/plugins/plugin_status_pref_setter.h
index 5f52e80..ee7c975 100644
--- a/chrome/browser/plugins/plugin_status_pref_setter.h
+++ b/chrome/browser/plugins/plugin_status_pref_setter.h
@@ -28,7 +28,7 @@
 class PluginStatusPrefSetter : public content::NotificationObserver {
  public:
   PluginStatusPrefSetter();
-  virtual ~PluginStatusPrefSetter();
+  ~PluginStatusPrefSetter() override;
 
   // Binds the preferences in the profile's PrefService, notifying |observer| if
   // any value changes.
@@ -46,9 +46,9 @@
   }
 
   // content::NotificationObserver methods:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
  private:
   void StartUpdate();
diff --git a/chrome/browser/plugins/plugins_resource_service.h b/chrome/browser/plugins/plugins_resource_service.h
index 44f4982..f5e7cbc 100644
--- a/chrome/browser/plugins/plugins_resource_service.h
+++ b/chrome/browser/plugins/plugins_resource_service.h
@@ -21,10 +21,10 @@
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
  private:
-  virtual ~PluginsResourceService();
+  ~PluginsResourceService() override;
 
   // WebResourceService override to process the parsed information.
-  virtual void Unpack(const base::DictionaryValue& parsed_json) override;
+  void Unpack(const base::DictionaryValue& parsed_json) override;
 
   DISALLOW_COPY_AND_ASSIGN(PluginsResourceService);
 };
diff --git a/chrome/browser/policy/PRESUBMIT.py b/chrome/browser/policy/PRESUBMIT.py
index 0de11ca..ea93f85 100644
--- a/chrome/browser/policy/PRESUBMIT.py
+++ b/chrome/browser/policy/PRESUBMIT.py
@@ -11,7 +11,7 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_chromeos_rel_swarming': set(['defaulttests']),
+      'linux_chromium_chromeos_rel': set(['defaulttests']),
       'linux_chromium_chromeos_clang_dbg': set(['defaulttests']),
     }
   }
diff --git a/chrome/browser/policy/chrome_browser_policy_connector.h b/chrome/browser/policy/chrome_browser_policy_connector.h
index b0e3ccee..ecca2f6f 100644
--- a/chrome/browser/policy/chrome_browser_policy_connector.h
+++ b/chrome/browser/policy/chrome_browser_policy_connector.h
@@ -31,9 +31,9 @@
   // Init() should be called to create and start the policy machinery.
   ChromeBrowserPolicyConnector();
 
-  virtual ~ChromeBrowserPolicyConnector();
+  ~ChromeBrowserPolicyConnector() override;
 
-  virtual void Init(
+  void Init(
       PrefService* local_state,
       scoped_refptr<net::URLRequestContextGetter> request_context) override;
 
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
index 4ce44c6..1cfd9da 100644
--- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -200,7 +200,7 @@
   CloudPolicyTest() {}
   virtual ~CloudPolicyTest() {}
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     ASSERT_NO_FATAL_FAILURE(SetServerPolicy(GetEmptyPolicy()));
 
@@ -216,7 +216,7 @@
         RegisterTestingFactory(BuildFakeProfileInvalidationProvider);
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     ASSERT_TRUE(PolicyServiceIsEmpty(g_browser_process->policy_service()))
         << "Pre-existing policies in this machine will make this test fail.";
 
@@ -308,16 +308,16 @@
     return temp_dir_.path().AppendASCII("policy.json");
   }
 
-  virtual void OnPolicyUpdated(const PolicyNamespace& ns,
-                               const PolicyMap& previous,
-                               const PolicyMap& current) override {
+  void OnPolicyUpdated(const PolicyNamespace& ns,
+                       const PolicyMap& previous,
+                       const PolicyMap& current) override {
     if (!on_policy_updated_.is_null()) {
       on_policy_updated_.Run();
       on_policy_updated_.Reset();
     }
   }
 
-  virtual void OnPolicyServiceInitialized(PolicyDomain domain) override {}
+  void OnPolicyServiceInitialized(PolicyDomain domain) override {}
 
   base::ScopedTempDir temp_dir_;
   scoped_ptr<LocalPolicyTestServer> test_server_;
diff --git a/chrome/browser/policy/cloud/cloud_policy_invalidator.h b/chrome/browser/policy/cloud/cloud_policy_invalidator.h
index eeb12b5..ab9c068 100644
--- a/chrome/browser/policy/cloud/cloud_policy_invalidator.h
+++ b/chrome/browser/policy/cloud/cloud_policy_invalidator.h
@@ -72,7 +72,7 @@
       const scoped_refptr<base::SequencedTaskRunner>& task_runner,
       scoped_ptr<base::Clock> clock,
       int64 highest_handled_invalidation_version);
-  virtual ~CloudPolicyInvalidator();
+  ~CloudPolicyInvalidator() override;
 
   // Initializes the invalidator. No invalidations will be generated before this
   // method is called. This method must only be called once.
@@ -95,20 +95,19 @@
   }
 
   // syncer::InvalidationHandler:
-  virtual void OnInvalidatorStateChange(
-      syncer::InvalidatorState state) override;
-  virtual void OnIncomingInvalidation(
+  void OnInvalidatorStateChange(syncer::InvalidatorState state) override;
+  void OnIncomingInvalidation(
       const syncer::ObjectIdInvalidationMap& invalidation_map) override;
-  virtual std::string GetOwnerName() const override;
+  std::string GetOwnerName() const override;
 
   // CloudPolicyCore::Observer:
-  virtual void OnCoreConnected(CloudPolicyCore* core) override;
-  virtual void OnRefreshSchedulerStarted(CloudPolicyCore* core) override;
-  virtual void OnCoreDisconnecting(CloudPolicyCore* core) override;
+  void OnCoreConnected(CloudPolicyCore* core) override;
+  void OnRefreshSchedulerStarted(CloudPolicyCore* core) override;
+  void OnCoreDisconnecting(CloudPolicyCore* core) override;
 
   // CloudPolicyStore::Observer:
-  virtual void OnStoreLoaded(CloudPolicyStore* store) override;
-  virtual void OnStoreError(CloudPolicyStore* store) override;
+  void OnStoreLoaded(CloudPolicyStore* store) override;
+  void OnStoreError(CloudPolicyStore* store) override;
 
  private:
   // Handle an invalidation to the policy.
diff --git a/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc b/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
index 7472917..349733b 100644
--- a/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
@@ -862,7 +862,7 @@
 
  private:
   // CloudPolicyInvalidatorTest:
-  virtual em::DeviceRegisterRequest::Type GetPolicyType() const override;
+  em::DeviceRegisterRequest::Type GetPolicyType() const override;
 
   // Get histogram samples for the given histogram.
   scoped_ptr<base::HistogramSamples> GetHistogramSamples(
diff --git a/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
index 1796f54..6ee06d2 100644
--- a/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
@@ -49,13 +49,13 @@
   CloudPolicyManagerTest() {}
   virtual ~CloudPolicyManagerTest() {}
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     CommandLine* command_line = CommandLine::ForCurrentProcess();
     command_line->AppendSwitchASCII(switches::kDeviceManagementUrl,
                                     "http://localhost");
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     ASSERT_TRUE(PolicyServiceIsEmpty(g_browser_process->policy_service()))
         << "Pre-existing policies in this machine will make this test fail.";
 
@@ -85,7 +85,7 @@
 #endif
   }
 
-  virtual void TearDownOnMainThread() override {
+  void TearDownOnMainThread() override {
     // Verify that all the expected requests were handled.
     EXPECT_EQ(0u, interceptor_->GetPendingSize());
 
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
index ee5a06a9..c69fccf 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
@@ -105,7 +105,7 @@
   ComponentCloudPolicyTest() {}
   virtual ~ComponentCloudPolicyTest() {}
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     ExtensionBrowserTest::SetUpCommandLine(command_line);
 #if defined(OS_CHROMEOS)
     // ExtensionBrowserTest sets the login users to a non-managed value;
@@ -116,7 +116,7 @@
 #endif
   }
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     test_server_.RegisterClient(kDMToken, kDeviceID);
     EXPECT_TRUE(test_server_.UpdatePolicyData(
         dm_protocol::kChromeExtensionPolicyType, kTestExtension, kTestPolicy));
@@ -129,7 +129,7 @@
     ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     ASSERT_TRUE(PolicyServiceIsEmpty(g_browser_process->policy_service()))
         << "Pre-existing policies in this machine will make this test fail.";
 
diff --git a/chrome/browser/policy/cloud/policy_header_service_factory.cc b/chrome/browser/policy/cloud/policy_header_service_factory.cc
index 8608802..c2164a7f 100644
--- a/chrome/browser/policy/cloud/policy_header_service_factory.cc
+++ b/chrome/browser/policy/cloud/policy_header_service_factory.cc
@@ -37,7 +37,7 @@
     return policy_header_service_.get();
   }
 
-  virtual void Shutdown() override {
+  void Shutdown() override {
     // Shutdown our core object so it can unregister any observers before the
     // services we depend on are shutdown.
     policy_header_service_.reset();
diff --git a/chrome/browser/policy/cloud/policy_header_service_factory.h b/chrome/browser/policy/cloud/policy_header_service_factory.h
index 31e78b2..6fe95ef 100644
--- a/chrome/browser/policy/cloud/policy_header_service_factory.h
+++ b/chrome/browser/policy/cloud/policy_header_service_factory.h
@@ -27,14 +27,14 @@
 
  protected:
   // BrowserContextKeyedServiceFactory implementation.
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
 
  private:
   friend struct DefaultSingletonTraits<PolicyHeaderServiceFactory>;
 
   PolicyHeaderServiceFactory();
-  virtual ~PolicyHeaderServiceFactory();
+  ~PolicyHeaderServiceFactory() override;
 
   DISALLOW_COPY_AND_ASSIGN(PolicyHeaderServiceFactory);
 };
diff --git a/chrome/browser/policy/cloud/test_request_interceptor.cc b/chrome/browser/policy/cloud/test_request_interceptor.cc
index 5069ca8d..aa45435 100644
--- a/chrome/browser/policy/cloud/test_request_interceptor.cc
+++ b/chrome/browser/policy/cloud/test_request_interceptor.cc
@@ -160,10 +160,10 @@
  public:
   Delegate(const std::string& hostname,
            scoped_refptr<base::SequencedTaskRunner> io_task_runner);
-  virtual ~Delegate();
+  ~Delegate() override;
 
   // net::URLRequestInterceptor implementation:
-  virtual net::URLRequestJob* MaybeInterceptRequest(
+  net::URLRequestJob* MaybeInterceptRequest(
       net::URLRequest* request,
       net::NetworkDelegate* network_delegate) const override;
 
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_invalidator.h b/chrome/browser/policy/cloud/user_cloud_policy_invalidator.h
index 0e9d265..82e19ed 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_invalidator.h
+++ b/chrome/browser/policy/cloud/user_cloud_policy_invalidator.h
@@ -35,12 +35,12 @@
   static enterprise_management::DeviceRegisterRequest::Type GetPolicyType();
 
   // KeyedService:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // content::NotificationObserver implementation:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
  private:
   // The profile associated with the invalidator.
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.h b/chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.h
index 0d75410..8ae5671 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.h
+++ b/chrome/browser/policy/cloud/user_cloud_policy_invalidator_factory.h
@@ -20,13 +20,13 @@
   friend struct DefaultSingletonTraits<UserCloudPolicyInvalidatorFactory>;
 
   UserCloudPolicyInvalidatorFactory();
-  virtual ~UserCloudPolicyInvalidatorFactory();
+  ~UserCloudPolicyInvalidatorFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
+  bool ServiceIsNULLWhileTesting() const override;
 
   DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyInvalidatorFactory);
 };
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc b/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc
index 877b190..65667ec 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc
+++ b/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.cc
@@ -40,11 +40,9 @@
       : manager_(manager) {
     DCHECK(manager);
   }
-  virtual ~ManagerWrapper() {}
+  ~ManagerWrapper() override {}
 
-  virtual void Shutdown() override {
-    manager_->Shutdown();
-  }
+  void Shutdown() override { manager_->Shutdown(); }
 
   UserCloudPolicyManager* manager() { return manager_; }
 
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h b/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h
index 9bda2ba..d44034bb 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h
+++ b/chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h
@@ -88,7 +88,7 @@
   friend struct DefaultSingletonTraits<UserCloudPolicyManagerFactory>;
 
   UserCloudPolicyManagerFactory();
-  virtual ~UserCloudPolicyManagerFactory();
+  ~UserCloudPolicyManagerFactory() override;
 
   // See comments for the static versions above.
   UserCloudPolicyManager* GetManagerForBrowserContext(
@@ -106,16 +106,12 @@
       content::BrowserContext* off_the_record_context);
 
   // BrowserContextKeyedBaseFactory:
-  virtual void BrowserContextShutdown(
-      content::BrowserContext* context) override;
-  virtual void BrowserContextDestroyed(
-      content::BrowserContext* context) override;
-  virtual void SetEmptyTestingFactory(
-      content::BrowserContext* context) override;
-  virtual bool HasTestingFactory(content::BrowserContext* context) override;
-  virtual void CreateServiceNow(content::BrowserContext* context) override;
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
-
+  void BrowserContextShutdown(content::BrowserContext* context) override;
+  void BrowserContextDestroyed(content::BrowserContext* context) override;
+  void SetEmptyTestingFactory(content::BrowserContext* context) override;
+  bool HasTestingFactory(content::BrowserContext* context) override;
+  void CreateServiceNow(content::BrowserContext* context) override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
 
   typedef std::map<content::BrowserContext*, ManagerWrapper*> ManagerWrapperMap;
 
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service.h b/chrome/browser/policy/cloud/user_policy_signin_service.h
index 6eb0428..6c0b0e33 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service.h
+++ b/chrome/browser/policy/cloud/user_policy_signin_service.h
@@ -40,7 +40,7 @@
       SigninManager* signin_manager,
       scoped_refptr<net::URLRequestContextGetter> system_request_context,
       ProfileOAuth2TokenService* oauth2_token_service);
-  virtual ~UserPolicySigninService();
+  ~UserPolicySigninService() override;
 
   // Registers a CloudPolicyClient for fetching policy for a user. The
   // |oauth2_login_token| and |username| are explicitly passed because
@@ -52,22 +52,22 @@
                          const PolicyRegistrationCallback& callback);
 
   // OAuth2TokenService::Observer implementation:
-  virtual void OnRefreshTokenAvailable(const std::string& account_id) override;
+  void OnRefreshTokenAvailable(const std::string& account_id) override;
 
   // CloudPolicyService::Observer implementation:
-  virtual void OnInitializationCompleted(CloudPolicyService* service) override;
+  void OnInitializationCompleted(CloudPolicyService* service) override;
 
   // KeyedService implementation:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
  protected:
   // UserPolicySigninServiceBase implementation:
-  virtual void InitializeUserCloudPolicyManager(
+  void InitializeUserCloudPolicyManager(
       const std::string& username,
       scoped_ptr<CloudPolicyClient> client) override;
 
-  virtual void PrepareForUserCloudPolicyManagerShutdown() override;
-  virtual void ShutdownUserCloudPolicyManager() override;
+  void PrepareForUserCloudPolicyManagerShutdown() override;
+  void ShutdownUserCloudPolicyManager() override;
 
  private:
   // Fetches an OAuth token to allow the cloud policy service to register with
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_base.h b/chrome/browser/policy/cloud/user_policy_signin_service_base.h
index 3a562779..75e5699 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_base.h
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_base.h
@@ -69,7 +69,7 @@
       UserCloudPolicyManager* policy_manager,
       SigninManager* signin_manager,
       scoped_refptr<net::URLRequestContextGetter> system_request_context);
-  virtual ~UserPolicySigninServiceBase();
+  ~UserPolicySigninServiceBase() override;
 
   // Initiates a policy fetch as part of user signin, using a |dm_token| and
   // |client_id| fetched via RegisterForPolicy(). |callback| is invoked
@@ -83,24 +83,24 @@
       const PolicyFetchCallback& callback);
 
   // SigninManagerBase::Observer implementation:
-  virtual void GoogleSignedOut(const std::string& account_id,
-                               const std::string& username) override;
+  void GoogleSignedOut(const std::string& account_id,
+                       const std::string& username) override;
 
   // content::NotificationObserver implementation:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // CloudPolicyService::Observer implementation:
-  virtual void OnInitializationCompleted(CloudPolicyService* service) override;
+  void OnInitializationCompleted(CloudPolicyService* service) override;
 
   // CloudPolicyClient::Observer implementation:
-  virtual void OnPolicyFetched(CloudPolicyClient* client) override;
-  virtual void OnRegistrationStateChanged(CloudPolicyClient* client) override;
-  virtual void OnClientError(CloudPolicyClient* client) override;
+  void OnPolicyFetched(CloudPolicyClient* client) override;
+  void OnRegistrationStateChanged(CloudPolicyClient* client) override;
+  void OnClientError(CloudPolicyClient* client) override;
 
   // KeyedService implementation:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   void SetSystemRequestContext(
       scoped_refptr<net::URLRequestContextGetter> request_context);
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_factory.h b/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
index 69a57e0c..12ecd396 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_factory.h
@@ -39,21 +39,21 @@
 
  protected:
   // BrowserContextKeyedServiceFactory implementation.
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
 
   // Overridden to cause this object to be created when the profile is created.
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
 
   // Register the preferences related to cloud-based user policy.
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
 
  private:
   friend struct DefaultSingletonTraits<UserPolicySigninServiceFactory>;
 
   UserPolicySigninServiceFactory();
-  virtual ~UserPolicySigninServiceFactory();
+  ~UserPolicySigninServiceFactory() override;
 
   DISALLOW_COPY_AND_ASSIGN(UserPolicySigninServiceFactory);
 };
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
index a07045a..8f8627d 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -376,7 +376,7 @@
 
 class UserPolicySigninServiceSignedInTest : public UserPolicySigninServiceTest {
  public:
-  virtual void AddProfile() override {
+  void AddProfile() override {
     // UserCloudPolicyManager should not be initialized.
     ASSERT_FALSE(manager_->core()->service());
 
diff --git a/chrome/browser/policy/device_management_service_configuration.h b/chrome/browser/policy/device_management_service_configuration.h
index 1d1e3aa..98cb681 100644
--- a/chrome/browser/policy/device_management_service_configuration.h
+++ b/chrome/browser/policy/device_management_service_configuration.h
@@ -19,11 +19,11 @@
     : public DeviceManagementService::Configuration {
  public:
   explicit DeviceManagementServiceConfiguration(const std::string& server_url);
-  virtual ~DeviceManagementServiceConfiguration();
+  ~DeviceManagementServiceConfiguration() override;
 
-  virtual std::string GetServerUrl() override;
-  virtual std::string GetAgentParameter() override;
-  virtual std::string GetPlatformParameter() override;
+  std::string GetServerUrl() override;
+  std::string GetAgentParameter() override;
+  std::string GetPlatformParameter() override;
 
  private:
   const std::string server_url_;
diff --git a/chrome/browser/policy/file_selection_dialogs_policy_handler.h b/chrome/browser/policy/file_selection_dialogs_policy_handler.h
index cbaaf10..b5b95d9 100644
--- a/chrome/browser/policy/file_selection_dialogs_policy_handler.h
+++ b/chrome/browser/policy/file_selection_dialogs_policy_handler.h
@@ -15,11 +15,11 @@
 class FileSelectionDialogsPolicyHandler : public TypeCheckingPolicyHandler {
  public:
   FileSelectionDialogsPolicyHandler();
-  virtual ~FileSelectionDialogsPolicyHandler();
+  ~FileSelectionDialogsPolicyHandler() override;
 
   // ConfigurationPolicyHandler methods:
-  virtual void ApplyPolicySettings(const PolicyMap& policies,
-                                   PrefValueMap* prefs) override;
+  void ApplyPolicySettings(const PolicyMap& policies,
+                           PrefValueMap* prefs) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FileSelectionDialogsPolicyHandler);
diff --git a/chrome/browser/policy/javascript_policy_handler.h b/chrome/browser/policy/javascript_policy_handler.h
index 9c91976..e7ce805 100644
--- a/chrome/browser/policy/javascript_policy_handler.h
+++ b/chrome/browser/policy/javascript_policy_handler.h
@@ -18,13 +18,13 @@
 class JavascriptPolicyHandler : public ConfigurationPolicyHandler {
  public:
   JavascriptPolicyHandler();
-  virtual ~JavascriptPolicyHandler();
+  ~JavascriptPolicyHandler() override;
 
   // ConfigurationPolicyHandler methods:
-  virtual bool CheckPolicySettings(const PolicyMap& policies,
-                                   PolicyErrorMap* errors) override;
-  virtual void ApplyPolicySettings(const PolicyMap& policies,
-                                   PrefValueMap* prefs) override;
+  bool CheckPolicySettings(const PolicyMap& policies,
+                           PolicyErrorMap* errors) override;
+  void ApplyPolicySettings(const PolicyMap& policies,
+                           PrefValueMap* prefs) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(JavascriptPolicyHandler);
diff --git a/chrome/browser/policy/managed_bookmarks_policy_handler.h b/chrome/browser/policy/managed_bookmarks_policy_handler.h
index c0601743..bbe09cb 100644
--- a/chrome/browser/policy/managed_bookmarks_policy_handler.h
+++ b/chrome/browser/policy/managed_bookmarks_policy_handler.h
@@ -17,11 +17,11 @@
 class ManagedBookmarksPolicyHandler : public SchemaValidatingPolicyHandler {
  public:
   explicit ManagedBookmarksPolicyHandler(Schema chrome_schema);
-  virtual ~ManagedBookmarksPolicyHandler();
+  ~ManagedBookmarksPolicyHandler() override;
 
   // ConfigurationPolicyHandler methods:
-  virtual void ApplyPolicySettings(const PolicyMap& policies,
-                                   PrefValueMap* prefs) override;
+  void ApplyPolicySettings(const PolicyMap& policies,
+                           PrefValueMap* prefs) override;
 
  private:
   void FilterBookmarks(base::ListValue* bookmarks);
diff --git a/chrome/browser/policy/network_prediction_policy_handler.h b/chrome/browser/policy/network_prediction_policy_handler.h
index a485fab..9a8d3e4 100644
--- a/chrome/browser/policy/network_prediction_policy_handler.h
+++ b/chrome/browser/policy/network_prediction_policy_handler.h
@@ -18,13 +18,13 @@
 class NetworkPredictionPolicyHandler : public ConfigurationPolicyHandler {
  public:
   NetworkPredictionPolicyHandler();
-  virtual ~NetworkPredictionPolicyHandler();
+  ~NetworkPredictionPolicyHandler() override;
 
   // ConfigurationPolicyHandler methods:
-  virtual bool CheckPolicySettings(const PolicyMap& policies,
-                                   PolicyErrorMap* errors) override;
-  virtual void ApplyPolicySettings(const PolicyMap& policies,
-                                   PrefValueMap* prefs) override;
+  bool CheckPolicySettings(const PolicyMap& policies,
+                           PolicyErrorMap* errors) override;
+  void ApplyPolicySettings(const PolicyMap& policies,
+                           PrefValueMap* prefs) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(NetworkPredictionPolicyHandler);
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index b433268..1b369fb 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -38,6 +38,7 @@
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_management_constants.h"
 #include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/shared_module_service.h"
 #include "chrome/browser/extensions/unpacked_installer.h"
 #include "chrome/browser/extensions/updater/extension_cache_fake.h"
 #include "chrome/browser/extensions/updater/extension_updater.h"
@@ -75,6 +76,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/extensions/features/feature_channel.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
@@ -124,12 +126,15 @@
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
 #include "extensions/browser/extension_host.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/process_manager.h"
+#include "extensions/browser/test_extension_registry_observer.h"
 #include "extensions/browser/uninstall_reason.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
+#include "extensions/common/manifest_handlers/shared_module_info.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_util.h"
 #include "net/base/url_util.h"
@@ -510,15 +515,14 @@
  public:
   explicit WebContentsLoadedOrDestroyedWatcher(
       content::WebContents* web_contents);
-  virtual ~WebContentsLoadedOrDestroyedWatcher();
+  ~WebContentsLoadedOrDestroyedWatcher() override;
 
   // Waits until the WebContents's load is done or until it is destroyed.
   void Wait();
 
   // Overridden WebContentsObserver methods.
-  virtual void WebContentsDestroyed() override;
-  virtual void DidStopLoading(
-      content::RenderViewHost* render_view_host) override;
+  void WebContentsDestroyed() override;
+  void DidStopLoading(content::RenderViewHost* render_view_host) override;
 
  private:
   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
@@ -604,14 +608,14 @@
     InProcessBrowserTest::SetUp();
   }
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     CommandLine::ForCurrentProcess()->AppendSwitch("noerrdialogs");
     EXPECT_CALL(provider_, IsInitializationComplete(_))
         .WillRepeatedly(Return(true));
     BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
         base::Bind(chrome_browser_net::SetUrlRequestMocksEnabled, true));
@@ -1605,6 +1609,78 @@
   EXPECT_FALSE(service->GetExtensionById(kGoodCrxId, true));
 }
 
+IN_PROC_BROWSER_TEST_F(PolicyTest, ExtensionInstallBlacklistSharedModules) {
+  // Verifies that shared_modules are not affected by the blacklist.
+
+  const char kImporterId[] = "pchakhniekfaeoddkifplhnfbffomabh";
+  const char kSharedModuleId[] = "nfgclafboonjbiafbllihiailjlhelpm";
+
+  // Make sure that "import" and "export" are available to these extension IDs
+  // by mocking the release channel.
+  extensions::ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_DEV);
+
+  // Verify that the extensions are not installed initially.
+  ExtensionService* service = extension_service();
+  ASSERT_FALSE(service->GetExtensionById(kImporterId, true));
+  ASSERT_FALSE(service->GetExtensionById(kSharedModuleId, true));
+
+  // Mock the webstore update URL. This is where the shared module extension
+  // will be installed from.
+  base::FilePath update_xml_path = base::FilePath(kTestExtensionsDir)
+                                       .AppendASCII("policy_shared_module")
+                                       .AppendASCII("update.xml");
+  GURL update_xml_url(URLRequestMockHTTPJob::GetMockUrl(update_xml_path));
+  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+      switches::kAppsGalleryUpdateURL, update_xml_url.spec());
+  ui_test_utils::NavigateToURL(browser(), update_xml_url);
+
+  // Blacklist "*" but force-install the importer extension. The shared module
+  // should be automatically installed too.
+  base::ListValue blacklist;
+  blacklist.AppendString("*");
+  base::ListValue forcelist;
+  forcelist.AppendString(
+      base::StringPrintf("%s;%s", kImporterId, update_xml_url.spec().c_str()));
+  PolicyMap policies;
+  policies.Set(key::kExtensionInstallBlacklist, POLICY_LEVEL_MANDATORY,
+               POLICY_SCOPE_USER, blacklist.DeepCopy(), NULL);
+  policies.Set(key::kExtensionInstallForcelist, POLICY_LEVEL_MANDATORY,
+               POLICY_SCOPE_USER, forcelist.DeepCopy(), NULL);
+
+  extensions::ExtensionRegistry* registry =
+      extensions::ExtensionRegistry::Get(browser()->profile());
+  extensions::TestExtensionRegistryObserver observe_importer(
+      registry, kImporterId);
+  extensions::TestExtensionRegistryObserver observe_shared_module(
+      registry, kSharedModuleId);
+  UpdateProviderPolicy(policies);
+  observe_importer.WaitForExtensionLoaded();
+  observe_shared_module.WaitForExtensionLoaded();
+
+  // Verify that both extensions got installed.
+  const extensions::Extension* importer =
+      service->GetExtensionById(kImporterId, true);
+  ASSERT_TRUE(importer);
+  EXPECT_EQ(kImporterId, importer->id());
+  const extensions::Extension* shared_module =
+      service->GetExtensionById(kSharedModuleId, true);
+  ASSERT_TRUE(shared_module);
+  EXPECT_EQ(kSharedModuleId, shared_module->id());
+  EXPECT_TRUE(shared_module->is_shared_module());
+
+  // Verify the dependency.
+  scoped_ptr<extensions::ExtensionSet> set =
+      service->shared_module_service()->GetDependentExtensions(shared_module);
+  ASSERT_TRUE(set);
+  EXPECT_EQ(1u, set->size());
+  EXPECT_TRUE(set->Contains(importer->id()));
+
+  std::vector<extensions::SharedModuleInfo::ImportInfo> imports =
+      extensions::SharedModuleInfo::GetImports(importer);
+  ASSERT_EQ(1u, imports.size());
+  EXPECT_EQ(kSharedModuleId, imports[0].extension_id);
+}
+
 IN_PROC_BROWSER_TEST_F(PolicyTest, ExtensionInstallWhitelist) {
   // Verifies that the whitelist can open exceptions to the blacklist.
   ExtensionService* service = extension_service();
@@ -2800,7 +2876,7 @@
   }
 #endif
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     PolicyTest::SetUpInProcessBrowserTestFixture();
     // Set early policies now, before the browser is created.
     (this->*(GetParam()))();
@@ -2816,7 +2892,7 @@
                            command_line->argv().begin()));
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     BrowserThread::PostTask(
         BrowserThread::IO,
         FROM_HERE,
@@ -2964,7 +3040,7 @@
   PolicyStatisticsCollectorTest() {}
   virtual ~PolicyStatisticsCollectorTest() {}
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     PolicyTest::SetUpInProcessBrowserTestFixture();
     PolicyMap policies;
     policies.Set(key::kShowHomeButton,
@@ -3254,7 +3330,7 @@
 // started.
 class PolicyVariationsServiceTest : public PolicyTest {
  public:
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     PolicyTest::SetUpInProcessBrowserTestFixture();
     PolicyMap policies;
     policies.Set(key::kVariationsRestrictParameter,
diff --git a/chrome/browser/policy/policy_prefs_browsertest.cc b/chrome/browser/policy/policy_prefs_browsertest.cc
index b9ebde3..973768c 100644
--- a/chrome/browser/policy/policy_prefs_browsertest.cc
+++ b/chrome/browser/policy/policy_prefs_browsertest.cc
@@ -490,20 +490,18 @@
 // Base class for tests that change policy.
 class PolicyPrefsTest : public InProcessBrowserTest {
  protected:
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     EXPECT_CALL(provider_, IsInitializationComplete(_))
         .WillRepeatedly(Return(true));
     BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     ui_test_utils::WaitForTemplateURLServiceToLoad(
         TemplateURLServiceFactory::GetForProfile(browser()->profile()));
   }
 
-  virtual void TearDownOnMainThread() override {
-    ClearProviderPolicy();
-  }
+  void TearDownOnMainThread() override { ClearProviderPolicy(); }
 
   void ClearProviderPolicy() {
     provider_.UpdateChromePolicy(PolicyMap());
diff --git a/chrome/browser/policy/profile_policy_connector.h b/chrome/browser/policy/profile_policy_connector.h
index e32e2c1d..820eb0f 100644
--- a/chrome/browser/policy/profile_policy_connector.h
+++ b/chrome/browser/policy/profile_policy_connector.h
@@ -27,7 +27,7 @@
 class ProfilePolicyConnector : public KeyedService {
  public:
   ProfilePolicyConnector();
-  virtual ~ProfilePolicyConnector();
+  ~ProfilePolicyConnector() override;
 
   // If |force_immediate_load| then disk caches will be loaded synchronously.
   void Init(bool force_immediate_load,
@@ -40,7 +40,7 @@
   void InitForTesting(scoped_ptr<PolicyService> service);
 
   // KeyedService:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // This is never NULL.
   PolicyService* policy_service() const { return policy_service_.get(); }
diff --git a/chrome/browser/policy/profile_policy_connector_factory.h b/chrome/browser/policy/profile_policy_connector_factory.h
index 22569f4..f11c3de 100644
--- a/chrome/browser/policy/profile_policy_connector_factory.h
+++ b/chrome/browser/policy/profile_policy_connector_factory.h
@@ -67,7 +67,7 @@
   friend struct DefaultSingletonTraits<ProfilePolicyConnectorFactory>;
 
   ProfilePolicyConnectorFactory();
-  virtual ~ProfilePolicyConnectorFactory();
+  ~ProfilePolicyConnectorFactory() override;
 
   ProfilePolicyConnector* GetForProfileInternal(Profile* profile);
 
@@ -76,14 +76,11 @@
       bool force_immediate_load);
 
   // BrowserContextKeyedBaseFactory:
-  virtual void BrowserContextShutdown(
-      content::BrowserContext* context) override;
-  virtual void BrowserContextDestroyed(
-      content::BrowserContext* context) override;
-  virtual void SetEmptyTestingFactory(
-      content::BrowserContext* context) override;
-  virtual bool HasTestingFactory(content::BrowserContext* context) override;
-  virtual void CreateServiceNow(content::BrowserContext* context) override;
+  void BrowserContextShutdown(content::BrowserContext* context) override;
+  void BrowserContextDestroyed(content::BrowserContext* context) override;
+  void SetEmptyTestingFactory(content::BrowserContext* context) override;
+  bool HasTestingFactory(content::BrowserContext* context) override;
+  void CreateServiceNow(content::BrowserContext* context) override;
 
   typedef std::map<Profile*, ProfilePolicyConnector*> ConnectorMap;
   ConnectorMap connectors_;
diff --git a/chrome/browser/policy/schema_registry_service.h b/chrome/browser/policy/schema_registry_service.h
index 24beefcb..316ba08 100644
--- a/chrome/browser/policy/schema_registry_service.h
+++ b/chrome/browser/policy/schema_registry_service.h
@@ -24,7 +24,7 @@
   SchemaRegistryService(scoped_ptr<SchemaRegistry> registry,
                         const Schema& chrome_schema,
                         CombinedSchemaRegistry* global_registry);
-  virtual ~SchemaRegistryService();
+  ~SchemaRegistryService() override;
 
   SchemaRegistry* registry() const { return registry_.get(); }
 
diff --git a/chrome/browser/policy/schema_registry_service_factory.h b/chrome/browser/policy/schema_registry_service_factory.h
index a4be07d..4b33df9e 100644
--- a/chrome/browser/policy/schema_registry_service_factory.h
+++ b/chrome/browser/policy/schema_registry_service_factory.h
@@ -48,7 +48,7 @@
   friend struct DefaultSingletonTraits<SchemaRegistryServiceFactory>;
 
   SchemaRegistryServiceFactory();
-  virtual ~SchemaRegistryServiceFactory();
+  ~SchemaRegistryServiceFactory() override;
 
   SchemaRegistryService* GetForContextInternal(
       content::BrowserContext* context);
@@ -59,14 +59,11 @@
       CombinedSchemaRegistry* global_registry);
 
   // BrowserContextKeyedBaseFactory:
-  virtual void BrowserContextShutdown(
-      content::BrowserContext* context) override;
-  virtual void BrowserContextDestroyed(
-      content::BrowserContext* context) override;
-  virtual void SetEmptyTestingFactory(
-      content::BrowserContext* context) override;
-  virtual bool HasTestingFactory(content::BrowserContext* context) override;
-  virtual void CreateServiceNow(content::BrowserContext* context) override;
+  void BrowserContextShutdown(content::BrowserContext* context) override;
+  void BrowserContextDestroyed(content::BrowserContext* context) override;
+  void SetEmptyTestingFactory(content::BrowserContext* context) override;
+  bool HasTestingFactory(content::BrowserContext* context) override;
+  void CreateServiceNow(content::BrowserContext* context) override;
 
   typedef std::map<content::BrowserContext*, SchemaRegistryService*>
       RegistryMap;
diff --git a/chrome/browser/policy/test/bootstrap_deps b/chrome/browser/policy/test/bootstrap_deps
new file mode 100644
index 0000000..fe1511f3
--- /dev/null
+++ b/chrome/browser/policy/test/bootstrap_deps
@@ -0,0 +1,20 @@
+# 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.
+
+deps = {
+    "src/chrome/browser/policy/test":
+        "https://src.chromium.org/chrome/trunk/src/chrome/browser/policy/test",
+    "src/net/tools/testserver":
+        "https://src.chromium.org/chrome/trunk/src/net/tools/testserver",
+    "src/third_party/tlslite/tlslite":
+        "https://src.chromium.org/chrome/trunk/src/third_party/tlslite/tlslite",
+    "src/third_party/protobuf/python/google":
+        "https://src.chromium.org/chrome/trunk/src/third_party/protobuf/python/google",
+}
+
+# Also include telemetry deps.
+deps_includes = {
+    "src/tools/telemetry/bootstrap_deps":
+        "https://src.chromium.org/chrome/trunk/src/tools/telemetry/bootstrap_deps",
+}
diff --git a/chrome/browser/policy/test/local_policy_test_server.h b/chrome/browser/policy/test/local_policy_test_server.h
index 8e2838a..a8e04aa 100644
--- a/chrome/browser/policy/test/local_policy_test_server.h
+++ b/chrome/browser/policy/test/local_policy_test_server.h
@@ -36,7 +36,7 @@
   // chrome/test/data/policy/policy_|test_name|.json.
   explicit LocalPolicyTestServer(const std::string& test_name);
 
-  virtual ~LocalPolicyTestServer();
+  ~LocalPolicyTestServer() override;
 
   // Sets the policy signing key and verification signature used by the server.
   // This must be called before starting the server, and only works when the
@@ -80,10 +80,9 @@
   GURL GetServiceURL() const;
 
   // net::LocalTestServer:
-  virtual bool SetPythonPath() const override;
-  virtual bool GetTestServerPath(
-      base::FilePath* testserver_path) const override;
-  virtual bool GenerateAdditionalArguments(
+  bool SetPythonPath() const override;
+  bool GetTestServerPath(base::FilePath* testserver_path) const override;
+  bool GenerateAdditionalArguments(
       base::DictionaryValue* arguments) const override;
 
  private:
diff --git a/chrome/browser/policy/url_blacklist_manager_unittest.cc b/chrome/browser/policy/url_blacklist_manager_unittest.cc
index 3d521b6..83d7324 100644
--- a/chrome/browser/policy/url_blacklist_manager_unittest.cc
+++ b/chrome/browser/policy/url_blacklist_manager_unittest.cc
@@ -51,8 +51,7 @@
         update_called_(0),
         set_blacklist_called_(false) {}
 
-  virtual ~TestingURLBlacklistManager() {
-  }
+  ~TestingURLBlacklistManager() override {}
 
   // Make this method public for testing.
   using URLBlacklistManager::ScheduleUpdate;
@@ -66,12 +65,12 @@
   }
 
   // URLBlacklistManager overrides:
-  virtual void SetBlacklist(scoped_ptr<URLBlacklist> blacklist) override {
+  void SetBlacklist(scoped_ptr<URLBlacklist> blacklist) override {
     set_blacklist_called_ = true;
     URLBlacklistManager::SetBlacklist(blacklist.Pass());
   }
 
-  virtual void Update() override {
+  void Update() override {
     update_called_++;
     URLBlacklistManager::Update();
   }
diff --git a/chrome/browser/predictors/resource_prefetch_common_unittest.cc b/chrome/browser/predictors/resource_prefetch_common_unittest.cc
index 74033fb80..61089d61 100644
--- a/chrome/browser/predictors/resource_prefetch_common_unittest.cc
+++ b/chrome/browser/predictors/resource_prefetch_common_unittest.cc
@@ -27,14 +27,14 @@
 
 class MockNetworkChangeNotifierWIFI : public NetworkChangeNotifier {
  public:
-  ConnectionType GetCurrentConnectionType() const OVERRIDE {
+  ConnectionType GetCurrentConnectionType() const override {
     return NetworkChangeNotifier::CONNECTION_WIFI;
   }
 };
 
 class MockNetworkChangeNotifier4G : public NetworkChangeNotifier {
  public:
-  ConnectionType GetCurrentConnectionType() const OVERRIDE {
+  ConnectionType GetCurrentConnectionType() const override {
     return NetworkChangeNotifier::CONNECTION_4G;
   }
 };
@@ -46,7 +46,7 @@
 class ResourcePrefetchCommonTest : public testing::Test {
  public:
   ResourcePrefetchCommonTest();
-  virtual void SetUp() OVERRIDE;
+  void SetUp() override;
 
   void CreateTestFieldTrial(const std::string& name,
                             const std::string& group_name) {
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index fd84b269..874b3ef 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -687,7 +687,10 @@
   migrated |= !host_zoom_dictionary->empty();
   UMA_HISTOGRAM_BOOLEAN("Settings.ZoomLevelPreferencesMigrated", migrated);
 
-  zoom_level_prefs->ExtractPerHostZoomLevels(host_zoom_dictionary);
+  // Since |host_zoom_dictionary| is not partition-based, do not attempt to
+  // sanitize it.
+  zoom_level_prefs->ExtractPerHostZoomLevels(
+      host_zoom_dictionary, false /* sanitize_partition_host_zoom_levels */);
 
   // We're done migrating the profile per-host zoom level values, so we clear
   // them all.
diff --git a/chrome/browser/prefs/browser_ui_prefs_migrator.h b/chrome/browser/prefs/browser_ui_prefs_migrator.h
index 9c8aec3..7094aca 100644
--- a/chrome/browser/prefs/browser_ui_prefs_migrator.h
+++ b/chrome/browser/prefs/browser_ui_prefs_migrator.h
@@ -24,13 +24,13 @@
   explicit BrowserUIPrefsMigrator(WriteablePrefStore* pref_store);
 
   // Overrides from PrefStore::Observer.
-  virtual void OnPrefValueChanged(const std::string& key) override {}
-  virtual void OnInitializationCompleted(bool succeeded) override;
+  void OnPrefValueChanged(const std::string& key) override {}
+  void OnInitializationCompleted(bool succeeded) override;
 
  private:
   friend struct base::DefaultDeleter<BrowserUIPrefsMigrator>;
 
-  virtual ~BrowserUIPrefsMigrator();
+  ~BrowserUIPrefsMigrator() override;
 
   WriteablePrefStore* pref_store_;
 
diff --git a/chrome/browser/prefs/browser_ui_prefs_migrator_unittest.cc b/chrome/browser/prefs/browser_ui_prefs_migrator_unittest.cc
index 811235ac..575fcea3 100644
--- a/chrome/browser/prefs/browser_ui_prefs_migrator_unittest.cc
+++ b/chrome/browser/prefs/browser_ui_prefs_migrator_unittest.cc
@@ -17,40 +17,38 @@
   DictionaryPrefStore() : WriteablePrefStore() {}
 
   // Overrides from PrefStore.
-  virtual void AddObserver(Observer* observer) override {
+  void AddObserver(Observer* observer) override {
     observers_.AddObserver(observer);
   }
 
-  virtual void RemoveObserver(Observer* observer) override {
+  void RemoveObserver(Observer* observer) override {
     observers_.RemoveObserver(observer);
   }
 
-  virtual bool GetValue(const std::string& key,
-                        const base::Value** result) const override {
+  bool GetValue(const std::string& key,
+                const base::Value** result) const override {
     return prefs_.Get(key, result);
   }
 
   // Overrides from WriteablePrefStore.
-  virtual void SetValue(const std::string& key, base::Value* value) override {
+  void SetValue(const std::string& key, base::Value* value) override {
     DCHECK(value);
     prefs_.Set(key, value);
     ReportValueChanged(key);
   }
 
-  virtual void RemoveValue(const std::string& key) override {
+  void RemoveValue(const std::string& key) override {
     if (prefs_.RemovePath(key, NULL))
       ReportValueChanged(key);
   }
 
-  virtual bool GetMutableValue(const std::string& key,
-                               base::Value** result) override {
+  bool GetMutableValue(const std::string& key, base::Value** result) override {
     return prefs_.Get(key, result);
   }
 
-  virtual void ReportValueChanged(const std::string& key) override {}
+  void ReportValueChanged(const std::string& key) override {}
 
-  virtual void SetValueSilently(const std::string& key,
-                                base::Value* value) override {
+  void SetValueSilently(const std::string& key, base::Value* value) override {
     NOTIMPLEMENTED();
   }
 
@@ -60,7 +58,7 @@
   }
 
  private:
-  virtual ~DictionaryPrefStore() {}
+  ~DictionaryPrefStore() override {}
 
   base::DictionaryValue prefs_;
   ObserverList<PrefStore::Observer, true> observers_;
diff --git a/chrome/browser/prefs/command_line_pref_store.h b/chrome/browser/prefs/command_line_pref_store.h
index e614c8e..a9b93829 100644
--- a/chrome/browser/prefs/command_line_pref_store.h
+++ b/chrome/browser/prefs/command_line_pref_store.h
@@ -17,7 +17,7 @@
   explicit CommandLinePrefStore(const base::CommandLine* command_line);
 
  protected:
-  virtual ~CommandLinePrefStore();
+  ~CommandLinePrefStore() override;
 
   // Logs a message and returns false if the proxy switches are
   // self-contradictory. Protected so it can be used in unit testing.
diff --git a/chrome/browser/prefs/command_line_pref_store_unittest.cc b/chrome/browser/prefs/command_line_pref_store_unittest.cc
index cd5ad93..c4d2490 100644
--- a/chrome/browser/prefs/command_line_pref_store_unittest.cc
+++ b/chrome/browser/prefs/command_line_pref_store_unittest.cc
@@ -59,7 +59,7 @@
   }
 
  private:
-  virtual ~TestCommandLinePrefStore() {}
+  ~TestCommandLinePrefStore() override {}
 };
 
 // Tests a simple string pref on the command line.
diff --git a/chrome/browser/prefs/leveldb_pref_store.h b/chrome/browser/prefs/leveldb_pref_store.h
index 0f74127..0b6b052 100644
--- a/chrome/browser/prefs/leveldb_pref_store.h
+++ b/chrome/browser/prefs/leveldb_pref_store.h
@@ -37,33 +37,31 @@
                    base::SequencedTaskRunner* sequenced_task_runner);
 
   // PrefStore overrides:
-  virtual bool GetValue(const std::string& key,
-                        const base::Value** result) const override;
-  virtual void AddObserver(PrefStore::Observer* observer) override;
-  virtual void RemoveObserver(PrefStore::Observer* observer) override;
-  virtual bool HasObservers() const override;
-  virtual bool IsInitializationComplete() const override;
+  bool GetValue(const std::string& key,
+                const base::Value** result) const override;
+  void AddObserver(PrefStore::Observer* observer) override;
+  void RemoveObserver(PrefStore::Observer* observer) override;
+  bool HasObservers() const override;
+  bool IsInitializationComplete() const override;
 
   // PersistentPrefStore overrides:
-  virtual bool GetMutableValue(const std::string& key,
-                               base::Value** result) override;
+  bool GetMutableValue(const std::string& key, base::Value** result) override;
   // Takes ownership of value.
-  virtual void SetValue(const std::string& key, base::Value* value) override;
-  virtual void SetValueSilently(const std::string& key,
-                                base::Value* value) override;
-  virtual void RemoveValue(const std::string& key) override;
-  virtual bool ReadOnly() const override;
-  virtual PrefReadError GetReadError() const override;
-  virtual PrefReadError ReadPrefs() override;
-  virtual void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override;
-  virtual void CommitPendingWrite() override;
-  virtual void ReportValueChanged(const std::string& key) override;
+  void SetValue(const std::string& key, base::Value* value) override;
+  void SetValueSilently(const std::string& key, base::Value* value) override;
+  void RemoveValue(const std::string& key) override;
+  bool ReadOnly() const override;
+  PrefReadError GetReadError() const override;
+  PrefReadError ReadPrefs() override;
+  void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override;
+  void CommitPendingWrite() override;
+  void ReportValueChanged(const std::string& key) override;
 
  private:
   struct ReadingResults;
   class FileThreadSerializer;
 
-  virtual ~LevelDBPrefStore();
+  ~LevelDBPrefStore() override;
 
   static scoped_ptr<ReadingResults> DoReading(const base::FilePath& path);
   static void OpenDB(const base::FilePath& path,
diff --git a/chrome/browser/prefs/pref_metrics_service.h b/chrome/browser/prefs/pref_metrics_service.h
index 2b6c67e1..0335817d 100644
--- a/chrome/browser/prefs/pref_metrics_service.h
+++ b/chrome/browser/prefs/pref_metrics_service.h
@@ -23,7 +23,7 @@
 class PrefMetricsService : public KeyedService {
  public:
   explicit PrefMetricsService(Profile* profile);
-  virtual ~PrefMetricsService();
+  ~PrefMetricsService() override;
 
   class Factory : public BrowserContextKeyedServiceFactory {
    public:
@@ -33,14 +33,14 @@
     friend struct DefaultSingletonTraits<Factory>;
 
     Factory();
-    virtual ~Factory();
+    ~Factory() override;
 
     // BrowserContextKeyedServiceFactory implementation
-    virtual KeyedService* BuildServiceInstanceFor(
+    KeyedService* BuildServiceInstanceFor(
         content::BrowserContext* profile) const override;
-    virtual bool ServiceIsCreatedWithBrowserContext() const override;
-    virtual bool ServiceIsNULLWhileTesting() const override;
-    virtual content::BrowserContext* GetBrowserContextToUse(
+    bool ServiceIsCreatedWithBrowserContext() const override;
+    bool ServiceIsNULLWhileTesting() const override;
+    content::BrowserContext* GetBrowserContextToUse(
         content::BrowserContext* context) const override;
   };
 
diff --git a/chrome/browser/prefs/pref_model_associator.h b/chrome/browser/prefs/pref_model_associator.h
index 2c20f040..4e72722 100644
--- a/chrome/browser/prefs/pref_model_associator.h
+++ b/chrome/browser/prefs/pref_model_associator.h
@@ -38,23 +38,22 @@
       public base::NonThreadSafe {
  public:
   explicit PrefModelAssociator(syncer::ModelType type);
-  virtual ~PrefModelAssociator();
+  ~PrefModelAssociator() override;
 
   // See description above field for details.
   bool models_associated() const { return models_associated_; }
 
   // syncer::SyncableService implementation.
-  virtual syncer::SyncDataList GetAllSyncData(
-      syncer::ModelType type) const override;
-  virtual syncer::SyncError ProcessSyncChanges(
+  syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override;
+  syncer::SyncError ProcessSyncChanges(
       const tracked_objects::Location& from_here,
       const syncer::SyncChangeList& change_list) override;
-  virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
+  syncer::SyncMergeResult MergeDataAndStartSyncing(
       syncer::ModelType type,
       const syncer::SyncDataList& initial_sync_data,
       scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
       scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) override;
-  virtual void StopSyncing(syncer::ModelType type) override;
+  void StopSyncing(syncer::ModelType type) override;
 
   // Returns the list of preference names that are registered as syncable, and
   // hence should be monitored for changes.
diff --git a/chrome/browser/prefs/pref_service_browsertest.cc b/chrome/browser/prefs/pref_service_browsertest.cc
index 72be947f..c8134be 100644
--- a/chrome/browser/prefs/pref_service_browsertest.cc
+++ b/chrome/browser/prefs/pref_service_browsertest.cc
@@ -54,7 +54,7 @@
   explicit PreferenceServiceTest(bool new_profile) : new_profile_(new_profile) {
   }
 
-  virtual bool SetUpUserDataDirectory() override {
+  bool SetUpUserDataDirectory() override {
     base::FilePath user_data_directory;
     PathService::Get(chrome::DIR_USER_DATA, &user_data_directory);
 
diff --git a/chrome/browser/prefs/pref_service_mock_factory.h b/chrome/browser/prefs/pref_service_mock_factory.h
index 44617e89..ab9bc26 100644
--- a/chrome/browser/prefs/pref_service_mock_factory.h
+++ b/chrome/browser/prefs/pref_service_mock_factory.h
@@ -11,7 +11,7 @@
 class PrefServiceMockFactory : public PrefServiceSyncableFactory {
  public:
   PrefServiceMockFactory();
-  virtual ~PrefServiceMockFactory();
+  ~PrefServiceMockFactory() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PrefServiceMockFactory);
diff --git a/chrome/browser/prefs/pref_service_syncable.h b/chrome/browser/prefs/pref_service_syncable.h
index fd799b3..c1b4960 100644
--- a/chrome/browser/prefs/pref_service_syncable.h
+++ b/chrome/browser/prefs/pref_service_syncable.h
@@ -44,7 +44,7 @@
       base::Callback<void(PersistentPrefStore::PrefReadError)>
           read_error_callback,
       bool async);
-  virtual ~PrefServiceSyncable();
+  ~PrefServiceSyncable() override;
 
   // Creates an incognito copy of the pref service that shares most pref stores
   // but uses a fresh non-persistent overlay for the user pref store and an
@@ -79,7 +79,7 @@
   syncer::SyncableService* GetSyncableService(const syncer::ModelType& type);
 
   // Do not call this after having derived an incognito or per tab pref service.
-  virtual void UpdateCommandLinePrefStore(PrefStore* cmd_line_store) override;
+  void UpdateCommandLinePrefStore(PrefStore* cmd_line_store) override;
 
   void AddSyncedPrefObserver(const std::string& name,
                              SyncedPrefObserver* observer);
diff --git a/chrome/browser/prefs/pref_service_syncable_factory.h b/chrome/browser/prefs/pref_service_syncable_factory.h
index b3d326c..ff57059a5 100644
--- a/chrome/browser/prefs/pref_service_syncable_factory.h
+++ b/chrome/browser/prefs/pref_service_syncable_factory.h
@@ -27,7 +27,7 @@
 class PrefServiceSyncableFactory : public base::PrefServiceFactory {
  public:
   PrefServiceSyncableFactory();
-  virtual ~PrefServiceSyncableFactory();
+  ~PrefServiceSyncableFactory() override;
 
 #if defined(ENABLE_CONFIGURATION_POLICY)
   // Set up policy pref stores using the given policy service.
diff --git a/chrome/browser/prefs/prefs_syncable_service_unittest.cc b/chrome/browser/prefs/prefs_syncable_service_unittest.cc
index 2f20316..462c46d1 100644
--- a/chrome/browser/prefs/prefs_syncable_service_unittest.cc
+++ b/chrome/browser/prefs/prefs_syncable_service_unittest.cc
@@ -40,7 +40,7 @@
  public:
   explicit TestSyncProcessorStub(syncer::SyncChangeList* output)
       : output_(output), fail_next_(false) {}
-  virtual syncer::SyncError ProcessSyncChanges(
+  syncer::SyncError ProcessSyncChanges(
       const tracked_objects::Location& from_here,
       const syncer::SyncChangeList& change_list) override {
     if (output_)
@@ -58,8 +58,7 @@
     fail_next_ = true;
   }
 
-  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
-      const override {
+  syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override {
     return syncer::SyncDataList();
   }
  private:
diff --git a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
index a552d86..bc9d983 100644
--- a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
+++ b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
@@ -51,7 +51,7 @@
       : pref_registry_(pref_registry) {}
 
   // PrefStore::Observer implementation
-  virtual void OnPrefValueChanged(const std::string& key) override {
+  void OnPrefValueChanged(const std::string& key) override {
     EXPECT_TRUE(pref_registry_->end() !=
                 std::find_if(pref_registry_->begin(),
                              pref_registry_->end(),
@@ -59,7 +59,7 @@
         << "Unregistered key " << key << " was changed.";
   }
 
-  virtual void OnInitializationCompleted(bool succeeded) override {}
+  void OnInitializationCompleted(bool succeeded) override {}
 
  private:
   scoped_refptr<PrefRegistry> pref_registry_;
diff --git a/chrome/browser/prefs/synced_pref_change_registrar.h b/chrome/browser/prefs/synced_pref_change_registrar.h
index 8acc1e7..66d6bc5e 100644
--- a/chrome/browser/prefs/synced_pref_change_registrar.h
+++ b/chrome/browser/prefs/synced_pref_change_registrar.h
@@ -43,8 +43,7 @@
 
  private:
   // SyncedPrefObserver implementation
-  virtual void OnSyncedPrefChanged(const std::string& path, bool from_sync)
-      override;
+  void OnSyncedPrefChanged(const std::string& path, bool from_sync) override;
 
   typedef std::map<std::string, NamedChangeCallback> ObserverMap;
 
diff --git a/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc b/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc
index 939aff40..f99ea75 100644
--- a/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc
+++ b/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc
@@ -94,7 +94,7 @@
 
  private:
 #if defined(ENABLE_CONFIGURATION_POLICY)
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     EXPECT_CALL(policy_provider_, IsInitializationComplete(_))
         .WillRepeatedly(Return(true));
     policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
@@ -102,7 +102,7 @@
   }
 #endif
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     prefs_ = PrefServiceSyncable::FromProfile(browser()->profile());
     syncer_ = prefs_->GetSyncableService(syncer::PREFERENCES);
     syncer_->MergeDataAndStartSyncing(
@@ -114,9 +114,7 @@
     registrar_.reset(new SyncedPrefChangeRegistrar(prefs_));
   }
 
-  virtual void TearDownOnMainThread() override {
-    registrar_.reset();
-  }
+  void TearDownOnMainThread() override { registrar_.reset(); }
 
   PrefServiceSyncable* prefs_;
   syncer::SyncableService* syncer_;
diff --git a/chrome/browser/prefs/tracked/dictionary_hash_store_contents.cc b/chrome/browser/prefs/tracked/dictionary_hash_store_contents.cc
index 50cc479..7b6f542 100644
--- a/chrome/browser/prefs/tracked/dictionary_hash_store_contents.cc
+++ b/chrome/browser/prefs/tracked/dictionary_hash_store_contents.cc
@@ -21,7 +21,7 @@
   explicit MutablePreferenceMacDictionary(base::DictionaryValue* storage);
 
   // MutableDictionary implementation
-  virtual base::DictionaryValue* operator->() override;
+  base::DictionaryValue* operator->() override;
 
  private:
   base::DictionaryValue* storage_;
diff --git a/chrome/browser/prefs/tracked/dictionary_hash_store_contents.h b/chrome/browser/prefs/tracked/dictionary_hash_store_contents.h
index f3317c89..fc29db59 100644
--- a/chrome/browser/prefs/tracked/dictionary_hash_store_contents.h
+++ b/chrome/browser/prefs/tracked/dictionary_hash_store_contents.h
@@ -31,13 +31,13 @@
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // HashStoreContents implementation
-  virtual std::string hash_store_id() const override;
-  virtual void Reset() override;
-  virtual bool IsInitialized() const override;
-  virtual const base::DictionaryValue* GetContents() const override;
-  virtual scoped_ptr<MutableDictionary> GetMutableContents() override;
-  virtual std::string GetSuperMac() const override;
-  virtual void SetSuperMac(const std::string& super_mac) override;
+  std::string hash_store_id() const override;
+  void Reset() override;
+  bool IsInitialized() const override;
+  const base::DictionaryValue* GetContents() const override;
+  scoped_ptr<MutableDictionary> GetMutableContents() override;
+  std::string GetSuperMac() const override;
+  void SetSuperMac(const std::string& super_mac) override;
 
  private:
   base::DictionaryValue* storage_;
diff --git a/chrome/browser/prefs/tracked/interceptable_pref_filter.h b/chrome/browser/prefs/tracked/interceptable_pref_filter.h
index 3a70ab3c..aacbfc7 100644
--- a/chrome/browser/prefs/tracked/interceptable_pref_filter.h
+++ b/chrome/browser/prefs/tracked/interceptable_pref_filter.h
@@ -33,10 +33,10 @@
            scoped_ptr<base::DictionaryValue> prefs)> FilterOnLoadInterceptor;
 
   InterceptablePrefFilter();
-  virtual ~InterceptablePrefFilter();
+  ~InterceptablePrefFilter() override;
 
   // PrefFilter partial implementation.
-  virtual void FilterOnLoad(
+  void FilterOnLoad(
       const PostFilterOnLoadCallback& post_filter_on_load_callback,
       scoped_ptr<base::DictionaryValue> pref_store_contents) override;
 
diff --git a/chrome/browser/prefs/tracked/mock_validation_delegate.h b/chrome/browser/prefs/tracked/mock_validation_delegate.h
index e5725082..7fbb204 100644
--- a/chrome/browser/prefs/tracked/mock_validation_delegate.h
+++ b/chrome/browser/prefs/tracked/mock_validation_delegate.h
@@ -35,7 +35,7 @@
   };
 
   MockValidationDelegate();
-  virtual ~MockValidationDelegate();
+  ~MockValidationDelegate() override;
 
   // Returns the number of recorded validations.
   size_t recorded_validations_count() const { return validations_.size(); }
@@ -48,12 +48,12 @@
   const ValidationEvent* GetEventForPath(const std::string& pref_path) const;
 
   // TrackedPreferenceValidationDelegate implementation.
-  virtual void OnAtomicPreferenceValidation(
+  void OnAtomicPreferenceValidation(
       const std::string& pref_path,
       const base::Value* value,
       PrefHashStoreTransaction::ValueState value_state,
       TrackedPreferenceHelper::ResetAction reset_action) override;
-  virtual void OnSplitPreferenceValidation(
+  void OnSplitPreferenceValidation(
       const std::string& pref_path,
       const base::DictionaryValue* dict_value,
       const std::vector<std::string>& invalid_keys,
diff --git a/chrome/browser/prefs/tracked/pref_hash_browsertest.cc b/chrome/browser/prefs/tracked/pref_hash_browsertest.cc
index 155ce31..d60b998 100644
--- a/chrome/browser/prefs/tracked/pref_hash_browsertest.cc
+++ b/chrome/browser/prefs/tracked/pref_hash_browsertest.cc
@@ -147,7 +147,7 @@
       : protection_level_(GetProtectionLevelFromTrialGroup(GetParam())) {
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     ExtensionBrowserTest::SetUpCommandLine(command_line);
     EXPECT_FALSE(command_line->HasSwitch(switches::kForceFieldTrials));
     command_line->AppendSwitchASCII(
@@ -160,7 +160,7 @@
 #endif
   }
 
-  virtual bool SetUpUserDataDirectory() override {
+  bool SetUpUserDataDirectory() override {
     // Do the normal setup in the PRE test and attack preferences in the main
     // test.
     if (IsPRETest())
@@ -231,7 +231,7 @@
   // In the PRE_ test, find the number of tracked preferences that were
   // initialized and save it to a file to be read back in the main test and used
   // as the total number of tracked preferences.
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     ExtensionBrowserTest::SetUpOnMainThread();
 
     // File in which the PRE_ test will save the number of tracked preferences
@@ -354,17 +354,17 @@
 // Also sanity checks that the expected preferences files are in place.
 class PrefHashBrowserTestUnchangedDefault : public PrefHashBrowserTestBase {
  public:
-  virtual void SetupPreferences() override {
+  void SetupPreferences() override {
     // Default Chrome setup.
   }
 
-  virtual void AttackPreferencesOnDisk(
+  void AttackPreferencesOnDisk(
       base::DictionaryValue* unprotected_preferences,
       base::DictionaryValue* protected_preferences) override {
     // No attack.
   }
 
-  virtual void VerifyReactionToPrefAttack() override {
+  void VerifyReactionToPrefAttack() override {
     // Expect all prefs to be reported as Unchanged with no resets.
     EXPECT_EQ(protection_level_ > PROTECTION_DISABLED_ON_PLATFORM
                   ? num_tracked_prefs() : 0,
@@ -408,14 +408,14 @@
 class PrefHashBrowserTestUnchangedCustom
     : public PrefHashBrowserTestUnchangedDefault {
  public:
-  virtual void SetupPreferences() override {
+  void SetupPreferences() override {
     profile()->GetPrefs()->SetString(prefs::kHomePage, "http://example.com");
 
     InstallExtensionWithUIAutoConfirm(
         test_data_dir_.AppendASCII("good.crx"), 1, browser());
   }
 
-  virtual void VerifyReactionToPrefAttack() override {
+  void VerifyReactionToPrefAttack() override {
     // Make sure the settings written in the last run stuck.
     EXPECT_EQ("http://example.com",
               profile()->GetPrefs()->GetString(prefs::kHomePage));
@@ -432,11 +432,11 @@
 // Verifies that cleared prefs are reported.
 class PrefHashBrowserTestClearedAtomic : public PrefHashBrowserTestBase {
  public:
-  virtual void SetupPreferences() override {
+  void SetupPreferences() override {
     profile()->GetPrefs()->SetString(prefs::kHomePage, "http://example.com");
   }
 
-  virtual void AttackPreferencesOnDisk(
+  void AttackPreferencesOnDisk(
       base::DictionaryValue* unprotected_preferences,
       base::DictionaryValue* protected_preferences) override {
     base::DictionaryValue* selected_prefs =
@@ -448,7 +448,7 @@
     EXPECT_TRUE(selected_prefs->Remove(prefs::kHomePage, NULL));
   }
 
-  virtual void VerifyReactionToPrefAttack() override {
+  void VerifyReactionToPrefAttack() override {
     // The clearance of homepage should have been noticed (as pref #2 being
     // cleared), but shouldn't have triggered a reset (as there is nothing we
     // can do when the pref is already gone).
@@ -492,7 +492,7 @@
 // non-null protected prefs.
 class PrefHashBrowserTestUntrustedInitialized : public PrefHashBrowserTestBase {
  public:
-  virtual void SetupPreferences() override {
+  void SetupPreferences() override {
     // Explicitly set the DSE (it's otherwise NULL by default, preventing
     // thorough testing of the PROTECTION_ENABLED_DSE level).
     DefaultSearchManager default_search_manager(
@@ -516,7 +516,7 @@
                                       SessionStartupPref::URLS);
   }
 
-  virtual void AttackPreferencesOnDisk(
+  void AttackPreferencesOnDisk(
       base::DictionaryValue* unprotected_preferences,
       base::DictionaryValue* protected_preferences) override {
     EXPECT_TRUE(unprotected_preferences->Remove("protection.macs", NULL));
@@ -524,7 +524,7 @@
       EXPECT_TRUE(protected_preferences->Remove("protection.macs", NULL));
   }
 
-  virtual void VerifyReactionToPrefAttack() override {
+  void VerifyReactionToPrefAttack() override {
     // Preferences that are NULL by default will be NullInitialized.
     int num_null_values = GetTrackedPrefHistogramCount(
         "Settings.TrackedPreferenceNullInitialized", ALLOW_ANY);
@@ -613,7 +613,7 @@
 // if the protection level allows it).
 class PrefHashBrowserTestChangedAtomic : public PrefHashBrowserTestBase {
  public:
-  virtual void SetupPreferences() override {
+  void SetupPreferences() override {
     profile()->GetPrefs()->SetInteger(prefs::kRestoreOnStartup,
                                       SessionStartupPref::URLS);
 
@@ -622,7 +622,7 @@
     update->AppendString("http://example.com");
   }
 
-  virtual void AttackPreferencesOnDisk(
+  void AttackPreferencesOnDisk(
       base::DictionaryValue* unprotected_preferences,
       base::DictionaryValue* protected_preferences) override {
     base::DictionaryValue* selected_prefs =
@@ -639,7 +639,7 @@
     startup_urls->AppendString("http://example.org");
   }
 
-  virtual void VerifyReactionToPrefAttack() override {
+  void VerifyReactionToPrefAttack() override {
     // Expect a single Changed event for tracked pref #4 (startup URLs).
     EXPECT_EQ(protection_level_ > PROTECTION_DISABLED_ON_PLATFORM ? 1 : 0,
               GetTrackedPrefHistogramCount("Settings.TrackedPreferenceChanged",
@@ -695,12 +695,12 @@
 // items being reported (and remove if the protection level allows it).
 class PrefHashBrowserTestChangedSplitPref : public PrefHashBrowserTestBase {
  public:
-  virtual void SetupPreferences() override {
+  void SetupPreferences() override {
     InstallExtensionWithUIAutoConfirm(
         test_data_dir_.AppendASCII("good.crx"), 1, browser());
   }
 
-  virtual void AttackPreferencesOnDisk(
+  void AttackPreferencesOnDisk(
       base::DictionaryValue* unprotected_preferences,
       base::DictionaryValue* protected_preferences) override {
     base::DictionaryValue* selected_prefs =
@@ -730,7 +730,7 @@
     extensions_dict->Set(std::string(32, 'a'), fake_extension);
   }
 
-  virtual void VerifyReactionToPrefAttack() override {
+  void VerifyReactionToPrefAttack() override {
     // Expect a single split pref changed report with a count of 2 for tracked
     // pref #5 (extensions).
     EXPECT_EQ(protection_level_ > PROTECTION_DISABLED_ON_PLATFORM ? 1 : 0,
@@ -788,20 +788,20 @@
 class PrefHashBrowserTestUntrustedAdditionToPrefs
     : public PrefHashBrowserTestBase {
  public:
-  virtual void SetupPreferences() override {
+  void SetupPreferences() override {
     // Ensure there is no user-selected value for kRestoreOnStartup.
     EXPECT_FALSE(
         profile()->GetPrefs()->GetUserPrefValue(prefs::kRestoreOnStartup));
   }
 
-  virtual void AttackPreferencesOnDisk(
+  void AttackPreferencesOnDisk(
       base::DictionaryValue* unprotected_preferences,
       base::DictionaryValue* protected_preferences) override {
     unprotected_preferences->SetInteger(prefs::kRestoreOnStartup,
                                         SessionStartupPref::LAST);
   }
 
-  virtual void VerifyReactionToPrefAttack() override {
+  void VerifyReactionToPrefAttack() override {
     // Expect a single Changed event for tracked pref #3 (kRestoreOnStartup) if
     // not protecting; if protection is enabled the change should be a no-op.
     int changed_expected =
@@ -854,11 +854,11 @@
 class PrefHashBrowserTestUntrustedAdditionToPrefsAfterWipe
     : public PrefHashBrowserTestBase {
  public:
-  virtual void SetupPreferences() override {
+  void SetupPreferences() override {
     profile()->GetPrefs()->SetString(prefs::kHomePage, "http://example.com");
   }
 
-  virtual void AttackPreferencesOnDisk(
+  void AttackPreferencesOnDisk(
       base::DictionaryValue* unprotected_preferences,
       base::DictionaryValue* protected_preferences) override {
     // Set or change the value in Preferences to the attacker's choice.
@@ -868,7 +868,7 @@
       protected_preferences->Remove(prefs::kHomePage, NULL);
   }
 
-  virtual void VerifyReactionToPrefAttack() override {
+  void VerifyReactionToPrefAttack() override {
     // Expect a single Changed event for tracked pref #2 (kHomePage) if
     // not protecting; if protection is enabled the change should be a Cleared.
     int changed_expected =
diff --git a/chrome/browser/prefs/tracked/pref_hash_filter.h b/chrome/browser/prefs/tracked/pref_hash_filter.h
index 1c1a3c89..669f327 100644
--- a/chrome/browser/prefs/tracked/pref_hash_filter.h
+++ b/chrome/browser/prefs/tracked/pref_hash_filter.h
@@ -75,7 +75,7 @@
       size_t reporting_ids_count,
       bool report_super_mac_validity);
 
-  virtual ~PrefHashFilter();
+  ~PrefHashFilter() override;
 
   // Registers required user preferences.
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
@@ -94,13 +94,12 @@
   void Initialize(base::DictionaryValue* pref_store_contents);
 
   // PrefFilter remaining implementation.
-  virtual void FilterUpdate(const std::string& path) override;
-  virtual void FilterSerializeData(
-      base::DictionaryValue* pref_store_contents) override;
+  void FilterUpdate(const std::string& path) override;
+  void FilterSerializeData(base::DictionaryValue* pref_store_contents) override;
 
  private:
   // InterceptablePrefFilter implementation.
-  virtual void FinalizeFilterOnLoad(
+  void FinalizeFilterOnLoad(
       const PostFilterOnLoadCallback& post_filter_on_load_callback,
       scoped_ptr<base::DictionaryValue> pref_store_contents,
       bool prefs_altered) override;
diff --git a/chrome/browser/prefs/tracked/pref_hash_filter_unittest.cc b/chrome/browser/prefs/tracked/pref_hash_filter_unittest.cc
index 25bfb99..3c3e58e 100644
--- a/chrome/browser/prefs/tracked/pref_hash_filter_unittest.cc
+++ b/chrome/browser/prefs/tracked/pref_hash_filter_unittest.cc
@@ -85,9 +85,7 @@
         transactions_performed_(0),
         transaction_active_(false) {}
 
-  virtual ~MockPrefHashStore() {
-    EXPECT_FALSE(transaction_active_);
-  }
+  ~MockPrefHashStore() override { EXPECT_FALSE(transaction_active_); }
 
   // Set the result that will be returned when |path| is passed to
   // |CheckValue/CheckSplitValue|.
@@ -153,7 +151,7 @@
   }
 
   // PrefHashStore implementation.
-  virtual scoped_ptr<PrefHashStoreTransaction> BeginTransaction(
+  scoped_ptr<PrefHashStoreTransaction> BeginTransaction(
       scoped_ptr<HashStoreContents> storage) override;
 
  private:
@@ -166,29 +164,28 @@
     explicit MockPrefHashStoreTransaction(MockPrefHashStore* outer)
         : outer_(outer) {}
 
-    virtual ~MockPrefHashStoreTransaction() {
+    ~MockPrefHashStoreTransaction() override {
       outer_->transaction_active_ = false;
       ++outer_->transactions_performed_;
     }
 
     // PrefHashStoreTransaction implementation.
-    virtual PrefHashStoreTransaction::ValueState CheckValue(
-        const std::string& path, const base::Value* value) const override;
-    virtual void StoreHash(const std::string& path,
-                           const base::Value* new_value) override;
-    virtual PrefHashStoreTransaction::ValueState CheckSplitValue(
+    PrefHashStoreTransaction::ValueState CheckValue(
+        const std::string& path,
+        const base::Value* value) const override;
+    void StoreHash(const std::string& path,
+                   const base::Value* new_value) override;
+    PrefHashStoreTransaction::ValueState CheckSplitValue(
         const std::string& path,
         const base::DictionaryValue* initial_split_value,
         std::vector<std::string>* invalid_keys) const override;
-    virtual void StoreSplitHash(
-        const std::string& path,
-        const base::DictionaryValue* split_value) override;
-    virtual bool HasHash(const std::string& path) const override;
-    virtual void ImportHash(const std::string& path,
-                            const base::Value* hash) override;
-    virtual void ClearHash(const std::string& path) override;
-    virtual bool IsSuperMACValid() const override;
-    virtual bool StampSuperMac() override;
+    void StoreSplitHash(const std::string& path,
+                        const base::DictionaryValue* split_value) override;
+    bool HasHash(const std::string& path) const override;
+    void ImportHash(const std::string& path, const base::Value* hash) override;
+    void ClearHash(const std::string& path) override;
+    bool IsSuperMACValid() const override;
+    bool StampSuperMac() override;
 
    private:
     MockPrefHashStore* outer_;
diff --git a/chrome/browser/prefs/tracked/pref_hash_store_impl.cc b/chrome/browser/prefs/tracked/pref_hash_store_impl.cc
index a99db41..f43e06b1 100644
--- a/chrome/browser/prefs/tracked/pref_hash_store_impl.cc
+++ b/chrome/browser/prefs/tracked/pref_hash_store_impl.cc
@@ -17,26 +17,23 @@
   // members of its |outer| PrefHashStoreImpl.
   PrefHashStoreTransactionImpl(PrefHashStoreImpl* outer,
                                scoped_ptr<HashStoreContents> storage);
-  virtual ~PrefHashStoreTransactionImpl();
+  ~PrefHashStoreTransactionImpl() override;
 
   // PrefHashStoreTransaction implementation.
-  virtual ValueState CheckValue(const std::string& path,
-                                const base::Value* value) const override;
-  virtual void StoreHash(const std::string& path,
-                         const base::Value* value) override;
-  virtual ValueState CheckSplitValue(
+  ValueState CheckValue(const std::string& path,
+                        const base::Value* value) const override;
+  void StoreHash(const std::string& path, const base::Value* value) override;
+  ValueState CheckSplitValue(
       const std::string& path,
       const base::DictionaryValue* initial_split_value,
       std::vector<std::string>* invalid_keys) const override;
-  virtual void StoreSplitHash(
-      const std::string& path,
-      const base::DictionaryValue* split_value) override;
-  virtual bool HasHash(const std::string& path) const override;
-  virtual void ImportHash(const std::string& path,
-                          const base::Value* hash) override;
-  virtual void ClearHash(const std::string& path) override;
-  virtual bool IsSuperMACValid() const override;
-  virtual bool StampSuperMac() override;
+  void StoreSplitHash(const std::string& path,
+                      const base::DictionaryValue* split_value) override;
+  bool HasHash(const std::string& path) const override;
+  void ImportHash(const std::string& path, const base::Value* hash) override;
+  void ClearHash(const std::string& path) override;
+  bool IsSuperMACValid() const override;
+  bool StampSuperMac() override;
 
  private:
   bool GetSplitMacs(const std::string& path,
diff --git a/chrome/browser/prefs/tracked/pref_hash_store_impl.h b/chrome/browser/prefs/tracked/pref_hash_store_impl.h
index 2b4640f..ccef877 100644
--- a/chrome/browser/prefs/tracked/pref_hash_store_impl.h
+++ b/chrome/browser/prefs/tracked/pref_hash_store_impl.h
@@ -39,7 +39,7 @@
                     const std::string& device_id,
                     bool use_super_mac);
 
-  virtual ~PrefHashStoreImpl();
+  ~PrefHashStoreImpl() override;
 
   // Provides an external HashStoreContents implementation to be used.
   // BeginTransaction() will ignore |storage| if this is provided.
@@ -51,7 +51,7 @@
   void Reset();
 
   // PrefHashStore implementation.
-  virtual scoped_ptr<PrefHashStoreTransaction> BeginTransaction(
+  scoped_ptr<PrefHashStoreTransaction> BeginTransaction(
       scoped_ptr<HashStoreContents> storage) override;
 
  private:
diff --git a/chrome/browser/prefs/tracked/pref_service_hash_store_contents.cc b/chrome/browser/prefs/tracked/pref_service_hash_store_contents.cc
index a59eb84..9ab446f 100644
--- a/chrome/browser/prefs/tracked/pref_service_hash_store_contents.cc
+++ b/chrome/browser/prefs/tracked/pref_service_hash_store_contents.cc
@@ -23,7 +23,7 @@
                                PrefService* pref_service);
 
   // HashStoreContents::MutableDictionary implementation
-  virtual base::DictionaryValue* operator->() override;
+  base::DictionaryValue* operator->() override;
 
  private:
   const std::string key_;
diff --git a/chrome/browser/prefs/tracked/pref_service_hash_store_contents.h b/chrome/browser/prefs/tracked/pref_service_hash_store_contents.h
index 851e2ad..5bb6c959 100644
--- a/chrome/browser/prefs/tracked/pref_service_hash_store_contents.h
+++ b/chrome/browser/prefs/tracked/pref_service_hash_store_contents.h
@@ -54,13 +54,13 @@
   static void ResetAllPrefHashStores(PrefService* pref_service);
 
   // HashStoreContents implementation
-  virtual std::string hash_store_id() const override;
-  virtual void Reset() override;
-  virtual bool IsInitialized() const override;
-  virtual const base::DictionaryValue* GetContents() const override;
-  virtual scoped_ptr<MutableDictionary> GetMutableContents() override;
-  virtual std::string GetSuperMac() const override;
-  virtual void SetSuperMac(const std::string& super_mac) override;
+  std::string hash_store_id() const override;
+  void Reset() override;
+  bool IsInitialized() const override;
+  const base::DictionaryValue* GetContents() const override;
+  scoped_ptr<MutableDictionary> GetMutableContents() override;
+  std::string GetSuperMac() const override;
+  void SetSuperMac(const std::string& super_mac) override;
 
  private:
   const std::string hash_store_id_;
diff --git a/chrome/browser/prefs/tracked/segregated_pref_store.h b/chrome/browser/prefs/tracked/segregated_pref_store.h
index aea3a3b..5fe4778 100644
--- a/chrome/browser/prefs/tracked/segregated_pref_store.h
+++ b/chrome/browser/prefs/tracked/segregated_pref_store.h
@@ -44,28 +44,26 @@
       const std::set<std::string>& selected_pref_names);
 
   // PrefStore implementation
-  virtual void AddObserver(Observer* observer) override;
-  virtual void RemoveObserver(Observer* observer) override;
-  virtual bool HasObservers() const override;
-  virtual bool IsInitializationComplete() const override;
-  virtual bool GetValue(const std::string& key,
-                        const base::Value** result) const override;
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
+  bool HasObservers() const override;
+  bool IsInitializationComplete() const override;
+  bool GetValue(const std::string& key,
+                const base::Value** result) const override;
 
   // WriteablePrefStore implementation
-  virtual void SetValue(const std::string& key, base::Value* value) override;
-  virtual void RemoveValue(const std::string& key) override;
+  void SetValue(const std::string& key, base::Value* value) override;
+  void RemoveValue(const std::string& key) override;
 
   // PersistentPrefStore implementation
-  virtual bool GetMutableValue(const std::string& key,
-                               base::Value** result) override;
-  virtual void ReportValueChanged(const std::string& key) override;
-  virtual void SetValueSilently(const std::string& key,
-                                base::Value* value) override;
-  virtual bool ReadOnly() const override;
-  virtual PrefReadError GetReadError() const override;
-  virtual PrefReadError ReadPrefs() override;
-  virtual void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override;
-  virtual void CommitPendingWrite() override;
+  bool GetMutableValue(const std::string& key, base::Value** result) override;
+  void ReportValueChanged(const std::string& key) override;
+  void SetValueSilently(const std::string& key, base::Value* value) override;
+  bool ReadOnly() const override;
+  PrefReadError GetReadError() const override;
+  PrefReadError ReadPrefs() override;
+  void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override;
+  void CommitPendingWrite() override;
 
  private:
   // Aggregates events from the underlying stores and synthesizes external
@@ -75,8 +73,8 @@
     explicit AggregatingObserver(SegregatedPrefStore* outer);
 
     // PrefStore::Observer implementation
-    virtual void OnPrefValueChanged(const std::string& key) override;
-    virtual void OnInitializationCompleted(bool succeeded) override;
+    void OnPrefValueChanged(const std::string& key) override;
+    void OnInitializationCompleted(bool succeeded) override;
 
    private:
     SegregatedPrefStore* outer_;
@@ -86,7 +84,7 @@
     DISALLOW_COPY_AND_ASSIGN(AggregatingObserver);
   };
 
-  virtual ~SegregatedPrefStore();
+  ~SegregatedPrefStore() override;
 
   // Returns |selected_pref_store| if |key| is selected and |default_pref_store|
   // otherwise.
diff --git a/chrome/browser/prefs/tracked/segregated_pref_store_unittest.cc b/chrome/browser/prefs/tracked/segregated_pref_store_unittest.cc
index 182b2eb..693fbfcc 100644
--- a/chrome/browser/prefs/tracked/segregated_pref_store_unittest.cc
+++ b/chrome/browser/prefs/tracked/segregated_pref_store_unittest.cc
@@ -42,7 +42,7 @@
   }
 
   // PersistentPrefStore::ReadErrorDelegate implementation
-  virtual void OnError(PersistentPrefStore::PrefReadError read_error) override {
+  void OnError(PersistentPrefStore::PrefReadError read_error) override {
     EXPECT_FALSE(data_->invoked);
     data_->invoked = true;
     data_->read_error = read_error;
diff --git a/chrome/browser/prefs/tracked/tracked_atomic_preference.h b/chrome/browser/prefs/tracked/tracked_atomic_preference.h
index f3ee9c7..1f9567b 100644
--- a/chrome/browser/prefs/tracked/tracked_atomic_preference.h
+++ b/chrome/browser/prefs/tracked/tracked_atomic_preference.h
@@ -27,11 +27,10 @@
                           TrackedPreferenceValidationDelegate* delegate);
 
   // TrackedPreference implementation.
-  virtual void OnNewValue(const base::Value* value,
-                          PrefHashStoreTransaction* transaction) const override;
-  virtual bool EnforceAndReport(
-      base::DictionaryValue* pref_store_contents,
-      PrefHashStoreTransaction* transaction) const override;
+  void OnNewValue(const base::Value* value,
+                  PrefHashStoreTransaction* transaction) const override;
+  bool EnforceAndReport(base::DictionaryValue* pref_store_contents,
+                        PrefHashStoreTransaction* transaction) const override;
 
  private:
   const std::string pref_path_;
diff --git a/chrome/browser/prefs/tracked/tracked_preferences_migration_unittest.cc b/chrome/browser/prefs/tracked/tracked_preferences_migration_unittest.cc
index bf7e0faa..c753596d 100644
--- a/chrome/browser/prefs/tracked/tracked_preferences_migration_unittest.cc
+++ b/chrome/browser/prefs/tracked/tracked_preferences_migration_unittest.cc
@@ -46,17 +46,15 @@
 class SimpleInterceptablePrefFilter : public InterceptablePrefFilter {
  public:
   // PrefFilter remaining implementation.
-  virtual void FilterUpdate(const std::string& path) override {
-    ADD_FAILURE();
-  }
-  virtual void FilterSerializeData(
+  void FilterUpdate(const std::string& path) override { ADD_FAILURE(); }
+  void FilterSerializeData(
       base::DictionaryValue* pref_store_contents) override {
     ADD_FAILURE();
   }
 
  private:
   // InterceptablePrefFilter implementation.
-  virtual void FinalizeFilterOnLoad(
+  void FinalizeFilterOnLoad(
       const PostFilterOnLoadCallback& post_filter_on_load_callback,
       scoped_ptr<base::DictionaryValue> pref_store_contents,
       bool prefs_altered) override {
diff --git a/chrome/browser/prefs/tracked/tracked_split_preference.h b/chrome/browser/prefs/tracked/tracked_split_preference.h
index 0bbe7c7..2c2d596 100644
--- a/chrome/browser/prefs/tracked/tracked_split_preference.h
+++ b/chrome/browser/prefs/tracked/tracked_split_preference.h
@@ -30,11 +30,10 @@
                          TrackedPreferenceValidationDelegate* delegate);
 
   // TrackedPreference implementation.
-  virtual void OnNewValue(const base::Value* value,
-                          PrefHashStoreTransaction* transaction) const override;
-  virtual bool EnforceAndReport(
-      base::DictionaryValue* pref_store_contents,
-      PrefHashStoreTransaction* transaction) const override;
+  void OnNewValue(const base::Value* value,
+                  PrefHashStoreTransaction* transaction) const override;
+  bool EnforceAndReport(base::DictionaryValue* pref_store_contents,
+                        PrefHashStoreTransaction* transaction) const override;
 
  private:
   const std::string pref_path_;
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 48b195e8..6bea3c0 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -133,14 +133,14 @@
 
 class MockNetworkChangeNotifierWIFI : public NetworkChangeNotifier {
  public:
-  virtual ConnectionType GetCurrentConnectionType() const override {
+  ConnectionType GetCurrentConnectionType() const override {
     return NetworkChangeNotifier::CONNECTION_WIFI;
   }
 };
 
 class MockNetworkChangeNotifier4G : public NetworkChangeNotifier {
  public:
-  virtual ConnectionType GetCurrentConnectionType() const override {
+  ConnectionType GetCurrentConnectionType() const override {
     return NetworkChangeNotifier::CONNECTION_4G;
   }
 };
@@ -234,14 +234,14 @@
     }
 
    private:
-    virtual ~DestructionMessageFilter() {
+    ~DestructionMessageFilter() override {
       content::BrowserThread::PostTask(
           content::BrowserThread::UI, FROM_HERE,
           base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed,
                      base::Unretained(watcher_)));
     }
 
-    virtual bool OnMessageReceived(const IPC::Message& message) override {
+    bool OnMessageReceived(const IPC::Message& message) override {
       return false;
     }
 
@@ -298,7 +298,7 @@
     tab_strip_model_->AddObserver(this);
   }
 
-  virtual ~NavigationOrSwapObserver() {
+  ~NavigationOrSwapObserver() override {
     tab_strip_model_->RemoveObserver(this);
   }
 
@@ -311,10 +311,10 @@
   }
 
   // WebContentsObserver implementation:
-  virtual void DidStartLoading(RenderViewHost* render_view_host) override {
+  void DidStartLoading(RenderViewHost* render_view_host) override {
     did_start_loading_ = true;
   }
-  virtual void DidStopLoading(RenderViewHost* render_view_host) override {
+  void DidStopLoading(RenderViewHost* render_view_host) override {
     if (!did_start_loading_)
       return;
     number_of_loads_--;
@@ -323,10 +323,10 @@
   }
 
   // TabStripModelObserver implementation:
-  virtual void TabReplacedAt(TabStripModel* tab_strip_model,
-                             WebContents* old_contents,
-                             WebContents* new_contents,
-                             int index) override {
+  void TabReplacedAt(TabStripModel* tab_strip_model,
+                     WebContents* old_contents,
+                     WebContents* new_contents,
+                     int index) override {
     if (old_contents != web_contents())
       return;
     // Switch to observing the new WebContents.
@@ -405,7 +405,7 @@
         skip_final_checks_(false) {
   }
 
-  virtual ~TestPrerenderContents() {
+  ~TestPrerenderContents() override {
     if (skip_final_checks_)
       return;
 
@@ -433,7 +433,7 @@
     EXPECT_EQ(should_be_shown_, was_shown_);
   }
 
-  virtual void RenderProcessGone(base::TerminationStatus status) override {
+  void RenderProcessGone(base::TerminationStatus status) override {
     // On quit, it's possible to end up here when render processes are closed
     // before the PrerenderManager is destroyed.  As a result, it's possible to
     // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED
@@ -450,7 +450,7 @@
     PrerenderContents::RenderProcessGone(status);
   }
 
-  virtual bool CheckURL(const GURL& url) override {
+  bool CheckURL(const GURL& url) override {
     // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in
     // the PrerenderRendererCrash test.
     if (url.spec() != content::kChromeUICrashURL)
@@ -469,8 +469,7 @@
   FinalStatus expected_final_status() const { return expected_final_status_; }
 
  private:
-  virtual void OnRenderViewHostCreated(
-      RenderViewHost* new_render_view_host) override {
+  void OnRenderViewHostCreated(RenderViewHost* new_render_view_host) override {
     // Used to make sure the RenderViewHost is hidden and, if used,
     // subsequently shown.
     notification_registrar().Add(
@@ -483,9 +482,9 @@
     PrerenderContents::OnRenderViewHostCreated(new_render_view_host);
   }
 
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override {
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {
     if (type ==
         content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
       EXPECT_EQ(new_render_view_host_,
@@ -532,7 +531,7 @@
         number_of_loads_(0),
         expected_number_of_loads_(0) {
   }
-  virtual ~TestPrerender() {
+  ~TestPrerender() override {
     if (contents_)
       contents_->RemoveObserver(this);
   }
@@ -569,17 +568,17 @@
   }
 
   // PrerenderContents::Observer implementation:
-  virtual void OnPrerenderStart(PrerenderContents* contents) override {
+  void OnPrerenderStart(PrerenderContents* contents) override {
     start_loop_.Quit();
   }
 
-  virtual void OnPrerenderStopLoading(PrerenderContents* contents) override {
+  void OnPrerenderStopLoading(PrerenderContents* contents) override {
     number_of_loads_++;
     if (load_waiter_ && number_of_loads_ >= expected_number_of_loads_)
       load_waiter_->Quit();
   }
 
-  virtual void OnPrerenderStop(PrerenderContents* contents) override {
+  void OnPrerenderStop(PrerenderContents* contents) override {
     DCHECK(contents_);
     contents_ = NULL;
     stop_loop_.Quit();
@@ -589,9 +588,9 @@
       load_waiter_->Quit();
   }
 
-  virtual void OnPrerenderCreatedMatchCompleteReplacement(
-      PrerenderContents* contents, PrerenderContents* replacement) override {
-  }
+  void OnPrerenderCreatedMatchCompleteReplacement(
+      PrerenderContents* contents,
+      PrerenderContents* replacement) override {}
 
  private:
   TestPrerenderContents* contents_;
@@ -612,7 +611,7 @@
  public:
   TestPrerenderContentsFactory() {}
 
-  virtual ~TestPrerenderContentsFactory() {
+  ~TestPrerenderContentsFactory() override {
     EXPECT_TRUE(expected_contents_queue_.empty());
   }
 
@@ -623,7 +622,7 @@
     return handle.Pass();
   }
 
-  virtual PrerenderContents* CreatePrerenderContents(
+  PrerenderContents* CreatePrerenderContents(
       PrerenderManager* prerender_manager,
       Profile* profile,
       const GURL& url,
@@ -681,7 +680,7 @@
   // (in which that result will be communicated back via a call into the
   // client, and false will be returned).
   // Overrides SafeBrowsingService::CheckBrowseUrl.
-  virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
+  bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
     if (gurl != url_ || threat_type_ == SB_THREAT_TYPE_SAFE)
       return true;
 
@@ -698,7 +697,7 @@
   }
 
  private:
-  virtual ~FakeSafeBrowsingDatabaseManager() {}
+  ~FakeSafeBrowsingDatabaseManager() override {}
 
   void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
     std::vector<SBThreatType> expected_threats;
@@ -730,9 +729,9 @@
   }
 
  protected:
-  virtual ~FakeSafeBrowsingService() { }
+  ~FakeSafeBrowsingService() override {}
 
-  virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
+  SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
     fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
     return fake_database_manager_;
   }
@@ -748,9 +747,9 @@
  public:
   TestSafeBrowsingServiceFactory() :
       most_recent_service_(NULL) { }
-  virtual ~TestSafeBrowsingServiceFactory() { }
+  ~TestSafeBrowsingServiceFactory() override {}
 
-  virtual SafeBrowsingService* CreateSafeBrowsingService() override {
+  SafeBrowsingService* CreateSafeBrowsingService() override {
     most_recent_service_ =  new FakeSafeBrowsingService();
     return most_recent_service_;
   }
@@ -767,11 +766,10 @@
 class FakeDevToolsClient : public content::DevToolsAgentHostClient {
  public:
   FakeDevToolsClient() {}
-  virtual ~FakeDevToolsClient() {}
-  virtual void DispatchProtocolMessage(
-      DevToolsAgentHost* agent_host, const std::string& message) override {}
-  virtual void AgentHostClosed(
-      DevToolsAgentHost* agent_host, bool replaced) override {}
+  ~FakeDevToolsClient() override {}
+  void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
+                               const std::string& message) override {}
+  void AgentHostClosed(DevToolsAgentHost* agent_host, bool replaced) override {}
 };
 
 class RestorePrerenderMode {
@@ -792,10 +790,10 @@
       : net::URLRequestJob(request, network_delegate) {
   }
 
-  virtual void Start() override {}
+  void Start() override {}
 
  private:
-  virtual ~HangingURLRequestJob() {}
+  ~HangingURLRequestJob() override {}
 };
 
 class HangingFirstRequestInterceptor : public net::URLRequestInterceptor {
@@ -806,9 +804,9 @@
         callback_(callback),
         first_run_(true) {
   }
-  virtual ~HangingFirstRequestInterceptor() {}
+  ~HangingFirstRequestInterceptor() override {}
 
-  virtual net::URLRequestJob* MaybeInterceptRequest(
+  net::URLRequestJob* MaybeInterceptRequest(
       net::URLRequest* request,
       net::NetworkDelegate* network_delegate) const override {
     if (first_run_) {
@@ -862,14 +860,14 @@
     start_callback_ = start_callback;
   }
 
-  virtual void Start() override {
+  void Start() override {
     if (!start_callback_.is_null())
       start_callback_.Run();
     net::URLRequestMockHTTPJob::Start();
   }
 
  private:
-  virtual ~MockHTTPJob() {}
+  ~MockHTTPJob() override {}
 
   base::Closure start_callback_;
 };
@@ -914,9 +912,9 @@
         counter_(counter),
         weak_factory_(this) {
   }
-  virtual ~CountingInterceptor() {}
+  ~CountingInterceptor() override {}
 
-  virtual net::URLRequestJob* MaybeInterceptRequest(
+  net::URLRequestJob* MaybeInterceptRequest(
       net::URLRequest* request,
       net::NetworkDelegate* network_delegate) const override {
     MockHTTPJob* job = new MockHTTPJob(request, network_delegate, file_);
@@ -963,11 +961,11 @@
 class TestContentBrowserClient : public chrome::ChromeContentBrowserClient {
  public:
   TestContentBrowserClient() {}
-  virtual ~TestContentBrowserClient() {}
+  ~TestContentBrowserClient() override {}
 
   // chrome::ChromeContentBrowserClient implementation.
-  virtual bool ShouldAllowOpenURL(content::SiteInstance* site_instance,
-                                  const GURL& url) override {
+  bool ShouldAllowOpenURL(content::SiteInstance* site_instance,
+                          const GURL& url) override {
     PrerenderManagerFactory::GetForProfile(
         Profile::FromBrowserContext(site_instance->GetBrowserContext()))
         ->CancelAllPrerenders();
@@ -984,10 +982,10 @@
     : public chrome::ChromeContentBrowserClient {
  public:
   SwapProcessesContentBrowserClient() {}
-  virtual ~SwapProcessesContentBrowserClient() {}
+  ~SwapProcessesContentBrowserClient() override {}
 
   // chrome::ChromeContentBrowserClient implementation.
-  virtual bool ShouldSwapProcessesForRedirect(
+  bool ShouldSwapProcessesForRedirect(
       content::ResourceContext* resource_context,
       const GURL& current_url,
       const GURL& new_url) override {
@@ -1004,7 +1002,7 @@
     : public ExternalProtocolHandler::Delegate {
  public:
   // ExternalProtocolHandler::Delegate implementation.
-  virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
+  ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
       ShellIntegration::DefaultWebClientObserver* observer,
       const std::string& protocol) override {
     NOTREACHED();
@@ -1012,24 +1010,20 @@
     // anyway.
     return NULL;
   }
-  virtual ExternalProtocolHandler::BlockState GetBlockState(
+  ExternalProtocolHandler::BlockState GetBlockState(
       const std::string& scheme) override {
     // Block everything and fail the test.
     ADD_FAILURE();
     return ExternalProtocolHandler::BLOCK;
   }
-  virtual void BlockRequest() override { }
-  virtual void RunExternalProtocolDialog(const GURL& url,
-                                         int render_process_host_id,
-                                         int routing_id) override {
+  void BlockRequest() override {}
+  void RunExternalProtocolDialog(const GURL& url,
+                                 int render_process_host_id,
+                                 int routing_id) override {
     NOTREACHED();
   }
-  virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) override {
-    NOTREACHED();
-  }
-  virtual void FinishedProcessingCheck() override {
-    NOTREACHED();
-  }
+  void LaunchUrlWithoutSecurityCheck(const GURL& url) override { NOTREACHED(); }
+  void FinishedProcessingCheck() override { NOTREACHED(); }
 };
 
 base::FilePath GetTestPath(const std::string& file_name) {
@@ -1063,19 +1057,19 @@
     return web_contents->GetController().GetDefaultSessionStorageNamespace();
   }
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
 #if defined(FULL_SAFE_BROWSING)
     SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get());
 #endif
   }
 
-  virtual void TearDownInProcessBrowserTestFixture() override {
+  void TearDownInProcessBrowserTestFixture() override {
 #if defined(FULL_SAFE_BROWSING)
     SafeBrowsingService::RegisterFactory(NULL);
 #endif
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     command_line->AppendSwitchASCII(switches::kPrerenderMode,
                                     switches::kPrerenderModeSwitchValueEnabled);
 #if defined(OS_MACOSX)
@@ -1164,7 +1158,7 @@
     }
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     current_browser()->profile()->GetPrefs()->SetBoolean(
         prefs::kPromptForDownload, false);
     IncreasePrerenderMemory();
@@ -3017,12 +3011,12 @@
 class TestClientCertStore : public net::ClientCertStore {
  public:
   TestClientCertStore() {}
-  virtual ~TestClientCertStore() {}
+  ~TestClientCertStore() override {}
 
   // net::ClientCertStore:
-  virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
-                              net::CertificateList* selected_certs,
-                              const base::Closure& callback) override {
+  void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
+                      net::CertificateList* selected_certs,
+                      const base::Closure& callback) override {
     *selected_certs = net::CertificateList(
         1, scoped_refptr<net::X509Certificate>(
         new net::X509Certificate("test", "test", base::Time(), base::Time())));
@@ -3535,7 +3529,7 @@
   PrerenderBrowserTestWithNaCl() {}
   virtual ~PrerenderBrowserTestWithNaCl() {}
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     PrerenderBrowserTest::SetUpCommandLine(command_line);
     command_line->AppendSwitch(switches::kEnableNaCl);
   }
@@ -3625,22 +3619,22 @@
     PrerenderBrowserTest::SetUp();
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     PrerenderBrowserTest::SetUpCommandLine(command_line);
     ExtensionApiTest::SetUpCommandLine(command_line);
   }
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     PrerenderBrowserTest::SetUpInProcessBrowserTestFixture();
     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
   }
 
-  virtual void TearDownInProcessBrowserTestFixture() override {
+  void TearDownInProcessBrowserTestFixture() override {
     PrerenderBrowserTest::TearDownInProcessBrowserTestFixture();
     ExtensionApiTest::TearDownInProcessBrowserTestFixture();
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     PrerenderBrowserTest::SetUpOnMainThread();
   }
 };
@@ -4416,7 +4410,7 @@
 
 class PrerenderIncognitoBrowserTest : public PrerenderBrowserTest {
  public:
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     Profile* normal_profile = current_browser()->profile();
     set_browser(ui_test_utils::OpenURLOffTheRecord(
         normal_profile, GURL("about:blank")));
diff --git a/chrome/browser/prerender/prerender_config.cc b/chrome/browser/prerender/prerender_config.cc
index 18d5ea2..7f43785 100644
--- a/chrome/browser/prerender/prerender_config.cc
+++ b/chrome/browser/prerender/prerender_config.cc
@@ -12,7 +12,7 @@
                    rate_limit_enabled(true),
                    max_wait_to_launch(base::TimeDelta::FromMinutes(4)),
                    time_to_live(base::TimeDelta::FromMinutes(5)),
-                   abandon_time_to_live(base::TimeDelta::FromSeconds(30)),
+                   abandon_time_to_live(base::TimeDelta::FromSeconds(3)),
                    default_tab_bounds(640, 480),
                    is_overriding_user_agent(false) {
 }
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 767e2080..c6489b6 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -99,10 +99,13 @@
 
 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory {
  public:
-  virtual PrerenderContents* CreatePrerenderContents(
-      PrerenderManager* prerender_manager, Profile* profile,
-      const GURL& url, const content::Referrer& referrer,
-      Origin origin, uint8 experiment_id) override {
+  PrerenderContents* CreatePrerenderContents(
+      PrerenderManager* prerender_manager,
+      Profile* profile,
+      const GURL& url,
+      const content::Referrer& referrer,
+      Origin origin,
+      uint8 experiment_id) override {
     return new PrerenderContents(prerender_manager, profile,
                                  url, referrer, origin, experiment_id);
   }
@@ -118,8 +121,8 @@
   }
 
   // content::WebContentsDelegate implementation:
-  virtual WebContents* OpenURLFromTab(WebContents* source,
-                                      const OpenURLParams& params) override {
+  WebContents* OpenURLFromTab(WebContents* source,
+                              const OpenURLParams& params) override {
     // |OpenURLFromTab| is typically called when a frame performs a navigation
     // that requires the browser to perform the transition instead of WebKit.
     // Examples include prerendering a site that redirects to an app URL,
@@ -131,28 +134,27 @@
     return NULL;
   }
 
-  virtual void CloseContents(content::WebContents* contents) override {
+  void CloseContents(content::WebContents* contents) override {
     prerender_contents_->Destroy(FINAL_STATUS_CLOSED);
   }
 
-  virtual void CanDownload(
-      RenderViewHost* render_view_host,
-      const GURL& url,
-      const std::string& request_method,
-      const base::Callback<void(bool)>& callback) override {
+  void CanDownload(RenderViewHost* render_view_host,
+                   const GURL& url,
+                   const std::string& request_method,
+                   const base::Callback<void(bool)>& callback) override {
     prerender_contents_->Destroy(FINAL_STATUS_DOWNLOAD);
     // Cancel the download.
     callback.Run(false);
   }
 
-   virtual bool ShouldCreateWebContents(
-       WebContents* web_contents,
-       int route_id,
-       WindowContainerType window_container_type,
-       const base::string16& frame_name,
-       const GURL& target_url,
-       const std::string& partition_id,
-       SessionStorageNamespace* session_storage_namespace) override {
+  bool ShouldCreateWebContents(
+      WebContents* web_contents,
+      int route_id,
+      WindowContainerType window_container_type,
+      const base::string16& frame_name,
+      const GURL& target_url,
+      const std::string& partition_id,
+      SessionStorageNamespace* session_storage_namespace) override {
     // Since we don't want to permit child windows that would have a
     // window.opener property, terminate prerendering.
     prerender_contents_->Destroy(FINAL_STATUS_CREATE_NEW_WINDOW);
@@ -160,7 +162,7 @@
     return false;
   }
 
-  virtual bool OnGoToEntryOffset(int offset) override {
+  bool OnGoToEntryOffset(int offset) override {
     // This isn't allowed because the history merge operation
     // does not work if there are renderer issued challenges.
     // TODO(cbentzel): Cancel in this case? May not need to do
@@ -169,7 +171,7 @@
     return false;
   }
 
-  virtual bool ShouldSuppressDialogs() override {
+  bool ShouldSuppressDialogs() override {
     // We still want to show the user the message when they navigate to this
     // page, so cancel this prerender.
     prerender_contents_->Destroy(FINAL_STATUS_JAVASCRIPT_ALERT);
@@ -178,17 +180,16 @@
     return true;
   }
 
-  virtual void RegisterProtocolHandler(WebContents* web_contents,
-                                       const std::string& protocol,
-                                       const GURL& url,
-                                       bool user_gesture) override {
+  void RegisterProtocolHandler(WebContents* web_contents,
+                               const std::string& protocol,
+                               const GURL& url,
+                               bool user_gesture) override {
     // TODO(mmenke): Consider supporting this if it is a common case during
     // prerenders.
     prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER);
   }
 
-  virtual gfx::Size GetSizeForNewRenderView(
-      WebContents* web_contents) const override {
+  gfx::Size GetSizeForNewRenderView(WebContents* web_contents) const override {
     // Have to set the size of the RenderView on initialization to be sure it is
     // set before the RenderView is hidden on all platforms (esp. Android).
     return prerender_contents_->size_;
diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h
index bd257db7..1bd4e6e 100644
--- a/chrome/browser/prerender/prerender_contents.h
+++ b/chrome/browser/prerender/prerender_contents.h
@@ -122,7 +122,7 @@
     MATCH_COMPLETE_REPLACEMENT_PENDING,
   };
 
-  virtual ~PrerenderContents();
+  ~PrerenderContents() override;
 
   // All observers of a PrerenderContents are removed after the OnPrerenderStop
   // event is sent, so there is no need to call RemoveObserver() in the normal
@@ -205,33 +205,31 @@
       const content::SessionStorageNamespace* session_storage_namespace) const;
 
   // content::WebContentsObserver implementation.
-  virtual void RenderFrameCreated(
+  void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
+  void DidStopLoading(content::RenderViewHost* render_view_host) override;
+  void DocumentLoadedInFrame(
       content::RenderFrameHost* render_frame_host) override;
-  virtual void DidStopLoading(
-      content::RenderViewHost* render_view_host) override;
-  virtual void DocumentLoadedInFrame(
-      content::RenderFrameHost* render_frame_host) override;
-  virtual void DidStartProvisionalLoadForFrame(
+  void DidStartProvisionalLoadForFrame(
       content::RenderFrameHost* render_frame_host,
       const GURL& validated_url,
       bool is_error_page,
       bool is_iframe_srcdoc) override;
-  virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host,
-                             const GURL& validated_url) override;
-  virtual void DidNavigateMainFrame(
+  void DidFinishLoad(content::RenderFrameHost* render_frame_host,
+                     const GURL& validated_url) override;
+  void DidNavigateMainFrame(
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) override;
-  virtual void DidGetRedirectForResourceRequest(
+  void DidGetRedirectForResourceRequest(
       content::RenderViewHost* render_view_host,
       const content::ResourceRedirectDetails& details) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
-  virtual void RenderProcessGone(base::TerminationStatus status) override;
+  void RenderProcessGone(base::TerminationStatus status) override;
 
   // content::NotificationObserver
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Checks that a URL may be prerendered, for one of the many redirections. If
   // the URL can not be prerendered - for example, it's an ftp URL - |this| will
diff --git a/chrome/browser/prerender/prerender_cookie_store.h b/chrome/browser/prerender/prerender_cookie_store.h
index e93bcd6..81463dab 100644
--- a/chrome/browser/prerender/prerender_cookie_store.h
+++ b/chrome/browser/prerender/prerender_cookie_store.h
@@ -48,24 +48,21 @@
                        const base::Closure& cookie_conflict_cb);
 
   // CookieStore implementation
-  virtual void SetCookieWithOptionsAsync(
-      const GURL& url,
-      const std::string& cookie_line,
-      const net::CookieOptions& options,
-      const SetCookiesCallback& callback) override;
+  void SetCookieWithOptionsAsync(const GURL& url,
+                                 const std::string& cookie_line,
+                                 const net::CookieOptions& options,
+                                 const SetCookiesCallback& callback) override;
 
-  virtual void GetCookiesWithOptionsAsync(
-      const GURL& url,
-      const net::CookieOptions& options,
-      const GetCookiesCallback& callback) override;
+  void GetCookiesWithOptionsAsync(const GURL& url,
+                                  const net::CookieOptions& options,
+                                  const GetCookiesCallback& callback) override;
 
-  virtual void GetAllCookiesForURLAsync(
-      const GURL& url,
-      const GetCookieListCallback& callback) override;
+  void GetAllCookiesForURLAsync(const GURL& url,
+                                const GetCookieListCallback& callback) override;
 
-  virtual void DeleteCookieAsync(const GURL& url,
-                                 const std::string& cookie_name,
-                                 const base::Closure& callback) override;
+  void DeleteCookieAsync(const GURL& url,
+                         const std::string& cookie_name,
+                         const base::Closure& callback) override;
 
   // All the following methods should not be used in the scenarios where
   // a PrerenderCookieStore is used. This will be checked via NOTREACHED().
@@ -73,20 +70,19 @@
   // need to be implemented first. They are only intended to be called on the
   // IO thread.
 
-  virtual void DeleteAllCreatedBetweenAsync(
-      const base::Time& delete_begin,
-      const base::Time& delete_end,
-      const DeleteCallback& callback) override;
+  void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin,
+                                    const base::Time& delete_end,
+                                    const DeleteCallback& callback) override;
 
-  virtual void DeleteAllCreatedBetweenForHostAsync(
+  void DeleteAllCreatedBetweenForHostAsync(
       const base::Time delete_begin,
       const base::Time delete_end,
       const GURL& url,
       const DeleteCallback& callback) override;
 
-  virtual void DeleteSessionCookiesAsync(const DeleteCallback&) override;
+  void DeleteSessionCookiesAsync(const DeleteCallback&) override;
 
-  virtual net::CookieMonster* GetCookieMonster() override;
+  net::CookieMonster* GetCookieMonster() override;
 
   // Commits the changes made to the underlying cookie store, and switches
   // into forwarding mode. To be called on the IO thread.
@@ -123,7 +119,7 @@
     ~CookieOperation();
   };
 
-  virtual ~PrerenderCookieStore();
+  ~PrerenderCookieStore() override;
 
   // Gets the appropriate cookie store for the operation provided, and pushes
   // it back on the log of cookie operations performed.
diff --git a/chrome/browser/prerender/prerender_handle.h b/chrome/browser/prerender/prerender_handle.h
index c97dc819..427dd8a 100644
--- a/chrome/browser/prerender/prerender_handle.h
+++ b/chrome/browser/prerender/prerender_handle.h
@@ -55,7 +55,7 @@
 
   // Before calling the destructor, the caller must invalidate the handle by
   // calling either OnNavigateAway or OnCancel.
-  virtual ~PrerenderHandle();
+  ~PrerenderHandle() override;
 
   void SetObserver(Observer* observer);
 
@@ -103,14 +103,14 @@
   explicit PrerenderHandle(PrerenderManager::PrerenderData* prerender_data);
 
   // From PrerenderContents::Observer:
-  virtual void OnPrerenderStart(PrerenderContents* prerender_contents) override;
-  virtual void OnPrerenderStopLoading(PrerenderContents* prerender_contents)
-      override;
-  virtual void OnPrerenderDomContentLoaded(
+  void OnPrerenderStart(PrerenderContents* prerender_contents) override;
+  void OnPrerenderStopLoading(PrerenderContents* prerender_contents) override;
+  void OnPrerenderDomContentLoaded(
       PrerenderContents* prerender_contents) override;
-  virtual void OnPrerenderStop(PrerenderContents* prerender_contents) override;
-  virtual void OnPrerenderCreatedMatchCompleteReplacement(
-      PrerenderContents* contents, PrerenderContents* replacement) override;
+  void OnPrerenderStop(PrerenderContents* prerender_contents) override;
+  void OnPrerenderCreatedMatchCompleteReplacement(
+      PrerenderContents* contents,
+      PrerenderContents* replacement) override;
 
   Observer* observer_;
 
diff --git a/chrome/browser/prerender/prerender_link_manager.cc b/chrome/browser/prerender/prerender_link_manager.cc
index 4a2bb7c1..21a1dac 100644
--- a/chrome/browser/prerender/prerender_link_manager.cc
+++ b/chrome/browser/prerender/prerender_link_manager.cc
@@ -105,7 +105,7 @@
   explicit PendingPrerenderManager(PrerenderLinkManager* link_manager)
       : link_manager_(link_manager) {}
 
-  virtual ~PendingPrerenderManager() {
+  ~PendingPrerenderManager() override {
     DCHECK(observed_launchers_.empty());
     for (std::set<PrerenderContents*>::iterator i = observed_launchers_.begin();
          i != observed_launchers_.end(); ++i) {
@@ -121,9 +121,9 @@
     launcher->AddObserver(this);
   }
 
-  virtual void OnPrerenderStart(PrerenderContents* launcher) override {}
+  void OnPrerenderStart(PrerenderContents* launcher) override {}
 
-  virtual void OnPrerenderStop(PrerenderContents* launcher) override {
+  void OnPrerenderStop(PrerenderContents* launcher) override {
     observed_launchers_.erase(launcher);
     if (launcher->final_status() == FINAL_STATUS_USED) {
       link_manager_->StartPendingPrerendersForLauncher(launcher);
diff --git a/chrome/browser/prerender/prerender_link_manager.h b/chrome/browser/prerender/prerender_link_manager.h
index 7dc0360..a671c81 100644
--- a/chrome/browser/prerender/prerender_link_manager.h
+++ b/chrome/browser/prerender/prerender_link_manager.h
@@ -39,7 +39,7 @@
                              public PrerenderHandle::Observer {
  public:
   explicit PrerenderLinkManager(PrerenderManager* manager);
-  virtual ~PrerenderLinkManager();
+  ~PrerenderLinkManager() override;
 
   // A <link rel=prerender ...> element has been inserted into the document.
   // The |prerender_id| must be unique per |child_id|, and is assigned by the
@@ -144,16 +144,14 @@
   void CancelPendingPrerendersForLauncher(PrerenderContents* launcher);
 
   // From KeyedService:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // From PrerenderHandle::Observer:
-  virtual void OnPrerenderStart(PrerenderHandle* prerender_handle) override;
-  virtual void OnPrerenderStopLoading(PrerenderHandle* prerender_handle)
-      override;
-  virtual void OnPrerenderDomContentLoaded(PrerenderHandle* prerender_handle)
-      override;
-  virtual void OnPrerenderStop(PrerenderHandle* prerender_handle) override;
-  virtual void OnPrerenderCreatedMatchCompleteReplacement(
+  void OnPrerenderStart(PrerenderHandle* prerender_handle) override;
+  void OnPrerenderStopLoading(PrerenderHandle* prerender_handle) override;
+  void OnPrerenderDomContentLoaded(PrerenderHandle* prerender_handle) override;
+  void OnPrerenderStop(PrerenderHandle* prerender_handle) override;
+  void OnPrerenderCreatedMatchCompleteReplacement(
       PrerenderHandle* handle) override;
 
   bool has_shutdown_;
diff --git a/chrome/browser/prerender/prerender_link_manager_factory.h b/chrome/browser/prerender/prerender_link_manager_factory.h
index da826233..ba4949a6 100644
--- a/chrome/browser/prerender/prerender_link_manager_factory.h
+++ b/chrome/browser/prerender/prerender_link_manager_factory.h
@@ -24,11 +24,11 @@
   friend struct DefaultSingletonTraits<PrerenderLinkManagerFactory>;
 
   PrerenderLinkManagerFactory();
-  virtual ~PrerenderLinkManagerFactory() { }
+  ~PrerenderLinkManagerFactory() override {}
 
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
 };
 
diff --git a/chrome/browser/prerender/prerender_local_predictor.cc b/chrome/browser/prerender/prerender_local_predictor.cc
index 50b885db..a4168535 100644
--- a/chrome/browser/prerender/prerender_local_predictor.cc
+++ b/chrome/browser/prerender/prerender_local_predictor.cc
@@ -175,22 +175,22 @@
         start_time_(base::Time::Now()) {
   }
 
-  virtual bool RunOnDBThread(history::HistoryBackend* backend,
-                             history::HistoryDatabase* db) override {
+  bool RunOnDBThread(history::HistoryBackend* backend,
+                     history::HistoryDatabase* db) override {
     DoURLLookup(db, &request_->source_url_);
     for (int i = 0; i < static_cast<int>(request_->candidate_urls_.size()); i++)
       DoURLLookup(db, &request_->candidate_urls_[i]);
     return true;
   }
 
-  virtual void DoneRunOnMainThread() override {
+  void DoneRunOnMainThread() override {
     callback_.Run();
     TIMING_HISTOGRAM("Prerender.LocalPredictorURLLookupTime",
                      base::Time::Now() - start_time_);
   }
 
  private:
-  virtual ~GetURLForURLIDTask() {}
+  ~GetURLForURLIDTask() override {}
 
   void DoURLLookup(history::HistoryDatabase* db,
                    PrerenderLocalPredictor::LocalPredictorURLInfo* request) {
@@ -216,18 +216,18 @@
         visit_history_(new vector<history::BriefVisitInfo>) {
   }
 
-  virtual bool RunOnDBThread(history::HistoryBackend* backend,
-                             history::HistoryDatabase* db) override {
+  bool RunOnDBThread(history::HistoryBackend* backend,
+                     history::HistoryDatabase* db) override {
     db->GetBriefVisitInfoOfMostRecentVisits(max_visits_, visit_history_.get());
     return true;
   }
 
-  virtual void DoneRunOnMainThread() override {
+  void DoneRunOnMainThread() override {
     local_predictor_->OnGetInitialVisitHistory(visit_history_.Pass());
   }
 
  private:
-  virtual ~GetVisitHistoryTask() {}
+  ~GetVisitHistoryTask() override {}
 
   PrerenderLocalPredictor* local_predictor_;
   int max_visits_;
diff --git a/chrome/browser/prerender/prerender_local_predictor.h b/chrome/browser/prerender/prerender_local_predictor.h
index 1db2afe7..95ca574 100644
--- a/chrome/browser/prerender/prerender_local_predictor.h
+++ b/chrome/browser/prerender/prerender_local_predictor.h
@@ -153,13 +153,13 @@
   // in the constructor.  It will be destoryed at the time its owning
   // PrerenderManager is destroyed.
   explicit PrerenderLocalPredictor(PrerenderManager* prerender_manager);
-  virtual ~PrerenderLocalPredictor();
+  ~PrerenderLocalPredictor() override;
 
   void Shutdown();
 
   // history::HistoryServiceObserver:
-  virtual void OnAddVisit(HistoryService* history_service,
-                          const history::BriefVisitInfo& info) override;
+  void OnAddVisit(HistoryService* history_service,
+                  const history::BriefVisitInfo& info) override;
 
   void OnGetInitialVisitHistory(
       scoped_ptr<std::vector<history::BriefVisitInfo> > visit_history);
@@ -169,7 +169,7 @@
   void OnTabHelperURLSeen(const GURL& url, content::WebContents* web_contents);
 
   // net::URLFetcherDelegate implementation:
-  void virtual OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  private:
   struct PrerenderProperties;
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 13c84c92..d95a8a1 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -182,17 +182,17 @@
         base::TimeDelta::FromSeconds(kDeleteWithExtremePrejudiceSeconds));
   }
 
-  virtual void CloseContents(WebContents* source) override {
+  void CloseContents(WebContents* source) override {
     DCHECK_EQ(tab_, source);
     ScheduleWebContentsForDeletion(false);
   }
 
-  virtual void SwappedOut(WebContents* source) override {
+  void SwappedOut(WebContents* source) override {
     DCHECK_EQ(tab_, source);
     ScheduleWebContentsForDeletion(false);
   }
 
-  virtual bool ShouldSuppressDialogs() override {
+  bool ShouldSuppressDialogs() override {
     // Use this as a proxy for getting statistics on how often we fail to honor
     // the beforeunload event.
     suppressed_dialog_ = true;
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index 8c33c93..59d74d0f 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -109,10 +109,10 @@
   // Owned by a Profile object for the lifetime of the profile.
   PrerenderManager(Profile* profile, PrerenderTracker* prerender_tracker);
 
-  virtual ~PrerenderManager();
+  ~PrerenderManager() override;
 
   // From KeyedService:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // Entry points for adding prerenders.
 
@@ -279,13 +279,13 @@
                             int cookie_send_type) const;
 
   // content::NotificationObserver
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // MediaCaptureDevicesDispatcher::Observer
-  virtual void OnCreatingAudioStream(int render_process_id,
-                                     int render_frame_id) override;
+  void OnCreatingAudioStream(int render_process_id,
+                             int render_frame_id) override;
 
   const Config& config() const { return config_; }
   Config& mutable_config() { return config_; }
@@ -368,8 +368,7 @@
   bool MayReuseProcessHost(content::RenderProcessHost* process_host);
 
   // content::RenderProcessHostObserver implementation.
-  virtual void RenderProcessHostDestroyed(
-      content::RenderProcessHost* host) override;
+  void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
 
   // To be called once the cookie store for this profile has been loaded.
   void OnCookieStoreLoaded();
@@ -467,7 +466,7 @@
                 PrerenderData* prerender_data,
                 const GURL& url,
                 bool should_replace_current_entry);
-    virtual ~PendingSwap();
+    ~PendingSwap() override;
 
     void set_swap_successful(bool swap_successful) {
       swap_successful_ = swap_successful;
@@ -476,23 +475,23 @@
     void BeginSwap();
 
     // content::WebContentsObserver implementation.
-    virtual void AboutToNavigateRenderView(
+    void AboutToNavigateRenderView(
         content::RenderViewHost* render_view_host) override;
-    virtual void DidStartProvisionalLoadForFrame(
+    void DidStartProvisionalLoadForFrame(
         content::RenderFrameHost* render_frame_host,
         const GURL& validated_url,
         bool is_error_page,
         bool is_iframe_srcdoc) override;
-    virtual void DidCommitProvisionalLoadForFrame(
+    void DidCommitProvisionalLoadForFrame(
         content::RenderFrameHost* render_frame_host,
         const GURL& validated_url,
         ui::PageTransition transition_type) override;
-    virtual void DidFailProvisionalLoad(
+    void DidFailProvisionalLoad(
         content::RenderFrameHost* render_frame_host,
         const GURL& validated_url,
         int error_code,
         const base::string16& error_description) override;
-    virtual void WebContentsDestroyed() override;
+    void WebContentsDestroyed() override;
 
    private:
     void RecordEvent(PrerenderEvent event) const;
diff --git a/chrome/browser/prerender/prerender_manager_factory.h b/chrome/browser/prerender/prerender_manager_factory.h
index 27c6b19e..f3e9433 100644
--- a/chrome/browser/prerender/prerender_manager_factory.h
+++ b/chrome/browser/prerender/prerender_manager_factory.h
@@ -29,12 +29,12 @@
   friend struct DefaultSingletonTraits<PrerenderManagerFactory>;
 
   PrerenderManagerFactory();
-  virtual ~PrerenderManagerFactory();
+  ~PrerenderManagerFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
 };
 
diff --git a/chrome/browser/prerender/prerender_message_filter.h b/chrome/browser/prerender/prerender_message_filter.h
index 3680d4e..2f96b46 100644
--- a/chrome/browser/prerender/prerender_message_filter.h
+++ b/chrome/browser/prerender/prerender_message_filter.h
@@ -31,14 +31,13 @@
   PrerenderMessageFilter(int render_process_id, Profile* profile);
 
  private:
-  virtual ~PrerenderMessageFilter();
+  ~PrerenderMessageFilter() override;
 
   // Overridden from content::BrowserMessageFilter.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
-  virtual void OverrideThreadForMessage(
-      const IPC::Message& message,
-      content::BrowserThread::ID* thread) override;
-  virtual void OnChannelClosing() override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+  void OverrideThreadForMessage(const IPC::Message& message,
+                                content::BrowserThread::ID* thread) override;
+  void OnChannelClosing() override;
 
   void OnAddPrerender(int prerender_id,
                       const PrerenderAttributes& attributes,
diff --git a/chrome/browser/prerender/prerender_pending_swap_throttle.h b/chrome/browser/prerender/prerender_pending_swap_throttle.h
index 6097ccd9..0652519 100644
--- a/chrome/browser/prerender/prerender_pending_swap_throttle.h
+++ b/chrome/browser/prerender/prerender_pending_swap_throttle.h
@@ -31,9 +31,9 @@
                                PrerenderTracker* tracker);
 
   // content::ResourceThrottle implementation:
-  virtual void WillStartRequest(bool* defer) override;
+  void WillStartRequest(bool* defer) override;
 
-  virtual const char* GetNameForLogging() const override;
+  const char* GetNameForLogging() const override;
 
   // Called by the PrerenderTracker when the swap failed.
   // May only be called if currently throttling the resource.
diff --git a/chrome/browser/prerender/prerender_resource_throttle.h b/chrome/browser/prerender/prerender_resource_throttle.h
index dd6d5cc..ae993c8 100644
--- a/chrome/browser/prerender/prerender_resource_throttle.h
+++ b/chrome/browser/prerender/prerender_resource_throttle.h
@@ -31,9 +31,9 @@
   explicit PrerenderResourceThrottle(net::URLRequest* request);
 
   // content::ResourceThrottle implementation:
-  virtual void WillStartRequest(bool* defer) override;
-  virtual void WillRedirectRequest(const GURL& new_url, bool* defer) override;
-  virtual const char* GetNameForLogging() const override;
+  void WillStartRequest(bool* defer) override;
+  void WillRedirectRequest(const GURL& new_url, bool* defer) override;
+  const char* GetNameForLogging() const override;
 
   // Called by the PrerenderContents when a prerender becomes visible.
   // May only be called if currently throttling the resource.
diff --git a/chrome/browser/prerender/prerender_tab_helper.h b/chrome/browser/prerender/prerender_tab_helper.h
index f842f0b1..397ca09 100644
--- a/chrome/browser/prerender/prerender_tab_helper.h
+++ b/chrome/browser/prerender/prerender_tab_helper.h
@@ -48,20 +48,19 @@
       content::WebContents* web_contents,
       password_manager::PasswordManager* password_manager);
 
-  virtual ~PrerenderTabHelper();
+  ~PrerenderTabHelper() override;
 
   // content::WebContentsObserver implementation.
-  virtual void DidGetRedirectForResourceRequest(
+  void DidGetRedirectForResourceRequest(
       content::RenderViewHost* render_view_host,
       const content::ResourceRedirectDetails& details) override;
-  virtual void DidStopLoading(
-      content::RenderViewHost* render_view_host) override;
-  virtual void DidStartProvisionalLoadForFrame(
+  void DidStopLoading(content::RenderViewHost* render_view_host) override;
+  void DidStartProvisionalLoadForFrame(
       content::RenderFrameHost* render_frame_host,
       const GURL& validated_url,
       bool is_error_page,
       bool is_iframe_srcdoc) override;
-  virtual void DidCommitProvisionalLoadForFrame(
+  void DidCommitProvisionalLoadForFrame(
       content::RenderFrameHost* render_frame_host,
       const GURL& validated_url,
       ui::PageTransition transition_type) override;
diff --git a/chrome/browser/prerender/prerender_tracker_unittest.cc b/chrome/browser/prerender/prerender_tracker_unittest.cc
index 4a48a87..70cce6b 100644
--- a/chrome/browser/prerender/prerender_tracker_unittest.cc
+++ b/chrome/browser/prerender/prerender_tracker_unittest.cc
@@ -46,18 +46,18 @@
     PrerenderResourceThrottle::OverridePrerenderContentsForTesting(this);
   }
 
-  virtual ~TestPrerenderContents() {
+  ~TestPrerenderContents() override {
     if (final_status() == FINAL_STATUS_MAX)
       SetFinalStatus(FINAL_STATUS_USED);
     PrerenderResourceThrottle::OverridePrerenderContentsForTesting(NULL);
   }
 
-  virtual bool GetChildId(int* child_id) const override {
+  bool GetChildId(int* child_id) const override {
     *child_id = child_id_;
     return true;
   }
 
-  virtual bool GetRouteId(int* route_id) const override {
+  bool GetRouteId(int* route_id) const override {
     *route_id = route_id_;
     return true;
   }
@@ -89,9 +89,8 @@
 
   // We never allocate our PrerenderContents in PrerenderManager, so we don't
   // ever want the default pending delete behaviour.
-  virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
-                                        FinalStatus final_status) override {
-  }
+  void MoveEntryToPendingDelete(PrerenderContents* entry,
+                                FinalStatus final_status) override {}
 };
 
 class DeferredRedirectDelegate : public net::URLRequest::Delegate,
@@ -119,9 +118,9 @@
   bool resume_called() const { return resume_called_; }
 
   // net::URLRequest::Delegate implementation:
-  virtual void OnReceivedRedirect(net::URLRequest* request,
-                                  const net::RedirectInfo& redirect_info,
-                                  bool* defer_redirect) override {
+  void OnReceivedRedirect(net::URLRequest* request,
+                          const net::RedirectInfo& redirect_info,
+                          bool* defer_redirect) override {
     // Defer the redirect either way.
     *defer_redirect = true;
 
@@ -129,22 +128,20 @@
     throttle_->WillRedirectRequest(redirect_info.new_url, &was_deferred_);
     run_loop_->Quit();
   }
-  virtual void OnResponseStarted(net::URLRequest* request) override { }
-  virtual void OnReadCompleted(net::URLRequest* request,
-                               int bytes_read) override {
-  }
+  void OnResponseStarted(net::URLRequest* request) override {}
+  void OnReadCompleted(net::URLRequest* request, int bytes_read) override {}
 
   // content::ResourceController implementation:
-  virtual void Cancel() override {
+  void Cancel() override {
     EXPECT_FALSE(cancel_called_);
     EXPECT_FALSE(resume_called_);
 
     cancel_called_ = true;
     run_loop_->Quit();
   }
-  virtual void CancelAndIgnore() override { Cancel(); }
-  virtual void CancelWithError(int error_code) override { Cancel(); }
-  virtual void Resume() override {
+  void CancelAndIgnore() override { Cancel(); }
+  void CancelWithError(int error_code) override { Cancel(); }
+  void Resume() override {
     EXPECT_TRUE(was_deferred_);
     EXPECT_FALSE(cancel_called_);
     EXPECT_FALSE(resume_called_);
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc
index 6d6e2b2b..0a54294 100644
--- a/chrome/browser/prerender/prerender_unittest.cc
+++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -50,22 +50,22 @@
                          Origin origin,
                          FinalStatus expected_final_status);
 
-  virtual ~DummyPrerenderContents();
+  ~DummyPrerenderContents() override;
 
-  virtual void StartPrerendering(
+  void StartPrerendering(
       int creator_child_id,
       const gfx::Size& size,
       content::SessionStorageNamespace* session_storage_namespace,
       net::URLRequestContextGetter* request_context) override;
 
-  virtual bool GetChildId(int* child_id) const override {
+  bool GetChildId(int* child_id) const override {
     // Having a default child_id of -1 forces pending prerenders not to fail
     // on session storage and cross domain checking.
     *child_id = -1;
     return true;
   }
 
-  virtual bool GetRouteId(int* route_id) const override {
+  bool GetRouteId(int* route_id) const override {
     *route_id = route_id_;
     return true;
   }
@@ -107,19 +107,18 @@
     OnCookieStoreLoaded();
   }
 
-  virtual ~UnitTestPrerenderManager() {
-  }
+  ~UnitTestPrerenderManager() override {}
 
   // From KeyedService, via PrererenderManager:
-  virtual void Shutdown() override {
+  void Shutdown() override {
     if (next_prerender_contents())
       next_prerender_contents_->Destroy(FINAL_STATUS_MANAGER_SHUTDOWN);
     PrerenderManager::Shutdown();
   }
 
   // From PrerenderManager:
-  virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
-                                        FinalStatus final_status) override {
+  void MoveEntryToPendingDelete(PrerenderContents* entry,
+                                FinalStatus final_status) override {
     if (entry == next_prerender_contents_.get())
       return;
     PrerenderManager::MoveEntryToPendingDelete(entry, final_status);
@@ -203,16 +202,12 @@
   }
 
   // from PrerenderManager
-  virtual Time GetCurrentTime() const override {
-    return time_;
-  }
+  Time GetCurrentTime() const override { return time_; }
 
-  virtual TimeTicks GetCurrentTimeTicks() const override {
-    return time_ticks_;
-  }
+  TimeTicks GetCurrentTimeTicks() const override { return time_ticks_; }
 
-  virtual PrerenderContents* GetPrerenderContentsForRoute(
-      int child_id, int route_id) const override {
+  PrerenderContents* GetPrerenderContentsForRoute(int child_id,
+                                                  int route_id) const override {
     // Overridden for the PrerenderLinkManager's pending prerender logic.
     PrerenderContentsMap::const_iterator iter = prerender_contents_map_.find(
         std::make_pair(child_id, route_id));
@@ -234,9 +229,7 @@
   }
 
  protected:
-  virtual net::URLRequestContextGetter* GetURLRequestContext() override {
-    return NULL;
-  }
+  net::URLRequestContextGetter* GetURLRequestContext() override { return NULL; }
 
  private:
   void SetNextPrerenderContents(DummyPrerenderContents* prerender_contents) {
@@ -246,12 +239,10 @@
       used_prerender_contents_.push_back(prerender_contents);
   }
 
-
-  virtual PrerenderContents* CreatePrerenderContents(
-      const GURL& url,
-      const Referrer& referrer,
-      Origin origin,
-      uint8 experiment_id) override {
+  PrerenderContents* CreatePrerenderContents(const GURL& url,
+                                             const Referrer& referrer,
+                                             Origin origin,
+                                             uint8 experiment_id) override {
     CHECK(next_prerender_contents_.get());
     EXPECT_EQ(url, next_prerender_contents_->prerender_url());
     EXPECT_EQ(origin, next_prerender_contents_->origin());
diff --git a/chrome/browser/printing/background_printing_manager.cc b/chrome/browser/printing/background_printing_manager.cc
index 3a891bc..daa8402d 100644
--- a/chrome/browser/printing/background_printing_manager.cc
+++ b/chrome/browser/printing/background_printing_manager.cc
@@ -27,8 +27,8 @@
   Observer(BackgroundPrintingManager* manager, WebContents* web_contents);
 
  private:
-  virtual void RenderProcessGone(base::TerminationStatus status) override;
-  virtual void WebContentsDestroyed() override;
+  void RenderProcessGone(base::TerminationStatus status) override;
+  void WebContentsDestroyed() override;
 
   BackgroundPrintingManager* manager_;
 };
diff --git a/chrome/browser/printing/background_printing_manager.h b/chrome/browser/printing/background_printing_manager.h
index 3899dbb..fdcc952 100644
--- a/chrome/browser/printing/background_printing_manager.h
+++ b/chrome/browser/printing/background_printing_manager.h
@@ -31,7 +31,7 @@
   typedef std::map<content::WebContents*, Observer*> WebContentsObserverMap;
 
   BackgroundPrintingManager();
-  virtual ~BackgroundPrintingManager();
+  ~BackgroundPrintingManager() override;
 
   // Takes ownership of |preview_dialog| and deletes it when |preview_dialog|
   // finishes printing. This removes |preview_dialog| from its ConstrainedDialog
@@ -46,9 +46,9 @@
 
  private:
   // content::NotificationObserver overrides:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Schedule deletion of |preview_contents|.
   void DeletePreviewContents(content::WebContents* preview_contents);
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h
index cef60be..6f4b7dc 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h
+++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service.h
@@ -31,7 +31,7 @@
 class CloudPrintProxyService : public KeyedService {
  public:
   explicit CloudPrintProxyService(Profile* profile);
-  virtual ~CloudPrintProxyService();
+  ~CloudPrintProxyService() override;
 
   typedef base::Callback<void(const std::vector<std::string>&)>
       PrintersCallback;
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h
index d8c6877..c14e04d9 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h
+++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h
@@ -27,12 +27,12 @@
   friend struct DefaultSingletonTraits<CloudPrintProxyServiceFactory>;
 
   CloudPrintProxyServiceFactory();
-  virtual ~CloudPrintProxyServiceFactory();
+  ~CloudPrintProxyServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsNULLWhileTesting() const override;
 };
 
 #endif  // CHROME_BROWSER_PRINTING_CLOUD_PRINT_CLOUD_PRINT_PROXY_SERVICE_FACTORY_H_
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc
index db8129e..b0d6613 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc
@@ -183,7 +183,7 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  virtual ServiceProcessControl* GetServiceProcessControl() override {
+  ServiceProcessControl* GetServiceProcessControl() override {
     return &process_control_;
   }
   MockServiceProcessControl* GetMockServiceProcessControl() {
diff --git a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc
index 1ffdd53..c3bfbeb 100644
--- a/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc
+++ b/chrome/browser/printing/cloud_print/test/cloud_print_proxy_process_browsertest.cc
@@ -89,9 +89,7 @@
 
 class TestStartupClientChannelListener : public IPC::Listener {
  public:
-  virtual bool OnMessageReceived(const IPC::Message& message) override {
-    return false;
-  }
+  bool OnMessageReceived(const IPC::Message& message) override { return false; }
 };
 
 }  // namespace
@@ -99,7 +97,7 @@
 class TestServiceProcess : public ServiceProcess {
  public:
   TestServiceProcess() { }
-  virtual ~TestServiceProcess() { }
+  ~TestServiceProcess() override {}
 
   bool Initialize(base::MessageLoopForUI* message_loop,
                   ServiceProcessState* state);
@@ -316,13 +314,11 @@
   void ShutdownAndWaitForExitWithTimeout(base::ProcessHandle handle);
 
   // IPC::Listener implementation
-  virtual bool OnMessageReceived(const IPC::Message& message) override {
-    return false;
-  }
-  virtual void OnChannelConnected(int32 peer_pid) override;
+  bool OnMessageReceived(const IPC::Message& message) override { return false; }
+  void OnChannelConnected(int32 peer_pid) override;
 
   // MultiProcessTest implementation.
-  virtual CommandLine MakeCmdLine(const std::string& procname) override;
+  CommandLine MakeCmdLine(const std::string& procname) override;
 
   bool LaunchBrowser(const CommandLine& command_line, Profile* profile) {
     int return_code = 0;
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index 5aa77aeb..b5d49f0 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -143,7 +143,7 @@
 
  private:
   // Overridden from content::WebContentsObserver:
-  virtual void DidNavigateMainFrame(
+  void DidNavigateMainFrame(
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) override {
     if (IsSimilarUrl(params.url, cloud_print_url_)) {
@@ -154,9 +154,7 @@
     }
   }
 
-  virtual void WebContentsDestroyed() override {
-    delete this;
-  }
+  void WebContentsDestroyed() override { delete this; }
 
   void OnSignIn() {
     callback_.Run();
diff --git a/chrome/browser/printing/print_dialog_cloud_internal.h b/chrome/browser/printing/print_dialog_cloud_internal.h
index e904113..eae8384 100644
--- a/chrome/browser/printing/print_dialog_cloud_internal.h
+++ b/chrome/browser/printing/print_dialog_cloud_internal.h
@@ -99,15 +99,15 @@
                         const base::string16& print_job_title,
                         const base::string16& print_ticket,
                         const std::string& file_type);
-  virtual ~CloudPrintFlowHandler();
+  ~CloudPrintFlowHandler() override;
 
   // WebUIMessageHandler implementation.
-  virtual void RegisterMessages() override;
+  void RegisterMessages() override;
 
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Callbacks from the page.
   void HandleShowDebugger(const base::ListValue* args);
@@ -152,22 +152,21 @@
                               const base::string16& print_job_title,
                               const base::string16& print_ticket,
                               const std::string& file_type);
-  virtual ~CloudPrintWebDialogDelegate();
+  ~CloudPrintWebDialogDelegate() override;
 
   // ui::WebDialogDelegate implementation:
-  virtual ui::ModalType GetDialogModalType() const override;
-  virtual base::string16 GetDialogTitle() const override;
-  virtual GURL GetDialogContentURL() const override;
-  virtual void GetWebUIMessageHandlers(
+  ui::ModalType GetDialogModalType() const override;
+  base::string16 GetDialogTitle() const override;
+  GURL GetDialogContentURL() const override;
+  void GetWebUIMessageHandlers(
       std::vector<content::WebUIMessageHandler*>* handlers) const override;
-  virtual void GetDialogSize(gfx::Size* size) const override;
-  virtual std::string GetDialogArgs() const override;
-  virtual void OnDialogClosed(const std::string& json_retval) override;
-  virtual void OnCloseContents(content::WebContents* source,
-                               bool* out_close_dialog) override;
-  virtual bool ShouldShowDialogTitle() const override;
-  virtual bool HandleContextMenu(
-      const content::ContextMenuParams& params) override;
+  void GetDialogSize(gfx::Size* size) const override;
+  std::string GetDialogArgs() const override;
+  void OnDialogClosed(const std::string& json_retval) override;
+  void OnCloseContents(content::WebContents* source,
+                       bool* out_close_dialog) override;
+  bool ShouldShowDialogTitle() const override;
+  bool HandleContextMenu(const content::ContextMenuParams& params) override;
 
  private:
   friend class ::CloudPrintWebDialogDelegateTest;
diff --git a/chrome/browser/printing/print_job.h b/chrome/browser/printing/print_job.h
index ae22e98..c468bbd 100644
--- a/chrome/browser/printing/print_job.h
+++ b/chrome/browser/printing/print_job.h
@@ -49,16 +49,16 @@
                   int page_count);
 
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // PrintJobWorkerOwner implementation.
-  virtual void GetSettingsDone(const PrintSettings& new_settings,
-                               PrintingContext::Result result) override;
-  virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) override;
-  virtual const PrintSettings& settings() const override;
-  virtual int cookie() const override;
+  void GetSettingsDone(const PrintSettings& new_settings,
+                       PrintingContext::Result result) override;
+  PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) override;
+  const PrintSettings& settings() const override;
+  int cookie() const override;
 
   // Starts the actual printing. Signals the worker that it should begin to
   // spool as soon as data is available.
@@ -98,7 +98,7 @@
 #endif  // OS_WIN
 
  protected:
-  virtual ~PrintJob();
+  ~PrintJob() override;
 
  private:
   // Updates document_ to a new instance.
diff --git a/chrome/browser/printing/print_job_manager.h b/chrome/browser/printing/print_job_manager.h
index 32d5b30..22c72bb0 100644
--- a/chrome/browser/printing/print_job_manager.h
+++ b/chrome/browser/printing/print_job_manager.h
@@ -58,15 +58,15 @@
 class PrintJobManager : public content::NotificationObserver {
  public:
   PrintJobManager();
-  virtual ~PrintJobManager();
+  ~PrintJobManager() override;
 
   // On browser quit, we should wait to have the print job finished.
   void Shutdown();
 
   // content::NotificationObserver
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Returns queries queue. Never returns NULL. Must be called on Browser UI
   // Thread. Reference could be stored and used from any thread.
diff --git a/chrome/browser/printing/print_job_unittest.cc b/chrome/browser/printing/print_job_unittest.cc
index 118c4b18..b514682 100644
--- a/chrome/browser/printing/print_job_unittest.cc
+++ b/chrome/browser/printing/print_job_unittest.cc
@@ -19,9 +19,7 @@
 
 class TestSource : public printing::PrintedPagesSource {
  public:
-  virtual base::string16 RenderSourceName() override {
-    return base::string16();
-  }
+  base::string16 RenderSourceName() override { return base::string16(); }
 };
 
 class TestPrintJobWorker : public printing::PrintJobWorker {
@@ -35,12 +33,11 @@
 
 class TestOwner : public printing::PrintJobWorkerOwner {
  public:
-  virtual void GetSettingsDone(
-      const printing::PrintSettings& new_settings,
-      printing::PrintingContext::Result result) override {
+  void GetSettingsDone(const printing::PrintSettings& new_settings,
+                       printing::PrintingContext::Result result) override {
     EXPECT_FALSE(true);
   }
-  virtual printing::PrintJobWorker* DetachWorker(
+  printing::PrintJobWorker* DetachWorker(
       printing::PrintJobWorkerOwner* new_owner) override {
     // We're screwing up here since we're calling worker from the main thread.
     // That's fine for testing. It is actually simulating PrinterQuery behavior.
@@ -50,15 +47,11 @@
     settings_ = worker->printing_context()->settings();
     return worker;
   }
-  virtual const printing::PrintSettings& settings() const override {
-    return settings_;
-  }
-  virtual int cookie() const override {
-    return 42;
-  }
+  const printing::PrintSettings& settings() const override { return settings_; }
+  int cookie() const override { return 42; }
 
  private:
-  virtual ~TestOwner() {}
+  ~TestOwner() override {}
 
   printing::PrintSettings settings_;
 };
@@ -68,18 +61,16 @@
   explicit TestPrintJob(volatile bool* check) : check_(check) {
   }
  private:
-  virtual ~TestPrintJob() {
-    *check_ = true;
-  }
+  ~TestPrintJob() override { *check_ = true; }
   volatile bool* check_;
 };
 
 class TestPrintNotifObserv : public content::NotificationObserver {
  public:
   // content::NotificationObserver
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override {
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {
     ADD_FAILURE();
   }
 };
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index 2313d6a..ee8cdde 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -39,10 +39,10 @@
 class PrintingContextDelegate : public PrintingContext::Delegate {
  public:
   PrintingContextDelegate(int render_process_id, int render_view_id);
-  virtual ~PrintingContextDelegate();
+  ~PrintingContextDelegate() override;
 
-  virtual gfx::NativeView GetParentView() override;
-  virtual std::string GetAppLocale() override;
+  gfx::NativeView GetParentView() override;
+  std::string GetAppLocale() override;
 
  private:
   int render_process_id_;
diff --git a/chrome/browser/printing/print_preview_context_menu_observer.h b/chrome/browser/printing/print_preview_context_menu_observer.h
index aaf10fd..e1a11ef 100644
--- a/chrome/browser/printing/print_preview_context_menu_observer.h
+++ b/chrome/browser/printing/print_preview_context_menu_observer.h
@@ -16,11 +16,11 @@
 class PrintPreviewContextMenuObserver : public RenderViewContextMenuObserver {
  public:
   explicit PrintPreviewContextMenuObserver(content::WebContents* contents);
-  virtual ~PrintPreviewContextMenuObserver();
+  ~PrintPreviewContextMenuObserver() override;
 
   // RenderViewContextMenuObserver implementation.
-  virtual bool IsCommandIdSupported(int command_id) override;
-  virtual bool IsCommandIdEnabled(int command_id) override;
+  bool IsCommandIdSupported(int command_id) override;
+  bool IsCommandIdEnabled(int command_id) override;
 
  private:
   bool IsPrintPreviewDialog();
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc
index 3f3e94f9..9a93111 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -69,19 +69,18 @@
 class PrintPreviewDialogDelegate : public ui::WebDialogDelegate {
  public:
   explicit PrintPreviewDialogDelegate(WebContents* initiator);
-  virtual ~PrintPreviewDialogDelegate();
+  ~PrintPreviewDialogDelegate() override;
 
-  virtual ui::ModalType GetDialogModalType() const override;
-  virtual base::string16 GetDialogTitle() const override;
-  virtual GURL GetDialogContentURL() const override;
-  virtual void GetWebUIMessageHandlers(
+  ui::ModalType GetDialogModalType() const override;
+  base::string16 GetDialogTitle() const override;
+  GURL GetDialogContentURL() const override;
+  void GetWebUIMessageHandlers(
       std::vector<WebUIMessageHandler*>* handlers) const override;
-  virtual void GetDialogSize(gfx::Size* size) const override;
-  virtual std::string GetDialogArgs() const override;
-  virtual void OnDialogClosed(const std::string& json_retval) override;
-  virtual void OnCloseContents(WebContents* source,
-                               bool* out_close_dialog) override;
-  virtual bool ShouldShowDialogTitle() const override;
+  void GetDialogSize(gfx::Size* size) const override;
+  std::string GetDialogArgs() const override;
+  void OnDialogClosed(const std::string& json_retval) override;
+  void OnCloseContents(WebContents* source, bool* out_close_dialog) override;
+  bool ShouldShowDialogTitle() const override;
 
  private:
   WebContents* initiator_;
diff --git a/chrome/browser/printing/print_preview_dialog_controller.h b/chrome/browser/printing/print_preview_dialog_controller.h
index ecd2ead..493e1c2 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.h
+++ b/chrome/browser/printing/print_preview_dialog_controller.h
@@ -62,9 +62,9 @@
       base::Callback<void(content::WebContents*)> callback);
 
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Returns true if |contents| is a print preview dialog.
   static bool IsPrintPreviewDialog(content::WebContents* contents);
@@ -88,7 +88,7 @@
   typedef std::map<content::WebContents*, content::WebContents*>
       PrintPreviewDialogMap;
 
-  virtual ~PrintPreviewDialogController();
+  ~PrintPreviewDialogController() override;
 
   // Handler for the RENDERER_PROCESS_CLOSED notification. This is observed when
   // the initiator renderer crashed.
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
index 4871112..facedba1 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -25,7 +25,7 @@
   explicit RequestPrintPreviewObserver(WebContents* dialog)
       : WebContentsObserver(dialog) {
   }
-  virtual ~RequestPrintPreviewObserver() {}
+  ~RequestPrintPreviewObserver() override {}
 
   void set_quit_closure(const base::Closure& quit_closure) {
     quit_closure_ = quit_closure;
@@ -33,7 +33,7 @@
 
  private:
   // content::WebContentsObserver implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) override {
+  bool OnMessageReceived(const IPC::Message& message) override {
     IPC_BEGIN_MESSAGE_MAP(RequestPrintPreviewObserver, message)
       IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
                           OnRequestPrintPreview)
@@ -57,7 +57,7 @@
   explicit PrintPreviewDialogClonedObserver(WebContents* dialog)
       : WebContentsObserver(dialog) {
   }
-  virtual ~PrintPreviewDialogClonedObserver() {}
+  ~PrintPreviewDialogClonedObserver() override {}
 
   RequestPrintPreviewObserver* request_preview_dialog_observer() {
     return request_preview_dialog_observer_.get();
@@ -65,9 +65,8 @@
 
  private:
   // content::WebContentsObserver implementation.
-  virtual void DidCloneToNewWebContents(
-      WebContents* old_web_contents,
-      WebContents* new_web_contents) override {
+  void DidCloneToNewWebContents(WebContents* old_web_contents,
+                                WebContents* new_web_contents) override {
     request_preview_dialog_observer_.reset(
         new RequestPrintPreviewObserver(new_web_contents));
   }
@@ -83,15 +82,13 @@
       : WebContentsObserver(dialog),
         dialog_destroyed_(false) {
   }
-  virtual ~PrintPreviewDialogDestroyedObserver() {}
+  ~PrintPreviewDialogDestroyedObserver() override {}
 
   bool dialog_destroyed() const { return dialog_destroyed_; }
 
  private:
   // content::WebContentsObserver implementation.
-  virtual void WebContentsDestroyed() override {
-    dialog_destroyed_ = true;
-  }
+  void WebContentsDestroyed() override { dialog_destroyed_ = true; }
 
   bool dialog_destroyed_;
 
@@ -121,7 +118,7 @@
   }
 
  private:
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     WebContents* first_tab =
         browser()->tab_strip_model()->GetActiveWebContents();
     ASSERT_TRUE(first_tab);
@@ -139,7 +136,7 @@
     ASSERT_NE(first_tab, initiator_);
   }
 
-  virtual void TearDownOnMainThread() override {
+  void TearDownOnMainThread() override {
     cloned_tab_observer_.reset();
     initiator_ = NULL;
   }
diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h
index ad72e872..e91dc3d 100644
--- a/chrome/browser/printing/print_preview_message_handler.h
+++ b/chrome/browser/printing/print_preview_message_handler.h
@@ -33,10 +33,10 @@
     : public content::WebContentsObserver,
       public content::WebContentsUserData<PrintPreviewMessageHandler> {
  public:
-  virtual ~PrintPreviewMessageHandler();
+  ~PrintPreviewMessageHandler() override;
 
   // content::WebContentsObserver implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
  private:
   explicit PrintPreviewMessageHandler(content::WebContents* web_contents);
diff --git a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
index bd93dc2c..646f954e 100644
--- a/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
+++ b/chrome/browser/printing/print_preview_pdf_generated_browsertest.cc
@@ -118,7 +118,7 @@
         failed_setting_("None"),
         pdf_file_save_path_(pdf_file_save_path) {}
 
-  virtual ~PrintPreviewObserver() {}
+  ~PrintPreviewObserver() override {}
 
   // Sets closure for the observer so that it can end the loop.
   void set_quit_closure(const base::Closure &closure) {
@@ -130,7 +130,7 @@
     base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
   }
 
-  virtual bool OnMessageReceived(const IPC::Message& message) override {
+  bool OnMessageReceived(const IPC::Message& message) override {
     IPC_BEGIN_MESSAGE_MAP(PrintPreviewObserver, message)
       IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
                           OnDidGetPreviewPageCount)
@@ -222,7 +222,7 @@
     explicit UIDoneLoadingMessageHandler(PrintPreviewObserver* observer)
         : observer_(observer) {}
 
-    virtual ~UIDoneLoadingMessageHandler() {}
+    ~UIDoneLoadingMessageHandler() override {}
 
     // When a setting has been set succesfully, this is called and the observer
     // is told to send the next setting to be set.
@@ -242,7 +242,7 @@
     // successfully set and its effects have been finalized.
     // 'UIFailedLoadingForTest' is sent when the setting could not be set. This
     // causes the browser test to fail.
-    virtual void RegisterMessages() override {
+    void RegisterMessages() override {
       web_ui()->RegisterMessageCallback(
           "UILoadedForTest",
           base::Bind(&UIDoneLoadingMessageHandler::HandleDone,
@@ -277,9 +277,8 @@
     ui->web_ui()->CallJavascriptFunction("onEnableManipulateSettingsForTest");
   }
 
-  virtual void DidCloneToNewWebContents(
-      WebContents* old_web_contents,
-      WebContents* new_web_contents) override {
+  void DidCloneToNewWebContents(WebContents* old_web_contents,
+                                WebContents* new_web_contents) override {
     Observe(new_web_contents);
   }
 
diff --git a/chrome/browser/printing/print_preview_test.cc b/chrome/browser/printing/print_preview_test.cc
index 1ebfd131..3d9c1a5 100644
--- a/chrome/browser/printing/print_preview_test.cc
+++ b/chrome/browser/printing/print_preview_test.cc
@@ -26,7 +26,7 @@
   PrintPreviewTestBrowserWindow() {}
 
   // BrowserWindow overrides
-  virtual WebContentsModalDialogHost* GetWebContentsModalDialogHost() override {
+  WebContentsModalDialogHost* GetWebContentsModalDialogHost() override {
     return this;
   }
 
@@ -34,23 +34,19 @@
 
   // The web contents modal dialog must be parented to *something*; use the
   // WebContents window since there is no true browser window for unit tests.
-  virtual gfx::NativeView GetHostView() const override {
+  gfx::NativeView GetHostView() const override {
     return FindBrowser()->tab_strip_model()->GetActiveWebContents()->
         GetNativeView();
   }
 
-  virtual gfx::Point GetDialogPosition(const gfx::Size& size) override {
+  gfx::Point GetDialogPosition(const gfx::Size& size) override {
     return gfx::Point();
   }
 
-  virtual gfx::Size GetMaximumDialogSize() override {
-    return gfx::Size();
-  }
+  gfx::Size GetMaximumDialogSize() override { return gfx::Size(); }
 
-  virtual void AddObserver(
-      ModalDialogHostObserver* observer) override {}
-  virtual void RemoveObserver(
-      ModalDialogHostObserver* observer) override {}
+  void AddObserver(ModalDialogHostObserver* observer) override {}
+  void RemoveObserver(ModalDialogHostObserver* observer) override {}
 
  private:
   Browser* FindBrowser() const {
diff --git a/chrome/browser/printing/print_preview_test.h b/chrome/browser/printing/print_preview_test.h
index 1932c875..2a843c4d 100644
--- a/chrome/browser/printing/print_preview_test.h
+++ b/chrome/browser/printing/print_preview_test.h
@@ -16,7 +16,7 @@
   virtual void SetUp() override;
 
   // Create a browser window to provide parenting for web contents modal dialog.
-  virtual BrowserWindow* CreateBrowserWindow() override;
+  BrowserWindow* CreateBrowserWindow() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PrintPreviewTest);
diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h
index c1b12cc..444f003 100644
--- a/chrome/browser/printing/print_view_manager.h
+++ b/chrome/browser/printing/print_view_manager.h
@@ -20,7 +20,7 @@
 class PrintViewManager : public PrintViewManagerBase,
                          public content::WebContentsUserData<PrintViewManager> {
  public:
-  virtual ~PrintViewManager();
+  ~PrintViewManager() override;
 
 #if !defined(DISABLE_BASIC_PRINTING)
   // Same as PrintNow(), but for the case where a user prints with the system
@@ -53,11 +53,11 @@
   void set_observer(PrintViewManagerObserver* observer);
 
   // content::WebContentsObserver implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // content::WebContentsObserver implementation.
   // Terminates or cancels the print job if one was pending.
-  virtual void RenderProcessGone(base::TerminationStatus status) override;
+  void RenderProcessGone(base::TerminationStatus status) override;
 
  private:
   explicit PrintViewManager(content::WebContents* web_contents);
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h
index 7e1cee5..85738c4b 100644
--- a/chrome/browser/printing/print_view_manager_base.h
+++ b/chrome/browser/printing/print_view_manager_base.h
@@ -33,7 +33,7 @@
                              public PrintedPagesSource,
                              public content::WebContentsObserver {
  public:
-  virtual ~PrintViewManagerBase();
+  ~PrintViewManagerBase() override;
 
 #if !defined(DISABLE_BASIC_PRINTING)
   // Prints the current document immediately. Since the rendering is
@@ -46,7 +46,7 @@
   void UpdateScriptedPrintingBlocked();
 
   // PrintedPagesSource implementation.
-  virtual base::string16 RenderSourceName() override;
+  base::string16 RenderSourceName() override;
 
  protected:
   explicit PrintViewManagerBase(content::WebContents* web_contents);
@@ -55,26 +55,25 @@
   bool PrintNowInternal(IPC::Message* message);
 
   // Terminates or cancels the print job if one was pending.
-  virtual void RenderProcessGone(base::TerminationStatus status) override;
+  void RenderProcessGone(base::TerminationStatus status) override;
 
   // content::WebContentsObserver implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // IPC Message handlers.
   virtual void OnPrintingFailed(int cookie);
 
  private:
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // content::WebContentsObserver implementation.
-  virtual void DidStartLoading(
-      content::RenderViewHost* render_view_host) override;
+  void DidStartLoading(content::RenderViewHost* render_view_host) override;
 
   // Cancels the print job.
-  virtual void NavigationStopped() override;
+  void NavigationStopped() override;
 
   // IPC Message handlers.
   void OnDidGetPrintedPagesCount(int cookie, int number_pages);
diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h
index 9fd9a82..dcabfdd 100644
--- a/chrome/browser/printing/printer_query.h
+++ b/chrome/browser/printing/printer_query.h
@@ -32,11 +32,11 @@
   PrinterQuery(int render_process_id, int render_view_id);
 
   // PrintJobWorkerOwner implementation.
-  virtual void GetSettingsDone(const PrintSettings& new_settings,
-                               PrintingContext::Result result) override;
-  virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) override;
-  virtual const PrintSettings& settings() const override;
-  virtual int cookie() const override;
+  void GetSettingsDone(const PrintSettings& new_settings,
+                       PrintingContext::Result result) override;
+  PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) override;
+  const PrintSettings& settings() const override;
+  int cookie() const override;
 
   // Initializes the printing context. It is fine to call this function multiple
   // times to reinitialize the settings. |web_contents_observer| can be queried
@@ -65,7 +65,7 @@
   bool is_valid() const;
 
  private:
-  virtual ~PrinterQuery();
+  ~PrinterQuery() override;
 
   // Lazy create the worker thread. There is one worker thread per print job.
   void StartWorker(const base::Closure& callback);
diff --git a/chrome/browser/printing/printing_message_filter.h b/chrome/browser/printing/printing_message_filter.h
index b160cce..80ed60b 100644
--- a/chrome/browser/printing/printing_message_filter.h
+++ b/chrome/browser/printing/printing_message_filter.h
@@ -40,13 +40,12 @@
   PrintingMessageFilter(int render_process_id, Profile* profile);
 
   // content::BrowserMessageFilter methods.
-  virtual void OverrideThreadForMessage(
-      const IPC::Message& message,
-      content::BrowserThread::ID* thread) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OverrideThreadForMessage(const IPC::Message& message,
+                                content::BrowserThread::ID* thread) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
  private:
-  virtual ~PrintingMessageFilter();
+  ~PrintingMessageFilter() override;
 
 #if defined(OS_WIN)
   // Used to pass resulting EMF from renderer to browser in printing.
diff --git a/chrome/browser/profiles/avatar_menu.h b/chrome/browser/profiles/avatar_menu.h
index 1bdf2ae..8d746e5 100644
--- a/chrome/browser/profiles/avatar_menu.h
+++ b/chrome/browser/profiles/avatar_menu.h
@@ -87,7 +87,7 @@
   AvatarMenu(ProfileInfoInterface* profile_cache,
              AvatarMenuObserver* observer,
              Browser* browser);
-  virtual ~AvatarMenu();
+  ~AvatarMenu() override;
 
   // True if avatar menu should be displayed.
   static bool ShouldShowAvatarMenu();
@@ -147,14 +147,14 @@
   bool ShouldShowEditProfileLink() const;
 
   // content::NotificationObserver:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
  private:
 #if defined(ENABLE_MANAGED_USERS)
   // SupervisedUserServiceObserver:
-  virtual void OnCustodianInfoChanged() override;
+  void OnCustodianInfoChanged() override;
 #endif
 
   // The model that provides the list of menu items.
diff --git a/chrome/browser/profiles/avatar_menu_actions_desktop.h b/chrome/browser/profiles/avatar_menu_actions_desktop.h
index 031923f..a015c37 100644
--- a/chrome/browser/profiles/avatar_menu_actions_desktop.h
+++ b/chrome/browser/profiles/avatar_menu_actions_desktop.h
@@ -16,14 +16,14 @@
 class AvatarMenuActionsDesktop : public AvatarMenuActions {
  public:
   AvatarMenuActionsDesktop();
-  virtual ~AvatarMenuActionsDesktop();
+  ~AvatarMenuActionsDesktop() override;
 
   // AvatarMenuActions overrides:
-  virtual void AddNewProfile(ProfileMetrics::ProfileAdd type) override;
-  virtual void EditProfile(Profile* profile, size_t index) override;
-  virtual bool ShouldShowAddNewProfileLink() const override;
-  virtual bool ShouldShowEditProfileLink() const override;
-  virtual void ActiveBrowserChanged(Browser* browser) override;
+  void AddNewProfile(ProfileMetrics::ProfileAdd type) override;
+  void EditProfile(Profile* profile, size_t index) override;
+  bool ShouldShowAddNewProfileLink() const override;
+  bool ShouldShowEditProfileLink() const override;
+  void ActiveBrowserChanged(Browser* browser) override;
 
  private:
   // Browser in which this avatar menu resides. Weak.
diff --git a/chrome/browser/profiles/bookmark_model_loaded_observer.h b/chrome/browser/profiles/bookmark_model_loaded_observer.h
index 49b6722d..e96bffd 100644
--- a/chrome/browser/profiles/bookmark_model_loaded_observer.h
+++ b/chrome/browser/profiles/bookmark_model_loaded_observer.h
@@ -16,10 +16,9 @@
   explicit BookmarkModelLoadedObserver(Profile* profile);
 
  private:
-  virtual void BookmarkModelChanged() override;
-  virtual void BookmarkModelLoaded(BookmarkModel* model,
-                                   bool ids_reassigned) override;
-  virtual void BookmarkModelBeingDeleted(BookmarkModel* model) override;
+  void BookmarkModelChanged() override;
+  void BookmarkModelLoaded(BookmarkModel* model, bool ids_reassigned) override;
+  void BookmarkModelBeingDeleted(BookmarkModel* model) override;
 
   Profile* profile_;
 
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h
index 3120ae5..f20e834 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h
@@ -18,7 +18,7 @@
 class ChromeBrowserMainExtraPartsProfiles : public ChromeBrowserMainExtraParts {
  public:
   ChromeBrowserMainExtraPartsProfiles();
-  virtual ~ChromeBrowserMainExtraPartsProfiles();
+  ~ChromeBrowserMainExtraPartsProfiles() override;
 
   // Instantiates all chrome KeyedService factories, which is
   // especially important for services that should be created at profile
@@ -26,7 +26,7 @@
   static void EnsureBrowserContextKeyedServiceFactoriesBuilt();
 
   // Overridden from ChromeBrowserMainExtraParts:
-  virtual void PreProfileInit() override;
+  void PreProfileInit() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsProfiles);
diff --git a/chrome/browser/profiles/gaia_info_update_service.h b/chrome/browser/profiles/gaia_info_update_service.h
index 4e5c997d..03dc918 100644
--- a/chrome/browser/profiles/gaia_info_update_service.h
+++ b/chrome/browser/profiles/gaia_info_update_service.h
@@ -24,7 +24,7 @@
                               public SigninManagerBase::Observer {
  public:
   explicit GAIAInfoUpdateService(Profile* profile);
-  virtual ~GAIAInfoUpdateService();
+  ~GAIAInfoUpdateService() override;
 
   // Updates the GAIA info for the profile associated with this instance.
   virtual void Update();
@@ -33,17 +33,17 @@
   static bool ShouldUseGAIAProfileInfo(Profile* profile);
 
   // ProfileDownloaderDelegate:
-  virtual bool NeedsProfilePicture() const override;
-  virtual int GetDesiredImageSideLength() const override;
-  virtual Profile* GetBrowserProfile() override;
-  virtual std::string GetCachedPictureURL() const override;
-  virtual void OnProfileDownloadSuccess(ProfileDownloader* downloader) override;
-  virtual void OnProfileDownloadFailure(
+  bool NeedsProfilePicture() const override;
+  int GetDesiredImageSideLength() const override;
+  Profile* GetBrowserProfile() override;
+  std::string GetCachedPictureURL() const override;
+  void OnProfileDownloadSuccess(ProfileDownloader* downloader) override;
+  void OnProfileDownloadFailure(
       ProfileDownloader* downloader,
       ProfileDownloaderDelegate::FailureReason reason) override;
 
   // Overridden from KeyedService:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(GAIAInfoUpdateServiceTest, ScheduleUpdate);
@@ -52,11 +52,11 @@
   void ScheduleNextUpdate();
 
   // Overridden from SigninManagerBase::Observer:
-  virtual void GoogleSigninSucceeded(const std::string& account_id,
-                                     const std::string& username,
-                                     const std::string& password) override;
-  virtual void GoogleSignedOut(const std::string& account_id,
-                               const std::string& username) override;
+  void GoogleSigninSucceeded(const std::string& account_id,
+                             const std::string& username,
+                             const std::string& password) override;
+  void GoogleSignedOut(const std::string& account_id,
+                       const std::string& username) override;
 
   Profile* profile_;
   scoped_ptr<ProfileDownloader> profile_image_downloader_;
diff --git a/chrome/browser/profiles/gaia_info_update_service_factory.h b/chrome/browser/profiles/gaia_info_update_service_factory.h
index e594c49..9bd9c89 100644
--- a/chrome/browser/profiles/gaia_info_update_service_factory.h
+++ b/chrome/browser/profiles/gaia_info_update_service_factory.h
@@ -32,15 +32,15 @@
   friend struct DefaultSingletonTraits<GAIAInfoUpdateServiceFactory>;
 
   GAIAInfoUpdateServiceFactory();
-  virtual ~GAIAInfoUpdateServiceFactory();
+  ~GAIAInfoUpdateServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
 
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsNULLWhileTesting() const override;
 
   DISALLOW_COPY_AND_ASSIGN(GAIAInfoUpdateServiceFactory);
 };
diff --git a/chrome/browser/profiles/host_zoom_map_browsertest.cc b/chrome/browser/profiles/host_zoom_map_browsertest.cc
index 7f388bad..15c32ce 100644
--- a/chrome/browser/profiles/host_zoom_map_browsertest.cc
+++ b/chrome/browser/profiles/host_zoom_map_browsertest.cc
@@ -131,7 +131,7 @@
   }
 
   // BrowserTestBase:
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
     embedded_test_server()->RegisterRequestHandler(base::Bind(
         &HostZoomMapBrowserTest::HandleRequest, base::Unretained(this)));
@@ -150,7 +150,7 @@
 
  private:
   // InProcessBrowserTest:
-  virtual bool SetUpUserDataDirectory() override {
+  bool SetUpUserDataDirectory() override {
     std::replace(prefs_data_.begin(), prefs_data_.end(), '\'', '\"');
     // It seems the hash functions on different platforms can return different
     // values for the same input, so make sure we test with the hash appropriate
diff --git a/chrome/browser/profiles/incognito_mode_policy_handler.h b/chrome/browser/profiles/incognito_mode_policy_handler.h
index 9f09b6d..4d16637f 100644
--- a/chrome/browser/profiles/incognito_mode_policy_handler.h
+++ b/chrome/browser/profiles/incognito_mode_policy_handler.h
@@ -22,13 +22,13 @@
 class IncognitoModePolicyHandler : public ConfigurationPolicyHandler {
  public:
   IncognitoModePolicyHandler();
-  virtual ~IncognitoModePolicyHandler();
+  ~IncognitoModePolicyHandler() override;
 
   // ConfigurationPolicyHandler methods:
-  virtual bool CheckPolicySettings(const PolicyMap& policies,
-                                   PolicyErrorMap* errors) override;
-  virtual void ApplyPolicySettings(const PolicyMap& policies,
-                                   PrefValueMap* prefs) override;
+  bool CheckPolicySettings(const PolicyMap& policies,
+                           PolicyErrorMap* errors) override;
+  void ApplyPolicySettings(const PolicyMap& policies,
+                           PrefValueMap* prefs) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(IncognitoModePolicyHandler);
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 1e30d33..e38f12b 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/download/chrome_download_manager_delegate.h"
 #include "chrome/browser/download/download_service.h"
 #include "chrome/browser/download/download_service_factory.h"
-#include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "chrome/browser/io_thread.h"
 #include "chrome/browser/net/chrome_url_request_context_getter.h"
 #include "chrome/browser/net/pref_proxy_config_tracker.h"
@@ -72,6 +71,7 @@
 
 #if defined(ENABLE_EXTENSIONS)
 #include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "extensions/browser/api/web_request/web_request_api.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/guest_view/guest_view_manager.h"
@@ -355,6 +355,7 @@
 }
 
 HostContentSettingsMap* OffTheRecordProfileImpl::GetHostContentSettingsMap() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Retrieve the host content settings map of the parent profile in order to
   // ensure the preferences have been migrated.
   profile_->GetHostContentSettingsMap();
@@ -382,7 +383,11 @@
 
 storage::SpecialStoragePolicy*
 OffTheRecordProfileImpl::GetSpecialStoragePolicy() {
+#if defined(ENABLE_EXTENSIONS)
   return GetExtensionSpecialStoragePolicy();
+#else
+  return NULL;
+#endif
 }
 
 content::PushMessagingService*
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h
index c367409..53e0621e 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.h
+++ b/chrome/browser/profiles/off_the_record_profile_impl.h
@@ -32,42 +32,40 @@
 class OffTheRecordProfileImpl : public Profile {
  public:
   explicit OffTheRecordProfileImpl(Profile* real_profile);
-  virtual ~OffTheRecordProfileImpl();
+  ~OffTheRecordProfileImpl() override;
   void Init();
 
   // Profile implementation.
-  virtual std::string GetProfileName() override;
-  virtual ProfileType GetProfileType() const override;
-  virtual Profile* GetOffTheRecordProfile() override;
-  virtual void DestroyOffTheRecordProfile() override;
-  virtual bool HasOffTheRecordProfile() override;
-  virtual Profile* GetOriginalProfile() override;
-  virtual bool IsSupervised() override;
-  virtual ExtensionSpecialStoragePolicy*
-      GetExtensionSpecialStoragePolicy() override;
-  virtual PrefService* GetPrefs() override;
-  virtual PrefService* GetOffTheRecordPrefs() override;
-  virtual net::URLRequestContextGetter*
-      GetRequestContextForExtensions() override;
-  virtual net::URLRequestContextGetter* CreateRequestContext(
+  std::string GetProfileName() override;
+  ProfileType GetProfileType() const override;
+  Profile* GetOffTheRecordProfile() override;
+  void DestroyOffTheRecordProfile() override;
+  bool HasOffTheRecordProfile() override;
+  Profile* GetOriginalProfile() override;
+  bool IsSupervised() override;
+  ExtensionSpecialStoragePolicy* GetExtensionSpecialStoragePolicy() override;
+  PrefService* GetPrefs() override;
+  PrefService* GetOffTheRecordPrefs() override;
+  net::URLRequestContextGetter* GetRequestContextForExtensions() override;
+  net::URLRequestContextGetter* CreateRequestContext(
       content::ProtocolHandlerMap* protocol_handlers,
       content::URLRequestInterceptorScopedVector request_interceptors) override;
-  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+  net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
       const base::FilePath& partition_path,
       bool in_memory,
       content::ProtocolHandlerMap* protocol_handlers,
       content::URLRequestInterceptorScopedVector request_interceptors) override;
-  virtual net::SSLConfigService* GetSSLConfigService() override;
-  virtual HostContentSettingsMap* GetHostContentSettingsMap() override;
-  virtual bool IsSameProfile(Profile* profile) override;
-  virtual Time GetStartTime() const override;
-  virtual history::TopSites* GetTopSitesWithoutCreating() override;
-  virtual history::TopSites* GetTopSites() override;
-  virtual base::FilePath last_selected_directory() override;
-  virtual void set_last_selected_directory(const base::FilePath& path) override;
-  virtual bool WasCreatedByVersionOrLater(const std::string& version) override;
-  virtual void SetExitType(ExitType exit_type) override;
-  virtual ExitType GetLastSessionExitType() override;
+  net::SSLConfigService* GetSSLConfigService() override;
+  HostContentSettingsMap* GetHostContentSettingsMap() override;
+  bool IsSameProfile(Profile* profile) override;
+  Time GetStartTime() const override;
+  history::TopSites* GetTopSitesWithoutCreating() override;
+  history::TopSites* GetTopSites() override;
+  base::FilePath last_selected_directory() override;
+  void set_last_selected_directory(const base::FilePath& path) override;
+  bool WasCreatedByVersionOrLater(const std::string& version) override;
+  void SetExitType(ExitType exit_type) override;
+  ExitType GetLastSessionExitType() override;
 
 #if defined(OS_CHROMEOS)
   virtual void ChangeAppLocale(const std::string& locale,
@@ -76,36 +74,33 @@
   virtual void InitChromeOSPreferences() override;
 #endif  // defined(OS_CHROMEOS)
 
-  virtual PrefProxyConfigTracker* GetProxyConfigTracker() override;
+  PrefProxyConfigTracker* GetProxyConfigTracker() override;
 
-  virtual chrome_browser_net::Predictor* GetNetworkPredictor() override;
-  virtual DevToolsNetworkController* GetDevToolsNetworkController() override;
-  virtual void ClearNetworkingHistorySince(
-      base::Time time,
-      const base::Closure& completion) override;
-  virtual GURL GetHomePage() override;
+  chrome_browser_net::Predictor* GetNetworkPredictor() override;
+  DevToolsNetworkController* GetDevToolsNetworkController() override;
+  void ClearNetworkingHistorySince(base::Time time,
+                                   const base::Closure& completion) override;
+  GURL GetHomePage() override;
 
   // content::BrowserContext implementation:
-  virtual base::FilePath GetPath() const override;
-  virtual scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() override;
-  virtual bool IsOffTheRecord() const override;
-  virtual content::DownloadManagerDelegate*
-      GetDownloadManagerDelegate() override;
-  virtual net::URLRequestContextGetter* GetRequestContext() override;
-  virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
+  base::FilePath GetPath() const override;
+  scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() override;
+  bool IsOffTheRecord() const override;
+  content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
+  net::URLRequestContextGetter* GetRequestContext() override;
+  net::URLRequestContextGetter* GetRequestContextForRenderProcess(
       int renderer_child_id) override;
-  virtual net::URLRequestContextGetter* GetMediaRequestContext() override;
-  virtual net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(
+  net::URLRequestContextGetter* GetMediaRequestContext() override;
+  net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(
       int renderer_child_id) override;
-  virtual net::URLRequestContextGetter*
-      GetMediaRequestContextForStoragePartition(
-          const base::FilePath& partition_path,
-          bool in_memory) override;
-  virtual content::ResourceContext* GetResourceContext() override;
-  virtual content::BrowserPluginGuestManager* GetGuestManager() override;
-  virtual storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
-  virtual content::PushMessagingService* GetPushMessagingService() override;
-  virtual content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
+  net::URLRequestContextGetter* GetMediaRequestContextForStoragePartition(
+      const base::FilePath& partition_path,
+      bool in_memory) override;
+  content::ResourceContext* GetResourceContext() override;
+  content::BrowserPluginGuestManager* GetGuestManager() override;
+  storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
+  content::PushMessagingService* GetPushMessagingService() override;
+  content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(OffTheRecordProfileImplTest, GetHostZoomMap);
diff --git a/chrome/browser/profiles/off_the_record_profile_impl_unittest.cc b/chrome/browser/profiles/off_the_record_profile_impl_unittest.cc
index 9bb689a..4040a71 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl_unittest.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl_unittest.cc
@@ -37,12 +37,10 @@
     zoom_level_prefs_->InitPrefsAndCopyToHostZoomMap(GetPath(), host_zoom_map);
   }
 
-  virtual ~TestingProfileWithHostZoomMap() {}
+  ~TestingProfileWithHostZoomMap() override {}
 
   // Profile overrides:
-  virtual PrefService* GetOffTheRecordPrefs() override {
-    return GetPrefs();
-  }
+  PrefService* GetOffTheRecordPrefs() override { return GetPrefs(); }
 
  private:
   void OnZoomLevelChanged(const HostZoomMap::ZoomLevelChange& change) {
@@ -104,7 +102,7 @@
   }
 
   // BrowserWithTestWindowTest overrides:
-  virtual TestingProfile* CreateProfile() override {
+  TestingProfile* CreateProfile() override {
     return new TestingProfileWithHostZoomMap;
   }
 
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.h b/chrome/browser/profiles/off_the_record_profile_io_data.h
index 7014006..0675b89 100644
--- a/chrome/browser/profiles/off_the_record_profile_io_data.h
+++ b/chrome/browser/profiles/off_the_record_profile_io_data.h
@@ -107,41 +107,37 @@
   friend class base::RefCountedThreadSafe<OffTheRecordProfileIOData>;
 
   explicit OffTheRecordProfileIOData(Profile::ProfileType profile_type);
-  virtual ~OffTheRecordProfileIOData();
+  ~OffTheRecordProfileIOData() override;
 
-  virtual void InitializeInternal(
-      ProfileParams* profile_params,
-      content::ProtocolHandlerMap* protocol_handlers,
-      content::URLRequestInterceptorScopedVector request_interceptors)
-          const override;
-  virtual void InitializeExtensionsRequestContext(
+  void InitializeInternal(ProfileParams* profile_params,
+                          content::ProtocolHandlerMap* protocol_handlers,
+                          content::URLRequestInterceptorScopedVector
+                              request_interceptors) const override;
+  void InitializeExtensionsRequestContext(
       ProfileParams* profile_params) const override;
-  virtual net::URLRequestContext* InitializeAppRequestContext(
+  net::URLRequestContext* InitializeAppRequestContext(
       net::URLRequestContext* main_context,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
           protocol_handler_interceptor,
       content::ProtocolHandlerMap* protocol_handlers,
       content::URLRequestInterceptorScopedVector request_interceptors)
-          const override;
-  virtual net::URLRequestContext* InitializeMediaRequestContext(
+      const override;
+  net::URLRequestContext* InitializeMediaRequestContext(
       net::URLRequestContext* original_context,
       const StoragePartitionDescriptor& partition_descriptor) const override;
-  virtual net::URLRequestContext*
-      AcquireMediaRequestContext() const override;
-  virtual net::URLRequestContext* AcquireIsolatedAppRequestContext(
+  net::URLRequestContext* AcquireMediaRequestContext() const override;
+  net::URLRequestContext* AcquireIsolatedAppRequestContext(
       net::URLRequestContext* main_context,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
           protocol_handler_interceptor,
       content::ProtocolHandlerMap* protocol_handlers,
       content::URLRequestInterceptorScopedVector request_interceptors)
-          const override;
-  virtual net::URLRequestContext*
-      AcquireIsolatedMediaRequestContext(
-          net::URLRequestContext* app_context,
-          const StoragePartitionDescriptor& partition_descriptor)
-              const override;
+      const override;
+  net::URLRequestContext* AcquireIsolatedMediaRequestContext(
+      net::URLRequestContext* app_context,
+      const StoragePartitionDescriptor& partition_descriptor) const override;
 
   mutable scoped_ptr<net::HttpTransactionFactory> main_http_factory_;
   mutable scoped_ptr<net::FtpTransactionFactory> ftp_factory_;
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index c3b2983c..1ca4451e1 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -153,7 +153,7 @@
   static const char kNoHostedDomainFound[];
 
   Profile();
-  virtual ~Profile();
+  ~Profile() override;
 
   // Profile prefs are registered as soon as the prefs are loaded for the first
   // time.
diff --git a/chrome/browser/profiles/profile_avatar_downloader.h b/chrome/browser/profiles/profile_avatar_downloader.h
index 7825ccc..6844100 100644
--- a/chrome/browser/profiles/profile_avatar_downloader.h
+++ b/chrome/browser/profiles/profile_avatar_downloader.h
@@ -14,12 +14,12 @@
   ProfileAvatarDownloader(size_t icon_index,
                           const base::FilePath& profile_path,
                           ProfileInfoCache* cache);
-  virtual ~ProfileAvatarDownloader();
+  ~ProfileAvatarDownloader() override;
 
   void Start();
 
   // BitmapFetcherDelegate:
-  virtual void OnFetchComplete(const GURL url, const SkBitmap* bitmap) override;
+  void OnFetchComplete(const GURL url, const SkBitmap* bitmap) override;
 
  private:
   // Downloads the avatar image from a url.
diff --git a/chrome/browser/profiles/profile_avatar_icon_util.cc b/chrome/browser/profiles/profile_avatar_icon_util.cc
index d413cf6b..b074d11 100644
--- a/chrome/browser/profiles/profile_avatar_icon_util.cc
+++ b/chrome/browser/profiles/profile_avatar_icon_util.cc
@@ -57,10 +57,10 @@
                     int width,
                     AvatarPosition position,
                     AvatarBorder border);
-  virtual ~AvatarImageSource();
+  ~AvatarImageSource() override;
 
   // CanvasImageSource override:
-  virtual void Draw(gfx::Canvas* canvas) override;
+  void Draw(gfx::Canvas* canvas) override;
 
  private:
   gfx::ImageSkia avatar_;
@@ -190,6 +190,9 @@
 const SkColor kAvatarTutorialContentTextColor = SkColorSetRGB(0xc6, 0xda, 0xfc);
 const SkColor kAvatarBubbleAccountsBackgroundColor =
     SkColorSetRGB(0xf3, 0xf3, 0xf3);
+const SkColor kAvatarBubbleGaiaBackgroundColor =
+    SkColorSetRGB(0xf5, 0xf5, 0xf5);
+const SkColor kUserManagerBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
 
 const char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_";
 const char kGAIAPictureFileName[] = "Google Profile Picture.png";
diff --git a/chrome/browser/profiles/profile_avatar_icon_util.h b/chrome/browser/profiles/profile_avatar_icon_util.h
index 6f228ae..8e27212 100644
--- a/chrome/browser/profiles/profile_avatar_icon_util.h
+++ b/chrome/browser/profiles/profile_avatar_icon_util.h
@@ -31,6 +31,8 @@
 extern const SkColor kAvatarTutorialBackgroundColor;
 extern const SkColor kAvatarTutorialContentTextColor;
 extern const SkColor kAvatarBubbleAccountsBackgroundColor;
+extern const SkColor kAvatarBubbleGaiaBackgroundColor;
+extern const SkColor kUserManagerBackgroundColor;
 
 // Gets the number of default avatar icons that exist.
 size_t GetDefaultAvatarIconCount();
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc
index 40e5282..f9513fae 100644
--- a/chrome/browser/profiles/profile_browsertest.cc
+++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -93,7 +93,7 @@
 
 class ProfileBrowserTest : public InProcessBrowserTest {
  protected:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
 #if defined(OS_CHROMEOS)
     command_line->AppendSwitch(
         chromeos::switches::kIgnoreUserProfileMappingForTests);
diff --git a/chrome/browser/profiles/profile_destroyer.h b/chrome/browser/profiles/profile_destroyer.h
index cd5054f1..59b705b 100644
--- a/chrome/browser/profiles/profile_destroyer.h
+++ b/chrome/browser/profiles/profile_destroyer.h
@@ -31,11 +31,10 @@
   friend class base::RefCounted<ProfileDestroyer>;
 
   ProfileDestroyer(Profile* const profile, HostSet* hosts);
-  virtual ~ProfileDestroyer();
+  ~ProfileDestroyer() override;
 
   // content::RenderProcessHostObserver override.
-  virtual void RenderProcessHostDestroyed(
-      content::RenderProcessHost* host) override;
+  void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
 
   // Called by the timer to cancel the pending destruction and do it now.
   void DestroyProfile();
diff --git a/chrome/browser/profiles/profile_downloader.h b/chrome/browser/profiles/profile_downloader.h
index 3a62938..aac6bb2 100644
--- a/chrome/browser/profiles/profile_downloader.h
+++ b/chrome/browser/profiles/profile_downloader.h
@@ -41,7 +41,7 @@
   };
 
   explicit ProfileDownloader(ProfileDownloaderDelegate* delegate);
-  virtual ~ProfileDownloader();
+  ~ProfileDownloader() override;
 
   // Starts downloading profile information if the necessary authorization token
   // is ready. If not, subscribes to token service and starts fetching if the
@@ -86,28 +86,28 @@
   FRIEND_TEST_ALL_PREFIXES(ProfileDownloaderTest, DefaultURL);
 
   // gaia::GaiaOAuthClient::Delegate implementation.
-  virtual void OnGetUserInfoResponse(
+  void OnGetUserInfoResponse(
       scoped_ptr<base::DictionaryValue> user_info) override;
-  virtual void OnOAuthError() override;
-  virtual void OnNetworkError(int response_code) override;
+  void OnOAuthError() override;
+  void OnNetworkError(int response_code) override;
 
   // Overriden from net::URLFetcherDelegate:
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // Overriden from ImageDecoder::Delegate:
-  virtual void OnImageDecoded(const ImageDecoder* decoder,
-                              const SkBitmap& decoded_image) override;
-  virtual void OnDecodeImageFailed(const ImageDecoder* decoder) override;
+  void OnImageDecoded(const ImageDecoder* decoder,
+                      const SkBitmap& decoded_image) override;
+  void OnDecodeImageFailed(const ImageDecoder* decoder) override;
 
   // Overriden from OAuth2TokenService::Observer:
-  virtual void OnRefreshTokenAvailable(const std::string& account_id) override;
+  void OnRefreshTokenAvailable(const std::string& account_id) override;
 
   // Overriden from OAuth2TokenService::Consumer:
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
   // Parses the entry response and gets the name, profile image URL and locale.
   // |data| should be the JSON formatted data return by the response.
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 56dc924..436c557f0 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -1079,6 +1079,7 @@
 }
 
 HostContentSettingsMap* ProfileImpl::GetHostContentSettingsMap() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (!host_content_settings_map_.get()) {
     host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false);
   }
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index ccefbda..2ff686ee 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -71,74 +71,69 @@
   // Value written to prefs when the exit type is EXIT_NORMAL. Public for tests.
   static const char* const kPrefExitTypeNormal;
 
-  virtual ~ProfileImpl();
+  ~ProfileImpl() override;
 
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // content::BrowserContext implementation:
-  virtual base::FilePath GetPath() const override;
-  virtual content::DownloadManagerDelegate*
-      GetDownloadManagerDelegate() override;
-  virtual net::URLRequestContextGetter* GetRequestContext() override;
-  virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
+  base::FilePath GetPath() const override;
+  content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
+  net::URLRequestContextGetter* GetRequestContext() override;
+  net::URLRequestContextGetter* GetRequestContextForRenderProcess(
       int renderer_child_id) override;
-  virtual net::URLRequestContextGetter* GetMediaRequestContext() override;
-  virtual net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(
+  net::URLRequestContextGetter* GetMediaRequestContext() override;
+  net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(
       int renderer_child_id) override;
-  virtual net::URLRequestContextGetter*
-      GetMediaRequestContextForStoragePartition(
-          const base::FilePath& partition_path,
-          bool in_memory) override;
-  virtual content::ResourceContext* GetResourceContext() override;
-  virtual content::BrowserPluginGuestManager* GetGuestManager() override;
-  virtual storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
-  virtual content::PushMessagingService* GetPushMessagingService() override;
-  virtual content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
+  net::URLRequestContextGetter* GetMediaRequestContextForStoragePartition(
+      const base::FilePath& partition_path,
+      bool in_memory) override;
+  content::ResourceContext* GetResourceContext() override;
+  content::BrowserPluginGuestManager* GetGuestManager() override;
+  storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
+  content::PushMessagingService* GetPushMessagingService() override;
+  content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
 
   // Profile implementation:
-  virtual scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() override;
+  scoped_refptr<base::SequencedTaskRunner> GetIOTaskRunner() override;
   // Note that this implementation returns the Google-services username, if any,
   // not the Chrome user's display name.
-  virtual std::string GetProfileName() override;
-  virtual ProfileType GetProfileType() const override;
-  virtual bool IsOffTheRecord() const override;
-  virtual Profile* GetOffTheRecordProfile() override;
-  virtual void DestroyOffTheRecordProfile() override;
-  virtual bool HasOffTheRecordProfile() override;
-  virtual Profile* GetOriginalProfile() override;
-  virtual bool IsSupervised() override;
-  virtual history::TopSites* GetTopSites() override;
-  virtual history::TopSites* GetTopSitesWithoutCreating() override;
-  virtual ExtensionSpecialStoragePolicy*
-      GetExtensionSpecialStoragePolicy() override;
-  virtual PrefService* GetPrefs() override;
-  virtual chrome::ChromeZoomLevelPrefs* GetZoomLevelPrefs() override;
-  virtual PrefService* GetOffTheRecordPrefs() override;
-  virtual net::URLRequestContextGetter*
-      GetRequestContextForExtensions() override;
-  virtual net::SSLConfigService* GetSSLConfigService() override;
-  virtual HostContentSettingsMap* GetHostContentSettingsMap() override;
-  virtual bool IsSameProfile(Profile* profile) override;
-  virtual base::Time GetStartTime() const override;
-  virtual net::URLRequestContextGetter* CreateRequestContext(
+  std::string GetProfileName() override;
+  ProfileType GetProfileType() const override;
+  bool IsOffTheRecord() const override;
+  Profile* GetOffTheRecordProfile() override;
+  void DestroyOffTheRecordProfile() override;
+  bool HasOffTheRecordProfile() override;
+  Profile* GetOriginalProfile() override;
+  bool IsSupervised() override;
+  history::TopSites* GetTopSites() override;
+  history::TopSites* GetTopSitesWithoutCreating() override;
+  ExtensionSpecialStoragePolicy* GetExtensionSpecialStoragePolicy() override;
+  PrefService* GetPrefs() override;
+  chrome::ChromeZoomLevelPrefs* GetZoomLevelPrefs() override;
+  PrefService* GetOffTheRecordPrefs() override;
+  net::URLRequestContextGetter* GetRequestContextForExtensions() override;
+  net::SSLConfigService* GetSSLConfigService() override;
+  HostContentSettingsMap* GetHostContentSettingsMap() override;
+  bool IsSameProfile(Profile* profile) override;
+  base::Time GetStartTime() const override;
+  net::URLRequestContextGetter* CreateRequestContext(
       content::ProtocolHandlerMap* protocol_handlers,
       content::URLRequestInterceptorScopedVector request_interceptors) override;
-  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+  net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
       const base::FilePath& partition_path,
       bool in_memory,
       content::ProtocolHandlerMap* protocol_handlers,
       content::URLRequestInterceptorScopedVector request_interceptors) override;
-  virtual base::FilePath last_selected_directory() override;
-  virtual void set_last_selected_directory(const base::FilePath& path) override;
-  virtual chrome_browser_net::Predictor* GetNetworkPredictor() override;
-  virtual DevToolsNetworkController* GetDevToolsNetworkController() override;
-  virtual void ClearNetworkingHistorySince(
-      base::Time time,
-      const base::Closure& completion) override;
-  virtual GURL GetHomePage() override;
-  virtual bool WasCreatedByVersionOrLater(const std::string& version) override;
-  virtual void SetExitType(ExitType exit_type) override;
-  virtual ExitType GetLastSessionExitType() override;
+  base::FilePath last_selected_directory() override;
+  void set_last_selected_directory(const base::FilePath& path) override;
+  chrome_browser_net::Predictor* GetNetworkPredictor() override;
+  DevToolsNetworkController* GetDevToolsNetworkController() override;
+  void ClearNetworkingHistorySince(base::Time time,
+                                   const base::Closure& completion) override;
+  GURL GetHomePage() override;
+  bool WasCreatedByVersionOrLater(const std::string& version) override;
+  void SetExitType(ExitType exit_type) override;
+  ExitType GetLastSessionExitType() override;
 
 #if defined(OS_CHROMEOS)
   virtual void ChangeAppLocale(const std::string& locale,
@@ -147,7 +142,7 @@
   virtual void InitChromeOSPreferences() override;
 #endif  // defined(OS_CHROMEOS)
 
-  virtual PrefProxyConfigTracker* GetProxyConfigTracker() override;
+  PrefProxyConfigTracker* GetProxyConfigTracker() override;
 
  private:
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h
index 27125b5..a4bb5f6 100644
--- a/chrome/browser/profiles/profile_impl_io_data.h
+++ b/chrome/browser/profiles/profile_impl_io_data.h
@@ -149,7 +149,7 @@
     DISALLOW_COPY_AND_ASSIGN(Handle);
   };
 
-  virtual bool IsDataReductionProxyEnabled() const override;
+  bool IsDataReductionProxyEnabled() const override;
 
   BooleanPrefMember* data_reduction_proxy_enabled() const {
     return &data_reduction_proxy_enabled_;
@@ -176,41 +176,37 @@
   };
 
   ProfileImplIOData();
-  virtual ~ProfileImplIOData();
+  ~ProfileImplIOData() override;
 
-  virtual void InitializeInternal(
-      ProfileParams* profile_params,
-      content::ProtocolHandlerMap* protocol_handlers,
-      content::URLRequestInterceptorScopedVector request_interceptors)
-          const override;
-  virtual void InitializeExtensionsRequestContext(
+  void InitializeInternal(ProfileParams* profile_params,
+                          content::ProtocolHandlerMap* protocol_handlers,
+                          content::URLRequestInterceptorScopedVector
+                              request_interceptors) const override;
+  void InitializeExtensionsRequestContext(
       ProfileParams* profile_params) const override;
-  virtual net::URLRequestContext* InitializeAppRequestContext(
+  net::URLRequestContext* InitializeAppRequestContext(
       net::URLRequestContext* main_context,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
           protocol_handler_interceptor,
       content::ProtocolHandlerMap* protocol_handlers,
       content::URLRequestInterceptorScopedVector request_interceptors)
-          const override;
-  virtual net::URLRequestContext* InitializeMediaRequestContext(
+      const override;
+  net::URLRequestContext* InitializeMediaRequestContext(
       net::URLRequestContext* original_context,
       const StoragePartitionDescriptor& partition_descriptor) const override;
-  virtual net::URLRequestContext*
-      AcquireMediaRequestContext() const override;
-  virtual net::URLRequestContext* AcquireIsolatedAppRequestContext(
+  net::URLRequestContext* AcquireMediaRequestContext() const override;
+  net::URLRequestContext* AcquireIsolatedAppRequestContext(
       net::URLRequestContext* main_context,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
           protocol_handler_interceptor,
       content::ProtocolHandlerMap* protocol_handlers,
       content::URLRequestInterceptorScopedVector request_interceptors)
-          const override;
-  virtual net::URLRequestContext*
-      AcquireIsolatedMediaRequestContext(
-          net::URLRequestContext* app_context,
-          const StoragePartitionDescriptor& partition_descriptor)
-              const override;
+      const override;
+  net::URLRequestContext* AcquireIsolatedMediaRequestContext(
+      net::URLRequestContext* app_context,
+      const StoragePartitionDescriptor& partition_descriptor) const override;
 
   // Deletes all network related data since |time|. It deletes transport
   // security state since |time| and also deletes HttpServerProperties data.
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h
index ead90eb..a0631542 100644
--- a/chrome/browser/profiles/profile_info_cache.h
+++ b/chrome/browser/profiles/profile_info_cache.h
@@ -37,7 +37,7 @@
                          public base::SupportsWeakPtr<ProfileInfoCache> {
  public:
   ProfileInfoCache(PrefService* prefs, const base::FilePath& user_data_dir);
-  virtual ~ProfileInfoCache();
+  ~ProfileInfoCache() override;
 
   // If the |supervised_user_id| is non-empty, the profile will be marked to be
   // omitted from the avatar-menu list on desktop versions. This is used while a
@@ -52,46 +52,37 @@
   void DeleteProfileFromCache(const base::FilePath& profile_path);
 
   // ProfileInfoInterface:
-  virtual size_t GetNumberOfProfiles() const override;
+  size_t GetNumberOfProfiles() const override;
   // Don't cache this value and reuse, because resorting the menu could cause
   // the item being referred to to change out from under you.
-  virtual size_t GetIndexOfProfileWithPath(
+  size_t GetIndexOfProfileWithPath(
       const base::FilePath& profile_path) const override;
-  virtual base::string16 GetNameOfProfileAtIndex(size_t index) const override;
-  virtual base::string16 GetShortcutNameOfProfileAtIndex(size_t index)
-      const override;
-  virtual base::FilePath GetPathOfProfileAtIndex(size_t index) const override;
-  virtual base::Time GetProfileActiveTimeAtIndex(size_t index) const override;
-  virtual base::string16 GetUserNameOfProfileAtIndex(
-      size_t index) const override;
-  virtual const gfx::Image& GetAvatarIconOfProfileAtIndex(
-      size_t index) const override;
-  virtual std::string GetLocalAuthCredentialsOfProfileAtIndex(
+  base::string16 GetNameOfProfileAtIndex(size_t index) const override;
+  base::string16 GetShortcutNameOfProfileAtIndex(size_t index) const override;
+  base::FilePath GetPathOfProfileAtIndex(size_t index) const override;
+  base::Time GetProfileActiveTimeAtIndex(size_t index) const override;
+  base::string16 GetUserNameOfProfileAtIndex(size_t index) const override;
+  const gfx::Image& GetAvatarIconOfProfileAtIndex(size_t index) const override;
+  std::string GetLocalAuthCredentialsOfProfileAtIndex(
       size_t index) const override;
   // Note that a return value of false could mean an error in collection or
   // that there are currently no background apps running. However, the action
   // which results is the same in both cases (thus far).
-  virtual bool GetBackgroundStatusOfProfileAtIndex(
-      size_t index) const override;
-  virtual base::string16 GetGAIANameOfProfileAtIndex(
-      size_t index) const override;
-  virtual base::string16 GetGAIAGivenNameOfProfileAtIndex(
-      size_t index) const override;
+  bool GetBackgroundStatusOfProfileAtIndex(size_t index) const override;
+  base::string16 GetGAIANameOfProfileAtIndex(size_t index) const override;
+  base::string16 GetGAIAGivenNameOfProfileAtIndex(size_t index) const override;
   // Returns the GAIA picture for the given profile. This may return NULL
   // if the profile does not have a GAIA picture or if the picture must be
   // loaded from disk.
-  virtual const gfx::Image* GetGAIAPictureOfProfileAtIndex(
-      size_t index) const override;
-  virtual bool IsUsingGAIAPictureOfProfileAtIndex(
-      size_t index) const override;
-  virtual bool ProfileIsSupervisedAtIndex(size_t index) const override;
-  virtual bool IsOmittedProfileAtIndex(size_t index) const override;
-  virtual bool ProfileIsSigninRequiredAtIndex(size_t index) const override;
-  virtual std::string GetSupervisedUserIdOfProfileAtIndex(size_t index) const
-      override;
-  virtual bool ProfileIsEphemeralAtIndex(size_t index) const override;
-  virtual bool ProfileIsUsingDefaultNameAtIndex(size_t index) const override;
-  virtual bool ProfileIsUsingDefaultAvatarAtIndex(size_t index) const override;
+  const gfx::Image* GetGAIAPictureOfProfileAtIndex(size_t index) const override;
+  bool IsUsingGAIAPictureOfProfileAtIndex(size_t index) const override;
+  bool ProfileIsSupervisedAtIndex(size_t index) const override;
+  bool IsOmittedProfileAtIndex(size_t index) const override;
+  bool ProfileIsSigninRequiredAtIndex(size_t index) const override;
+  std::string GetSupervisedUserIdOfProfileAtIndex(size_t index) const override;
+  bool ProfileIsEphemeralAtIndex(size_t index) const override;
+  bool ProfileIsUsingDefaultNameAtIndex(size_t index) const override;
+  bool ProfileIsUsingDefaultAvatarAtIndex(size_t index) const override;
 
   size_t GetAvatarIconIndexOfProfileAtIndex(size_t index) const;
 
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.h b/chrome/browser/profiles/profile_info_cache_unittest.h
index 882e6055..4908342 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.h
+++ b/chrome/browser/profiles/profile_info_cache_unittest.h
@@ -24,19 +24,16 @@
  public:
   explicit ProfileNameVerifierObserver(
       TestingProfileManager* testing_profile_manager);
-  virtual ~ProfileNameVerifierObserver();
+  ~ProfileNameVerifierObserver() override;
 
   // ProfileInfoCacheObserver overrides:
-  virtual void OnProfileAdded(const base::FilePath& profile_path) override;
-  virtual void OnProfileWillBeRemoved(
-      const base::FilePath& profile_path) override;
-  virtual void OnProfileWasRemoved(const base::FilePath& profile_path,
-                                   const base::string16& profile_name) override;
-  virtual void OnProfileNameChanged(
-      const base::FilePath& profile_path,
-      const base::string16& old_profile_name) override;
-  virtual void OnProfileAvatarChanged(
-      const base::FilePath& profile_path) override;
+  void OnProfileAdded(const base::FilePath& profile_path) override;
+  void OnProfileWillBeRemoved(const base::FilePath& profile_path) override;
+  void OnProfileWasRemoved(const base::FilePath& profile_path,
+                           const base::string16& profile_name) override;
+  void OnProfileNameChanged(const base::FilePath& profile_path,
+                            const base::string16& old_profile_name) override;
+  void OnProfileAvatarChanged(const base::FilePath& profile_path) override;
 
  private:
   ProfileInfoCache* GetCache();
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 27ef592f..86e148f 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -335,6 +335,17 @@
 }
 #endif  // defined(OS_CHROMEOS)
 
+#if defined(USE_NSS)
+void InitializeAndPassKeygenHandler(
+    scoped_ptr<net::KeygenHandler> keygen_handler,
+    const base::Callback<void(scoped_ptr<net::KeygenHandler>)>& callback,
+    scoped_ptr<ChromeNSSCryptoModuleDelegate> delegate) {
+  if (delegate)
+    keygen_handler->set_crypto_module_delegate(delegate.Pass());
+  callback.Run(keygen_handler.Pass());
+}
+#endif  // defined(USE_NSS)
+
 void InvalidateContextGettersOnIO(
     scoped_ptr<ProfileIOData::ChromeURLRequestContextGetterVector> getters) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -936,20 +947,16 @@
   scoped_ptr<net::KeygenHandler> keygen_handler(
       new net::KeygenHandler(key_size_in_bits, challenge_string, url));
 
-  scoped_ptr<ChromeNSSCryptoModuleDelegate> delegate(
-      new ChromeNSSCryptoModuleDelegate(chrome::kCryptoModulePasswordKeygen,
-                                        net::HostPortPair::FromURL(url)));
-  ChromeNSSCryptoModuleDelegate* delegate_ptr = delegate.get();
-  keygen_handler->set_crypto_module_delegate(delegate.Pass());
+  base::Callback<void(scoped_ptr<ChromeNSSCryptoModuleDelegate>)>
+      got_delegate_callback = base::Bind(&InitializeAndPassKeygenHandler,
+                                         base::Passed(&keygen_handler),
+                                         callback);
 
-  base::Closure bound_callback =
-      base::Bind(callback, base::Passed(&keygen_handler));
-  if (delegate_ptr->InitializeSlot(this, bound_callback)) {
-    // Initialization complete, run the callback synchronously.
-    bound_callback.Run();
-    return;
-  }
-  // Otherwise, the InitializeSlot will run the callback asynchronously.
+  ChromeNSSCryptoModuleDelegate::CreateForResourceContext(
+      chrome::kCryptoModulePasswordKeygen,
+      net::HostPortPair::FromURL(url),
+      this,
+      got_delegate_callback);
 #else
   callback.Run(make_scoped_ptr(
       new net::KeygenHandler(key_size_in_bits, challenge_string, url)));
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index ce911f9..9695bab 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -273,7 +273,7 @@
         scoped_ptr<net::HttpTransactionFactory> http_factory);
 
    private:
-    virtual ~MediaRequestContext();
+    ~MediaRequestContext() override;
 
     scoped_ptr<net::HttpTransactionFactory> http_factory_;
   };
@@ -290,7 +290,7 @@
     void SetJobFactory(scoped_ptr<net::URLRequestJobFactory> job_factory);
 
    private:
-    virtual ~AppRequestContext();
+    ~AppRequestContext() override;
 
     scoped_refptr<net::CookieStore> cookie_store_;
     scoped_ptr<net::HttpTransactionFactory> http_factory_;
@@ -486,19 +486,19 @@
   class ResourceContext : public content::ResourceContext {
    public:
     explicit ResourceContext(ProfileIOData* io_data);
-    virtual ~ResourceContext();
+    ~ResourceContext() override;
 
     // ResourceContext implementation:
-    virtual net::HostResolver* GetHostResolver() override;
-    virtual net::URLRequestContext* GetRequestContext() override;
-    virtual scoped_ptr<net::ClientCertStore> CreateClientCertStore() override;
-    virtual void CreateKeygenHandler(
+    net::HostResolver* GetHostResolver() override;
+    net::URLRequestContext* GetRequestContext() override;
+    scoped_ptr<net::ClientCertStore> CreateClientCertStore() override;
+    void CreateKeygenHandler(
         uint32 key_size_in_bits,
         const std::string& challenge_string,
         const GURL& url,
         const base::Callback<void(scoped_ptr<net::KeygenHandler>)>& callback)
         override;
-    virtual SaltCallback GetMediaDeviceIDSalt() override;
+    SaltCallback GetMediaDeviceIDSalt() override;
 
    private:
     friend class ProfileIOData;
diff --git a/chrome/browser/profiles/profile_list_desktop.h b/chrome/browser/profiles/profile_list_desktop.h
index 38d4354..ef9ca8e 100644
--- a/chrome/browser/profiles/profile_list_desktop.h
+++ b/chrome/browser/profiles/profile_list_desktop.h
@@ -18,17 +18,17 @@
 class ProfileListDesktop : public ProfileList {
  public:
   explicit ProfileListDesktop(ProfileInfoInterface* profile_cache);
-  virtual ~ProfileListDesktop();
+  ~ProfileListDesktop() override;
 
   // ProfileList overrides:
-  virtual size_t GetNumberOfItems() const override;
-  virtual const AvatarMenu::Item& GetItemAt(size_t index) const override;
-  virtual void RebuildMenu() override;
+  size_t GetNumberOfItems() const override;
+  const AvatarMenu::Item& GetItemAt(size_t index) const override;
+  void RebuildMenu() override;
   // Returns the menu index of the profile at |index| in the ProfileInfoCache.
   // The profile index must exist, and it may not be marked as omitted from the
   // menu.
-  virtual size_t MenuIndexFromProfileIndex(size_t index) override;
-  virtual void ActiveProfilePathChanged(base::FilePath& path) override;
+  size_t MenuIndexFromProfileIndex(size_t index) override;
+  void ActiveProfilePathChanged(base::FilePath& path) override;
 
  private:
   void ClearMenu();
diff --git a/chrome/browser/profiles/profile_list_desktop_unittest.cc b/chrome/browser/profiles/profile_list_desktop_unittest.cc
index 97db42c..e4cf9d7 100644
--- a/chrome/browser/profiles/profile_list_desktop_unittest.cc
+++ b/chrome/browser/profiles/profile_list_desktop_unittest.cc
@@ -30,12 +30,9 @@
 class MockObserver : public AvatarMenuObserver {
  public:
   MockObserver() : count_(0) {}
-  virtual ~MockObserver() {}
+  ~MockObserver() override {}
 
-  virtual void OnAvatarMenuChanged(
-      AvatarMenu* avatar_menu) override {
-    ++count_;
-  }
+  void OnAvatarMenuChanged(AvatarMenu* avatar_menu) override { ++count_; }
 
   int change_count() const { return count_; }
 
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 21df767..0ce1503 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -25,6 +25,8 @@
 #include "chrome/browser/content_settings/host_content_settings_map.h"
 #include "chrome/browser/download/download_service.h"
 #include "chrome/browser/download/download_service_factory.h"
+#include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
+#include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
@@ -1010,6 +1012,11 @@
   StartupTaskRunnerServiceFactory::GetForProfile(profile)->
       StartDeferredTaskRunners();
 
+  // Activate data reduction proxy. This creates a request context and makes a
+  // URL request to check if the data reduction proxy server is reachable.
+  DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile)->
+      MaybeActivateDataReductionProxy(true);
+
   AccountTrackerServiceFactory::GetForProfile(profile);
   AccountReconcilorFactory::GetForProfile(profile);
 }
diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h
index efad19a..d246aadd 100644
--- a/chrome/browser/profiles/profile_manager.h
+++ b/chrome/browser/profiles/profile_manager.h
@@ -34,7 +34,7 @@
   typedef base::Callback<void(Profile*, Profile::CreateStatus)> CreateCallback;
 
   explicit ProfileManager(const base::FilePath& user_data_dir);
-  virtual ~ProfileManager();
+  ~ProfileManager() override;
 
 #if defined(ENABLE_SESSION_SERVICE)
   // Invokes SessionServiceFactory::ShutdownForProfile() for all profiles.
@@ -188,14 +188,14 @@
   bool IsLoggedIn() const { return logged_in_; }
 
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Profile::Delegate implementation:
-  virtual void OnProfileCreated(Profile* profile,
-                                bool success,
-                                bool is_new_profile) override;
+  void OnProfileCreated(Profile* profile,
+                        bool success,
+                        bool is_new_profile) override;
 
  protected:
   // Does final initial actions.
@@ -287,12 +287,12 @@
   class BrowserListObserver : public chrome::BrowserListObserver {
    public:
     explicit BrowserListObserver(ProfileManager* manager);
-    virtual ~BrowserListObserver();
+    ~BrowserListObserver() override;
 
     // chrome::BrowserListObserver implementation.
-    virtual void OnBrowserAdded(Browser* browser) override;
-    virtual void OnBrowserRemoved(Browser* browser) override;
-    virtual void OnBrowserSetLastActive(Browser* browser) override;
+    void OnBrowserAdded(Browser* browser) override;
+    void OnBrowserRemoved(Browser* browser) override;
+    void OnBrowserSetLastActive(Browser* browser) override;
 
    private:
     ProfileManager* profile_manager_;
@@ -359,8 +359,8 @@
   explicit ProfileManagerWithoutInit(const base::FilePath& user_data_dir);
 
  protected:
-  virtual void DoFinalInitForServices(Profile*, bool) override {}
-  virtual void DoFinalInitLogging(Profile*) override {}
+  void DoFinalInitForServices(Profile*, bool) override {}
+  void DoFinalInitLogging(Profile*) override {}
 };
 
 #endif  // CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc
index 059c379..c8762441 100644
--- a/chrome/browser/profiles/profile_manager_browsertest.cc
+++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -69,7 +69,7 @@
         this);
   }
 
-  virtual ~ProfileRemovalObserver() {
+  ~ProfileRemovalObserver() override {
     g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
         this);
   }
@@ -77,8 +77,7 @@
   std::string last_used_profile_name() { return last_used_profile_name_; }
 
   // ProfileInfoCacheObserver overrides:
-  virtual void OnProfileWillBeRemoved(
-      const base::FilePath& profile_path) override {
+  void OnProfileWillBeRemoved(const base::FilePath& profile_path) override {
     last_used_profile_name_ = g_browser_process->local_state()->GetString(
         prefs::kProfileLastUsed);
   }
@@ -96,7 +95,7 @@
  public:
   PasswordStoreConsumerVerifier() : called_(false) {}
 
-  virtual void OnGetPasswordStoreResults(
+  void OnGetPasswordStoreResults(
       const std::vector<autofill::PasswordForm*>& results) override {
     EXPECT_FALSE(called_);
     called_ = true;
@@ -123,7 +122,7 @@
 // platforms.
 class ProfileManagerBrowserTest : public InProcessBrowserTest {
  protected:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
 #if defined(OS_CHROMEOS)
     command_line->AppendSwitch(
         chromeos::switches::kIgnoreUserProfileMappingForTests);
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index c965a6f..e86c8833 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -71,8 +71,7 @@
       : ::ProfileManagerWithoutInit(user_data_dir) {}
 
  protected:
-  virtual Profile* CreateProfileHelper(
-      const base::FilePath& file_path) override {
+  Profile* CreateProfileHelper(const base::FilePath& file_path) override {
     if (!base::PathExists(file_path)) {
       if (!base::CreateDirectory(file_path))
         return NULL;
@@ -80,8 +79,8 @@
     return new TestingProfile(file_path, NULL);
   }
 
-  virtual Profile* CreateProfileAsyncHelper(const base::FilePath& path,
-                                            Delegate* delegate) override {
+  Profile* CreateProfileAsyncHelper(const base::FilePath& path,
+                                    Delegate* delegate) override {
     // This is safe while all file operations are done on the FILE thread.
     BrowserThread::PostTask(
         BrowserThread::FILE, FROM_HERE,
@@ -392,8 +391,7 @@
       : UnittestProfileManager(user_data_dir) {}
 
  protected:
-  virtual Profile* CreateProfileHelper(
-      const base::FilePath& file_path) override {
+  Profile* CreateProfileHelper(const base::FilePath& file_path) override {
     TestingProfile::Builder builder;
     builder.SetGuestSession();
     builder.SetPath(file_path);
diff --git a/chrome/browser/profiles/profile_metrics.h b/chrome/browser/profiles/profile_metrics.h
index 0f34312..ed13aa9e 100644
--- a/chrome/browser/profiles/profile_metrics.h
+++ b/chrome/browser/profiles/profile_metrics.h
@@ -124,13 +124,31 @@
 #if defined(OS_ANDROID)
   // Enum for tracking user interactions with the account management menu
   // on Android.
+  //
+  // A Java counterpart will be generated for this enum.
+  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.profiles
+  // GENERATED_JAVA_CLASS_NAME_OVERRIDE: ProfileAccountManagementMetrics
+  // GENERATED_JAVA_PREFIX_TO_STRIP: PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_
   enum ProfileAndroidAccountManagementMenu {
-
-#define PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(label, value) \
-    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_##label = value,
-#include "profile_metrics_list.h"
-#undef PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU
-
+    // User arrived at the Account management screen.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_VIEW = 0,
+    // User arrived at the Account management screen, and clicked Add account.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_ADD_ACCOUNT = 1,
+    // User arrived at the Account management screen, and clicked Go incognito.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_GO_INCOGNITO = 2,
+    // User arrived at the Account management screen, and clicked on primary.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_CLICK_PRIMARY_ACCOUNT = 3,
+    // User arrived at the Account management screen, and clicked on secondary.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_CLICK_SECONDARY_ACCOUNT = 4,
+    // User arrived at the Account management screen, toggled Chrome signout.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_TOGGLE_SIGNOUT = 5,
+    // User toggled Chrome signout, and clicked Signout.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_SIGNOUT_SIGNOUT = 6,
+    // User toggled Chrome signout, and clicked Cancel.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_SIGNOUT_CANCEL = 7,
+    // User arrived at the android Account management screen directly from some
+    // Gaia requests.
+    PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_DIRECT_ADD_ACCOUNT = 8,
     NUM_PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU_METRICS,
   };
 #endif  // defined(OS_ANDROID)
diff --git a/chrome/browser/profiles/profile_metrics_list.h b/chrome/browser/profiles/profile_metrics_list.h
deleted file mode 100644
index 47255d2b..0000000
--- a/chrome/browser/profiles/profile_metrics_list.h
+++ /dev/null
@@ -1,30 +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.
-
-// Intentionally no include guards because this file is meant to be included
-// inside a macro to generate enum values.
-
-// Enum for tracking user interactions with the account management menu
-// on Android.
-
-// User arrived at the Account management screen.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(VIEW, 0)
-// User arrived at the Account management screen, and clicked Add account.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(ADD_ACCOUNT, 1)
-// User arrived at the Account management screen, and clicked Go incognito.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(GO_INCOGNITO, 2)
-// User arrived at the Account management screen, and clicked on primary.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(CLICK_PRIMARY_ACCOUNT, 3)
-// User arrived at the Account management screen, and clicked on secondary.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(CLICK_SECONDARY_ACCOUNT, 4)
-// User arrived at the Account management screen, toggled Chrome signout.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(TOGGLE_SIGNOUT, 5)
-// User toggled Chrome signout, and clicked Signout.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(SIGNOUT_SIGNOUT, 6)
-// User toggled Chrome signout, and clicked Cancel.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(SIGNOUT_CANCEL, 7)
-// User arrived at the android Account management screen directly from some
-// Gaia requests.
-PROFILE_ANDROID_ACCOUNT_MANAGEMENT_MENU(DIRECT_ADD_ACCOUNT, 8)
-
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index f2d44d4..ea5bb92 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -57,12 +57,11 @@
     DCHECK(!callback_.is_null());
     BrowserList::AddObserver(this);
   }
-  virtual ~BrowserAddedForProfileObserver() {
-  }
+  ~BrowserAddedForProfileObserver() override {}
 
  private:
   // Overridden from BrowserListObserver:
-  virtual void OnBrowserAdded(Browser* browser) override {
+  void OnBrowserAdded(Browser* browser) override {
     if (browser->profile() == profile_) {
       BrowserList::RemoveObserver(this);
       callback_.Run(profile_, Profile::CREATE_STATUS_INITIALIZED);
diff --git a/chrome/browser/profiles/startup_task_runner_service.h b/chrome/browser/profiles/startup_task_runner_service.h
index 6f9ea741..d8e6b22 100644
--- a/chrome/browser/profiles/startup_task_runner_service.h
+++ b/chrome/browser/profiles/startup_task_runner_service.h
@@ -21,7 +21,7 @@
                                  public KeyedService {
  public:
   explicit StartupTaskRunnerService(Profile* profile);
-  virtual ~StartupTaskRunnerService();
+  ~StartupTaskRunnerService() override;
 
   // Returns sequenced task runner where all bookmarks I/O operations are
   // performed.
diff --git a/chrome/browser/profiles/startup_task_runner_service_factory.h b/chrome/browser/profiles/startup_task_runner_service_factory.h
index beddade..49abdf2 100644
--- a/chrome/browser/profiles/startup_task_runner_service_factory.h
+++ b/chrome/browser/profiles/startup_task_runner_service_factory.h
@@ -28,10 +28,10 @@
   friend struct DefaultSingletonTraits<StartupTaskRunnerServiceFactory>;
 
   StartupTaskRunnerServiceFactory();
-  virtual ~StartupTaskRunnerServiceFactory();
+  ~StartupTaskRunnerServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
 
   DISALLOW_COPY_AND_ASSIGN(StartupTaskRunnerServiceFactory);
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 2d67cc0..de555230 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -341,6 +341,7 @@
 
 // Menu construction functions -------------------------------------------------
 
+#if defined(ENABLE_EXTENSIONS)
 // static
 bool RenderViewContextMenu::ExtensionContextAndPatternMatch(
     const content::ContextMenuParams& params,
@@ -474,6 +475,7 @@
                                           false);  // is_action_menu
   }
 }
+#endif  // defined(ENABLE_EXTENSIONS)
 
 void RenderViewContextMenu::InitMenu() {
   RenderViewContextMenuBase::InitMenu();
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h
index ebacb0e..6f7d044 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.h
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -12,8 +12,6 @@
 #include "base/observer_list.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
-#include "chrome/browser/extensions/context_menu_matcher.h"
-#include "chrome/browser/extensions/menu_manager.h"
 #include "components/renderer_context_menu/context_menu_content_type.h"
 #include "components/renderer_context_menu/render_view_context_menu_base.h"
 #include "components/renderer_context_menu/render_view_context_menu_observer.h"
@@ -22,6 +20,11 @@
 #include "ui/base/models/simple_menu_model.h"
 #include "ui/base/window_open_disposition.h"
 
+#if defined(ENABLE_EXTENSIONS)
+#include "chrome/browser/extensions/context_menu_matcher.h"
+#include "chrome/browser/extensions/menu_manager.h"
+#endif
+
 class PrintPreviewContextMenuObserver;
 class Profile;
 class SpellingMenuObserver;
@@ -60,7 +63,10 @@
 
  protected:
   Profile* GetProfile();
+
+#if defined(ENABLE_EXTENSIONS)
   extensions::ContextMenuMatcher extension_items_;
+#endif
 
  private:
   friend class RenderViewContextMenuTest;
@@ -68,12 +74,14 @@
 
   static bool IsDevToolsURL(const GURL& url);
   static bool IsInternalResourcesURL(const GURL& url);
+#if defined(ENABLE_EXTENSIONS)
   static bool ExtensionContextAndPatternMatch(
       const content::ContextMenuParams& params,
       const extensions::MenuItem::ContextList& contexts,
       const extensions::URLPatternSet& target_url_patterns);
   static bool MenuItemMatchesParams(const content::ContextMenuParams& params,
                                     const extensions::MenuItem* item);
+#endif
 
   // RenderViewContextMenuBase:
   void InitMenu() override;
@@ -105,8 +113,10 @@
   void AppendRotationItems();
   void AppendEditableItems();
   void AppendSearchProvider();
+#if defined(ENABLE_EXTENSIONS)
   void AppendAllExtensionItems();
   void AppendCurrentExtensionItems();
+#endif
   void AppendPrintPreviewItems();
   void AppendSearchWebForImageItems();
   void AppendSpellingSuggestionsSubMenu();
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h b/chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h
index 5930465..72522e2 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h
@@ -6,10 +6,13 @@
 #define CHROME_BROWSER_RENDERER_CONTEXT_MENU_RENDER_VIEW_CONTEXT_MENU_TEST_UTIL_H_
 
 #include "base/basictypes.h"
-#include "chrome/browser/extensions/context_menu_matcher.h"
 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
 #include "url/gurl.h"
 
+#if defined(ENABLE_EXTENSIONS)
+#include "chrome/browser/extensions/context_menu_matcher.h"
+#endif
+
 class Browser;
 
 namespace content {
@@ -50,7 +53,9 @@
                                 ui::MenuModel** found_model,
                                 int* found_index);
 
+#if defined(ENABLE_EXTENSIONS)
   extensions::ContextMenuMatcher& extension_items() { return extension_items_; }
+#endif
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu);
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
index cf5e5d6..c41f19bfc 100644
--- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -35,7 +35,7 @@
 #include "chrome/common/render_messages.h"
 #include "chrome/common/url_constants.h"
 #include "components/google/core/browser/google_util.h"
-#include "components/variations/variations_http_header_provider.h"
+#include "components/variations/net/variations_http_header_provider.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
diff --git a/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
index 2bbd857..46b4fc690 100644
--- a/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
+++ b/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
@@ -5,7 +5,9 @@
 #include "chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h"
 
 #include "chrome/browser/browser_process.h"
+#if defined(ENABLE_EXTENSIONS)
 #include "chrome/browser/extensions/extension_service.h"
+#endif
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_switches.h"
@@ -14,10 +16,12 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/render_view_host.h"
+#if defined(ENABLE_EXTENSIONS)
 #include "extensions/browser/extension_system.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
+#endif
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/host/dispatch_host_message.h"
 #include "ppapi/host/host_message_context.h"
diff --git a/chrome/browser/renderer_preferences_util.cc b/chrome/browser/renderer_preferences_util.cc
index 21eb25f..fc0ada5 100644
--- a/chrome/browser/renderer_preferences_util.cc
+++ b/chrome/browser/renderer_preferences_util.cc
@@ -7,9 +7,9 @@
 #include "base/macros.h"
 #include "base/prefs/pref_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/zoom/zoom_controller.h"
 #include "chrome/common/pref_names.h"
 #include "content/public/browser/host_zoom_map.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/common/renderer_preferences.h"
 #include "third_party/skia/include/core/SkColor.h"
 
@@ -17,6 +17,10 @@
 #include "ui/gfx/font_render_params.h"
 #endif
 
+#if !defined(OS_ANDROID)
+#include "chrome/browser/ui/zoom/zoom_controller.h"
+#endif
+
 #if defined(TOOLKIT_VIEWS)
 #include "chrome/browser/defaults.h"
 #include "ui/views/controls/textfield/textfield.h"
@@ -38,15 +42,20 @@
   prefs->enable_referrers = pref_service->GetBoolean(prefs::kEnableReferrers);
   prefs->enable_do_not_track =
       pref_service->GetBoolean(prefs::kEnableDoNotTrack);
+
+  double default_zoom_level = -1;
+#if !defined(OS_ANDROID)
   ZoomController* zoom_controller =
       ZoomController::FromWebContents(web_contents);
-  if (zoom_controller) {
-    prefs->default_zoom_level = zoom_controller->GetDefaultZoomLevel();
-  } else {
-    prefs->default_zoom_level =
-        content::HostZoomMap::GetDefaultForBrowserContext(
-            web_contents->GetBrowserContext())->GetDefaultZoomLevel();
+  if (zoom_controller)
+    default_zoom_level = zoom_controller->GetDefaultZoomLevel();
+#endif
+
+  if (default_zoom_level < 0) {
+    default_zoom_level = content::HostZoomMap::GetDefaultForBrowserContext(
+        web_contents->GetBrowserContext())->GetDefaultZoomLevel();
   }
+  prefs->default_zoom_level = default_zoom_level;
 
 #if defined(USE_DEFAULT_RENDER_THEME)
   prefs->focus_ring_color = SkColorSetRGB(0x4D, 0x90, 0xFE);
diff --git a/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js b/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js
index 67dff9d..6f532a96 100644
--- a/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js
+++ b/chrome/browser/resources/chromeos/chromevox/common/chrome_extension_externs.js
@@ -1240,6 +1240,12 @@
 
 
 /**
+ * @type {!chrome.automation.AutomationNode}
+ */
+chrome.automation.AutomationNode.prototype.root;
+
+
+/**
  * @return {chrome.automation.AutomationNode}
  */
 chrome.automation.AutomationNode.prototype.firstChild = function() {};
@@ -1299,6 +1305,9 @@
     function(eventType, callback, capture) {};
 
 
+chrome.automation.AutomationNode.prototype.focus = function() {};
+
+
 /**
  * @param {function(chrome.automation.AutomationNode)} callback
  */
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js
index 6ce94ea..617f398 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_util.js
@@ -30,15 +30,16 @@
 
 
 goog.scope(function() {
+var AutomationNode = chrome.automation.AutomationNode;
 var Dir = AutomationUtil.Dir;
 
 /**
  * Find a node in subtree of |cur| satisfying |pred| using pre-order traversal.
- * @param {chrome.automation.AutomationNode} cur Node to begin the search from.
+ * @param {AutomationNode} cur Node to begin the search from.
  * @param {Dir} dir
  * @param {AutomationPredicate.Unary} pred A predicate to apply
  *     to a candidate node.
- * @return {chrome.automation.AutomationNode}
+ * @return {AutomationNode}
  */
 AutomationUtil.findNodePre = function(cur, dir, pred) {
   if (pred(cur))
@@ -56,11 +57,11 @@
 
 /**
  * Find a node in subtree of |cur| satisfying |pred| using post-order traversal.
- * @param {chrome.automation.AutomationNode} cur Node to begin the search from.
+ * @param {AutomationNode} cur Node to begin the search from.
  * @param {Dir} dir
  * @param {AutomationPredicate.Unary} pred A predicate to apply
  *     to a candidate node.
- * @return {chrome.automation.AutomationNode}
+ * @return {AutomationNode}
  */
 AutomationUtil.findNodePost = function(cur, dir, pred) {
   var child = dir == Dir.BACKWARD ? cur.lastChild() : cur.firstChild();
@@ -79,9 +80,9 @@
 /**
  * Find the next node in the given direction that is either an immediate sibling
  * or a sibling of an ancestor.
- * @param {chrome.automation.AutomationNode} cur Node to start search from.
+ * @param {AutomationNode} cur Node to start search from.
  * @param {Dir} dir
- * @return {chrome.automation.AutomationNode}
+ * @return {AutomationNode}
  */
 AutomationUtil.findNextSubtree = function(cur, dir) {
   while (cur) {
@@ -95,11 +96,11 @@
 
 /**
  * Find the next node in the given direction in depth first order.
- * @param {chrome.automation.AutomationNode} cur Node to begin the search from.
+ * @param {AutomationNode} cur Node to begin the search from.
  * @param {Dir} dir
  * @param {AutomationPredicate.Unary} pred A predicate to apply
  *     to a candidate node.
- * @return {chrome.automation.AutomationNode}
+ * @return {AutomationNode}
  */
 AutomationUtil.findNextNode = function(cur, dir, pred) {
   var next = cur;
@@ -116,7 +117,7 @@
  * Given nodes a_1, ..., a_n starting at |cur| in pre order traversal, apply
  * |pred| to a_i and a_(i - 1) until |pred| is satisfied.  Returns a_(i - 1) or
  * a_i (depending on opt_options.before) or null if no match was found.
- * @param {chrome.automation.AutomationNode} cur
+ * @param {AutomationNode} cur
  * @param {Dir} dir
  * @param {AutomationPredicate.Binary} pred
  * @param {{filter: (AutomationPredicate.Unary|undefined),
@@ -125,7 +126,7 @@
  *         consider. Defaults to leaf nodes only.
  *     before - True to return a_(i -
  *     1); a_i otherwise. Defaults to false.
- * @return {chrome.automation.AutomationNode}
+ * @return {AutomationNode}
  */
 AutomationUtil.findNodeUntil = function(cur, dir, pred, opt_options) {
   opt_options =
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
index 989adde..6bde6b1 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -16,9 +16,9 @@
 goog.require('cvox.TabsApiHandler');
 
 goog.scope(function() {
+var AutomationNode = chrome.automation.AutomationNode;
 var Dir = AutomationUtil.Dir;
 var EventType = chrome.automation.EventType;
-var AutomationNode = chrome.automation.AutomationNode;
 
 /** Classic Chrome accessibility API. */
 global.accessibility =
@@ -46,10 +46,10 @@
                                               cvox.ChromeVox.earcons);
 
   /**
-   * @type {chrome.automation.AutomationNode}
+   * @type {cursors.Range}
    * @private
    */
-  this.currentNode_ = null;
+  this.currentRange_ = null;
 
   /**
    * Whether ChromeVox Next is active.
@@ -129,12 +129,10 @@
       return;
     }
 
-    if (!this.active_ || !this.current_)
+    if (!this.active_ || !this.currentRange_)
       return;
 
-    var previous = this.current_;
-    var current = this.current_;
-
+    var current = this.currentRange_;
     var dir = Dir.FORWARD;
     var pred = null;
     switch (command) {
@@ -147,12 +145,10 @@
         pred = AutomationPredicate.heading;
         break;
       case 'nextLine':
-        dir = Dir.FORWARD;
-        pred = AutomationPredicate.inlineTextBox;
+        current = current.move(cursors.Unit.LINE, Dir.FORWARD);
         break;
       case 'previousLine':
-        dir = Dir.BACKWARD;
-        pred = AutomationPredicate.inlineTextBox;
+        current = current.move(cursors.Unit.LINE, Dir.BACKWARD);
         break;
       case 'nextLink':
         dir = Dir.FORWARD;
@@ -163,40 +159,42 @@
         pred = AutomationPredicate.link;
         break;
       case 'nextElement':
-        current = current.role == chrome.automation.RoleType.inlineTextBox ?
-            current.parent() : current;
-        current = AutomationUtil.findNextNode(current,
-            Dir.FORWARD,
-            AutomationPredicate.inlineTextBox);
-        current = current ? current.parent() : current;
+        current = current.move(cursors.Unit.NODE, Dir.FORWARD);
         break;
       case 'previousElement':
-        current = current.role == chrome.automation.RoleType.inlineTextBox ?
-            current.parent() : current;
-        current = AutomationUtil.findNextNode(current,
-            Dir.BACKWARD,
-            AutomationPredicate.inlineTextBox);
-        current = current ? current.parent() : current;
+        current = current.move(cursors.Unit.NODE, Dir.BACKWARD);
         break;
       case 'goToBeginning':
-        current = AutomationUtil.findNodePost(current.root,
+      var node = AutomationUtil.findNodePost(current.getStart().getNode().root,
             Dir.FORWARD,
-            AutomationPredicate.inlineTextBox);
+            AutomationPredicate.leaf);
+      if (node)
+        current = cursors.Range.fromNode(node);
         break;
       case 'goToEnd':
-        current = AutomationUtil.findNodePost(current.root,
+      var node =
+          AutomationUtil.findNodePost(current.getStart().getNode().root,
             Dir.BACKWARD,
-            AutomationPredicate.inlineTextBox);
+            AutomationPredicate.leaf);
+      if (node)
+        current = cursors.Range.fromNode(node);
         break;
     }
 
-    if (pred)
-      current = AutomationUtil.findNextNode(current, dir, pred);
+    if (pred) {
+      var node = AutomationUtil.findNextNode(
+          current.getBound(dir).getNode(), dir, pred);
+
+      if (node)
+        current = cursors.Range.fromNode(node);
+    }
 
     if (current) {
-      current.focus();
+      // TODO(dtseng): Figure out what it means to focus a range.
+      current.getStart().getNode().focus();
 
-      this.onFocus({target: current});
+      this.currentRange_ = current;
+      this.handleOutput(this.currentRange_);
     }
   },
 
@@ -209,20 +207,8 @@
     if (!node)
       return;
 
-    this.current_ = node;
-    var container = node;
-    while (container &&
-        (container.role == chrome.automation.RoleType.inlineTextBox ||
-        container.role == chrome.automation.RoleType.staticText))
-      container = container.parent();
-
-    var role = container ? container.role : node.role;
-
-    var output =
-        [node.attributes.name, node.attributes.value, role].join(', ');
-    cvox.ChromeVox.tts.speak(output, cvox.QueueMode.FLUSH);
-    cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(output));
-    chrome.accessibilityPrivate.setFocusRing([evt.target.location]);
+    this.currentRange_ = cursors.Range.fromNode(node);
+    this.handleOutput(this.currentRange_);
   },
 
   /**
@@ -230,13 +216,17 @@
    * @param {Object} evt
    */
   onLoadComplete: function(evt) {
-    if (this.current_)
+    if (this.currentRange_)
       return;
 
-    this.current_ = AutomationUtil.findNodePost(evt.target,
+    var node = AutomationUtil.findNodePost(evt.target,
         Dir.FORWARD,
-        AutomationPredicate.inlineTextBox);
-    this.onFocus({target: this.current_});
+        AutomationPredicate.leaf);
+    if (node)
+      this.currentRange_ = cursors.Range.fromNode(node);
+
+    if (this.currentRange_)
+      this.handleOutput(this.currentRange_);
   },
 
   /**
@@ -278,7 +268,7 @@
     } else {
       if (this.active_) {
         for (var eventType in this.listeners_) {
-          this.current_.root.removeEventListener(
+          this.currentRange_.getStart().getNode().root.removeEventListener(
               eventType, this.listeners_[eventType], true);
         }
       }
@@ -294,6 +284,43 @@
         }.bind(this));
       }
     }.bind(this));
+  },
+
+  /**
+   * Handles output of a Range.
+   * @param {!cursors.Range} range Current location.
+   */
+  handleOutput: function(range) {
+    // TODO(dtseng): This is just placeholder logic for generating descriptions
+    // pending further design discussion.
+    function getCursorDesc(cursor) {
+      var node = cursor.getNode();
+      var container = node;
+      while (container &&
+          (container.role == chrome.automation.RoleType.inlineTextBox ||
+          container.role == chrome.automation.RoleType.staticText))
+        container = container.parent();
+
+      var role = container ? container.role : node.role;
+      return [node.attributes.name, node.attributes.value, role].join(', ');
+    }
+
+    // Walk the range and collect descriptions.
+    var output = '';
+    var cursor = range.getStart();
+    var nodeLocations = [];
+    while (cursor.getNode() != range.getEnd().getNode()) {
+      output += getCursorDesc(cursor);
+      nodeLocations.push(cursor.getNode().location);
+      cursor = cursor.move(
+          cursors.Unit.NODE, cursors.Movement.DIRECTIONAL, Dir.FORWARD);
+    }
+    output += getCursorDesc(range.getEnd());
+    nodeLocations.push(range.getEnd().getNode().location);
+
+    cvox.ChromeVox.tts.speak(output, cvox.QueueMode.FLUSH);
+    cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(output));
+    chrome.accessibilityPrivate.setFocusRing(nodeLocations);
   }
 };
 
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
index 74f41252..c847e03 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -71,3 +71,53 @@
     cvox.ChromeVox.tts.expectSpeech('end', testDone);
   }.bind(this));
 });
+
+/** Tests consistency of navigating forward and backward. */
+TEST_F('BackgroundTest', 'ForwardBackwardNavigation', function() {
+  this.runWithDocument(function() {/*!
+    <p>start</p>
+    <a href='#a'>alpha</a>
+    <a href='#b'>beta</a>
+    <p>
+      <h1>charlie</h1>
+      <a href='foo'>delta</a>
+    </p>
+    <a href='#bar'>echo</a>
+    <h2>foxtraut</h2>
+    <p>end<span>of test</span></p>
+  */},
+  function() {
+    var doCmd = function(cmd) {
+      return function() {
+        global.backgroundObj.onGotCommand(cmd);
+      };
+    };
+
+    var expectAfter =
+        cvox.ChromeVox.tts.expectSpeechAfter.bind(cvox.ChromeVox.tts);
+
+    cvox.ChromeVox.tts.expectSpeech('start');
+    expectAfter('alpha', doCmd('nextLink'));
+    expectAfter('beta', doCmd('nextLink'));
+    expectAfter('delta', doCmd('nextLink'));
+    expectAfter('beta', doCmd('previousLink'));
+
+    expectAfter('charlie', doCmd('nextHeading'));
+    expectAfter('foxtraut', doCmd('nextHeading'));
+    expectAfter('charlie', doCmd('previousHeading'));
+
+    expectAfter('delta', doCmd('nextElement'));
+    expectAfter('echo', doCmd('nextElement'));
+    expectAfter('foxtraut', doCmd('nextElement'));
+    expectAfter('end', doCmd('nextElement'));
+    expectAfter('foxtraut', doCmd('previousElement'));
+
+    // TODO(dtseng): cleanup these utterances.
+    expectAfter(', end, paragraph, of test, paragraph', doCmd('nextLine'));
+
+    expectAfter('start', doCmd('goToBeginning'));
+    expectAfter('of test', doCmd('goToEnd'));
+
+    cvox.ChromeVox.tts.finishExpectations();
+  }.bind(this));
+});
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
index c8b65e50..5339a636e 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
@@ -66,19 +66,44 @@
  * pointed to and covers the case where the accessible text is empty.
  */
 cursors.Cursor = function(node, index) {
-  /** @type {!AutomationNode} */
-  this.node = node;
-  /** @type {number} */
-  this.index = index;
+  /** @type {!AutomationNode} @private */
+  this.node_ = node;
+  /** @type {number} @private */
+  this.index_ = index;
+};
+
+/**
+ * Convenience method to construct a Cursor from a node.
+ * @param {!AutomationNode} node
+ * @return {!cursors.Cursor}
+ */
+cursors.Cursor.fromNode = function(node) {
+  return new cursors.Cursor(node, cursors.NODE_INDEX);
 };
 
 cursors.Cursor.prototype = {
   /**
-   * Returns a copy of this cursor.
-   * @return {cursors.Cursor}
+   * Returns true if |rhs| is equal to this cursor.
+   * @param {!cursors.Cursor} rhs
+   * @return {boolean}
    */
-  clone: function() {
-    return new cursors.Cursor(this.node, this.index);
+  equals: function(rhs) {
+    return this.node_ === rhs.getNode() &&
+        this.index_ === rhs.getIndex();
+  },
+
+  /**
+   * @return {!AutomationNode}
+   */
+  getNode: function() {
+    return this.node_;
+  },
+
+  /**
+   * @return {number}
+   */
+  getIndex: function() {
+    return this.index_;
   },
 
   /**
@@ -92,23 +117,25 @@
    * @return {string}
    */
   getText: function(opt_node) {
-    var node = opt_node || this.node;
+    var node = opt_node || this.node_;
     return node.attributes.name || node.attributes.value || '';
   },
 
   /**
-   * Moves this cursor by the unit in the given direction using the given
-   * movement type.
+   * Makes a Cursor which has been moved from this cursor by the unit in the
+   * given direction using the given movement type.
    * @param {Unit} unit
    * @param {Movement} movement
    * @param {Dir} dir
+   * @return {!cursors.Cursor} The moved cursor.
    */
   move: function(unit, movement, dir) {
+    var newNode, newIndex;
     switch (unit) {
       case Unit.CHARACTER:
         // BOUND and DIRECTIONAL are the same for characters.
-        var node = this.node;
-        var nextIndex = dir == Dir.FORWARD ? this.index + 1 : this.index - 1;
+        var node = this.node_;
+        var nextIndex = dir == Dir.FORWARD ? this.index_ + 1 : this.index_ - 1;
         if (nextIndex < 0 || nextIndex >= this.getText().length) {
           node = AutomationUtil.findNextNode(
               node, dir, AutomationPredicate.leaf);
@@ -116,57 +143,67 @@
             nextIndex =
                 dir == Dir.FORWARD ? 0 : this.getText(node).length - 1;
           } else {
-            node = this.node;
-            nextIndex = this.index;
+            node = this.node_;
+            nextIndex = this.index_;
           }
         }
-        this.node = node;
-        this.index = nextIndex;
+        newNode = node;
+        newIndex = nextIndex;
         break;
       case Unit.WORD:
         switch (movement) {
           case Movement.BOUND:
-            if (this.node.role == Role.inlineTextBox) {
+            if (this.node_.role == Role.inlineTextBox) {
               var start, end;
-              for (var i = 0; i < this.node.attributes.wordStarts.length; i++) {
-                if (this.index >= this.node.attributes.wordStarts[i] &&
-                    this.index <= this.node.attributes.wordEnds[i]) {
-                  start = this.node.attributes.wordStarts[i];
-                  end = this.node.attributes.wordEnds[i];
+              for (var i = 0;
+                   i < this.node_.attributes.wordStarts.length;
+                   i++) {
+                if (this.index_ >= this.node_.attributes.wordStarts[i] &&
+                    this.index_ <= this.node_.attributes.wordEnds[i]) {
+                  start = this.node_.attributes.wordStarts[i];
+                  end = this.node_.attributes.wordEnds[i];
                   break;
                 }
               }
               if (goog.isDef(start) && goog.isDef(end))
-                this.index = dir == Dir.FORWARD ? end : start;
+                newIndex = dir == Dir.FORWARD ? end : start;
             } else {
               // TODO(dtseng): Figure out what to do in this case.
             }
             break;
           case Movement.DIRECTIONAL:
-            if (this.node.role == Role.inlineTextBox) {
+            if (this.node_.role == Role.inlineTextBox) {
               var start, end;
-              for (var i = 0; i < this.node.attributes.wordStarts.length; i++) {
-                if (this.index >= this.node.attributes.wordStarts[i] &&
-                    this.index <= this.node.attributes.wordEnds[i]) {
+              for (var i = 0;
+                   i < this.node_.attributes.wordStarts.length;
+                   i++) {
+                if (this.index_ >= this.node_.attributes.wordStarts[i] &&
+                    this.index_ <= this.node_.attributes.wordEnds[i]) {
                   var nextIndex = dir == Dir.FORWARD ? i + 1 : i - 1;
-                  start = this.node.attributes.wordStarts[nextIndex];
-                  end = this.node.attributes.wordEnds[nextIndex];
+                  start = this.node_.attributes.wordStarts[nextIndex];
+                  end = this.node_.attributes.wordEnds[nextIndex];
                   break;
                 }
               }
               if (goog.isDef(start)) {
-                this.index = start;
+                newIndex = start;
               } else {
-                var node = AutomationUtil.findNextNode(this.node, dir,
-                            AutomationPredicate.leaf);
-                if (node) {
-                  this.node = node;
-                  this.index = 0;
-                  if (dir == Dir.BACKWARD && node.role == Role.inlineTextBox) {
-                    var starts = node.attributes.wordStarts;
-                    this.index = starts[starts.length - 1] || 0;
-                  } else {
-                    // TODO(dtseng): Figure out what to do for general nodes.
+                // The backward case is special at the beginning of nodes.
+                if (dir == Dir.BACKWARD && this.index_ != 0) {
+                  this.index_ = 0;
+                } else {
+                  var node = AutomationUtil.findNextNode(this.node_, dir,
+                      AutomationPredicate.leaf);
+                  if (node) {
+                    newNode = node;
+                    newIndex = 0;
+                    if (dir == Dir.BACKWARD &&
+                        node.role == Role.inlineTextBox) {
+                      var starts = node.attributes.wordStarts;
+                      newIndex = starts[starts.length - 1] || 0;
+                    } else {
+                      // TODO(dtseng): Figure out what to do for general nodes.
+                    }
                   }
                 }
               }
@@ -178,39 +215,133 @@
       case Unit.NODE:
         switch (movement) {
           case Movement.BOUND:
-            this.index = dir == Dir.FORWARD ? this.getText().length - 1 : 0;
+            newIndex = dir == Dir.FORWARD ? this.getText().length - 1 : 0;
             break;
           case Movement.DIRECTIONAL:
-            this.node = AutomationUtil.findNextNode(
-                this.node, dir, AutomationPredicate.leaf) || this.node;
-            this.index = cursors.NODE_INDEX;
+            newNode = AutomationUtil.findNextNode(
+                this.node_, dir, AutomationPredicate.leaf) || this.node_;
+            newIndex = cursors.NODE_INDEX;
             break;
         }
         break;
       case Unit.LINE:
-        this.index = 0;
+        newIndex = 0;
         switch (movement) {
           case Movement.BOUND:
-            var node = this.node;
-            node = AutomationUtil.findNodeUntil(node, dir,
+            newNode = AutomationUtil.findNodeUntil(this.node_, dir,
                 AutomationPredicate.linebreak, {before: true});
-            this.node = node || this.node;
+            newNode = newNode || this.node_;
+            newIndex =
+                dir == Dir.FORWARD ? this.getText(newNode).length - 1 : 0;
             break;
           case Movement.DIRECTIONAL:
-            var node = this.node;
-            node = AutomationUtil.findNodeUntil(
-                node, dir, AutomationPredicate.linebreak);
+            newNode = AutomationUtil.findNodeUntil(
+                this.node_, dir, AutomationPredicate.linebreak);
 
             // We stick to the beginning of lines out of convention.
-            if (node && dir == Dir.BACKWARD) {
-              node = AutomationUtil.findNodeUntil(node, dir,
+            if (newNode && dir == Dir.BACKWARD) {
+              newNode = AutomationUtil.findNodeUntil(newNode, dir,
                   AutomationPredicate.linebreak, {before: true}) || node;
             }
-            this.node = node || this.node;
             break;
           }
+      break;
+      default:
+        throw 'Unrecognized unit: ' + unit;
+    }
+    newNode = newNode || this.node_;
+    newIndex = goog.isDef(newIndex) ? newIndex : this.index_;
+    return new cursors.Cursor(newNode, newIndex);
+  }
+};
+
+/**
+ * Represents a range in the automation tree. There is no visible selection on
+ * the page caused by usage of this object.
+ * It is assumed that the caller provides |start| and |end| in document order.
+ * @param {!cursors.Cursor} start
+ * @param {!cursors.Cursor} end
+ * @constructor
+ */
+cursors.Range = function(start, end) {
+  /** @type {!cursors.Cursor} @private */
+  this.start_ = start;
+  /** @type {!cursors.Cursor} @private */
+  this.end_ = end;
+};
+
+/**
+ * Convenience method to construct a Range surrounding one node.
+ * @param {!AutomationNode} node
+ * @return {!cursors.Range}
+ */
+cursors.Range.fromNode = function(node) {
+  var cursor = cursors.Cursor.fromNode(node);
+  return new cursors.Range(cursor, cursor);
+};
+
+cursors.Range.prototype = {
+  /**
+   * Returns true if |rhs| is equal to this range.
+   * @param {!cursors.Range} rhs
+   * @return {boolean}
+   */
+  equals: function(rhs) {
+    return this.start_.equals(rhs.getStart()) &&
+        this.end_.equals(rhs.getEnd());
+  },
+
+  /**
+   * Gets a cursor bounding this range.
+   * @param {Dir} dir Which endpoint cursor to return; Dir.FORWARD for end,
+   * Dir.BACKWARD for start.
+   * @return {!cursors.Cursor}
+   */
+  getBound: function(dir) {
+    return dir == Dir.FORWARD ? this.end_ : this.start_;
+  },
+
+  /**
+   * @return {!cursors.Cursor}
+   */
+  getStart: function() {
+    return this.start_;
+  },
+
+  /**
+   * @return {!cursors.Cursor}
+   */
+  getEnd: function() {
+    return this.end_;
+  },
+
+  /**
+   * Makes a Range which has been moved from this range by the given unit and
+   * direction.
+   * @param {Unit} unit
+   * @param {Dir} dir
+   * @return {cursors.Range}
+   */
+  move: function(unit, dir) {
+    var newStart = this.start_;
+    var newEnd = newStart;
+    switch (unit) {
+      case Unit.CHARACTER:
+        newStart = newStart.move(unit, Movement.BOUND, dir);
+        newEnd = newStart.move(unit, Movement.BOUND, Dir.FORWARD);
+        // Character crossed a node; collapses to the end of the node.
+        if (newStart.getNode() !== newEnd.getNode())
+          newEnd = newStart;
+        break;
+      case Unit.WORD:
+      case Unit.LINE:
+      case Unit.NODE:
+        newEnd = newEnd.move(unit, Movement.DIRECTIONAL, dir);
+        newStart = newEnd;
+        newEnd = newEnd.move(unit, Movement.BOUND, Dir.FORWARD);
         break;
     }
+    return new cursors.Range(newStart, newEnd);
   }
 };
 
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs
index bc66b56..7d6e112 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors_test.extjs
@@ -15,6 +15,12 @@
 CursorsTest.prototype = {
   __proto__: ChromeVoxNextE2ETest.prototype,
 
+  /** Test cursors.Cursor. @const {string} */
+  CURSOR: 'cursor',
+
+  /** Test cursors.Range. @const {string} */
+  RANGE: 'range',
+
   /** @override */
   setUp: function() {
     // Various aliases.
@@ -38,107 +44,227 @@
    *     moves An array of arrays. Each inner array contains 4 items: unit,
    *     movement, direction, and assertions object. See example below.
    */
-  moveAndAssert: function(cursor, moves) {
+  cursorMoveAndAssert: function(cursor, moves) {
     var move = null;
     while (move = moves.shift()) {
-      cursor.move(move[0], move[1], move[2]);
+      cursor = cursor.move(move[0], move[1], move[2]);
       var expected = move[3];
-      if (expected.index)
-        assertEquals(expected.index, cursor.index);
-      if (expected.value)
-        assertEquals(expected.value, cursor.node.attributes.value);
+      this.makeCursorAssertion(expected, cursor);
     }
-  }
-};
+  },
 
-/** Tests basic text movement. */
-TEST_F('CursorsTest', 'BasicMovement', function() {
-  this.runWithDocument(function() {/*!
+  /**
+   * Performs a series of operations on a range and asserts the result.
+   * @param {cursors.Range} range The starting range.
+   * @param {!Array.<Array.<
+   *          cursors.Unit|
+   *          cursors.Movement|
+   *          automationUtil.Dir|
+   *          Object>>}
+   *     moves An array of arrays. Each inner array contains 4 items: unit,
+   *     direction, start and end assertions objects. See example below.
+   */
+  rangeMoveAndAssert: function(range, moves) {
+    var move = null;
+    while (move = moves.shift()) {
+      range = range.move(move[0], move[1]);
+      var expectedStart = move[2];
+      var expectedEnd = move[3];
+      this.makeCursorAssertion(expectedStart, range.getStart());
+      this.makeCursorAssertion(expectedEnd, range.getEnd());
+    }
+  },
+
+  /**
+   * Makes assertions about the given |cursor|.
+   * @param {Object} expected
+   * @param {Cursor} cursor
+   */
+  makeCursorAssertion: function(expected, cursor) {
+    if (goog.isDef(expected.index))
+      assertEquals(expected.index, cursor.getIndex());
+    if (goog.isDef(expected.value))
+      assertEquals(expected.value, cursor.getNode().attributes.value);
+  },
+
+  /**
+   * Runs the specified moves on the |doc| and asserts expectations.
+   * @param {function} doc
+   * @param {string=} opt_testType Either CURSOR or RANGE.
+   */
+  runCursorMovesOnDocument: function(doc, moves, opt_testType) {
+    this.runWithDocument(doc,
+    function() {
+      chrome.automation.getTree(function(root) {
+        var start = null;
+
+        // This occurs as a result of a load complete.
+        var start = AutomationUtil.findNodePost(root,
+            FORWARD,
+            AutomationPredicate.leaf);
+
+        var cursor = new cursors.Cursor(start, 0);
+        if (!opt_testType || opt_testType == this.CURSOR) {
+          var cursor = new cursors.Cursor(start, 0);
+          this.cursorMoveAndAssert(cursor, moves);
+          testDone();
+        } else if (opt_testType == this.RANGE) {
+          var range = new cursors.Range(cursor, cursor);
+          this.rangeMoveAndAssert(range, moves);
+          testDone();
+        }
+      }.bind(this));
+    }.bind(this));
+  },
+
+simpleDoc: function() {/*!
     <p>start <span>same line</span>
     <p>end
-  */},
-  function() {
-    chrome.automation.getTree(function(root) {
-      // This occurs as a result of a load complete.
-      var leftmost = AutomationUtil.findNodePost(root,
-          FORWARD,
-          AutomationPredicate.leaf);
-      assertEquals('start ', leftmost.attributes.value);
+  */}
+};
 
-      // Construct a cursor and make all possible movements.
-      var cursor = new cursors.Cursor(leftmost, 0);
+TEST_F('CursorsTest', 'CharacterCursor', function() {
+  this.runCursorMovesOnDocument(this.simpleDoc, [
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'start '}],
+    [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
+    [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
 
-      this.moveAndAssert(cursor, [
-          // Line (BOUND).
-          [LINE, BOUND, FORWARD, {value: 'same line'}],
-          [LINE, BOUND, FORWARD, {value: 'same line'}],
-          [LINE, BOUND, BACKWARD, {value: 'start '}],
-          [LINE, BOUND, BACKWARD, {value: 'start '}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'start '}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 2, value: 'start '}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 3, value: 'start '}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 4, value: 'start '}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 5, value: 'start '}],
 
-          // Line (DIRECTIONAL).
-          [LINE, DIRECTIONAL, FORWARD, {value: 'end'}],
-          [LINE, DIRECTIONAL, FORWARD, {value: 'end'}],
-          [LINE, DIRECTIONAL, BACKWARD, {value: 'start '}],
-          [LINE, DIRECTIONAL, BACKWARD, {value: 'start '}],
-          [LINE, BOUND, FORWARD, {value: 'same line'}],
-          [LINE, DIRECTIONAL, FORWARD, {value: 'end'}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 0, value: 'same line'}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'same line'}],
+    [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
 
-          // Character.
-          [CHARACTER, DIRECTIONAL, FORWARD, {index: 1}],
-          [CHARACTER, DIRECTIONAL, FORWARD, {index: 2}],
-          [CHARACTER, DIRECTIONAL, FORWARD, {index: 2}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 1}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0}],
-
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 8, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, FORWARD, {index: 0, value: 'end'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 8, value: 'same line'}],
-                    
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 7, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 6, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 5, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 4, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 3, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 2, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 5, value: 'start '}],
-
-          // Word (BOUND).
-          [WORD, BOUND, BACKWARD, {index: 0, value: 'start '}],
-          [WORD, BOUND, BACKWARD, {index: 0, value: 'start '}],
-          [WORD, BOUND, FORWARD, {index: 5, value: 'start '}],
-          [WORD, BOUND, FORWARD, {index: 5, value: 'start '}],
-
-          // Word (DIRECTIONAL).
-          [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'same line'}],
-          [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
-
-          [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'end'}],
-          [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'end'}],
-
-          [WORD, DIRECTIONAL, BACKWARD, {index: 5, value: 'same line'}],
-          [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
-
-          [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
-          [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
-
-          // Characters and words.
-          [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'start '}],
-
-          [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'same line'}],
-          [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 4, value: 'same line'}],
-          [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, FORWARD, {index: 6, value: 'same line'}],
-          [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 5, value: 'start '}],
-          [CHARACTER, DIRECTIONAL, BACKWARD, {index: 4, value: 'start '}],
-          [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
-]);
-
-      testDone();
-    }.bind(this));
-  }.bind(this));
+    [CHARACTER, DIRECTIONAL, BACKWARD, {index: 5, value: 'start '}],]);
 });
+
+TEST_F('CursorsTest', 'WordCursor', function() {
+  this.runCursorMovesOnDocument(this.simpleDoc, [
+    // Word (BOUND).
+    [WORD, BOUND, BACKWARD, {index: 0, value: 'start '}],
+    [WORD, BOUND, BACKWARD, {index: 0, value: 'start '}],
+    [WORD, BOUND, FORWARD, {index: 5, value: 'start '}],
+    [WORD, BOUND, FORWARD, {index: 5, value: 'start '}],
+
+    // Word (DIRECTIONAL).
+    [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'same line'}],
+    [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
+
+    [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'end'}],
+    [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'end'}],
+
+    [WORD, DIRECTIONAL, BACKWARD, {index: 5, value: 'same line'}],
+    [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
+
+    [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}],
+    [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}]]);
+});
+
+TEST_F('CursorsTest', 'CharacterWordCursor', function() {
+  this.runCursorMovesOnDocument(this.simpleDoc, [
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'start '}],
+
+    [WORD, DIRECTIONAL, FORWARD, {index: 0, value: 'same line'}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 1, value: 'same line'}],
+    [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
+    [CHARACTER, DIRECTIONAL, BACKWARD, {index: 4, value: 'same line'}],
+    [WORD, DIRECTIONAL, FORWARD, {index: 5, value: 'same line'}],
+    [CHARACTER, DIRECTIONAL, FORWARD, {index: 6, value: 'same line'}],
+    [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'same line'}],
+    [CHARACTER, DIRECTIONAL, BACKWARD, {index: 5, value: 'start '}],
+    [CHARACTER, DIRECTIONAL, BACKWARD, {index: 4, value: 'start '}],
+    [WORD, DIRECTIONAL, BACKWARD, {index: 0, value: 'start '}]]);
+});
+
+TEST_F('CursorsTest', 'LineCursor', function() {
+  this.runCursorMovesOnDocument(this.simpleDoc, [
+    // Line (BOUND).
+    [LINE, BOUND, FORWARD, {value: 'same line'}],
+    [LINE, BOUND, FORWARD, {value: 'same line'}],
+    [LINE, BOUND, BACKWARD, {value: 'start '}],
+    [LINE, BOUND, BACKWARD, {value: 'start '}],
+
+    // Line (DIRECTIONAL).
+    [LINE, DIRECTIONAL, FORWARD, {value: 'end'}],
+    [LINE, DIRECTIONAL, FORWARD, {value: 'end'}],
+    [LINE, DIRECTIONAL, BACKWARD, {value: 'start '}],
+    [LINE, DIRECTIONAL, BACKWARD, {value: 'start '}],
+    [LINE, BOUND, FORWARD, {value: 'same line'}],
+    [LINE, DIRECTIONAL, FORWARD, {value: 'end'}]]);
+});
+
+TEST_F('CursorsTest', 'CharacterRange', function() {
+  this.runCursorMovesOnDocument(this.simpleDoc, [
+      [CHARACTER, FORWARD,
+          {value: 'start ', index: 1}, {value: 'start ', index: 2}],
+      [CHARACTER, FORWARD,
+          {value: 'start ', index: 2}, {value: 'start ', index: 3}],
+      [CHARACTER, FORWARD,
+          {value: 'start ', index: 3}, {value: 'start ', index: 4}],
+      [CHARACTER, FORWARD,
+          {value: 'start ', index: 4}, {value: 'start ', index: 5}],
+      [CHARACTER, FORWARD,
+          {value: 'start ', index: 5}, {value: 'start ', index: 5}],
+
+      [CHARACTER, FORWARD,
+          {value: 'same line', index: 0}, {value: 'same line', index: 1}],
+
+      [CHARACTER, BACKWARD,
+          {value: 'start ', index: 5}, {value: 'start ', index: 5}],
+      [CHARACTER, BACKWARD,
+          {value: 'start ', index: 4}, {value: 'start ', index: 5}],
+      [CHARACTER, BACKWARD,
+          {value: 'start ', index: 3}, {value: 'start ', index: 4}],
+      [CHARACTER, BACKWARD,
+          {value: 'start ', index: 2}, {value: 'start ', index: 3}],
+      [CHARACTER, BACKWARD,
+          {value: 'start ', index: 1}, {value: 'start ', index: 2}],
+      [CHARACTER, BACKWARD,
+          {value: 'start ', index: 0}, {value: 'start ', index: 1}],
+      [CHARACTER, BACKWARD,
+          {value: 'start ', index: 0}, {value: 'start ', index: 1}],
+  ], this.RANGE);
+});
+
+TEST_F('CursorsTest', 'WordRange', function() {
+  this.runCursorMovesOnDocument(this.simpleDoc, [
+      [WORD, FORWARD,
+          {value: 'same line', index: 0}, {value: 'same line', index: 4}],
+      [WORD, FORWARD,
+          {value: 'same line', index: 5}, {value: 'same line', index: 9}],
+
+      [WORD, FORWARD,
+          {value: 'end', index: 0}, {value: 'end', index: 3}],
+      [WORD, FORWARD,
+          {value: 'end', index: 0}, {value: 'end', index: 3}],
+
+      [WORD, BACKWARD,
+          {value: 'same line', index: 5}, {value: 'same line', index: 9}],
+      [WORD, BACKWARD,
+          {value: 'same line', index: 0}, {value: 'same line', index: 4}],
+
+      [WORD, BACKWARD,
+          {value: 'start ', index: 0}, {value: 'start ', index: 5}],
+      [WORD, BACKWARD,
+          {value: 'start ', index: 0}, {value: 'start ', index: 5}],
+  ], this.RANGE);
+});
+      
+     
+TEST_F('CursorsTest', 'LineRange', function() {
+  this.runCursorMovesOnDocument(this.simpleDoc, [
+      [LINE, FORWARD, {value: 'end', index: 0}, {value: 'end', index: 2}],
+      [LINE, FORWARD, {value: 'end', index: 0}, {value: 'end', index: 2}],
+
+      [LINE, BACKWARD,
+          {value: 'start ', index: 0}, {value: 'same line', index: 8}],
+
+      [LINE, BACKWARD,
+          {value: 'start ', index: 0}, {value: 'same line', index: 8}],
+  ], this.RANGE);
+});
+      
diff --git a/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json b/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json
index 75c60d6..c9f2f28 100644
--- a/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json
+++ b/chrome/browser/resources/chromeos/input_method/google_input_tools_manifest.json
@@ -284,6 +284,17 @@
       "input_view": "inputview.html#id=t13n-rtl&language=ur&passwordLayout=t13n-rtl&name=transliteration_ur"
     },
     {
+      "name": "__MSG_inputmethod_hangul__",
+      "type": "ime",
+      "id": "ko-t-i0-und",
+      "indicator": "\uD55C",
+      "description": "Korean input method.",
+      "language": "ko",
+      "layouts": ["us"],
+      "input_view": "inputview.html#id=m17n:ko_2set&language=ko&passwordLayout=us&name=inputmethod_hangul",
+      "options_page": "hmm_options.html?code=ko-t-i0-und"
+    },
+    {
       "name": "__MSG_inputmethod_mozc_us__",
       "type": "ime",
       "id": "nacl_mozc_us",
diff --git a/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json b/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
index e4a4546d..11d9c08 100644
--- a/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
+++ b/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json
@@ -7,6 +7,7 @@
   "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7C0oB6YTnf69uhWnVTZl5TB/psHrJXgIPLYchFb0whlVCG8fqMo9lW/oxBmZXZ3N8T7zZrdYI/SUjoc9I5R/dMVVD2q4iKox+x7xlTbqSdVeOb6b9ZVJ24pLbO1L7feSNSBgR0t61jrC2eY/gf78h7w58UEQBPFT2mUxhhwodyQIDAQAB",
   "permissions": [
     "app.window.ime",
+    "app.window.alpha",
     "input",
     "inputMethodPrivate",
     "virtualKeyboardPrivate",
diff --git a/chrome/browser/resources/chromeos/input_method/xkb_manifest.json b/chrome/browser/resources/chromeos/input_method/xkb_manifest.json
index a42dce9..974b7a7 100644
--- a/chrome/browser/resources/chromeos/input_method/xkb_manifest.json
+++ b/chrome/browser/resources/chromeos/input_method/xkb_manifest.json
@@ -6,6 +6,7 @@
   "default_locale": "en",
   "permissions": [
     "app.window.ime",
+    "app.window.alpha",
     "input",
     "metricsPrivate",
     "accessibilityFeatures.read"
diff --git a/chrome/browser/resources/chromeos/login/login.js b/chrome/browser/resources/chromeos/login/login.js
index cf10252d6..393130e 100644
--- a/chrome/browser/resources/chromeos/login/login.js
+++ b/chrome/browser/resources/chromeos/login/login.js
@@ -31,6 +31,7 @@
       login.AppLaunchSplashScreen.register();
       login.ConfirmPasswordScreen.register();
       login.FatalErrorScreen.register();
+      login.DeviceDisabledScreen.register();
 
       cr.ui.Bubble.decorate($('bubble'));
       login.HeaderBar.decorate($('login-header-bar'));
diff --git a/chrome/browser/resources/chromeos/login/login_common.js b/chrome/browser/resources/chromeos/login/login_common.js
index 3dc3b63..c25f59bc 100644
--- a/chrome/browser/resources/chromeos/login/login_common.js
+++ b/chrome/browser/resources/chromeos/login/login_common.js
@@ -30,6 +30,7 @@
 <include src="screen_wrong_hwid.js">
 <include src="screen_confirm_password.js">
 <include src="screen_fatal_error.js">
+<include src="screen_device_disabled.js">
 <include src="../../../../../ui/login/login_ui_tools.js">
 <include src="../../../../../ui/login/account_picker/user_pod_row.js">
 <include src="../../../../../ui/login/resource_loader.js">
@@ -262,7 +263,7 @@
   Oobe.loginForTesting = function(username, password) {
     Oobe.disableSigninUI();
     chrome.send('skipToLoginForTesting', [username]);
-    chrome.send('completeLogin', [username, password, false]);
+    chrome.send('completeLogin', ['12345', username, password, false]);
   };
 
   /**
diff --git a/chrome/browser/resources/chromeos/login/login_resources.html b/chrome/browser/resources/chromeos/login/login_resources.html
index d987db1..09d6f69 100644
--- a/chrome/browser/resources/chromeos/login/login_resources.html
+++ b/chrome/browser/resources/chromeos/login/login_resources.html
@@ -36,6 +36,7 @@
 <link rel="stylesheet" href="screen_supervised_user_creation.css">
 <link rel="stylesheet" href="screen_confirm_password.css">
 <link rel="stylesheet" href="screen_fatal_error.css">
+<link rel="stylesheet" href="screen_device_disabled.css">
 <link rel="stylesheet" href="../../../../../ui/login/account_picker/user_pod_row.css">
 <link rel="stylesheet" href="../../options/chromeos/bluetooth.css">
 <script src="chrome://resources/js/cr.js"></script>
diff --git a/chrome/browser/resources/chromeos/login/login_screens.html b/chrome/browser/resources/chromeos/login/login_screens.html
index 529bc09..676c8f8 100644
--- a/chrome/browser/resources/chromeos/login/login_screens.html
+++ b/chrome/browser/resources/chromeos/login/login_screens.html
@@ -13,3 +13,4 @@
 <include src="screen_app_launch_splash.html">
 <include src="screen_confirm_password.html">
 <include src="screen_fatal_error.html">
+<include src="screen_device_disabled.html">
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js
index aab4099..ea7a0b9f 100644
--- a/chrome/browser/resources/chromeos/login/oobe.js
+++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -94,6 +94,7 @@
       login.FatalErrorScreen.register();
       login.ControllerPairingScreen.register();
       login.HostPairingScreen.register();
+      login.DeviceDisabledScreen.register();
 
       cr.ui.Bubble.decorate($('bubble'));
       login.HeaderBar.decorate($('login-header-bar'));
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
index 0947594..67e163d 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
+++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.js
@@ -16,7 +16,6 @@
       'showStep',
       'showError',
       'showWorking',
-      'setAuthenticatedUserEmail',
       'doReload',
     ],
 
@@ -206,24 +205,6 @@
       this.showStep(STEP_WORKING);
     },
 
-    /**
-     * Invoked when the authenticated user's e-mail address has been retrieved.
-     * This completes SAML authentication.
-     * @param {number} attemptToken An opaque token used to correlate this
-     *     method invocation with the corresponding request to retrieve the
-     *     user's e-mail address.
-     * @param {string} email The authenticated user's e-mail address.
-     */
-    setAuthenticatedUserEmail: function(attemptToken, email) {
-      if (this.attemptToken_ != attemptToken)
-        return;
-
-      if (!email)
-        this.showError(loadTimeData.getString('fatalEnrollmentError'), false);
-      else
-        chrome.send('oauthEnrollCompleteLogin', [email]);
-    },
-
     doReload: function() {
       $('oauth-enroll-signin-frame').contentWindow.location.href =
           this.signInUrl_;
@@ -289,20 +270,10 @@
       var msg = m.data;
 
       if (msg.method == 'completeLogin') {
-        // A user has successfully authenticated via regular GAIA.
+        // A user has successfully authenticated via regular GAIA or SAML.
         chrome.send('oauthEnrollCompleteLogin', [msg.email]);
       }
 
-      if (msg.method == 'retrieveAuthenticatedUserEmail') {
-        // A user has successfully authenticated via SAML. However, the user's
-        // identity is not known. Instead of reporting success immediately,
-        // retrieve the user's e-mail address first.
-        this.attemptToken_ = msg.attemptToken;
-        this.showWorking(null);
-        chrome.send('oauthEnrollRetrieveAuthenticatedUserEmail',
-                    [msg.attemptToken]);
-      }
-
       if (msg.method == 'authPageLoaded' && this.currentStep_ == STEP_SIGNIN) {
         if (msg.isSAML) {
           $('oauth-saml-notice-message').textContent = loadTimeData.getStringF(
@@ -318,6 +289,12 @@
             loadTimeData.getStringF('insecureURLEnrollmentError', msg.url),
             false);
       }
+
+      if (msg.method == 'missingGaiaInfo') {
+        this.showError(
+            loadTimeData.getString('fatalEnrollmentError'),
+            false);
+      }
     }
   };
 });
diff --git a/chrome/browser/resources/chromeos/login/oobe_screens.html b/chrome/browser/resources/chromeos/login/oobe_screens.html
index 084d2ea..b71fc5b 100644
--- a/chrome/browser/resources/chromeos/login/oobe_screens.html
+++ b/chrome/browser/resources/chromeos/login/oobe_screens.html
@@ -20,3 +20,4 @@
 <include src="screen_app_launch_splash.html">
 <include src="screen_confirm_password.html">
 <include src="screen_fatal_error.html">
+<include src="screen_device_disabled.html">
diff --git a/chrome/browser/resources/chromeos/login/screen_device_disabled.css b/chrome/browser/resources/chromeos/login/screen_device_disabled.css
new file mode 100644
index 0000000..fa7527d
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/screen_device_disabled.css
@@ -0,0 +1,42 @@
+/* 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.
+ */
+
+#device-disabled,
+#device-disabled-top-container {
+  display: flex;
+  flex-direction: column;
+}
+
+#device-disabled {
+  font-size: 12px;
+  width: 330px;
+}
+
+#device-disabled-top-container {
+  background-color: rgb(214, 0, 0);
+  color: white;
+  text-align: center;
+}
+
+#device-disabled-heading {
+  font-size: 16px;
+  margin: 60px 20px 0;
+}
+
+#device-disabled-message {
+  font-weight: bold;
+  margin: 20px;
+  max-height: 400px;
+  overflow: auto;
+  white-space: pre-wrap;
+}
+
+#device-disabled-bottom-container {
+  background-color: white;
+}
+
+#device-disabled-explanation {
+  margin: 25px 20px 45px
+}
diff --git a/chrome/browser/resources/chromeos/login/screen_device_disabled.html b/chrome/browser/resources/chromeos/login/screen_device_disabled.html
new file mode 100644
index 0000000..b06d953
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/screen_device_disabled.html
@@ -0,0 +1,11 @@
+<div id="device-disabled" class="step hidden no-logo" role="group" hidden>
+  <div id="device-disabled-top-container">
+    <div id="device-disabled-heading" i18n-content="deviceDisabledHeading">
+    </div>
+    <div id="device-disabled-message"></div>
+  </div>
+  <div id="device-disabled-bottom-container">
+    <div id="device-disabled-explanation"
+        i18n-content="deviceDisabledExplanation">
+  </div>
+</div>
diff --git a/chrome/browser/resources/chromeos/login/screen_device_disabled.js b/chrome/browser/resources/chromeos/login/screen_device_disabled.js
new file mode 100644
index 0000000..6bb1731
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/screen_device_disabled.js
@@ -0,0 +1,31 @@
+// 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.
+
+/**
+ * @fileoverview Device disabled screen implementation.
+ */
+
+login.createScreen('DeviceDisabledScreen', 'device-disabled', function() {
+  return {
+    EXTERNAL_API: [
+      'setMessage'
+    ],
+
+    /**
+     * Event handler that is invoked just before the screen in shown.
+     */
+    onBeforeShow: function() {
+      $('progress-dots').hidden = true;
+    },
+
+    /**
+      * Sets the message to show to the user.
+      * @param {string} message The message to show to the user.
+      * @private
+      */
+    setMessage: function(message) {
+      $('device-disabled-message').textContent = message;
+    }
+  };
+});
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.js b/chrome/browser/resources/chromeos/login/screen_error_message.js
index 031d239..d0c47e5 100644
--- a/chrome/browser/resources/chromeos/login/screen_error_message.js
+++ b/chrome/browser/resources/chromeos/login/screen_error_message.js
@@ -53,7 +53,8 @@
     ERROR_STATE.OFFLINE,
     ERROR_STATE.PROXY,
     ERROR_STATE.AUTH_EXT_TIMEOUT,
-    ERROR_STATE.KIOSK_ONLINE
+    ERROR_STATE.NONE,
+    ERROR_STATE.KIOSK_ONLINE,
   ];
 
   return {
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
index 153663d..ff044033 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -22,7 +22,6 @@
     EXTERNAL_API: [
       'loadAuthExtension',
       'updateAuthExtension',
-      'setAuthenticatedUserEmail',
       'doReload',
       'onFrameError',
       'updateCancelButtonState'
@@ -94,14 +93,16 @@
       this.gaiaAuthHost_ = new cr.login.GaiaAuthHost($('signin-frame'));
       this.gaiaAuthHost_.addEventListener(
           'ready', this.onAuthReady_.bind(this));
-      this.gaiaAuthHost_.retrieveAuthenticatedUserEmailCallback =
-          this.onRetrieveAuthenticatedUserEmail_.bind(this);
       this.gaiaAuthHost_.confirmPasswordCallback =
           this.onAuthConfirmPassword_.bind(this);
       this.gaiaAuthHost_.noPasswordCallback =
           this.onAuthNoPassword_.bind(this);
       this.gaiaAuthHost_.insecureContentBlockedCallback =
           this.onInsecureContentBlocked_.bind(this);
+      this.gaiaAuthHost_.missingGaiaInfoCallback =
+          this.missingGaiaInfo_.bind(this);
+      this.gaiaAuthHost_.samlApiUsedCallback =
+          this.samlApiUsed_.bind(this);
       this.gaiaAuthHost_.addEventListener('authFlowChange',
           this.onAuthFlowChange_.bind(this));
 
@@ -338,21 +339,6 @@
     },
 
     /**
-     * Sends the authenticated user's e-mail address to the auth extension.
-     * @param {number} attemptToken The opaque token provided to
-     *     onRetrieveAuthenticatedUserEmail_.
-     * @param {string} email The authenticated user's e-mail address.
-     */
-    setAuthenticatedUserEmail: function(attemptToken, email) {
-      if (!email) {
-        this.showFatalAuthError(
-            loadTimeData.getString('fatalErrorMessageNoEmail'));
-      } else {
-        this.gaiaAuthHost_.setAuthenticatedUserEmail(attemptToken, email);
-      }
-    },
-
-    /**
      * Updates [Cancel] button state. Allow cancellation of screen only when
      * user pods can be displayed.
      */
@@ -413,27 +399,6 @@
     },
 
     /**
-     * Invoked when the user has successfully authenticated via SAML and the
-     * auth host needs to retrieve the user's e-mail.
-     * @param {number} attemptToken Opaque token to be passed to
-     *     setAuthenticatedUserEmail along with the e-mail address.
-     * @param {boolean} apiUsed Whether the principals API was used during
-     *     authentication.
-     * @private
-     */
-    onRetrieveAuthenticatedUserEmail_: function(attemptToken, apiUsed) {
-      if (apiUsed) {
-        // If the principals API was used, report this to the C++ backend so
-        // that statistics can be kept. If password scraping was used instead,
-        // there is no need to inform the C++ backend at this point: Either
-        // onAuthNoPassword_ or onAuthConfirmPassword_ will be called in a
-        // moment, both of which imply to the backend that the API was not used.
-        chrome.send('usingSAMLAPI');
-      }
-      chrome.send('retrieveAuthenticatedUserEmail', [attemptToken]);
-    },
-
-    /**
      * Invoked when the user has successfully authenticated via SAML, the
      * principals API was not used and the auth host needs the user to confirm
      * the scraped password.
@@ -503,6 +468,21 @@
     },
 
     /**
+     * Show fatal auth error when information is missing from GAIA.
+     */
+    missingGaiaInfo_: function() {
+      this.showFatalAuthError(
+          loadTimeData.getString('fatalErrorMessageNoAccountDetails'));
+    },
+
+    /**
+     * Record that SAML API was used during sign-in.
+     */
+    samlApiUsed_: function() {
+      chrome.send('usingSAMLAPI');
+    },
+
+    /**
      * Invoked when auth is completed successfully.
      * @param {!Object} credentials Credentials of the completed authentication.
      * @private
@@ -511,15 +491,19 @@
       if (credentials.useOffline) {
         this.email = credentials.email;
         chrome.send('authenticateUser',
-                    [credentials.email, credentials.password]);
+                    [credentials.gaiaId,
+                     credentials.email,
+                     credentials.password]);
       } else if (credentials.authCode) {
         chrome.send('completeAuthentication',
-                    [credentials.email,
+                    [credentials.gaiaId,
+                     credentials.email,
                      credentials.password,
                      credentials.authCode]);
       } else {
         chrome.send('completeLogin',
-                    [credentials.email,
+                    [credentials.gaiaId,
+                     credentials.email,
                      credentials.password,
                      credentials.usingSAML]);
       }
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js
index 34280a9a..f4f50ec 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/util.js
@@ -54,6 +54,7 @@
   var storeDir = Constants.WallpaperDirNameEnum.ORIGINAL;
   if (filenName.indexOf(Constants.CustomWallpaperThumbnailSuffix) != -1)
     storeDir = Constants.WallpaperDirNameEnum.THUMBNAIL;
+  filenName = filenName.replace(Constants.CustomWallpaperThumbnailSuffix, '');
   wallpaperFileEntry.file(function(file) {
     var reader = new FileReader();
     reader.onloadend = function() {
diff --git a/chrome/browser/resources/component_extension_resources.grd b/chrome/browser/resources/component_extension_resources.grd
index 914afdf..12abe4e3 100644
--- a/chrome/browser/resources/component_extension_resources.grd
+++ b/chrome/browser/resources/component_extension_resources.grd
@@ -49,7 +49,6 @@
       <include name="IDR_GAIA_AUTH_OFFLINE_JS" file="gaia_auth/offline.js" type="BINDATA" />
       <include name="IDR_GAIA_AUTH_OFFLINE_CSS" file="gaia_auth/offline.css" type="BINDATA" />
       <include name="IDR_GAIA_AUTH_SUCCESS" file="gaia_auth/success.html" allowexternalscript="true" type="BINDATA" />
-      <include name="IDR_GAIA_AUTH_SUCCESS_JS" file="gaia_auth/success.js" type="BINDATA" />
       <include name="IDR_GAIA_AUTH_UTIL_JS" file="gaia_auth/util.js" type="BINDATA" />
       <include name="IDR_GAIA_AUTH_BACKGROUND_JS" file="gaia_auth/background.js" type="BINDATA" />
       <include name="IDR_GAIA_AUTH_SAML_INJECTED_JS" file="gaia_auth/saml_injected.js" type="BINDATA" />
@@ -91,6 +90,7 @@
         <include name="IDR_HOTWORD_LAUNCHER_MANAGER_JS" file="hotword/launcher_manager.js" type="BINDATA" />
         <include name="IDR_HOTWORD_LOGGING_JS" file="hotword/logging.js" type="BINDATA" />
         <include name="IDR_HOTWORD_MANAGER_JS" file="hotword/manager.js" type="BINDATA" />
+        <include name="IDR_HOTWORD_METRICS_JS" file="hotword/metrics.js" type="BINDATA" />
         <include name="IDR_HOTWORD_NACL_MANAGER_JS" file="hotword/nacl_manager.js" type="BINDATA" />
         <include name="IDR_HOTWORD_PAGE_AUDIO_MANAGER_JS" file="hotword/page_audio_manager.js" type="BINDATA" />
         <include name="IDR_HOTWORD_STATE_MANAGER_JS" file="hotword/state_manager.js" type="BINDATA" />
diff --git a/chrome/browser/resources/crashes.html b/chrome/browser/resources/crashes.html
index 6e0de5f52..a340047b 100644
--- a/chrome/browser/resources/crashes.html
+++ b/chrome/browser/resources/crashes.html
@@ -5,6 +5,7 @@
   <title i18n-content="crashesTitle"></title>
   <link rel="stylesheet" href="chrome://resources/css/widgets.css">
   <link rel="stylesheet" href="crashes.css">
+  <script src="chrome://resources/js/action_link.js"></script>
   <script src="chrome://resources/js/load_time_data.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="chrome://crashes/strings.js"></script>
@@ -13,8 +14,8 @@
 <body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
   <header><h1 i18n-content="crashesTitle"></h1></header>
   <div id="crashUploadStatus" hidden>
-    <button id="uploadCrashes" class="link-button"
-            i18n-content="uploadCrashesLinkText">
+    <a is="action-link" id="uploadCrashes"
+        i18n-content="uploadCrashesLinkText"></a>
   </div>
   <div id="enabledMode">
     <h2 id="countBanner"></h2>
diff --git a/chrome/browser/resources/downloads/downloads.html b/chrome/browser/resources/downloads/downloads.html
index 837fb4b..470a189 100644
--- a/chrome/browser/resources/downloads/downloads.html
+++ b/chrome/browser/resources/downloads/downloads.html
@@ -6,6 +6,7 @@
   <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
   <!-- This has to come after chrome_shared.css -->
   <link rel="stylesheet" href="downloads.css">
+  <script src="chrome://resources/js/action_link.js"></script>
   <script src="chrome://resources/js/load_time_data.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="chrome://downloads/downloads.js"></script>
@@ -20,9 +21,8 @@
     <div class="summary" id="downloads-summary">
       <span id="downloads-summary-text"></span>
       <span id="downloads-actions">
-        <a id="open-downloads-folder" href="#"
-            i18n-content="open_downloads_folder">
-        </a>
+        <a is="action-link" id="open-downloads-folder"
+            i18n-content="open_downloads_folder"></a>
         <span id="clear-all-holder"></span>
       </span>
     </div>
diff --git a/chrome/browser/resources/downloads/downloads.js b/chrome/browser/resources/downloads/downloads.js
index 75124aa..193e9f69 100644
--- a/chrome/browser/resources/downloads/downloads.js
+++ b/chrome/browser/resources/downloads/downloads.js
@@ -52,15 +52,13 @@
 /**
  * Creates a link with a specified onclick handler and content.
  * @param {function()} onclick The onclick handler.
- * @param {string} value The link text.
+ * @param {string=} opt_text The link text.
  * @return {!Element} The created link element.
  */
-function createLink(onclick, value) {
-  var link = document.createElement('a');
+function createActionLink(onclick, opt_text) {
+  var link = document.createElement('a', 'action-link');
   link.onclick = onclick;
-  link.href = '#';
-  link.textContent = value;
-  link.oncontextmenu = function() { return false; };
+  if (opt_text) link.textContent = opt_text;
   return link;
 }
 
@@ -330,7 +328,7 @@
   this.nodeTitleArea_ = createElementWithClassName('div', 'title-area');
   this.safe_.appendChild(this.nodeTitleArea_);
 
-  this.nodeFileLink_ = createLink(this.openFile_.bind(this), '');
+  this.nodeFileLink_ = createActionLink(this.openFile_.bind(this));
   this.nodeFileLink_.className = 'name';
   this.nodeFileLink_.style.display = 'none';
   this.nodeTitleArea_.appendChild(this.nodeFileLink_);
@@ -356,7 +354,7 @@
   // We don't need 'show in folder' in chromium os. See download_ui.cc and
   // http://code.google.com/p/chromium-os/issues/detail?id=916.
   if (loadTimeData.valueExists('control_showinfolder')) {
-    this.controlShow_ = createLink(this.show_.bind(this),
+    this.controlShow_ = createActionLink(this.show_.bind(this),
         loadTimeData.getString('control_showinfolder'));
     this.nodeControls_.appendChild(this.controlShow_);
   } else {
@@ -369,17 +367,17 @@
   this.nodeControls_.appendChild(this.controlRetry_);
 
   // Pause/Resume are a toggle.
-  this.controlPause_ = createLink(this.pause_.bind(this),
+  this.controlPause_ = createActionLink(this.pause_.bind(this),
       loadTimeData.getString('control_pause'));
   this.nodeControls_.appendChild(this.controlPause_);
 
-  this.controlResume_ = createLink(this.resume_.bind(this),
+  this.controlResume_ = createActionLink(this.resume_.bind(this),
       loadTimeData.getString('control_resume'));
   this.nodeControls_.appendChild(this.controlResume_);
 
   // Anchors <a> don't support the "disabled" property.
   if (loadTimeData.getBoolean('allow_deleting_history')) {
-    this.controlRemove_ = createLink(this.remove_.bind(this),
+    this.controlRemove_ = createActionLink(this.remove_.bind(this),
         loadTimeData.getString('control_removefromlist'));
     this.controlRemove_.classList.add('control-remove-link');
   } else {
@@ -394,7 +392,7 @@
 
   this.nodeControls_.appendChild(this.controlRemove_);
 
-  this.controlCancel_ = createLink(this.cancel_.bind(this),
+  this.controlCancel_ = createActionLink(this.cancel_.bind(this),
       loadTimeData.getString('control_cancel'));
   this.nodeControls_.appendChild(this.controlCancel_);
 
@@ -414,11 +412,11 @@
 
   // Buttons for the malicious case.
   this.malwareNodeControls_ = createElementWithClassName('div', 'controls');
-  this.malwareSave_ = createLink(
+  this.malwareSave_ = createActionLink(
       this.saveDangerous_.bind(this),
       loadTimeData.getString('danger_restore'));
   this.malwareNodeControls_.appendChild(this.malwareSave_);
-  this.malwareDiscard_ = createLink(
+  this.malwareDiscard_ = createActionLink(
       this.discardDangerous_.bind(this),
       loadTimeData.getString('control_removefromlist'));
   this.malwareNodeControls_.appendChild(this.malwareDiscard_);
@@ -884,7 +882,8 @@
   var clearAllHolder = $('clear-all-holder');
   var clearAllElement;
   if (loadTimeData.getBoolean('allow_deleting_history')) {
-    clearAllElement = createLink(clearAll, loadTimeData.getString('clear_all'));
+    clearAllElement = createActionLink(
+        clearAll, loadTimeData.getString('clear_all'));
     clearAllElement.classList.add('clear-all-link');
     clearAllHolder.classList.remove('disabled-link');
   } else {
@@ -896,14 +895,10 @@
     clearAllHolder.hidden = true;
 
   clearAllHolder.appendChild(clearAllElement);
-  clearAllElement.oncontextmenu = function() { return false; };
 
-  // TODO(jhawkins): Use a link-button here.
-  var openDownloadsFolderLink = $('open-downloads-folder');
-  openDownloadsFolderLink.onclick = function() {
+  $('open-downloads-folder').onclick = function() {
     chrome.send('openDownloadsFolder');
   };
-  openDownloadsFolderLink.oncontextmenu = function() { return false; };
 
   $('term').onsearch = function(e) {
     setSearch($('term').value);
@@ -989,5 +984,3 @@
 
 // Add handlers to HTML elements.
 window.addEventListener('DOMContentLoaded', load);
-
-preventDefaultOnPoundLinkClicks();  // From util.js.
diff --git a/chrome/browser/resources/easy_unlock/manifest.json b/chrome/browser/resources/easy_unlock/manifest.json
index ca4cb4aa..0892f19 100644
--- a/chrome/browser/resources/easy_unlock/manifest.json
+++ b/chrome/browser/resources/easy_unlock/manifest.json
@@ -40,7 +40,7 @@
     "socket" : true,
     "low_energy" : true,
     "uuids": [
-      "0000AB34-0000-1000-8000-00805F9B34FB",  // Unlock UUID
+      "704EE561-3782-405A-A14B-2D47A2DDCDDF",  // Unlock UUID
       "29422880-D56D-11E3-9C1A-0800200C9A66"   // Setup UUID
     ]
   },
diff --git a/chrome/browser/resources/extensions/extension_error.html b/chrome/browser/resources/extensions/extension_error.html
index 1e90aece..041994b 100644
--- a/chrome/browser/resources/extensions/extension_error.html
+++ b/chrome/browser/resources/extensions/extension_error.html
@@ -7,13 +7,11 @@
   <div class="extension-error-list">
     <ul class="extension-error-list-contents"></ul>
     <div class="extension-error-list-show-more">
-      <button class="link-button"
-              i18n-content="extensionErrorsShowMore" hidden>
-      </button>
+      <a is="action-link" i18n-content="extensionErrorsShowMore" hidden></a>
     </div>
   </div>
   <div class="extension-error-metadata">
     <span class="extension-error-message"></span>
-    <button class="extension-error-view-details link-button"></button>
+    <a is="action-link" class="extension-error-view-details"></a>
   </div>
 </div>
diff --git a/chrome/browser/resources/extensions/extension_list.js b/chrome/browser/resources/extensions/extension_list.js
index 929bcb15..7546db1f 100644
--- a/chrome/browser/resources/extensions/extension_list.js
+++ b/chrome/browser/resources/extensions/extension_list.js
@@ -18,6 +18,7 @@
  *            dependentExtensions: Array,
  *            description: string,
  *            detailsUrl: string,
+ *            enableExtensionInfoDialog: boolean,
  *            enable_show_button: boolean,
  *            enabled: boolean,
  *            enabledIncognito: boolean,
@@ -308,7 +309,7 @@
       });
 
       // The 'View in Web Store/View Web Site' link.
-      if (extension.homepageUrl) {
+      if (extension.homepageUrl && !extension.enableExtensionInfoDialog) {
         var siteLink = node.querySelector('.site-link');
         siteLink.href = extension.homepageUrl;
         siteLink.textContent = loadTimeData.getString(
diff --git a/chrome/browser/resources/extensions/extensions.css b/chrome/browser/resources/extensions/extensions.css
index f1ca739..81d1d213 100644
--- a/chrome/browser/resources/extensions/extensions.css
+++ b/chrome/browser/resources/extensions/extensions.css
@@ -230,7 +230,7 @@
   margin-bottom: 0.5em;
 }
 
-.action-links :-webkit-any(a, .link-button) {
+.action-links a {
   -webkit-margin-end: 1em;
   -webkit-margin-start: 0;
 }
@@ -256,10 +256,10 @@
   position: relative;
 }
 
-/* We use x.link-button here so that we get higher specifity than the
- * link-button rules without resorting to the Dark Side (!IMPORTANT). */
-.terminated-reload-link.link-button,
-.corrupted-repair-button.link-button {
+/* We use x[is='action-link'] here so that we get higher specifity than the
+ * action link rules without resorting to the Dark Side (!IMPORTANT). */
+.terminated-reload-link[is='action-link'],
+.corrupted-repair-button[is='action-link'] {
   /* Matches width of trash. */
   -webkit-margin-end: 30px;
 }
diff --git a/chrome/browser/resources/extensions/extensions.html b/chrome/browser/resources/extensions/extensions.html
index a3add541..d6d806d 100644
--- a/chrome/browser/resources/extensions/extensions.html
+++ b/chrome/browser/resources/extensions/extensions.html
@@ -16,6 +16,7 @@
 <link rel="stylesheet" href="chrome://resources/css/trash.css">
 <link rel="stylesheet" href="../uber/uber_shared.css">
 
+<script src="chrome://resources/js/action_link.js"></script>
 <script src="chrome://resources/js/cr.js"></script>
 <script src="chrome://resources/js/load_time_data.js"></script>
 <script src="chrome://resources/js/util.js"></script>
@@ -115,10 +116,8 @@
     <a target="_blank" class="more-extensions-link"
         i18n-values="href:extensionSettingsGetMoreExtensionsUrl"
         i18n-content="extensionSettingsGetMoreExtensions"></a>
-    <a target="_blank" hidden
-        class="extension-commands-config"
-        i18n-content="extensionSettingsCommandsLink"
-        href="#"></a>
+    <a is="action-link" class="extension-commands-config"
+        i18n-content="extensionSettingsCommandsLink" hidden></a>
   </div>
 </div>
 
@@ -137,18 +136,17 @@
            i18n-content="extensionSettingsCorruptInstall" hidden></p>
         <p class="extension-description"></p>
         <div class="action-links">
-          <button class="permissions-link link-button"
-                  i18n-content="extensionSettingsPermissions"></button>
-          <button class="options-button link-button"
-                  i18n-content="extensionSettingsOptions" hidden></button>
+          <a is="action-link" class="permissions-link"
+              i18n-content="extensionSettingsPermissions"></a>
+          <a is="action-link" class="options-button"
+              i18n-content="extensionSettingsOptions" hidden></a>
           <a class="options-link"
-             i18n-content="extensionSettingsOptions" hidden></a>
+              i18n-content="extensionSettingsOptions" hidden></a>
           <a class="site-link" target="_parent" hidden></a>
-          <button class="launch-link link-button"
-                  i18n-content="extensionSettingsLaunch" hidden></button>
-          <button class="reload-link link-button"
-                  i18n-content="extensionSettingsReloadUnpacked" hidden>
-          </button>
+          <a is="action-link" class="launch-link"
+              i18n-content="extensionSettingsLaunch" hidden></a>
+          <a is="action-link" class="reload-link"
+              i18n-content="extensionSettingsReloadUnpacked" hidden></a>
         </div>
         <div class="permanent-warnings">
           <div class="extension-warnings" hidden>
@@ -175,14 +173,14 @@
           </div>
           <div class="load-path" hidden>
             <span i18n-content="extensionSettingsExtensionPath"></span>
-            <a href="#"></a>
+            <a is="action-link"></a>
           </div>
           <div class="managed-message"
               i18n-content="extensionSettingsPolicyControlled" hidden>
           </div>
           <div class="active-views" hidden>
             <span i18n-content="extensionSettingsInspectViews"></span>
-            <a href="#"></a>
+            <a is="action-link"></a>
           </div>
           <div class="manifest-errors" hidden></div>
           <div class="runtime-errors" hidden></div>
@@ -225,10 +223,10 @@
         </div>
       </div>
       <div class="enable-controls">
-        <div class="terminated-reload-link link-button"
-            i18n-content="extensionSettingsReloadTerminated" hidden></div>
-        <div class="corrupted-repair-button link-button"
-            i18n-content="extensionSettingsRepairCorrupted" hidden></div>
+        <a is="action-link" class="terminated-reload-link"
+            i18n-content="extensionSettingsReloadTerminated" hidden></a>
+        <a is="action-link" class="corrupted-repair-button"
+            i18n-content="extensionSettingsRepairCorrupted" hidden></a>
         <div class="checkbox enable-checkbox" hidden><label>
           <input type="checkbox">
           <span class="enable-checkbox-text">
diff --git a/chrome/browser/resources/extensions/extensions.js b/chrome/browser/resources/extensions/extensions.js
index ca186f2..42ad4a4 100644
--- a/chrome/browser/resources/extensions/extensions.js
+++ b/chrome/browser/resources/extensions/extensions.js
@@ -195,8 +195,6 @@
         if (overlayName == 'configureCommands')
           this.showExtensionCommandsConfigUi_();
       }
-
-      preventDefaultOnPoundLinkClicks();  // From webui/js/util.js.
     },
 
     /**
diff --git a/chrome/browser/resources/feedback/js/event_handler.js b/chrome/browser/resources/feedback/js/event_handler.js
index 4fafc52..8e168cb 100644
--- a/chrome/browser/resources/feedback/js/event_handler.js
+++ b/chrome/browser/resources/feedback/js/event_handler.js
@@ -46,6 +46,8 @@
   'ljclpkphhpbpinifbeabbhlfddcpfdde', // Hangouts Extension
   'nckgahadagoaajjgafhacjanaoiihapd', // Hangouts Extension
   'knipolnnllmklapflnccelgolnpehhpl', // Hangouts Extension
+  'dogkdgiahcdchbabhdmpbhlfoddjined', // GLS nightly
+  'khkjfddibboofomnlkndfedpoccieiee', // GLS stable
 ];
 
 /**
diff --git a/chrome/browser/resources/gaia_auth/background.js b/chrome/browser/resources/gaia_auth/background.js
index ffe0b078..db94085 100644
--- a/chrome/browser/resources/gaia_auth/background.js
+++ b/chrome/browser/resources/gaia_auth/background.js
@@ -119,6 +119,10 @@
   // 'google-accounts-signin'.
   email_: null,
 
+  // Gaia Id of the newly authenticated user based on the gaia response
+  // header 'google-accounts-signin'.
+  gaiaId_: null,
+
   // Session index of the newly authenticated user based on the gaia response
   // header 'google-accounts-signin'.
   sessionIndex_: null,
@@ -204,7 +208,7 @@
   onCompleted: function(details) {
     // Only monitors requests in the gaia frame whose parent frame ID must be
     // positive.
-    if (!this.isDesktopFlow_ || details.parentFrameId <= 0)
+    if (details.parentFrameId <= 0)
       return;
 
     if (details.url.lastIndexOf(backgroundBridgeManager.CONTINUE_URL_BASE, 0) ==
@@ -213,11 +217,12 @@
       if (details.url.indexOf('ntp=1') >= 0)
         skipForNow = true;
 
-      // TOOD(guohui): Show password confirmation UI.
+      // TOOD(guohui): For desktop SAML flow, show password confirmation UI.
       var passwords = this.onGetScrapedPasswords_();
       var msg = {
         'name': 'completeLogin',
         'email': this.email_,
+        'gaiaId': this.gaiaId_,
         'password': passwords[0],
         'sessionIndex': this.sessionIndex_,
         'skipForNow': skipForNow
@@ -262,11 +267,7 @@
   onHeadersReceived: function(details) {
     var headers = details.responseHeaders;
 
-    if (this.isDesktopFlow_ &&
-        this.gaiaUrl_ &&
-        details.url.lastIndexOf(this.gaiaUrl_) == 0) {
-      // TODO(xiyuan, guohui): CrOS should reuse the logic below for reading the
-      // email for SAML users and cut off the /ListAccount call.
+    if (this.gaiaUrl_ && details.url.lastIndexOf(this.gaiaUrl_) == 0) {
       for (var i = 0; headers && i < headers.length; ++i) {
         if (headers[i].name.toLowerCase() == 'google-accounts-signin') {
           var headerValues = headers[i].value.toLowerCase().split(',');
@@ -277,6 +278,7 @@
           });
           // Remove "" around.
           this.email_ = signinDetails['email'].slice(1, -1);
+          this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1);
           this.sessionIndex_ = signinDetails['sessionindex'];
           break;
         }
diff --git a/chrome/browser/resources/gaia_auth/main.js b/chrome/browser/resources/gaia_auth/main.js
index ba48c65d..b9a57d8 100644
--- a/chrome/browser/resources/gaia_auth/main.js
+++ b/chrome/browser/resources/gaia_auth/main.js
@@ -48,6 +48,7 @@
 
 Authenticator.prototype = {
   email_: null,
+  gaiaId_: null,
 
   // Depending on the key type chosen, this will contain the plain text password
   // or a credential derived from it along with the information required to
@@ -56,6 +57,9 @@
   // when support for key types other than plain text password is added.
   passwordBytes_: null,
 
+  chooseWhatToSync_: false,
+  skipForNow_: false,
+  sessionIndex_: null,
   attemptToken_: null,
 
   // Input params from extension initialization URL.
@@ -104,10 +108,6 @@
            this.GAIA_URL.indexOf(msg.origin) == 0;
   },
 
-  isInternalMessage_: function(msg) {
-    return msg.origin == Authenticator.THIS_EXTENSION_ORIGIN;
-  },
-
   isParentMessage_: function(msg) {
     return msg.origin == this.parentPage_;
   },
@@ -165,9 +165,9 @@
         });
         this.supportChannel_.registerMessage(
             'switchToFullTab', this.switchToFullTab_.bind(this));
-        this.supportChannel_.registerMessage(
-            'completeLogin', this.completeLogin_.bind(this));
       }
+      this.supportChannel_.registerMessage(
+          'completeLogin', this.onCompleteLogin_.bind(this));
       this.initSAML_();
       this.maybeInitialized_();
     }.bind(this));
@@ -198,7 +198,7 @@
   /**
    * Invoked when the background script sends a message to indicate that the
    * current content does not fit in a constrained window.
-   * @param {Object=} opt_extraMsg Optional extra info to send.
+   * @param {Object=} msg Extra info to send.
    */
   switchToFullTab_: function(msg) {
     var parentMsg = {
@@ -220,8 +220,11 @@
                   this.passwordBytes_,
       'usingSAML': this.isSAMLFlow_,
       'chooseWhatToSync': this.chooseWhatToSync_ || false,
-      'skipForNow': opt_extraMsg && opt_extraMsg.skipForNow,
-      'sessionIndex': opt_extraMsg && opt_extraMsg.sessionIndex
+      'skipForNow': (opt_extraMsg && opt_extraMsg.skipForNow) ||
+                    this.skipForNow_,
+      'sessionIndex': (opt_extraMsg && opt_extraMsg.sessionIndex) ||
+                      this.sessionIndex_,
+      'gaiaId': (opt_extraMsg && opt_extraMsg.gaiaId) || this.gaiaId_
     };
     window.parent.postMessage(msg, this.parentPage_);
     this.supportChannel_.send({name: 'resetAuth'});
@@ -268,6 +271,7 @@
       // from the GAIA login form are no longer relevant and can be discarded.
       this.isSAMLFlow_ = true;
       this.email_ = null;
+      this.gaiaId_ = null;
       this.passwordBytes_ = null;
     }
 
@@ -316,8 +320,9 @@
         console.error('Authenticator.onAPICall_: unsupported key type');
         return;
       }
+      // Not setting |email_| and |gaiaId_| because this API call will
+      // eventually be followed by onCompleteLogin_() which does set it.
       this.apiToken_ = call.token;
-      this.email_ = call.user;
       this.passwordBytes_ = call.passwordBytes;
     } else if (call.method == 'confirm') {
       if (call.token != this.apiToken_)
@@ -342,21 +347,34 @@
     });
   },
 
-  onConfirmLogin_: function() {
-    if (!this.isSAMLFlow_) {
-      this.completeLogin_();
+  /**
+   * Callback invoked for 'completeLogin' message.
+   * @param {Object=} msg Message sent from background page.
+   */
+  onCompleteLogin_: function(msg) {
+    if (!msg.email || !msg.gaiaId || !msg.sessionIndex) {
+      console.error('Missing fields to complete login.');
+      window.parent.postMessage({method: 'missingGaiaInfo'}, this.parentPage_);
       return;
     }
 
-    var apiUsed = !!this.passwordBytes_;
+    // Skip SAML extra steps for desktop flow and non-SAML flow.
+    if (!this.isSAMLFlow_ || this.desktopMode_) {
+      this.completeLogin_(msg);
+      return;
+    }
 
-    // Retrieve the e-mail address of the user who just authenticated from GAIA.
-    window.parent.postMessage({method: 'retrieveAuthenticatedUserEmail',
-                               attemptToken: this.attemptToken_,
-                               apiUsed: apiUsed},
-                              this.parentPage_);
+    this.email_ = msg.email;
+    this.gaiaId_ = msg.gaiaId;
+    // Password from |msg| is not used because ChromeOS SAML flow
+    // gets password by asking user to confirm.
+    this.skipForNow_ = msg.skipForNow;
+    this.sessionIndex_ = msg.sessionIndex;
 
-    if (!apiUsed) {
+    if (this.passwordBytes_) {
+      window.parent.postMessage({method: 'samlApiUsed'}, this.parentPage_);
+      this.completeLogin_(msg);
+    } else {
       this.supportChannel_.sendWithCallback(
           {name: 'getScrapedPasswords'},
           function(passwords) {
@@ -374,13 +392,6 @@
     }
   },
 
-  maybeCompleteSAMLLogin_: function() {
-    // SAML login is complete when the user's e-mail address has been retrieved
-    // from GAIA and the user has successfully confirmed the password.
-    if (this.email_ !== null && this.passwordBytes_ !== null)
-      this.completeLogin_();
-  },
-
   onVerifyConfirmedPassword_: function(password) {
     this.supportChannel_.sendWithCallback(
         {name: 'getScrapedPasswords'},
@@ -388,7 +399,10 @@
           for (var i = 0; i < passwords.length; ++i) {
             if (passwords[i] == password) {
               this.passwordBytes_ = passwords[i];
-              this.maybeCompleteSAMLLogin_();
+              // SAML login is complete when the user has successfully
+              // confirmed the password.
+              if (this.passwordBytes_ !== null)
+                this.completeLogin_();
               return;
             }
           }
@@ -401,6 +415,7 @@
   onMessage: function(e) {
     var msg = e.data;
     if (msg.method == 'attemptLogin' && this.isGaiaMessage_(e)) {
+      // At this point GAIA does not yet know the gaiaId, so its not set here.
       this.email_ = msg.email;
       this.passwordBytes_ = msg.password;
       this.attemptToken_ = msg.attemptToken;
@@ -416,27 +431,15 @@
         this.maybeInitialized_();
       }
       this.email_ = null;
+      this.gaiaId_ = null;
+      this.sessionIndex_ = false;
       this.passwordBytes_ = null;
       this.attemptToken_ = null;
       this.isSAMLFlow_ = false;
+      this.skipForNow_ = false;
+      this.chooseWhatToSync_ = false;
       if (this.supportChannel_)
         this.supportChannel_.send({name: 'resetAuth'});
-    } else if (msg.method == 'setAuthenticatedUserEmail' &&
-               this.isParentMessage_(e)) {
-      if (this.attemptToken_ == msg.attemptToken) {
-        this.email_ = msg.email;
-        this.maybeCompleteSAMLLogin_();
-      }
-    } else if (msg.method == 'confirmLogin' && this.isInternalMessage_(e)) {
-      // In the desktop mode, Chrome needs to wait for extra info such as
-      // session index from the background JS.
-      if (this.desktopMode_)
-        return;
-
-      if (this.attemptToken_ == msg.attemptToken)
-        this.onConfirmLogin_();
-      else
-        console.error('Authenticator.onMessage: unexpected attemptToken!?');
     } else if (msg.method == 'verifyConfirmedPassword' &&
                this.isParentMessage_(e)) {
       this.onVerifyConfirmedPassword_(msg.password);
diff --git a/chrome/browser/resources/gaia_auth/success.html b/chrome/browser/resources/gaia_auth/success.html
index d9c57127..fa5b1e6c 100644
--- a/chrome/browser/resources/gaia_auth/success.html
+++ b/chrome/browser/resources/gaia_auth/success.html
@@ -1,8 +1,6 @@
 <!DOCTYPE html>
 <head>
 <meta charset="utf-8">
-<script src="util.js"></script>
-<script src="success.js"></script>
 </head>
 <html>
 <body></body>
diff --git a/chrome/browser/resources/gaia_auth/success.js b/chrome/browser/resources/gaia_auth/success.js
deleted file mode 100644
index 54ed7fac..0000000
--- a/chrome/browser/resources/gaia_auth/success.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-function load() {
-  var params = getUrlSearchParams(location.search);
-  var msg = {
-    'method': 'confirmLogin',
-    'attemptToken': params['attemptToken']
-  };
-  window.parent.postMessage(msg,
-          'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/main.html');
-}
-
-document.addEventListener('DOMContentLoaded', load);
-
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js
new file mode 100644
index 0000000..4a1bf5a
--- /dev/null
+++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -0,0 +1,315 @@
+// 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.
+
+/**
+ * @fileoverview An UI component to authenciate to Chrome. The component hosts
+ * IdP web pages in a webview. A client who is interested in monitoring
+ * authentication events should pass a listener object of type
+ * cr.login.GaiaAuthHost.Listener as defined in this file. After initialization,
+ * call {@code load} to start the authentication flow.
+ */
+cr.define('cr.login', function() {
+  'use strict';
+
+  var IDP_ORIGIN = 'https://accounts.google.com/';
+  var IDP_PATH = 'ServiceLogin?skipvpage=true&sarp=1&rm=hide';
+  var CONTINUE_URL =
+      'chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/success.html';
+  var SIGN_IN_HEADER = 'google-accounts-signin';
+  var EMBEDDED_FORM_HEADER = 'google-accounts-embedded';
+  var SAML_HEADER = 'google-accounts-saml';
+
+  /**
+   * The source URL parameter for the constrained signin flow.
+   */
+  var CONSTRAINED_FLOW_SOURCE = 'chrome';
+
+  /**
+   * Enum for the authorization mode, must match AuthMode defined in
+   * chrome/browser/ui/webui/inline_login_ui.cc.
+   * @enum {number}
+   */
+  var AuthMode = {
+    DEFAULT: 0,
+    OFFLINE: 1,
+    DESKTOP: 2
+  };
+
+  /**
+   * Enum for the authorization type.
+   * @enum {number}
+   */
+  var AuthFlow = {
+    DEFAULT: 0,
+    SAML: 1
+  };
+
+  /**
+   * Initializes the authenticator component.
+   * @param {webview|string} webview The webview element or its ID to host IdP
+   *     web pages.
+   * @param {Authenticator.Listener=} opt_listener An optional listener for
+   *     authentication events.
+   * @constructor
+   * @extends {cr.EventTarget}
+   */
+  function Authenticator(webview, opt_listener) {
+    this.webview_ = typeof webview == 'string' ? $(webview) : webview;
+    assert(this.webview_);
+
+    this.listener_ = opt_listener || null;
+
+    this.email_ = null;
+    this.password_ = null;
+    this.sessionIndex_ = null;
+    this.chooseWhatToSync_ = false;
+    this.skipForNow_ = false;
+    this.authFlow_ = AuthFlow.DEFAULT;
+    this.loaded_ = false;
+    this.idpOrigin_ = null;
+    this.continueUrl_ = null;
+    this.continueUrlWithoutParams_ = null;
+    this.initialFrameUrl_ = null;
+    this.reloadUrl_ = null;
+  }
+
+  // TODO(guohui,xiyuan): no need to inherit EventTarget once we deprecate the
+  // old event-based signin flow.
+  Authenticator.prototype = Object.create(cr.EventTarget.prototype);
+
+  /**
+   * An interface for receiving notifications upon authentication events.
+   * @interface
+   */
+  Authenticator.Listener = function() {};
+
+  /**
+   * Invoked when authentication UI is ready.
+   */
+  Authenticator.Listener.prototype.onReady = function(e) {};
+
+  /**
+   * Invoked when authentication is completed successfully with credential data.
+   * A credential data object looks like this:
+   * <pre>
+   * {@code
+   * {
+   *   email: 'xx@gmail.com',
+   *   password: 'xxxx',  // May be null or empty.
+   *   usingSAML: false,
+   *   chooseWhatToSync: false,
+   *   skipForNow: false,
+   *   sessionIndex: '0'
+   * }
+   * }
+   * </pre>
+   * @param {Object} credentials A credential data object.
+   */
+  Authenticator.Listener.prototype.onSuccess = function(credentials) {};
+
+  /**
+   * Invoked when the requested URL does not fit the container.
+   * @param {string} url Request URL.
+   */
+  Authenticator.Listener.prototype.onResize = function(url) {};
+
+  /**
+   * Invoked when a new window event is fired.
+   * @param {Event} e Event object.
+   */
+  Authenticator.Listener.prototype.onNewWindow = function(e) {};
+
+  /**
+   * Loads the authenticator component with the given parameters.
+   * @param {AuthMode} authMode Authorization mode.
+   * @param {Object} data Parameters for the authorization flow.
+   */
+  Authenticator.prototype.load = function(authMode, data) {
+    this.idpOrigin_ = data.gaiaUrl || IDP_ORIGIN;
+    this.continueUrl_ = data.continueUrl || CONTINUE_URL;
+    this.continueUrlWithoutParams_ =
+        this.continueUrl_.substring(0, this.continueUrl_.indexOf('?')) ||
+        this.continueUrl_;
+    this.isConstrainedWindow_ = data.constrained == '1';
+
+    this.initialFrameUrl_ = this.constructInitialFrameUrl_(data);
+    this.reloadUrl_ = data.frameUrl || this.initialFrameUrl_;
+    this.authFlow_ = AuthFlow.DEFAULT;
+
+    this.webview_.src = this.reloadUrl_;
+    this.webview_.addEventListener(
+        'newwindow', this.onNewWindow_.bind(this));
+    this.webview_.request.onCompleted.addListener(
+        this.onRequestCompleted_.bind(this),
+        {urls: ['*://*/*', this.continueUrlWithoutParams_ + '*'],
+            types: ['main_frame']},
+        ['responseHeaders']);
+    this.webview_.request.onHeadersReceived.addListener(
+        this.onHeadersReceived_.bind(this),
+        {urls: [this.idpOrigin_ + '*'], types: ['main_frame']},
+        ['responseHeaders']);
+    window.addEventListener(
+        'message', this.onMessage_.bind(this), false);
+  };
+
+  /**
+   * Reloads the authenticator component.
+   */
+  Authenticator.prototype.reload = function() {
+    this.webview_.src = this.reloadUrl_;
+    this.authFlow_ = AuthFlow.DEFAULT;
+  };
+
+  Authenticator.prototype.constructInitialFrameUrl_ = function(data) {
+    var url = this.idpOrigin_ + (data.gaiaPath || IDP_PATH);
+
+    url = appendParam(url, 'continue', this.continueUrl_);
+    url = appendParam(url, 'service', data.service);
+    if (data.hl)
+      url = appendParam(url, 'hl', data.hl);
+    if (data.email)
+      url = appendParam(url, 'Email', data.email);
+    if (this.isConstrainedWindow_)
+      url = appendParam(url, 'source', CONSTRAINED_FLOW_SOURCE);
+    return url;
+  };
+
+  /**
+   * Invoked when a main frame request in the webview has completed.
+   * @private
+   */
+  Authenticator.prototype.onRequestCompleted_ = function(details) {
+    var currentUrl = details.url;
+    if (currentUrl.lastIndexOf(this.continueUrlWithoutParams_, 0) == 0) {
+      if (currentUrl.indexOf('ntp=1') >= 0) {
+        this.skipForNow_ = true;
+      }
+      this.onAuthCompleted_();
+      return;
+    }
+
+    if (this.isConstrainedWindow_) {
+      var isEmbeddedPage = false;
+      if (this.idpOrigin_ && currentUrl.lastIndexOf(this.idpOrigin_) == 0) {
+        var headers = details.responseHeaders;
+        for (var i = 0; headers && i < headers.length; ++i) {
+          if (headers[i].name.toLowerCase() == EMBEDDED_FORM_HEADER) {
+            isEmbeddedPage = true;
+            break;
+          }
+        }
+      }
+      if (!isEmbeddedPage && this.listener_) {
+        this.listener_.onResize(currentUrl);
+        return;
+      }
+    }
+
+    if (currentUrl.lastIndexOf(this.idpOrigin_) == 0) {
+      this.webview_.contentWindow.postMessage({}, currentUrl);
+    }
+
+    if (!this.loaded_) {
+      this.loaded_ = true;
+      if (this.listener_) {
+        this.listener_.onReady();
+      }
+    }
+  };
+
+  /**
+   * Invoked when headers are received in the main frame of the webview. It
+   * 1) reads the authenticated user info from a signin header,
+   * 2) signals the start of a saml flow upon receiving a saml header.
+   * @return {!Object} Modified request headers.
+   * @private
+   */
+  Authenticator.prototype.onHeadersReceived_ = function(details) {
+    var headers = details.responseHeaders;
+    for (var i = 0; headers && i < headers.length; ++i) {
+      var header = headers[i];
+      var headerName = header.name.toLowerCase();
+      if (headerName == SIGN_IN_HEADER) {
+        var headerValues = header.value.toLowerCase().split(',');
+        var signinDetails = {};
+        headerValues.forEach(function(e) {
+          var pair = e.split('=');
+          signinDetails[pair[0].trim()] = pair[1].trim();
+        });
+        // Removes "" around.
+        var email = signinDetails['email'].slice(1, -1);
+        if (this.email_ != email) {
+          this.email_ = email;
+          // Clears the scraped password if the email has changed.
+          this.password_ = null;
+        }
+        this.sessionIndex_ = signinDetails['sessionindex'];
+      } else if (headerName == SAML_HEADER) {
+        this.authFlow_ = AuthFlow.SAML;
+      }
+    }
+  };
+
+  /**
+   * Invoked when an HTML5 message is received.
+   * @param {object} e Payload of the received HTML5 message.
+   * @private
+   */
+  Authenticator.prototype.onMessage_ = function(e) {
+    if (e.origin != this.idpOrigin_) {
+      return;
+    }
+
+    var msg = e.data;
+
+    if (msg.method == 'attemptLogin') {
+      this.email_ = msg.email;
+      this.password_ = msg.password;
+      this.chooseWhatToSync_ = msg.chooseWhatToSync;
+    }
+  };
+
+  /**
+   * Invoked to process authentication completion.
+   * @private
+   */
+  Authenticator.prototype.onAuthCompleted_ = function() {
+    if (!this.listener_) {
+      return;
+    }
+
+    if (!this.email_ && !this.skipForNow_) {
+      this.webview_.src = this.initialFrameUrl_;
+      return;
+    }
+
+    this.listener_.onSuccess({email: this.email_,
+                              password: this.password_,
+                              usingSAML: this.authFlow_ == AuthFlow.SAML,
+                              chooseWhatToSync: this.chooseWhatToSync_,
+                              skipForNow: this.skipForNow_,
+                              sessionIndex: this.sessionIndex_ || ''});
+  };
+
+  /**
+   * Invoked when the webview attempts to open a new window.
+   * @private
+   */
+  Authenticator.prototype.onNewWindow_ = function(e) {
+    if (!this.listener_) {
+      return;
+    }
+
+    this.listener_.onNewWindow(e);
+  };
+
+  Authenticator.AuthFlow = AuthFlow;
+  Authenticator.AuthMode = AuthMode;
+
+  return {
+    // TODO(guohui, xiyuan): Rename GaiaAuthHost to Authenticator once the old
+    // iframe-based flow is deprecated.
+    GaiaAuthHost: Authenticator
+  };
+});
diff --git a/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js b/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
index e835e20..cf870cb 100644
--- a/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
+++ b/chrome/browser/resources/gaia_auth_host/gaia_auth_host.js
@@ -141,18 +141,6 @@
     successCallback_: null,
 
     /**
-     * Invoked when GAIA indicates login success and SAML was used. At this
-     * point, GAIA cookies are present but the identity of the authenticated
-     * user is not known. The embedder of GaiaAuthHost should extract the GAIA
-     * cookies from the cookie jar, query GAIA for the authenticated user's
-     * e-mail address and invoke GaiaAuthHost.setAuthenticatedUserEmail with the
-     * result. The argument is an opaque token that should be passed back to
-     * GaiaAuthHost.setAuthenticatedUserEmail.
-     * @type {function(number)}
-     */
-    retrieveAuthenticatedUserEmailCallback_: null,
-
-    /**
      * Invoked when the auth flow needs a user to confirm his/her passwords.
      * This could happen when there are more than one passwords scraped during
      * SAML flow. The embedder of GaiaAuthHost should show an UI to collect a
@@ -175,9 +163,23 @@
     /**
      * Invoked when the authentication flow had to be aborted because content
      * served over an unencrypted connection was detected.
+     */
     insecureContentBlockedCallback_: null,
 
     /**
+     * Invoked to display an error message to the user when a GAIA error occurs
+     * during authentication.
+     * @type {function()}
+     */
+    missingGaiaInfoCallback_: null,
+
+    /**
+     * Invoked to record that the credentials passing API was used.
+     * @type {function()}
+     */
+    samlApiUsedCallback_: null,
+
+    /**
      * The iframe container.
      * @type {HTMLIFrameElement}
      */
@@ -186,14 +188,6 @@
     },
 
     /**
-     * Sets retrieveAuthenticatedUserEmailCallback_.
-     * @type {function()}
-     */
-    set retrieveAuthenticatedUserEmailCallback(callback) {
-      this.retrieveAuthenticatedUserEmailCallback_ = callback;
-    },
-
-    /**
      * Sets confirmPasswordCallback_.
      * @type {function()}
      */
@@ -218,6 +212,22 @@
     },
 
     /**
+     * Sets missingGaiaInfoCallback_.
+     * @type {function()}
+     */
+    set missingGaiaInfoCallback(callback) {
+      this.missingGaiaInfoCallback_ = callback;
+    },
+
+    /**
+     * Sets samlApiUsedCallback_.
+     * @type {function()}
+     */
+    set samlApiUsedCallback(callback) {
+      this.samlApiUsedCallback_ = callback;
+    },
+
+    /**
      * Loads the auth extension.
      * @param {AuthMode} authMode Authorization mode.
      * @param {Object} data Parameters for the auth extension. See the auth
@@ -286,21 +296,6 @@
     },
 
     /**
-     * Sends the authenticated user's e-mail address to the auth extension.
-     * @param {number} attemptToken The opaque token provided to the
-     *     retrieveAuthenticatedUserEmailCallback_.
-     * @param {string} email The authenticated user's e-mail address.
-     */
-    setAuthenticatedUserEmail: function(attemptToken, email) {
-      var msg = {
-        method: 'setAuthenticatedUserEmail',
-        attemptToken: attemptToken,
-        email: email
-      };
-      this.frame_.contentWindow.postMessage(msg, AUTH_URL_BASE);
-    },
-
-    /**
      * Invoked to process authentication success.
      * @param {Object} credentials Credential object to pass to success
      *     callback.
@@ -346,6 +341,7 @@
         }
         this.onAuthSuccess_({email: msg.email,
                              password: msg.password,
+                             gaiaId: msg.gaiaId,
                              useOffline: msg.method == 'offlineLogin',
                              usingSAML: msg.usingSAML || false,
                              chooseWhatToSync: msg.chooseWhatToSync,
@@ -354,17 +350,6 @@
         return;
       }
 
-      if (msg.method == 'retrieveAuthenticatedUserEmail') {
-        if (this.retrieveAuthenticatedUserEmailCallback_) {
-          this.retrieveAuthenticatedUserEmailCallback_(msg.attemptToken,
-                                                       msg.apiUsed);
-        } else {
-          console.error(
-              'GaiaAuthHost: Invalid retrieveAuthenticatedUserEmailCallback_.');
-        }
-        return;
-      }
-
       if (msg.method == 'confirmPassword') {
         if (this.confirmPasswordCallback_)
           this.confirmPasswordCallback_(msg.passwordCount);
@@ -402,6 +387,24 @@
         return;
       }
 
+      if (msg.method == 'missingGaiaInfo') {
+        if (this.missingGaiaInfoCallback_) {
+          this.missingGaiaInfoCallback_();
+        } else {
+          console.error('GaiaAuthHost: Invalid missingGaiaInfoCallback_.');
+        }
+        return;
+      }
+
+      if (msg.method == 'samlApiUsed') {
+        if (this.samlApiUsedCallback_) {
+          this.samlApiUsedCallback_();
+        } else {
+          console.error('GaiaAuthHost: Invalid samlApiUsedCallback_.');
+        }
+        return;
+      }
+
       console.error('Unknown message method=' + msg.method);
     }
   };
diff --git a/chrome/browser/resources/help/help.html b/chrome/browser/resources/help/help.html
index 6d7b1fb..5f637b6 100644
--- a/chrome/browser/resources/help/help.html
+++ b/chrome/browser/resources/help/help.html
@@ -13,6 +13,7 @@
   <link rel="stylesheet" href="channel_change_page.css">
 </if>
 
+  <script src="chrome://resources/js/action_link.js"></script>
   <script src="chrome://resources/js/cr.js"></script>
   <script src="chrome://resources/js/cr/event_target.js"></script>
   <script src="chrome://resources/js/load_time_data.js"></script>
diff --git a/chrome/browser/resources/help/help_content.html b/chrome/browser/resources/help/help_content.html
index 591efe9..60527ad 100644
--- a/chrome/browser/resources/help/help_content.html
+++ b/chrome/browser/resources/help/help_content.html
@@ -96,9 +96,7 @@
         <div id="build-date"></div>
       </section>
     </div>
-    <button id="more-info-expander" class="link-button"
-        i18n-content="showMoreInfo">
-    </button>
+    <a is="action-link" id="more-info-expander" i18n-content="showMoreInfo"></a>
 </if>
   </div>
   <div id="product-container">
diff --git a/chrome/browser/resources/history/history.css b/chrome/browser/resources/history/history.css
index 45bbd96..c3caa576 100644
--- a/chrome/browser/resources/history/history.css
+++ b/chrome/browser/resources/history/history.css
@@ -506,7 +506,7 @@
 }
 
 .entry .title > a,
-.site-domain .link-button {
+.site-domain [is='action-link'] {
   color: rgb(48, 57, 66);
   margin: 2px;
   padding: 2px;
diff --git a/chrome/browser/resources/history/history.html b/chrome/browser/resources/history/history.html
index 8362eff..bbe5546 100644
--- a/chrome/browser/resources/history/history.html
+++ b/chrome/browser/resources/history/history.html
@@ -27,6 +27,7 @@
 <link rel="stylesheet" href="other_devices.css">
 </if>
 
+<script src="chrome://resources/js/action_link.js"></script>
 <script src="chrome://resources/js/assert.js"></script>
 <script src="chrome://resources/js/event_tracker.js"></script>
 <script src="chrome://resources/js/util.js"></script>
@@ -78,7 +79,7 @@
       <h1 i18n-content="history"></h1>
       <div id="search-form" class="search-field-container">
         <input type="search" id="search-field"
-               i18n-values="aria-label:searchButton" required>
+               i18n-values="aria-label:searchButton">
         <input type="submit" id="search-button"
                i18n-values="value:searchButton">
       </div>
@@ -122,13 +123,9 @@
       </span>
     </div>
     <div id="results-pagination">
-      <button id="newest-button" class="link-button" i18n-content="newest"
-          hidden>
-      </button>
-      <button id="newer-button" class="link-button" i18n-content="newer" hidden>
-      </button>
-      <button id="older-button" class="link-button" i18n-content="older" hidden>
-      </button>
+      <a is="action-link" id="newest-button" i18n-content="newest" hidden></a>
+      <a is="action-link" id="newer-button" i18n-content="newer" hidden></a>
+      <a is="action-link" id="older-button" i18n-content="older" hidden></a>
     </div>
   </div>
 </div>
diff --git a/chrome/browser/resources/history/history.js b/chrome/browser/resources/history/history.js
index 6c18a61a..58962c0 100644
--- a/chrome/browser/resources/history/history.js
+++ b/chrome/browser/resources/history/history.js
@@ -187,7 +187,7 @@
   var entryBox = createElementWithClassName('div', 'entry-box');
   var domain = createElementWithClassName('div', 'domain');
 
-  this.id_ = this.model_.nextVisitId_++;
+  this.id_ = this.model_.getNextVisitId();
   var self = this;
 
   // Only create the checkbox if it can be used either to delete an entry or to
@@ -196,9 +196,13 @@
     var checkbox = document.createElement('input');
     checkbox.type = 'checkbox';
     checkbox.id = 'checkbox-' + this.id_;
-    checkbox.setAttribute('aria-label',
-                          loadTimeData.getString('removeFromHistory'));
     checkbox.time = this.date.getTime();
+    checkbox.setAttribute('aria-label', loadTimeData.getStringF(
+        'entrySummary',
+        this.dateTimeOfDay,
+        this.starred_ ? loadTimeData.getString('bookmarked') : '',
+        this.title_,
+        this.domain_));
     checkbox.addEventListener('click', checkboxClicked);
     entryBox.appendChild(checkbox);
 
@@ -743,6 +747,14 @@
     this.visits_.splice(index, 1);
 };
 
+/**
+ * Automatically generates a new visit ID.
+ * @return {number} The next visit ID.
+ */
+HistoryModel.prototype.getNextVisitId = function() {
+  return this.nextVisitId_++;
+};
+
 // HistoryModel, Private: -----------------------------------------------------
 
 /**
@@ -1311,8 +1323,7 @@
   var siteDomain = siteDomainRow.appendChild(
       createElementWithClassName('div', 'site-domain'));
   var siteDomainLink = siteDomain.appendChild(
-      createElementWithClassName('button', 'link-button'));
-  siteDomainLink.addEventListener('click', function(e) { e.preventDefault(); });
+      document.createElement('a', 'action-link'));
   siteDomainLink.textContent = domain;
   var numberOfVisits = createElementWithClassName('span', 'number-visits');
   var domainElement = document.createElement('span');
@@ -1604,7 +1615,7 @@
   '.title a',
   '.drop-down',
   '.domain-checkbox',
-  '.link-button',
+  '[is="action-link"]',
 ].join(', ');
 
 /** @private */
diff --git a/chrome/browser/resources/history/other_devices.css b/chrome/browser/resources/history/other_devices.css
index 893522f0..2cbdf9a4 100644
--- a/chrome/browser/resources/history/other_devices.css
+++ b/chrome/browser/resources/history/other_devices.css
@@ -38,6 +38,11 @@
   white-space: nowrap;
 }
 
+.device-contents {
+  margin: 0;
+  padding: 0;
+}
+
 .device-tab-entry {
   -webkit-margin-end: 8px;
   -webkit-margin-start: 0;
diff --git a/chrome/browser/resources/history/other_devices.js b/chrome/browser/resources/history/other_devices.js
index 3043b21..398a0b5 100644
--- a/chrome/browser/resources/history/other_devices.js
+++ b/chrome/browser/resources/history/other_devices.js
@@ -189,6 +189,7 @@
   var dropDownButton = new cr.ui.ContextMenuButton;
   dropDownButton.tabIndex = 0;
   dropDownButton.classList.add('drop-down');
+  dropDownButton.title = loadTimeData.getString('actionMenuDescription');
   dropDownButton.addEventListener('mousedown', function(event) {
       handleDropDownFocus(event);
       // Mousedown handling of cr.ui.MenuButton.handleEvent calls
@@ -242,7 +243,7 @@
  * @private
  */
 Device.prototype.createSessionContents_ = function(maxNumTabs) {
-  var contents = createElementWithClassName('div', 'device-contents');
+  var contents = createElementWithClassName('ol', 'device-contents');
 
   var sessionTag = this.session_.tag;
   var numTabsShown = 0;
@@ -293,14 +294,12 @@
   }
 
   if (numTabsHidden > 0) {
-    var moreLinkButton = createElementWithClassName('button',
-        'device-show-more-tabs link-button');
-    moreLinkButton.addEventListener('click', this.view_.increaseRowHeight.bind(
+    var moreLink = document.createElement('a', 'action-link');
+    moreLink.classList.add('device-show-more-tabs');
+    moreLink.addEventListener('click', this.view_.increaseRowHeight.bind(
         this.view_, this.row_, numTabsHidden));
-    var xMore = loadTimeData.getString('xMore');
-    moreLinkButton.appendChild(
-        document.createTextNode(xMore.replace('$1', numTabsHidden)));
-    contents.appendChild(moreLinkButton);
+    moreLink.textContent = loadTimeData.getStringF('xMore', numTabsHidden);
+    contents.appendChild(moreLink);
   }
 
   return contents;
diff --git a/chrome/browser/resources/hotword/constants.js b/chrome/browser/resources/hotword/constants.js
index 15bb5faa..3339d63 100644
--- a/chrome/browser/resources/hotword/constants.js
+++ b/chrome/browser/resources/hotword/constants.js
@@ -125,6 +125,68 @@
 };
 
 /**
+ * MediaStream open success/errors to be reported via UMA.
+ * DO NOT remove or renumber values in this enum. Only add new ones.
+ * @enum {number}
+ */
+var UmaMediaStreamOpenResult = {
+  SUCCESS: 0,
+  UNKNOWN: 1,
+  NOT_SUPPORTED: 2,
+  PERMISSION_DENIED: 3,
+  CONSTRAINT_NOT_SATISFIED: 4,
+  OVERCONSTRAINED: 5,
+  NOT_FOUND: 6,
+  ABORT: 7,
+  SOURCE_UNAVAILABLE: 8,
+  PERMISSION_DISMISSED: 9,
+  INVALID_STATE: 10,
+  DEVICES_NOT_FOUND: 11,
+  INVALID_SECURITY_ORIGIN: 12,
+  MAX: 12
+};
+
+/**
+ * UMA metrics.
+ * DO NOT change these enum values.
+ * @enum {string}
+ */
+var UmaMetrics = {
+  TRIGGER: 'Hotword.HotwordTrigger',
+  MEDIA_STREAM_RESULT: 'Hotword.HotwordMediaStreamResult',
+  NACL_PLUGIN_LOAD_RESULT: 'Hotword.HotwordNaClPluginLoadResult',
+  NACL_MESSAGE_TIMEOUT: 'Hotword.HotwordNaClMessageTimeout'
+};
+
+/**
+ * Message waited for by NaCl plugin, to be reported via UMA.
+ * DO NOT remove or renumber values in this enum. Only add new ones.
+ * @enum {number}
+ */
+var UmaNaClMessageTimeout = {
+  REQUEST_MODEL: 0,
+  MODEL_LOADED: 1,
+  READY_FOR_AUDIO: 2,
+  STOPPED: 3,
+  HOTWORD_DETECTED: 4,
+  MS_CONFIGURED: 5,
+  MAX: 5
+};
+
+/**
+ * NaCl plugin load success/errors to be reported via UMA.
+ * DO NOT remove or renumber values in this enum. Only add new ones.
+ * @enum {number}
+ */
+var UmaNaClPluginLoadResult = {
+  SUCCESS: 0,
+  UNKNOWN: 1,
+  CRASH: 2,
+  NO_MODULE_FOUND: 3,
+  MAX: 3
+};
+
+/**
  * The browser UI language.
  * @const {string}
  */
@@ -144,7 +206,11 @@
   File: File,
   NaClPlugin: NaClPlugin,
   SessionSource: SessionSource,
-  TimeoutMs: TimeoutMs
+  TimeoutMs: TimeoutMs,
+  UmaMediaStreamOpenResult: UmaMediaStreamOpenResult,
+  UmaMetrics: UmaMetrics,
+  UmaNaClMessageTimeout: UmaNaClMessageTimeout,
+  UmaNaClPluginLoadResult: UmaNaClPluginLoadResult
 };
 
 });
diff --git a/chrome/browser/resources/hotword/manifest.json b/chrome/browser/resources/hotword/manifest.json
index 21372dc..871c96c4 100644
--- a/chrome/browser/resources/hotword/manifest.json
+++ b/chrome/browser/resources/hotword/manifest.json
@@ -13,6 +13,7 @@
       "chrome://resources/js/cr/event_target.js",
       "constants.js",
       "logging.js",
+      "metrics.js",
       "nacl_manager.js",
       "state_manager.js",
       "base_session_manager.js",
@@ -31,6 +32,7 @@
     "audioCapture",
     "hotwordPrivate",
     "management",
+    "metricsPrivate",
     "tabs"
   ],
 
diff --git a/chrome/browser/resources/hotword/metrics.js b/chrome/browser/resources/hotword/metrics.js
new file mode 100644
index 0000000..6adccb4a
--- /dev/null
+++ b/chrome/browser/resources/hotword/metrics.js
@@ -0,0 +1,28 @@
+// 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('hotword.metrics', function() {
+  'use strict';
+
+  /**
+   * Helper function to record enum values in UMA.
+   * @param {!string} name
+   * @param {!number} value
+   * @param {!number} maxValue
+   */
+  function recordEnum(name, value, maxValue) {
+    var metricDesc = {
+      'metricName': name,
+      'type': 'histogram-linear',
+      'min': 1,
+      'max': maxValue,
+      'buckets': maxValue + 1
+    };
+    chrome.metricsPrivate.recordValue(metricDesc, value);
+  }
+
+  return {
+    recordEnum: recordEnum
+  };
+});
diff --git a/chrome/browser/resources/hotword/nacl_manager.js b/chrome/browser/resources/hotword/nacl_manager.js
index fc0753f..db23ece0 100644
--- a/chrome/browser/resources/hotword/nacl_manager.js
+++ b/chrome/browser/resources/hotword/nacl_manager.js
@@ -77,6 +77,8 @@
 };
 var ManagerState_ = NaClManager.ManagerState_;
 var Error_ = hotword.constants.Error;
+var UmaNaClMessageTimeout_ = hotword.constants.UmaNaClMessageTimeout;
+var UmaNaClPluginLoadResult_ = hotword.constants.UmaNaClPluginLoadResult;
 
 NaClManager.prototype.__proto__ = cr.EventTarget.prototype;
 
@@ -92,6 +94,18 @@
 };
 
 /**
+ * Record the result of loading the NaCl plugin to UMA.
+ * @param {!hotword.constants.UmaNaClPluginLoadResult} error
+ * @private
+ */
+NaClManager.prototype.logPluginLoadResult_ = function(error) {
+  hotword.metrics.recordEnum(
+      hotword.constants.UmaMetrics.NACL_PLUGIN_LOAD_RESULT,
+      error,
+      UmaNaClPluginLoadResult_.MAX);
+};
+
+/**
  * @return {boolean} True if the recognizer is in a running state.
  */
 NaClManager.prototype.isRunning = function() {
@@ -250,11 +264,16 @@
                             false);
 
     plugin.addEventListener('crash',
-                            this.handleError_.bind(this, Error_.NACL_CRASH),
+                            function() {
+                              this.handleError_(Error_.NACL_CRASH);
+                              this.logPluginLoadResult_(
+                                  UmaNaClPluginLoadResult_.CRASH);
+                            }.bind(this),
                             false);
     return true;
   }
   this.recognizerState_ = ManagerState_.ERROR;
+  this.logPluginLoadResult_(UmaNaClPluginLoadResult_.NO_MODULE_FOUND);
   return false;
 };
 
@@ -297,6 +316,30 @@
       function() {
         this.recognizerState_ = ManagerState_.ERROR;
         this.handleError_(Error_.TIMEOUT);
+        switch (this.expectingMessage_) {
+          case hotword.constants.NaClPlugin.REQUEST_MODEL:
+            var metricValue = UmaNaClMessageTimeout_.REQUEST_MODEL;
+            break;
+          case hotword.constants.NaClPlugin.MODEL_LOADED:
+            var metricValue = UmaNaClMessageTimeout_.MODEL_LOADED;
+            break;
+          case hotword.constants.NaClPlugin.READY_FOR_AUDIO:
+            var metricValue = UmaNaClMessageTimeout_.READY_FOR_AUDIO;
+            break;
+          case hotword.constants.NaClPlugin.STOPPED:
+            var metricValue = UmaNaClMessageTimeout_.STOPPED;
+            break;
+          case hotword.constants.NaClPlugin.HOTWORD_DETECTED:
+            var metricValue = UmaNaClMessageTimeout_.HOTWORD_DETECTED;
+            break;
+          case hotword.constants.NaClPlugin.MS_CONFIGURED:
+            var metricValue = UmaNaClMessageTimeout_.MS_CONFIGURED;
+            break;
+        }
+        hotword.metrics.recordEnum(
+            hotword.constants.UmaMetrics.NACL_MESSAGE_TIMEOUT,
+            metricValue,
+            UmaNaClMessageTimeout_.MAX);
       }.bind(this), timeout);
   this.expectingMessage_ = message;
 };
@@ -323,6 +366,7 @@
   if (this.recognizerState_ != ManagerState_.LOADING) {
     return;
   }
+  this.logPluginLoadResult_(UmaNaClPluginLoadResult_.SUCCESS);
   this.sendDataToPlugin_(
       hotword.constants.NaClPlugin.MODEL_PREFIX + this.modelUrl_);
   this.waitForMessage_(hotword.constants.TimeoutMs.LONG,
diff --git a/chrome/browser/resources/hotword/state_manager.js b/chrome/browser/resources/hotword/state_manager.js
index 9b033da..67d4f41 100644
--- a/chrome/browser/resources/hotword/state_manager.js
+++ b/chrome/browser/resources/hotword/state_manager.js
@@ -102,6 +102,34 @@
   };
   var State_ = StateManager.State_;
 
+  var UmaMediaStreamOpenResults_ = {
+    // These first error are defined by the MediaStream spec:
+    // http://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-MediaStreamError
+    'NotSupportedError':
+        hotword.constants.UmaMediaStreamOpenResult.NOT_SUPPORTED,
+    'PermissionDeniedError':
+        hotword.constants.UmaMediaStreamOpenResult.PERMISSION_DENIED,
+    'ConstraintNotSatisfiedError':
+        hotword.constants.UmaMediaStreamOpenResult.CONSTRAINT_NOT_SATISFIED,
+    'OverconstrainedError':
+        hotword.constants.UmaMediaStreamOpenResult.OVERCONSTRAINED,
+    'NotFoundError': hotword.constants.UmaMediaStreamOpenResult.NOT_FOUND,
+    'AbortError': hotword.constants.UmaMediaStreamOpenResult.ABORT,
+    'SourceUnavailableError':
+        hotword.constants.UmaMediaStreamOpenResult.SOURCE_UNAVAILABLE,
+    // The next few errors are chrome-specific. See:
+    // content/renderer/media/user_media_client_impl.cc
+    // (UserMediaClientImpl::GetUserMediaRequestFailed)
+    'PermissionDismissedError':
+        hotword.constants.UmaMediaStreamOpenResult.PERMISSION_DISMISSED,
+    'InvalidStateError':
+        hotword.constants.UmaMediaStreamOpenResult.INVALID_STATE,
+    'DevicesNotFoundError':
+        hotword.constants.UmaMediaStreamOpenResult.DEVICES_NOT_FOUND,
+    'InvalidSecurityOriginError':
+        hotword.constants.UmaMediaStreamOpenResult.INVALID_SECURITY_ORIGIN
+  };
+
   StateManager.prototype = {
     /**
      * Request status details update. Intended to be called from the
@@ -199,12 +227,26 @@
           navigator.webkitGetUserMedia(
               /** @type {MediaStreamConstraints} */ (constraints),
               function(stream) {
+                hotword.metrics.recordEnum(
+                    hotword.constants.UmaMetrics.MEDIA_STREAM_RESULT,
+                    hotword.constants.UmaMediaStreamOpenResult.SUCCESS,
+                    hotword.constants.UmaMediaStreamOpenResult.MAX);
                 if (!this.pluginManager_.initialize(naclArch, stream)) {
                   this.state_ = State_.ERROR;
                   this.shutdownPluginManager_();
                 }
               }.bind(this),
               function(error) {
+                if (error.name in UmaMediaStreamOpenResults_) {
+                  var metricValue = UmaMediaStreamOpenResults_[error.name];
+                } else {
+                  var metricValue =
+                      hotword.constants.UmaMediaStreamOpenResult.UNKNOWN;
+                }
+                hotword.metrics.recordEnum(
+                    hotword.constants.UmaMetrics.MEDIA_STREAM_RESULT,
+                    metricValue,
+                    hotword.constants.UmaMediaStreamOpenResult.MAX);
                 this.state_ = State_.ERROR;
                 this.pluginManager_ = null;
               }.bind(this));
@@ -285,6 +327,8 @@
      */
     onTrigger_: function() {
       hotword.debug('Hotword triggered!');
+      chrome.metricsPrivate.recordUserAction(
+          hotword.constants.UmaMetrics.TRIGGER);
       assert(this.pluginManager_, 'No NaCl plugin loaded on trigger');
       // Detector implicitly stops when the hotword is detected.
       this.state_ = State_.STOPPED;
diff --git a/chrome/browser/resources/hotword_audio_verification/flow.js b/chrome/browser/resources/hotword_audio_verification/flow.js
index c8672df..635456a 100644
--- a/chrome/browser/resources/hotword_audio_verification/flow.js
+++ b/chrome/browser/resources/hotword_audio_verification/flow.js
@@ -21,7 +21,7 @@
     // TODO(kcarattini): Remove the first flow, since we will not be
     // managing the Audio History Setting in Chrome anymore.
     [AUDIO_HISTORY_START],
-    [HOTWORD_ONLY_START, SPEECH_TRAINING, FINISHED],
+    [HOTWORD_ONLY_START, FINISHED],
     [HOTWORD_AUDIO_HISTORY, SPEECH_TRAINING, FINISHED],
     [SPEECH_TRAINING, FINISHED]
   ];
diff --git a/chrome/browser/resources/hotword_audio_verification/main.html b/chrome/browser/resources/hotword_audio_verification/main.html
index f910711..ae20de2 100644
--- a/chrome/browser/resources/hotword_audio_verification/main.html
+++ b/chrome/browser/resources/hotword_audio_verification/main.html
@@ -4,6 +4,7 @@
     <meta charset=utf-8>
     <title></title>
     <link type="text/css" rel="stylesheet" href="style.css">
+    <script src="chrome://resources/js/action_link.js"></script>
     <script src="chrome://resources/js/util.js"></script>
     <script src="flow.js"></script>
     <script src="main.js"></script>
diff --git a/chrome/browser/resources/hotword_audio_verification/main.js b/chrome/browser/resources/hotword_audio_verification/main.js
index 46f8709..8c78ef4a 100644
--- a/chrome/browser/resources/hotword_audio_verification/main.js
+++ b/chrome/browser/resources/hotword_audio_verification/main.js
@@ -14,39 +14,49 @@
     var closeButton = closeButtons[i];
     closeButton.addEventListener('click', function(e) {
       appWindow.close();
-      e.stopPropagation();
+      e.preventDefault();
     });
   }
 
   $('ah-cancel-button').addEventListener('click', function(e) {
     appWindow.close();
-    e.stopPropagation();
+    e.preventDefault();
+  });
+
+  $('done-button').addEventListener('click', function(e) {
+    appWindow.close();
+    e.preventDefault();
+  });
+
+  $('ho-cancel-button').addEventListener('click', function(e) {
+    appWindow.close();
+    e.preventDefault();
   });
 
   $('hw-cancel-button').addEventListener('click', function(e) {
     appWindow.close();
-    e.stopPropagation();
+    e.preventDefault();
   });
 
   $('st-cancel-button').addEventListener('click', function(e) {
     appWindow.close();
-    e.stopPropagation();
+    e.preventDefault();
   });
 
   $('ah-agree-button').addEventListener('click', function(e) {
     // TODO(kcarattini): Set the Audio History setting.
     appWindow.close();
-    e.stopPropagation();
+    e.preventDefault();
   });
 
   $('hw-agree-button').addEventListener('click', function(e) {
     flow.advanceStep();
-    e.stopPropagation();
+    e.preventDefault();
   });
 
   // TODO(kcarattini): Remove this once speech training is implemented. The
   // way to get to the next page will be to complete the speech training.
-  $('training').addEventListener('click', function(e) {
+  $('st-training').addEventListener('click', function(e) {
     if (chrome.hotwordPrivate.setAudioLoggingEnabled)
       chrome.hotwordPrivate.setAudioLoggingEnabled(true, function() {});
 
@@ -54,12 +64,19 @@
       chrome.hotwordPrivate.setHotwordAlwaysOnSearchEnabled(true,
           flow.advanceStep.bind(flow));
     }
-    e.stopPropagation();
+    e.preventDefault();
   });
 
-  $('try-now-button').addEventListener('click', function(e) {
-    // TODO(kcarattini): Figure out what happens when you click this button.
-    appWindow.close();
-    e.stopPropagation();
+  // TODO(kcarattini): Remove this once speech training is implemented. The
+  // way to get to the next page will be to complete the speech training.
+  $('ho-training').addEventListener('click', function(e) {
+    if (chrome.hotwordPrivate.setAudioLoggingEnabled)
+      chrome.hotwordPrivate.setAudioLoggingEnabled(true, function() {});
+
+    if (chrome.hotwordPrivate.setHotwordAlwaysOnSearchEnabled) {
+      chrome.hotwordPrivate.setHotwordAlwaysOnSearchEnabled(true,
+          flow.advanceStep.bind(flow));
+    }
+    e.preventDefault();
   });
 });
diff --git a/chrome/browser/resources/hotword_audio_verification/steps/audio_history_step.html b/chrome/browser/resources/hotword_audio_verification/steps/audio_history_step.html
index 71965f4..8bf8b4e 100644
--- a/chrome/browser/resources/hotword_audio_verification/steps/audio_history_step.html
+++ b/chrome/browser/resources/hotword_audio_verification/steps/audio_history_step.html
@@ -15,7 +15,7 @@
         associated with your Google Account to help recognize your voice and
         improve speech recognition.
         <br>
-        <a href="#" class="link-button">LEARN MORE</a>
+        <a is="action-link">LEARN MORE</a>
       </div>
     </div>
     <div class="buttonbar">
diff --git a/chrome/browser/resources/hotword_audio_verification/steps/finished_step.html b/chrome/browser/resources/hotword_audio_verification/steps/finished_step.html
index 5091c3e..d750f66 100644
--- a/chrome/browser/resources/hotword_audio_verification/steps/finished_step.html
+++ b/chrome/browser/resources/hotword_audio_verification/steps/finished_step.html
@@ -27,7 +27,7 @@
       </div>
     </div>
     <div class="buttonbar">
-      <button id="try-now-button" class="primary">OK, TRY IT NOW</button>
+      <button id="done-button" class="primary">DONE</button>
     </div>
   </div>
 </div>
diff --git a/chrome/browser/resources/hotword_audio_verification/steps/hotword_audio_history_step.html b/chrome/browser/resources/hotword_audio_verification/steps/hotword_audio_history_step.html
index 01daaf2..aba6cf8 100644
--- a/chrome/browser/resources/hotword_audio_verification/steps/hotword_audio_history_step.html
+++ b/chrome/browser/resources/hotword_audio_verification/steps/hotword_audio_history_step.html
@@ -16,7 +16,7 @@
         associated with your Google Account to help recognize your voice and
         improve speech recognition.
         <br>
-        <a href="#" class="link-button">LEARN MORE</a>
+        <a is="action-link">LEARN MORE</a>
       </div>
     </div>
     <div class="buttonbar">
diff --git a/chrome/browser/resources/hotword_audio_verification/steps/hotword_only_step.html b/chrome/browser/resources/hotword_audio_verification/steps/hotword_only_step.html
index 8df25af..0889719 100644
--- a/chrome/browser/resources/hotword_audio_verification/steps/hotword_only_step.html
+++ b/chrome/browser/resources/hotword_audio_verification/steps/hotword_only_step.html
@@ -1,2 +1,40 @@
 <div id="hotword-only-container" hidden>
+  <div class="mic"></div>
+  <div class="container">
+    <div class="header">
+      <span class="close"></span>
+      <div class="header-text">
+        <h1>Voice search at any time</h1>
+        <h2>Say 'Ok Google' any time your screen is on</h2>
+      </div>
+    </div>
+    <div id="ho-training" class="content">
+      <h4>Let's train your Chromebook</h4>
+      <div class="col-2">
+        <br>
+        To help Google respond to you and for reliable and easy access to
+        voice search, you need to teach Google the sound of your voice.
+        <br>
+        <h4>Just say 'Ok Google' three times</h4>
+      </div>
+      <div class="col-spacing"></div>
+      <div class="col-2">
+        <div class="train listening">
+          <span class="icon"></span>
+          <span class="text">Say 'Ok Google'</span>
+        </div>
+        <div class="train not-started">
+          <span class="icon"></span>
+          <span class="text">Say 'Ok Google' again</span>
+        </div>
+        <div class="train not-started">
+          <span class="icon"></span>
+          <span class="text">Say 'Ok Google' one last time</span>
+        </div>
+      </div>
+    </div>
+    <div class="buttonbar">
+      <button id="ho-cancel-button">CANCEL</button>
+    </div>
+  </div>
 </div>
diff --git a/chrome/browser/resources/hotword_audio_verification/steps/speech_training_step.html b/chrome/browser/resources/hotword_audio_verification/steps/speech_training_step.html
index ba7e0c8b..a7c0871d 100644
--- a/chrome/browser/resources/hotword_audio_verification/steps/speech_training_step.html
+++ b/chrome/browser/resources/hotword_audio_verification/steps/speech_training_step.html
@@ -5,34 +5,34 @@
       <span class="close"></span>
       <div class="header-text">
         <div class="v-spacing-for-no-subheading"></div>
-          <h1>Let's train your Chromebook</h1>
+        <h1>Let's train your Chromebook</h1>
+      </div>
+    </div>
+    <div id="st-training" class="content">
+      <div class="col-2">
+        To help Google respond to you and for reliable and easy access to
+        voice search, you need to teach Google the sound of your voice.
+        <br>
+        <h4>Just say 'Ok Google' three times</h4>
+      </div>
+      <div class="col-spacing"></div>
+      <div class="col-2">
+        <div class="train listening">
+          <span class="icon"></span>
+          <span class="text">Say 'Ok Google'</span>
+        </div>
+        <div class="train not-started">
+          <span class="icon"></span>
+          <span class="text">Say 'Ok Google' again</span>
+        </div>
+        <div class="train not-started">
+          <span class="icon"></span>
+          <span class="text">Say 'Ok Google' one last time</span>
         </div>
       </div>
-      <div id="training" class="content">
-        <div class="col-2">
-          To help Google respond to you and for reliable and easy access to
-          voice search, you need to teach Google the sound of your voice.
-          <br>
-          <h4>Just say 'Ok Google' three times</h4>
-       </div>
-       <div class="col-spacing"></div>
-       <div class="col-2">
-         <div class="train listening">
-           <span class="icon"></span>
-           <span class="text">Say 'Ok Google'</span>
-         </div>
-         <div class="train not-started">
-           <span class="icon"></span>
-           <span class="text">Say 'Ok Google' again</span>
-         </div>
-         <div class="train not-started">
-           <span class="icon"></span>
-           <span class="text">Say 'Ok Google' one last time</span>
-         </div>
-       </div>
-     </div>
-     <div class="buttonbar">
-       <button id="st-cancel-button">FINISH LATER</button>
+    </div>
+    <div class="buttonbar">
+      <button id="st-cancel-button">CANCEL</button>
     </div>
   </div>
 </div>
diff --git a/chrome/browser/resources/hotword_audio_verification/style.css b/chrome/browser/resources/hotword_audio_verification/style.css
index 8825dd7..8d93da96 100644
--- a/chrome/browser/resources/hotword_audio_verification/style.css
+++ b/chrome/browser/resources/hotword_audio_verification/style.css
@@ -109,7 +109,7 @@
   width: 16px;
 }
 
-a.link-button {
+a[is='action-link'] {
   display: inline-block;
   font-size: 14px;
   margin-top: 22px;
diff --git a/chrome/browser/resources/inline_login/inline_login.html b/chrome/browser/resources/inline_login/inline_login.html
index 826780e1..71430c61e 100644
--- a/chrome/browser/resources/inline_login/inline_login.html
+++ b/chrome/browser/resources/inline_login/inline_login.html
@@ -8,6 +8,7 @@
   <script src="chrome://resources/js/cr/event_target.js"></script>
   <script src="chrome://resources/js/load_time_data.js"></script>
   <script src="chrome://resources/js/util.js"></script>
+  <script src="chrome://chrome-signin/gaia_auth_host.js"></script>
   <script src="chrome://chrome-signin/inline_login.js"></script>
   <script src="chrome://chrome-signin/strings.js"></script>
 </head>
diff --git a/chrome/browser/resources/inline_login/inline_login.js b/chrome/browser/resources/inline_login/inline_login.js
index 82ed092..fe41e0b 100644
--- a/chrome/browser/resources/inline_login/inline_login.js
+++ b/chrome/browser/resources/inline_login/inline_login.js
@@ -6,14 +6,12 @@
  * @fileoverview Inline login UI.
  */
 
-<include src="../gaia_auth_host/gaia_auth_host.js">
-
 cr.define('inline.login', function() {
   'use strict';
 
   /**
    * The auth extension host instance.
-   * @type {Object}
+   * @type {cr.login.GaiaAuthHost}
    */
   var authExtHost;
 
@@ -23,6 +21,34 @@
   var authReadyFired;
 
   /**
+   * A listener class for authentication events from GaiaAuthHost.
+   * @constructor
+   * @implements {cr.login.GaiaAuthHost.Listener}
+   */
+  function GaiaAuthHostListener() {}
+
+  /** @override */
+  GaiaAuthHostListener.prototype.onSuccess = function(credentials) {
+    onAuthCompleted(credentials);
+  };
+
+  /** @override */
+  GaiaAuthHostListener.prototype.onReady = function(e) {
+    onAuthReady();
+  };
+
+  /** @override */
+  GaiaAuthHostListener.prototype.onResize = function(url) {
+    chrome.send('switchToFullTab', url);
+  };
+
+  /** @override */
+  GaiaAuthHostListener.prototype.onNewWindow = function(e) {
+    window.open(e.targetUrl, '_blank');
+    e.window.discard();
+  };
+
+  /**
    * Handler of auth host 'ready' event.
    */
   function onAuthReady() {
@@ -43,7 +69,8 @@
    * Initialize the UI.
    */
   function initialize() {
-    authExtHost = new cr.login.GaiaAuthHost('signin-frame');
+    authExtHost = new cr.login.GaiaAuthHost(
+        'signin-frame', new GaiaAuthHostListener());
     authExtHost.addEventListener('ready', onAuthReady);
 
     chrome.send('initialize');
diff --git a/chrome/browser/resources/inline_login/new_inline_login.html b/chrome/browser/resources/inline_login/new_inline_login.html
new file mode 100644
index 0000000..68da6c2
--- /dev/null
+++ b/chrome/browser/resources/inline_login/new_inline_login.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html i18n-values="dir:textdirection">
+<head>
+  <title i18n-content="title"></title>
+  <link rel="stylesheet" href="chrome://resources/css/spinner.css">
+  <link rel="stylesheet" href="chrome://chrome-signin/inline_login.css">
+  <script src="chrome://resources/js/cr.js"></script>
+  <script src="chrome://resources/js/cr/event_target.js"></script>
+  <script src="chrome://resources/js/load_time_data.js"></script>
+  <script src="chrome://resources/js/util.js"></script>
+  <script src="chrome://chrome-signin/gaia_auth_host.js"></script>
+  <script src="chrome://chrome-signin/inline_login.js"></script>
+  <script src="chrome://chrome-signin/strings.js"></script>
+</head>
+<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
+  <div id="contents" class="loading">
+    <webview id="signin-frame" name="signin-frame"></webview>
+    <div id="spinner-container">
+      <div class="spinner"></div>
+    </div>
+  </div>
+  <script src="chrome://resources/js/i18n_template2.js"></script>
+</body>
+</html>
diff --git a/chrome/browser/resources/local_discovery/local_discovery.html b/chrome/browser/resources/local_discovery/local_discovery.html
index 68fc7b32..787e30df 100644
--- a/chrome/browser/resources/local_discovery/local_discovery.html
+++ b/chrome/browser/resources/local_discovery/local_discovery.html
@@ -8,6 +8,7 @@
   <link rel="stylesheet" href="chrome://resources/css/spinner.css">
   <link rel="stylesheet" href="local_discovery.css">
 
+  <script src="chrome://resources/js/action_link.js"></script>
   <script src="chrome://resources/js/cr.js"></script>
   <script src="chrome://resources/js/util.js"></script>
   <script src="chrome://resources/js/load_time_data.js"></script>
@@ -33,8 +34,8 @@
                    class="inline-login-promo"
                    hidden>
                 <span i18n-content="registerNeedLogin"></span>
-                <button class="link-button" id="register-overlay-login-button"
-                        i18n-content="cloudDevicesLogin"></button>
+                <a is="action-link" id="register-overlay-login-button"
+                    i18n-content="cloudDevicesLogin"></a>
               </div>
               <button class="register-cancel" i18n-content="cancel"></button>
               <button id="register-continue-button"
@@ -100,9 +101,9 @@
     </div>
 
     <header>
-      <button id="back-button" class="link-button" hidden>
+      <a is="action-link" id="back-button" hidden>
         <span i18n-content="backButton"></span>
-      </button>
+      </a>
       <h1 i18n-content="devicesTitle"></h1>
     </header>
 
@@ -112,8 +113,8 @@
       <div id="register-login-promo" class="login-promo cloud-print-message"
            hidden>
         <span i18n-content="registerNeedLogin"></span>
-        <button class="link-button" id="register-login-button"
-                i18n-content="cloudDevicesLogin"></button>
+        <a is="action-link" id="register-login-button"
+            i18n-content="cloudDevicesLogin"></a>
       </div>
       <div id="no-printers-message"
            class="cloud-print-message"
@@ -144,14 +145,14 @@
     <div id="cloud-devices-login-promo" class="login-promo cloud-print-message"
          hidden>
       <span i18n-content="cloudDevicesNeedLogin"></span>
-      <button class="link-button" id="cloud-devices-login-button"
-              i18n-content="cloudDevicesLogin"></button>
+      <a is="action-link" id="cloud-devices-login-button"
+          i18n-content="cloudDevicesLogin"></a>
     </div>
     <div id="cloud-devices-unavailable"
          class="cloud-print-message" hidden>
       <span i18n-content="cloudDevicesUnavailable"></span>
-      <button class="link-button" id="cloud-devices-retry-button"
-              i18n-content="retryLoadCloudDevices"></button>
+      <a is="action-link" id="cloud-devices-retry-button"
+          i18n-content="retryLoadCloudDevices"></a>
     </div>
     <div id="cloud-devices">
 
diff --git a/chrome/browser/resources/net_internals/import_view.html b/chrome/browser/resources/net_internals/import_view.html
index 91ab9fe55..cae43304 100644
--- a/chrome/browser/resources/net_internals/import_view.html
+++ b/chrome/browser/resources/net_internals/import_view.html
@@ -64,6 +64,12 @@
       <td><pre jscontent="constants.clientInfo.command_line"></pre></td>
     </tr>
     <tr>
+      <th>Active Field Trial Groups</th>
+      <td>
+        <span jsselect="constants.activeFieldTrialGroups" jscontent="$this + ' '"></span>
+      </td>
+    </tr>
+    <tr>
       <th>User comments</th>
       <td>
         <pre id=import-view-user-comments jscontent="userComments"
diff --git a/chrome/browser/resources/ntp4/new_tab.css b/chrome/browser/resources/ntp4/new_tab.css
index 8a01ac4..ca7caf50 100644
--- a/chrome/browser/resources/ntp4/new_tab.css
+++ b/chrome/browser/resources/ntp4/new_tab.css
@@ -105,7 +105,7 @@
           2x);
 }
 
-.link-button {
+[is='action-link'] {
   -webkit-margin-start: 0.5em;
 }
 
diff --git a/chrome/browser/resources/ntp4/new_tab.html b/chrome/browser/resources/ntp4/new_tab.html
index eeda187..bb8b82b 100644
--- a/chrome/browser/resources/ntp4/new_tab.html
+++ b/chrome/browser/resources/ntp4/new_tab.html
@@ -35,6 +35,7 @@
 <link rel="stylesheet" href="tile_page.css">
 <link id="themecss" rel="stylesheet">
 
+<script src="../../../../ui/webui/resources/js/action_link.js"></script>
 <script src="../../../../ui/webui/resources/js/event_tracker.js"></script>
 <script src="../../../../ui/webui/resources/js/parse_html_subset.js"></script>
 <script src="../../../../ui/webui/resources/js/util.js"></script>
@@ -162,8 +163,8 @@
   </div>
   <div class="login-status-row">
     <div id="login-status-advanced-container">
-      <a id="login-status-advanced"
-          i18n-content="login_status_advanced" href="#"></a>
+      <a is="action-link" id="login-status-advanced"
+          i18n-content="login_status_advanced"></a>
     </div>
     <button id="login-status-dismiss" i18n-content="login_status_dismiss">
     </button>
diff --git a/chrome/browser/resources/ntp4/new_tab.js b/chrome/browser/resources/ntp4/new_tab.js
index 50a58dc..020d1f8 100644
--- a/chrome/browser/resources/ntp4/new_tab.js
+++ b/chrome/browser/resources/ntp4/new_tab.js
@@ -299,7 +299,6 @@
       startTime = Date.now();
     });
 
-    preventDefaultOnPoundLinkClicks();  // From webui/js/util.js.
     cr.ui.FocusManager.disableMouseFocusOnButtons();
   }
 
@@ -463,16 +462,13 @@
     var linksBin = $('notificationLinks');
     linksBin.textContent = '';
     for (var i = 0; i < links.length; i++) {
-      var link = linksBin.ownerDocument.createElement('div');
+      var link = linksBin.ownerDocument.createElement('a', 'action-link');
       link.textContent = links[i].text;
       link.action = links[i].action;
       link.onclick = function() {
         this.action();
         hideNotification();
       };
-      link.setAttribute('role', 'button');
-      link.setAttribute('tabindex', 0);
-      link.className = 'link-button';
       linksBin.appendChild(link);
     }
 
diff --git a/chrome/browser/resources/ntp4/new_tab_theme.css b/chrome/browser/resources/ntp4/new_tab_theme.css
index adfeeb7..888eebd 100644
--- a/chrome/browser/resources/ntp4/new_tab_theme.css
+++ b/chrome/browser/resources/ntp4/new_tab_theme.css
@@ -25,12 +25,12 @@
 }
 
 #attribution,
-.link-button,
+[is='action-link'],
 .link-span {
   color: $21;  /* COLOR_NTP_TEXT_LIGHT */
 }
 
-.link-button:active {
+[is='action-link']:active {
   color: $8;  /* COLOR_NTP_TEXT */
 }
 
diff --git a/chrome/browser/resources/options/browser_options.css b/chrome/browser/resources/options/browser_options.css
index cb10c46..a5c2538 100644
--- a/chrome/browser/resources/options/browser_options.css
+++ b/chrome/browser/resources/options/browser_options.css
@@ -135,7 +135,7 @@
   padding: 10px;
 }
 
-.sync-error .link-button {
+.sync-error [is='action-link'] {
   margin: 0 1ex;
   padding: 0;
 }
@@ -474,7 +474,7 @@
 }
 
 #about-button {
-  margin-right: 30px;
+  -webkit-margin-end: 30px;
 }
 
 /* An input that has no function except to take up the same amount of space as
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index ff50358..8d9e42d 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -73,8 +73,8 @@
         <span id="home-page-ntp" class="home-page-label"
             i18n-content="homePageNtp"></span>
         <span id="home-page-url" class="home-page-label"></span>
-        <button id="change-home-page" class="link-button"
-            i18n-content="changeHomePage"></button>
+        <a is="action-link" id="change-home-page" i18n-content="changeHomePage">
+        </a>
         <div id="extension-controlled-container"></div>
       </div>
     </div>
@@ -394,8 +394,8 @@
         </label>
         <span id="metrics-reporting-reset-restart">
           <!-- Text filled by JavaScript -->
-          <span></span><button class=
-              "link-button standalone-link-button"></button><span></span>
+          <span></span><a is="action-link"
+              class="standalone-action-link"></a><span></span>
         </span>
 </if>
       </div>
@@ -479,9 +479,8 @@
           </span>
         </span>
       </label>
-      <button id="autofill-settings" class="link-button"
-          i18n-content="manageAutofillSettings">
-      </button>
+      <a is="action-link" id="autofill-settings"
+          i18n-content="manageAutofillSettings"></a>
     </div>
     <div class="checkbox controlled-setting-with-label">
       <label>
@@ -494,8 +493,8 @@
               pref="profile.password_manager_enabled"></span>
         </span>
       </label>
-      <button id="manage-passwords" class="link-button"
-          i18n-content="managePasswords"></button>
+      <a is="action-link" id="manage-passwords" i18n-content="managePasswords">
+      </a>
     </div>
 <if expr="is_macosx">
     <div id="mac-passwords-warning" i18n-content="macPasswordsWarning" hidden>
@@ -603,8 +602,8 @@
           </span>
         </span>
       </label>
-      <button id="manage-languages" class="link-button"
-          i18n-content="manageLanguages"></button>
+      <a is="action-link" id="manage-languages" i18n-content="manageLanguages">
+      </a>
     </div>
   </section>
   <section id="downloads-section">
@@ -929,8 +928,7 @@
   </div>  <!-- advanced-settings-container -->
   </div>  <!-- advanced-settings -->
   <footer>
-    <button id="advanced-settings-expander" class="link-button"
-        i18n-content="showAdvancedSettings">
-    </button>
+    <a is="action-link" id="advanced-settings-expander"
+        i18n-content="showAdvancedSettings"></a>
   </footer>
 </div>
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.js b/chrome/browser/resources/options/chromeos/internet_detail.js
index fbbbb35..2ca8f59 100644
--- a/chrome/browser/resources/options/chromeos/internet_detail.js
+++ b/chrome/browser/resources/options/chromeos/internet_detail.js
@@ -1377,7 +1377,10 @@
       else if (staticNameServersString == inetNameServersString)
         nameServerType = 'user';
     }
-    $('automatic-dns-display').textContent = inetNameServersString;
+    if (nameServerType == 'automatic')
+      $('automatic-dns-display').textContent = inetNameServersString;
+    else
+      $('automatic-dns-display').textContent = savedNameServersString;
     $('google-dns-display').textContent = GoogleNameServersString;
 
     var nameServersUser = [];
diff --git a/chrome/browser/resources/options/chromeos/keyboard_overlay.html b/chrome/browser/resources/options/chromeos/keyboard_overlay.html
index 7332a2c7..039c2aa 100644
--- a/chrome/browser/resources/options/chromeos/keyboard_overlay.html
+++ b/chrome/browser/resources/options/chromeos/keyboard_overlay.html
@@ -118,10 +118,10 @@
           </div>
       </div>
     </div>
-    <button id="keyboard-shortcuts" class="settings-row link-button"
-        i18n-content="showKeyboardShortcuts"></button>
-    <button id="languages-and-input-settings" class="settings-row link-button"
-        i18n-content="changeLanguageAndInputSettings"></button>
+    <a is="action-link" id="keyboard-shortcuts" class="settings-row"
+        i18n-content="showKeyboardShortcuts"></a>
+    <a is="action-link" id="languages-and-input-settings" class="settings-row"
+        i18n-content="changeLanguageAndInputSettings"></a>
   </div>
   <div class="action-area">
     <div class="button-strip">
diff --git a/chrome/browser/resources/options/chromeos/network_list.js b/chrome/browser/resources/options/chromeos/network_list.js
index 70cc49c..90b1d17 100644
--- a/chrome/browser/resources/options/chromeos/network_list.js
+++ b/chrome/browser/resources/options/chromeos/network_list.js
@@ -511,7 +511,14 @@
           };
         }
         addendum.push(entry);
+      } else if (this.data_.key == 'VPN') {
+        addendum.push({
+          label: loadTimeData.getString('joinOtherNetwork'),
+          command: createAddConnectionCallback_('VPN'),
+          data: {}
+        });
       }
+
       var list = this.data.rememberedNetworks;
       if (list && list.length > 0) {
         var callback = function(list) {
@@ -531,24 +538,29 @@
       list = this.data.networkList;
       var empty = !list || list.length == 0;
       if (list) {
+        var connectedVpnServicePath = '';
         for (var i = 0; i < list.length; i++) {
           var data = list[i];
           this.createNetworkOptionsCallback_(networkGroup, data);
-          if (data.ConnectionState == 'Connected') {
-            if (data.Type == 'VPN') {
-              var disconnectCallback = function() {
-                sendChromeMetricsAction('Options_NetworkDisconnectVPN');
-                // TODO(stevenjb): chrome.networkingPrivate.startDisconnect
-                chrome.send('startDisconnect', [data.servicePath]);
-              };
-              // Add separator
-              addendum.push({});
-              addendum.push({label: loadTimeData.getString('disconnectNetwork'),
-                             command: disconnectCallback,
-                             data: data});
-            }
+          // For VPN only, append a 'Disconnect' item to the dropdown menu.
+          if (!connectedVpnServicePath && data.Type == 'VPN' &&
+              (data.ConnectionState == 'Connected' ||
+               data.ConnectionState == 'Connecting')) {
+            connectedVpnServicePath = data.servicePath;
           }
         }
+        if (connectedVpnServicePath) {
+          var disconnectCallback = function() {
+            sendChromeMetricsAction('Options_NetworkDisconnectVPN');
+            // TODO(stevenjb): chrome.networkingPrivate.startDisconnect
+            chrome.send('startDisconnect', [connectedVpnServicePath]);
+          };
+          // Add separator
+          addendum.push({});
+          addendum.push({label: loadTimeData.getString('disconnectNetwork'),
+                         command: disconnectCallback,
+                         data: data});
+        }
       }
       if (this.data_.key == 'WiFi' || this.data_.key == 'WiMAX' ||
           this.data_.key == 'Cellular') {
diff --git a/chrome/browser/resources/options/clear_browser_data_overlay.js b/chrome/browser/resources/options/clear_browser_data_overlay.js
index 4684943b..b3886bd0 100644
--- a/chrome/browser/resources/options/clear_browser_data_overlay.js
+++ b/chrome/browser/resources/options/clear_browser_data_overlay.js
@@ -108,22 +108,21 @@
           loadTimeData.getString('contentSettingsAndSearchEnginesRemain')
                       .split(/([|#])/);
       for (var i = 0; i < footerFragments.length;) {
-        var buttonId = '';
+        var linkId = '';
         if (i + 2 < footerFragments.length) {
           if (footerFragments[i] == '|' && footerFragments[i + 2] == '|') {
-            buttonId = 'open-content-settings-from-clear-browsing-data';
+            linkId = 'open-content-settings-from-clear-browsing-data';
           } else if (footerFragments[i] == '#' &&
                      footerFragments[i + 2] == '#') {
-            buttonId = 'open-search-engines-from-clear-browsing-data';
+            linkId = 'open-search-engines-from-clear-browsing-data';
           }
         }
 
-        if (buttonId != '') {
-          var button = document.createElement('button');
-          button.id = buttonId;
-          button.className = 'link-button';
-          button.textContent = footerFragments[i + 1];
-          footer.appendChild(button);
+        if (linkId) {
+          var link = document.createElement('a', 'action-link');
+          link.id = linkId;
+          link.textContent = footerFragments[i + 1];
+          footer.appendChild(link);
           i += 3;
         } else {
           var span = document.createElement('span');
diff --git a/chrome/browser/resources/options/controlled_setting.js b/chrome/browser/resources/options/controlled_setting.js
index 652af1061..96a023ee 100644
--- a/chrome/browser/resources/options/controlled_setting.js
+++ b/chrome/browser/resources/options/controlled_setting.js
@@ -145,8 +145,7 @@
         if (this.controlledBy == 'hasRecommendation' && this.resetHandler_ &&
             !this.readOnly) {
           var container = document.createElement('div');
-          var action = document.createElement('button');
-          action.classList.add('link-button');
+          var action = document.createElement('a', 'action-link');
           action.classList.add('controlled-setting-bubble-action');
           action.textContent =
               loadTimeData.getString('controlledSettingFollowRecommendation');
diff --git a/chrome/browser/resources/options/font_settings.html b/chrome/browser/resources/options/font_settings.html
index da310601..b35cb25 100644
--- a/chrome/browser/resources/options/font_settings.html
+++ b/chrome/browser/resources/options/font_settings.html
@@ -102,8 +102,8 @@
     <div class="button-strip">
       <span id="advanced-font-settings-install" hidden
           i18n-values=".innerHTML:advancedFontSettingsInstall"></span>
-      <a id="advanced-font-settings-options" href="#" hidden
-          i18n-content="advancedFontSettingsOptions"></a>
+      <a is="action-link" id="advanced-font-settings-options"
+          i18n-content="advancedFontSettingsOptions" hidden></a>
       <span class="spacer"></span>
       <button id="font-settings-confirm" class="default-button"
           i18n-content="done">
diff --git a/chrome/browser/resources/options/inline_editable_list.js b/chrome/browser/resources/options/inline_editable_list.js
index 89d10e7..de5b5b4 100644
--- a/chrome/browser/resources/options/inline_editable_list.js
+++ b/chrome/browser/resources/options/inline_editable_list.js
@@ -428,6 +428,7 @@
       this.setAttribute('inlineeditable', '');
       this.addEventListener('hasElementFocusChange',
                             this.handleListFocusChange_);
+      this.removeAttribute('tabindex');
     },
 
     /**
diff --git a/chrome/browser/resources/options/language_options.css b/chrome/browser/resources/options/language_options.css
index 2a802a8..732f928 100644
--- a/chrome/browser/resources/options/language_options.css
+++ b/chrome/browser/resources/options/language_options.css
@@ -190,7 +190,3 @@
 #add-language-overlay-language-list {
   width: -webkit-calc(100% - 4px);
 }
-
-.standalone-link-button {
-  padding: 0;
-}
diff --git a/chrome/browser/resources/options/language_options.html b/chrome/browser/resources/options/language_options.html
index 456b32ea..eebd29d3 100644
--- a/chrome/browser/resources/options/language_options.html
+++ b/chrome/browser/resources/options/language_options.html
@@ -106,9 +106,9 @@
 <if expr="chromeos">
       <div i18n-content="switchInputMethodsHint"></div>
       <div i18n-content="selectPreviousInputMethodHint"></div>
-      <button id="edit-dictionary-button"
-          class="link-button standalone-link-button"
-          i18n-content="languageDictionaryOverlayTitle"></button>
+      <a is="action-link" id="edit-dictionary-button"
+          class="standalone-action-link"
+          i18n-content="languageDictionaryOverlayTitle"></a>
 </if>
 <if expr="not chromeos and not is_macosx">
       <div id="spell-check-option" class="checkbox">
@@ -117,8 +117,8 @@
               metric="Options_SpellCheck" type="checkbox">
           <span i18n-content="enableSpellCheck"></span>
         </label>
-        <button id="edit-dictionary-button" class="link-button"
-            i18n-content="languageDictionaryOverlayTitle" hidden></button>
+        <a is="action-link" id="edit-dictionary-button"
+            i18n-content="languageDictionaryOverlayTitle" hidden></a>
       </div>
       <div id="auto-spell-correction-option" class="checkbox" hidden>
         <label>
diff --git a/chrome/browser/resources/options/manage_profile_overlay.html b/chrome/browser/resources/options/manage_profile_overlay.html
index b6c5340..d922da0 100644
--- a/chrome/browser/resources/options/manage_profile_overlay.html
+++ b/chrome/browser/resources/options/manage_profile_overlay.html
@@ -103,13 +103,12 @@
             <span id="create-profile-supervised-account-details-out-of-date-label"
                 hidden>
             </span>
-            <button id="create-profile-supervised-signed-in-learn-more-link"
-                class="link-button" i18n-content="learnMore">
-            </button>
-            <button id="create-profile-supervised-sign-in-again-link"
-                class="link-button"
-                i18n-content="manageProfilesSupervisedSignInAgainLink" hidden>
-            </button>
+            <a id="create-profile-supervised-signed-in-learn-more-link"
+                is="action-link" i18n-content="learnMore"></a>
+            <a id="create-profile-supervised-sign-in-again-link"
+                is="action-link"
+                i18n-content="manageProfilesSupervisedSignInAgainLink"
+                hidden></a>
           </span>
           <span id="create-profile-supervised-not-signed-in"
               i18n-values=".innerHTML:manageProfilesSupervisedNotSignedIn"
@@ -124,9 +123,8 @@
     </div>
     <div class="action-area">
       <div id="create-profile-throbber" class="throbber"></div>
-      <button id="import-existing-supervised-user-link" class="link-button"
-          i18n-content="importExistingSupervisedUserLink" hidden>
-      </button>
+      <a is="action-link" id="import-existing-supervised-user-link"
+          i18n-content="importExistingSupervisedUserLink" hidden></a>
       <div class="button-strip">
         <button id="create-profile-cancel" i18n-content="cancel"></button>
         <button id="create-profile-ok" i18n-content="createProfileConfirm"
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html
index 356ae99..6bbbcd21 100644
--- a/chrome/browser/resources/options/options.html
+++ b/chrome/browser/resources/options/options.html
@@ -73,6 +73,7 @@
 <link rel="stylesheet" href="options_settings_app.css">
 </if>
 <script src="chrome://resources/css/tree.css.js"></script>
+<script src="chrome://resources/js/action_link.js"></script>
 <script src="chrome://resources/js/cr.js"></script>
 <script src="chrome://resources/js/event_tracker.js"></script>
 <script src="chrome://resources/js/cr/event_target.js"></script>
@@ -179,8 +180,8 @@
     <div class="controlled-setting-bubble-extension-name"></div>
   </div>
   <div class="controlled-setting-bubble-content-row">
-    <button class="controlled-setting-bubble-extension-manage-link link-button"
-        i18n-content="controlledSettingManageExtension"></button>
+    <a is="action-link" class="controlled-setting-bubble-extension-manage-link"
+        i18n-content="controlledSettingManageExtension"></a>
     <button class='controlled-setting-bubble-extension-disable-button'
         i18n-content="controlledSettingDisableExtension"></button>
   </div>
diff --git a/chrome/browser/resources/options/options_page.css b/chrome/browser/resources/options/options_page.css
index 2c997c6..e122a1b 100644
--- a/chrome/browser/resources/options/options_page.css
+++ b/chrome/browser/resources/options/options_page.css
@@ -443,3 +443,7 @@
 html:not([enablePepperFlashSettings]) .pepper-flash-settings {
   display: none;
 }
+
+.standalone-action-link {
+  padding: 0;
+}
diff --git a/chrome/browser/resources/options/search_box.html b/chrome/browser/resources/options/search_box.html
index 226134bc..d723885 100644
--- a/chrome/browser/resources/options/search_box.html
+++ b/chrome/browser/resources/options/search_box.html
@@ -2,9 +2,8 @@
   <header >
     <span id="browser-options-search-field-container"
         class="search-field-container">
-      <button id="about-button" class="link-button" hidden
-          i18n-content="aboutButton">
-      </button>
+      <a is="action-link" id="about-button" i18n-content="aboutButton"
+          hidden></a>
       <input id="search-field" type="search"
           i18n-values="placeholder:searchPlaceholder;
                        aria-label:searchPlaceholder" incremental>
diff --git a/chrome/browser/resources/options/search_engine_manager_engine_list.js b/chrome/browser/resources/options/search_engine_manager_engine_list.js
index 4fe3651..2076f26 100644
--- a/chrome/browser/resources/options/search_engine_manager_engine_list.js
+++ b/chrome/browser/resources/options/search_engine_manager_engine_list.js
@@ -111,6 +111,7 @@
         this.classList.add('default');
 
       this.deletable = engine.canBeRemoved;
+      this.closeButtonElement.tabIndex = 0;
 
       // Construct the name column.
       var nameColEl = this.ownerDocument.createElement('div');
diff --git a/chrome/browser/resources/options/startup_section.html b/chrome/browser/resources/options/startup_section.html
index fd14dabd..0d429a8 100644
--- a/chrome/browser/resources/options/startup_section.html
+++ b/chrome/browser/resources/options/startup_section.html
@@ -37,12 +37,10 @@
               pref="session.restore_on_startup" value="4"></span>
         </span>
       </label>
-      <button id="startup-set-pages" class="link-button"
-          i18n-content="startupSetPages">
-      </button>
+      <a is="action-link" id="startup-set-pages"
+          i18n-content="startupSetPages"></a>
       <span class="controlled-setting-indicator"
-          pref="session.startup_urls">
-      </span>
+          pref="session.startup_urls"></span>
     </div>
   </div>
 </section>
diff --git a/chrome/browser/resources/options/sync_section.html b/chrome/browser/resources/options/sync_section.html
index 83fbc8e6..8f85388 100644
--- a/chrome/browser/resources/options/sync_section.html
+++ b/chrome/browser/resources/options/sync_section.html
@@ -27,7 +27,7 @@
 
     <div id="sync-status" class="settings-row" hidden>
       <span id="sync-status-text"></span>
-      <button id="sync-action-link" class="link-button"></button>
+      <a is="action-link" id="sync-action-link"></a>
     </div>
 
 <if expr="chromeos">
diff --git a/chrome/browser/resources/policy.html b/chrome/browser/resources/policy.html
index 04161518..0aff4e6 100644
--- a/chrome/browser/resources/policy.html
+++ b/chrome/browser/resources/policy.html
@@ -9,6 +9,7 @@
 <link rel="stylesheet" href="uber/uber_shared.css">
 <link rel="stylesheet" href="chrome://policy/policy.css">
 
+<script src="chrome://resources/js/action_link.js"></script>
 <script src="chrome://resources/js/cr.js"></script>
 <script src="chrome://resources/js/cr/ui.js"></script>
 <script src="chrome://resources/js/cr/ui/focus_outline_manager.js"></script>
@@ -93,7 +94,7 @@
           <td class="value-column">
             <div class="value-container">
               <span class="value"></span>
-              <button class="toggle-expanded-value link-button"></button>
+              <a is="action-link" class="toggle-expanded-value"></a>
             </div>
           </td>
           <td class="status-column">
diff --git a/chrome/browser/resources/print_preview/native_layer.js b/chrome/browser/resources/print_preview/native_layer.js
index 7fc53fa..5e87d9a 100644
--- a/chrome/browser/resources/print_preview/native_layer.js
+++ b/chrome/browser/resources/print_preview/native_layer.js
@@ -244,8 +244,8 @@
         // preview, they still need to be included.
         'duplex': printTicketStore.duplex.getValue() ?
             NativeLayer.DuplexMode.LONG_EDGE : NativeLayer.DuplexMode.SIMPLEX,
-        'copies': printTicketStore.copies.getValueAsNumber(),
-        'collate': printTicketStore.collate.getValue(),
+        'copies': 1,
+        'collate': true,
         'shouldPrintBackgrounds': printTicketStore.cssBackground.getValue(),
         'shouldPrintSelectionOnly': printTicketStore.selectionOnly.getValue()
       };
diff --git a/chrome/browser/resources/print_preview/print_preview.css b/chrome/browser/resources/print_preview/print_preview.css
index b96d4b4d..97edf38 100644
--- a/chrome/browser/resources/print_preview/print_preview.css
+++ b/chrome/browser/resources/print_preview/print_preview.css
@@ -316,11 +316,11 @@
 html:not(.focus-outline-visible)
 :enabled:focus:-webkit-any(input[type='checkbox'],
                            input[type='radio'],
-                           button):not(.link-button) {
+                           button) {
   /* Cancel border-color for :focus specified in widgets.css. */
   border-color: rgba(0,0,0,0.25);
 }
 
-html:not(.focus-outline-visible) button:focus.link-button {
+html:not(.focus-outline-visible) [is='action-link']:focus {
   outline: none;
 }
diff --git a/chrome/browser/resources/print_preview/print_preview.html b/chrome/browser/resources/print_preview/print_preview.html
index ca2ad402..a3d9e0c 100644
--- a/chrome/browser/resources/print_preview/print_preview.html
+++ b/chrome/browser/resources/print_preview/print_preview.html
@@ -35,6 +35,7 @@
   <link rel="stylesheet" href="search/destination_search.css">
   <link rel="stylesheet" href="search/fedex_tos.css">
 
+  <script src="chrome://resources/js/action_link.js"></script>
   <script src="chrome://resources/js/cr.js"></script>
   <script src="chrome://resources/js/cr/event_target.js"></script>
   <script src="chrome://resources/js/cr/ui.js"></script>
@@ -68,20 +69,20 @@
       </div>
       <div id="link-container">
         <div>
-          <button id="system-dialog-link" class="link-button navbar-link"
-              i18n-content="systemDialogOption"></button>
+          <a is="action-link" id="system-dialog-link" class="navbar-link"
+              i18n-content="systemDialogOption"></a>
           <div id="system-dialog-throbber" hidden class="throbber"></div>
         </div>
 <if expr="is_macosx">
         <div>
-          <button id="open-pdf-in-preview-link" class="link-button navbar-link"
-              i18n-content="openPdfInPreviewOption"></button>
+          <a is="action-link" id="open-pdf-in-preview-link" class="navbar-link"
+              i18n-content="openPdfInPreviewOption"></a>
           <div id="open-preview-app-throbber" hidden class="throbber"></div>
         </div>
 </if>
         <div>
-          <button id="cloud-print-dialog-link" class="link-button navbar-link"
-              hidden i18n-content="cloudPrintDialogOption"></button>
+          <a is="action-link" id="cloud-print-dialog-link" class="navbar-link"
+              hidden i18n-content="cloudPrintDialogOption"></a>
           <div id="cloud-print-dialog-throbber" hidden class="throbber"></div>
         </div>
       </div>
diff --git a/chrome/browser/resources/print_preview/search/destination_list.html b/chrome/browser/resources/print_preview/search/destination_list.html
index 9fc948b..fe4bd81 100644
--- a/chrome/browser/resources/print_preview/search/destination_list.html
+++ b/chrome/browser/resources/print_preview/search/destination_list.html
@@ -1,7 +1,7 @@
 <div id="destination-list-template" class="destination-list" hidden>
   <header>
     <h4 class="title"></h4>
-    <button class="action-link link-button" hidden></button>
+    <a is="action-link" class="action-link" hidden></a>
     <div class="throbber-container">
       <div class="throbber"></div>
     </div>
diff --git a/chrome/browser/resources/print_preview/search/destination_search.css b/chrome/browser/resources/print_preview/search/destination_search.css
index 87de0e1..5d014d2c 100644
--- a/chrome/browser/resources/print_preview/search/destination_search.css
+++ b/chrome/browser/resources/print_preview/search/destination_search.css
@@ -107,7 +107,7 @@
   padding: 12px;
 }
 
-#destination-search .cloudprint-promo .sign-in.link-button {
+#destination-search .cloudprint-promo .sign-in[is='action-link'] {
   padding: inherit;
 }
 
diff --git a/chrome/browser/resources/print_preview/search/destination_search.js b/chrome/browser/resources/print_preview/search/destination_search.js
index 9baa926..c16f7e2 100644
--- a/chrome/browser/resources/print_preview/search/destination_search.js
+++ b/chrome/browser/resources/print_preview/search/destination_search.js
@@ -280,8 +280,8 @@
       this.cloudList_.render(this.getChildElement('.cloud-list'));
       this.getChildElement('.promo-text').innerHTML = loadTimeData.getStringF(
           'cloudPrintPromotion',
-          '<span class="sign-in link-button">',
-          '</span>');
+          '<a is="action-link" class="sign-in">',
+          '</a>');
       this.getChildElement('.account-select-label').textContent =
           loadTimeData.getString('accountSelectTitle');
     },
diff --git a/chrome/browser/resources/print_preview/settings/more_settings.html b/chrome/browser/resources/print_preview/settings/more_settings.html
index 6af9823..fdcf5509 100644
--- a/chrome/browser/resources/print_preview/settings/more_settings.html
+++ b/chrome/browser/resources/print_preview/settings/more_settings.html
@@ -1,4 +1,4 @@
 <div id="more-settings" class="more-settings collapsible" hidden>
   <div class="more-settings-icon more-settings-icon-plus"></div>
-  <button class="link-button more-settings-label"></button>
+  <a is="action-link" class="more-settings-label"></a>
 </div>
diff --git a/chrome/browser/resources/security_warnings/images/1x/clock.png b/chrome/browser/resources/security_warnings/images/1x/clock.png
new file mode 100644
index 0000000..98e2ed36
--- /dev/null
+++ b/chrome/browser/resources/security_warnings/images/1x/clock.png
Binary files differ
diff --git a/chrome/browser/resources/security_warnings/images/2x/clock.png b/chrome/browser/resources/security_warnings/images/2x/clock.png
new file mode 100644
index 0000000..6d11c7f8
--- /dev/null
+++ b/chrome/browser/resources/security_warnings/images/2x/clock.png
Binary files differ
diff --git a/chrome/browser/resources/supervised_user_block_interstitial.css b/chrome/browser/resources/supervised_user_block_interstitial.css
index 86ff2af..1e9998e3 100644
--- a/chrome/browser/resources/supervised_user_block_interstitial.css
+++ b/chrome/browser/resources/supervised_user_block_interstitial.css
@@ -36,7 +36,7 @@
   text-decoration: none;
 }
 
-.error-img {
+#error-img {
   /* Can't access chrome:// urls from an untrusted renderer process, so embed
    * the resource manually. */
   -webkit-user-select: none;
@@ -47,7 +47,7 @@
   margin-top: 10px;
 }
 
-.avatar-container {
+#avatar-container {
   position: relative;
 }
 
@@ -87,6 +87,19 @@
 }
 
 @media (max-width: 375px) {
+  #button-container {
+    display: flex;
+    flex-flow: column;
+  }
+
+  #back-button {
+    order: 2;
+  }
+
+  #request-access-button {
+    order: 1;
+  }
+
   button {
     width: 100%;
   }
diff --git a/chrome/browser/resources/supervised_user_block_interstitial.html b/chrome/browser/resources/supervised_user_block_interstitial.html
index d1824fdd..e04fccc7 100644
--- a/chrome/browser/resources/supervised_user_block_interstitial.html
+++ b/chrome/browser/resources/supervised_user_block_interstitial.html
@@ -14,8 +14,8 @@
 <div id="main-frame-blocked">
  <div id="box">
   <div id="content-top">
-    <img id="error-img" class="error-img">
-    <div id="avatar-container" class="avatar-container">
+    <img id="error-img">
+    <div id="avatar-container">
       <img id="avatar-img" class="avatar-img" hidden>
       <img id="second-avatar-img" class="avatar-img" hidden>
     </div>
@@ -25,9 +25,11 @@
      </div>
     </h1>
 
-    <button id="back-button" i18n-content="backButton"></button>
-    <button id="request-access-button" i18n-content="requestAccessButton">
-    </button>
+    <div id="button-container">
+      <button id="back-button" i18n-content="backButton"></button>
+      <button id="request-access-button" i18n-content="requestAccessButton">
+      </button>
+    </div>
   </div>
 
 </div>
diff --git a/chrome/browser/resources/sync_setup_overlay.html b/chrome/browser/resources/sync_setup_overlay.html
index 8ece57d1..9e76025e 100644
--- a/chrome/browser/resources/sync_setup_overlay.html
+++ b/chrome/browser/resources/sync_setup_overlay.html
@@ -12,10 +12,8 @@
       <div>
         <div class="action-area">
           <div class="action-area-link-container">
-            <button id="customize-link" type="button"
-                i18n-content="customizeLinkLabel"
-                class="link-button">
-            </button>
+            <a is="action-link" id="customize-link"
+                i18n-content="customizeLinkLabel"></a>
           </div>
           <div id="confirm-everything-throbber" class="throbber"></div>
           <div class="button-strip">
@@ -186,10 +184,8 @@
         </div>
         <div class="action-area">
           <div class="action-area-link-container">
-            <button id="use-default-link" type="button"
-                i18n-content="useDefaultSettings"
-                class="link-button">
-            </button>
+            <a is="action-link" id="use-default-link"
+                i18n-content="useDefaultSettings"></a>
           </div>
           <div id="choose-datatypes-throbber" class="throbber"></div>
           <div class="button-strip">
diff --git a/chrome/browser/resources/user_manager/user_manager.html b/chrome/browser/resources/user_manager/user_manager.html
index 8c0c7a7..d89e4a6 100644
--- a/chrome/browser/resources/user_manager/user_manager.html
+++ b/chrome/browser/resources/user_manager/user_manager.html
@@ -16,6 +16,7 @@
 <link rel="stylesheet" href="user_manager_tutorial.css">
 <!-- framework imports -->
 <!-- as per chrome/browser/resources/chromeos/login/login_resources.html -->
+<script src="chrome://resources/js/action_link.js"></script>
 <script src="chrome://resources/js/cr.js"></script>
 <script src="chrome://resources/js/event_tracker.js"></script>
 <script src="chrome://resources/js/cr/event_target.js"></script>
diff --git a/chrome/browser/resources/user_manager/user_manager_tutorial.css b/chrome/browser/resources/user_manager/user_manager_tutorial.css
index 7337153..b0c6c60 100644
--- a/chrome/browser/resources/user_manager/user_manager_tutorial.css
+++ b/chrome/browser/resources/user_manager/user_manager_tutorial.css
@@ -92,7 +92,7 @@
   width: 100%;
 }
 
-.slide-buttons .link-button {
+.slide-buttons [is='action-link'] {
   width: 100%;
 }
 
diff --git a/chrome/browser/resources/user_manager/user_manager_tutorial.html b/chrome/browser/resources/user_manager/user_manager_tutorial.html
index 5fb93a0..c1da41d 100644
--- a/chrome/browser/resources/user_manager/user_manager_tutorial.html
+++ b/chrome/browser/resources/user_manager/user_manager_tutorial.html
@@ -49,8 +49,8 @@
     <div id="dismiss-bubble-button"></div>
     <div class="slide-buttons">
       <div class="slide-text" i18n-content="slideCompleteUserNotFound"></div>
-      <button id="slide-add-user" class="link-button"
-          i18n-content="slideCompleteAddUser"></button>
+      <a is="action-link" id="slide-add-user"
+          i18n-content="slideCompleteAddUser"></a>
     </div>
     <div class="arrow-down"></div>
   </div>
diff --git a/chrome/browser/resources/whispernet_proxy/js/init.js b/chrome/browser/resources/whispernet_proxy/js/init.js
index a5b11c9f..693b7d4 100644
--- a/chrome/browser/resources/whispernet_proxy/js/init.js
+++ b/chrome/browser/resources/whispernet_proxy/js/init.js
@@ -50,11 +50,12 @@
 
 /**
  * Sends a request to whispernet to decode samples.
- * @param {ArrayBuffer} samples Array of samples to decode.
+ * @param {ArrayBuffer} samples Array of samples to process.
+ * @param {Object} type Type of decoding to perform.
  */
-function decodeSamplesRequest(samples) {
+function decodeSamplesRequest(samples, type) {
   if (whisperDecoder) {
-    whisperDecoder.processSamples(samples);
+    whisperDecoder.processSamples(samples, type);
   } else {
     console.error('decodeSamplesRequest: Whisper not initialized!');
   }
diff --git a/chrome/browser/resources/whispernet_proxy/js/wrapper.js b/chrome/browser/resources/whispernet_proxy/js/wrapper.js
index 7c3262b..1b5b495 100644
--- a/chrome/browser/resources/whispernet_proxy/js/wrapper.js
+++ b/chrome/browser/resources/whispernet_proxy/js/wrapper.js
@@ -49,7 +49,7 @@
     sample_rate: params.sampleRate || 48000.0,
     upsampling_factor: params.bitsPerSample || 16,
   };
-  this.whisperNacl_.send(JSON.stringify(msg));
+  this.whisperNacl_.send(msg);
 }
 
 /**
@@ -71,7 +71,7 @@
     use_dtmf: audible,
     return_raw_samples: raw
   };
-  this.whisperNacl_.send(JSON.stringify(msg));
+  this.whisperNacl_.send(msg);
 };
 
 /**
@@ -119,7 +119,7 @@
     max_candidates: 1,
     max_buffer_duration_in_seconds: 3
   };
-  this.whisperNacl_.send(JSON.stringify(msg));
+  this.whisperNacl_.send(msg);
 }
 
 /**
@@ -129,7 +129,7 @@
   var msg = {
     type: 'wipe_decode_buffer'
   };
-  this.whisperNacl_.send(JSON.stringify(msg));
+  this.whisperNacl_.send(msg);
 };
 
 /**
@@ -139,17 +139,23 @@
   var msg = {
     type: 'detect_broadcast'
   };
-  this.whisperNacl_.send(JSON.stringify(msg));
+  this.whisperNacl_.send(msg);
 };
 
 /**
  * Method to request the decoder to process samples.
  * @param {ArrayBuffer} samples Array of samples to process.
+ * @param {Object} type Type of decoding to perform.
  */
-WhisperDecoder.prototype.processSamples = function(samples) {
-  // For sample processing, the Nacl module doesn't expect any frills in the
-  // message, just send the samples directly.
-  this.whisperNacl_.send(samples);
+WhisperDecoder.prototype.processSamples = function(samples, type) {
+  var msg = {
+    type: 'decode_tokens',
+    decode_audible: type.decodeAudible,
+    decode_inaudible: type.decodeInaudible,
+    data: samples,
+  };
+
+  this.whisperNacl_.send(msg);
 };
 
 /**
@@ -179,7 +185,7 @@
 WhisperDecoder.prototype.onNaclMessage_ = function(e) {
   var msg = e.data;
   if (msg.type == 'decode_tokens_response') {
-    this.handleCandidates_(JSON.parse(msg.tokens), msg.audible);
+    this.handleCandidates_(msg.tokens, msg.audible);
   } else if (msg.type == 'detect_broadcast_response') {
     this.detectBroadcastCallback_(msg.detected);
   }
diff --git a/chrome/browser/resources/whispernet_proxy/whispernet_proxy_pnacl.pexe.png b/chrome/browser/resources/whispernet_proxy/whispernet_proxy_pnacl.pexe.png
index 894f1f8..f5ffb3b8 100644
--- a/chrome/browser/resources/whispernet_proxy/whispernet_proxy_pnacl.pexe.png
+++ b/chrome/browser/resources/whispernet_proxy/whispernet_proxy_pnacl.pexe.png
Binary files differ
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.h b/chrome/browser/safe_browsing/client_side_detection_host.h
index 77ed9e3a..2384e35c 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host.h
+++ b/chrome/browser/safe_browsing/client_side_detection_host.h
@@ -35,26 +35,26 @@
   // The caller keeps ownership of the tab object and is responsible for
   // ensuring that it stays valid until WebContentsDestroyed is called.
   static ClientSideDetectionHost* Create(content::WebContents* tab);
-  virtual ~ClientSideDetectionHost();
+  ~ClientSideDetectionHost() override;
 
   // From content::WebContentsObserver.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // From content::WebContentsObserver.  If we navigate away we cancel all
   // pending callbacks that could show an interstitial, and check to see whether
   // we should classify the new URL.
-  virtual void DidNavigateMainFrame(
+  void DidNavigateMainFrame(
       const content::LoadCommittedDetails& details,
       const content::FrameNavigateParams& params) override;
 
   // Called when the SafeBrowsingService found a hit with one of the
   // SafeBrowsing lists.  This method is called on the UI thread.
-  virtual void OnSafeBrowsingHit(
+  void OnSafeBrowsingHit(
       const SafeBrowsingUIManager::UnsafeResource& resource) override;
 
   // Called when the SafeBrowsingService finds a match on the SB lists.
   // Called on the UI thread. Called even if the resource is whitelisted.
-  virtual void OnSafeBrowsingMatch(
+  void OnSafeBrowsingMatch(
       const SafeBrowsingUIManager::UnsafeResource& resource) override;
 
   virtual scoped_refptr<SafeBrowsingDatabaseManager> database_manager();
@@ -67,7 +67,7 @@
   explicit ClientSideDetectionHost(content::WebContents* tab);
 
   // From content::WebContentsObserver.
-  virtual void WebContentsDestroyed() override;
+  void WebContentsDestroyed() override;
 
   // Used for testing.
   void set_safe_browsing_managers(
@@ -122,13 +122,13 @@
 
   // From NotificationObserver.  Called when a notification comes in.  This
   // method is called in the UI thread.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Inherited from WebContentsObserver.  This is called once the page is
   // done loading.
-  virtual void DidStopLoading(content::RenderViewHost* rvh) override;
+  void DidStopLoading(content::RenderViewHost* rvh) override;
 
   // Returns true if the user has seen a regular SafeBrowsing
   // interstitial for the current page.  This is only true if the user has
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
index 2330132..240fdab 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -233,7 +233,7 @@
     ChromeRenderViewHostTestHarness::TearDown();
   }
 
-  virtual content::BrowserContext* CreateBrowserContext() override {
+  content::BrowserContext* CreateBrowserContext() override {
     // Set custom profile object so that we can mock calls to IsOffTheRecord.
     // This needs to happen before we call the parent SetUp() function.  We use
     // a nice mock because other parts of the code are calling IsOffTheRecord.
diff --git a/chrome/browser/safe_browsing/client_side_detection_service.h b/chrome/browser/safe_browsing/client_side_detection_service.h
index 6528b5c..8804f73 100644
--- a/chrome/browser/safe_browsing/client_side_detection_service.h
+++ b/chrome/browser/safe_browsing/client_side_detection_service.h
@@ -66,7 +66,7 @@
   typedef base::Callback<void(GURL, GURL, bool)>
       ClientReportMalwareRequestCallback;
 
-  virtual ~ClientSideDetectionService();
+  ~ClientSideDetectionService() override;
 
   // Creates a client-side detection service.  The service is initially
   // disabled, use SetEnabledAndRefreshState() to start it.  The caller takes
@@ -88,12 +88,12 @@
   }
 
   // From the net::URLFetcherDelegate interface.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // content::NotificationObserver overrides:
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Sends a request to the SafeBrowsing servers with the ClientPhishingRequest.
   // The URL scheme of the |url()| in the request should be HTTP.  This method
diff --git a/chrome/browser/safe_browsing/database_manager.h b/chrome/browser/safe_browsing/database_manager.h
index 824800a..e001a35e 100644
--- a/chrome/browser/safe_browsing/database_manager.h
+++ b/chrome/browser/safe_browsing/database_manager.h
@@ -205,7 +205,7 @@
   void StopOnIOThread(bool shutdown);
 
  protected:
-  virtual ~SafeBrowsingDatabaseManager();
+  ~SafeBrowsingDatabaseManager() override;
 
   // protected for tests.
   void NotifyDatabaseUpdateFinished(bool update_succeeded);
@@ -341,15 +341,15 @@
                               const base::Closure& task);
 
   // SafeBrowsingProtocolManageDelegate override
-  virtual void ResetDatabase() override;
-  virtual void UpdateStarted() override;
-  virtual void UpdateFinished(bool success) override;
-  virtual void GetChunks(GetChunksCallback callback) override;
-  virtual void AddChunks(const std::string& list,
-                         scoped_ptr<ScopedVector<SBChunkData> > chunks,
-                         AddChunksCallback callback) override;
-  virtual void DeleteChunks(
-      scoped_ptr<std::vector<SBChunkDelete> > chunk_deletes) override;
+  void ResetDatabase() override;
+  void UpdateStarted() override;
+  void UpdateFinished(bool success) override;
+  void GetChunks(GetChunksCallback callback) override;
+  void AddChunks(const std::string& list,
+                 scoped_ptr<ScopedVector<SBChunkData>> chunks,
+                 AddChunksCallback callback) override;
+  void DeleteChunks(
+      scoped_ptr<std::vector<SBChunkDelete>> chunk_deletes) override;
 
   scoped_refptr<SafeBrowsingService> sb_service_;
 
diff --git a/chrome/browser/safe_browsing/download_feedback.cc b/chrome/browser/safe_browsing/download_feedback.cc
index dfa248b..27f4008 100644
--- a/chrome/browser/safe_browsing/download_feedback.cc
+++ b/chrome/browser/safe_browsing/download_feedback.cc
@@ -38,15 +38,15 @@
                        const base::FilePath& file_path,
                        const std::string& ping_request,
                        const std::string& ping_response);
-  virtual ~DownloadFeedbackImpl();
+  ~DownloadFeedbackImpl() override;
 
-  virtual void Start(const base::Closure& finish_callback) override;
+  void Start(const base::Closure& finish_callback) override;
 
-  virtual const std::string& GetPingRequestForTesting() const override {
+  const std::string& GetPingRequestForTesting() const override {
     return ping_request_;
   }
 
-  virtual const std::string& GetPingResponseForTesting() const override {
+  const std::string& GetPingResponseForTesting() const override {
     return ping_response_;
   }
 
diff --git a/chrome/browser/safe_browsing/download_feedback_service_unittest.cc b/chrome/browser/safe_browsing/download_feedback_service_unittest.cc
index e545b8d..450524f 100644
--- a/chrome/browser/safe_browsing/download_feedback_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_feedback_service_unittest.cc
@@ -40,20 +40,18 @@
         start_called_(false) {
   }
 
-  virtual ~FakeDownloadFeedback() {
-    deletion_callback_.Run();
-  }
+  ~FakeDownloadFeedback() override { deletion_callback_.Run(); }
 
-  virtual void Start(const base::Closure& finish_callback) override {
+  void Start(const base::Closure& finish_callback) override {
     start_called_ = true;
     finish_callback_ = finish_callback;
   }
 
-  virtual const std::string& GetPingRequestForTesting() const override {
+  const std::string& GetPingRequestForTesting() const override {
     return ping_request_;
   }
 
-  virtual const std::string& GetPingResponseForTesting() const override {
+  const std::string& GetPingResponseForTesting() const override {
     return ping_response_;
   }
 
@@ -79,9 +77,9 @@
 
 class FakeDownloadFeedbackFactory : public DownloadFeedbackFactory {
  public:
-  virtual ~FakeDownloadFeedbackFactory() {}
+  ~FakeDownloadFeedbackFactory() override {}
 
-  virtual DownloadFeedback* CreateDownloadFeedback(
+  DownloadFeedback* CreateDownloadFeedback(
       net::URLRequestContextGetter* request_context_getter,
       base::TaskRunner* file_task_runner,
       const base::FilePath& file_path,
diff --git a/chrome/browser/safe_browsing/download_feedback_unittest.cc b/chrome/browser/safe_browsing/download_feedback_unittest.cc
index 0fc5d15b..fa9113a 100644
--- a/chrome/browser/safe_browsing/download_feedback_unittest.cc
+++ b/chrome/browser/safe_browsing/download_feedback_unittest.cc
@@ -29,11 +29,9 @@
                const base::FilePath& file_path,
                const ProgressCallback& progress_callback,
                const FinishCallback& finish_callback);
-  virtual ~FakeUploader() {}
+  ~FakeUploader() override {}
 
-  virtual void Start() override {
-    start_called_ = true;
-  }
+  void Start() override { start_called_ = true; }
 
   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
   scoped_refptr<base::TaskRunner> file_task_runner_;
@@ -67,9 +65,9 @@
 class FakeUploaderFactory : public TwoPhaseUploaderFactory {
  public:
   FakeUploaderFactory() : uploader_(NULL) {}
-  virtual ~FakeUploaderFactory() {}
+  ~FakeUploaderFactory() override {}
 
-  virtual TwoPhaseUploader* CreateTwoPhaseUploader(
+  TwoPhaseUploader* CreateTwoPhaseUploader(
       net::URLRequestContextGetter* url_request_context_getter,
       base::TaskRunner* file_task_runner,
       const GURL& base_url,
diff --git a/chrome/browser/safe_browsing/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection_service.cc
index b00646a2..3af48ae4 100644
--- a/chrome/browser/safe_browsing/download_protection_service.cc
+++ b/chrome/browser/safe_browsing/download_protection_service.cc
@@ -166,7 +166,7 @@
 
  protected:
   friend class base::RefCountedThreadSafe<DownloadSBClient>;
-  virtual ~DownloadSBClient() {}
+  ~DownloadSBClient() override {}
 
   void CheckDone(SBThreatType threat_type) {
     DownloadProtectionService::DownloadCheckResult result =
@@ -236,7 +236,7 @@
                          DOWNLOAD_URL_CHECKS_MALWARE),
         database_manager_(database_manager) { }
 
-  virtual void StartCheck() override {
+  void StartCheck() override {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     if (!database_manager_.get() ||
         database_manager_->CheckDownloadUrl(url_chain_, this)) {
@@ -246,12 +246,12 @@
     }
   }
 
-  virtual bool IsDangerous(SBThreatType threat_type) const override {
+  bool IsDangerous(SBThreatType threat_type) const override {
     return threat_type == SB_THREAT_TYPE_BINARY_MALWARE_URL;
   }
 
-  virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
-                                        SBThreatType threat_type) override {
+  void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
+                                SBThreatType threat_type) override {
     CheckDone(threat_type);
     UMA_HISTOGRAM_TIMES("SB2.DownloadUrlCheckDuration",
                         base::TimeTicks::Now() - start_time_);
@@ -259,7 +259,7 @@
   }
 
  protected:
-  virtual ~DownloadUrlSBClient() {}
+  ~DownloadUrlSBClient() override {}
 
  private:
   scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
@@ -378,13 +378,13 @@
   }
 
   // content::DownloadItem::Observer implementation.
-  virtual void OnDownloadDestroyed(content::DownloadItem* download) override {
+  void OnDownloadDestroyed(content::DownloadItem* download) override {
     Cancel();
     DCHECK(item_ == NULL);
   }
 
   // From the net::URLFetcherDelegate interface.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override {
+  void OnURLFetchComplete(const net::URLFetcher* source) override {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     DCHECK_EQ(source, fetcher_.get());
     VLOG(2) << "Received a response for URL: "
@@ -479,7 +479,7 @@
   friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
   friend class base::DeleteHelper<CheckClientDownloadRequest>;
 
-  virtual ~CheckClientDownloadRequest() {
+  ~CheckClientDownloadRequest() override {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     DCHECK(item_ == NULL);
   }
diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
index 9aed0ae..93324cf 100644
--- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
@@ -90,14 +90,14 @@
   }
 
  protected:
-  virtual ~FakeSafeBrowsingService() { }
+  ~FakeSafeBrowsingService() override {}
 
-  virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
+  SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
     mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this);
     return mock_database_manager_;
   }
 
-  virtual void RegisterAllDelayedAnalysis() override { }
+  void RegisterAllDelayedAnalysis() override {}
 
  private:
   MockSafeBrowsingDatabaseManager* mock_database_manager_;
@@ -131,12 +131,12 @@
   }
 
   // TestURLFetcherDelegateForTests impl:
-  virtual void OnRequestStart(int fetcher_id) override {
+  void OnRequestStart(int fetcher_id) override {
     fetcher_id_ = fetcher_id;
     run_loop_.Quit();
   }
-  virtual void OnChunkUpload(int fetcher_id) override {}
-  virtual void OnRequestEnd(int fetcher_id) override {}
+  void OnChunkUpload(int fetcher_id) override {}
+  void OnRequestEnd(int fetcher_id) override {}
 
   int WaitForRequest() {
     run_loop_.Run();
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.h b/chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.h
index 83aadd9..4c755714 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.h
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.h
@@ -34,7 +34,7 @@
   // The id associated with the URLFetcher, for use by tests.
   static const int kTestUrlFetcherId;
 
-  virtual ~IncidentReportUploaderImpl();
+  ~IncidentReportUploaderImpl() override;
 
   // Uploads a report with a caller-provided URL context. |callback| will be run
   // when the upload is complete. Returns NULL if |report| cannot be serialized
@@ -54,7 +54,7 @@
   static GURL GetIncidentReportUrl();
 
   // net::URLFetcherDelegate methods.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // The underlying URL fetcher. The instance is alive from construction through
   // OnURLFetchComplete.
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 10fb114e..9434e66 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h
@@ -71,7 +71,7 @@
 
   // All incident collection, data collection, and uploads in progress are
   // dropped at destruction.
-  virtual ~IncidentReportingService();
+  ~IncidentReportingService() override;
 
   // Returns a callback by which external components can add an incident to the
   // service on behalf of |profile|. The callback may outlive the service, but
@@ -233,9 +233,9 @@
                             scoped_ptr<ClientIncidentResponse> response);
 
   // content::NotificationObserver methods.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   base::ThreadChecker thread_checker_;
 
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc
index 9e469c1..ae6c3ceb 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc
@@ -68,25 +68,25 @@
       test_instance_.Get().Set(this);
     }
 
-    virtual ~TestIncidentReportingService() { test_instance_.Get().Set(NULL); }
+    ~TestIncidentReportingService() override { test_instance_.Get().Set(NULL); }
 
     bool IsProcessingReport() const {
       return IncidentReportingService::IsProcessingReport();
     }
 
    protected:
-    virtual void OnProfileAdded(Profile* profile) override {
+    void OnProfileAdded(Profile* profile) override {
       pre_profile_add_callback_.Run(profile);
       safe_browsing::IncidentReportingService::OnProfileAdded(profile);
     }
 
-    virtual scoped_ptr<safe_browsing::LastDownloadFinder> CreateDownloadFinder(
+    scoped_ptr<safe_browsing::LastDownloadFinder> CreateDownloadFinder(
         const safe_browsing::LastDownloadFinder::LastDownloadCallback& callback)
         override {
       return create_download_finder_callback_.Run(callback);
     }
 
-    virtual scoped_ptr<safe_browsing::IncidentReportUploader> StartReportUpload(
+    scoped_ptr<safe_browsing::IncidentReportUploader> StartReportUpload(
         const safe_browsing::IncidentReportUploader::OnResultCallback& callback,
         const scoped_refptr<net::URLRequestContextGetter>&
             request_context_getter,
@@ -315,7 +315,7 @@
           FROM_HERE,
           base::Bind(&FakeUploader::FinishUpload, base::Unretained(this)));
     }
-    virtual ~FakeUploader() { on_deleted_.Run(); }
+    ~FakeUploader() override { on_deleted_.Run(); }
 
    private:
     void FinishUpload() {
@@ -346,7 +346,7 @@
           new FakeDownloadFinder(on_deleted));
     }
 
-    virtual ~FakeDownloadFinder() { on_deleted_.Run(); }
+    ~FakeDownloadFinder() override { on_deleted_.Run(); }
 
    private:
     explicit FakeDownloadFinder(const base::Closure& on_deleted)
diff --git a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h
index 80d9694f..233773b 100644
--- a/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h
+++ b/chrome/browser/safe_browsing/incident_reporting/last_download_finder.h
@@ -42,7 +42,7 @@
   typedef base::Callback<void(scoped_ptr<ClientIncidentReport_DownloadDetails>)>
       LastDownloadCallback;
 
-  virtual ~LastDownloadFinder();
+  ~LastDownloadFinder() override;
 
   // Initiates an asynchronous search for the most recent download. |callback|
   // will be run when the search is complete. The returned instance can be
@@ -89,9 +89,9 @@
   void ReportResults();
 
   // content::NotificationObserver methods.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Caller-supplied callback to be invoked when the most recent download is
   // found.
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h
index 6addfae..c013993 100644
--- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h
+++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h
@@ -19,16 +19,16 @@
  public:
   explicit PreferenceValidationDelegate(
       const AddIncidentCallback& add_incident);
-  virtual ~PreferenceValidationDelegate();
+  ~PreferenceValidationDelegate() override;
 
  private:
   // TrackedPreferenceValidationDelegate methods.
-  virtual void OnAtomicPreferenceValidation(
+  void OnAtomicPreferenceValidation(
       const std::string& pref_path,
       const base::Value* value,
       PrefHashStoreTransaction::ValueState value_state,
       TrackedPreferenceHelper::ResetAction reset_action) override;
-  virtual void OnSplitPreferenceValidation(
+  void OnSplitPreferenceValidation(
       const std::string& pref_path,
       const base::DictionaryValue* dict_value,
       const std::vector<std::string>& invalid_keys,
diff --git a/chrome/browser/safe_browsing/local_safebrowsing_test_server.h b/chrome/browser/safe_browsing/local_safebrowsing_test_server.h
index 1bdc9a9f..7639385 100644
--- a/chrome/browser/safe_browsing/local_safebrowsing_test_server.h
+++ b/chrome/browser/safe_browsing/local_safebrowsing_test_server.h
@@ -17,17 +17,16 @@
   // Initialize a safebrowsing server using the given |data_file|.
   explicit LocalSafeBrowsingTestServer(const base::FilePath& data_file);
 
-  virtual ~LocalSafeBrowsingTestServer();
+  ~LocalSafeBrowsingTestServer() override;
 
-  virtual bool SetPythonPath() const override;
+  bool SetPythonPath() const override;
 
   // Returns the path to safe_browsing_testserver.py.
-  virtual bool GetTestServerPath(
-      base::FilePath* testserver_path) const override;
+  bool GetTestServerPath(base::FilePath* testserver_path) const override;
 
  protected:
   // Adds the --data-file switch. Returns true on success.
-  virtual bool GenerateAdditionalArguments(
+  bool GenerateAdditionalArguments(
       base::DictionaryValue* arguments) const override;
 
  private:
diff --git a/chrome/browser/safe_browsing/local_two_phase_testserver.h b/chrome/browser/safe_browsing/local_two_phase_testserver.h
index 1b6bffd..1614521 100644
--- a/chrome/browser/safe_browsing/local_two_phase_testserver.h
+++ b/chrome/browser/safe_browsing/local_two_phase_testserver.h
@@ -17,11 +17,10 @@
   // Initialize a two phase protocol test server.
   LocalTwoPhaseTestServer();
 
-  virtual ~LocalTwoPhaseTestServer();
+  ~LocalTwoPhaseTestServer() override;
 
   // Returns the path to two_phase_testserver.py.
-  virtual bool GetTestServerPath(
-      base::FilePath* testserver_path) const override;
+  bool GetTestServerPath(base::FilePath* testserver_path) const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(LocalTwoPhaseTestServer);
diff --git a/chrome/browser/safe_browsing/malware_details.cc b/chrome/browser/safe_browsing/malware_details.cc
index 9db467c..f831a3c 100644
--- a/chrome/browser/safe_browsing/malware_details.cc
+++ b/chrome/browser/safe_browsing/malware_details.cc
@@ -35,7 +35,7 @@
 // don't leak it.
 class MalwareDetailsFactoryImpl : public MalwareDetailsFactory {
  public:
-  virtual MalwareDetails* CreateMalwareDetails(
+  MalwareDetails* CreateMalwareDetails(
       SafeBrowsingUIManager* ui_manager,
       WebContents* web_contents,
       const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) override {
diff --git a/chrome/browser/safe_browsing/malware_details.h b/chrome/browser/safe_browsing/malware_details.h
index 059588b..51dff4b 100644
--- a/chrome/browser/safe_browsing/malware_details.h
+++ b/chrome/browser/safe_browsing/malware_details.h
@@ -70,7 +70,7 @@
   void OnRedirectionCollectionReady();
 
   // content::WebContentsObserver implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
  protected:
   friend class MalwareDetailsFactoryImpl;
@@ -79,7 +79,7 @@
                  content::WebContents* web_contents,
                  const UnsafeResource& resource);
 
-  virtual ~MalwareDetails();
+  ~MalwareDetails() override;
 
   // Called on the IO thread with the DOM details.
   virtual void AddDOMDetails(
diff --git a/chrome/browser/safe_browsing/malware_details_cache.h b/chrome/browser/safe_browsing/malware_details_cache.h
index a6b7397..ec855cf 100644
--- a/chrome/browser/safe_browsing/malware_details_cache.h
+++ b/chrome/browser/safe_browsing/malware_details_cache.h
@@ -54,12 +54,12 @@
  protected:
   // Implementation of URLFetcher::Delegate. Called after the request
   // completes (either successfully or with failure).
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  private:
   friend class base::RefCountedThreadSafe<MalwareDetailsCacheCollector>;
 
-  virtual ~MalwareDetailsCacheCollector();
+  ~MalwareDetailsCacheCollector() override;
 
   // Points to the url for which we are fetching the HTTP cache entry or
   // redirect chain.
diff --git a/chrome/browser/safe_browsing/malware_details_history.h b/chrome/browser/safe_browsing/malware_details_history.h
index 31936264..7482cc5 100644
--- a/chrome/browser/safe_browsing/malware_details_history.h
+++ b/chrome/browser/safe_browsing/malware_details_history.h
@@ -47,16 +47,16 @@
   const std::vector<safe_browsing::RedirectChain>& GetCollectedUrls() const;
 
   // content::NotificationObserver
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
  private:
   friend struct content::BrowserThread::DeleteOnThread<
       content::BrowserThread::UI>;
   friend class base::DeleteHelper<MalwareDetailsRedirectsCollector>;
 
-  virtual ~MalwareDetailsRedirectsCollector();
+  ~MalwareDetailsRedirectsCollector() override;
 
   void StartGetRedirects(const std::vector<GURL>& urls);
   void GetRedirects(const GURL& url);
diff --git a/chrome/browser/safe_browsing/malware_details_unittest.cc b/chrome/browser/safe_browsing/malware_details_unittest.cc
index 3fc29057..390c6b42 100644
--- a/chrome/browser/safe_browsing/malware_details_unittest.cc
+++ b/chrome/browser/safe_browsing/malware_details_unittest.cc
@@ -136,7 +136,7 @@
   }
 
  private:
-  virtual ~MalwareDetailsWrap() {}
+  ~MalwareDetailsWrap() override {}
 };
 
 class MockSafeBrowsingUIManager : public SafeBrowsingUIManager {
@@ -147,8 +147,7 @@
       : SafeBrowsingUIManager(NULL), run_loop_(NULL) {}
 
   // When the MalwareDetails is done, this is called.
-  virtual void SendSerializedMalwareDetails(
-      const std::string& serialized) override {
+  void SendSerializedMalwareDetails(const std::string& serialized) override {
     DVLOG(1) << "SendSerializedMalwareDetails";
     run_loop_->Quit();
     run_loop_ = NULL;
@@ -169,7 +168,7 @@
   }
 
  private:
-  virtual ~MockSafeBrowsingUIManager() {}
+  ~MockSafeBrowsingUIManager() override {}
 
   std::string serialized_;
   DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager);
diff --git a/chrome/browser/safe_browsing/ping_manager.h b/chrome/browser/safe_browsing/ping_manager.h
index d48cc4f6..a33559b 100644
--- a/chrome/browser/safe_browsing/ping_manager.h
+++ b/chrome/browser/safe_browsing/ping_manager.h
@@ -25,7 +25,7 @@
 
 class SafeBrowsingPingManager : public net::URLFetcherDelegate {
  public:
-  virtual ~SafeBrowsingPingManager();
+  ~SafeBrowsingPingManager() override;
 
   // Create an instance of the safe browsing ping manager.
   static SafeBrowsingPingManager* Create(
@@ -33,7 +33,7 @@
       const SafeBrowsingProtocolConfig& config);
 
   // net::URLFetcherDelegate interface.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // For UMA users we report to Google when a SafeBrowsing interstitial is shown
   // to the user.  |threat_type| should be one of the types known by
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc
index 64dc05b..7a39760 100644
--- a/chrome/browser/safe_browsing/protocol_manager.cc
+++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -73,8 +73,8 @@
 class SBProtocolManagerFactoryImpl : public SBProtocolManagerFactory {
  public:
   SBProtocolManagerFactoryImpl() { }
-  virtual ~SBProtocolManagerFactoryImpl() { }
-  virtual SafeBrowsingProtocolManager* CreateProtocolManager(
+  ~SBProtocolManagerFactoryImpl() override {}
+  SafeBrowsingProtocolManager* CreateProtocolManager(
       SafeBrowsingProtocolManagerDelegate* delegate,
       net::URLRequestContextGetter* request_context_getter,
       const SafeBrowsingProtocolConfig& config) override {
diff --git a/chrome/browser/safe_browsing/protocol_manager.h b/chrome/browser/safe_browsing/protocol_manager.h
index 3eb549a41..ae357f8 100644
--- a/chrome/browser/safe_browsing/protocol_manager.h
+++ b/chrome/browser/safe_browsing/protocol_manager.h
@@ -51,7 +51,7 @@
   typedef base::Callback<void(const std::vector<SBFullHashResult>&,
                               const base::TimeDelta&)> FullHashCallback;
 
-  virtual ~SafeBrowsingProtocolManager();
+  ~SafeBrowsingProtocolManager() override;
 
   // Makes the passed |factory| the factory used to instantiate
   // a SafeBrowsingService. Useful for tests.
@@ -70,7 +70,7 @@
   virtual void Initialize();
 
   // net::URLFetcherDelegate interface.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // Retrieve the full hash for a set of prefixes, and invoke the callback
   // argument when the results are retrieved. The callback may be invoked
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
index ac6b798..1c47c2c 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -126,7 +126,7 @@
 class SafeBrowsingBlockingPageFactoryImpl
     : public SafeBrowsingBlockingPageFactory {
  public:
-  virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
+  SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
       SafeBrowsingUIManager* ui_manager,
       WebContents* web_contents,
       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
index 3db2560..09dfe91 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
@@ -65,7 +65,7 @@
   typedef std::vector<UnsafeResource> UnsafeResourceList;
   typedef std::map<content::WebContents*, UnsafeResourceList> UnsafeResourceMap;
 
-  virtual ~SafeBrowsingBlockingPage();
+  ~SafeBrowsingBlockingPage() override;
 
   // Creates a blocking page. Use ShowBlockingPage if you don't need to access
   // the blocking page directly.
@@ -89,12 +89,11 @@
   }
 
   // InterstitialPageDelegate method:
-  virtual std::string GetHTMLContents() override;
-  virtual void OnProceed() override;
-  virtual void OnDontProceed() override;
-  virtual void CommandReceived(const std::string& command) override;
-  virtual void OverrideRendererPrefs(
-      content::RendererPreferences* prefs) override;
+  std::string GetHTMLContents() override;
+  void OnProceed() override;
+  void OnDontProceed() override;
+  void CommandReceived(const std::string& command) override;
+  void OverrideRendererPrefs(content::RendererPreferences* prefs) override;
 
  protected:
   friend class SafeBrowsingBlockingPageTest;
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index 862d8a0..8b3c56a 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -61,7 +61,7 @@
   // Otherwise it returns false, and "client" is called asynchronously with the
   // result when it is ready.
   // Overrides SafeBrowsingDatabaseManager::CheckBrowseUrl.
-  virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
+  bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
     if (badurls[gurl.spec()] == SB_THREAT_TYPE_SAFE)
       return true;
 
@@ -91,7 +91,7 @@
   }
 
  private:
-  virtual ~FakeSafeBrowsingDatabaseManager() {}
+  ~FakeSafeBrowsingDatabaseManager() override {}
 
   base::hash_map<std::string, SBThreatType> badurls;
   DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
@@ -104,8 +104,7 @@
       SafeBrowsingUIManager(service) { }
 
   // Overrides SafeBrowsingUIManager
-  virtual void SendSerializedMalwareDetails(
-      const std::string& serialized) override {
+  void SendSerializedMalwareDetails(const std::string& serialized) override {
     // Notify the UI thread that we got a report.
     BrowserThread::PostTask(
         BrowserThread::UI,
@@ -138,7 +137,7 @@
   }
 
  protected:
-  virtual ~FakeSafeBrowsingUIManager() { }
+  ~FakeSafeBrowsingUIManager() override {}
 
  private:
   std::string report_;
@@ -165,14 +164,14 @@
   }
 
  protected:
-  virtual ~FakeSafeBrowsingService() { }
+  ~FakeSafeBrowsingService() override {}
 
-  virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
+  SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
     fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
     return fake_database_manager_;
   }
 
-  virtual SafeBrowsingUIManager* CreateUIManager() override {
+  SafeBrowsingUIManager* CreateUIManager() override {
     fake_ui_manager_ = new FakeSafeBrowsingUIManager(this);
     return fake_ui_manager_;
   }
@@ -189,9 +188,9 @@
  public:
   TestSafeBrowsingServiceFactory() :
       most_recent_service_(NULL) { }
-  virtual ~TestSafeBrowsingServiceFactory() { }
+  ~TestSafeBrowsingServiceFactory() override {}
 
-  virtual SafeBrowsingService* CreateSafeBrowsingService() override {
+  SafeBrowsingService* CreateSafeBrowsingService() override {
     most_recent_service_ =  new FakeSafeBrowsingService();
     return most_recent_service_;
   }
@@ -215,9 +214,9 @@
         got_dom_(false),
         waiting_(false) { }
 
-  virtual void AddDOMDetails(
+  void AddDOMDetails(
       const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params)
-          override {
+      override {
     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
     MalwareDetails::AddDOMDetails(params);
 
@@ -239,7 +238,7 @@
   }
 
  private:
-  virtual ~FakeMalwareDetails() {}
+  ~FakeMalwareDetails() override {}
 
   void OnDOMDetailsDone() {
     got_dom_ = true;
@@ -257,9 +256,9 @@
 class TestMalwareDetailsFactory : public MalwareDetailsFactory {
  public:
   TestMalwareDetailsFactory() : details_() { }
-  virtual ~TestMalwareDetailsFactory() { }
+  ~TestMalwareDetailsFactory() override {}
 
-  virtual MalwareDetails* CreateMalwareDetails(
+  MalwareDetails* CreateMalwareDetails(
       SafeBrowsingUIManager* delegate,
       WebContents* web_contents,
       const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) override {
@@ -288,7 +287,7 @@
     malware_details_proceed_delay_ms_ = 100;
   }
 
-  virtual ~TestSafeBrowsingBlockingPage() {
+  ~TestSafeBrowsingBlockingPage() override {
     if (!wait_for_delete_)
       return;
 
@@ -303,15 +302,11 @@
   }
 
   // InterstitialPageDelegate methods:
-  virtual void CommandReceived(const std::string& command) override {
+  void CommandReceived(const std::string& command) override {
     SafeBrowsingBlockingPage::CommandReceived(command);
   }
-  virtual void OnProceed() override {
-    SafeBrowsingBlockingPage::OnProceed();
-  }
-  virtual void OnDontProceed() override {
-    SafeBrowsingBlockingPage::OnDontProceed();
-  }
+  void OnProceed() override { SafeBrowsingBlockingPage::OnProceed(); }
+  void OnDontProceed() override { SafeBrowsingBlockingPage::OnDontProceed(); }
 
  private:
   bool wait_for_delete_;
@@ -321,13 +316,13 @@
     : public SafeBrowsingBlockingPageFactory {
  public:
   TestSafeBrowsingBlockingPageFactory() { }
-  virtual ~TestSafeBrowsingBlockingPageFactory() { }
+  ~TestSafeBrowsingBlockingPageFactory() override {}
 
-  virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
+  SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
       SafeBrowsingUIManager* delegate,
       WebContents* web_contents,
       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
-          override {
+      override {
     return new TestSafeBrowsingBlockingPage(delegate, web_contents,
                                               unsafe_resources);
   }
@@ -363,7 +358,7 @@
     MalwareDetails::RegisterFactory(NULL);
   }
 
-  virtual void SetUpInProcessBrowserTestFixture() override {
+  void SetUpInProcessBrowserTestFixture() override {
     ASSERT_TRUE(test_server()->Start());
   }
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
index 6656837..700183d 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
@@ -51,8 +51,7 @@
       : SafeBrowsingUIManager(service) {
   }
 
-  virtual void SendSerializedMalwareDetails(
-      const std::string& serialized) override {
+  void SendSerializedMalwareDetails(const std::string& serialized) override {
     details_.push_back(serialized);
   }
 
@@ -61,7 +60,7 @@
   }
 
  private:
-  virtual ~TestSafeBrowsingUIManager() {}
+  ~TestSafeBrowsingUIManager() override {}
 
   std::list<std::string> details_;
 };
@@ -70,9 +69,9 @@
     : public SafeBrowsingBlockingPageFactory {
  public:
   TestSafeBrowsingBlockingPageFactory() { }
-  virtual ~TestSafeBrowsingBlockingPageFactory() { }
+  ~TestSafeBrowsingBlockingPageFactory() override {}
 
-  virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
+  SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
       SafeBrowsingUIManager* manager,
       WebContents* web_contents,
       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.cc b/chrome/browser/safe_browsing/safe_browsing_database.cc
index c95a508a..dea4b3c 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database.cc
@@ -313,7 +313,7 @@
 // The default SafeBrowsingDatabaseFactory.
 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory {
  public:
-  virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
+  SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
       bool enable_download_protection,
       bool enable_client_side_whitelist,
       bool enable_download_whitelist,
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.h b/chrome/browser/safe_browsing/safe_browsing_database.h
index 17aad1d..3e2ca8d 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.h
+++ b/chrome/browser/safe_browsing/safe_browsing_database.h
@@ -287,42 +287,37 @@
   // useds Sqlite.
   SafeBrowsingDatabaseNew();
 
-  virtual ~SafeBrowsingDatabaseNew();
+  ~SafeBrowsingDatabaseNew() override;
 
   // Implement SafeBrowsingDatabase interface.
-  virtual void Init(const base::FilePath& filename) override;
-  virtual bool ResetDatabase() override;
-  virtual bool ContainsBrowseUrl(
-      const GURL& url,
-      std::vector<SBPrefix>* prefix_hits,
-      std::vector<SBFullHashResult>* cache_hits) override;
-  virtual bool ContainsDownloadUrl(const std::vector<GURL>& urls,
-                                   std::vector<SBPrefix>* prefix_hits) override;
-  virtual bool ContainsCsdWhitelistedUrl(const GURL& url) override;
-  virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) override;
-  virtual bool ContainsDownloadWhitelistedString(
-      const std::string& str) override;
-  virtual bool ContainsExtensionPrefixes(
-      const std::vector<SBPrefix>& prefixes,
-      std::vector<SBPrefix>* prefix_hits) override;
-  virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url)  override;
-  virtual bool ContainsMalwareIP(const std::string& ip_address) override;
-  virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) override;
-  virtual void InsertChunks(const std::string& list_name,
-                            const std::vector<SBChunkData*>& chunks) override;
-  virtual void DeleteChunks(
-      const std::vector<SBChunkDelete>& chunk_deletes) override;
-  virtual void UpdateFinished(bool update_succeeded) override;
-  virtual void CacheHashResults(
-      const std::vector<SBPrefix>& prefixes,
-      const std::vector<SBFullHashResult>& full_hits,
-      const base::TimeDelta& cache_lifetime) override;
+  void Init(const base::FilePath& filename) override;
+  bool ResetDatabase() override;
+  bool ContainsBrowseUrl(const GURL& url,
+                         std::vector<SBPrefix>* prefix_hits,
+                         std::vector<SBFullHashResult>* cache_hits) override;
+  bool ContainsDownloadUrl(const std::vector<GURL>& urls,
+                           std::vector<SBPrefix>* prefix_hits) override;
+  bool ContainsCsdWhitelistedUrl(const GURL& url) override;
+  bool ContainsDownloadWhitelistedUrl(const GURL& url) override;
+  bool ContainsDownloadWhitelistedString(const std::string& str) override;
+  bool ContainsExtensionPrefixes(const std::vector<SBPrefix>& prefixes,
+                                 std::vector<SBPrefix>* prefix_hits) override;
+  bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) 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 DeleteChunks(const std::vector<SBChunkDelete>& chunk_deletes) override;
+  void UpdateFinished(bool update_succeeded) override;
+  void CacheHashResults(const std::vector<SBPrefix>& prefixes,
+                        const std::vector<SBFullHashResult>& full_hits,
+                        const base::TimeDelta& cache_lifetime) override;
 
   // Returns the value of malware_kill_switch_;
-  virtual bool IsMalwareIPMatchKillSwitchOn() override;
+  bool IsMalwareIPMatchKillSwitchOn() override;
 
   // Returns true if the CSD whitelist has everything whitelisted.
-  virtual bool IsCsdWhitelistKillSwitchOn() override;
+  bool IsCsdWhitelistKillSwitchOn() override;
 
  private:
   friend class SafeBrowsingDatabaseTest;
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index a232dc7..f100f9b7 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -108,12 +108,12 @@
       SafeBrowsingService* sb_service_);
 
   // Implementation for net::UrlRequestContextGetter.
-  virtual net::URLRequestContext* GetURLRequestContext() override;
-  virtual scoped_refptr<base::SingleThreadTaskRunner>
-      GetNetworkTaskRunner() const override;
+  net::URLRequestContext* GetURLRequestContext() override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+      const override;
 
  protected:
-  virtual ~SafeBrowsingURLRequestContextGetter();
+  ~SafeBrowsingURLRequestContextGetter() override;
 
  private:
   SafeBrowsingService* const sb_service_;  // Owned by BrowserProcess.
@@ -151,7 +151,7 @@
 // don't leak it.
 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory {
  public:
-  virtual SafeBrowsingService* CreateSafeBrowsingService() override {
+  SafeBrowsingService* CreateSafeBrowsingService() override {
     return new SafeBrowsingService();
   }
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h
index 60eea7e..51595489 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.h
+++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -135,7 +135,7 @@
   // Creates the safe browsing service.  Need to initialize before using.
   SafeBrowsingService();
 
-  virtual ~SafeBrowsingService();
+  ~SafeBrowsingService() override;
 
   virtual SafeBrowsingDatabaseManager* CreateDatabaseManager();
 
@@ -181,9 +181,9 @@
   void Stop(bool shutdown);
 
   // content::NotificationObserver override
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
   // Starts following the safe browsing preference on |pref_service|.
   void AddPrefService(PrefService* pref_service);
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index 1d906dd..cdb03bb 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -71,7 +71,7 @@
   explicit FakeSafeBrowsingService(const std::string& url_prefix)
       : url_prefix_(url_prefix) {}
 
-  virtual SafeBrowsingProtocolConfig GetProtocolConfig() const override {
+  SafeBrowsingProtocolConfig GetProtocolConfig() const override {
     SafeBrowsingProtocolConfig config;
     config.url_prefix = url_prefix_;
     // Makes sure the auto update is not triggered. The tests will force the
@@ -85,7 +85,7 @@
   }
 
  private:
-  virtual ~FakeSafeBrowsingService() {}
+  ~FakeSafeBrowsingService() override {}
 
   std::string url_prefix_;
 
@@ -98,7 +98,7 @@
   explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix)
       : url_prefix_(url_prefix) {}
 
-  virtual SafeBrowsingService* CreateSafeBrowsingService() override {
+  SafeBrowsingService* CreateSafeBrowsingService() override {
     return new FakeSafeBrowsingService(url_prefix_);
   }
 
@@ -111,13 +111,13 @@
  public:
   TestSafeBrowsingDatabase() {}
 
-  virtual ~TestSafeBrowsingDatabase() {}
+  ~TestSafeBrowsingDatabase() override {}
 
   // Initializes the database with the given filename.
-  virtual void Init(const base::FilePath& filename) override {}
+  void Init(const base::FilePath& filename) override {}
 
   // Deletes the current database and creates a new one.
-  virtual bool ResetDatabase() override {
+  bool ResetDatabase() override {
     badurls_.clear();
     return true;
   }
@@ -125,19 +125,17 @@
   // Called on the IO thread to check if the given URL is safe or not.  If we
   // can synchronously determine that the URL is safe, CheckUrl returns true,
   // otherwise it returns false.
-  virtual bool ContainsBrowseUrl(
-      const GURL& url,
-      std::vector<SBPrefix>* prefix_hits,
-      std::vector<SBFullHashResult>* cache_hits) override {
+  bool ContainsBrowseUrl(const GURL& url,
+                         std::vector<SBPrefix>* prefix_hits,
+                         std::vector<SBFullHashResult>* cache_hits) override {
     cache_hits->clear();
     return ContainsUrl(safe_browsing_util::MALWARE,
                        safe_browsing_util::PHISH,
                        std::vector<GURL>(1, url),
                        prefix_hits);
   }
-  virtual bool ContainsDownloadUrl(
-      const std::vector<GURL>& urls,
-      std::vector<SBPrefix>* prefix_hits) override {
+  bool ContainsDownloadUrl(const std::vector<GURL>& urls,
+                           std::vector<SBPrefix>* prefix_hits) override {
     bool found = ContainsUrl(safe_browsing_util::BINURL,
                              safe_browsing_util::BINURL,
                              urls,
@@ -147,55 +145,42 @@
     DCHECK_LE(1U, prefix_hits->size());
     return true;
   }
-  virtual bool ContainsCsdWhitelistedUrl(const GURL& url) override {
+  bool ContainsCsdWhitelistedUrl(const GURL& url) override { return true; }
+  bool ContainsDownloadWhitelistedString(const std::string& str) override {
     return true;
   }
-  virtual bool ContainsDownloadWhitelistedString(
-      const std::string& str) override {
+  bool ContainsDownloadWhitelistedUrl(const GURL& url) override { return true; }
+  bool ContainsExtensionPrefixes(const std::vector<SBPrefix>& prefixes,
+                                 std::vector<SBPrefix>* prefix_hits) override {
     return true;
   }
-  virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) override {
+  bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) override {
     return true;
   }
-  virtual bool ContainsExtensionPrefixes(
-      const std::vector<SBPrefix>& prefixes,
-      std::vector<SBPrefix>* prefix_hits) override {
+  bool ContainsMalwareIP(const std::string& ip_address) override {
     return true;
   }
-  virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) override {
-    return true;
-  }
-  virtual bool ContainsMalwareIP(const std::string& ip_address) override {
-    return true;
-  }
-  virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) override {
+  bool UpdateStarted(std::vector<SBListChunkRanges>* lists) override {
     ADD_FAILURE() << "Not implemented.";
     return false;
   }
-  virtual void InsertChunks(
-      const std::string& list_name,
-      const std::vector<SBChunkData*>& chunks) override {
+  void InsertChunks(const std::string& list_name,
+                    const std::vector<SBChunkData*>& chunks) override {
     ADD_FAILURE() << "Not implemented.";
   }
-  virtual void DeleteChunks(
-      const std::vector<SBChunkDelete>& chunk_deletes) override {
+  void DeleteChunks(const std::vector<SBChunkDelete>& chunk_deletes) override {
     ADD_FAILURE() << "Not implemented.";
   }
-  virtual void UpdateFinished(bool update_succeeded) override {
+  void UpdateFinished(bool update_succeeded) override {
     ADD_FAILURE() << "Not implemented.";
   }
-  virtual void CacheHashResults(
-      const std::vector<SBPrefix>& prefixes,
-      const std::vector<SBFullHashResult>& cache_hits,
-      const base::TimeDelta& cache_lifetime) override {
+  void CacheHashResults(const std::vector<SBPrefix>& prefixes,
+                        const std::vector<SBFullHashResult>& cache_hits,
+                        const base::TimeDelta& cache_lifetime) override {
     // Do nothing for the cache.
   }
-  virtual bool IsMalwareIPMatchKillSwitchOn() override {
-    return false;
-  }
-  virtual bool IsCsdWhitelistKillSwitchOn() override {
-    return false;
-  }
+  bool IsMalwareIPMatchKillSwitchOn() override { return false; }
+  bool IsCsdWhitelistKillSwitchOn() override { return false; }
 
   // Fill up the database with test URL.
   void AddUrl(const GURL& url,
@@ -248,9 +233,9 @@
 class TestSafeBrowsingDatabaseFactory : public SafeBrowsingDatabaseFactory {
  public:
   TestSafeBrowsingDatabaseFactory() : db_(NULL) {}
-  virtual ~TestSafeBrowsingDatabaseFactory() {}
+  ~TestSafeBrowsingDatabaseFactory() override {}
 
-  virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
+  SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
       bool enable_download_protection,
       bool enable_client_side_whitelist,
       bool enable_download_whitelist,
@@ -279,19 +264,16 @@
     create_count_++;
   }
 
-  virtual ~TestProtocolManager() {
-    delete_count_++;
-  }
+  ~TestProtocolManager() override { delete_count_++; }
 
   // This function is called when there is a prefix hit in local safebrowsing
   // database and safebrowsing service issues a get hash request to backends.
   // We return a result from the prefilled full_hashes_ hash_map to simulate
   // server's response. At the same time, latency is added to simulate real
   // life network issues.
-  virtual void GetFullHash(
-      const std::vector<SBPrefix>& prefixes,
-      SafeBrowsingProtocolManager::FullHashCallback callback,
-      bool is_download) override {
+  void GetFullHash(const std::vector<SBPrefix>& prefixes,
+                   SafeBrowsingProtocolManager::FullHashCallback callback,
+                   bool is_download) override {
     BrowserThread::PostDelayedTask(
         BrowserThread::IO, FROM_HERE,
         base::Bind(InvokeFullHashCallback, callback, full_hashes_),
@@ -332,9 +314,9 @@
 class TestSBProtocolManagerFactory : public SBProtocolManagerFactory {
  public:
   TestSBProtocolManagerFactory() : pm_(NULL) {}
-  virtual ~TestSBProtocolManagerFactory() {}
+  ~TestSBProtocolManagerFactory() override {}
 
-  virtual SafeBrowsingProtocolManager* CreateProtocolManager(
+  SafeBrowsingProtocolManager* CreateProtocolManager(
       SafeBrowsingProtocolManagerDelegate* delegate,
       net::URLRequestContextGetter* request_context_getter,
       const SafeBrowsingProtocolConfig& config) override {
@@ -514,13 +496,13 @@
  public:
   SafeBrowsingServiceMetadataTest() {}
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     SafeBrowsingServiceTest::SetUpOnMainThread();
     g_browser_process->safe_browsing_service()->ui_manager()->AddObserver(
         &observer_);
   }
 
-  virtual void TearDownOnMainThread() override {
+  void TearDownOnMainThread() override {
     g_browser_process->safe_browsing_service()->ui_manager()->RemoveObserver(
         &observer_);
     SafeBrowsingServiceTest::TearDownOnMainThread();
@@ -744,7 +726,7 @@
 
  private:
   friend class base::RefCountedThreadSafe<TestSBClient>;
-  virtual ~TestSBClient() {}
+  ~TestSBClient() override {}
 
   void CheckDownloadUrlOnIOThread(const std::vector<GURL>& url_chain) {
     safe_browsing_service_->database_manager()->
@@ -752,8 +734,8 @@
   }
 
   // Called when the result of checking a download URL is known.
-  virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
-                                        SBThreatType threat_type) override {
+  void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
+                                SBThreatType threat_type) override {
     threat_type_ = threat_type;
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                             base::Bind(&TestSBClient::DownloadCheckDone, this));
@@ -1013,7 +995,7 @@
     SafeBrowsingService::RegisterFactory(NULL);
   }
 
-  virtual bool SetUpUserDataDirectory() override {
+  bool SetUpUserDataDirectory() override {
     base::FilePath cookie_path(
         SafeBrowsingService::GetCookieFilePathForTesting());
     EXPECT_FALSE(base::PathExists(cookie_path));
@@ -1059,7 +1041,7 @@
     return InProcessBrowserTest::SetUpUserDataDirectory();
   }
 
-  virtual void TearDownInProcessBrowserTestFixture() override {
+  void TearDownInProcessBrowserTestFixture() override {
     InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
 
     sql::Connection db;
@@ -1080,14 +1062,12 @@
     EXPECT_FALSE(smt.Step());
   }
 
-  virtual void SetUpOnMainThread() override {
+  void SetUpOnMainThread() override {
     sb_service_ = g_browser_process->safe_browsing_service();
     ASSERT_TRUE(sb_service_.get() != NULL);
   }
 
-  virtual void TearDownOnMainThread() override {
-    sb_service_ = NULL;
-  }
+  void TearDownOnMainThread() override { sb_service_ = NULL; }
 
   void ForceUpdate() {
     sb_service_->protocol_manager()->ForceScheduleNextUpdate(
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file.h b/chrome/browser/safe_browsing/safe_browsing_store_file.h
index b8d324a..7497c9b 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file.h
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file.h
@@ -125,50 +125,50 @@
 class SafeBrowsingStoreFile : public SafeBrowsingStore {
  public:
   SafeBrowsingStoreFile();
-  virtual ~SafeBrowsingStoreFile();
+  ~SafeBrowsingStoreFile() override;
 
-  virtual void Init(const base::FilePath& filename,
-                    const base::Closure& corruption_callback) override;
+  void Init(const base::FilePath& filename,
+            const base::Closure& corruption_callback) override;
 
   // Delete any on-disk files, including the permanent storage.
-  virtual bool Delete() override;
+  bool Delete() override;
 
   // Get all add hash prefixes and full-length hashes, respectively, from
   // the store.
-  virtual bool GetAddPrefixes(SBAddPrefixes* add_prefixes) override;
-  virtual bool GetAddFullHashes(
-      std::vector<SBAddFullHash>* add_full_hashes) override;
+  bool GetAddPrefixes(SBAddPrefixes* add_prefixes) override;
+  bool GetAddFullHashes(std::vector<SBAddFullHash>* add_full_hashes) override;
 
-  virtual bool BeginChunk() override;
+  bool BeginChunk() override;
 
-  virtual bool WriteAddPrefix(int32 chunk_id, SBPrefix prefix) override;
-  virtual bool WriteAddHash(int32 chunk_id,
-                            const SBFullHash& full_hash) override;
-  virtual bool WriteSubPrefix(int32 chunk_id,
-                              int32 add_chunk_id, SBPrefix prefix) override;
-  virtual bool WriteSubHash(int32 chunk_id, int32 add_chunk_id,
-                            const SBFullHash& full_hash) override;
-  virtual bool FinishChunk() override;
+  bool WriteAddPrefix(int32 chunk_id, SBPrefix prefix) override;
+  bool WriteAddHash(int32 chunk_id, const SBFullHash& full_hash) override;
+  bool WriteSubPrefix(int32 chunk_id,
+                      int32 add_chunk_id,
+                      SBPrefix prefix) override;
+  bool WriteSubHash(int32 chunk_id,
+                    int32 add_chunk_id,
+                    const SBFullHash& full_hash) override;
+  bool FinishChunk() override;
 
-  virtual bool BeginUpdate() override;
-  virtual bool FinishUpdate(
+  bool BeginUpdate() override;
+  bool FinishUpdate(
       safe_browsing::PrefixSetBuilder* builder,
       std::vector<SBAddFullHash>* add_full_hashes_result) override;
-  virtual bool CancelUpdate() override;
+  bool CancelUpdate() override;
 
-  virtual void SetAddChunk(int32 chunk_id) override;
-  virtual bool CheckAddChunk(int32 chunk_id) override;
-  virtual void GetAddChunks(std::vector<int32>* out) override;
-  virtual void SetSubChunk(int32 chunk_id) override;
-  virtual bool CheckSubChunk(int32 chunk_id) override;
-  virtual void GetSubChunks(std::vector<int32>* out) override;
+  void SetAddChunk(int32 chunk_id) override;
+  bool CheckAddChunk(int32 chunk_id) override;
+  void GetAddChunks(std::vector<int32>* out) override;
+  void SetSubChunk(int32 chunk_id) override;
+  bool CheckSubChunk(int32 chunk_id) override;
+  void GetSubChunks(std::vector<int32>* out) override;
 
-  virtual void DeleteAddChunk(int32 chunk_id) override;
-  virtual void DeleteSubChunk(int32 chunk_id) override;
+  void DeleteAddChunk(int32 chunk_id) override;
+  void DeleteSubChunk(int32 chunk_id) override;
 
   // Verify |file_|'s checksum, calling the corruption callback if it
   // does not check out.  Empty input is considered valid.
-  virtual bool CheckValidity() override;
+  bool CheckValidity() override;
 
   // Returns the name of the temporary file used to buffer data for
   // |filename|.  Exported for unit tests.
diff --git a/chrome/browser/safe_browsing/safe_browsing_tab_observer.h b/chrome/browser/safe_browsing/safe_browsing_tab_observer.h
index b168540..c7201d9 100644
--- a/chrome/browser/safe_browsing/safe_browsing_tab_observer.h
+++ b/chrome/browser/safe_browsing/safe_browsing_tab_observer.h
@@ -21,7 +21,7 @@
 class SafeBrowsingTabObserver
     : public content::WebContentsUserData<SafeBrowsingTabObserver> {
  public:
-  virtual ~SafeBrowsingTabObserver();
+  ~SafeBrowsingTabObserver() override;
 
   // Forwards to detection host is client-side detection is enabled.
   bool DidPageReceiveSafeBrowsingMatch() const;
diff --git a/chrome/browser/safe_browsing/safe_browsing_test.cc b/chrome/browser/safe_browsing/safe_browsing_test.cc
index 21f6ec2..273a086 100644
--- a/chrome/browser/safe_browsing/safe_browsing_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_test.cc
@@ -112,7 +112,7 @@
   explicit FakeSafeBrowsingService(const std::string& url_prefix)
       : url_prefix_(url_prefix) {}
 
-  virtual SafeBrowsingProtocolConfig GetProtocolConfig() const override {
+  SafeBrowsingProtocolConfig GetProtocolConfig() const override {
     SafeBrowsingProtocolConfig config;
     config.url_prefix = url_prefix_;
     // Makes sure the auto update is not triggered. The tests will force the
@@ -126,7 +126,7 @@
   }
 
  private:
-  virtual ~FakeSafeBrowsingService() {}
+  ~FakeSafeBrowsingService() override {}
 
   std::string url_prefix_;
 
@@ -139,7 +139,7 @@
   explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix)
       : url_prefix_(url_prefix) {}
 
-  virtual SafeBrowsingService* CreateSafeBrowsingService() override {
+  SafeBrowsingService* CreateSafeBrowsingService() override {
     return new FakeSafeBrowsingService(url_prefix_);
   }
 
@@ -281,7 +281,7 @@
     SafeBrowsingService::RegisterFactory(NULL);
   }
 
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     // This test uses loopback. No need to use IPv6 especially it makes
     // local requests slow on Windows trybot when ipv6 local address [::1]
     // is not setup.
@@ -349,9 +349,9 @@
   }
 
   // Callbacks for SafeBrowsingDatabaseManager::Client.
-  virtual void OnCheckBrowseUrlResult(const GURL& url,
-                                      SBThreatType threat_type,
-                                      const std::string& metadata) override {
+  void OnCheckBrowseUrlResult(const GURL& url,
+                              SBThreatType threat_type,
+                              const std::string& metadata) override {
     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
     EXPECT_TRUE(safe_browsing_test_->is_checked_url_in_db());
     safe_browsing_test_->set_is_checked_url_safe(
@@ -453,7 +453,7 @@
   }
 
   // Callback for URLFetcher.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override {
+  void OnURLFetchComplete(const net::URLFetcher* source) override {
     source->GetResponseAsString(&response_data_);
     response_status_ = source->GetStatus().status();
     StopUILoop();
@@ -465,7 +465,7 @@
 
  private:
   friend class base::RefCountedThreadSafe<SafeBrowsingServerTestHelper>;
-  virtual ~SafeBrowsingServerTestHelper() {}
+  ~SafeBrowsingServerTestHelper() override {}
 
   // Stops UI loop after desired status is updated.
   void StopUILoop() {
diff --git a/chrome/browser/safe_browsing/sandboxed_zip_analyzer.h b/chrome/browser/safe_browsing/sandboxed_zip_analyzer.h
index e1cdfd7..7075b45 100644
--- a/chrome/browser/safe_browsing/sandboxed_zip_analyzer.h
+++ b/chrome/browser/safe_browsing/sandboxed_zip_analyzer.h
@@ -40,7 +40,7 @@
   void Start();
 
  private:
-  virtual ~SandboxedZipAnalyzer();
+  ~SandboxedZipAnalyzer() override;
 
   // Creates the sandboxed utility process and tells it to start analysis.
   // Runs on a worker thread.
@@ -48,7 +48,7 @@
 
   // content::UtilityProcessHostClient implementation.
   // These notifications run on the IO thread.
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
   // Notification that the utility process is running, and we can now get its
   // process handle.
diff --git a/chrome/browser/safe_browsing/two_phase_uploader.cc b/chrome/browser/safe_browsing/two_phase_uploader.cc
index bbc404fa2..ac79e41 100644
--- a/chrome/browser/safe_browsing/two_phase_uploader.cc
+++ b/chrome/browser/safe_browsing/two_phase_uploader.cc
@@ -33,16 +33,16 @@
                        const base::FilePath& file_path,
                        const ProgressCallback& progress_callback,
                        const FinishCallback& finish_callback);
-  virtual ~TwoPhaseUploaderImpl();
+  ~TwoPhaseUploaderImpl() override;
 
   // Begins the upload process.
-  virtual void Start() override;
+  void Start() override;
 
   // net::URLFetcherDelegate implementation:
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
-  virtual void OnURLFetchUploadProgress(const net::URLFetcher* source,
-                                        int64 current,
-                                        int64 total) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchUploadProgress(const net::URLFetcher* source,
+                                int64 current,
+                                int64 total) override;
 
  private:
   void UploadMetadata();
diff --git a/chrome/browser/search/hotword_service.cc b/chrome/browser/search/hotword_service.cc
index 4a6f2c9..b530ae6 100644
--- a/chrome/browser/search/hotword_service.cc
+++ b/chrome/browser/search/hotword_service.cc
@@ -194,17 +194,22 @@
   // This will be called during profile initialization which is a good time
   // to check the user's hotword state.
   HotwordEnabled enabled_state = UNSET;
-  if (profile_->GetPrefs()->HasPrefPath(prefs::kHotwordSearchEnabled)) {
-    if (profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled))
-      enabled_state = ENABLED;
-    else
-      enabled_state = DISABLED;
+  if (IsExperimentalHotwordingEnabled()) {
+    // Disable the old extension so it doesn't interfere with the new stuff.
+    DisableHotwordExtension(GetExtensionService(profile_));
   } else {
-    // If the preference has not been set the hotword extension should
-    // not be running. However, this should only be done if auto-install
-    // is enabled which is gated through the IsHotwordAllowed check.
-    if (IsHotwordAllowed())
-      DisableHotwordExtension(GetExtensionService(profile_));
+    if (profile_->GetPrefs()->HasPrefPath(prefs::kHotwordSearchEnabled)) {
+      if (profile_->GetPrefs()->GetBoolean(prefs::kHotwordSearchEnabled))
+        enabled_state = ENABLED;
+      else
+        enabled_state = DISABLED;
+    } else {
+      // If the preference has not been set the hotword extension should
+      // not be running. However, this should only be done if auto-install
+      // is enabled which is gated through the IsHotwordAllowed check.
+      if (IsHotwordAllowed())
+        DisableHotwordExtension(GetExtensionService(profile_));
+    }
   }
   UMA_HISTOGRAM_ENUMERATION("Hotword.Enabled", enabled_state,
                             NUM_HOTWORD_ENABLED_METRICS);
@@ -215,10 +220,6 @@
       base::Bind(&HotwordService::OnHotwordSearchEnabledChanged,
                  base::Unretained(this)));
 
-  registrar_.Add(this,
-                 chrome::NOTIFICATION_BROWSER_WINDOW_READY,
-                 content::NotificationService::AllSources());
-
   extensions::ExtensionSystem::Get(profile_)->ready().Post(
       FROM_HERE,
       base::Bind(base::IgnoreResult(
@@ -236,25 +237,6 @@
 HotwordService::~HotwordService() {
 }
 
-void HotwordService::Observe(int type,
-                             const content::NotificationSource& source,
-                             const content::NotificationDetails& details) {
-  if (type == chrome::NOTIFICATION_BROWSER_WINDOW_READY) {
-    // The microphone monitor must be initialized as the page is loading
-    // so that the state of the microphone is available when the page
-    // loads. The Ok Google Hotword setting will display an error if there
-    // is no microphone but this information will not be up-to-date unless
-    // the monitor had already been started. Furthermore, the pop up to
-    // opt in to hotwording won't be available if it thinks there is no
-    // microphone. There is no hard guarantee that the monitor will actually
-    // be up by the time it's needed, but this is the best we can do without
-    // starting it at start up which slows down start up too much.
-    // The content/media for microphone uses the same observer design and
-    // makes use of the same audio device monitor.
-    HotwordServiceFactory::GetInstance()->UpdateMicrophoneState();
-  }
-}
-
 void HotwordService::OnExtensionUninstalled(
     content::BrowserContext* browser_context,
     const extensions::Extension* extension,
@@ -417,10 +399,20 @@
   RecordErrorMetrics(error_message_);
 
   // Determine if the proper audio capabilities exist.
-  bool audio_capture_allowed =
-      profile_->GetPrefs()->GetBoolean(prefs::kAudioCaptureAllowed);
-  if (!audio_capture_allowed || !HotwordServiceFactory::IsMicrophoneAvailable())
-    error_message_ = IDS_HOTWORD_MICROPHONE_ERROR_MESSAGE;
+  // The first time this is called, it probably won't return in time, but that's
+  // why it won't be included in the error calculation (i.e., the call to
+  // IsAudioDeviceStateUpdated()). However, this use case is rare and typically
+  // the devices will be initialized by the time a user goes to settings.
+  bool audio_device_state_updated =
+      HotwordServiceFactory::IsAudioDeviceStateUpdated();
+  HotwordServiceFactory::GetInstance()->UpdateMicrophoneState();
+  if (audio_device_state_updated) {
+    bool audio_capture_allowed =
+        profile_->GetPrefs()->GetBoolean(prefs::kAudioCaptureAllowed);
+    if (!audio_capture_allowed ||
+        !HotwordServiceFactory::IsMicrophoneAvailable())
+      error_message_ = IDS_HOTWORD_MICROPHONE_ERROR_MESSAGE;
+  }
 
   return (error_message_ == 0) && IsHotwordAllowed();
 }
@@ -448,7 +440,7 @@
 
 void HotwordService::EnableHotwordExtension(
     ExtensionService* extension_service) {
-  if (extension_service)
+  if (extension_service && !IsExperimentalHotwordingEnabled())
     extension_service->EnableExtension(extension_misc::kHotwordExtensionId);
 }
 
diff --git a/chrome/browser/search/hotword_service.h b/chrome/browser/search/hotword_service.h
index 3a70003..79e22d9 100644
--- a/chrome/browser/search/hotword_service.h
+++ b/chrome/browser/search/hotword_service.h
@@ -32,8 +32,7 @@
 
 // Provides an interface for the Hotword component that does voice triggered
 // search.
-class HotwordService : public content::NotificationObserver,
-                       public extensions::ExtensionRegistryObserver,
+class HotwordService : public extensions::ExtensionRegistryObserver,
                        public KeyedService {
  public:
   // Returns true if the hotword supports the current system language.
@@ -45,11 +44,6 @@
   explicit HotwordService(Profile* profile);
   ~HotwordService() override;
 
-  // Overridden from content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
   // Overridden from ExtensionRegisterObserver:
   void OnExtensionInstalled(content::BrowserContext* browser_context,
                             const extensions::Extension* extension,
diff --git a/chrome/browser/search/hotword_service_factory.cc b/chrome/browser/search/hotword_service_factory.cc
index d8a0619..7d05057c 100644
--- a/chrome/browser/search/hotword_service_factory.cc
+++ b/chrome/browser/search/hotword_service_factory.cc
@@ -52,11 +52,17 @@
   return GetInstance()->microphone_available();
 }
 
+// static
+bool HotwordServiceFactory::IsAudioDeviceStateUpdated() {
+  return GetInstance()->audio_device_state_updated();
+}
+
 HotwordServiceFactory::HotwordServiceFactory()
     : BrowserContextKeyedServiceFactory(
         "HotwordService",
         BrowserContextDependencyManager::GetInstance()),
-      microphone_available_(false) {
+      microphone_available_(false),
+      audio_device_state_updated_(false) {
   // No dependencies.
 
   // Register with the device observer list to update the microphone
@@ -77,19 +83,13 @@
 void HotwordServiceFactory::OnUpdateAudioDevices(
     const content::MediaStreamDevices& devices) {
   microphone_available_ = !devices.empty();
+  audio_device_state_updated_ = true;
 }
 
 void HotwordServiceFactory::UpdateMicrophoneState() {
   // In order to trigger the monitor, just call getAudioCaptureDevices.
   content::MediaStreamDevices devices =
-      MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices();
-
-  // If the monitor had not previously been started, there may be 0 devices
-  // even if that is not accurate. However, we can update the microphone
-  // availability state now. Either the number of devices will be correct or
-  // we know that the call above will start the monitor and the microphone
-  // state will be updated very soon and call OnUpdateAudioDevices.
-  OnUpdateAudioDevices(devices);
+    MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices();
 }
 
 void HotwordServiceFactory::RegisterProfilePrefs(
diff --git a/chrome/browser/search/hotword_service_factory.h b/chrome/browser/search/hotword_service_factory.h
index 44b655d2..74665ec 100644
--- a/chrome/browser/search/hotword_service_factory.h
+++ b/chrome/browser/search/hotword_service_factory.h
@@ -35,6 +35,11 @@
   // is browser (not profile) specific, it resides in the factory.
   static bool IsMicrophoneAvailable();
 
+  // Returns whether the state of the audio devices has been updated.
+  // Essentially it indicates the validity of the return value from
+  // IsMicrophoneAvailable().
+  static bool IsAudioDeviceStateUpdated();
+
   // Overridden from MediaCaptureDevicesDispatcher::Observer
   void OnUpdateAudioDevices(
       const content::MediaStreamDevices& devices) override;
@@ -67,6 +72,13 @@
 
   bool microphone_available_;
 
+  // Indicates if the check for audio devices has been run such that it can be
+  // included in the error checking. Audio checking is not done immediately
+  // upon start up because of the negative impact on performance.
+  bool audio_device_state_updated_;
+
+  bool audio_device_state_updated() { return audio_device_state_updated_; }
+
   DISALLOW_COPY_AND_ASSIGN(HotwordServiceFactory);
 };
 
diff --git a/chrome/browser/services/gcm/fake_gcm_profile_service.cc b/chrome/browser/services/gcm/fake_gcm_profile_service.cc
index 4855b95..8169ded5 100644
--- a/chrome/browser/services/gcm/fake_gcm_profile_service.cc
+++ b/chrome/browser/services/gcm/fake_gcm_profile_service.cc
@@ -111,7 +111,10 @@
 }
 
 FakeGCMProfileService::FakeGCMProfileService(Profile* profile)
-    : collect_(false) {}
+    : collect_(false) {
+  static_cast<PushMessagingServiceImpl*>(push_messaging_service())
+      ->SetProfileForTesting(profile);
+}
 
 FakeGCMProfileService::~FakeGCMProfileService() {}
 
diff --git a/chrome/browser/services/gcm/push_messaging_browsertest.cc b/chrome/browser/services/gcm/push_messaging_browsertest.cc
new file mode 100644
index 0000000..46cd0cb
--- /dev/null
+++ b/chrome/browser/services/gcm/push_messaging_browsertest.cc
@@ -0,0 +1,168 @@
+// 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 <string>
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/message_loop/message_loop.h"
+#include "chrome/browser/infobars/infobar_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/services/gcm/fake_gcm_profile_service.h"
+#include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
+#include "chrome/browser/services/gcm/push_messaging_application_id.h"
+#include "chrome/browser/services/gcm/push_messaging_constants.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/infobars/core/confirm_infobar_delegate.h"
+#include "components/infobars/core/infobar.h"
+#include "components/infobars/core/infobar_manager.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+
+namespace gcm {
+
+namespace {
+// Responds to a confirm infobar by accepting or cancelling it. Responds to at
+// most one infobar.
+class InfoBarResponder : public infobars::InfoBarManager::Observer {
+ public:
+  InfoBarResponder(Browser* browser, bool accept)
+      : infobar_service_(InfoBarService::FromWebContents(
+            browser->tab_strip_model()->GetActiveWebContents())),
+        accept_(accept),
+        has_observed_(false) {
+    infobar_service_->AddObserver(this);
+  }
+
+  virtual ~InfoBarResponder() { infobar_service_->RemoveObserver(this); }
+
+  // infobars::InfoBarManager::Observer
+  virtual void OnInfoBarAdded(infobars::InfoBar* infobar) override {
+    if (has_observed_)
+      return;
+    has_observed_ = true;
+    ConfirmInfoBarDelegate* delegate =
+        infobar->delegate()->AsConfirmInfoBarDelegate();
+    DCHECK(delegate);
+
+    // Respond to the infobar asynchronously, like a person.
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(
+            &InfoBarResponder::Respond, base::Unretained(this), delegate));
+  }
+
+ private:
+  void Respond(ConfirmInfoBarDelegate* delegate) {
+    if (accept_) {
+      delegate->Accept();
+    } else {
+      delegate->Cancel();
+    }
+  }
+
+  InfoBarService* infobar_service_;
+  bool accept_;
+  bool has_observed_;
+};
+}  // namespace
+
+class PushMessagingBrowserTest : public InProcessBrowserTest {
+ public:
+  PushMessagingBrowserTest() : gcm_service_(nullptr) {}
+  virtual ~PushMessagingBrowserTest() {}
+
+  // InProcessBrowserTest:
+  virtual void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitch(
+        switches::kEnableExperimentalWebPlatformFeatures);
+
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+  }
+
+  // InProcessBrowserTest:
+  virtual void SetUp() override {
+    https_server_.reset(new net::SpawnedTestServer(
+        net::SpawnedTestServer::TYPE_HTTPS,
+        net::BaseTestServer::SSLOptions(
+            net::BaseTestServer::SSLOptions::CERT_OK),
+        base::FilePath(FILE_PATH_LITERAL("chrome/test/data/"))));
+    ASSERT_TRUE(https_server_->Start());
+
+    InProcessBrowserTest::SetUp();
+  }
+
+  // InProcessBrowserTest:
+  virtual void SetUpOnMainThread() override {
+    gcm_service_ = static_cast<FakeGCMProfileService*>(
+        GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+            browser()->profile(), &FakeGCMProfileService::Build));
+    gcm_service_->set_collect(true);
+
+    ui_test_utils::NavigateToURL(
+        browser(), https_server_->GetURL("files/push_messaging/test.html"));
+
+    InProcessBrowserTest::SetUpOnMainThread();
+  }
+
+  bool RunScript(const std::string& script, std::string* result) {
+    return content::ExecuteScriptAndExtractString(
+        browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
+        script,
+        result);
+  }
+
+  bool RegisterServiceWorker(std::string* result) {
+    return RunScript("registerServiceWorker()", result);
+  }
+
+  bool RegisterPush(std::string* result) {
+    return RunScript("registerPush('1234567890')", result);
+  }
+
+  net::SpawnedTestServer* https_server() const { return https_server_.get(); }
+
+  FakeGCMProfileService* gcm_service() const { return gcm_service_; }
+
+ private:
+  scoped_ptr<net::SpawnedTestServer> https_server_;
+  FakeGCMProfileService* gcm_service_;
+
+  DISALLOW_COPY_AND_ASSIGN(PushMessagingBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, RegisterSuccess) {
+  std::string register_worker_result;
+  ASSERT_TRUE(RegisterServiceWorker(&register_worker_result));
+  ASSERT_EQ("ok", register_worker_result);
+
+  InfoBarResponder accepting_responder(browser(), true);
+
+  std::string register_push_result;
+  ASSERT_TRUE(RegisterPush(&register_push_result));
+  EXPECT_EQ(std::string(kPushMessagingEndpoint) + " - 1", register_push_result);
+
+  PushMessagingApplicationId expected_id(https_server()->GetURL(""), 0L);
+  EXPECT_EQ(expected_id.ToString(), gcm_service()->last_registered_app_id());
+  EXPECT_EQ("1234567890", gcm_service()->last_registered_sender_ids()[0]);
+}
+
+IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, RegisterFailureNoPermission) {
+  std::string register_worker_result;
+  ASSERT_TRUE(RegisterServiceWorker(&register_worker_result));
+  ASSERT_EQ("ok", register_worker_result);
+
+  InfoBarResponder cancelling_responder(browser(), false);
+
+  std::string register_push_result;
+  ASSERT_TRUE(RegisterPush(&register_push_result));
+  EXPECT_EQ("AbortError - Registration failed - permission denied",
+            register_push_result);
+}
+
+}  // namespace gcm
diff --git a/chrome/browser/services/gcm/push_messaging_constants.cc b/chrome/browser/services/gcm/push_messaging_constants.cc
new file mode 100644
index 0000000..011bfa9
--- /dev/null
+++ b/chrome/browser/services/gcm/push_messaging_constants.cc
@@ -0,0 +1,11 @@
+// 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/services/gcm/push_messaging_constants.h"
+
+namespace gcm {
+
+const char kPushMessagingEndpoint[] = "https://android.googleapis.com/gcm/send";
+
+}  // namespace gcm
diff --git a/chrome/browser/services/gcm/push_messaging_constants.h b/chrome/browser/services/gcm/push_messaging_constants.h
new file mode 100644
index 0000000..3e0656a
--- /dev/null
+++ b/chrome/browser/services/gcm/push_messaging_constants.h
@@ -0,0 +1,14 @@
+// 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_SERVICES_GCM_PUSH_MESSAGING_CONSTANTS_H_
+#define CHROME_BROWSER_SERVICES_GCM_PUSH_MESSAGING_CONSTANTS_H_
+
+namespace gcm {
+
+extern const char kPushMessagingEndpoint[];
+
+}  // namespace gcm
+
+#endif  // CHROME_BROWSER_SERVICES_GCM_PUSH_MESSAGING_CONSTANTS_H_
diff --git a/chrome/browser/services/gcm/push_messaging_service_impl.cc b/chrome/browser/services/gcm/push_messaging_service_impl.cc
index ee49c0a..9d352eb7 100644
--- a/chrome/browser/services/gcm/push_messaging_service_impl.cc
+++ b/chrome/browser/services/gcm/push_messaging_service_impl.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/services/gcm/gcm_profile_service.h"
 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
 #include "chrome/browser/services/gcm/push_messaging_application_id.h"
+#include "chrome/browser/services/gcm/push_messaging_constants.h"
 #include "chrome/browser/services/gcm/push_messaging_permission_context.h"
 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory.h"
 #include "chrome/common/chrome_switches.h"
@@ -129,6 +130,10 @@
   }
 }
 
+void PushMessagingServiceImpl::SetProfileForTesting(Profile* profile) {
+  profile_ = profile;
+}
+
 void PushMessagingServiceImpl::DeliverMessageCallback(
     const PushMessagingApplicationId& application_id,
     const GCMClient::IncomingMessage& message,
@@ -233,7 +238,7 @@
     const content::PushMessagingService::RegisterCallback& callback,
     const std::string& registration_id,
     content::PushRegistrationStatus status) {
-  GURL endpoint = GURL("https://android.googleapis.com/gcm/send");
+  GURL endpoint = GURL(std::string(kPushMessagingEndpoint));
   callback.Run(endpoint, registration_id, status);
   if (status == content::PUSH_REGISTRATION_STATUS_SUCCESS) {
     // TODO(johnme): Make sure the pref doesn't get out of sync after crashes.
diff --git a/chrome/browser/services/gcm/push_messaging_service_impl.h b/chrome/browser/services/gcm/push_messaging_service_impl.h
index b38f377..5d74a73 100644
--- a/chrome/browser/services/gcm/push_messaging_service_impl.h
+++ b/chrome/browser/services/gcm/push_messaging_service_impl.h
@@ -58,6 +58,8 @@
       bool user_gesture,
       const content::PushMessagingService::RegisterCallback& callback) override;
 
+  void SetProfileForTesting(Profile* profile);
+
  private:
   void DeliverMessageCallback(const PushMessagingApplicationId& application_id,
                               const GCMClient::IncomingMessage& message,
diff --git a/chrome/browser/sessions/base_session_service.cc b/chrome/browser/sessions/base_session_service.cc
index cad08559..f85fc8f7 100644
--- a/chrome/browser/sessions/base_session_service.cc
+++ b/chrome/browser/sessions/base_session_service.cc
@@ -5,22 +5,11 @@
 #include "chrome/browser/sessions/base_session_service.h"
 
 #include "base/bind.h"
-#include "base/command_line.h"
 #include "base/pickle.h"
-#include "base/stl_util.h"
 #include "base/threading/thread.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sessions/base_session_service_delegate.h"
 #include "chrome/browser/sessions/session_backend.h"
 #include "chrome/browser/sessions/session_types.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/url_constants.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/navigation_entry.h"
-#include "content/public/common/referrer.h"
-
-using content::BrowserThread;
-using content::NavigationEntry;
 
 // BaseSessionService ---------------------------------------------------------
 
@@ -72,20 +61,16 @@
 // static
 const int BaseSessionService::max_persist_navigation_count = 6;
 
-BaseSessionService::BaseSessionService(SessionType type,
-                                       Profile* profile,
-                                       const base::FilePath& path)
-    : profile_(profile),
-      pending_reset_(false),
+BaseSessionService::BaseSessionService(
+    SessionType type,
+    const base::FilePath& path,
+    scoped_ptr<BaseSessionServiceDelegate> delegate)
+    : pending_reset_(false),
       commands_since_reset_(0),
-      sequence_token_(
-          content::BrowserThread::GetBlockingPool()->GetSequenceToken()),
+      delegate_(delegate.Pass()),
+      sequence_token_(delegate_->GetBlockingPool()->GetSequenceToken()),
       weak_factory_(this) {
-  if (profile) {
-    // We should never be created when incognito.
-    DCHECK(!profile->IsOffTheRecord());
-  }
-  backend_ = new SessionBackend(type, profile_ ? profile_->GetPath() : path);
+  backend_ = new SessionBackend(type, path);
   DCHECK(backend_.get());
 }
 
@@ -106,9 +91,8 @@
 }
 
 void BaseSessionService::StartSaveTimer() {
-  // Don't start a timer when testing (profile == NULL or
-  // MessageLoop::current() is NULL).
-  if (base::MessageLoop::current() && profile() &&
+  // Don't start a timer when testing.
+  if (delegate_->ShouldUseDelayedSave() && base::MessageLoop::current() &&
       !weak_factory_.HasWeakPtrs()) {
     base::MessageLoop::current()->PostDelayedTask(
         FROM_HERE,
@@ -265,11 +249,7 @@
 }
 
 bool BaseSessionService::ShouldTrackEntry(const GURL& url) {
-  // Blacklist chrome://quit and chrome://restart to avoid quit or restart
-  // loops.
-  return url.is_valid() && !(url.SchemeIs(content::kChromeUIScheme) &&
-                             (url.host() == chrome::kChromeUIQuitHost ||
-                              url.host() == chrome::kChromeUIRestartHost));
+  return url.is_valid() && delegate_->ShouldTrackEntry(url);
 }
 
 base::CancelableTaskTracker::TaskId
@@ -297,8 +277,7 @@
 void BaseSessionService::RunTaskOnBackendThread(
     const tracked_objects::Location& from_here,
     const base::Closure& task) {
-  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
+  base::SequencedWorkerPool* pool = delegate_->GetBlockingPool();
   if (!pool->IsShutdownInProgress()) {
     pool->PostSequencedWorkerTask(sequence_token_, from_here, task);
   } else {
diff --git a/chrome/browser/sessions/base_session_service.h b/chrome/browser/sessions/base_session_service.h
index 527ca40..3ce684cb 100644
--- a/chrome/browser/sessions/base_session_service.h
+++ b/chrome/browser/sessions/base_session_service.h
@@ -18,7 +18,7 @@
 #include "components/sessions/session_id.h"
 #include "url/gurl.h"
 
-class Profile;
+class BaseSessionServiceDelegate;
 class SessionBackend;
 class SessionCommand;
 
@@ -41,14 +41,10 @@
 
   // Creates a new BaseSessionService. After creation you need to invoke
   // Init.
-  // |type| gives the type of session service, |profile| the profile and
-  // |path| the path to save files to. If |profile| is non-NULL, |path| is
-  // ignored and instead the path comes from the profile.
+  // |type| gives the type of session service, |path| the path to save files to.
   BaseSessionService(SessionType type,
-                     Profile* profile,
-                     const base::FilePath& path);
-
-  Profile* profile() const { return profile_; }
+                     const base::FilePath& path,
+                     scoped_ptr<BaseSessionServiceDelegate> delegate);
 
   // Deletes the last session.
   void DeleteLastSession();
@@ -165,9 +161,6 @@
  private:
   friend class BetterSessionRestoreCrashTest;
 
-  // The profile. This may be null during testing.
-  Profile* profile_;
-
   // The backend.
   scoped_refptr<SessionBackend> backend_;
 
@@ -181,6 +174,8 @@
   // The number of commands sent to the backend before doing a reset.
   int commands_since_reset_;
 
+  scoped_ptr<BaseSessionServiceDelegate> delegate_;
+
   // A token to make sure that all tasks will be serialized.
   base::SequencedWorkerPool::SequenceToken sequence_token_;
 
diff --git a/chrome/browser/sessions/base_session_service_delegate.h b/chrome/browser/sessions/base_session_service_delegate.h
new file mode 100644
index 0000000..33658638
--- /dev/null
+++ b/chrome/browser/sessions/base_session_service_delegate.h
@@ -0,0 +1,35 @@
+// 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_SESSIONS_BASE_SESSION_SERVICE_DELEGATE_H_
+#define CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_DELEGATE_H_
+
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class SequencedWorkerPool;
+}
+
+class GURL;
+
+// The BaseSessionServiceDelegate decouples the BaseSessionService from
+// chrome/content dependencies.
+class BaseSessionServiceDelegate {
+ public:
+  BaseSessionServiceDelegate() {}
+  virtual ~BaseSessionServiceDelegate() {}
+
+  // Get the sequenced worker pool for running tasks on the backend thread as
+  // long as the system is not shutting down.
+  virtual base::SequencedWorkerPool* GetBlockingPool() = 0;
+
+  // Tests if a given URL should be tracked.
+  virtual bool ShouldTrackEntry(const GURL& url) = 0;
+
+  // Returns true if save operations can be performed as a delayed task - which
+  // is usually only used by unit tests.
+  virtual bool ShouldUseDelayedSave() = 0;
+};
+
+#endif  // CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_DELEGATE_H_
diff --git a/chrome/browser/sessions/base_session_service_delegate_impl.cc b/chrome/browser/sessions/base_session_service_delegate_impl.cc
new file mode 100644
index 0000000..972da4d6
--- /dev/null
+++ b/chrome/browser/sessions/base_session_service_delegate_impl.cc
@@ -0,0 +1,30 @@
+// 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/sessions/base_session_service_delegate_impl.h"
+
+#include "chrome/common/url_constants.h"
+#include "content/public/browser/browser_thread.h"
+#include "url/gurl.h"
+
+BaseSessionServiceDelegateImpl::BaseSessionServiceDelegateImpl(
+    bool should_use_delayed_save)
+      : should_use_delayed_save_(should_use_delayed_save) {}
+
+base::SequencedWorkerPool* BaseSessionServiceDelegateImpl::GetBlockingPool() {
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  return content::BrowserThread::GetBlockingPool();
+}
+
+bool BaseSessionServiceDelegateImpl::ShouldTrackEntry(const GURL& url) {
+  // Blacklist chrome://quit and chrome://restart to avoid quit or restart
+  // loops.
+  return !(url.SchemeIs(content::kChromeUIScheme) &&
+          (url.host() == chrome::kChromeUIQuitHost ||
+           url.host() == chrome::kChromeUIRestartHost));
+}
+
+bool BaseSessionServiceDelegateImpl::ShouldUseDelayedSave() {
+  return should_use_delayed_save_;
+}
diff --git a/chrome/browser/sessions/base_session_service_delegate_impl.h b/chrome/browser/sessions/base_session_service_delegate_impl.h
new file mode 100644
index 0000000..42eabbd
--- /dev/null
+++ b/chrome/browser/sessions/base_session_service_delegate_impl.h
@@ -0,0 +1,31 @@
+// 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_SESSIONS_BASE_SESSION_SERVICE_DELEGATE_IMPL_H_
+#define CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_DELEGATE_IMPL_H_
+
+#include "chrome/browser/sessions/base_session_service_delegate.h"
+
+class BaseSessionServiceDelegateImpl : public BaseSessionServiceDelegate {
+ public:
+  // If |use_delayed_save| is true, save operations can be performed as a
+  // delayed task. Generally |used_delayed_save| should be true, testing may
+  // supply false.
+  explicit BaseSessionServiceDelegateImpl(bool should_use_delayed_save);
+  ~BaseSessionServiceDelegateImpl() override {}
+
+  // BaseSessionServiceDelegate:
+  base::SequencedWorkerPool* GetBlockingPool() override;
+  bool ShouldTrackEntry(const GURL& url) override;
+  bool ShouldUseDelayedSave() override;
+
+ private:
+  // True if save operations can be performed as a delayed task. This can be
+  // disabled for unit tests.
+  const bool should_use_delayed_save_;
+
+  DISALLOW_COPY_AND_ASSIGN(BaseSessionServiceDelegateImpl);
+};
+
+#endif  // CHROME_BROWSER_SESSIONS_BASE_SESSION_SERVICE_DELEGATE_IMPL_H_
diff --git a/chrome/browser/sessions/persistent_tab_restore_service.cc b/chrome/browser/sessions/persistent_tab_restore_service.cc
index 766a3f0..f0be5620 100644
--- a/chrome/browser/sessions/persistent_tab_restore_service.cc
+++ b/chrome/browser/sessions/persistent_tab_restore_service.cc
@@ -19,6 +19,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/base_session_service.h"
+#include "chrome/browser/sessions/base_session_service_delegate_impl.h"
 #include "chrome/browser/sessions/session_command.h"
 #include "chrome/browser/sessions/session_service.h"
 #include "chrome/browser/sessions/session_service_factory.h"
@@ -212,6 +213,9 @@
                        std::vector<TabRestoreService::Entry*>* entries);
 
  private:
+  // The associated profile.
+  Profile* profile_;
+
   TabRestoreServiceHelper* tab_restore_service_helper_;
 
   // The number of entries to write.
@@ -235,12 +239,18 @@
 };
 
 PersistentTabRestoreService::Delegate::Delegate(Profile* profile)
-    : BaseSessionService(BaseSessionService::TAB_RESTORE, profile,
-                         base::FilePath()),
+    : BaseSessionService(
+        BaseSessionService::TAB_RESTORE,
+        profile->GetPath(),
+        scoped_ptr<BaseSessionServiceDelegate>(
+          new BaseSessionServiceDelegateImpl(true))),
+      profile_(profile),
       tab_restore_service_helper_(NULL),
       entries_to_write_(0),
       entries_written_(0),
       load_state_(NOT_LOADED) {
+  // We should never be created when incognito.
+  DCHECK(!profile->IsOffTheRecord());
 }
 
 PersistentTabRestoreService::Delegate::~Delegate() {}
@@ -335,9 +345,9 @@
   load_state_ = LOADING;
 
   SessionService* session_service =
-      SessionServiceFactory::GetForProfile(profile());
-  Profile::ExitType exit_type = profile()->GetLastSessionExitType();
-  if (!profile()->restored_last_session() && session_service &&
+      SessionServiceFactory::GetForProfile(profile_);
+  Profile::ExitType exit_type = profile_->GetLastSessionExitType();
+  if (!profile_->restored_last_session() && session_service &&
       (exit_type == Profile::EXIT_CRASHED ||
        exit_type == Profile::EXIT_SESSION_ENDED)) {
     // The previous session crashed and wasn't restored, or was a forced
diff --git a/chrome/browser/sessions/session_restore_android.cc b/chrome/browser/sessions/session_restore_android.cc
index 15af2e9..dcf5ac3f 100644
--- a/chrome/browser/sessions/session_restore_android.cc
+++ b/chrome/browser/sessions/session_restore_android.cc
@@ -6,6 +6,7 @@
 
 #include <vector>
 
+#include "base/memory/scoped_vector.h"
 #include "chrome/browser/android/tab_android.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_types.h"
@@ -13,7 +14,9 @@
 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
+#include "components/sessions/content/content_serialized_navigation_builder.h"
 #include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
 
 // The android implementation does not do anything "foreign session" specific.
@@ -28,9 +31,12 @@
   Profile* profile = Profile::FromBrowserContext(context);
   TabModel* tab_model = TabModelList::GetTabModelForWebContents(web_contents);
   DCHECK(tab_model);
-  std::vector<content::NavigationEntry*> entries =
-      sessions::SerializedNavigationEntry::ToNavigationEntries(
+  ScopedVector<content::NavigationEntry> scoped_entries =
+      sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
           session_tab.navigations, profile);
+  // NavigationController::Restore() expects to take ownership of the entries.
+  std::vector<content::NavigationEntry*> entries;
+  scoped_entries.release(&entries);
   content::WebContents* new_web_contents = content::WebContents::Create(
       content::WebContents::CreateParams(context));
   int selected_index = session_tab.normalized_navigation_index();
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index 0a0ac5a..8094054 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -24,6 +24,7 @@
 #include "chrome/browser/prefs/session_startup_pref.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/sessions/base_session_service_delegate_impl.h"
 #include "chrome/browser/sessions/session_backend.h"
 #include "chrome/browser/sessions/session_command.h"
 #include "chrome/browser/sessions/session_data_deleter.h"
@@ -37,6 +38,7 @@
 #include "chrome/browser/ui/host_desktop.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "components/sessions/content/content_serialized_navigation_builder.h"
 #include "components/startup_metric_utils/startup_metric_utils.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
@@ -53,6 +55,7 @@
 using base::Time;
 using content::NavigationEntry;
 using content::WebContents;
+using sessions::ContentSerializedNavigationBuilder;
 using sessions::SerializedNavigationEntry;
 
 // Identifier for commands written to file.
@@ -60,10 +63,9 @@
 // OBSOLETE Superseded by kCommandSetWindowBounds3.
 // static const SessionCommand::id_type kCommandSetWindowBounds = 1;
 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2;
-// Original kCommandTabClosed/kCommandWindowClosed. See comment in
-// MigrateClosedPayload for details on why they were replaced.
-static const SessionCommand::id_type kCommandTabClosedObsolete = 3;
-static const SessionCommand::id_type kCommandWindowClosedObsolete = 4;
+// OBSOLETE Superseded kCommandTabClosed/kCommandWindowClosed commands.
+// static const SessionCommand::id_type kCommandTabClosedObsolete = 3;
+// static const SessionCommand::id_type kCommandWindowClosedObsolete = 4;
 static const SessionCommand::id_type
     kCommandTabNavigationPathPrunedFromBack = 5;
 static const SessionCommand::id_type kCommandUpdateTabNavigation = 6;
@@ -198,37 +200,17 @@
   return ui::SHOW_STATE_NORMAL;
 }
 
-// Migrates a |ClosedPayload|, returning true on success (migration was
-// necessary and happened), or false (migration was not necessary or was not
-// successful).
-bool MigrateClosedPayload(const SessionCommand& command,
-                          ClosedPayload* payload) {
-#if defined(OS_CHROMEOS)
-  // Pre M17 versions of chromeos were 32bit. Post M17 is 64 bit. Apparently the
-  // 32 bit versions of chrome on pre M17 resulted in a sizeof 12 for the
-  // ClosedPayload, where as post M17 64-bit gives a sizeof 16 (presumably the
-  // struct is padded).
-  if ((command.id() == kCommandWindowClosedObsolete ||
-       command.id() == kCommandTabClosedObsolete) &&
-      command.size() == 12 && sizeof(payload->id) == 4 &&
-      sizeof(payload->close_time) == 8) {
-    memcpy(&payload->id, command.contents(), 4);
-    memcpy(&payload->close_time, command.contents() + 4, 8);
-    return true;
-  } else {
-    return false;
-  }
-#else
-  return false;
-#endif
-}
-
 }  // namespace
 
 // SessionService -------------------------------------------------------------
 
 SessionService::SessionService(Profile* profile)
-    : BaseSessionService(SESSION_RESTORE, profile, base::FilePath()),
+    : BaseSessionService(
+        SESSION_RESTORE,
+        profile->GetPath(),
+        scoped_ptr<BaseSessionServiceDelegate>(
+            new BaseSessionServiceDelegateImpl(true))),
+      profile_(profile),
       has_open_trackable_browsers_(false),
       move_on_new_browser_(false),
       save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)),
@@ -236,11 +218,18 @@
       save_delay_in_hrs_(base::TimeDelta::FromHours(8)),
       force_browser_not_alive_with_no_windows_(false),
       weak_factory_(this) {
+  // We should never be created when incognito.
+  DCHECK(!profile->IsOffTheRecord());
   Init();
 }
 
 SessionService::SessionService(const base::FilePath& save_path)
-    : BaseSessionService(SESSION_RESTORE, NULL, save_path),
+    : BaseSessionService(
+        SESSION_RESTORE,
+        save_path,
+        scoped_ptr<BaseSessionServiceDelegate>(
+            new BaseSessionServiceDelegateImpl(false))),
+      profile_(NULL),
       has_open_trackable_browsers_(false),
       move_on_new_browser_(false),
       save_delay_in_millis_(base::TimeDelta::FromMilliseconds(2500)),
@@ -695,7 +684,7 @@
         return;
       content::Details<content::EntryChangedDetails> changed(details);
       const SerializedNavigationEntry navigation =
-          SerializedNavigationEntry::FromNavigationEntry(
+          ContentSerializedNavigationBuilder::FromNavigationEntry(
               changed->index, *changed->changed_entry);
       UpdateTabNavigation(session_tab_helper->window_id(),
                           session_tab_helper->session_id(),
@@ -718,7 +707,7 @@
           session_tab_helper->session_id(),
           current_entry_index);
       const SerializedNavigationEntry navigation =
-          SerializedNavigationEntry::FromNavigationEntry(
+          ContentSerializedNavigationBuilder::FromNavigationEntry(
               current_entry_index,
               *web_contents->GetController().GetEntryAtIndex(
                   current_entry_index));
@@ -1143,18 +1132,14 @@
         break;
       }
 
-      case kCommandTabClosedObsolete:
-      case kCommandWindowClosedObsolete:
       case kCommandTabClosed:
       case kCommandWindowClosed: {
         ClosedPayload payload;
-        if (!command->GetPayload(&payload, sizeof(payload)) &&
-            !MigrateClosedPayload(*command, &payload)) {
+        if (!command->GetPayload(&payload, sizeof(payload))) {
           VLOG(1) << "Failed reading command " << command->id();
           return true;
         }
-        if (command->id() == kCommandTabClosed ||
-            command->id() == kCommandTabClosedObsolete) {
+        if (command->id() == kCommandTabClosed) {
           delete GetTab(payload.id, tabs);
           tabs->erase(payload.id);
         } else {
@@ -1382,7 +1367,7 @@
     DCHECK(entry);
     if (ShouldTrackEntry(entry->GetVirtualURL())) {
       const SerializedNavigationEntry navigation =
-          SerializedNavigationEntry::FromNavigationEntry(i, *entry);
+          ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry);
       commands->push_back(
           CreateUpdateTabNavigationCommand(
               kCommandUpdateTabNavigation, session_id.id(), navigation));
diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h
index d2500fa..d602669e 100644
--- a/chrome/browser/sessions/session_service.h
+++ b/chrome/browser/sessions/session_service.h
@@ -74,6 +74,9 @@
 
   ~SessionService() override;
 
+  // This may be NULL during testing.
+  Profile* profile() const { return profile_; }
+
   // Returns true if a new window opening should really be treated like the
   // start of a session (with potential session restore, startup URLs, etc.).
   // In particular, this is true if there are no tabbed browsers running
@@ -439,6 +442,9 @@
   static WindowType WindowTypeForBrowserType(Browser::Type type);
   static Browser::Type BrowserTypeForWindowType(WindowType type);
 
+  // The profile. This may be null during testing.
+  Profile* profile_;
+
   content::NotificationRegistrar registrar_;
 
   // Maps from session tab id to the range of navigation entries that has
diff --git a/chrome/browser/sessions/session_service_unittest.cc b/chrome/browser/sessions/session_service_unittest.cc
index 21a99f4..64f6fd58 100644
--- a/chrome/browser/sessions/session_service_unittest.cc
+++ b/chrome/browser/sessions/session_service_unittest.cc
@@ -771,7 +771,8 @@
   SerializedNavigationEntry nav1 =
       SerializedNavigationEntryTestHelper::CreateNavigation(
           "http://google.com", "title");
-  SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav1);
+  SerializedNavigationEntryTestHelper::SetEncodedPageState(
+      page_state.ToEncodedData(), &nav1);
   SerializedNavigationEntryTestHelper::SetHasPostData(true, &nav1);
 
   // Create a TabNavigation containing page_state and representing a normal
@@ -779,7 +780,8 @@
   SerializedNavigationEntry nav2 =
       SerializedNavigationEntryTestHelper::CreateNavigation(
           "http://google.com/nopost", "title");
-  SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav2);
+  SerializedNavigationEntryTestHelper::SetEncodedPageState(
+      page_state.ToEncodedData(), &nav2);
   nav2.set_index(1);
 
   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
@@ -810,7 +812,8 @@
   SerializedNavigationEntry nav1 =
       SerializedNavigationEntryTestHelper::CreateNavigation(
           "http://google.com", "title");
-  SerializedNavigationEntryTestHelper::SetPageState(page_state, &nav1);
+  SerializedNavigationEntryTestHelper::SetEncodedPageState(
+      page_state.ToEncodedData(), &nav1);
   SerializedNavigationEntryTestHelper::SetHasPostData(true, &nav1);
   helper_.PrepareTabInWindow(window_id, tab_id, 0, true);
   UpdateNavigation(window_id, tab_id, nav1, true);
@@ -826,35 +829,6 @@
             windows[0]->tabs[0]->navigations[0].encoded_page_state());
 }
 
-// This test is only applicable to chromeos.
-#if defined(OS_CHROMEOS)
-// Verifies migration of tab/window closed works.
-TEST_F(SessionServiceTest, CanOpenV1TabClosed) {
-  base::FilePath v1_file_path;
-  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &v1_file_path));
-  // v1_session_file contains a tab closed command with the original id. The
-  // file was generated from ClosingTabStaysClosed. If we successfully processed
-  // the file we'll have one tab.
-  v1_file_path =
-      v1_file_path.AppendASCII("sessions").AppendASCII("v1_session_file");
-  base::FilePath dest_file_path(path_);
-  dest_file_path = dest_file_path.AppendASCII("Current Session");
-
-  // Forces closing the file.
-  helper_.SetService(NULL);
-
-  ASSERT_TRUE(base::CopyFile(v1_file_path, dest_file_path));
-
-  SessionService* session_service = new SessionService(path_);
-  helper_.SetService(session_service);
-  ScopedVector<SessionWindow> windows;
-  SessionID::id_type active_window_id = 0;
-  helper_.ReadWindows(&(windows.get()), &active_window_id);
-  ASSERT_EQ(1u, windows.size());
-  EXPECT_EQ(1u, windows[0]->tabs.size());
-}
-#endif  // defined(OS_CHROMEOS)
-
 TEST_F(SessionServiceTest, ReplacePendingNavigation) {
   const std::string base_url("http://google.com/");
   SessionID tab_id;
diff --git a/chrome/browser/sessions/tab_restore_service_helper.cc b/chrome/browser/sessions/tab_restore_service_helper.cc
index b5ec258..9a9ca026 100644
--- a/chrome/browser/sessions/tab_restore_service_helper.cc
+++ b/chrome/browser/sessions/tab_restore_service_helper.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
 #include "chrome/browser/sessions/tab_restore_service_observer.h"
 #include "chrome/common/url_constants.h"
+#include "components/sessions/content/content_serialized_navigation_builder.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/session_storage_namespace.h"
@@ -413,7 +414,8 @@
     NavigationEntry* entry = (i == pending_index) ?
         controller->GetPendingEntry() : controller->GetEntryAtIndex(i);
     tab->navigations[i] =
-        sessions::SerializedNavigationEntry::FromNavigationEntry(i, *entry);
+        sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
+            i, *entry);
   }
   tab->timestamp = TimeNow();
   tab->current_navigation_index = controller->GetCurrentEntryIndex();
diff --git a/chrome/browser/signin/about_signin_internals_factory.h b/chrome/browser/signin/about_signin_internals_factory.h
index 457adb4..bc60fba 100644
--- a/chrome/browser/signin/about_signin_internals_factory.h
+++ b/chrome/browser/signin/about_signin_internals_factory.h
@@ -23,17 +23,17 @@
   static AboutSigninInternalsFactory* GetInstance();
 
   // Implementation of BrowserContextKeyedServiceFactory.
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
 
  private:
   friend struct DefaultSingletonTraits<AboutSigninInternalsFactory>;
 
   AboutSigninInternalsFactory();
-  virtual ~AboutSigninInternalsFactory();
+  ~AboutSigninInternalsFactory() override;
 
   // BrowserContextKeyedServiceFactory
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
 };
 
diff --git a/chrome/browser/signin/account_reconcilor_factory.h b/chrome/browser/signin/account_reconcilor_factory.h
index 733b6fa6..4c2581b 100644
--- a/chrome/browser/signin/account_reconcilor_factory.h
+++ b/chrome/browser/signin/account_reconcilor_factory.h
@@ -28,12 +28,12 @@
   friend struct DefaultSingletonTraits<AccountReconcilorFactory>;
 
   AccountReconcilorFactory();
-  virtual ~AccountReconcilorFactory();
+  ~AccountReconcilorFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
 };
 
diff --git a/chrome/browser/signin/account_tracker_service_factory.h b/chrome/browser/signin/account_tracker_service_factory.h
index cbb3967..f4ce4e2 100644
--- a/chrome/browser/signin/account_tracker_service_factory.h
+++ b/chrome/browser/signin/account_tracker_service_factory.h
@@ -30,12 +30,12 @@
   friend struct DefaultSingletonTraits<AccountTrackerServiceFactory>;
 
   AccountTrackerServiceFactory();
-  virtual ~AccountTrackerServiceFactory();
+  ~AccountTrackerServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory implementation.
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
 
   DISALLOW_COPY_AND_ASSIGN(AccountTrackerServiceFactory);
diff --git a/chrome/browser/signin/chrome_signin_client.h b/chrome/browser/signin/chrome_signin_client.h
index 209a62c..c970f3bd 100644
--- a/chrome/browser/signin/chrome_signin_client.h
+++ b/chrome/browser/signin/chrome_signin_client.h
@@ -20,7 +20,7 @@
                            public content::RenderProcessHostObserver {
  public:
   explicit ChromeSigninClient(Profile* profile);
-  virtual ~ChromeSigninClient();
+  ~ChromeSigninClient() override;
 
   // Utility methods.
   static bool ProfileAllowsSigninCookies(Profile* profile);
@@ -34,40 +34,39 @@
   // N.B. This is the id returned by RenderProcessHost::GetID().
   // TODO(guohui): Eliminate these APIs once the web-based signin flow is
   // replaced by a native flow. crbug.com/347247
-  virtual void SetSigninProcess(int host_id) override;
-  virtual void ClearSigninProcess() override;
-  virtual bool IsSigninProcess(int host_id) const override;
-  virtual bool HasSigninProcess() const override;
+  void SetSigninProcess(int host_id) override;
+  void ClearSigninProcess() override;
+  bool IsSigninProcess(int host_id) const override;
+  bool HasSigninProcess() const override;
 
   // content::RenderProcessHostObserver implementation.
-  virtual void RenderProcessHostDestroyed(content::RenderProcessHost* host)
-      override;
+  void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
 
   // SigninClient implementation.
-  virtual PrefService* GetPrefs() override;
-  virtual scoped_refptr<TokenWebData> GetDatabase() override;
-  virtual bool CanRevokeCredentials() override;
-  virtual std::string GetSigninScopedDeviceId() override;
-  virtual void OnSignedOut() override;
-  virtual net::URLRequestContextGetter* GetURLRequestContext() override;
-  virtual bool ShouldMergeSigninCredentialsIntoCookieJar() override;
-  virtual bool IsFirstRun() const override;
-  virtual base::Time GetInstallDate() override;
+  PrefService* GetPrefs() override;
+  scoped_refptr<TokenWebData> GetDatabase() override;
+  bool CanRevokeCredentials() override;
+  std::string GetSigninScopedDeviceId() override;
+  void OnSignedOut() override;
+  net::URLRequestContextGetter* GetURLRequestContext() override;
+  bool ShouldMergeSigninCredentialsIntoCookieJar() override;
+  bool IsFirstRun() const override;
+  base::Time GetInstallDate() override;
 
   // Returns a string describing the chrome version environment. Version format:
   // <Build Info> <OS> <Version number> (<Last change>)<channel or "-devel">
   // If version information is unavailable, returns "invalid."
-  virtual std::string GetProductVersion() override;
-  virtual scoped_ptr<CookieChangedCallbackList::Subscription>
-      AddCookieChangedCallback(const CookieChangedCallback& callback) override;
-  virtual void GoogleSigninSucceeded(const std::string& account_id,
-                                     const std::string& username,
-                                     const std::string& password) override;
+  std::string GetProductVersion() override;
+  scoped_ptr<CookieChangedCallbackList::Subscription> AddCookieChangedCallback(
+      const CookieChangedCallback& callback) override;
+  void GoogleSigninSucceeded(const std::string& account_id,
+                             const std::string& username,
+                             const std::string& password) override;
 
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override;
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
 
  private:
   void RegisterForCookieChangedNotification();
diff --git a/chrome/browser/signin/chrome_signin_client_factory.h b/chrome/browser/signin/chrome_signin_client_factory.h
index bfdac87..05509a6 100644
--- a/chrome/browser/signin/chrome_signin_client_factory.h
+++ b/chrome/browser/signin/chrome_signin_client_factory.h
@@ -27,10 +27,10 @@
   friend struct DefaultSingletonTraits<ChromeSigninClientFactory>;
 
   ChromeSigninClientFactory();
-  virtual ~ChromeSigninClientFactory();
+  ~ChromeSigninClientFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
 };
 
diff --git a/chrome/browser/signin/easy_unlock_auth_attempt.cc b/chrome/browser/signin/easy_unlock_auth_attempt.cc
index 9a1842c..63920da 100644
--- a/chrome/browser/signin/easy_unlock_auth_attempt.cc
+++ b/chrome/browser/signin/easy_unlock_auth_attempt.cc
@@ -18,9 +18,6 @@
 
 namespace {
 
-// Fake secret used to force invalid login.
-const char kStubSecret[] = "\xFF\x00";
-
 // Decrypts the secret that should be used to login from |wrapped_secret| using
 // raw AES key |raw_key|.
 // In a case of error, an empty string is returned.
@@ -133,12 +130,6 @@
 
   std::string unwrapped_secret = UnwrapSecret(wrapped_secret, raw_session_key);
 
-  // If secret is not set, set it to an arbitrary value, otherwise there will
-  // be no authenitcation attempt and the ui will get stuck.
-  // TODO(tbarzic): Find a better way to handle this case.
-  if (unwrapped_secret.empty())
-    unwrapped_secret = kStubSecret;
-
   std::string key_label;
 #if defined(OS_CHROMEOS)
   key_label = chromeos::EasyUnlockKeyManager::GetKeyLabel(0u);
diff --git a/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc b/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
index 0b5226f..c1a7ba46 100644
--- a/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
+++ b/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
@@ -99,6 +99,14 @@
   return state_ != STATE_INACTIVE;
 }
 
+bool EasyUnlockScreenlockStateHandler::InStateValidOnRemoteAuthFailure() const {
+  // Note that NO_PHONE is not valid in this case because the phone may close
+  // the connection if the auth challenge sent to it is invalid. This case
+  // should be handled as authentication failure.
+  return state_ == EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH ||
+         state_ == EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED;
+}
+
 void EasyUnlockScreenlockStateHandler::ChangeState(State new_state) {
   if (state_ == new_state)
     return;
@@ -134,6 +142,12 @@
 
   UpdateTooltipOptions(is_trial_run_, &icon_options);
 
+  // For states without tooltips, we still need to set an accessibility label.
+  if (state_ == EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING) {
+    icon_options.SetAriaLabel(
+        l10n_util::GetStringUTF16(IDS_SMART_LOCK_SPINNER_ACCESSIBILITY_LABEL));
+  }
+
   screenlock_bridge_->lock_handler()->ShowUserPodCustomIcon(user_email_,
                                                             icon_options);
 }
@@ -143,6 +157,9 @@
   if (hardlock_state_ == new_state)
     return;
 
+  if (new_state == LOGIN_FAILED && hardlock_state_ != NO_HARDLOCK)
+    return;
+
   hardlock_state_ = new_state;
 
   // If hardlock_state_ was set to NO_HARDLOCK, this means the screen is about
@@ -171,6 +188,8 @@
 }
 
 void EasyUnlockScreenlockStateHandler::OnScreenDidUnlock() {
+  if (hardlock_state_ == LOGIN_FAILED)
+    hardlock_state_ = NO_HARDLOCK;
   hardlock_ui_shown_ = false;
   is_trial_run_ = false;
 }
@@ -210,7 +229,11 @@
     return;
 
   ScreenlockBridge::UserPodCustomIconOptions icon_options;
-  icon_options.SetIcon(ScreenlockBridge::USER_POD_CUSTOM_ICON_HARDLOCKED);
+  if (hardlock_state_ == LOGIN_FAILED) {
+    icon_options.SetIcon(ScreenlockBridge::USER_POD_CUSTOM_ICON_LOCKED);
+  } else {
+    icon_options.SetIcon(ScreenlockBridge::USER_POD_CUSTOM_ICON_HARDLOCKED);
+  }
 
   // TODO(tbarzic): Remove this condition for M-40.
   if (IsLocaleEnUS()) {
@@ -221,6 +244,9 @@
     } else if (hardlock_state_ == PAIRING_CHANGED) {
       tooltip = l10n_util::GetStringUTF16(
           IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_HARDLOCK_PAIRING_CHANGED);
+    } else if (hardlock_state_ == LOGIN_FAILED) {
+      tooltip = l10n_util::GetStringUTF16(
+          IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_LOGIN_FAILURE);
     } else {
       LOG(ERROR) << "Unknown hardlock state " << hardlock_state_;
     }
diff --git a/chrome/browser/signin/easy_unlock_screenlock_state_handler.h b/chrome/browser/signin/easy_unlock_screenlock_state_handler.h
index a86af96..9ae6b6b 100644
--- a/chrome/browser/signin/easy_unlock_screenlock_state_handler.h
+++ b/chrome/browser/signin/easy_unlock_screenlock_state_handler.h
@@ -50,7 +50,9 @@
     NO_HARDLOCK = 0,           // Hard lock is not enforced. This is default.
     USER_HARDLOCK = 1 << 0,    // Hard lock is requested by user.
     PAIRING_CHANGED = 1 << 1,  // Hard lock because pairing data is changed.
-    NO_PAIRING = 1 << 2        // Hard lock because there is no pairing data.
+    NO_PAIRING = 1 << 2,       // Hard lock because there is no pairing data.
+    LOGIN_FAILED = 1 << 3      // Transient hard lock caused by login attempt
+                               // failure. Reset when screen is unlocked.
   };
 
   // |user_email|: The email for the user associated with the profile to which
@@ -61,11 +63,16 @@
   EasyUnlockScreenlockStateHandler(const std::string& user_email,
                                    HardlockState initial_hardlock_state,
                                    ScreenlockBridge* screenlock_bridge);
-  virtual ~EasyUnlockScreenlockStateHandler();
+  ~EasyUnlockScreenlockStateHandler() override;
 
   // Returns true if handler is not in INACTIVE state.
   bool IsActive() const;
 
+  // Whether the handler is in state that is allowed just after auth failure
+  // (i.e. the state that would cause auth failure rather than one caused by an
+  // auth failure).
+  bool InStateValidOnRemoteAuthFailure() const;
+
   // Changes internal state to |new_state| and updates the user's screenlock
   // accordingly.
   void ChangeState(State new_state);
@@ -79,11 +86,13 @@
   // Marks the current screenlock state as the one for trial Easy Unlock run.
   void SetTrialRun();
 
+  State state() const { return state_; }
+
  private:
   // ScreenlockBridge::Observer:
-  virtual void OnScreenDidLock() override;
-  virtual void OnScreenDidUnlock() override;
-  virtual void OnFocusedUserChanged(const std::string& user_id) override;
+  void OnScreenDidLock() override;
+  void OnScreenDidUnlock() override;
+  void OnFocusedUserChanged(const std::string& user_id) override;
 
   // Forces refresh of the Easy Unlock screenlock UI.
   void RefreshScreenlockState();
diff --git a/chrome/browser/signin/easy_unlock_screenlock_state_handler_unittest.cc b/chrome/browser/signin/easy_unlock_screenlock_state_handler_unittest.cc
index cfca4d62..a6106ff 100644
--- a/chrome/browser/signin/easy_unlock_screenlock_state_handler_unittest.cc
+++ b/chrome/browser/signin/easy_unlock_screenlock_state_handler_unittest.cc
@@ -43,14 +43,14 @@
         show_icon_count_(0u),
         auth_type_(OFFLINE_PASSWORD) {
   }
-  virtual ~TestLockHandler() {}
+  ~TestLockHandler() override {}
 
   // ScreenlockBridge::LockHandler implementation:
-  virtual void ShowBannerMessage(const base::string16& message) override {
+  void ShowBannerMessage(const base::string16& message) override {
     ASSERT_FALSE(true) << "Should not be reached.";
   }
 
-  virtual void ShowUserPodCustomIcon(
+  void ShowUserPodCustomIcon(
       const std::string& user_email,
       const ScreenlockBridge::UserPodCustomIconOptions& icon) override {
     ASSERT_EQ(user_email_, user_email);
@@ -59,18 +59,18 @@
     ValidateCustomIcon();
   }
 
-  virtual void HideUserPodCustomIcon(const std::string& user_email) override {
+  void HideUserPodCustomIcon(const std::string& user_email) override {
     ASSERT_EQ(user_email_, user_email);
     last_custom_icon_.reset();
   }
 
-  virtual void EnableInput() override {
+  void EnableInput() override {
     ASSERT_FALSE(true) << "Should not be reached.";
   }
 
-  virtual void SetAuthType(const std::string& user_email,
-                           AuthType auth_type,
-                           const base::string16& auth_value) override {
+  void SetAuthType(const std::string& user_email,
+                   AuthType auth_type,
+                   const base::string16& auth_value) override {
     ASSERT_EQ(user_email_, user_email);
     // Generally, this is allowed, but EasyUnlockScreenlockStateHandler should
     // avoid resetting the same auth type.
@@ -80,18 +80,18 @@
     auth_value_ = auth_value;
   }
 
-  virtual AuthType GetAuthType(const std::string& user_email) const override {
+  AuthType GetAuthType(const std::string& user_email) const override {
     EXPECT_EQ(user_email_, user_email);
     return auth_type_;
   }
 
-  virtual void Unlock(const std::string& user_email) override {
+  void Unlock(const std::string& user_email) override {
     ASSERT_FALSE(true) << "Should not be reached.";
   }
 
-  virtual void AttemptEasySignin(const std::string& user_email,
-                                 const std::string& secret,
-                                 const std::string& key_label) override {
+  void AttemptEasySignin(const std::string& user_email,
+                         const std::string& secret,
+                         const std::string& key_label) override {
     ASSERT_FALSE(true) << "Should not be reached.";
   }
 
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc
index ad20dde..cb498dde 100644
--- a/chrome/browser/signin/easy_unlock_service.cc
+++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -104,7 +104,7 @@
         weak_ptr_factory_(this) {
   }
 
-  virtual ~BluetoothDetector() {
+  ~BluetoothDetector() override {
     if (adapter_.get())
       adapter_->RemoveObserver(this);
   }
@@ -121,8 +121,8 @@
   bool IsPresent() const { return adapter_.get() && adapter_->IsPresent(); }
 
   // device::BluetoothAdapter::Observer:
-  virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
-                                     bool present) override {
+  void AdapterPresentChanged(device::BluetoothAdapter* adapter,
+                             bool present) override {
     service_->OnBluetoothAdapterPresentChanged();
   }
 
@@ -312,8 +312,13 @@
 
   handler->ChangeState(state);
 
-  if (state != EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED)
+  if (state != EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED &&
+      auth_attempt_.get()) {
     auth_attempt_.reset();
+
+    if (!handler->InStateValidOnRemoteAuthFailure())
+      HandleAuthFailure(GetUserEmail());
+  }
   return true;
 }
 
@@ -328,18 +333,41 @@
 }
 
 void EasyUnlockService::FinalizeUnlock(bool success) {
-  if (auth_attempt_)
-    auth_attempt_->FinalizeUnlock(GetUserEmail(), success);
+  if (!auth_attempt_.get())
+    return;
+
+  auth_attempt_->FinalizeUnlock(GetUserEmail(), success);
   auth_attempt_.reset();
+
+  // Make sure that the lock screen is updated on failure.
+  if (!success)
+    HandleAuthFailure(GetUserEmail());
 }
 
 void EasyUnlockService::FinalizeSignin(const std::string& key) {
-  if (!auth_attempt_)
+  if (!auth_attempt_.get())
     return;
   std::string wrapped_secret = GetWrappedSecret();
   if (!wrapped_secret.empty())
     auth_attempt_->FinalizeSignin(GetUserEmail(), wrapped_secret, key);
   auth_attempt_.reset();
+
+  // Processing empty key is equivalent to auth cancellation. In this case the
+  // signin request will not actually be processed by login stack, so the lock
+  // screen state should be set from here.
+  if (key.empty())
+    HandleAuthFailure(GetUserEmail());
+}
+
+void EasyUnlockService::HandleAuthFailure(const std::string& user_id) {
+  if (user_id != GetUserEmail())
+    return;
+
+  if (!screenlock_state_handler_.get())
+    return;
+
+  screenlock_state_handler_->SetHardlockState(
+      EasyUnlockScreenlockStateHandler::LOGIN_FAILED);
 }
 
 void EasyUnlockService::CheckCryptohomeKeysAndMaybeHardlock() {
diff --git a/chrome/browser/signin/easy_unlock_service.h b/chrome/browser/signin/easy_unlock_service.h
index 2e3c7b4..1f256a1 100644
--- a/chrome/browser/signin/easy_unlock_service.h
+++ b/chrome/browser/signin/easy_unlock_service.h
@@ -107,6 +107,13 @@
   // for the user, returns an empty string.
   virtual std::string GetWrappedSecret() const = 0;
 
+  // Records metrics for Easy sign-in outcome for the given user.
+  virtual void RecordEasySignInOutcome(const std::string& user_id,
+                                       bool success) const = 0;
+
+  // Records metrics for password based flow for the given user.
+  virtual void RecordPasswordLoginEvent(const std::string& user_id) const = 0;
+
   // Whether easy unlock is allowed to be used. If the controlling preference
   // is set (from policy), this returns the preference value. Otherwise, it is
   // permitted either the flag is enabled or its field trial is enabled.
@@ -140,6 +147,9 @@
   // exists.
   void FinalizeSignin(const std::string& secret);
 
+  // Handles Easy Unlock auth failure for the user.
+  void HandleAuthFailure(const std::string& user_id);
+
   // Checks the consistency between pairing data and cryptohome keys. Set
   // hardlock state if the two do not match.
   void CheckCryptohomeKeysAndMaybeHardlock();
@@ -153,7 +163,7 @@
 
  protected:
   explicit EasyUnlockService(Profile* profile);
-  virtual ~EasyUnlockService();
+  ~EasyUnlockService() override;
 
   // Does a service type specific initialization.
   virtual void InitializeInternal() = 0;
@@ -167,7 +177,7 @@
   virtual bool IsAllowedInternal() = 0;
 
   // KeyedService override:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // Exposes the profile to which the service is attached to subclasses.
   Profile* profile() const { return profile_; }
@@ -201,6 +211,10 @@
   void SetScreenlockHardlockedState(
       EasyUnlockScreenlockStateHandler::HardlockState state);
 
+  const EasyUnlockScreenlockStateHandler* screenlock_state_handler() const {
+    return screenlock_state_handler_.get();
+  }
+
  private:
   // A class to detect whether a bluetooth adapter is present.
   class BluetoothDetector;
diff --git a/chrome/browser/signin/easy_unlock_service_factory.h b/chrome/browser/signin/easy_unlock_service_factory.h
index 7f95cdc..640967a 100644
--- a/chrome/browser/signin/easy_unlock_service_factory.h
+++ b/chrome/browser/signin/easy_unlock_service_factory.h
@@ -27,15 +27,15 @@
   friend struct DefaultSingletonTraits<EasyUnlockServiceFactory>;
 
   EasyUnlockServiceFactory();
-  virtual ~EasyUnlockServiceFactory();
+  ~EasyUnlockServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
-  virtual bool ServiceIsCreatedWithBrowserContext() const override;
-  virtual bool ServiceIsNULLWhileTesting() const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
+  bool ServiceIsNULLWhileTesting() const override;
 
   DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceFactory);
 };
diff --git a/chrome/browser/signin/easy_unlock_service_regular.cc b/chrome/browser/signin/easy_unlock_service_regular.cc
index 5ea5695..870d663 100644
--- a/chrome/browser/signin/easy_unlock_service_regular.cc
+++ b/chrome/browser/signin/easy_unlock_service_regular.cc
@@ -163,6 +163,17 @@
   return std::string();
 }
 
+void EasyUnlockServiceRegular::RecordEasySignInOutcome(
+    const std::string& user_id,
+    bool success) const {
+  NOTREACHED();
+}
+
+void EasyUnlockServiceRegular::RecordPasswordLoginEvent(
+    const std::string& user_id) const {
+  NOTREACHED();
+}
+
 void EasyUnlockServiceRegular::InitializeInternal() {
   registrar_.Init(profile()->GetPrefs());
   registrar_.Add(
diff --git a/chrome/browser/signin/easy_unlock_service_regular.h b/chrome/browser/signin/easy_unlock_service_regular.h
index 768d1fd..749b5830 100644
--- a/chrome/browser/signin/easy_unlock_service_regular.h
+++ b/chrome/browser/signin/easy_unlock_service_regular.h
@@ -25,27 +25,30 @@
 class EasyUnlockServiceRegular : public EasyUnlockService {
  public:
   explicit EasyUnlockServiceRegular(Profile* profile);
-  virtual ~EasyUnlockServiceRegular();
+  ~EasyUnlockServiceRegular() override;
 
  private:
   // EasyUnlockService implementation.
-  virtual EasyUnlockService::Type GetType() const override;
-  virtual std::string GetUserEmail() const override;
-  virtual void LaunchSetup() override;
-  virtual const base::DictionaryValue* GetPermitAccess() const override;
-  virtual void SetPermitAccess(const base::DictionaryValue& permit) override;
-  virtual void ClearPermitAccess() override;
-  virtual const base::ListValue* GetRemoteDevices() const override;
-  virtual void SetRemoteDevices(const base::ListValue& devices) override;
-  virtual void ClearRemoteDevices() override;
-  virtual void RunTurnOffFlow() override;
-  virtual void ResetTurnOffFlow() override;
-  virtual TurnOffFlowStatus GetTurnOffFlowStatus() const override;
-  virtual std::string GetChallenge() const override;
-  virtual std::string GetWrappedSecret() const override;
-  virtual void InitializeInternal() override;
-  virtual void ShutdownInternal() override;
-  virtual bool IsAllowedInternal() override;
+  EasyUnlockService::Type GetType() const override;
+  std::string GetUserEmail() const override;
+  void LaunchSetup() override;
+  const base::DictionaryValue* GetPermitAccess() const override;
+  void SetPermitAccess(const base::DictionaryValue& permit) override;
+  void ClearPermitAccess() override;
+  const base::ListValue* GetRemoteDevices() const override;
+  void SetRemoteDevices(const base::ListValue& devices) override;
+  void ClearRemoteDevices() override;
+  void RunTurnOffFlow() override;
+  void ResetTurnOffFlow() override;
+  TurnOffFlowStatus GetTurnOffFlowStatus() const override;
+  std::string GetChallenge() const override;
+  std::string GetWrappedSecret() const override;
+  void RecordEasySignInOutcome(const std::string& user_id,
+                               bool success) const override;
+  void RecordPasswordLoginEvent(const std::string& user_id) const override;
+  void InitializeInternal() override;
+  void ShutdownInternal() override;
+  bool IsAllowedInternal() override;
 
   // Callback when the controlling pref changes.
   void OnPrefsChanged();
diff --git a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
index f038a64..eb0da7c 100644
--- a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
+++ b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
@@ -12,6 +12,7 @@
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
+#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_metrics.h"
 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
 #include "chromeos/login/auth/user_context.h"
 
@@ -170,6 +171,73 @@
   return data->devices[device_index].wrapped_secret;
 }
 
+void EasyUnlockServiceSignin::RecordEasySignInOutcome(
+    const std::string& user_id,
+    bool success) const {
+  DCHECK_EQ(GetUserEmail(), user_id);
+
+  chromeos::RecordEasyUnlockLoginEvent(success
+                                           ? chromeos::EASY_SIGN_IN_SUCCESS
+                                           : chromeos::EASY_SIGN_IN_FAILURE);
+  VLOG(1) << "Easy sign-in " << (success ? "success" : "failure");
+}
+
+void EasyUnlockServiceSignin::RecordPasswordLoginEvent(
+    const std::string& user_id) const {
+  DCHECK_EQ(GetUserEmail(), user_id);
+
+  chromeos::EasyUnlockLoginEvent event =
+      chromeos::EASY_SIGN_IN_LOGIN_EVENT_COUNT;
+  if (!GetRemoteDevices() ||
+      GetHardlockState() == EasyUnlockScreenlockStateHandler::NO_PAIRING) {
+    event = chromeos::PASSWORD_SIGN_IN_NO_PAIRING;
+  } else if (GetHardlockState() ==
+             EasyUnlockScreenlockStateHandler::PAIRING_CHANGED) {
+    event = chromeos::PASSWORD_SIGN_IN_PAIRING_CHANGED;
+  } else if (GetHardlockState() ==
+             EasyUnlockScreenlockStateHandler::USER_HARDLOCK) {
+    event = chromeos::PASSWORD_SIGN_IN_USER_HARDLOCK;
+  } else if (!screenlock_state_handler()) {
+    event = chromeos::PASSWORD_SIGN_IN_SERVICE_NOT_ACTIVE;
+  } else {
+    switch (screenlock_state_handler()->state()) {
+      case EasyUnlockScreenlockStateHandler::STATE_INACTIVE:
+        event = chromeos::PASSWORD_SIGN_IN_SERVICE_NOT_ACTIVE;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH:
+        event = chromeos::PASSWORD_SIGN_IN_NO_BLUETOOTH;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING:
+        event = chromeos::PASSWORD_SIGN_IN_BLUETOOTH_CONNECTING;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_NO_PHONE:
+        event = chromeos::PASSWORD_SIGN_IN_NO_PHONE;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED:
+        event = chromeos::PASSWORD_SIGN_IN_PHONE_NOT_AUTHENTICATED;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED:
+        event = chromeos::PASSWORD_SIGN_IN_PHONE_LOCKED;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE:
+        event = chromeos::PASSWORD_SIGN_IN_PHONE_NOT_LOCKABLE;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY:
+        event = chromeos::PASSWORD_SIGN_IN_PHONE_NOT_NEARBY;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED:
+        event = chromeos::PASSWORD_SIGN_IN_PHONE_UNSUPPORTED;
+        break;
+      case EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED:
+        event = chromeos::PASSWORD_SIGN_IN_WITH_AUTHENTICATED_PHONE;
+        break;
+    }
+  }
+
+  chromeos::RecordEasyUnlockLoginEvent(event);
+  VLOG(1) << "EasySignIn password login event, event=" << event;
+}
+
 void EasyUnlockServiceSignin::InitializeInternal() {
   if (chromeos::LoginState::Get()->IsUserLoggedIn())
     return;
diff --git a/chrome/browser/signin/easy_unlock_service_signin_chromeos.h b/chrome/browser/signin/easy_unlock_service_signin_chromeos.h
index fc9c1b7..ac952a49 100644
--- a/chrome/browser/signin/easy_unlock_service_signin_chromeos.h
+++ b/chrome/browser/signin/easy_unlock_service_signin_chromeos.h
@@ -70,6 +70,10 @@
   virtual TurnOffFlowStatus GetTurnOffFlowStatus() const override;
   virtual std::string GetChallenge() const override;
   virtual std::string GetWrappedSecret() const override;
+  virtual void RecordEasySignInOutcome(const std::string& user_id,
+                                       bool success) const override;
+  virtual void RecordPasswordLoginEvent(
+      const std::string& user_id) const override;
   virtual void InitializeInternal() override;
   virtual void ShutdownInternal() override;
   virtual bool IsAllowedInternal() override;
diff --git a/chrome/browser/signin/easy_unlock_toggle_flow.cc b/chrome/browser/signin/easy_unlock_toggle_flow.cc
index 0be4333c..22f20525 100644
--- a/chrome/browser/signin/easy_unlock_toggle_flow.cc
+++ b/chrome/browser/signin/easy_unlock_toggle_flow.cc
@@ -54,14 +54,14 @@
   ToggleApiCall(EasyUnlockToggleFlow* flow,
                 const std::string& phone_public_key,
                 bool toggle_enable);
-  virtual ~ToggleApiCall();
+  ~ToggleApiCall() override;
 
   // OAuth2ApiCallFlow
-  virtual GURL CreateApiCallUrl() override;
-  virtual std::string CreateApiCallBody() override;
-  virtual std::string CreateApiCallBodyContentType() override;
-  virtual void ProcessApiCallSuccess(const net::URLFetcher* source) override;
-  virtual void ProcessApiCallFailure(const net::URLFetcher* source) override;
+  GURL CreateApiCallUrl() override;
+  std::string CreateApiCallBody() override;
+  std::string CreateApiCallBodyContentType() override;
+  void ProcessApiCallSuccess(const net::URLFetcher* source) override;
+  void ProcessApiCallFailure(const net::URLFetcher* source) override;
 
  private:
   EasyUnlockToggleFlow* flow_;
diff --git a/chrome/browser/signin/easy_unlock_toggle_flow.h b/chrome/browser/signin/easy_unlock_toggle_flow.h
index 303b843..7e04f02 100644
--- a/chrome/browser/signin/easy_unlock_toggle_flow.h
+++ b/chrome/browser/signin/easy_unlock_toggle_flow.h
@@ -27,24 +27,22 @@
                        const std::string& phone_public_key,
                        bool toggle_enable,
                        const ToggleFlowCallback& callback);
-  virtual ~EasyUnlockToggleFlow();
+  ~EasyUnlockToggleFlow() override;
 
   void Start();
 
   // OAuth2TokenService::Consumer
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
   // OAuth2MintTokenFlow::Delegate
-  virtual void OnMintTokenSuccess(const std::string& access_token,
-                                  int time_to_live) override;
-  virtual void OnMintTokenFailure(
-      const GoogleServiceAuthError& error) override;
-  virtual void OnIssueAdviceSuccess(
-      const IssueAdviceInfo& issue_advice) override;
+  void OnMintTokenSuccess(const std::string& access_token,
+                          int time_to_live) override;
+  void OnMintTokenFailure(const GoogleServiceAuthError& error) override;
+  void OnIssueAdviceSuccess(const IssueAdviceInfo& issue_advice) override;
 
  private:
   // Derived OAuth2ApiCallFlow class to make toggle api call after access token
diff --git a/chrome/browser/signin/fake_account_reconcilor.h b/chrome/browser/signin/fake_account_reconcilor.h
index b3907d5..6e3b6c9 100644
--- a/chrome/browser/signin/fake_account_reconcilor.h
+++ b/chrome/browser/signin/fake_account_reconcilor.h
@@ -22,8 +22,7 @@
  protected:
   // Override this method to perform no network call, instead the callback
   // is called immediately
-  virtual void GetAccountsFromCookie(GetAccountsFromCookieCallback callback)
-      override;
+  void GetAccountsFromCookie(GetAccountsFromCookieCallback callback) override;
 
   DISALLOW_COPY_AND_ASSIGN(FakeAccountReconcilor);
 };
diff --git a/chrome/browser/signin/fake_account_tracker_service.h b/chrome/browser/signin/fake_account_tracker_service.h
index 7700051..b25a850 100644
--- a/chrome/browser/signin/fake_account_tracker_service.h
+++ b/chrome/browser/signin/fake_account_tracker_service.h
@@ -22,9 +22,9 @@
 
  private:
   FakeAccountTrackerService();
-  virtual ~FakeAccountTrackerService();
+  ~FakeAccountTrackerService() override;
 
-  virtual void StartFetchingUserInfo(const std::string& account_id) override;
+  void StartFetchingUserInfo(const std::string& account_id) override;
 
   DISALLOW_COPY_AND_ASSIGN(FakeAccountTrackerService);
 };
diff --git a/chrome/browser/signin/fake_profile_oauth2_token_service.h b/chrome/browser/signin/fake_profile_oauth2_token_service.h
index 4eadb7d..9a5b97c 100644
--- a/chrome/browser/signin/fake_profile_oauth2_token_service.h
+++ b/chrome/browser/signin/fake_profile_oauth2_token_service.h
@@ -56,21 +56,20 @@
   };
 
   FakeProfileOAuth2TokenService();
-  virtual ~FakeProfileOAuth2TokenService();
+  ~FakeProfileOAuth2TokenService() override;
 
   // Overriden to make sure it works on Android.
-  virtual bool RefreshTokenIsAvailable(
-      const std::string& account_id) const override;
+  bool RefreshTokenIsAvailable(const std::string& account_id) const override;
 
   // Overriden to make sure it works on iOS.
-  virtual void LoadCredentials(const std::string& primary_account_id) override;
+  void LoadCredentials(const std::string& primary_account_id) override;
 
-  virtual std::vector<std::string> GetAccounts() override;
+  std::vector<std::string> GetAccounts() override;
 
   // Overriden to make sure it works on Android.  Simply calls
   // IssueRefreshToken().
-  virtual void UpdateCredentials(const std::string& account_id,
-                                 const std::string& refresh_token) override;
+  void UpdateCredentials(const std::string& account_id,
+                         const std::string& refresh_token) override;
 
   // Sets the current refresh token. If |token| is non-empty, this will invoke
   // OnRefreshTokenAvailable() on all Observers, otherwise this will invoke
@@ -116,24 +115,24 @@
 
  protected:
   // OAuth2TokenService overrides.
-  virtual void FetchOAuth2Token(RequestImpl* request,
-                                const std::string& account_id,
-                                net::URLRequestContextGetter* getter,
-                                const std::string& client_id,
-                                const std::string& client_secret,
-                                const ScopeSet& scopes) override;
+  void FetchOAuth2Token(RequestImpl* request,
+                        const std::string& account_id,
+                        net::URLRequestContextGetter* getter,
+                        const std::string& client_id,
+                        const std::string& client_secret,
+                        const ScopeSet& scopes) override;
 
-  virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
+  OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
       const std::string& account_id,
       net::URLRequestContextGetter* getter,
       OAuth2AccessTokenConsumer* consumer) override;
 
-  virtual void InvalidateOAuth2Token(const std::string& account_id,
-                                     const std::string& client_id,
-                                     const ScopeSet& scopes,
-                                     const std::string& access_token) override;
+  void InvalidateOAuth2Token(const std::string& account_id,
+                             const std::string& client_id,
+                             const ScopeSet& scopes,
+                             const std::string& access_token) override;
 
-  virtual net::URLRequestContextGetter* GetRequestContext() override;
+  net::URLRequestContextGetter* GetRequestContext() override;
 
  private:
   // Helper function to complete pending requests - if |all_scopes| is true,
diff --git a/chrome/browser/signin/fake_signin_manager.h b/chrome/browser/signin/fake_signin_manager.h
index 6128012..8e91531a 100644
--- a/chrome/browser/signin/fake_signin_manager.h
+++ b/chrome/browser/signin/fake_signin_manager.h
@@ -25,7 +25,7 @@
 class FakeSigninManagerBase : public SigninManagerBase {
  public:
   explicit FakeSigninManagerBase(Profile* profile);
-  virtual ~FakeSigninManagerBase();
+  ~FakeSigninManagerBase() override;
 
   // Helper function to be used with
   // KeyedService::SetTestingFactory(). In order to match
@@ -42,7 +42,7 @@
 class FakeSigninManager : public SigninManager {
  public:
   explicit FakeSigninManager(Profile* profile);
-  virtual ~FakeSigninManager();
+  ~FakeSigninManager() override;
 
   void set_auth_in_progress(const std::string& username) {
     possibly_invalid_username_ = username;
@@ -54,16 +54,15 @@
 
   void FailSignin(const GoogleServiceAuthError& error);
 
-  virtual void StartSignInWithRefreshToken(
+  void StartSignInWithRefreshToken(
       const std::string& refresh_token,
       const std::string& username,
       const std::string& password,
       const OAuthTokenFetchedCallback& oauth_fetched_callback) override;
 
-  virtual void SignOut(signin_metrics::ProfileSignout signout_source_metric)
-      override;
+  void SignOut(signin_metrics::ProfileSignout signout_source_metric) override;
 
-  virtual void CompletePendingSignin() override;
+  void CompletePendingSignin() override;
 };
 
 #endif  // !defined (OS_CHROMEOS)
diff --git a/chrome/browser/signin/principals_message_filter.h b/chrome/browser/signin/principals_message_filter.h
index 8eb9fe5..5d378646 100644
--- a/chrome/browser/signin/principals_message_filter.h
+++ b/chrome/browser/signin/principals_message_filter.h
@@ -17,13 +17,12 @@
   explicit PrincipalsMessageFilter(int render_process_id);
 
   // content::BrowserMessageFilter implementation.
-  virtual void OverrideThreadForMessage(
-      const IPC::Message& message,
-      content::BrowserThread::ID* thread) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  void OverrideThreadForMessage(const IPC::Message& message,
+                                content::BrowserThread::ID* thread) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
 
  private:
-  virtual ~PrincipalsMessageFilter();
+  ~PrincipalsMessageFilter() override;
 
   void OnMsgShowBrowserAccountManagementUI();
   void OnMsgGetManagedAccounts(const GURL& url,
diff --git a/chrome/browser/signin/profile_identity_provider.h b/chrome/browser/signin/profile_identity_provider.h
index b2291f43..aa1b168 100644
--- a/chrome/browser/signin/profile_identity_provider.h
+++ b/chrome/browser/signin/profile_identity_provider.h
@@ -20,20 +20,20 @@
   ProfileIdentityProvider(SigninManagerBase* signin_manager,
                           ProfileOAuth2TokenService* token_service,
                           LoginUIService* login_ui_service);
-  virtual ~ProfileIdentityProvider();
+  ~ProfileIdentityProvider() override;
 
   // IdentityProvider:
-  virtual std::string GetActiveUsername() override;
-  virtual std::string GetActiveAccountId() override;
-  virtual OAuth2TokenService* GetTokenService() override;
-  virtual bool RequestLogin() override;
+  std::string GetActiveUsername() override;
+  std::string GetActiveAccountId() override;
+  OAuth2TokenService* GetTokenService() override;
+  bool RequestLogin() override;
 
   // SigninManagerBase::Observer:
-  virtual void GoogleSigninSucceeded(const std::string& account_id,
-                                     const std::string& username,
-                                     const std::string& password) override;
-  virtual void GoogleSignedOut(const std::string& account_id,
-                               const std::string& username) override;
+  void GoogleSigninSucceeded(const std::string& account_id,
+                             const std::string& username,
+                             const std::string& password) override;
+  void GoogleSignedOut(const std::string& account_id,
+                       const std::string& username) override;
 
  private:
   SigninManagerBase* const signin_manager_;
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.h b/chrome/browser/signin/profile_oauth2_token_service_factory.h
index 33f5afa..f972e6c 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_factory.h
+++ b/chrome/browser/signin/profile_oauth2_token_service_factory.h
@@ -54,10 +54,10 @@
 #endif
 
   ProfileOAuth2TokenServiceFactory();
-  virtual ~ProfileOAuth2TokenServiceFactory();
+  ~ProfileOAuth2TokenServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory implementation.
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileOAuth2TokenServiceFactory);
diff --git a/chrome/browser/signin/screenlock_bridge.cc b/chrome/browser/signin/screenlock_bridge.cc
index a78d2613..5fb5192a 100644
--- a/chrome/browser/signin/screenlock_bridge.cc
+++ b/chrome/browser/signin/screenlock_bridge.cc
@@ -74,6 +74,9 @@
     result->Set("tooltip", tooltip_options);
   }
 
+  if (!aria_label_.empty())
+    result->SetString("ariaLabel", aria_label_);
+
   if (hardlock_on_click_)
     result->SetBoolean("hardlockOnClick", true);
 
@@ -92,6 +95,11 @@
   autoshow_tooltip_ = autoshow;
 }
 
+void ScreenlockBridge::UserPodCustomIconOptions::SetAriaLabel(
+    const base::string16& aria_label) {
+  aria_label_ = aria_label;
+}
+
 void ScreenlockBridge::UserPodCustomIconOptions::SetHardlockOnClick() {
   hardlock_on_click_ = true;
 }
diff --git a/chrome/browser/signin/screenlock_bridge.h b/chrome/browser/signin/screenlock_bridge.h
index 7add894..c9b702d 100644
--- a/chrome/browser/signin/screenlock_bridge.h
+++ b/chrome/browser/signin/screenlock_bridge.h
@@ -64,6 +64,10 @@
     // shown with the icon.
     void SetTooltip(const base::string16& tooltip, bool autoshow);
 
+    // Sets the accessiblity label of the icon. If this attribute is not
+    // provided, then the tooltip will be used.
+    void SetAriaLabel(const base::string16& aria_label);
+
     // If hardlock on click is set, clicking the icon in the screenlock will
     // go to state where password is required for unlock.
     void SetHardlockOnClick();
@@ -74,6 +78,8 @@
     base::string16 tooltip_;
     bool autoshow_tooltip_;
 
+    base::string16 aria_label_;
+
     bool hardlock_on_click_;
 
     DISALLOW_COPY_AND_ASSIGN(UserPodCustomIconOptions);
diff --git a/chrome/browser/signin/signin_browsertest.cc b/chrome/browser/signin/signin_browsertest.cc
index 259bc3c..b7645c4 100644
--- a/chrome/browser/signin/signin_browsertest.cc
+++ b/chrome/browser/signin/signin_browsertest.cc
@@ -36,7 +36,7 @@
 
 class SigninBrowserTest : public InProcessBrowserTest {
  public:
-  virtual void SetUpCommandLine(CommandLine* command_line) override {
+  void SetUpCommandLine(CommandLine* command_line) override {
     https_server_.reset(new net::SpawnedTestServer(
         net::SpawnedTestServer::TYPE_HTTPS,
         net::SpawnedTestServer::kLocalhost,
@@ -183,7 +183,7 @@
       : content::WebContentsObserver(web_contents) {
   }
 
-  virtual void DidCommitProvisionalLoadForFrame(
+  void DidCommitProvisionalLoadForFrame(
       content::RenderFrameHost* render_frame_host,
       const GURL& url,
       ui::PageTransition transition_type) override {
diff --git a/chrome/browser/signin/signin_global_error.h b/chrome/browser/signin/signin_global_error.h
index 673b03be..86846c8 100644
--- a/chrome/browser/signin/signin_global_error.h
+++ b/chrome/browser/signin/signin_global_error.h
@@ -22,7 +22,7 @@
  public:
   SigninGlobalError(SigninErrorController* error_controller,
                     Profile* profile);
-  virtual ~SigninGlobalError();
+  ~SigninGlobalError() override;
 
   // Returns true if there is an authentication error.
   bool HasError();
@@ -37,24 +37,24 @@
   FRIEND_TEST_ALL_PREFIXES(SigninGlobalErrorTest, AuthStatusEnumerateAllErrors);
 
   // KeyedService:
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // GlobalErrorWithStandardBubble:
-  virtual bool HasMenuItem() override;
-  virtual int MenuItemCommandID() override;
-  virtual base::string16 MenuItemLabel() override;
-  virtual void ExecuteMenuItem(Browser* browser) override;
-  virtual bool HasBubbleView() override;
-  virtual base::string16 GetBubbleViewTitle() override;
-  virtual std::vector<base::string16> GetBubbleViewMessages() override;
-  virtual base::string16 GetBubbleViewAcceptButtonLabel() override;
-  virtual base::string16 GetBubbleViewCancelButtonLabel() override;
-  virtual void OnBubbleViewDidClose(Browser* browser) override;
-  virtual void BubbleViewAcceptButtonPressed(Browser* browser) override;
-  virtual void BubbleViewCancelButtonPressed(Browser* browser) override;
+  bool HasMenuItem() override;
+  int MenuItemCommandID() override;
+  base::string16 MenuItemLabel() override;
+  void ExecuteMenuItem(Browser* browser) override;
+  bool HasBubbleView() override;
+  base::string16 GetBubbleViewTitle() override;
+  std::vector<base::string16> GetBubbleViewMessages() override;
+  base::string16 GetBubbleViewAcceptButtonLabel() override;
+  base::string16 GetBubbleViewCancelButtonLabel() override;
+  void OnBubbleViewDidClose(Browser* browser) override;
+  void BubbleViewAcceptButtonPressed(Browser* browser) override;
+  void BubbleViewCancelButtonPressed(Browser* browser) override;
 
   // SigninErrorController::Observer:
-  virtual void OnErrorChanged() override;
+  void OnErrorChanged() override;
 
   // The Profile this service belongs to.
   Profile* profile_;
diff --git a/chrome/browser/signin/signin_global_error_factory.h b/chrome/browser/signin/signin_global_error_factory.h
index fd7ea86..36bb94c 100644
--- a/chrome/browser/signin/signin_global_error_factory.h
+++ b/chrome/browser/signin/signin_global_error_factory.h
@@ -27,10 +27,10 @@
   friend struct DefaultSingletonTraits<SigninGlobalErrorFactory>;
 
   SigninGlobalErrorFactory();
-  virtual ~SigninGlobalErrorFactory();
+  ~SigninGlobalErrorFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
 
   DISALLOW_COPY_AND_ASSIGN(SigninGlobalErrorFactory);
diff --git a/chrome/browser/signin/signin_manager_factory.h b/chrome/browser/signin/signin_manager_factory.h
index 37eab458..3d00b06 100644
--- a/chrome/browser/signin/signin_manager_factory.h
+++ b/chrome/browser/signin/signin_manager_factory.h
@@ -54,7 +54,7 @@
 
   // Implementation of BrowserContextKeyedServiceFactory (public so tests
   // can call it).
-  virtual void RegisterProfilePrefs(
+  void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) override;
 
   // Registers the browser-global prefs used by SigninManager.
@@ -74,16 +74,15 @@
   friend struct DefaultSingletonTraits<SigninManagerFactory>;
 
   SigninManagerFactory();
-  virtual ~SigninManagerFactory();
+  ~SigninManagerFactory() override;
 
   // List of observers. Checks that list is empty on destruction.
   mutable ObserverList<Observer, true> observer_list_;
 
   // BrowserContextKeyedServiceFactory:
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override;
-  virtual void BrowserContextShutdown(content::BrowserContext* context)
-      override;
+  void BrowserContextShutdown(content::BrowserContext* context) override;
 };
 
 #endif  // CHROME_BROWSER_SIGNIN_SIGNIN_MANAGER_FACTORY_H_
diff --git a/chrome/browser/signin/signin_manager_unittest.cc b/chrome/browser/signin/signin_manager_unittest.cc
index 6df559d..1c43999 100644
--- a/chrome/browser/signin/signin_manager_unittest.cc
+++ b/chrome/browser/signin/signin_manager_unittest.cc
@@ -61,7 +61,7 @@
                                 num_signouts_(0) {
   }
 
-  virtual ~TestSigninManagerObserver() {}
+  ~TestSigninManagerObserver() override {}
 
   int num_failed_signins_;
   int num_successful_signins_;
@@ -69,20 +69,18 @@
 
  private:
   // SigninManagerBase::Observer:
-  virtual void GoogleSigninFailed(
-      const GoogleServiceAuthError& error) override {
+  void GoogleSigninFailed(const GoogleServiceAuthError& error) override {
     num_failed_signins_++;
   }
 
-  virtual void GoogleSigninSucceeded(
-      const std::string& account_id,
-      const std::string& username,
-      const std::string& password) override {
+  void GoogleSigninSucceeded(const std::string& account_id,
+                             const std::string& username,
+                             const std::string& password) override {
     num_successful_signins_++;
   }
 
-  virtual void GoogleSignedOut(const std::string& account_id,
-                               const std::string& username) override {
+  void GoogleSignedOut(const std::string& account_id,
+                       const std::string& username) override {
     num_signouts_++;
   }
 };
diff --git a/chrome/browser/signin/signin_names_io_thread.h b/chrome/browser/signin/signin_names_io_thread.h
index dbef056..1349308 100644
--- a/chrome/browser/signin/signin_names_io_thread.h
+++ b/chrome/browser/signin/signin_names_io_thread.h
@@ -30,7 +30,7 @@
 
   // Objects should only be created on UI thread.
   SigninNamesOnIOThread();
-  virtual ~SigninNamesOnIOThread();
+  ~SigninNamesOnIOThread() override;
 
   // Gets the set of email addresses of connected profiles.  This method should
   // only be called on the IO thread.
@@ -42,15 +42,15 @@
 
  private:
   // SigninManagerBase::Observer:
-  virtual void GoogleSigninSucceeded(const std::string& account_id,
-                                     const std::string& username,
-                                     const std::string& password) override;
-  virtual void GoogleSignedOut(const std::string& account_id,
-                               const std::string& username) override;
+  void GoogleSigninSucceeded(const std::string& account_id,
+                             const std::string& username,
+                             const std::string& password) override;
+  void GoogleSignedOut(const std::string& account_id,
+                       const std::string& username) override;
 
   // SigninManagerFactory::Observer:
-  virtual void SigninManagerCreated(SigninManagerBase* manager) override;
-  virtual void SigninManagerShutdown(SigninManagerBase* manager) override;
+  void SigninManagerCreated(SigninManagerBase* manager) override;
+  void SigninManagerShutdown(SigninManagerBase* manager) override;
 
   // Checks whether the current thread is the IO thread.
   void CheckOnIOThread() const;
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
index d83d1f0..267b9d2 100644
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.cc
@@ -188,9 +188,9 @@
   }
 
   // content::NotificationObserver implementation.
-  virtual void Observe(int type,
-                       const content::NotificationSource& source,
-                       const content::NotificationDetails& details) override {
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED ||
            type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED);
@@ -230,7 +230,7 @@
 
   friend class base::RefCountedThreadSafe<TabWatcher>;
 
-  virtual ~TabWatcher() {
+  ~TabWatcher() override {
     // Must be destroyed on the UI thread due to |registrar_| non thread-safety.
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   }
diff --git a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
index 83018d2..b806b99 100644
--- a/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
+++ b/chrome/browser/speech/chrome_speech_recognition_manager_delegate.h
@@ -20,32 +20,35 @@
       public content::SpeechRecognitionEventListener {
  public:
   ChromeSpeechRecognitionManagerDelegate();
-  virtual ~ChromeSpeechRecognitionManagerDelegate();
+  ~ChromeSpeechRecognitionManagerDelegate() override;
 
  protected:
   // SpeechRecognitionEventListener methods.
-  virtual void OnRecognitionStart(int session_id) override;
-  virtual void OnAudioStart(int session_id) override;
-  virtual void OnEnvironmentEstimationComplete(int session_id) override;
-  virtual void OnSoundStart(int session_id) override;
-  virtual void OnSoundEnd(int session_id) override;
-  virtual void OnAudioEnd(int session_id) override;
-  virtual void OnRecognitionEnd(int session_id) override;
-  virtual void OnRecognitionResults(
-      int session_id, const content::SpeechRecognitionResults& result) override;
-  virtual void OnRecognitionError(
-      int session_id, const content::SpeechRecognitionError& error) override;
-  virtual void OnAudioLevelsChange(int session_id, float volume,
-                                   float noise_volume) override;
+  void OnRecognitionStart(int session_id) override;
+  void OnAudioStart(int session_id) override;
+  void OnEnvironmentEstimationComplete(int session_id) override;
+  void OnSoundStart(int session_id) override;
+  void OnSoundEnd(int session_id) override;
+  void OnAudioEnd(int session_id) override;
+  void OnRecognitionEnd(int session_id) override;
+  void OnRecognitionResults(
+      int session_id,
+      const content::SpeechRecognitionResults& result) override;
+  void OnRecognitionError(
+      int session_id,
+      const content::SpeechRecognitionError& error) override;
+  void OnAudioLevelsChange(int session_id,
+                           float volume,
+                           float noise_volume) override;
 
   // SpeechRecognitionManagerDelegate methods.
-  virtual void GetDiagnosticInformation(bool* can_report_metrics,
-                                        std::string* hardware_info) override;
-  virtual void CheckRecognitionIsAllowed(
+  void GetDiagnosticInformation(bool* can_report_metrics,
+                                std::string* hardware_info) override;
+  void CheckRecognitionIsAllowed(
       int session_id,
       base::Callback<void(bool ask_user, bool is_allowed)> callback) override;
-  virtual content::SpeechRecognitionEventListener* GetEventListener() override;
-  virtual bool FilterProfanities(int render_process_id) override;
+  content::SpeechRecognitionEventListener* GetEventListener() override;
+  bool FilterProfanities(int render_process_id) override;
 
   // Callback called by |tab_watcher_| on the IO thread to signal tab closure.
   virtual void TabClosedCallback(int render_process_id, int render_view_id);
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_api.h b/chrome/browser/speech/extension_api/tts_engine_extension_api.h
index f363384..441d72f6 100644
--- a/chrome/browser/speech/extension_api/tts_engine_extension_api.h
+++ b/chrome/browser/speech/extension_api/tts_engine_extension_api.h
@@ -38,21 +38,21 @@
   static TtsExtensionEngine* GetInstance();
 
   // Overridden from TtsEngineDelegate:
-  virtual void GetVoices(content::BrowserContext* browser_context,
-                         std::vector<VoiceData>* out_voices) override;
-  virtual void Speak(Utterance* utterance, const VoiceData& voice) override;
-  virtual void Stop(Utterance* utterance) override;
-  virtual void Pause(Utterance* utterance) override;
-  virtual void Resume(Utterance* utterance) override;
-  virtual bool LoadBuiltInTtsExtension(
+  void GetVoices(content::BrowserContext* browser_context,
+                 std::vector<VoiceData>* out_voices) override;
+  void Speak(Utterance* utterance, const VoiceData& voice) override;
+  void Stop(Utterance* utterance) override;
+  void Pause(Utterance* utterance) override;
+  void Resume(Utterance* utterance) override;
+  bool LoadBuiltInTtsExtension(
       content::BrowserContext* browser_context) override;
 };
 // Hidden/internal extension function used to allow TTS engine extensions
 // to send events back to the client that's calling tts.speak().
 class ExtensionTtsEngineSendTtsEventFunction : public SyncExtensionFunction {
  private:
-  virtual ~ExtensionTtsEngineSendTtsEventFunction() {}
-  virtual bool RunSync() override;
+  ~ExtensionTtsEngineSendTtsEventFunction() override {}
+  bool RunSync() override;
   DECLARE_EXTENSION_FUNCTION("ttsEngine.sendTtsEvent", TTSENGINE_SENDTTSEVENT)
 };
 
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_observer.cc b/chrome/browser/speech/extension_api/tts_engine_extension_observer.cc
index c760a48..ef7be18c 100644
--- a/chrome/browser/speech/extension_api/tts_engine_extension_observer.cc
+++ b/chrome/browser/speech/extension_api/tts_engine_extension_observer.cc
@@ -6,7 +6,6 @@
 
 #include "base/logging.h"
 #include "base/memory/singleton.h"
-#include "base/profiler/scoped_profile.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_system_factory.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
@@ -42,16 +41,16 @@
     DependsOn(extensions::ExtensionSystemFactory::GetInstance());
   }
 
-  virtual ~TtsEngineExtensionObserverFactory() {}
+  ~TtsEngineExtensionObserverFactory() override {}
 
-  virtual content::BrowserContext* GetBrowserContextToUse(
+  content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override {
     // If given an incognito profile (including the Chrome OS login
     // profile), share the service with the original profile.
     return chrome::GetBrowserContextRedirectedInIncognito(context);
   }
 
-  virtual KeyedService* BuildServiceInstanceFor(
+  KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* profile) const override {
     return new TtsEngineExtensionObserver(static_cast<Profile*>(profile));
   }
@@ -115,11 +114,6 @@
 
 void TtsEngineExtensionObserver::OnListenerAdded(
     const extensions::EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "TtsEngineExtensionObserver::OnListenerAdded"));
-
   if (!IsLoadedTtsEngine(details.extension_id))
     return;
 
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_observer.h b/chrome/browser/speech/extension_api/tts_engine_extension_observer.h
index 2b0dd38..08d38c2 100644
--- a/chrome/browser/speech/extension_api/tts_engine_extension_observer.h
+++ b/chrome/browser/speech/extension_api/tts_engine_extension_observer.h
@@ -27,21 +27,20 @@
   bool SawExtensionLoad(const std::string& extension_id, bool update);
 
   // Implementation of KeyedService.
-  virtual void Shutdown() override;
+  void Shutdown() override;
 
   // Implementation of extensions::EventRouter::Observer.
-  virtual void OnListenerAdded(
-      const extensions::EventListenerInfo& details) override;
+  void OnListenerAdded(const extensions::EventListenerInfo& details) override;
 
   // extensions::ExtensionRegistryObserver overrides.
-  virtual void OnExtensionUnloaded(
+  void OnExtensionUnloaded(
       content::BrowserContext* browser_context,
       const extensions::Extension* extension,
       extensions::UnloadedExtensionInfo::Reason reason) override;
 
  private:
   explicit TtsEngineExtensionObserver(Profile* profile);
-  virtual ~TtsEngineExtensionObserver();
+  ~TtsEngineExtensionObserver() override;
 
   bool IsLoadedTtsEngine(const std::string& extension_id);
 
diff --git a/chrome/browser/speech/extension_api/tts_extension_api.cc b/chrome/browser/speech/extension_api/tts_extension_api.cc
index 823b849..8633523 100644
--- a/chrome/browser/speech/extension_api/tts_extension_api.cc
+++ b/chrome/browser/speech/extension_api/tts_extension_api.cc
@@ -86,12 +86,24 @@
     : public UtteranceEventDelegate,
       public base::SupportsWeakPtr<TtsExtensionEventHandler> {
  public:
-  virtual void OnTtsEvent(Utterance* utterance,
-                          TtsEventType event_type,
-                          int char_index,
-                          const std::string& error_message) override;
+  explicit TtsExtensionEventHandler(const std::string& src_extension_id);
+
+  void OnTtsEvent(Utterance* utterance,
+                  TtsEventType event_type,
+                  int char_index,
+                  const std::string& error_message) override;
+
+ private:
+  // The extension ID of the extension that called speak() and should
+  // receive events.
+  std::string src_extension_id_;
 };
 
+TtsExtensionEventHandler::TtsExtensionEventHandler(
+    const std::string& src_extension_id)
+    : src_extension_id_(src_extension_id) {
+}
+
 void TtsExtensionEventHandler::OnTtsEvent(Utterance* utterance,
                                           TtsEventType event_type,
                                           int char_index,
@@ -130,7 +142,7 @@
   event->restrict_to_browser_context = utterance->browser_context();
   event->event_url = utterance->src_url();
   extensions::EventRouter::Get(utterance->browser_context())
-      ->DispatchEventToExtension(utterance->src_extension_id(), event.Pass());
+      ->DispatchEventToExtension(src_extension_id_, event.Pass());
 
   if (utterance->finished())
     delete this;
@@ -267,7 +279,6 @@
   Utterance* utterance = new Utterance(GetProfile());
   utterance->set_text(text);
   utterance->set_voice_name(voice_name);
-  utterance->set_src_extension_id(extension_id());
   utterance->set_src_id(src_id);
   utterance->set_src_url(source_url());
   utterance->set_lang(lang);
@@ -279,7 +290,7 @@
   utterance->set_extension_id(voice_extension_id);
   utterance->set_options(options.get());
   utterance->set_event_delegate(
-      (new TtsExtensionEventHandler())->AsWeakPtr());
+      (new TtsExtensionEventHandler(extension_id()))->AsWeakPtr());
 
   TtsController* controller = TtsController::GetInstance();
   controller->SpeakOrEnqueue(utterance);
diff --git a/chrome/browser/speech/extension_api/tts_extension_api.h b/chrome/browser/speech/extension_api/tts_extension_api.h
index e41f35d..8c153bc 100644
--- a/chrome/browser/speech/extension_api/tts_extension_api.h
+++ b/chrome/browser/speech/extension_api/tts_extension_api.h
@@ -22,50 +22,50 @@
 
 class TtsSpeakFunction : public ChromeAsyncExtensionFunction {
  private:
-  virtual ~TtsSpeakFunction() {}
-  virtual bool RunAsync() override;
+  ~TtsSpeakFunction() override {}
+  bool RunAsync() override;
   DECLARE_EXTENSION_FUNCTION("tts.speak", TTS_SPEAK)
 };
 
 class TtsStopSpeakingFunction : public ChromeSyncExtensionFunction {
  private:
-  virtual ~TtsStopSpeakingFunction() {}
-  virtual bool RunSync() override;
+  ~TtsStopSpeakingFunction() override {}
+  bool RunSync() override;
   DECLARE_EXTENSION_FUNCTION("tts.stop", TTS_STOP)
 };
 
 class TtsPauseFunction : public ChromeSyncExtensionFunction {
  private:
-  virtual ~TtsPauseFunction() {}
-  virtual bool RunSync() override;
+  ~TtsPauseFunction() override {}
+  bool RunSync() override;
   DECLARE_EXTENSION_FUNCTION("tts.pause", TTS_PAUSE)
 };
 
 class TtsResumeFunction : public ChromeSyncExtensionFunction {
  private:
-  virtual ~TtsResumeFunction() {}
-  virtual bool RunSync() override;
+  ~TtsResumeFunction() override {}
+  bool RunSync() override;
   DECLARE_EXTENSION_FUNCTION("tts.resume", TTS_RESUME)
 };
 
 class TtsIsSpeakingFunction : public ChromeSyncExtensionFunction {
  private:
-  virtual ~TtsIsSpeakingFunction() {}
-  virtual bool RunSync() override;
+  ~TtsIsSpeakingFunction() override {}
+  bool RunSync() override;
   DECLARE_EXTENSION_FUNCTION("tts.isSpeaking", TTS_ISSPEAKING)
 };
 
 class TtsGetVoicesFunction : public ChromeSyncExtensionFunction {
  private:
-  virtual ~TtsGetVoicesFunction() {}
-  virtual bool RunSync() override;
+  ~TtsGetVoicesFunction() override {}
+  bool RunSync() override;
   DECLARE_EXTENSION_FUNCTION("tts.getVoices", TTS_GETVOICES)
 };
 
 class TtsAPI : public BrowserContextKeyedAPI {
  public:
   explicit TtsAPI(content::BrowserContext* context);
-  virtual ~TtsAPI();
+  ~TtsAPI() override;
 
   // BrowserContextKeyedAPI implementation.
   static BrowserContextKeyedAPIFactory<TtsAPI>* GetFactoryInstance();
diff --git a/chrome/browser/speech/extension_api/tts_extension_apitest.cc b/chrome/browser/speech/extension_api/tts_extension_apitest.cc
index 7a4003e..1dadbc5 100644
--- a/chrome/browser/speech/extension_api/tts_extension_apitest.cc
+++ b/chrome/browser/speech/extension_api/tts_extension_apitest.cc
@@ -169,9 +169,9 @@
 class FakeNetworkOnlineStateForTest : public net::NetworkChangeNotifier {
  public:
   explicit FakeNetworkOnlineStateForTest(bool online) : online_(online) {}
-  virtual ~FakeNetworkOnlineStateForTest() {}
+  ~FakeNetworkOnlineStateForTest() override {}
 
-  virtual ConnectionType GetCurrentConnectionType() const override {
+  ConnectionType GetCurrentConnectionType() const override {
     return online_ ?
         net::NetworkChangeNotifier::CONNECTION_ETHERNET :
         net::NetworkChangeNotifier::CONNECTION_NONE;
diff --git a/chrome/browser/speech/tts_controller.h b/chrome/browser/speech/tts_controller.h
index f664d4a8..45690c9 100644
--- a/chrome/browser/speech/tts_controller.h
+++ b/chrome/browser/speech/tts_controller.h
@@ -151,11 +151,6 @@
   void set_options(const base::Value* options);
   const base::Value* options() const { return options_.get(); }
 
-  void set_src_extension_id(const std::string& src_extension_id) {
-    src_extension_id_ = src_extension_id;
-  }
-  const std::string& src_extension_id() { return src_extension_id_; }
-
   void set_src_id(int src_id) { src_id_ = src_id; }
   int src_id() { return src_id_; }
 
@@ -242,10 +237,6 @@
   // other than the ones we explicitly parse, below.
   scoped_ptr<base::Value> options_;
 
-  // The extension ID of the extension that called speak() and should
-  // receive events.
-  std::string src_extension_id_;
-
   // The source extension's ID of this utterance, so that it can associate
   // events with the appropriate callback.
   int src_id_;
diff --git a/chrome/browser/speech/tts_controller_impl.h b/chrome/browser/speech/tts_controller_impl.h
index 267fbf3d..2192cf03 100644
--- a/chrome/browser/speech/tts_controller_impl.h
+++ b/chrome/browser/speech/tts_controller_impl.h
@@ -29,30 +29,28 @@
   static TtsControllerImpl* GetInstance();
 
   // TtsController methods
-  virtual bool IsSpeaking() override;
-  virtual void SpeakOrEnqueue(Utterance* utterance) override;
-  virtual void Stop() override;
-  virtual void Pause() override;
-  virtual void Resume() override;
-  virtual void OnTtsEvent(int utterance_id,
+  bool IsSpeaking() override;
+  void SpeakOrEnqueue(Utterance* utterance) override;
+  void Stop() override;
+  void Pause() override;
+  void Resume() override;
+  void OnTtsEvent(int utterance_id,
                   TtsEventType event_type,
                   int char_index,
                   const std::string& error_message) override;
-  virtual void GetVoices(content::BrowserContext* browser_context,
-                         std::vector<VoiceData>* out_voices) override;
-  virtual void VoicesChanged() override;
-  virtual void AddVoicesChangedDelegate(
-      VoicesChangedDelegate* delegate) override;
-  virtual void RemoveVoicesChangedDelegate(
-      VoicesChangedDelegate* delegate) override;
-  virtual void SetTtsEngineDelegate(TtsEngineDelegate* delegate) override;
-  virtual TtsEngineDelegate* GetTtsEngineDelegate() override;
-  virtual void SetPlatformImpl(TtsPlatformImpl* platform_impl) override;
-  virtual int QueueSize() override;
+  void GetVoices(content::BrowserContext* browser_context,
+                 std::vector<VoiceData>* out_voices) override;
+  void VoicesChanged() override;
+  void AddVoicesChangedDelegate(VoicesChangedDelegate* delegate) override;
+  void RemoveVoicesChangedDelegate(VoicesChangedDelegate* delegate) override;
+  void SetTtsEngineDelegate(TtsEngineDelegate* delegate) override;
+  TtsEngineDelegate* GetTtsEngineDelegate() override;
+  void SetPlatformImpl(TtsPlatformImpl* platform_impl) override;
+  int QueueSize() override;
 
  protected:
   TtsControllerImpl();
-  virtual ~TtsControllerImpl();
+  ~TtsControllerImpl() override;
 
  private:
   // Get the platform TTS implementation (or injected mock).
diff --git a/chrome/browser/speech/tts_controller_unittest.cc b/chrome/browser/speech/tts_controller_unittest.cc
index 7bd4155..9aa8450f 100644
--- a/chrome/browser/speech/tts_controller_unittest.cc
+++ b/chrome/browser/speech/tts_controller_unittest.cc
@@ -16,31 +16,30 @@
 class DummyTtsPlatformImpl : public TtsPlatformImpl {
  public:
   DummyTtsPlatformImpl() {}
-  virtual ~DummyTtsPlatformImpl() {}
-  virtual bool PlatformImplAvailable() override { return true; }
-  virtual bool Speak(
-      int utterance_id,
-      const std::string& utterance,
-      const std::string& lang,
-      const VoiceData& voice,
-      const UtteranceContinuousParameters& params) override {
+  ~DummyTtsPlatformImpl() override {}
+  bool PlatformImplAvailable() override { return true; }
+  bool Speak(int utterance_id,
+             const std::string& utterance,
+             const std::string& lang,
+             const VoiceData& voice,
+             const UtteranceContinuousParameters& params) override {
     return true;
   }
-  virtual bool IsSpeaking() override { return false; }
-  virtual bool StopSpeaking() override { return true; }
-  virtual void Pause() override {}
-  virtual void Resume() override {}
-  virtual void GetVoices(std::vector<VoiceData>* out_voices) override {}
-  virtual std::string error() override { return std::string(); }
-  virtual void clear_error() override {}
-  virtual void set_error(const std::string& error) override {}
+  bool IsSpeaking() override { return false; }
+  bool StopSpeaking() override { return true; }
+  void Pause() override {}
+  void Resume() override {}
+  void GetVoices(std::vector<VoiceData>* out_voices) override {}
+  std::string error() override { return std::string(); }
+  void clear_error() override {}
+  void set_error(const std::string& error) override {}
 };
 
 // Subclass of TtsController with a public ctor and dtor.
 class TestableTtsController : public TtsControllerImpl {
  public:
   TestableTtsController() {}
-  virtual ~TestableTtsController() {}
+  ~TestableTtsController() override {}
 };
 
 TEST_F(TtsApiControllerTest, TestTtsControllerShutdown) {
diff --git a/chrome/browser/speech/tts_mac.mm b/chrome/browser/speech/tts_mac.mm
index ed62b68..21aa9a2 100644
--- a/chrome/browser/speech/tts_mac.mm
+++ b/chrome/browser/speech/tts_mac.mm
@@ -50,26 +50,23 @@
 
 class TtsPlatformImplMac : public TtsPlatformImpl {
  public:
-  virtual bool PlatformImplAvailable() override {
-    return true;
-  }
+  bool PlatformImplAvailable() override { return true; }
 
-  virtual bool Speak(
-      int utterance_id,
-      const std::string& utterance,
-      const std::string& lang,
-      const VoiceData& voice,
-      const UtteranceContinuousParameters& params) override;
+  bool Speak(int utterance_id,
+             const std::string& utterance,
+             const std::string& lang,
+             const VoiceData& voice,
+             const UtteranceContinuousParameters& params) override;
 
-  virtual bool StopSpeaking() override;
+  bool StopSpeaking() override;
 
-  virtual void Pause() override;
+  void Pause() override;
 
-  virtual void Resume() override;
+  void Resume() override;
 
-  virtual bool IsSpeaking() override;
+  bool IsSpeaking() override;
 
-  virtual void GetVoices(std::vector<VoiceData>* out_voices) override;
+  void GetVoices(std::vector<VoiceData>* out_voices) override;
 
   // Called by ChromeTtsDelegate when we get a callback from the
   // native speech engine.
@@ -83,7 +80,7 @@
 
  private:
   TtsPlatformImplMac();
-  virtual ~TtsPlatformImplMac();
+  ~TtsPlatformImplMac() override;
 
   base::scoped_nsobject<SingleUseSpeechSynthesizer> speech_synthesizer_;
   base::scoped_nsobject<ChromeTtsDelegate> delegate_;
diff --git a/chrome/browser/speech/tts_message_filter.h b/chrome/browser/speech/tts_message_filter.h
index ab10440..11929a91 100644
--- a/chrome/browser/speech/tts_message_filter.h
+++ b/chrome/browser/speech/tts_message_filter.h
@@ -23,27 +23,26 @@
       content::BrowserContext* browser_context);
 
   // content::BrowserMessageFilter implementation.
-  virtual void OverrideThreadForMessage(
-      const IPC::Message& message,
-      content::BrowserThread::ID* thread) override;
-  virtual bool OnMessageReceived(const IPC::Message& message) override;
-  virtual void OnChannelClosing() override;
-  virtual void OnDestruct() const override;
+  void OverrideThreadForMessage(const IPC::Message& message,
+                                content::BrowserThread::ID* thread) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+  void OnChannelClosing() override;
+  void OnDestruct() const override;
 
   // UtteranceEventDelegate implementation.
-  virtual void OnTtsEvent(Utterance* utterance,
-                          TtsEventType event_type,
-                          int char_index,
-                          const std::string& error_message) override;
+  void OnTtsEvent(Utterance* utterance,
+                  TtsEventType event_type,
+                  int char_index,
+                  const std::string& error_message) override;
 
   // VoicesChangedDelegate implementation.
-  virtual void OnVoicesChanged() override;
+  void OnVoicesChanged() override;
 
  private:
   friend class content::BrowserThread;
   friend class base::DeleteHelper<TtsMessageFilter>;
 
-  virtual ~TtsMessageFilter();
+  ~TtsMessageFilter() override;
 
   void OnInitializeVoiceList();
   void OnSpeak(const TtsUtteranceRequest& utterance);
diff --git a/chrome/browser/ssl/ssl_blocking_page.cc b/chrome/browser/ssl/ssl_blocking_page.cc
index 56f91a7..19f27d5 100644
--- a/chrome/browser/ssl/ssl_blocking_page.cc
+++ b/chrome/browser/ssl/ssl_blocking_page.cc
@@ -232,9 +232,7 @@
   command.AppendArg(
       "'com.android.settings/.Settings$DateTimeSettingsActivity'");
 #elif defined(OS_IOS)
-  // Apparently, iOS really does not have a way to launch the date and time
-  // settings. Weird. TODO(palmer): Do something more graceful than ignoring
-  // the user's click! crbug.com/394993
+  // iOS does not have a way to launch the date and time settings.
   return;
 #elif defined(OS_LINUX)
   struct ClockCommand {
diff --git a/chrome/browser/supervised_user/supervised_user_browsertest.cc b/chrome/browser/supervised_user/supervised_user_browsertest.cc
index b41132d8..37d8229 100644
--- a/chrome/browser/supervised_user/supervised_user_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_browsertest.cc
@@ -228,6 +228,9 @@
                        HistoryVisitRecorded) {
   GURL allowed_url("http://www.example.com/files/simple.html");
 
+  scoped_refptr<SupervisedUserURLFilter> filter =
+      supervised_user_service_->GetURLFilterForUIThread();
+
   // Set the host as allowed.
   scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
   dict->SetBooleanWithoutPathExpansion(allowed_url.host(), true);
@@ -236,9 +239,10 @@
           browser()->profile());
   supervised_user_settings_service->SetLocalSettingForTesting(
       supervised_users::kContentPackManualBehaviorHosts, dict.Pass());
-  EXPECT_EQ(
-      SupervisedUserService::MANUAL_ALLOW,
-      supervised_user_service_->GetManualBehaviorForHost(allowed_url.host()));
+  EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
+            filter->GetFilteringBehaviorForURL(allowed_url));
+  EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
+            filter->GetFilteringBehaviorForURL(allowed_url.GetWithEmptyPath()));
 
   ui_test_utils::NavigateToURL(browser(), allowed_url);
 
@@ -258,13 +262,10 @@
   // Check that we went back to the first URL and that the manual behaviors
   // have not changed.
   EXPECT_EQ(allowed_url.spec(), tab->GetURL().spec());
-  EXPECT_EQ(SupervisedUserService::MANUAL_ALLOW,
-            supervised_user_service_->GetManualBehaviorForHost(
-                "www.example.com"));
-  EXPECT_EQ(
-      SupervisedUserService::MANUAL_NONE,
-      supervised_user_service_->GetManualBehaviorForHost(
-          "www.new-example.com"));
+  EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
+            filter->GetFilteringBehaviorForURL(allowed_url.GetWithEmptyPath()));
+  EXPECT_EQ(SupervisedUserURLFilter::BLOCK,
+            filter->GetFilteringBehaviorForURL(blocked_url.GetWithEmptyPath()));
 
   // Query the history entry.
   HistoryService* history_service = HistoryServiceFactory::GetForProfile(
@@ -302,9 +303,11 @@
           browser()->profile());
   supervised_user_settings_service->SetLocalSettingForTesting(
       supervised_users::kContentPackManualBehaviorHosts, dict.Pass());
-  EXPECT_EQ(
-      SupervisedUserService::MANUAL_ALLOW,
-      supervised_user_service_->GetManualBehaviorForHost(test_url.host()));
+
+  scoped_refptr<SupervisedUserURLFilter> filter =
+      supervised_user_service_->GetURLFilterForUIThread();
+  EXPECT_EQ(SupervisedUserURLFilter::ALLOW,
+            filter->GetFilteringBehaviorForURL(test_url.GetWithEmptyPath()));
 
   observer.Wait();
   EXPECT_EQ(test_url, web_contents->GetURL());
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index 5032516..67309b5 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -70,6 +70,14 @@
 using base::UserMetricsAction;
 using content::BrowserThread;
 
+base::FilePath SupervisedUserService::Delegate::GetBlacklistPath() const {
+  return base::FilePath();
+}
+
+GURL SupervisedUserService::Delegate::GetBlacklistURL() const {
+  return GURL();
+}
+
 SupervisedUserService::URLFilterContext::URLFilterContext()
     : ui_url_filter_(new SupervisedUserURLFilter),
       io_url_filter_(new SupervisedUserURLFilter) {}
@@ -308,6 +316,17 @@
   return name.empty() ? GetCustodianEmailAddress() : name;
 }
 
+std::string SupervisedUserService::GetSecondCustodianEmailAddress() const {
+  return profile_->GetPrefs()->GetString(
+      prefs::kSupervisedUserSecondCustodianEmail);
+}
+
+std::string SupervisedUserService::GetSecondCustodianName() const {
+  std::string name = profile_->GetPrefs()->GetString(
+      prefs::kSupervisedUserSecondCustodianName);
+  return name.empty() ? GetSecondCustodianEmailAddress() : name;
+}
+
 void SupervisedUserService::AddNavigationBlockedCallback(
     const NavigationBlockedCallback& callback) {
   navigation_blocked_callbacks_.push_back(callback);
@@ -519,8 +538,7 @@
     extensions::ExtensionResource site_list =
         extensions::SupervisedUserInfo::GetContentPackSiteList(extension.get());
     if (!site_list.empty()) {
-      site_lists.push_back(new SupervisedUserSiteList(extension->id(),
-                                                      site_list.GetFilePath()));
+      site_lists.push_back(new SupervisedUserSiteList(site_list.GetFilePath()));
     }
   }
 
@@ -662,43 +680,6 @@
                            0);
 }
 
-SupervisedUserService::ManualBehavior
-SupervisedUserService::GetManualBehaviorForHost(
-    const std::string& hostname) {
-  const base::DictionaryValue* dict =
-      profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualHosts);
-  bool allow = false;
-  if (!dict->GetBooleanWithoutPathExpansion(hostname, &allow))
-    return MANUAL_NONE;
-
-  return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
-}
-
-SupervisedUserService::ManualBehavior
-SupervisedUserService::GetManualBehaviorForURL(
-    const GURL& url) {
-  const base::DictionaryValue* dict =
-      profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
-  GURL normalized_url = SupervisedUserURLFilter::Normalize(url);
-  bool allow = false;
-  if (!dict->GetBooleanWithoutPathExpansion(normalized_url.spec(), &allow))
-    return MANUAL_NONE;
-
-  return allow ? MANUAL_ALLOW : MANUAL_BLOCK;
-}
-
-void SupervisedUserService::GetManualExceptionsForHost(
-    const std::string& host,
-    std::vector<GURL>* urls) {
-  const base::DictionaryValue* dict =
-      profile_->GetPrefs()->GetDictionary(prefs::kSupervisedUserManualURLs);
-  for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
-    GURL url(it.key());
-    if (url.host() == host)
-      urls->push_back(url);
-  }
-}
-
 void SupervisedUserService::InitSync(const std::string& refresh_token) {
   StartSetupSync();
 
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h
index 5f62466..53c63f4d 100644
--- a/chrome/browser/supervised_user/supervised_user_service.h
+++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -71,12 +71,6 @@
   typedef base::Callback<void(const GoogleServiceAuthError&)> AuthErrorCallback;
   typedef base::Callback<void(bool)> SuccessCallback;
 
-  enum ManualBehavior {
-    MANUAL_NONE = 0,
-    MANUAL_ALLOW,
-    MANUAL_BLOCK
-  };
-
   class Delegate {
    public:
     virtual ~Delegate() {}
@@ -85,10 +79,10 @@
     virtual bool SetActive(bool active) = 0;
     // Returns the path to a blacklist file to load, or an empty path to
     // indicate "none".
-    virtual base::FilePath GetBlacklistPath() const = 0;
+    virtual base::FilePath GetBlacklistPath() const;
     // Returns the URL from which to download a blacklist if no local one exists
     // yet. The blacklist file will be stored at |GetBlacklistPath()|.
-    virtual GURL GetBlacklistURL() const = 0;
+    virtual GURL GetBlacklistURL() const;
   };
 
   ~SupervisedUserService() override;
@@ -131,19 +125,13 @@
   // empty.
   std::string GetCustodianName() const;
 
-  // These methods allow querying and modifying the manual filtering behavior.
-  // The manual behavior is set by the user and overrides all other settings
-  // (whitelists or the default behavior).
+  // Returns the email address of the second custodian, or the empty string
+  // if there is no second custodian.
+  std::string GetSecondCustodianEmailAddress() const;
 
-  // Returns the manual behavior for the given host.
-  ManualBehavior GetManualBehaviorForHost(const std::string& hostname);
-
-  // Returns the manual behavior for the given URL.
-  ManualBehavior GetManualBehaviorForURL(const GURL& url);
-
-  // Returns all URLS on the given host that have exceptions.
-  void GetManualExceptionsForHost(const std::string& host,
-                                  std::vector<GURL>* urls);
+  // Returns the name of the second custodian, or the email address if the name
+  // is empty, or the empty string is there is no second custodian.
+  std::string GetSecondCustodianName() const;
 
   // Initializes this object. This method does nothing if the profile is not
   // supervised.
diff --git a/chrome/browser/supervised_user/supervised_user_service_unittest.cc b/chrome/browser/supervised_user/supervised_user_service_unittest.cc
index 8c3b46c..a37c3af 100644
--- a/chrome/browser/supervised_user/supervised_user_service_unittest.cc
+++ b/chrome/browser/supervised_user/supervised_user_service_unittest.cc
@@ -127,61 +127,6 @@
 
 }  // namespace
 
-TEST_F(SupervisedUserServiceTest, GetManualExceptionsForHost) {
-  GURL kExampleFooURL("http://www.example.com/foo");
-  GURL kExampleBarURL("http://www.example.com/bar");
-  GURL kExampleFooNoWWWURL("http://example.com/foo");
-  GURL kBlurpURL("http://blurp.net/bla");
-  GURL kMooseURL("http://moose.org/baz");
-  {
-    DictionaryPrefUpdate update(profile_->GetPrefs(),
-                                prefs::kSupervisedUserManualURLs);
-    base::DictionaryValue* dict = update.Get();
-    dict->SetBooleanWithoutPathExpansion(kExampleFooURL.spec(), true);
-    dict->SetBooleanWithoutPathExpansion(kExampleBarURL.spec(), false);
-    dict->SetBooleanWithoutPathExpansion(kExampleFooNoWWWURL.spec(), true);
-    dict->SetBooleanWithoutPathExpansion(kBlurpURL.spec(), true);
-  }
-
-  EXPECT_EQ(SupervisedUserService::MANUAL_ALLOW,
-            supervised_user_service_->GetManualBehaviorForURL(kExampleFooURL));
-  EXPECT_EQ(SupervisedUserService::MANUAL_BLOCK,
-            supervised_user_service_->GetManualBehaviorForURL(kExampleBarURL));
-  EXPECT_EQ(SupervisedUserService::MANUAL_ALLOW,
-            supervised_user_service_->GetManualBehaviorForURL(
-                kExampleFooNoWWWURL));
-  EXPECT_EQ(SupervisedUserService::MANUAL_ALLOW,
-            supervised_user_service_->GetManualBehaviorForURL(kBlurpURL));
-  EXPECT_EQ(SupervisedUserService::MANUAL_NONE,
-            supervised_user_service_->GetManualBehaviorForURL(kMooseURL));
-  std::vector<GURL> exceptions;
-  supervised_user_service_->GetManualExceptionsForHost("www.example.com",
-                                                       &exceptions);
-  ASSERT_EQ(2u, exceptions.size());
-  EXPECT_EQ(kExampleBarURL, exceptions[0]);
-  EXPECT_EQ(kExampleFooURL, exceptions[1]);
-
-  {
-    DictionaryPrefUpdate update(profile_->GetPrefs(),
-                                prefs::kSupervisedUserManualURLs);
-    base::DictionaryValue* dict = update.Get();
-    for (const GURL& url : exceptions)
-      dict->RemoveWithoutPathExpansion(url.spec(), NULL);
-  }
-
-  EXPECT_EQ(SupervisedUserService::MANUAL_NONE,
-            supervised_user_service_->GetManualBehaviorForURL(kExampleFooURL));
-  EXPECT_EQ(SupervisedUserService::MANUAL_NONE,
-            supervised_user_service_->GetManualBehaviorForURL(kExampleBarURL));
-  EXPECT_EQ(SupervisedUserService::MANUAL_ALLOW,
-            supervised_user_service_->GetManualBehaviorForURL(
-                kExampleFooNoWWWURL));
-  EXPECT_EQ(SupervisedUserService::MANUAL_ALLOW,
-            supervised_user_service_->GetManualBehaviorForURL(kBlurpURL));
-  EXPECT_EQ(SupervisedUserService::MANUAL_NONE,
-            supervised_user_service_->GetManualBehaviorForURL(kMooseURL));
-}
-
 TEST_F(SupervisedUserServiceTest, ChangesIncludedSessionOnChangedSettings) {
   supervised_user_service_->Init();
   EXPECT_TRUE(supervised_user_service_->IncludesSyncSessionsType());
diff --git a/chrome/browser/supervised_user/supervised_user_site_list.cc b/chrome/browser/supervised_user/supervised_user_site_list.cc
index 1bbba47..caf5027 100644
--- a/chrome/browser/supervised_user/supervised_user_site_list.cc
+++ b/chrome/browser/supervised_user/supervised_user_site_list.cc
@@ -8,7 +8,7 @@
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "extensions/common/extension.h"
+#include "url/gurl.h"
 
 const int kSitelistFormatVersion = 1;
 
@@ -17,8 +17,6 @@
 const char kNameKey[] = "name";
 const char kSitesKey[] = "sites";
 const char kSitelistFormatVersionKey[] = "version";
-const char kThumbnailKey[] = "thumbnail";
-const char kThumbnailUrlKey[] = "thumbnail_url";
 const char kUrlKey[] = "url";
 const char kWhitelistKey[] = "whitelist";
 
@@ -30,7 +28,7 @@
 };
 
 // These are placeholders for now.
-CategoryInfo g_categories[] = {
+const CategoryInfo g_categories[] = {
   {"com.google.chrome.animals", "Animals and Plants"},
   {"com.google.chrome.arts", "Arts"},
   {"com.google.chrome.business", "Business"},
@@ -127,17 +125,15 @@
 SupervisedUserSiteList::Site::~Site() {}
 
 SupervisedUserSiteList::SupervisedUserSiteList(
-    const std::string& extension_id,
     const base::FilePath& path)
-    : extension_id_(extension_id),
-      path_(path) {
+    : path_(path) {
 }
 
 SupervisedUserSiteList::~SupervisedUserSiteList() {
 }
 
 SupervisedUserSiteList* SupervisedUserSiteList::Clone() const {
-  return new SupervisedUserSiteList(extension_id_, path_);
+  return new SupervisedUserSiteList(path_);
 }
 
 // static
@@ -223,26 +219,3 @@
 
   return true;
 }
-
-void SupervisedUserSiteList::CopyThumbnailUrl(
-    const base::DictionaryValue* source,
-    base::DictionaryValue* dest) {
-  if (!source->HasKey(kThumbnailKey))
-    return;
-
-  std::string thumbnail;
-  if (!source->GetString(kThumbnailKey, &thumbnail)) {
-    LOG(ERROR) << "Invalid thumbnail";
-    return;
-  }
-
-  GURL base_url =
-      extensions::Extension::GetBaseURLFromExtensionId(extension_id_);
-  GURL thumbnail_url = base_url.Resolve(thumbnail);
-  if (!thumbnail_url.is_valid()) {
-    LOG(ERROR) << "Invalid thumbnail";
-    return;
-  }
-
-  dest->SetString(kThumbnailUrlKey, thumbnail_url.spec());
-}
diff --git a/chrome/browser/supervised_user/supervised_user_site_list.h b/chrome/browser/supervised_user/supervised_user_site_list.h
index abcb074..afb82f0 100644
--- a/chrome/browser/supervised_user/supervised_user_site_list.h
+++ b/chrome/browser/supervised_user/supervised_user_site_list.h
@@ -52,8 +52,7 @@
     std::vector<std::string> hostname_hashes;
   };
 
-  SupervisedUserSiteList(const std::string& extension_id,
-                         const base::FilePath& path);
+  explicit SupervisedUserSiteList(const base::FilePath& path);
   ~SupervisedUserSiteList();
 
   // Creates a copy of the site list.
@@ -70,10 +69,7 @@
 
  private:
   bool LazyLoad();
-  void CopyThumbnailUrl(const base::DictionaryValue* source,
-                        base::DictionaryValue* dest);
 
-  std::string extension_id_;
   base::FilePath path_;
   scoped_ptr<base::DictionaryValue> categories_;
   scoped_ptr<base::ListValue> sites_;
diff --git a/chrome/browser/sync/PRESUBMIT.py b/chrome/browser/sync/PRESUBMIT.py
index b3bcb5f..8420094 100644
--- a/chrome/browser/sync/PRESUBMIT.py
+++ b/chrome/browser/sync/PRESUBMIT.py
@@ -11,12 +11,12 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_rel_swarming': set(['defaulttests']),
+      'linux_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.mac': {
-      'mac_chromium_rel_swarming': set(['defaulttests']),
+      'mac_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.win': {
-      'win_chromium_rel_swarming': set(['defaulttests']),
+      'win_chromium_rel': set(['defaulttests']),
     }
   }
diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
index 5468d20..7f01963 100644
--- a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
+++ b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc
@@ -124,7 +124,7 @@
       bookmark_model_ = static_cast<BookmarkModel*>(
           BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
               &profile_, BuildBookmarkModel));
-      test::WaitForBookmarkModelToLoad(bookmark_model_);
+      bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model_);
     } else {
       bookmark_model_ = static_cast<BookmarkModel*>(
           BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
@@ -205,7 +205,7 @@
                         profile_.GetIOTaskRunner(),
                         content::BrowserThread::GetMessageLoopProxyForThread(
                             content::BrowserThread::UI));
-  test::WaitForBookmarkModelToLoad(bookmark_model_);
+  bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model_);
   EXPECT_EQ(DataTypeController::MODEL_LOADED, bookmark_dtc_->state());
 
   bookmark_dtc_->StartAssociating(
diff --git a/chrome/browser/sync/glue/sync_backend_registrar_unittest.cc b/chrome/browser/sync/glue/sync_backend_registrar_unittest.cc
index f1a62ee0..7067d99 100644
--- a/chrome/browser/sync/glue/sync_backend_registrar_unittest.cc
+++ b/chrome/browser/sync/glue/sync_backend_registrar_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/sync/glue/sync_backend_registrar.h"
 
+#include "base/run_loop.h"
 #include "chrome/browser/sync/glue/ui_model_worker.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/sync_driver/change_processor_mock.h"
@@ -272,15 +273,22 @@
       : thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD |
                        content::TestBrowserThreadBundle::REAL_FILE_THREAD |
                        content::TestBrowserThreadBundle::REAL_IO_THREAD),
-        db_thread_blocked_(false, false),
-        registrar_destroyed_(false, false) {}
+        db_thread_blocked_(false, false) {
+    quit_closure_ = run_loop_.QuitClosure();
+  }
 
   virtual ~SyncBackendRegistrarShutdownTest() {}
 
+  void PostQuitOnUIMessageLoop() {
+    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_closure_);
+  }
+
   content::TestBrowserThreadBundle thread_bundle_;
+  TestingProfile profile_;
   base::WaitableEvent db_thread_blocked_;
   base::Lock db_thread_lock_;
-  base::WaitableEvent registrar_destroyed_;
+  base::RunLoop run_loop_;
+  base::Closure quit_closure_;
 };
 
 // Wrap SyncBackendRegistrar so that we can monitor its lifetime.
@@ -291,7 +299,7 @@
       : SyncBackendRegistrar("test", profile, scoped_ptr<base::Thread>()),
         test_(test) {}
 
-  ~TestRegistrar() override { test_->registrar_destroyed_.Signal(); }
+  ~TestRegistrar() override { test_->PostQuitOnUIMessageLoop(); }
 
  private:
   SyncBackendRegistrarShutdownTest* test_;
@@ -308,8 +316,7 @@
       base::Bind(&SyncBackendRegistrarShutdownTest::BlockDBThread,
                  base::Unretained(this)));
 
-  TestingProfile profile;
-  scoped_ptr<TestRegistrar> registrar(new TestRegistrar(&profile, this));
+  scoped_ptr<TestRegistrar> registrar(new TestRegistrar(&profile_, this));
   base::Thread* sync_thread = registrar->sync_thread();
 
   // Stop here until the DB thread gets a chance to run and block on the lock.
@@ -323,6 +330,7 @@
 
   // Start the shutdown.
   registrar->RequestWorkerStopOnUIThread();
+
   sync_thread->message_loop()->PostTask(
       FROM_HERE,
       base::Bind(&SyncBackendRegistrar::Shutdown,
@@ -334,11 +342,9 @@
 
   db_thread_lock_.Release();
 
-  base::MessageLoop::current()->RunUntilIdle();
-
-  // This verifies that all workers have been removed and the registrar
-  // destroyed.
-  registrar_destroyed_.Wait();
+  // Run the main thread loop until all workers have been removed and the
+  // registrar destroyed.
+  run_loop_.Run();
 }
 
 }  // namespace
diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.cc b/chrome/browser/sync/profile_sync_components_factory_impl.cc
index e7c818e..95cee80 100644
--- a/chrome/browser/sync/profile_sync_components_factory_impl.cc
+++ b/chrome/browser/sync/profile_sync_components_factory_impl.cc
@@ -24,9 +24,6 @@
 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h"
 #include "chrome/browser/sync/glue/bookmark_model_associator.h"
 #include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h"
-#include "chrome/browser/sync/glue/extension_backed_data_type_controller.h"
-#include "chrome/browser/sync/glue/extension_data_type_controller.h"
-#include "chrome/browser/sync/glue/extension_setting_data_type_controller.h"
 #include "chrome/browser/sync/glue/history_delete_directives_data_type_controller.h"
 #include "chrome/browser/sync/glue/local_device_info_provider_impl.h"
 #include "chrome/browser/sync/glue/password_data_type_controller.h"
@@ -81,6 +78,9 @@
 #include "chrome/browser/extensions/api/storage/settings_sync_util.h"
 #include "chrome/browser/extensions/api/synced_notifications_private/synced_notifications_shim.h"
 #include "chrome/browser/extensions/extension_sync_service.h"
+#include "chrome/browser/sync/glue/extension_backed_data_type_controller.h"
+#include "chrome/browser/sync/glue/extension_data_type_controller.h"
+#include "chrome/browser/sync/glue/extension_setting_data_type_controller.h"
 #endif
 
 #if defined(ENABLE_MANAGED_USERS)
@@ -104,9 +104,11 @@
 using browser_sync::BookmarkDataTypeController;
 using browser_sync::BookmarkModelAssociator;
 using browser_sync::ChromeReportUnrecoverableError;
+#if defined(ENABLE_EXTENSIONS)
 using browser_sync::ExtensionBackedDataTypeController;
 using browser_sync::ExtensionDataTypeController;
 using browser_sync::ExtensionSettingDataTypeController;
+#endif
 using browser_sync::HistoryDeleteDirectivesDataTypeController;
 using browser_sync::PasswordDataTypeController;
 using browser_sync::SearchEngineDataTypeController;
@@ -303,6 +305,7 @@
     syncer::ModelTypeSet disabled_types,
     syncer::ModelTypeSet enabled_types,
     ProfileSyncService* pss) {
+#if defined(ENABLE_EXTENSIONS)
   // App sync is enabled by default.  Register unless explicitly
   // disabled.
   if (!disabled_types.Has(syncer::APPS)) {
@@ -316,6 +319,7 @@
     pss->RegisterDataTypeController(
         new ExtensionDataTypeController(syncer::EXTENSIONS, this, profile_));
   }
+#endif
 
   // Preference sync is enabled by default.  Register unless explicitly
   // disabled.
@@ -352,6 +356,7 @@
         new SearchEngineDataTypeController(this, profile_));
   }
 
+#if defined(ENABLE_EXTENSIONS)
   // Extension setting sync is enabled by default.  Register unless explicitly
   // disabled.
   if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) {
@@ -365,6 +370,7 @@
     pss->RegisterDataTypeController(new ExtensionSettingDataTypeController(
         syncer::APP_SETTINGS, this, profile_));
   }
+#endif
 
 #if defined(ENABLE_APP_LIST)
   if (app_list::switches::IsAppListSyncEnabled()) {
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc
index 8b1467fe..29effaf 100644
--- a/chrome/browser/sync/profile_sync_service_android.cc
+++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -43,10 +43,26 @@
 
 namespace {
 
-enum {
-#define DEFINE_MODEL_TYPE_SELECTION(name,value)  name = value,
-#include "chrome/browser/sync/profile_sync_service_model_type_selection_android.h"
-#undef DEFINE_MODEL_TYPE_SELECTION
+// This enum contains the list of sync ModelTypes that Android can register for
+// invalidations for.
+//
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.sync
+enum ModelTypeSelection {
+  AUTOFILL = 1 << 0,
+  BOOKMARK = 1 << 1,
+  PASSWORD = 1 << 2,
+  SESSION = 1 << 3,
+  TYPED_URL = 1 << 4,
+  AUTOFILL_PROFILE = 1 << 5,
+  HISTORY_DELETE_DIRECTIVE = 1 << 6,
+  PROXY_TABS = 1 << 7,
+  FAVICON_IMAGE = 1 << 8,
+  FAVICON_TRACKING = 1 << 9,
+  NIGORI = 1 << 10,
+  DEVICE_INFO = 1 << 11,
+  EXPERIMENTS = 1 << 12,
+  SUPERVISED_USER_SETTING = 1 << 13,
 };
 
 }  // namespace
diff --git a/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc b/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
index bd7a38c..071efe9 100644
--- a/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_bookmark_unittest.cc
@@ -274,7 +274,7 @@
 
 class ExtensiveChangesBookmarkModelObserver : public BaseBookmarkModelObserver {
  public:
-  explicit ExtensiveChangesBookmarkModelObserver()
+  ExtensiveChangesBookmarkModelObserver()
       : started_count_(0),
         completed_count_at_started_(0),
         completed_count_(0) {}
@@ -399,7 +399,7 @@
     bool delete_bookmarks = load == DELETE_EXISTING_STORAGE;
     profile_.CreateBookmarkModel(delete_bookmarks);
     model_ = BookmarkModelFactory::GetForProfile(&profile_);
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
     // This noticeably speeds up the unit tests that request it.
     if (save == DONT_SAVE_TO_STORAGE)
       model_->ClearStore();
diff --git a/chrome/browser/sync/profile_sync_service_model_type_selection_android.h b/chrome/browser/sync/profile_sync_service_model_type_selection_android.h
deleted file mode 100644
index 5da7e64..0000000
--- a/chrome/browser/sync/profile_sync_service_model_type_selection_android.h
+++ /dev/null
@@ -1,37 +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.
-
-// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum values.
-
-// This file contains the list of sync ModelTypes that Android can register for
-// invalidations for.
-
-DEFINE_MODEL_TYPE_SELECTION(AUTOFILL, 1<<0)
-
-DEFINE_MODEL_TYPE_SELECTION(BOOKMARK, 1<<1)
-
-DEFINE_MODEL_TYPE_SELECTION(PASSWORD, 1<<2)
-
-DEFINE_MODEL_TYPE_SELECTION(SESSION, 1<<3)
-
-DEFINE_MODEL_TYPE_SELECTION(TYPED_URL, 1<<4)
-
-DEFINE_MODEL_TYPE_SELECTION(AUTOFILL_PROFILE, 1<<5)
-
-DEFINE_MODEL_TYPE_SELECTION(HISTORY_DELETE_DIRECTIVE, 1<<6)
-
-DEFINE_MODEL_TYPE_SELECTION(PROXY_TABS, 1<<7)
-
-DEFINE_MODEL_TYPE_SELECTION(FAVICON_IMAGE, 1<<8)
-
-DEFINE_MODEL_TYPE_SELECTION(FAVICON_TRACKING, 1<<9)
-
-DEFINE_MODEL_TYPE_SELECTION(NIGORI, 1<<10)
-
-DEFINE_MODEL_TYPE_SELECTION(DEVICE_INFO, 1<<11)
-
-DEFINE_MODEL_TYPE_SELECTION(EXPERIMENTS, 1<<12)
-
-DEFINE_MODEL_TYPE_SELECTION(SUPERVISED_USER_SETTING, 1<<13)
diff --git a/chrome/browser/sync/sessions/session_data_type_controller.cc b/chrome/browser/sync/sessions/session_data_type_controller.cc
index b2468ba..fc503e8 100644
--- a/chrome/browser/sync/sessions/session_data_type_controller.cc
+++ b/chrome/browser/sync/sessions/session_data_type_controller.cc
@@ -72,6 +72,7 @@
 }
 
 void SessionDataTypeController::StopModels() {
+  subscription_.reset();
   notification_registrar_.RemoveAll();
 }
 
diff --git a/chrome/browser/sync/sessions/sessions_sync_manager.cc b/chrome/browser/sync/sessions/sessions_sync_manager.cc
index 0becf033..0a92ddd 100644
--- a/chrome/browser/sync/sessions/sessions_sync_manager.cc
+++ b/chrome/browser/sync/sessions/sessions_sync_manager.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/sync/sessions/sessions_util.h"
 #include "chrome/browser/sync/sessions/synced_window_delegates_getter.h"
 #include "chrome/common/url_constants.h"
+#include "components/sessions/content/content_serialized_navigation_builder.h"
 #include "components/sync_driver/local_device_info_provider.h"
 #include "content/public/browser/favicon_status.h"
 #include "content/public/browser/navigation_entry.h"
@@ -24,6 +25,7 @@
 #include "sync/api/time.h"
 
 using content::NavigationEntry;
+using sessions::ContentSerializedNavigationBuilder;
 using sessions::SerializedNavigationEntry;
 using sync_driver::DeviceInfo;
 using sync_driver::LocalDeviceInfoProvider;
@@ -975,7 +977,7 @@
       session_tab->current_navigation_index = session_tab->navigations.size();
 
     session_tab->navigations.push_back(
-        SerializedNavigationEntry::FromNavigationEntry(i, *entry));
+        ContentSerializedNavigationBuilder::FromNavigationEntry(i, *entry));
     if (is_supervised) {
       session_tab->navigations.back().set_blocked_state(
           SerializedNavigationEntry::STATE_ALLOWED);
@@ -995,7 +997,7 @@
     int offset = session_tab->navigations.size();
     for (size_t i = 0; i < blocked_navigations.size(); ++i) {
       session_tab->navigations.push_back(
-          SerializedNavigationEntry::FromNavigationEntry(
+          ContentSerializedNavigationBuilder::FromNavigationEntry(
               i + offset, *blocked_navigations[i]));
       session_tab->navigations.back().set_blocked_state(
           SerializedNavigationEntry::STATE_BLOCKED);
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index dc27dc4..729bc7e 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -350,7 +350,7 @@
 
   // Create the verifier profile.
   verifier_ = MakeProfile(FILE_PATH_LITERAL("Verifier"));
-  test::WaitForBookmarkModelToLoad(
+  bookmarks::test::WaitForBookmarkModelToLoad(
       BookmarkModelFactory::GetForProfile(verifier()));
   ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
       verifier(), Profile::EXPLICIT_ACCESS));
@@ -395,7 +395,7 @@
                                          << index << ".";
   InitializeInvalidations(index);
 
-  test::WaitForBookmarkModelToLoad(
+  bookmarks::test::WaitForBookmarkModelToLoad(
       BookmarkModelFactory::GetForProfile(GetProfile(index)));
   ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
       GetProfile(index), Profile::EXPLICIT_ACCESS));
diff --git a/chrome/browser/test_presubmit.py b/chrome/browser/test_presubmit.py
index fee5d4b..6552fcf 100755
--- a/chrome/browser/test_presubmit.py
+++ b/chrome/browser/test_presubmit.py
@@ -594,7 +594,8 @@
   }}
 
 @-webkit-keyframe blah {
-  100% { height: -500px 0; }
+  from { height: 0; }
+  100% { height: 500px; }
 }
 
 #rule {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index cc2e828d..cb1fa28 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -46,6 +46,7 @@
     "//chrome/browser/net:cert_logger_proto",
     "//chrome/common",
     "//chrome/common/net",
+    "//components/app_modal_dialogs",
     "//components/auto_login_parser",
     "//components/dom_distiller/webui",
     "//components/feedback/proto",
@@ -200,7 +201,7 @@
     if (!is_android) {
       sources += rebase_path(
           gypi_values.chrome_browser_ui_non_athena_non_android_sources,
-          ".", "//chrome")   
+          ".", "//chrome")
     }
     if (use_ash) {
       sources += rebase_path(
diff --git a/chrome/browser/ui/android/javascript_app_modal_dialog_android.cc b/chrome/browser/ui/android/javascript_app_modal_dialog_android.cc
index 0cdc5f4..3c7331fa 100644
--- a/chrome/browser/ui/android/javascript_app_modal_dialog_android.cc
+++ b/chrome/browser/ui/android/javascript_app_modal_dialog_android.cc
@@ -9,8 +9,8 @@
 #include "base/strings/utf_string_conversions.h"
 
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "components/app_modal_dialogs/app_modal_dialog_queue.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/javascript_message_type.h"
diff --git a/chrome/browser/ui/android/javascript_app_modal_dialog_android.h b/chrome/browser/ui/android/javascript_app_modal_dialog_android.h
index 5a731d1..af2ede5 100644
--- a/chrome/browser/ui/android/javascript_app_modal_dialog_android.h
+++ b/chrome/browser/ui/android/javascript_app_modal_dialog_android.h
@@ -8,7 +8,7 @@
 #include "base/android/jni_weak_ref.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 
 class JavaScriptAppModalDialog;
 
diff --git a/chrome/browser/ui/android/tab_model/tab_model_base.cc b/chrome/browser/ui/android/tab_model/tab_model_base.cc
deleted file mode 100644
index 1a17131c..0000000
--- a/chrome/browser/ui/android/tab_model/tab_model_base.cc
+++ /dev/null
@@ -1,39 +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/android/tab_model/tab_model_base.h"
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/android/jni_weak_ref.h"
-#include "chrome/browser/android/tab_android.h"
-#include "chrome/browser/ui/android/tab_model/tab_model.h"
-#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
-#include "jni/TabModelBase_jni.h"
-
-using base::android::AttachCurrentThread;
-using base::android::CheckException;
-using base::android::ConvertUTF8ToJavaString;
-using base::android::ConvertUTF16ToJavaString;
-using base::android::ScopedJavaLocalRef;
-
-TabModelBase::TabModelBase(JNIEnv* env, jobject obj, bool is_incognito)
-    : TabModelJniBridge(env, obj, is_incognito) {
-}
-
-
-// ----------------------------------------------------------------------------
-// Native JNI methods
-// ----------------------------------------------------------------------------
-
-static jlong Init(JNIEnv* env, jobject obj, jboolean is_incognito) {
-  TabModel* tab_model = new TabModelBase(env, obj, is_incognito);
-  return reinterpret_cast<intptr_t>(tab_model);
-}
-
-// Register native methods
-
-bool RegisterTabModelBase(JNIEnv* env) {
-  return RegisterNativesImpl(env);
-}
diff --git a/chrome/browser/ui/android/tab_model/tab_model_base.h b/chrome/browser/ui/android/tab_model/tab_model_base.h
deleted file mode 100644
index 2eed043..0000000
--- a/chrome/browser/ui/android/tab_model/tab_model_base.h
+++ /dev/null
@@ -1,38 +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_ANDROID_TAB_MODEL_TAB_MODEL_BASE_H_
-#define CHROME_BROWSER_UI_ANDROID_TAB_MODEL_TAB_MODEL_BASE_H_
-
-#include <jni.h>
-#include <vector>
-
-#include "base/android/jni_weak_ref.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h"
-
-class Profile;
-class TabAndroid;
-
-namespace content {
-class WebContents;
-}
-
-// Native representation of TabModelBase which provides access to information
-// about a tabstrip to native code and could potentially be used in place of
-// Browser for some functionality in Clank.
-class TabModelBase : public TabModelJniBridge {
- public:
-  TabModelBase(JNIEnv* env, jobject obj, bool is_incognito);
-  virtual ~TabModelBase() { }
-
-  // TabModel:
-};
-
-// Register the Tab's native methods through jni.
-bool RegisterTabModelBase(JNIEnv* env);
-
-#endif  // CHROME_BROWSER_UI_ANDROID_TAB_MODEL_TAB_MODEL_BASE_H_
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
index ccca4eb..65e4f6f 100644
--- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
@@ -43,9 +43,6 @@
     : TabModel(FindProfile(is_incognito)),
       java_object_(env, env->NewWeakGlobalRef(jobj)) {
   TabModelList::AddTabModel(this);
-  Java_TabModelJniBridge_setNativePtr(env,
-                                      jobj,
-                                      reinterpret_cast<intptr_t>(this));
 }
 
 void TabModelJniBridge::Destroy(JNIEnv* env, jobject obj) {
@@ -155,10 +152,13 @@
 
 TabModelJniBridge::~TabModelJniBridge() {
   TabModelList::RemoveTabModel(this);
-  JNIEnv* env = AttachCurrentThread();
-  Java_TabModelJniBridge_clearNativePtr(env, java_object_.get(env).obj());
 }
 
 bool TabModelJniBridge::Register(JNIEnv* env) {
   return RegisterNativesImpl(env);
 }
+
+static jlong Init(JNIEnv* env, jobject obj, jboolean is_incognito) {
+  TabModel* tab_model = new TabModelJniBridge(env, obj, is_incognito);
+  return reinterpret_cast<intptr_t>(tab_model);
+}
diff --git a/chrome/browser/ui/android/website_settings_popup_android.cc b/chrome/browser/ui/android/website_settings_popup_android.cc
index aecef2e..dcece726 100644
--- a/chrome/browser/ui/android/website_settings_popup_android.cc
+++ b/chrome/browser/ui/android/website_settings_popup_android.cc
@@ -11,12 +11,14 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/website_settings/website_settings.h"
 #include "chrome/browser/ui/website_settings/website_settings_ui.h"
+#include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/cert_store.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
+#include "grit/generated_resources.h"
 #include "jni/WebsiteSettingsPopup_jni.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -65,51 +67,25 @@
   delete this;
 }
 
+void WebsiteSettingsPopupAndroid::OnPermissionSettingChanged(JNIEnv* env,
+                                                             jobject obj,
+                                                             jint type,
+                                                             jint setting) {
+  ContentSettingsType content_setting_type =
+      static_cast<ContentSettingsType>(type);
+  ContentSetting content_setting = static_cast<ContentSetting>(setting);
+  presenter_->OnSitePermissionChanged(content_setting_type, content_setting);
+}
+
 void WebsiteSettingsPopupAndroid::SetIdentityInfo(
     const IdentityInfo& identity_info) {
   JNIEnv* env = base::android::AttachCurrentThread();
 
-  enum PageInfoConnectionType connection_type = CONNECTION_UNKNOWN;
-  switch (identity_info.connection_status) {
-    case WebsiteSettings::SITE_CONNECTION_STATUS_UNKNOWN:
-      connection_type = CONNECTION_UNKNOWN;
-      break;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED:
-      connection_type = CONNECTION_ENCRYPTED;
-      break;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_MIXED_CONTENT:
-      connection_type = CONNECTION_MIXED_CONTENT;
-      break;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_UNENCRYPTED:
-      connection_type = CONNECTION_UNENCRYPTED;
-      break;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED_ERROR:
-      connection_type = CONNECTION_ENCRYPTED_ERROR;
-      break;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_INTERNAL_PAGE:
-      connection_type = CONNECTION_INTERNAL_PAGE;
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
-
-  Java_WebsiteSettingsPopup_setURLTitle(
+  Java_WebsiteSettingsPopup_updatePageDetails(
       env,
       popup_jobject_.obj(),
-      ConvertUTF8ToJavaString(env, url_.scheme()).obj(),
-      ConvertUTF8ToJavaString(env, url_.host()).obj(),
-      ConvertUTF8ToJavaString(env, url_.path()).obj(),
-      static_cast<jint>(connection_type));
-
-  Java_WebsiteSettingsPopup_setConnectionMessage(
-      env,
-      popup_jobject_.obj(),
-      ConvertUTF16ToJavaString(
-          env,
-          l10n_util::GetStringUTF16(
-              WebsiteSettingsUI::GetConnectionSummaryMessageID(
-                  identity_info.connection_status))).obj());
+      identity_info.connection_status ==
+          WebsiteSettings::SITE_CONNECTION_STATUS_INTERNAL_PAGE);
 
   Java_WebsiteSettingsPopup_showDialog(env, popup_jobject_.obj());
 }
@@ -121,7 +97,43 @@
 
 void WebsiteSettingsPopupAndroid::SetPermissionInfo(
     const PermissionInfoList& permission_info_list) {
-  NOTIMPLEMENTED();
+  JNIEnv* env = base::android::AttachCurrentThread();
+
+  // On Android, we only want to display a subset of the available options in a
+  // particular order, but only if their value is different from the default.
+  std::vector<ContentSettingsType> permissions_to_display;
+  permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_GEOLOCATION);
+  permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM);
+  permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
+  permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_IMAGES);
+  permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
+  permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_POPUPS);
+
+  std::map<ContentSettingsType, ContentSetting>
+      user_specified_settings_to_display;
+
+  for (const auto& permission : permission_info_list) {
+    if (std::find(permissions_to_display.begin(),
+                  permissions_to_display.end(),
+                  permission.type) != permissions_to_display.end() &&
+        permission.setting != CONTENT_SETTING_DEFAULT) {
+      user_specified_settings_to_display[permission.type] = permission.setting;
+    }
+  }
+
+  for (const auto& permission : permissions_to_display) {
+    if (ContainsKey(user_specified_settings_to_display, permission)) {
+      base::string16 setting_title =
+          WebsiteSettingsUI::PermissionTypeToUIString(permission);
+
+      Java_WebsiteSettingsPopup_addPermissionSection(
+          env,
+          popup_jobject_.obj(),
+          ConvertUTF16ToJavaString(env, setting_title).obj(),
+          static_cast<jint>(permission),
+          static_cast<jint>(user_specified_settings_to_display[permission]));
+    }
+  }
 }
 
 void WebsiteSettingsPopupAndroid::SetSelectedTab(
diff --git a/chrome/browser/ui/android/website_settings_popup_android.h b/chrome/browser/ui/android/website_settings_popup_android.h
index 89ef601..57f5ec0 100644
--- a/chrome/browser/ui/android/website_settings_popup_android.h
+++ b/chrome/browser/ui/android/website_settings_popup_android.h
@@ -35,6 +35,10 @@
                               content::WebContents* web_contents);
   virtual ~WebsiteSettingsPopupAndroid();
   void Destroy(JNIEnv* env, jobject obj);
+  void OnPermissionSettingChanged(JNIEnv* env,
+                                  jobject obj,
+                                  jint type,
+                                  jint setting);
 
   // WebsiteSettingsUI implementations.
   virtual void SetCookieInfo(const CookieInfoList& cookie_info_list) override;
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate.cc b/chrome/browser/ui/app_list/app_list_controller_delegate.cc
index 5d8efc1..318ec8a 100644
--- a/chrome/browser/ui/app_list/app_list_controller_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_controller_delegate.cc
@@ -26,6 +26,7 @@
 #include "ui/app_list/app_list_item.h"
 #include "ui/app_list/app_list_model.h"
 #include "ui/app_list/app_list_switches.h"
+#include "ui/gfx/geometry/rect.h"
 
 #if defined(ENABLE_RLZ)
 #include "chrome/browser/rlz/rlz.h"
diff --git a/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc b/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
index e807582..d6c74a85 100644
--- a/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
+++ b/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
@@ -9,16 +9,14 @@
 #include "base/i18n/rtl.h"
 #include "base/memory/singleton.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/grit/generated_resources.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
+#include "components/app_modal_dialogs/app_modal_dialog_queue.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/javascript_message_type.h"
+#include "grit/components_strings.h"
 #include "net/base/net_util.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -171,11 +169,14 @@
   base::TimeDelta time_since_last_message = base::TimeTicks::Now() -
       extra_data->last_javascript_message_dismissal_;
   bool display_suppress_checkbox = false;
-  // Show a checkbox offering to suppress further messages if this message is
-  // being displayed within kJavaScriptMessageExpectedDelay of the last one.
+  // If a WebContents is impolite and displays a second JavaScript
+  // alert within kJavaScriptMessageExpectedDelay of a previous
+  // JavaScript alert being dismissed, show a checkbox offering to
+  // suppress future alerts from this WebContents.
+  const int kJavaScriptMessageExpectedDelay = 1000;
+
   if (time_since_last_message <
-      base::TimeDelta::FromMilliseconds(
-          chrome::kJavaScriptMessageExpectedDelay)) {
+      base::TimeDelta::FromMilliseconds(kJavaScriptMessageExpectedDelay)) {
     display_suppress_checkbox = true;
   } else {
     display_suppress_checkbox = false;
diff --git a/chrome/browser/ui/athena/extensions/DEPS b/chrome/browser/ui/athena/extensions/DEPS
index 564bb5e2..84a0082f 100644
--- a/chrome/browser/ui/athena/extensions/DEPS
+++ b/chrome/browser/ui/athena/extensions/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
+  "+athena/activity/public",
   "+athena/extensions/public",
 ]
diff --git a/chrome/browser/ui/athena/extensions/application_launch_web_app_athena.cc b/chrome/browser/ui/athena/extensions/application_launch_web_app_athena.cc
new file mode 100644
index 0000000..f280d551
--- /dev/null
+++ b/chrome/browser/ui/athena/extensions/application_launch_web_app_athena.cc
@@ -0,0 +1,52 @@
+// 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/extensions/application_launch_web_app.h"
+
+#include <string>
+
+#include "athena/activity/public/activity.h"
+#include "athena/activity/public/activity_factory.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/web_contents.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/common/extension.h"
+
+namespace {
+
+const extensions::Extension* GetExtension(const AppLaunchParams& params) {
+  if (params.extension_id.empty())
+    return NULL;
+
+  using extensions::ExtensionRegistry;
+  ExtensionRegistry* registry = ExtensionRegistry::Get(params.profile);
+  return registry->GetExtensionById(params.extension_id,
+                                    ExtensionRegistry::ENABLED |
+                                        ExtensionRegistry::DISABLED |
+                                        ExtensionRegistry::TERMINATED);
+}
+
+}  // namespace
+
+content::WebContents* OpenWebAppWindow(const AppLaunchParams& params,
+                                       const GURL& url) {
+  const extensions::Extension* extension = GetExtension(params);
+  athena::Activity* activity =
+      athena::ActivityFactory::Get()->CreateWebActivity(
+          params.profile, base::UTF8ToUTF16(extension->name()), url);
+  athena::Activity::Show(activity);
+
+  // TODO: http://crbug.com/8123 we should not need to set the initial focus
+  //       explicitly.
+  content::WebContents* web_contents = activity->GetWebContents();
+  web_contents->SetInitialFocus();
+  return web_contents;
+}
+
+content::WebContents* OpenWebAppTab(const AppLaunchParams& params,
+                                    const GURL& url) {
+  // There are no tabbed windows in Athena. Open a new window instead.
+  return OpenWebAppWindow(params, url);
+}
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index d34482d..41f2aaa 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
-#include "chrome/browser/ui/zoom/zoom_controller.h"
 #include "chrome/browser/webdata/web_data_service_factory.h"
 #include "chrome/common/url_constants.h"
 #include "components/autofill/content/browser/content_autofill_driver.h"
@@ -30,6 +29,8 @@
 #if defined(OS_ANDROID)
 #include "chrome/browser/android/chromium_application.h"
 #include "chrome/browser/ui/android/autofill/autofill_logger_android.h"
+#else
+#include "chrome/browser/ui/zoom/zoom_controller.h"
 #endif
 
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::ChromeAutofillClient);
@@ -39,6 +40,8 @@
 ChromeAutofillClient::ChromeAutofillClient(content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents), web_contents_(web_contents) {
   DCHECK(web_contents);
+
+#if !defined(OS_ANDROID)
   // Since ZoomController is also a WebContentsObserver, we need to be careful
   // about disconnecting from it since the relative order of destruction of
   // WebContentsObservers is not guaranteed. ZoomController silently clears
@@ -46,9 +49,11 @@
   // to explicitly remove ourselves on destruction.
   ZoomController* zoom_controller =
       ZoomController::FromWebContents(web_contents);
-  // There may not always be a ZoomController, e.g. on Android.
+  // There may not always be a ZoomController, e.g. in tests.
   if (zoom_controller)
     zoom_controller->AddObserver(this);
+#endif
+
 #if defined(OS_MACOSX) && !defined(OS_IOS)
   RegisterForKeystoneNotifications();
 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
diff --git a/chrome/browser/ui/autofill/password_generation_popup_controller.h b/chrome/browser/ui/autofill/password_generation_popup_controller.h
index e7c18b07..640203c 100644
--- a/chrome/browser/ui/autofill/password_generation_popup_controller.h
+++ b/chrome/browser/ui/autofill/password_generation_popup_controller.h
@@ -42,6 +42,7 @@
   // Translated strings
   virtual base::string16 SuggestedText() = 0;
   virtual const base::string16& HelpText() = 0;
+  virtual base::string16 AccessibleName() = 0;
   virtual const gfx::Range& HelpTextLinkRange() = 0;
 
  protected:
diff --git a/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc b/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc
index a2a2c7f9..76f1bd197 100644
--- a/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/password_generation_popup_controller_impl.cc
@@ -273,6 +273,10 @@
   return help_text_;
 }
 
+base::string16 PasswordGenerationPopupControllerImpl::AccessibleName() {
+  return l10n_util::GetStringUTF16(IDS_PASSWORD_GENERATION_ACCESSIBLE_TITLE);
+}
+
 const gfx::Range& PasswordGenerationPopupControllerImpl::HelpTextLinkRange() {
   return link_range_;
 }
diff --git a/chrome/browser/ui/autofill/password_generation_popup_controller_impl.h b/chrome/browser/ui/autofill/password_generation_popup_controller_impl.h
index 238d362..aa5bad99 100644
--- a/chrome/browser/ui/autofill/password_generation_popup_controller_impl.h
+++ b/chrome/browser/ui/autofill/password_generation_popup_controller_impl.h
@@ -103,6 +103,7 @@
   base::string16 password() const override;
   base::string16 SuggestedText() override;
   const base::string16& HelpText() override;
+  base::string16 AccessibleName() override;
   const gfx::Range& HelpTextLinkRange() override;
 
   base::WeakPtr<PasswordGenerationPopupControllerImpl> GetWeakPtr();
diff --git a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
index b96c0b1..035f7e03 100644
--- a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
@@ -80,7 +80,7 @@
   BookmarkModel* WaitForBookmarkModel(Profile* profile) {
     BookmarkModel* bookmark_model =
         BookmarkModelFactory::GetForProfile(profile);
-    test::WaitForBookmarkModelToLoad(bookmark_model);
+    bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
     return bookmark_model;
   }
 
diff --git a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc
index 3394688f..86388e1 100644
--- a/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc
@@ -55,7 +55,7 @@
     profile_ = builder.Build();
     profile_->CreateBookmarkModel(true);
     model_ = BookmarkModelFactory::GetForProfile(profile_.get());
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
     AddTestData(model_);
   }
 
@@ -245,7 +245,7 @@
 
   incognito->CreateBookmarkModel(true);
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(incognito);
-  test::WaitForBookmarkModelToLoad(model);
+  bookmarks::test::WaitForBookmarkModelToLoad(model);
   AddTestData(model);
 
   std::vector<const BookmarkNode*> nodes;
diff --git a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc
index 7d0c389..afc0f0a 100644
--- a/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc
+++ b/chrome/browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc
@@ -69,7 +69,7 @@
 void RecentlyUsedFoldersComboModelTest::SetUp() {
   profile_.reset(new TestingProfile());
   profile_->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(GetModel());
+  bookmarks::test::WaitForBookmarkModelToLoad(GetModel());
 }
 
 void RecentlyUsedFoldersComboModelTest::TearDown() {
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 1b5e697..94037f21 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1304,9 +1304,15 @@
 
   // If the download occurs in a new tab, and it's not a save page
   // download (started before initial navigation completed) close it.
+  // Avoid calling CloseContents if the tab is not in this browser's tab strip
+  // model; this can happen if the download was initiated by something internal
+  // to Chrome, such as by the app list.
   WebContents* source = download->GetWebContents();
   if (source && source->GetController().IsInitialNavigation() &&
-      tab_strip_model_->count() > 1 && !download->IsSavePackageDownload()) {
+      tab_strip_model_->count() > 1 &&
+      tab_strip_model_->GetIndexOfWebContents(source) !=
+          TabStripModel::kNoTab &&
+      !download->IsSavePackageDownload()) {
     CloseContents(source);
   }
 
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index cbff1c9..54acd9c 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -32,10 +32,6 @@
 #include "chrome/browser/sessions/session_service_factory.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/translate/cld_data_harness.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -60,6 +56,10 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/test_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
+#include "components/app_modal_dialogs/app_modal_dialog_queue.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/translate/core/common/language_detection_details.h"
 #include "content/public/browser/favicon_status.h"
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 0010021..dab47af 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -562,7 +562,6 @@
       break;
     case IDC_ENCODING_UTF8:
     case IDC_ENCODING_UTF16LE:
-    case IDC_ENCODING_ISO88591:
     case IDC_ENCODING_WINDOWS1252:
     case IDC_ENCODING_GBK:
     case IDC_ENCODING_GB18030:
@@ -909,7 +908,6 @@
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
-  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
   command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index ac37ac9..12b537b 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -18,6 +18,8 @@
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/location_bar/location_bar.h"
+#include "chrome/browser/ui/omnibox/omnibox_view.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_switches.h"
@@ -137,9 +139,9 @@
 
 void BrowserNavigatorTest::RunSuppressTest(WindowOpenDisposition disposition) {
   GURL old_url = browser()->tab_strip_model()->GetActiveWebContents()->GetURL();
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = disposition;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = disposition;
+  chrome::Navigate(&params);
 
   // Nothing should have happened as a result of Navigate();
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
@@ -156,15 +158,15 @@
   EXPECT_EQ(1, incognito_browser->tab_strip_model()->count());
 
   // Navigate to the page.
-  chrome::NavigateParams p(MakeNavigateParams(incognito_browser));
-  p.disposition = SINGLETON_TAB;
-  p.url = url;
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams(incognito_browser));
+  params.disposition = SINGLETON_TAB;
+  params.url = url;
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  chrome::Navigate(&params);
 
   // This page should be opened in browser() window.
-  EXPECT_NE(incognito_browser, p.browser);
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_NE(incognito_browser, params.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(url,
             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
@@ -183,14 +185,14 @@
                      IncognitoModePrefs::FORCED);
 
   // Navigate to the page.
-  chrome::NavigateParams p(MakeNavigateParams(browser));
-  p.disposition = OFF_THE_RECORD;
-  p.url = url;
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams(browser));
+  params.disposition = OFF_THE_RECORD;
+  params.url = url;
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  chrome::Navigate(&params);
 
   // The page should not be opened.
-  EXPECT_EQ(browser, p.browser);
+  EXPECT_EQ(browser, params.browser);
   EXPECT_EQ(1, browser->tab_strip_model()->count());
   EXPECT_EQ(GURL(url::kAboutBlankURL),
             browser->tab_strip_model()->GetActiveWebContents()->GetURL());
@@ -260,13 +262,13 @@
       created_tab_contents_count_ = 0;
 
   // Navigate to singleton_url1.
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = singleton_url1;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = singleton_url1;
+  chrome::Navigate(&params);
 
   // The middle tab should now be selected.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
 
   // No tab contents should have been created
@@ -289,37 +291,37 @@
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
 
   // Navigate to singleton_url2.
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = singleton_ref_url2;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = singleton_ref_url2;
+  chrome::Navigate(&params);
 
   // We should now have 2 tabs, the 2nd one selected.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
 
   // Navigate to singleton_url2, but with respect ref set.
-  p = MakeNavigateParams();
-  p.disposition = SINGLETON_TAB;
-  p.url = singleton_ref_url2;
-  p.ref_behavior = chrome::NavigateParams::RESPECT_REF;
-  chrome::Navigate(&p);
+  params = MakeNavigateParams();
+  params.disposition = SINGLETON_TAB;
+  params.url = singleton_ref_url2;
+  params.ref_behavior = chrome::NavigateParams::RESPECT_REF;
+  chrome::Navigate(&params);
 
   // We should now have 3 tabs, the 3th one selected.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(3, browser()->tab_strip_model()->count());
   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
 
   // Navigate to singleton_url3.
-  p = MakeNavigateParams();
-  p.disposition = SINGLETON_TAB;
-  p.url = singleton_ref_url3;
-  p.ref_behavior = chrome::NavigateParams::RESPECT_REF;
-  chrome::Navigate(&p);
+  params = MakeNavigateParams();
+  params.disposition = SINGLETON_TAB;
+  params.url = singleton_ref_url3;
+  params.ref_behavior = chrome::NavigateParams::RESPECT_REF;
+  chrome::Navigate(&params);
 
   // We should now have 4 tabs, the 4th one selected.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(4, browser()->tab_strip_model()->count());
   EXPECT_EQ(3, browser()->tab_strip_model()->active_index());
 }
@@ -333,13 +335,13 @@
   EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
 
   // Navigate to singleton_url1.
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = singleton_url1;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = singleton_url1;
+  chrome::Navigate(&params);
 
   // We should now have 2 tabs, the 2nd one selected.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
 }
@@ -350,13 +352,13 @@
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewForegroundTab) {
   WebContents* old_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_FOREGROUND_TAB;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_FOREGROUND_TAB;
+  chrome::Navigate(&params);
   EXPECT_NE(old_contents,
             browser()->tab_strip_model()->GetActiveWebContents());
   EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
-            p.target_contents);
+            params.target_contents);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
 }
 
@@ -365,9 +367,9 @@
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewBackgroundTab) {
   WebContents* old_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_BACKGROUND_TAB;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_BACKGROUND_TAB;
+  chrome::Navigate(&params);
   WebContents* new_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   // The selected tab should have remained unchanged, since the new tab was
@@ -385,17 +387,17 @@
   // existing compatible window somewhere else that they can be opened within.
   Browser* popup = CreateEmptyBrowserForType(Browser::TYPE_POPUP,
                                              browser()->profile());
-  chrome::NavigateParams p(MakeNavigateParams(popup));
-  p.disposition = NEW_FOREGROUND_TAB;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams(popup));
+  params.disposition = NEW_FOREGROUND_TAB;
+  chrome::Navigate(&params);
 
   // Navigate() should have opened the tab in a different browser since the
   // one we supplied didn't support additional tabs.
-  EXPECT_NE(popup, p.browser);
+  EXPECT_NE(popup, params.browser);
 
   // Since browser() is an existing compatible tabbed browser, it should have
   // opened the tab there.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
 
   // We should be left with 2 windows, the popup with one tab and the browser()
   // provided by the framework with two.
@@ -418,17 +420,17 @@
   Browser* popup = CreateEmptyBrowserForType(
       Browser::TYPE_POPUP,
       browser()->profile()->GetOffTheRecordProfile());
-  chrome::NavigateParams p(MakeNavigateParams(popup));
-  p.disposition = NEW_FOREGROUND_TAB;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams(popup));
+  params.disposition = NEW_FOREGROUND_TAB;
+  chrome::Navigate(&params);
 
   // Navigate() should have opened the tab in a different browser since the
   // one we supplied didn't support additional tabs.
-  EXPECT_NE(popup, p.browser);
+  EXPECT_NE(popup, params.browser);
 
   // This time, browser() is _not_ compatible with popup since it is not an
   // incognito window.
-  EXPECT_NE(browser(), p.browser);
+  EXPECT_NE(browser(), params.browser);
 
   // We should have three windows, each with one tab:
   // 1. the browser() provided by the framework (unchanged in this test)
@@ -437,82 +439,82 @@
   EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, popup->tab_strip_model()->count());
-  EXPECT_EQ(1, p.browser->tab_strip_model()->count());
-  EXPECT_TRUE(p.browser->is_type_tabbed());
+  EXPECT_EQ(1, params.browser->tab_strip_model()->count());
+  EXPECT_TRUE(params.browser->is_type_tabbed());
 }
 
 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
 // from a normal Browser results in a new Browser with TYPE_POPUP.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopup) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_POPUP;
-  p.window_bounds = gfx::Rect(0, 0, 200, 200);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_POPUP;
+  params.window_bounds = gfx::Rect(0, 0, 200, 200);
   // Wait for new popup to to load and gain focus.
-  ui_test_utils::NavigateToURL(&p);
+  ui_test_utils::NavigateToURL(&params);
 
   // Navigate() should have opened a new, focused popup window.
-  EXPECT_NE(browser(), p.browser);
+  EXPECT_NE(browser(), params.browser);
 #if 0
   // TODO(stevenjb): Enable this test. See: crbug.com/79493
-  EXPECT_TRUE(p.browser->window()->IsActive());
+  EXPECT_TRUE(browser->window()->IsActive());
 #endif
-  EXPECT_TRUE(p.browser->is_type_popup());
-  EXPECT_FALSE(p.browser->is_app());
+  EXPECT_TRUE(params.browser->is_type_popup());
+  EXPECT_FALSE(params.browser->is_app());
 
   // We should have two windows, the browser() provided by the framework and the
   // new popup window.
   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(1, p.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params.browser->tab_strip_model()->count());
 }
 
 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
 // from a normal Browser results in a new Browser with is_app() true.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopup_ExtensionId) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_POPUP;
-  p.extension_app_id = "extensionappid";
-  p.window_bounds = gfx::Rect(0, 0, 200, 200);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_POPUP;
+  params.extension_app_id = "extensionappid";
+  params.window_bounds = gfx::Rect(0, 0, 200, 200);
   // Wait for new popup to to load and gain focus.
-  ui_test_utils::NavigateToURL(&p);
+  ui_test_utils::NavigateToURL(&params);
 
   // Navigate() should have opened a new, focused popup window.
-  EXPECT_NE(browser(), p.browser);
-  EXPECT_TRUE(p.browser->is_type_popup());
-  EXPECT_TRUE(p.browser->is_app());
+  EXPECT_NE(browser(), params.browser);
+  EXPECT_TRUE(params.browser->is_type_popup());
+  EXPECT_TRUE(params.browser->is_app());
 
   // We should have two windows, the browser() provided by the framework and the
   // new popup window.
   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(1, p.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params.browser->tab_strip_model()->count());
 }
 
 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
 // from a normal popup results in a new Browser with TYPE_POPUP.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupFromPopup) {
   // Open a popup.
-  chrome::NavigateParams p1(MakeNavigateParams());
-  p1.disposition = NEW_POPUP;
-  p1.window_bounds = gfx::Rect(0, 0, 200, 200);
-  chrome::Navigate(&p1);
+  chrome::NavigateParams params1(MakeNavigateParams());
+  params1.disposition = NEW_POPUP;
+  params1.window_bounds = gfx::Rect(0, 0, 200, 200);
+  chrome::Navigate(&params1);
   // Open another popup.
-  chrome::NavigateParams p2(MakeNavigateParams(p1.browser));
-  p2.disposition = NEW_POPUP;
-  p2.window_bounds = gfx::Rect(0, 0, 200, 200);
-  chrome::Navigate(&p2);
+  chrome::NavigateParams params2(MakeNavigateParams(params1.browser));
+  params2.disposition = NEW_POPUP;
+  params2.window_bounds = gfx::Rect(0, 0, 200, 200);
+  chrome::Navigate(&params2);
 
   // Navigate() should have opened a new normal popup window.
-  EXPECT_NE(p1.browser, p2.browser);
-  EXPECT_TRUE(p2.browser->is_type_popup());
-  EXPECT_FALSE(p2.browser->is_app());
+  EXPECT_NE(params1.browser, params2.browser);
+  EXPECT_TRUE(params2.browser->is_type_popup());
+  EXPECT_FALSE(params2.browser->is_app());
 
   // We should have three windows, the browser() provided by the framework,
   // the first popup window, and the second popup window.
   EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(1, p1.browser->tab_strip_model()->count());
-  EXPECT_EQ(1, p2.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params1.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params2.browser->tab_strip_model()->count());
 }
 
 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
@@ -520,23 +522,23 @@
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                        Disposition_NewPopupFromAppWindow) {
   Browser* app_browser = CreateEmptyBrowserForApp(browser()->profile());
-  chrome::NavigateParams p(MakeNavigateParams(app_browser));
-  p.disposition = NEW_POPUP;
-  p.window_bounds = gfx::Rect(0, 0, 200, 200);
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams(app_browser));
+  params.disposition = NEW_POPUP;
+  params.window_bounds = gfx::Rect(0, 0, 200, 200);
+  chrome::Navigate(&params);
 
   // Navigate() should have opened a new popup app window.
-  EXPECT_NE(app_browser, p.browser);
-  EXPECT_NE(browser(), p.browser);
-  EXPECT_TRUE(p.browser->is_type_popup());
-  EXPECT_TRUE(p.browser->is_app());
+  EXPECT_NE(app_browser, params.browser);
+  EXPECT_NE(browser(), params.browser);
+  EXPECT_TRUE(params.browser->is_type_popup());
+  EXPECT_TRUE(params.browser->is_app());
 
   // We should now have three windows, the app window, the app popup it created,
   // and the original browser() provided by the framework.
   EXPECT_EQ(3u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, app_browser->tab_strip_model()->count());
-  EXPECT_EQ(1, p.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params.browser->tab_strip_model()->count());
 }
 
 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
@@ -545,29 +547,29 @@
                        Disposition_NewPopupFromAppPopup) {
   Browser* app_browser = CreateEmptyBrowserForApp(browser()->profile());
   // Open an app popup.
-  chrome::NavigateParams p1(MakeNavigateParams(app_browser));
-  p1.disposition = NEW_POPUP;
-  p1.window_bounds = gfx::Rect(0, 0, 200, 200);
-  chrome::Navigate(&p1);
+  chrome::NavigateParams params1(MakeNavigateParams(app_browser));
+  params1.disposition = NEW_POPUP;
+  params1.window_bounds = gfx::Rect(0, 0, 200, 200);
+  chrome::Navigate(&params1);
   // Now open another app popup.
-  chrome::NavigateParams p2(MakeNavigateParams(p1.browser));
-  p2.disposition = NEW_POPUP;
-  p2.window_bounds = gfx::Rect(0, 0, 200, 200);
-  chrome::Navigate(&p2);
+  chrome::NavigateParams params2(MakeNavigateParams(params1.browser));
+  params2.disposition = NEW_POPUP;
+  params2.window_bounds = gfx::Rect(0, 0, 200, 200);
+  chrome::Navigate(&params2);
 
   // Navigate() should have opened a new popup app window.
-  EXPECT_NE(browser(), p1.browser);
-  EXPECT_NE(p1.browser, p2.browser);
-  EXPECT_TRUE(p2.browser->is_type_popup());
-  EXPECT_TRUE(p2.browser->is_app());
+  EXPECT_NE(browser(), params1.browser);
+  EXPECT_NE(params1.browser, params2.browser);
+  EXPECT_TRUE(params2.browser->is_type_popup());
+  EXPECT_TRUE(params2.browser->is_app());
 
   // We should now have four windows, the app window, the first app popup,
   // the second app popup, and the original browser() provided by the framework.
   EXPECT_EQ(4u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, app_browser->tab_strip_model()->count());
-  EXPECT_EQ(1, p1.browser->tab_strip_model()->count());
-  EXPECT_EQ(1, p2.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params1.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params2.browser->tab_strip_model()->count());
 }
 
 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
@@ -580,16 +582,16 @@
 // This test verifies that navigating with window_action = SHOW_WINDOW_INACTIVE
 // does not focus a new new popup window.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupUnfocused) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_POPUP;
-  p.window_bounds = gfx::Rect(0, 0, 200, 200);
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW_INACTIVE;
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_POPUP;
+  params.window_bounds = gfx::Rect(0, 0, 200, 200);
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW_INACTIVE;
   // Wait for new popup to load (and gain focus if the test fails).
-  ui_test_utils::NavigateToURL(&p);
+  ui_test_utils::NavigateToURL(&params);
 
   // Navigate() should have opened a new, unfocused, popup window.
-  EXPECT_NE(browser(), p.browser);
-  EXPECT_EQ(Browser::TYPE_POPUP, p.browser->type());
+  EXPECT_NE(browser(), params.browser);
+  EXPECT_EQ(Browser::TYPE_POPUP, params.browser->type());
 #if 0
 // TODO(stevenjb): Enable this test. See: crbug.com/79493
   EXPECT_FALSE(p.browser->window()->IsActive());
@@ -600,59 +602,59 @@
 // and trusted_source = true results in a new Browser where is_trusted_source()
 // is true.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupTrusted) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_POPUP;
-  p.trusted_source = true;
-  p.window_bounds = gfx::Rect(0, 0, 200, 200);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_POPUP;
+  params.trusted_source = true;
+  params.window_bounds = gfx::Rect(0, 0, 200, 200);
   // Wait for new popup to to load and gain focus.
-  ui_test_utils::NavigateToURL(&p);
+  ui_test_utils::NavigateToURL(&params);
 
   // Navigate() should have opened a new popup window of TYPE_TRUSTED_POPUP.
-  EXPECT_NE(browser(), p.browser);
-  EXPECT_TRUE(p.browser->is_type_popup());
-  EXPECT_TRUE(p.browser->is_trusted_source());
+  EXPECT_NE(browser(), params.browser);
+  EXPECT_TRUE(params.browser->is_type_popup());
+  EXPECT_TRUE(params.browser->is_trusted_source());
 }
 
 
 // This test verifies that navigating with WindowOpenDisposition = NEW_WINDOW
 // always opens a new window.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewWindow) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_WINDOW;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_WINDOW;
+  chrome::Navigate(&params);
 
   // Navigate() should have opened a new toplevel window.
-  EXPECT_NE(browser(), p.browser);
-  EXPECT_TRUE(p.browser->is_type_tabbed());
+  EXPECT_NE(browser(), params.browser);
+  EXPECT_TRUE(params.browser->is_type_tabbed());
 
   // We should now have two windows, the browser() provided by the framework and
   // the new normal window.
   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(1, p.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params.browser->tab_strip_model()->count());
 }
 
 // This test verifies that navigating with WindowOpenDisposition = INCOGNITO
 // opens a new incognito window if no existing incognito window is present.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_Incognito) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = OFF_THE_RECORD;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = OFF_THE_RECORD;
+  chrome::Navigate(&params);
 
   // Navigate() should have opened a new toplevel incognito window.
-  EXPECT_NE(browser(), p.browser);
+  EXPECT_NE(browser(), params.browser);
   EXPECT_EQ(browser()->profile()->GetOffTheRecordProfile(),
-            p.browser->profile());
+            params.browser->profile());
 
   // |source_contents| should be set to NULL because the profile for the new
   // page is different from the originating page.
-  EXPECT_EQ(NULL, p.source_contents);
+  EXPECT_EQ(NULL, params.source_contents);
 
   // We should now have two windows, the browser() provided by the framework and
   // the new incognito window.
   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(1, p.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params.browser->tab_strip_model()->count());
 }
 
 // This test verifies that navigating with WindowOpenDisposition = INCOGNITO
@@ -661,13 +663,13 @@
   Browser* incognito_browser =
       CreateEmptyBrowserForType(Browser::TYPE_TABBED,
                                 browser()->profile()->GetOffTheRecordProfile());
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = OFF_THE_RECORD;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = OFF_THE_RECORD;
+  chrome::Navigate(&params);
 
   // Navigate() should have opened a new tab in the existing incognito window.
-  EXPECT_NE(browser(), p.browser);
-  EXPECT_EQ(p.browser, incognito_browser);
+  EXPECT_NE(browser(), params.browser);
+  EXPECT_EQ(params.browser, incognito_browser);
 
   // We should now have two windows, the browser() provided by the framework and
   // the incognito window we opened earlier.
@@ -696,16 +698,16 @@
 
 // This tests adding a foreground tab with a predefined WebContents.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, TargetContents_ForegroundTab) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_FOREGROUND_TAB;
-  p.target_contents = CreateWebContents();
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_FOREGROUND_TAB;
+  params.target_contents = CreateWebContents();
+  chrome::Navigate(&params);
 
   // Navigate() should have opened the contents in a new foreground in the
   // current Browser.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
-            p.target_contents);
+            params.target_contents);
 
   // We should have one window, with two tabs.
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
@@ -715,39 +717,39 @@
 #if defined(OS_WIN)
 // This tests adding a popup with a predefined WebContents.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, DISABLED_TargetContents_Popup) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_POPUP;
-  p.target_contents = CreateWebContents();
-  p.window_bounds = gfx::Rect(10, 10, 500, 500);
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_POPUP;
+  params.target_contents = CreateWebContents();
+  params.window_bounds = gfx::Rect(10, 10, 500, 500);
+  chrome::Navigate(&params);
 
   // Navigate() should have opened a new popup window.
-  EXPECT_NE(browser(), p.browser);
-  EXPECT_TRUE(p.browser->is_type_popup());
-  EXPECT_FALSE(p.browser->is_app());
+  EXPECT_NE(browser(), params.browser);
+  EXPECT_TRUE(params.browser->is_type_popup());
+  EXPECT_FALSE(params.browser->is_app());
 
   // The web platform is weird. The window bounds specified in
-  // |p.window_bounds| are used as follows:
+  // |params.window_bounds| are used as follows:
   // - the origin is used to position the window
   // - the size is used to size the WebContents of the window.
   // As such the position of the resulting window will always match
-  // p.window_bounds.origin(), but its size will not. We need to match
+  // params.window_bounds.origin(), but its size will not. We need to match
   // the size against the selected tab's view's container size.
-  // Only Windows positions the window according to |p.window_bounds.origin()| -
-  // on Mac the window is offset from the opener and on Linux it always opens
-  // at 0,0.
-  EXPECT_EQ(p.window_bounds.origin(),
-            p.browser->window()->GetRestoredBounds().origin());
+  // Only Windows positions the window according to
+  // |params.window_bounds.origin()| - on Mac the window is offset from the
+  // opener and on Linux it always opens at 0,0.
+  EXPECT_EQ(params.window_bounds.origin(),
+            params.browser->window()->GetRestoredBounds().origin());
   // All platforms should respect size however provided width > 400 (Mac has a
   // minimum window width of 400).
-  EXPECT_EQ(p.window_bounds.size(),
-            p.target_contents->GetContainerBounds().size());
+  EXPECT_EQ(params.window_bounds.size(),
+            params.target_contents->GetContainerBounds().size());
 
   // We should have two windows, the new popup and the browser() provided by the
   // framework.
   EXPECT_EQ(2u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(1, p.browser->tab_strip_model()->count());
+  EXPECT_EQ(1, params.browser->tab_strip_model()->count());
 }
 #endif
 
@@ -757,16 +759,16 @@
   // implementation of the browser observes the insertion index. That is
   // covered by the unit tests for TabStripModel. This merely verifies that
   // insertion index preference is reflected in common cases.
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = NEW_FOREGROUND_TAB;
-  p.tabstrip_index = 0;
-  p.tabstrip_add_types = TabStripModel::ADD_FORCE_INDEX;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_FOREGROUND_TAB;
+  params.tabstrip_index = 0;
+  params.tabstrip_add_types = TabStripModel::ADD_FORCE_INDEX;
+  chrome::Navigate(&params);
 
   // Navigate() should have inserted a new tab at slot 0 in the tabstrip.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(0, browser()->tab_strip_model()->GetIndexOfWebContents(
-      static_cast<const WebContents*>(p.target_contents)));
+      static_cast<const WebContents*>(params.target_contents)));
 
   // We should have one window - the browser() provided by the framework.
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
@@ -787,16 +789,16 @@
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
 
   // Navigate to a new singleton tab with a sub-page.
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = GetContentSettingsURL();
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  p.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = GetContentSettingsURL();
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
+  chrome::Navigate(&params);
 
   // The last tab should now be selected and navigated to the sub-page of the
   // URL.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(3, browser()->tab_strip_model()->count());
   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
   EXPECT_EQ(GetContentSettingsURL(),
@@ -821,16 +823,16 @@
   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
 
   // Navigate to singleton_url1.
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = GetContentSettingsURL();
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  p.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = GetContentSettingsURL();
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
+  chrome::Navigate(&params);
 
   // The middle tab should now be selected and navigated to the sub-page of the
   // URL.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(3, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
   EXPECT_EQ(GetContentSettingsURL(),
@@ -855,16 +857,16 @@
   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
 
   // Navigate to singleton_url1.
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = GetClearBrowsingDataURL();
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  p.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = GetClearBrowsingDataURL();
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
+  chrome::Navigate(&params);
 
   // The middle tab should now be selected and navigated to the sub-page of the
   // URL.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(3, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
   EXPECT_EQ(GetClearBrowsingDataURL(),
@@ -889,15 +891,15 @@
   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
 
   // Navigate to singleton_url1.
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = GetClearBrowsingDataURL();
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  p.path_behavior = chrome::NavigateParams::IGNORE_AND_STAY_PUT;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = GetClearBrowsingDataURL();
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  params.path_behavior = chrome::NavigateParams::IGNORE_AND_STAY_PUT;
+  chrome::Navigate(&params);
 
   // The middle tab should now be selected.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(3, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
   EXPECT_EQ(singleton_url1,
@@ -921,15 +923,15 @@
 
   // Navigate to a different settings path.
   GURL singleton_url_target(GetClearBrowsingDataURL());
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = singleton_url_target;
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  p.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = singleton_url_target;
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
+  chrome::Navigate(&params);
 
   // The second tab should still be selected, but navigated to the new path.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
   EXPECT_EQ(singleton_url_target,
@@ -954,15 +956,15 @@
   GURL singleton_url_target(
       "chrome://settings/internet?"
       "servicePath=/profile/ethernet_00aa00aa00aa&networkType=1");
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = singleton_url_target;
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  p.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
-  chrome::Navigate(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = singleton_url_target;
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
+  chrome::Navigate(&params);
 
   // Last tab should still be selected.
-  EXPECT_EQ(browser(), p.browser);
+  EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(initial_tab_count + 1, browser()->tab_strip_model()->count());
   EXPECT_EQ(initial_tab_count, browser()->tab_strip_model()->active_index());
 }
@@ -1062,12 +1064,12 @@
   web_contents->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
   EXPECT_TRUE(web_contents->IsCrashed());
 
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.disposition = SINGLETON_TAB;
-  p.url = singleton_url;
-  p.window_action = chrome::NavigateParams::SHOW_WINDOW;
-  p.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
-  ui_test_utils::NavigateToURL(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = SINGLETON_TAB;
+  params.url = singleton_url;
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
+  ui_test_utils::NavigateToURL(&params);
 
   // The tab should not be sad anymore.
   EXPECT_FALSE(web_contents->IsCrashed());
@@ -1090,9 +1092,9 @@
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                        NavigateFromBlankToOptionsInSameTab) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.url = GURL(url::kAboutBlankURL);
-  ui_test_utils::NavigateToURL(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.url = GURL(url::kAboutBlankURL);
+  ui_test_utils::NavigateToURL(&params);
 
   {
     content::WindowedNotificationObserver observer(
@@ -1109,9 +1111,9 @@
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                        NavigateFromNTPToOptionsInSameTab) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  p.url = GURL(chrome::kChromeUINewTabURL);
-  ui_test_utils::NavigateToURL(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.url = GURL(chrome::kChromeUINewTabURL);
+  ui_test_utils::NavigateToURL(&params);
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
   EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
@@ -1131,8 +1133,8 @@
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                        NavigateFromPageToOptionsInNewTab) {
-  chrome::NavigateParams p(MakeNavigateParams());
-  ui_test_utils::NavigateToURL(&p);
+  chrome::NavigateParams params(MakeNavigateParams());
+  ui_test_utils::NavigateToURL(&params);
   EXPECT_EQ(GetGoogleURL(),
             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
@@ -1376,4 +1378,39 @@
   EXPECT_NE(expected_title, title);
 }
 
+// This test navigates to a data URL that contains BiDi control
+// characters. For security reasons, BiDi control chars should always be
+// escaped in the URL but they should be unescaped in the loaded HTML.
+IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
+                       NavigateToDataURLWithBiDiControlChars) {
+  // Text in Arabic.
+  std::string text = "\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1";
+  // Page title starts with RTL mark.
+  std::string unescaped_title = "\xE2\x80\x8F" + text;
+  std::string data_url = "data:text/html;charset=utf-8,<html><title>" +
+                         unescaped_title + "</title></html>";
+  // BiDi control chars in URLs are always escaped, so the expected URL should
+  // have the title with the escaped RTL mark.
+  std::string escaped_title = "%E2%80%8F" + text;
+  std::string expected_url = "data:text/html;charset=utf-8,<html><title>" +
+                             escaped_title + "</title></html>";
+
+  // Navigate to the page.
+  chrome::NavigateParams params(MakeNavigateParams());
+  params.disposition = NEW_FOREGROUND_TAB;
+  params.url = GURL(data_url);
+  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+  ui_test_utils::NavigateToURL(&params);
+
+  base::string16 expected_title(base::UTF8ToUTF16(unescaped_title));
+  EXPECT_TRUE(params.target_contents);
+  EXPECT_EQ(expected_title, params.target_contents->GetTitle());
+  // GURL always keeps non-ASCII characters escaped, but check them anyways.
+  EXPECT_EQ(GURL(expected_url).spec(), params.target_contents->GetURL().spec());
+  // Check the omnibox text. It should have escaped RTL with unescaped text.
+  LocationBar* location_bar = browser()->window()->GetLocationBar();
+  OmniboxView* omnibox_view = location_bar->GetOmniboxView();
+  EXPECT_EQ(base::UTF8ToUTF16(expected_url), omnibox_view->GetText());
+}
+
 }  // namespace
diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc
index 134a3cf5d..a90291e 100644
--- a/chrome/browser/ui/browser_tabrestore.cc
+++ b/chrome/browser/ui/browser_tabrestore.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/browser_tabrestore.h"
 
+#include "base/memory/scoped_vector.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/session_service.h"
@@ -13,6 +14,7 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_contents_sizer.h"
+#include "components/sessions/content/content_serialized_navigation_builder.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/session_storage_namespace.h"
@@ -21,6 +23,7 @@
 using content::WebContents;
 using content::NavigationController;
 using content::NavigationEntry;
+using sessions::ContentSerializedNavigationBuilder;
 using sessions::SerializedNavigationEntry;
 
 namespace chrome {
@@ -69,9 +72,12 @@
   extensions::TabHelper::CreateForWebContents(web_contents);
   extensions::TabHelper::FromWebContents(web_contents)->
       SetExtensionAppById(extension_app_id);
-  std::vector<NavigationEntry*> entries =
-      SerializedNavigationEntry::ToNavigationEntries(
+  ScopedVector<NavigationEntry> scoped_entries =
+      ContentSerializedNavigationBuilder::ToNavigationEntries(
           navigations, browser->profile());
+  // NavigationController::Restore() expects to take ownership of the entries.
+  std::vector<NavigationEntry*> entries;
+  scoped_entries.release(&entries);
   web_contents->SetUserAgentOverride(user_agent_override);
   web_contents->GetController().Restore(
       selected_navigation, GetRestoreType(browser, from_last_session),
diff --git a/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm b/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm
index c6cab329..cf8e64cd 100644
--- a/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm
+++ b/chrome/browser/ui/cocoa/applescript/bookmark_applescript_utils_unittest.mm
@@ -67,7 +67,7 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string modelString("a f1:[ b d c ] d f2:[ e f g ] h ");
-  test::AddNodesFromModelString(model, root, modelString);
+  bookmarks::test::AddNodesFromModelString(model, root, modelString);
   bookmarkBar_.reset([[BookmarkFolderAppleScript alloc]
       initWithBookmarkNode:model->bookmark_bar_node()]);
 }
diff --git a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
index 8fc9e52..79fefcd7 100644
--- a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
@@ -164,11 +164,12 @@
       autofill::kPopupBorderThickness;
 
   width = std::max(width, (CGFloat)controller_->GetMinimumWidth());
+  CGFloat contentWidth = width - (2 * controller_->kHorizontalPadding);
 
   CGFloat height =
       autofill::kPopupBorderThickness +
       controller_->kHelpVerticalPadding +
-      [self helpSizeForPopupWidth:width].height +
+      [self helpSizeForPopupWidth:contentWidth].height +
       controller_->kHelpVerticalPadding +
       autofill::kPopupBorderThickness;
 
diff --git a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa_unittest.mm b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa_unittest.mm
index 2123185..7e9633b8 100644
--- a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa_unittest.mm
@@ -42,6 +42,10 @@
     return base::ASCIIToUTF16("Suggested by Chrome");
   }
 
+  virtual base::string16 AccessibleName() override {
+    return base::ASCIIToUTF16("Password Suggestion");
+  }
+
   virtual const base::string16& HelpText() override { return help_text_; }
 
   virtual const gfx::Range& HelpTextLinkRange() override { return link_range_; }
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
index 2a7eff4..65a4353 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
@@ -1265,10 +1265,10 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b 4f:[ 4f1b 4f2b ] ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model and that we do not have a folder controller.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
   EXPECT_FALSE([bar_ folderController]);
 
@@ -1484,10 +1484,10 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Remember how many buttons are showing.
@@ -1562,7 +1562,7 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
   [bar_ frameDidChange];
 
   // The default font changed between OSX Mavericks and OSX Yosemite, so this
@@ -1594,7 +1594,7 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
   [bar_ frameDidChange];
 
   // Apps page shortcut button should be visible.
@@ -1815,10 +1815,10 @@
       "3bWithLongName 4bWithLongName 5bWithLongName 6bWithLongName "
       "7bWithLongName 8bWithLongName 9bWithLongName 10bWithLongName "
       "11bWithLongName 12bWithLongName 13b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Insure that the off-the-side is not showing.
@@ -1867,16 +1867,16 @@
       "11bWithLongName 12bWithLongName 13bWithLongName 14bWithLongName "
       "15bWithLongName 16bWithLongName 17bWithLongName 18bWithLongName "
       "19bWithLongName 20bWithLongName ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   const BookmarkNode* other = model->other_node();
   const std::string other_string("1other 2other 3other ");
-  test::AddNodesFromModelString(model, other, other_string);
+  bookmarks::test::AddNodesFromModelString(model, other, other_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
-  std::string actualOtherString = test::ModelStringFromNode(other);
+  std::string actualOtherString = bookmarks::test::ModelStringFromNode(other);
   EXPECT_EQ(other_string, actualOtherString);
 
   // Insure that the off-the-side is showing.
@@ -1920,16 +1920,16 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                                   "2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
   const BookmarkNode* other = model->other_node();
   const std::string other_string("O1b O2b O3f:[ O3f1b O3f2f ] "
                                  "O4f:[ O4f1b O4f2f ] 05b ");
-  test::AddNodesFromModelString(model, other, other_string);
+  bookmarks::test::AddNodesFromModelString(model, other, other_string);
 
   // Validate initial model.
-  std::string actual = test::ModelStringFromNode(root);
+  std::string actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actual);
-  actual = test::ModelStringFromNode(other);
+  actual = bookmarks::test::ModelStringFromNode(other);
   EXPECT_EQ(other_string, actual);
 
   // Remember the little ones.
@@ -1951,7 +1951,7 @@
   // Verify the model.
   const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                              "2f3b ] O3f:[ O3f1b O3f2f ] 3b 4b ");
-  actual = test::ModelStringFromNode(root);
+  actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(expected, actual);
   oldChildCount = newChildCount;
 
@@ -1971,7 +1971,7 @@
   const std::string expected1("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                               "2f3b O4f:[ O4f1b O4f2f ] ] O3f:[ O3f1b O3f2f ] "
                               "3b 4b ");
-  actual = test::ModelStringFromNode(root);
+  actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(expected1, actual);
 }
 
@@ -1980,10 +1980,10 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                                  "2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actual = test::ModelStringFromNode(root);
+  std::string actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actual);
 
   // Remember the children.
@@ -2003,7 +2003,7 @@
   // Verify the model.
   const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                              "2f3b ] SiteA SiteB 3b 4b ");
-  actual = test::ModelStringFromNode(root);
+  actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(expected, actual);
 }
 
@@ -2011,10 +2011,10 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Find the main bar controller.
@@ -2027,7 +2027,7 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2b 2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Hide the apps shortcut.
   profile()->GetPrefs()->SetBoolean(
@@ -2035,7 +2035,7 @@
   ASSERT_TRUE([bar_ appsPageShortcutButtonIsHidden]);
 
   // Validate initial model.
-  std::string actualModel = test::ModelStringFromNode(root);
+  std::string actualModel = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModel);
 
   // Test a series of points starting at the right edge of the bar.
@@ -2102,10 +2102,10 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                                   "2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actual = test::ModelStringFromNode(root);
+  std::string actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actual);
 
   int oldChildCount = root->child_count();
@@ -2122,7 +2122,7 @@
   // Verify the model.
   const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                              "2f3b ] 4b ");
-  actual = test::ModelStringFromNode(root);
+  actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(expected, actual);
 
   // Verify that the other bookmark folder can't be deleted.
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
index 4b9c3ac..b5b7bbc0 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
@@ -729,10 +729,10 @@
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
       "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
       "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Pop up a folder menu and drag in a button from the bar.
@@ -761,7 +761,7 @@
   const std::string expected_string("2f:[ 2f1b 1b 2f2f:[ 2f2f1b "
       "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ "
       "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  EXPECT_EQ(expected_string, test::ModelStringFromNode(root));
+  EXPECT_EQ(expected_string, bookmarks::test::ModelStringFromNode(root));
 
   // Verify the window still appears by looking for its controller.
   EXPECT_TRUE([bar_ folderController]);
@@ -792,7 +792,7 @@
   [bar_ dragButton:draggedButton
                 to:[targetButton left]
               copy:NO];
-  EXPECT_EQ(model_string, test::ModelStringFromNode(root));
+  EXPECT_EQ(model_string, bookmarks::test::ModelStringFromNode(root));
   // Don't check the folder window since it's not supposed to be showing.
 }
 
@@ -802,10 +802,10 @@
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
       "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
       "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Pop up a folder menu and copy in a button from the bar.
@@ -833,7 +833,7 @@
   const std::string expected_1("1b 2f:[ 2f1b 1b 2f2f:[ 2f2f1b "
     "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ "
     "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  EXPECT_EQ(expected_1, test::ModelStringFromNode(root));
+  EXPECT_EQ(expected_1, bookmarks::test::ModelStringFromNode(root));
 
   // Gather the new frames.
   NSRect newToFolderFrame = [toFolder frame];
@@ -857,7 +857,7 @@
   const std::string expected_2("1b 2f:[ 2f1b 1b 2f2f:[ 2f2f1b "
       "2f2f2b 2f2f3b ] 2f3b ] 3b 1b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ "
       "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  EXPECT_EQ(expected_2, test::ModelStringFromNode(root));
+  EXPECT_EQ(expected_2, bookmarks::test::ModelStringFromNode(root));
 }
 
 TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveBarBookmarkToSubfolder) {
@@ -866,10 +866,10 @@
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
       "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
       "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Pop up a folder menu and a subfolder menu.
@@ -907,7 +907,7 @@
   const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b "
       "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ "
       "4f2f1b 4f2f2b 4f2f3b 5b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] ");
-  EXPECT_EQ(expected_string, test::ModelStringFromNode(root));
+  EXPECT_EQ(expected_string, bookmarks::test::ModelStringFromNode(root));
 
   // Check button spacing.
   [folderController validateMenuSpacing];
@@ -931,10 +931,10 @@
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
       "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
       "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Pop up a folder menu.
@@ -961,7 +961,7 @@
   const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b "
       "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f2f:[ 4f2f1b 4f2f2b 4f2f3b ] "
       "4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  EXPECT_EQ(expected_string, test::ModelStringFromNode(root));
+  EXPECT_EQ(expected_string, bookmarks::test::ModelStringFromNode(root));
 
   // The window should not have gone away.
   EXPECT_TRUE([bar_ folderController]);
@@ -980,10 +980,10 @@
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
       "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
       "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Pop up a folder menu.
@@ -1005,7 +1005,7 @@
                             to:[targetButton top]
                           copy:NO];
   // The model should not have changed.
-  EXPECT_EQ(model_string, test::ModelStringFromNode(root));
+  EXPECT_EQ(model_string, bookmarks::test::ModelStringFromNode(root));
 
   // Check button spacing.
   [folderController validateMenuSpacing];
@@ -1017,10 +1017,10 @@
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
       "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
       "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Pop up a folder menu and a subfolder menu.
@@ -1053,7 +1053,7 @@
   const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
       "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f3b 4f2f:[ "
       "4f2f1b 4f2f2b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
-  EXPECT_EQ(expected_string, test::ModelStringFromNode(root));
+  EXPECT_EQ(expected_string, bookmarks::test::ModelStringFromNode(root));
 
   // Check button spacing.
   [folderController validateMenuSpacing];
@@ -1068,10 +1068,10 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string(
       "a b:[ b1 b2 b3 ] reallyReallyLongBookmarkName c ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Pop up a folder menu.
@@ -1097,7 +1097,7 @@
   // Verify the model change.
   const std::string expected_string(
       "a b:[ b1 reallyReallyLongBookmarkName b2 b3 ] c ");
-  EXPECT_EQ(expected_string, test::ModelStringFromNode(root));
+  EXPECT_EQ(expected_string, bookmarks::test::ModelStringFromNode(root));
   // Verify the window grew. Just test a reasonable width gain.
   CGFloat newWidth = NSWidth([toWindow frame]);
   EXPECT_LT(oldWidth + 30.0, newWidth);
@@ -1107,10 +1107,10 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2b 2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Pop up a folder menu.
@@ -1207,10 +1207,10 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Find the main bar controller.
@@ -1242,10 +1242,10 @@
   BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2b 3b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   const BookmarkNode* parent = model->bookmark_bar_node();
@@ -1406,16 +1406,16 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                                  "2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
   const BookmarkNode* other = model->other_node();
   const std::string other_string("O1b O2b O3f:[ O3f1b O3f2f ] "
                                  "O4f:[ O4f1b O4f2f ] 05b ");
-  test::AddNodesFromModelString(model, other, other_string);
+  bookmarks::test::AddNodesFromModelString(model, other, other_string);
 
   // Validate initial model.
-  std::string actual = test::ModelStringFromNode(root);
+  std::string actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actual);
-  actual = test::ModelStringFromNode(other);
+  actual = bookmarks::test::ModelStringFromNode(other);
   EXPECT_EQ(other_string, actual);
 
   // Pop open a folder.
@@ -1440,7 +1440,7 @@
   // Verify the model.
   const std::string expected("1b 2f:[ O3f:[ O3f1b O3f2f ] 2f1b 2f2f:[ 2f2f1b "
                              "2f2f2b 2f2f3b ] 2f3b ] 3b 4b ");
-  actual = test::ModelStringFromNode(root);
+  actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(expected, actual);
 
   // Now drag over a folder button.
@@ -1456,7 +1456,7 @@
   const std::string expectedA("1b 2f:[ O3f:[ O3f1b O3f2f ] 2f1b 2f2f:[ "
                               "2f2f1b 2f2f2b 2f2f3b O4f:[ O4f1b O4f2f ] ] "
                               "2f3b ] 3b 4b ");
-  actual = test::ModelStringFromNode(root);
+  actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(expectedA, actual);
 
   // Check button spacing.
@@ -1468,10 +1468,10 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                                  "2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actual = test::ModelStringFromNode(root);
+  std::string actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actual);
 
   const BookmarkNode* folderNode = root->GetChild(1);
@@ -1499,7 +1499,7 @@
   // Verify the model.
   const std::string expected("1b 2f:[ 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                              "2f3b ] 3b 4b ");
-  actual = test::ModelStringFromNode(root);
+  actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(expected, actual);
 
   // Check button spacing.
@@ -1511,10 +1511,10 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                                  "2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actual = test::ModelStringFromNode(root);
+  std::string actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actual);
 
   // Pop open a folder.
@@ -1544,7 +1544,7 @@
   // Verify the model.
   const std::string expected("1b 2f:[ SiteA SiteB 2f1b 2f2f:[ 2f2f1b 2f2f2b "
                              "2f2f3b ] 2f3b ] 3b 4b ");
-  actual = test::ModelStringFromNode(root);
+  actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(expected, actual);
 
   // Check button spacing.
@@ -1556,10 +1556,10 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
                                  "2f3b ] 3b 4b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actual = test::ModelStringFromNode(root);
+  std::string actual = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actual);
 
   // Pop open the folder.
@@ -1615,10 +1615,10 @@
   const BookmarkNode* root = model->bookmark_bar_node();
   const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b ] "
                                  "2f3b ] 3b ");
-  test::AddNodesFromModelString(model, root, model_string);
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
 
   // Validate initial model.
-  std::string actualModelString = test::ModelStringFromNode(root);
+  std::string actualModelString = bookmarks::test::ModelStringFromNode(root);
   EXPECT_EQ(model_string, actualModelString);
 
   // Open the folder menu and submenu.
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
index b16fc59..38b507f7 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
@@ -158,7 +158,7 @@
   TestingProfile* other_profile =
       testing_profile_manager()->CreateTestingProfile("other");
   other_profile->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(
+  bookmarks::test::WaitForBookmarkModelToLoad(
       BookmarkModelFactory::GetForProfile(other_profile));
 
   mock_controller_.reset(GetMockController(
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm
index 21b0466..4e18604 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_view_unittest.mm
@@ -257,7 +257,7 @@
 
   BookmarkModel* bookmark_model =
       BookmarkModelFactory::GetForProfile(profile());
-  test::WaitForBookmarkModelToLoad(bookmark_model);
+  bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
 
   const BookmarkNode* node =
       bookmark_model->AddURL(bookmark_model->bookmark_bar_node(),
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h
index eb21da8..4d06dfd 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.h
+++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -270,7 +270,7 @@
 
 // Called to tell the selected tab to update its loading state.
 // |force| is set if the update is due to changing tabs, as opposed to
-// the page-load finishing.  See comment in reload_button.h.
+// the page-load finishing.  See comment in reload_button_cocoa.h.
 - (void)setIsLoading:(BOOL)isLoading force:(BOOL)force;
 
 // Brings this controller's window to the front.
diff --git a/chrome/browser/ui/cocoa/cocoa_profile_test.mm b/chrome/browser/ui/cocoa/cocoa_profile_test.mm
index 87f757ce..87de045a 100644
--- a/chrome/browser/ui/cocoa/cocoa_profile_test.mm
+++ b/chrome/browser/ui/cocoa/cocoa_profile_test.mm
@@ -60,7 +60,7 @@
       profile_, &AutocompleteClassifierFactory::BuildInstanceFor);
 
   profile_->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(
+  bookmarks::test::WaitForBookmarkModelToLoad(
       BookmarkModelFactory::GetForProfile(profile_));
 
   browser_.reset(CreateBrowser());
diff --git a/chrome/browser/ui/cocoa/extensions/browser_action_test_util_mac.mm b/chrome/browser/ui/cocoa/extensions/browser_action_test_util_mac.mm
index a2511fd0..5405539 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_action_test_util_mac.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_action_test_util_mac.mm
@@ -41,11 +41,6 @@
   return [GetController(browser_) visibleButtonCount];
 }
 
-ExtensionAction* BrowserActionTestUtil::GetExtensionAction(int index) {
-  NOTREACHED();
-  return NULL;
-}
-
 void BrowserActionTestUtil::InspectPopup(int index) {
   NOTREACHED();
 }
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
index d293d30..4e91304 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -690,7 +690,7 @@
 
     if (intersectionWidth > dragThreshold && button != draggedButton &&
         ![button isAnimating] && index < [self visibleButtonCount]) {
-      toolbarModel_->MoveExtensionIcon([draggedButton extension], index);
+      toolbarModel_->MoveExtensionIcon([draggedButton extension]->id(), index);
       [self positionActionButtonsAndAnimate:YES];
       return;
     }
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
index d3f05ea..f8e4503 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_install_dialog_controller.mm
@@ -43,9 +43,10 @@
     scoped_refptr<ExtensionInstallPrompt::Prompt> prompt)
     : delegate_(delegate) {
   view_controller_.reset([[ExtensionInstallViewController alloc]
-      initWithNavigator:show_params.navigator
-               delegate:this
-                 prompt:prompt]);
+      initWithProfile:show_params.profile
+            navigator:show_params.parent_web_contents
+             delegate:this
+               prompt:prompt]);
 
   base::scoped_nsobject<NSWindow> window([[ConstrainedWindowCustomWindow alloc]
       initWithContentRect:[[view_controller_ view] bounds]]);
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.h b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.h
index 2b403a1..170b293d 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.h
+++ b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.h
@@ -15,6 +15,8 @@
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "ui/gfx/image/image_skia.h"
 
+class Profile;
+
 namespace content {
 class PageNavigator;
 }
@@ -41,6 +43,7 @@
   IBOutlet NSTextField* userCountField_;
   IBOutlet NSButton* storeLinkButton_;
 
+  Profile* profile_; // weak
   content::PageNavigator* navigator_;  // weak
   ExtensionInstallPrompt::Delegate* delegate_;  // weak
   scoped_refptr<ExtensionInstallPrompt::Prompt> prompt_;
@@ -62,9 +65,10 @@
 @property(nonatomic, readonly) NSTextField* userCountField;
 @property(nonatomic, readonly) NSButton* storeLinkButton;
 
-- (id)initWithNavigator:(content::PageNavigator*)navigator
-               delegate:(ExtensionInstallPrompt::Delegate*)delegate
-                 prompt:(scoped_refptr<ExtensionInstallPrompt::Prompt>)prompt;
+- (id)initWithProfile:(Profile*)profile
+            navigator:(content::PageNavigator*)navigator
+             delegate:(ExtensionInstallPrompt::Delegate*)delegate
+               prompt:(scoped_refptr<ExtensionInstallPrompt::Prompt>)prompt;
 - (IBAction)storeLinkClicked:(id)sender; // Callback for "View details" link.
 - (IBAction)cancel:(id)sender;
 - (IBAction)ok:(id)sender;
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm
index d621a69..835ba3c 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller.mm
@@ -12,7 +12,10 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/bundle_installer.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
 #import "chrome/browser/ui/chrome_style.h"
+#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "content/public/browser/page_navigator.h"
@@ -186,9 +189,10 @@
 @synthesize userCountField = userCountField_;
 @synthesize storeLinkButton = storeLinkButton_;
 
-- (id)initWithNavigator:(content::PageNavigator*)navigator
-               delegate:(ExtensionInstallPrompt::Delegate*)delegate
-                 prompt:(scoped_refptr<ExtensionInstallPrompt::Prompt>)prompt {
+- (id)initWithProfile:(Profile*)profile
+            navigator:(content::PageNavigator*)navigator
+             delegate:(ExtensionInstallPrompt::Delegate*)delegate
+               prompt:(scoped_refptr<ExtensionInstallPrompt::Prompt>)prompt {
   // We use a different XIB in the case of bundle installs, installs with
   // webstore data, or no permission warnings. These are laid out nicely for
   // the data they display.
@@ -207,6 +211,7 @@
 
   if ((self = [super initWithNibName:nibName
                               bundle:base::mac::FrameworkBundle()])) {
+    profile_ = profile;
     navigator_ = navigator;
     delegate_ = delegate;
     prompt_ = prompt;
@@ -218,9 +223,15 @@
 - (IBAction)storeLinkClicked:(id)sender {
   GURL store_url(extension_urls::GetWebstoreItemDetailURLPrefix() +
                  prompt_->extension()->id());
-  navigator_->OpenURL(OpenURLParams(
-      store_url, Referrer(), NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
-      false));
+  OpenURLParams params(store_url, Referrer(), NEW_FOREGROUND_TAB,
+      ui::PAGE_TRANSITION_LINK, false);
+  if (navigator_) {
+    navigator_->OpenURL(params);
+  } else {
+    chrome::ScopedTabbedBrowserDisplayer displayer(
+        profile_, chrome::GetActiveDesktop());
+    displayer.browser()->OpenURL(params);
+  }
 
   delegate_->InstallUIAbort(/*user_initiated=*/true);
 }
diff --git a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm
index 7758f016..584101e 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_install_view_controller_unittest.mm
@@ -48,9 +48,10 @@
   prompt->SetPermissionsDetails(details, type);
 
   base::scoped_nsobject<ExtensionInstallViewController> controller(
-      [[ExtensionInstallViewController alloc] initWithNavigator:browser()
-                                                       delegate:&delegate
-                                                         prompt:prompt]);
+      [[ExtensionInstallViewController alloc] initWithProfile:profile()
+                                                    navigator:browser()
+                                                     delegate:&delegate
+                                                       prompt:prompt]);
 
   [controller view];  // Force nib load.
 
@@ -106,9 +107,10 @@
   prompt->SetPermissionsDetails(details, type);
 
   base::scoped_nsobject<ExtensionInstallViewController> controller(
-      [[ExtensionInstallViewController alloc] initWithNavigator:browser()
-                                                       delegate:&delegate
-                                                         prompt:prompt]);
+      [[ExtensionInstallViewController alloc] initWithProfile:profile()
+                                                    navigator:browser()
+                                                     delegate:&delegate
+                                                       prompt:prompt]);
 
   [controller view];  // Force nib load.
   [controller ok:nil];
@@ -146,17 +148,19 @@
 
   base::scoped_nsobject<ExtensionInstallViewController> controller1(
       [[ExtensionInstallViewController alloc]
-          initWithNavigator:browser()
-                   delegate:&delegate1
-                     prompt:one_warning_prompt]);
+          initWithProfile:profile()
+                navigator:browser()
+                 delegate:&delegate1
+                   prompt:one_warning_prompt]);
 
   [controller1 view];  // Force nib load.
 
   base::scoped_nsobject<ExtensionInstallViewController> controller2(
       [[ExtensionInstallViewController alloc]
-          initWithNavigator:browser()
-                   delegate:&delegate2
-                     prompt:two_warnings_prompt]);
+          initWithProfile:profile()
+                navigator:browser()
+                 delegate:&delegate2
+                   prompt:two_warnings_prompt]);
 
   [controller2 view];  // Force nib load.
 
@@ -181,9 +185,10 @@
 
   base::scoped_nsobject<ExtensionInstallViewController> controller(
       [[ExtensionInstallViewController alloc]
-          initWithNavigator:browser()
-                   delegate:&delegate
-                     prompt:no_warnings_prompt]);
+          initWithProfile:profile()
+                navigator:browser()
+                 delegate:&delegate
+                   prompt:no_warnings_prompt]);
 
   [controller view];  // Force nib load.
 
@@ -225,9 +230,10 @@
   inline_prompt->set_icon(chrome::LoadInstallPromptIcon());
 
   base::scoped_nsobject<ExtensionInstallViewController> controller(
-      [[ExtensionInstallViewController alloc] initWithNavigator:browser()
-                                                       delegate:&delegate
-                                                         prompt:inline_prompt]);
+      [[ExtensionInstallViewController alloc] initWithProfile:profile()
+                                                    navigator:browser()
+                                                     delegate:&delegate
+                                                       prompt:inline_prompt]);
 
   [controller view];  // Force nib load.
 
@@ -288,9 +294,10 @@
   prompt->SetPermissionsDetails(details, type);
 
   base::scoped_nsobject<ExtensionInstallViewController> controller(
-      [[ExtensionInstallViewController alloc] initWithNavigator:browser()
-                                                       delegate:&delegate
-                                                         prompt:prompt]);
+      [[ExtensionInstallViewController alloc] initWithProfile:profile()
+                                                    navigator:browser()
+                                                     delegate:&delegate
+                                                       prompt:prompt]);
 
   [controller view];  // Force nib load.
 
@@ -320,9 +327,10 @@
       ExtensionInstallPrompt::PERMISSIONS_DETAILS, 0, true);
 
   base::scoped_nsobject<ExtensionInstallViewController> controller(
-      [[ExtensionInstallViewController alloc] initWithNavigator:browser()
-                                                       delegate:&delegate
-                                                         prompt:prompt]);
+      [[ExtensionInstallViewController alloc] initWithProfile:profile()
+                                                    navigator:browser()
+                                                     delegate:&delegate
+                                                       prompt:prompt]);
 
   [controller view];  // Force nib load.
 
diff --git a/chrome/browser/ui/cocoa/extensions/windowed_install_dialog_controller.mm b/chrome/browser/ui/cocoa/extensions/windowed_install_dialog_controller.mm
index c457869..e4e894e 100644
--- a/chrome/browser/ui/cocoa/extensions/windowed_install_dialog_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/windowed_install_dialog_controller.mm
@@ -7,7 +7,9 @@
 #import "base/mac/sdk_forward_declarations.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/sys_string_conversions.h"
+#include "chrome/browser/profiles/profile.h"
 #import "chrome/browser/ui/cocoa/extensions/extension_install_view_controller.h"
+#include "content/public/browser/web_contents.h"
 #include "ui/base/cocoa/window_size_constants.h"
 
 @interface WindowedInstallController
@@ -19,9 +21,10 @@
 
 @property(readonly, nonatomic) ExtensionInstallViewController* viewController;
 
-- (id)initWithNavigator:(content::PageNavigator*)navigator
-               delegate:(WindowedInstallDialogController*)delegate
-                 prompt:(scoped_refptr<ExtensionInstallPrompt::Prompt>)prompt;
+- (id)initWithProfile:(Profile*)profile
+            navigator:(content::PageNavigator*)navigator
+             delegate:(WindowedInstallDialogController*)delegate
+               prompt:(scoped_refptr<ExtensionInstallPrompt::Prompt>)prompt;
 
 @end
 
@@ -31,9 +34,10 @@
     scoped_refptr<ExtensionInstallPrompt::Prompt> prompt)
     : delegate_(delegate) {
   install_controller_.reset([[WindowedInstallController alloc]
-      initWithNavigator:show_params.navigator
-               delegate:this
-                 prompt:prompt]);
+      initWithProfile:show_params.profile
+            navigator:show_params.parent_web_contents
+             delegate:this
+               prompt:prompt]);
   [[install_controller_ window] makeKeyAndOrderFront:nil];
 }
 
@@ -70,9 +74,10 @@
 
 @implementation WindowedInstallController
 
-- (id)initWithNavigator:(content::PageNavigator*)navigator
-               delegate:(WindowedInstallDialogController*)delegate
-                 prompt:(scoped_refptr<ExtensionInstallPrompt::Prompt>)prompt {
+- (id)initWithProfile:(Profile*)profile
+            navigator:(content::PageNavigator*)navigator
+             delegate:(WindowedInstallDialogController*)delegate
+               prompt:(scoped_refptr<ExtensionInstallPrompt::Prompt>)prompt {
   base::scoped_nsobject<NSWindow> controlledPanel(
       [[NSPanel alloc] initWithContentRect:ui::kWindowSizeDeterminedLater
                                  styleMask:NSTitledWindowMask
@@ -81,9 +86,10 @@
   if ((self = [super initWithWindow:controlledPanel])) {
     dialogController_ = delegate;
     installViewController_.reset([[ExtensionInstallViewController alloc]
-        initWithNavigator:navigator
-                 delegate:delegate
-                   prompt:prompt]);
+        initWithProfile:profile
+              navigator:navigator
+               delegate:delegate
+                 prompt:prompt]);
     NSWindow* window = [self window];
 
     // Ensure the window does not display behind the app launcher window, and is
diff --git a/chrome/browser/ui/cocoa/extensions/windowed_install_dialog_controller_browsertest.mm b/chrome/browser/ui/cocoa/extensions/windowed_install_dialog_controller_browsertest.mm
index 8c9ac58..3987b93 100644
--- a/chrome/browser/ui/cocoa/extensions/windowed_install_dialog_controller_browsertest.mm
+++ b/chrome/browser/ui/cocoa/extensions/windowed_install_dialog_controller_browsertest.mm
@@ -37,7 +37,7 @@
   // Construct a prompt with a NULL parent window, the way ExtensionEnableFlow
   // will for the Mac app list. For testing, sets a NULL PageNavigator as well.
   scoped_ptr<ExtensionInstallPrompt> prompt(
-      new ExtensionInstallPrompt(browser()->profile(), NULL, NULL));
+      new ExtensionInstallPrompt(browser()->profile(), NULL));
 
   WindowedInstallDialogController* controller = NULL;
   chrome::MockExtensionInstallPromptDelegate delegate;
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_view.h b/chrome/browser/ui/cocoa/find_bar/find_bar_view_cocoa.h
similarity index 71%
rename from chrome/browser/ui/cocoa/find_bar/find_bar_view.h
rename to chrome/browser/ui/cocoa/find_bar/find_bar_view_cocoa.h
index 10564c5..2b641e30 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_view.h
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_view_cocoa.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_COCOA_FIND_BAR_FIND_BAR_VIEW_H_
-#define CHROME_BROWSER_UI_COCOA_FIND_BAR_FIND_BAR_VIEW_H_
+#ifndef CHROME_BROWSER_UI_COCOA_FIND_BAR_FIND_BAR_VIEW_COCOA_H_
+#define CHROME_BROWSER_UI_COCOA_FIND_BAR_FIND_BAR_VIEW_COCOA_H_
 
 #import <Cocoa/Cocoa.h>
 
@@ -20,4 +20,4 @@
 
 @end
 
-#endif  // CHROME_BROWSER_UI_COCOA_FIND_BAR_FIND_BAR_VIEW_H_
+#endif  // CHROME_BROWSER_UI_COCOA_FIND_BAR_FIND_BAR_VIEW_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_view_cocoa.mm
similarity index 98%
rename from chrome/browser/ui/cocoa/find_bar/find_bar_view.mm
rename to chrome/browser/ui/cocoa/find_bar/find_bar_view_cocoa.mm
index 41dfa64a..b8f607bc 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_view_cocoa.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "chrome/browser/ui/cocoa/find_bar/find_bar_view.h"
+#import "chrome/browser/ui/cocoa/find_bar/find_bar_view_cocoa.h"
 
 #import "chrome/browser/ui/cocoa/themed_window.h"
 #import "chrome/browser/ui/cocoa/url_drop_target.h"
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_view_unittest.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_view_unittest.mm
index b530797a..bc8a574 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_view_unittest.mm
@@ -6,7 +6,7 @@
 
 #include "base/mac/scoped_nsobject.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/ui/cocoa/find_bar/find_bar_view.h"
+#import "chrome/browser/ui/cocoa/find_bar/find_bar_view_cocoa.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 #include "ui/events/test/cocoa_test_event_utils.h"
diff --git a/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.h b/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.h
index 459dff4..b3001805 100644
--- a/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.h
+++ b/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.h
@@ -5,11 +5,10 @@
 #ifndef CHROME_BROWSER_UI_COCOA_JAVASCRIPT_APP_MODAL_DIALOG_COCOA_H_
 #define CHROME_BROWSER_UI_COCOA_JAVASCRIPT_APP_MODAL_DIALOG_COCOA_H_
 
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
-
 #include "base/logging.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/memory/scoped_ptr.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 
 #if __OBJC__
 @class NSAlert;
diff --git a/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.mm b/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.mm
index 6ef8729..37c4ad7a 100644
--- a/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.mm
+++ b/chrome/browser/ui/cocoa/javascript_app_modal_dialog_cocoa.mm
@@ -11,8 +11,9 @@
 #import "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
 #import "chrome/browser/chrome_browser_application_mac.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "grit/components_strings.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/gfx/text_elider.h"
diff --git a/chrome/browser/ui/cocoa/menu_button.h b/chrome/browser/ui/cocoa/menu_button.h
index d0ffb58..0cc07c6 100644
--- a/chrome/browser/ui/cocoa/menu_button.h
+++ b/chrome/browser/ui/cocoa/menu_button.h
@@ -8,7 +8,7 @@
 #import <Cocoa/Cocoa.h>
 
 #include "base/mac/scoped_nsobject.h"
-#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h"
+#import "chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.h"
 
 // This a button which displays a user-provided menu "attached" below it upon
 // being clicked or dragged (or clicked and held). It expects a
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm b/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm
index 36a6496b..86eeda0a3 100644
--- a/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/profiles/avatar_icon_controller_unittest.mm
@@ -109,7 +109,7 @@
   AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse(
       profile, &AutocompleteClassifierFactory::BuildInstanceFor);
   profile->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(
+  bookmarks::test::WaitForBookmarkModelToLoad(
       BookmarkModelFactory::GetForProfile(profile));
 
   Browser* browser =
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
index d08dfcfa..589447d 100644
--- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
+++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -50,6 +50,7 @@
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/signin/core/common/profile_management_switches.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "google_apis/gaia/oauth2_token_service.h"
 #include "grit/theme_resources.h"
@@ -1911,6 +1912,9 @@
   NSView* webview = webContents_->GetNativeView();
   [webview setFrameSize:NSMakeSize(kFixedGaiaViewWidth, kFixedGaiaViewHeight)];
   [container addSubview:webview];
+  content::RenderWidgetHostView* rwhv = webContents_->GetRenderWidgetHostView();
+  if (rwhv)
+    rwhv->SetBackgroundColor(profiles::kAvatarBubbleGaiaBackgroundColor);
   yOffset = NSMaxY([webview frame]);
 
   // Adds the title card.
diff --git a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
index b9d77b9..f6b69bf8 100644
--- a/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
+++ b/chrome/browser/ui/cocoa/profiles/user_manager_mac.mm
@@ -8,6 +8,7 @@
 #include "chrome/app/chrome_command_ids.h"
 #import "chrome/browser/app_controller_mac.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/ui/browser_dialogs.h"
@@ -16,6 +17,7 @@
 #include "chrome/browser/ui/user_manager.h"
 #include "chrome/grit/chromium_strings.h"
 #include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "ui/base/l10n/l10n_util_mac.h"
@@ -128,6 +130,9 @@
   webContents_->GetController().LoadURL(url, content::Referrer(),
                                         ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
                                         std::string());
+  content::RenderWidgetHostView* rwhv = webContents_->GetRenderWidgetHostView();
+  if (rwhv)
+    rwhv->SetBackgroundColor(profiles::kUserManagerBackgroundColor);
   [self show];
 }
 
diff --git a/chrome/browser/ui/cocoa/toolbar/reload_button.h b/chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.h
similarity index 88%
rename from chrome/browser/ui/cocoa/toolbar/reload_button.h
rename to chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.h
index 64e7e67..761fab1 100644
--- a/chrome/browser/ui/cocoa/toolbar/reload_button.h
+++ b/chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_COCOA_TOOLBAR_RELOAD_BUTTON_H_
-#define CHROME_BROWSER_UI_COCOA_TOOLBAR_RELOAD_BUTTON_H_
+#ifndef CHROME_BROWSER_UI_COCOA_TOOLBAR_RELOAD_BUTTON_COCOA_H_
+#define CHROME_BROWSER_UI_COCOA_TOOLBAR_RELOAD_BUTTON_COCOA_H_
 
 #import <Cocoa/Cocoa.h>
 
@@ -43,4 +43,4 @@
 
 @end
 
-#endif  // CHROME_BROWSER_UI_COCOA_TOOLBAR_RELOAD_BUTTON_H_
+#endif  // CHROME_BROWSER_UI_COCOA_TOOLBAR_RELOAD_BUTTON_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/toolbar/reload_button.mm b/chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.mm
similarity index 98%
rename from chrome/browser/ui/cocoa/toolbar/reload_button.mm
rename to chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.mm
index 0231579..3becf15 100644
--- a/chrome/browser/ui/cocoa/toolbar/reload_button.mm
+++ b/chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "chrome/browser/ui/cocoa/toolbar/reload_button.h"
+#import "chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.h"
 
 #include "chrome/app/chrome_command_ids.h"
 #import "chrome/browser/ui/cocoa/accelerators_cocoa.h"
diff --git a/chrome/browser/ui/cocoa/toolbar/reload_button_unittest.mm b/chrome/browser/ui/cocoa/toolbar/reload_button_unittest.mm
index 2bc38f5..5f730d80 100644
--- a/chrome/browser/ui/cocoa/toolbar/reload_button_unittest.mm
+++ b/chrome/browser/ui/cocoa/toolbar/reload_button_unittest.mm
@@ -4,7 +4,7 @@
 
 #import <Cocoa/Cocoa.h>
 
-#import "chrome/browser/ui/cocoa/toolbar/reload_button.h"
+#import "chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.h"
 
 #include "base/mac/scoped_nsobject.h"
 #include "chrome/app/chrome_command_ids.h"
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button.h b/chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.h
similarity index 75%
rename from chrome/browser/ui/cocoa/toolbar/toolbar_button.h
rename to chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.h
index 9adb033..2216ae8 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_button.h
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_
-#define CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_
+#ifndef CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_COCOA_H_
+#define CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_COCOA_H_
 
 #import <Cocoa/Cocoa.h>
 
@@ -24,4 +24,4 @@
 - (BOOL)shouldHandleEvent:(NSEvent*)theEvent;
 @end
 
-#endif  // CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_
+#endif  // CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm
similarity index 95%
rename from chrome/browser/ui/cocoa/toolbar/toolbar_button.mm
rename to chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm
index afc3483..7e971cdf 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_button.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h"
+#import "chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.h"
 
 @implementation ToolbarButton
 
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm
index 4a59a9c49..5ff48e4 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm
@@ -7,7 +7,7 @@
 #import "base/mac/scoped_nsobject.h"
 #include "chrome/app/chrome_command_ids.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h"
+#import "chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.h"
 #import "testing/gtest_mac.h"
 #import "ui/events/test/cocoa_test_event_utils.h"
 
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h
index 7469a6a..2b641e6d 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h
@@ -133,7 +133,7 @@
 // Called to update the loading state. Handles updating the go/stop
 // button state.  |force| is set if the update is due to changing
 // tabs, as opposed to the page-load finishing.  See comment in
-// reload_button.h.
+// reload_button_cocoa.h.
 - (void)setIsLoading:(BOOL)isLoading force:(BOOL)force;
 
 // Allow turning off the toolbar (but we may keep the location bar without a
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
index f6100a3..a33f9a33 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm
@@ -35,9 +35,9 @@
 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
 #import "chrome/browser/ui/cocoa/menu_button.h"
 #import "chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h"
-#import "chrome/browser/ui/cocoa/toolbar/reload_button.h"
-#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h"
-#import "chrome/browser/ui/cocoa/toolbar/toolbar_view.h"
+#import "chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.h"
+#import "chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.h"
+#import "chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.h"
 #import "chrome/browser/ui/cocoa/toolbar/wrench_toolbar_button_cell.h"
 #import "chrome/browser/ui/cocoa/view_id_util.h"
 #import "chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h"
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_view.h b/chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.h
similarity index 79%
rename from chrome/browser/ui/cocoa/toolbar/toolbar_view.h
rename to chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.h
index f8a99bb..b714af5 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_view.h
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_VIEW_H_
-#define CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_VIEW_H_
+#ifndef CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_VIEW_COCOA_H_
+#define CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_VIEW_COCOA_H_
 
 #import <Cocoa/Cocoa.h>
 #import "chrome/browser/ui/cocoa/background_gradient_view.h"
@@ -22,4 +22,4 @@
 @property(assign, nonatomic) CGFloat dividerOpacity;
 @end
 
-#endif  // CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_VIEW_H_
+#endif  // CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_VIEW_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_view.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.mm
similarity index 95%
rename from chrome/browser/ui/cocoa/toolbar/toolbar_view.mm
rename to chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.mm
index 18bf58b..f4ef84d8 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_view.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "chrome/browser/ui/cocoa/toolbar/toolbar_view.h"
+#import "chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.h"
 
 #import "chrome/browser/ui/cocoa/themed_window.h"
 #import "chrome/browser/ui/cocoa/view_id_util.h"
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_view_unittest.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_view_unittest.mm
index 4bdeb56..52df1e95 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_view_unittest.mm
@@ -4,7 +4,7 @@
 
 #include "base/mac/scoped_nsobject.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/ui/cocoa/toolbar/toolbar_view.h"
+#import "chrome/browser/ui/cocoa/toolbar/toolbar_view_cocoa.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
diff --git a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
index 083b23d..fe3666c 100644
--- a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
+++ b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
@@ -58,7 +58,7 @@
         BookmarkModelFactory::GetForProfile(browser()->profile());
     if (bookmark_model) {
       if (!bookmark_model->loaded())
-        test::WaitForBookmarkModelToLoad(bookmark_model);
+        bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
 
       bookmarks::AddIfNotBookmarked(bookmark_model,
                                     GURL(url::kAboutBlankURL),
diff --git a/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm b/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
index 7bf04caca..5d6597c3 100644
--- a/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
@@ -104,7 +104,7 @@
 // The amount of padding to leave on either side of the tab label.
 const CGFloat kTabLabelXPadding = 12;
 
-// Return the text color to use for the indentity status when the site's
+// Return the text color to use for the identity status when the site's
 // identity has been verified.
 NSColor* IdentityVerifiedTextColor() {
   // RGB components are specified using integer RGB [0-255] values for easy
@@ -131,9 +131,20 @@
   // the same as the currently selected segment.
   NSInteger keySegment_;
 }
+
+// The text attributes to use for the tab labels.
++ (NSDictionary*)textAttributes;
+
 @end
 
 @implementation WebsiteSettingsTabSegmentedCell
+
++ (NSDictionary*)textAttributes {
+  NSFont* smallSystemFont =
+      [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
+  return @{ NSFontAttributeName : smallSystemFont };
+}
+
 - (id)init {
   if ((self = [super init])) {
     ResourceBundle& rb = ResourceBundle::GetSharedInstance();
@@ -245,17 +256,29 @@
 }
 
 - (void)drawSegment:(NSInteger)segment
-            inFrame:(NSRect)frame
+            inFrame:(NSRect)tabFrame
            withView:(NSView*)controlView {
-  // Call the superclass to draw the label, adjusting the rectangle so that
-  // the label appears centered in the tab.
+  // Adjust the tab's frame so that the label appears centered in the tab.
   if (segment == 0) {
-    frame.origin.x += kTabStripXPadding / 2;
-    frame.size.width -= kTabStripXPadding;
+    tabFrame.origin.x += kTabStripXPadding;
+    tabFrame.size.width -= kTabStripXPadding;
   }
-  frame.origin.y += kTabLabelTopPadding;
-  frame.size.height -= kTabLabelTopPadding;
-  [super drawSegment:segment inFrame:frame withView:controlView];
+  tabFrame.origin.y += kTabLabelTopPadding;
+  tabFrame.size.height -= kTabLabelTopPadding;
+
+  // Center the label's frame in the tab's frame.
+  NSString* label = [self labelForSegment:segment];
+  NSDictionary* textAttributes =
+      [WebsiteSettingsTabSegmentedCell textAttributes];
+  NSSize textSize = [label sizeWithAttributes:textAttributes];
+  NSRect labelFrame;
+  labelFrame.size = textSize;
+  labelFrame.origin.x =
+      tabFrame.origin.x + (NSWidth(tabFrame) - textSize.width) / 2.0;
+  labelFrame.origin.y =
+      tabFrame.origin.y + (NSHeight(tabFrame) - textSize.height) / 2.0;
+
+  [label drawInRect:labelFrame withAttributes:textAttributes];
 }
 
 // Overrides the default tracking behavior to only respond to clicks inside the
@@ -415,11 +438,8 @@
   [segmentedControl_ setAction:@selector(tabSelected:)];
   [segmentedControl_ setAutoresizingMask:NSViewWidthSizable];
 
-  NSFont* smallSystemFont =
-      [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
   NSDictionary* textAttributes =
-      [NSDictionary dictionaryWithObject:smallSystemFont
-                                  forKey:NSFontAttributeName];
+      [WebsiteSettingsTabSegmentedCell textAttributes];
 
   // Create the "Permissions" tab.
   NSString* label = l10n_util::GetNSString(
@@ -428,8 +448,6 @@
                    forSegment:WebsiteSettingsUI::TAB_ID_PERMISSIONS];
   NSSize textSize = [label sizeWithAttributes:textAttributes];
   CGFloat tabWidth = textSize.width + 2 * kTabLabelXPadding;
-  [segmentedControl_ setWidth:tabWidth + kTabStripXPadding
-                   forSegment:WebsiteSettingsUI::TAB_ID_PERMISSIONS];
 
   // Create the "Connection" tab.
   label = l10n_util::GetNSString(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION);
@@ -449,7 +467,7 @@
   [segmentedControl_ setWidth:tabWidth
                    forSegment:WebsiteSettingsUI::TAB_ID_CONNECTION];
 
-  [segmentedControl_ setFont:smallSystemFont];
+  [segmentedControl_ setFont:[textAttributes objectForKey:NSFontAttributeName]];
   [contentView_ addSubview:segmentedControl_];
 
   NSRect tabFrame = NSMakeRect(0, 0, [self defaultWindowWidth], 300);
diff --git a/chrome/browser/ui/crypto_module_delegate_nss.cc b/chrome/browser/ui/crypto_module_delegate_nss.cc
index 4829a4a..5812e54 100644
--- a/chrome/browser/ui/crypto_module_delegate_nss.cc
+++ b/chrome/browser/ui/crypto_module_delegate_nss.cc
@@ -11,31 +11,53 @@
 
 using content::BrowserThread;
 
+namespace {
+
+void CreateWithSlot(chrome::CryptoModulePasswordReason reason,
+                    const net::HostPortPair& server,
+                    const base::Callback<void(
+                        scoped_ptr<ChromeNSSCryptoModuleDelegate>)>& callback,
+                    crypto::ScopedPK11Slot slot) {
+  if (!slot) {
+    callback.Run(scoped_ptr<ChromeNSSCryptoModuleDelegate>());
+    return;
+  }
+  callback.Run(scoped_ptr<ChromeNSSCryptoModuleDelegate>(
+      new ChromeNSSCryptoModuleDelegate(reason, server, slot.Pass())));
+}
+
+}  // namespace
+
 ChromeNSSCryptoModuleDelegate::ChromeNSSCryptoModuleDelegate(
     chrome::CryptoModulePasswordReason reason,
-    const net::HostPortPair& server)
+    const net::HostPortPair& server,
+    crypto::ScopedPK11Slot slot)
     : reason_(reason),
       server_(server),
       event_(false, false),
-      cancelled_(false) {}
+      cancelled_(false),
+      slot_(slot.Pass()) {
+}
 
 ChromeNSSCryptoModuleDelegate::~ChromeNSSCryptoModuleDelegate() {}
 
-bool ChromeNSSCryptoModuleDelegate::InitializeSlot(
+// static
+void ChromeNSSCryptoModuleDelegate::CreateForResourceContext(
+    chrome::CryptoModulePasswordReason reason,
+    const net::HostPortPair& server,
     content::ResourceContext* context,
-    const base::Closure& initialization_complete_callback) {
+    const base::Callback<void(scoped_ptr<ChromeNSSCryptoModuleDelegate>)>&
+        callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DCHECK(!slot_);
-  base::Callback<void(crypto::ScopedPK11Slot)> get_slot_callback;
-  if (!initialization_complete_callback.is_null())
-    get_slot_callback = base::Bind(&ChromeNSSCryptoModuleDelegate::DidGetSlot,
-                                   // Caller is responsible for keeping |this|
-                                   // alive until the callback is run.
-                                   base::Unretained(this),
-                                   initialization_complete_callback);
+  DCHECK(!callback.is_null());
 
-  slot_ = GetPrivateNSSKeySlotForResourceContext(context, get_slot_callback);
-  return slot_.get() != NULL;
+  base::Callback<void(crypto::ScopedPK11Slot)> get_slot_callback =
+      base::Bind(&CreateWithSlot, reason, server, callback);
+
+  crypto::ScopedPK11Slot slot =
+      GetPrivateNSSKeySlotForResourceContext(context, get_slot_callback);
+  if (slot)
+    get_slot_callback.Run(slot.Pass());
 }
 
 // TODO(mattm): allow choosing which slot to generate and store the key.
@@ -88,19 +110,13 @@
   event_.Signal();
 }
 
-void ChromeNSSCryptoModuleDelegate::DidGetSlot(const base::Closure& callback,
-                                               crypto::ScopedPK11Slot slot) {
-  DCHECK(!slot_);
-  slot_ = slot.Pass();
-  callback.Run();
-}
-
 crypto::CryptoModuleBlockingPasswordDelegate*
 CreateCryptoModuleBlockingPasswordDelegate(
     chrome::CryptoModulePasswordReason reason,
     const net::HostPortPair& server) {
-  // Returns a ChromeNSSCryptoModuleDelegate without calling InitializeSlot.
-  // Since it is only being used as a CreateCryptoModuleBlockingDialogDelegate,
-  // initializing the slot handle is unnecessary.
-  return new ChromeNSSCryptoModuleDelegate(reason, server);
+  // Returns a ChromeNSSCryptoModuleDelegate without Pk11Slot. Since it is only
+  // being used as a CryptoModuleBlockingDialogDelegate, using a slot handle is
+  // unnecessary.
+  return new ChromeNSSCryptoModuleDelegate(
+      reason, server, crypto::ScopedPK11Slot());
 }
diff --git a/chrome/browser/ui/crypto_module_delegate_nss.h b/chrome/browser/ui/crypto_module_delegate_nss.h
index 998d0e0..7afde30 100644
--- a/chrome/browser/ui/crypto_module_delegate_nss.h
+++ b/chrome/browser/ui/crypto_module_delegate_nss.h
@@ -25,20 +25,22 @@
  public:
   // Create a ChromeNSSCryptoModuleDelegate. |reason| is used to select what
   // string to show the user, |server| is displayed to indicate which connection
-  // is causing the dialog to appear.
+  // is causing the dialog to appear. |slot| can be NULL.
   ChromeNSSCryptoModuleDelegate(chrome::CryptoModulePasswordReason reason,
-                                const net::HostPortPair& server);
+                                const net::HostPortPair& server,
+                                crypto::ScopedPK11Slot slot);
 
   virtual ~ChromeNSSCryptoModuleDelegate();
 
-  // Must be called on IO thread. Returns true if the delegate is ready for use.
-  // Otherwise, if |initialization_complete_callback| is non-null, the
-  // initialization will proceed asynchronously and the callback will be run
-  // once the delegate is ready to use. In that case, the caller must ensure the
-  // delegate remains alive until the callback is run.
-  bool InitializeSlot(content::ResourceContext* context,
-                      const base::Closure& initialization_complete_callback)
-      WARN_UNUSED_RESULT;
+  // Must be called on IO thread. Creates a delegate and returns it
+  // synchronously or asynchronously to |callback|. If the delegate could not be
+  // created, |callback| is called with NULL.
+  static void CreateForResourceContext(
+      chrome::CryptoModulePasswordReason reason,
+      const net::HostPortPair& server,
+      content::ResourceContext* context,
+      const base::Callback<void(scoped_ptr<ChromeNSSCryptoModuleDelegate>)>&
+          callback);
 
   // crypto::NSSCryptoModuleDelegate implementation.
   virtual crypto::ScopedPK11Slot RequestSlot() override;
@@ -53,8 +55,6 @@
 
   void GotPassword(const std::string& password);
 
-  void DidGetSlot(const base::Closure& callback, crypto::ScopedPK11Slot slot);
-
   // Parameters displayed in the dialog.
   const chrome::CryptoModulePasswordReason reason_;
   net::HostPortPair server_;
diff --git a/chrome/browser/ui/extensions/app_launch_params.cc b/chrome/browser/ui/extensions/app_launch_params.cc
new file mode 100644
index 0000000..a8598753
--- /dev/null
+++ b/chrome/browser/ui/extensions/app_launch_params.cc
@@ -0,0 +1,70 @@
+// 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/extensions/app_launch_params.h"
+
+#include "chrome/browser/extensions/launch_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/common/extension.h"
+
+using extensions::ExtensionPrefs;
+
+AppLaunchParams::AppLaunchParams(Profile* profile,
+                                 const extensions::Extension* extension,
+                                 extensions::LaunchContainer container,
+                                 WindowOpenDisposition disposition)
+    : profile(profile),
+      extension_id(extension ? extension->id() : std::string()),
+      container(container),
+      disposition(disposition),
+      desktop_type(chrome::GetActiveDesktop()),
+      override_url(),
+      override_bounds(),
+      command_line(CommandLine::NO_PROGRAM) {}
+
+AppLaunchParams::AppLaunchParams(Profile* profile,
+                                 const extensions::Extension* extension,
+                                 WindowOpenDisposition disposition)
+    : profile(profile),
+      extension_id(extension ? extension->id() : std::string()),
+      container(extensions::LAUNCH_CONTAINER_NONE),
+      disposition(disposition),
+      desktop_type(chrome::GetActiveDesktop()),
+      override_url(),
+      override_bounds(),
+      command_line(CommandLine::NO_PROGRAM) {
+  // Look up the app preference to find out the right launch container. Default
+  // is to launch as a regular tab.
+  container =
+      extensions::GetLaunchContainer(ExtensionPrefs::Get(profile), extension);
+}
+
+AppLaunchParams::AppLaunchParams(Profile* profile,
+                                 const extensions::Extension* extension,
+                                 int event_flags,
+                                 chrome::HostDesktopType desktop_type)
+    : profile(profile),
+      extension_id(extension ? extension->id() : std::string()),
+      container(extensions::LAUNCH_CONTAINER_NONE),
+      disposition(ui::DispositionFromEventFlags(event_flags)),
+      desktop_type(desktop_type),
+      override_url(),
+      override_bounds(),
+      command_line(CommandLine::NO_PROGRAM) {
+  if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) {
+    container = extensions::LAUNCH_CONTAINER_TAB;
+  } else if (disposition == NEW_WINDOW) {
+    container = extensions::LAUNCH_CONTAINER_WINDOW;
+  } else {
+    // Look at preference to find the right launch container.  If no preference
+    // is set, launch as a regular tab.
+    container =
+        extensions::GetLaunchContainer(ExtensionPrefs::Get(profile), extension);
+    disposition = NEW_FOREGROUND_TAB;
+  }
+}
+
+AppLaunchParams::~AppLaunchParams() {
+}
diff --git a/chrome/browser/ui/extensions/app_launch_params.h b/chrome/browser/ui/extensions/app_launch_params.h
new file mode 100644
index 0000000..b9298f9
--- /dev/null
+++ b/chrome/browser/ui/extensions/app_launch_params.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2012 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_EXTENSIONS_APP_LAUNCH_PARAMS_H_
+#define CHROME_BROWSER_UI_EXTENSIONS_APP_LAUNCH_PARAMS_H_
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "chrome/browser/ui/host_desktop.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "ui/base/window_open_disposition.h"
+#include "ui/gfx/rect.h"
+#include "url/gurl.h"
+
+class Profile;
+
+namespace extensions {
+class Extension;
+}
+
+struct AppLaunchParams {
+  AppLaunchParams(Profile* profile,
+                  const extensions::Extension* extension,
+                  extensions::LaunchContainer container,
+                  WindowOpenDisposition disposition);
+
+  // Helper to create AppLaunchParams using extensions::GetLaunchContainer with
+  // LAUNCH_TYPE_REGULAR to check for a user-configured container.
+  AppLaunchParams(Profile* profile,
+                  const extensions::Extension* extension,
+                  WindowOpenDisposition disposition);
+
+  // Helper to create AppLaunchParams using event flags that allows user to
+  // override the user-configured container using modifier keys, falling back to
+  // extensions::GetLaunchContainer() with no modifiers. |desktop_type|
+  // indicates the desktop upon which to launch (Ash or Native).
+  AppLaunchParams(Profile* profile,
+                  const extensions::Extension* extension,
+                  int event_flags,
+                  chrome::HostDesktopType desktop_type);
+
+  ~AppLaunchParams();
+
+  // The profile to load the application from.
+  Profile* profile;
+
+  // The extension to load.
+  std::string extension_id;
+
+  // The container type to launch the application in.
+  extensions::LaunchContainer container;
+
+  // If container is TAB, this field controls how the tab is opened.
+  WindowOpenDisposition disposition;
+
+  // The desktop type to launch on. Uses GetActiveDesktop() if unspecified.
+  chrome::HostDesktopType desktop_type;
+
+  // If non-empty, use override_url in place of the application's launch url.
+  GURL override_url;
+
+  // If non-empty, use override_boudns in place of the application's default
+  // position and dimensions.
+  gfx::Rect override_bounds;
+
+  // If non-empty, information from the command line may be passed on to the
+  // application.
+  base::CommandLine command_line;
+
+  // If non-empty, the current directory from which any relative paths on the
+  // command line should be expanded from.
+  base::FilePath current_directory;
+};
+
+#endif  // CHROME_BROWSER_UI_EXTENSIONS_APP_LAUNCH_PARAMS_H_
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc
index 8bd0102..e2a52cd8 100644
--- a/chrome/browser/ui/extensions/application_launch.cc
+++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -7,46 +7,27 @@
 #include <string>
 
 #include "apps/launcher.h"
-#include "base/command_line.h"
 #include "base/metrics/histogram.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/app_mode/app_mode_utils.h"
 #include "chrome/browser/apps/per_app_settings_service.h"
 #include "chrome/browser/apps/per_app_settings_service_factory.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/launch_util.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_list_service.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_tabstrip.h"
-#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/extensions/app_launch_params.h"
+#include "chrome/browser/ui/extensions/application_launch_web_app.h"
 #include "chrome/browser/ui/extensions/extension_enable_flow.h"
 #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/common/url_constants.h"
-#include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/renderer_preferences.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
-#include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/features/feature.h"
 #include "extensions/common/features/feature_provider.h"
 #include "extensions/common/manifest_handlers/options_page_info.h"
-#include "ui/base/window_open_disposition.h"
-#include "ui/gfx/rect.h"
-
-#if defined(OS_MACOSX)
-#include "chrome/browser/ui/browser_commands_mac.h"
-#endif
 
 using content::WebContents;
 using extensions::Extension;
@@ -55,39 +36,44 @@
 
 namespace {
 
-// Attempts to launch a packaged app, prompting the user to enable it if
-// necessary. If a prompt is required it will be shown inside the AppList.
+#if !defined(USE_ATHENA)
+// Shows the app list for |desktop_type| and returns the app list's window.
+gfx::NativeWindow ShowAppListAndGetNativeWindow(
+      chrome::HostDesktopType desktop_type) {
+  AppListService* app_list_service = AppListService::Get(desktop_type);
+  app_list_service->Show();
+  return app_list_service->GetAppListWindow();
+}
+#endif
+
+// Attempts to launch an app, prompting the user to enable it if necessary. If
+// a prompt is required it will be shown inside the window returned by
+// |parent_window_getter|.
 // This class manages its own lifetime.
-class EnableViaAppListFlow : public ExtensionEnableFlowDelegate {
+class EnableViaDialogFlow : public ExtensionEnableFlowDelegate {
  public:
-  EnableViaAppListFlow(ExtensionService* service,
-                       Profile* profile,
-                       chrome::HostDesktopType desktop_type,
-                       const std::string& extension_id,
-                       const base::Closure& callback)
+  EnableViaDialogFlow(
+      ExtensionService* service,
+      Profile* profile,
+      const std::string& extension_id,
+      const base::Callback<gfx::NativeWindow(void)>& parent_window_getter,
+      const base::Closure& callback)
       : service_(service),
         profile_(profile),
-        desktop_type_(desktop_type),
         extension_id_(extension_id),
+        parent_window_getter_(parent_window_getter),
         callback_(callback) {
   }
 
-  ~EnableViaAppListFlow() override {}
+  ~EnableViaDialogFlow() override {}
 
   void Run() {
     DCHECK(!service_->IsExtensionEnabled(extension_id_));
     flow_.reset(new ExtensionEnableFlow(profile_, extension_id_, this));
-    flow_->StartForCurrentlyNonexistentWindow(
-        base::Bind(&EnableViaAppListFlow::ShowAppList, base::Unretained(this)));
+    flow_->StartForCurrentlyNonexistentWindow(parent_window_getter_);
   }
 
  private:
-  gfx::NativeWindow ShowAppList() {
-    AppListService* app_list_service = AppListService::Get(desktop_type_);
-    app_list_service->Show();
-    return app_list_service->GetAppListWindow();
-  }
-
   // ExtensionEnableFlowDelegate overrides.
   void ExtensionEnableFlowFinished() override {
     const Extension* extension =
@@ -102,12 +88,12 @@
 
   ExtensionService* service_;
   Profile* profile_;
-  chrome::HostDesktopType desktop_type_;
   std::string extension_id_;
+  base::Callback<gfx::NativeWindow(void)> parent_window_getter_;
   base::Closure callback_;
   scoped_ptr<ExtensionEnableFlow> flow_;
 
-  DISALLOW_COPY_AND_ASSIGN(EnableViaAppListFlow);
+  DISALLOW_COPY_AND_ASSIGN(EnableViaDialogFlow);
 };
 
 const Extension* GetExtension(const AppLaunchParams& params) {
@@ -120,164 +106,31 @@
                                         ExtensionRegistry::TERMINATED);
 }
 
-ui::WindowShowState DetermineWindowShowState(
-    Profile* profile,
-    extensions::LaunchContainer container,
-    const Extension* extension) {
-  if (!extension || container != extensions::LAUNCH_CONTAINER_WINDOW)
-    return ui::SHOW_STATE_DEFAULT;
+// Get the launch URL for a given extension, with optional override/fallback.
+// |override_url|, if non-empty, will be preferred over the extension's
+// launch url.
+GURL UrlForExtension(const extensions::Extension* extension,
+                     const GURL& override_url) {
+  if (!extension)
+    return override_url;
 
-  if (chrome::IsRunningInForcedAppMode())
-    return ui::SHOW_STATE_FULLSCREEN;
-
-#if defined(USE_ASH)
-  // In ash, LAUNCH_TYPE_FULLSCREEN launches in a maximized app window and
-  // LAUNCH_TYPE_WINDOW launches in a normal app window.
-  extensions::LaunchType launch_type =
-      extensions::GetLaunchType(ExtensionPrefs::Get(profile), extension);
-  if (launch_type == extensions::LAUNCH_TYPE_FULLSCREEN)
-    return ui::SHOW_STATE_MAXIMIZED;
-  else if (launch_type == extensions::LAUNCH_TYPE_WINDOW)
-    return ui::SHOW_STATE_NORMAL;
-#endif
-
-  return ui::SHOW_STATE_DEFAULT;
-}
-
-WebContents* OpenApplicationWindow(const AppLaunchParams& params) {
-  Profile* const profile = params.profile;
-  const Extension* const extension = GetExtension(params);
-  const GURL url_input = params.override_url;
-
-  DCHECK(!url_input.is_empty() || extension);
-  GURL url = UrlForExtension(extension, url_input);
-  std::string app_name = extension ?
-      web_app::GenerateApplicationNameFromExtensionId(extension->id()) :
-      web_app::GenerateApplicationNameFromURL(url);
-
-  gfx::Rect initial_bounds;
-  if (!params.override_bounds.IsEmpty()) {
-    initial_bounds = params.override_bounds;
-  } else if (extension) {
-    initial_bounds.set_width(
-        extensions::AppLaunchInfo::GetLaunchWidth(extension));
-    initial_bounds.set_height(
-        extensions::AppLaunchInfo::GetLaunchHeight(extension));
-  }
-
-  Browser::CreateParams browser_params(
-      Browser::CreateParams::CreateForApp(app_name,
-                                          true /* trusted_source */,
-                                          initial_bounds,
-                                          profile,
-                                          params.desktop_type));
-
-  browser_params.initial_show_state = DetermineWindowShowState(profile,
-                                                               params.container,
-                                                               extension);
-
-  Browser* browser = new Browser(browser_params);
-
-  WebContents* web_contents = chrome::AddSelectedTabWithURL(
-      browser, url, ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
-  web_contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
-  web_contents->GetRenderViewHost()->SyncRendererPrefs();
-
-  browser->window()->Show();
-
-  // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
-  //                focus explicitly.
-  web_contents->SetInitialFocus();
-  return web_contents;
-}
-
-WebContents* OpenApplicationTab(const AppLaunchParams& launch_params) {
-  const Extension* extension = GetExtension(launch_params);
-  CHECK(extension);
-  Profile* const profile = launch_params.profile;
-  WindowOpenDisposition disposition = launch_params.disposition;
-
-  Browser* browser = chrome::FindTabbedBrowser(profile,
-                                               false,
-                                               launch_params.desktop_type);
-  WebContents* contents = NULL;
-  if (!browser) {
-    // No browser for this profile, need to open a new one.
-    browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED,
-                                                profile,
-                                                launch_params.desktop_type));
-    browser->window()->Show();
-    // There's no current tab in this browser window, so add a new one.
-    disposition = NEW_FOREGROUND_TAB;
+  GURL url;
+  if (!override_url.is_empty()) {
+    DCHECK(extension->web_extent().MatchesURL(override_url) ||
+           override_url.GetOrigin() == extension->url());
+    url = override_url;
   } else {
-    // For existing browser, ensure its window is shown and activated.
-    browser->window()->Show();
-    browser->window()->Activate();
+    url = extensions::AppLaunchInfo::GetFullLaunchURL(extension);
   }
 
-  extensions::LaunchType launch_type =
-      extensions::GetLaunchType(ExtensionPrefs::Get(profile), extension);
-  UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
-
-  int add_type = TabStripModel::ADD_ACTIVE;
-  if (launch_type == extensions::LAUNCH_TYPE_PINNED)
-    add_type |= TabStripModel::ADD_PINNED;
-
-  GURL extension_url = UrlForExtension(extension, launch_params.override_url);
-  chrome::NavigateParams params(browser, extension_url,
-                                ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
-  params.tabstrip_add_types = add_type;
-  params.disposition = disposition;
-
-  if (disposition == CURRENT_TAB) {
-    WebContents* existing_tab =
-        browser->tab_strip_model()->GetActiveWebContents();
-    TabStripModel* model = browser->tab_strip_model();
-    int tab_index = model->GetIndexOfWebContents(existing_tab);
-
-    existing_tab->OpenURL(content::OpenURLParams(
-          extension_url,
-          content::Referrer(existing_tab->GetURL(),
-                            blink::WebReferrerPolicyDefault),
-          disposition, ui::PAGE_TRANSITION_LINK, false));
-    // Reset existing_tab as OpenURL() may have clobbered it.
-    existing_tab = browser->tab_strip_model()->GetActiveWebContents();
-    if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
-      model->SetTabPinned(tab_index, true);
-      // Pinning may have moved the tab.
-      tab_index = model->GetIndexOfWebContents(existing_tab);
-    }
-    if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
-      model->ActivateTabAt(tab_index, true);
-
-    contents = existing_tab;
-  } else {
-    chrome::Navigate(&params);
-    contents = params.target_contents;
+  // For extensions lacking launch urls, determine a reasonable fallback.
+  if (!url.is_valid()) {
+    url = extensions::OptionsPageInfo::GetOptionsPage(extension);
+    if (!url.is_valid())
+      url = GURL(chrome::kChromeUIExtensionsURL);
   }
 
-  // On Chrome OS the host desktop type for a browser window is always set to
-  // HOST_DESKTOP_TYPE_ASH. On Windows 8 it is only the case for Chrome ASH
-  // in metro mode.
-  if (browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH) {
-    // In ash, LAUNCH_FULLSCREEN launches in the OpenApplicationWindow function
-    // i.e. it should not reach here.
-    DCHECK(launch_type != extensions::LAUNCH_TYPE_FULLSCREEN);
-  } else {
-    // TODO(skerner):  If we are already in full screen mode, and the user
-    // set the app to open as a regular or pinned tab, what should happen?
-    // Today we open the tab, but stay in full screen mode.  Should we leave
-    // full screen mode in this case?
-    if (launch_type == extensions::LAUNCH_TYPE_FULLSCREEN &&
-        !browser->window()->IsFullscreen()) {
-#if defined(OS_MACOSX)
-      chrome::ToggleFullscreenWithChromeOrFallback(browser);
-#else
-      chrome::ToggleFullscreenMode(browser);
-#endif
-    }
-  }
-  return contents;
+  return url;
 }
 
 WebContents* OpenEnabledApplication(const AppLaunchParams& params) {
@@ -308,6 +161,7 @@
   // the onLaunched event.
   prefs->SetLastLaunchTime(extension->id(), base::Time::Now());
 
+  GURL url = UrlForExtension(extension, params.override_url);
   switch (params.container) {
     case extensions::LAUNCH_CONTAINER_NONE: {
       NOTREACHED();
@@ -315,10 +169,10 @@
     }
     case extensions::LAUNCH_CONTAINER_PANEL:
     case extensions::LAUNCH_CONTAINER_WINDOW:
-      tab = OpenApplicationWindow(params);
+      tab = OpenWebAppWindow(params, url);
       break;
     case extensions::LAUNCH_CONTAINER_TAB: {
-      tab = OpenApplicationTab(params);
+      tab = OpenWebAppTab(params, url);
       break;
     }
     default:
@@ -330,64 +184,6 @@
 
 }  // namespace
 
-AppLaunchParams::AppLaunchParams(Profile* profile,
-                                 const extensions::Extension* extension,
-                                 extensions::LaunchContainer container,
-                                 WindowOpenDisposition disposition)
-    : profile(profile),
-      extension_id(extension ? extension->id() : std::string()),
-      container(container),
-      disposition(disposition),
-      desktop_type(chrome::GetActiveDesktop()),
-      override_url(),
-      override_bounds(),
-      command_line(CommandLine::NO_PROGRAM) {}
-
-AppLaunchParams::AppLaunchParams(Profile* profile,
-                                 const extensions::Extension* extension,
-                                 WindowOpenDisposition disposition)
-    : profile(profile),
-      extension_id(extension ? extension->id() : std::string()),
-      container(extensions::LAUNCH_CONTAINER_NONE),
-      disposition(disposition),
-      desktop_type(chrome::GetActiveDesktop()),
-      override_url(),
-      override_bounds(),
-      command_line(CommandLine::NO_PROGRAM) {
-  // Look up the app preference to find out the right launch container. Default
-  // is to launch as a regular tab.
-  container =
-      extensions::GetLaunchContainer(ExtensionPrefs::Get(profile), extension);
-}
-
-AppLaunchParams::AppLaunchParams(Profile* profile,
-                                 const extensions::Extension* extension,
-                                 int event_flags,
-                                 chrome::HostDesktopType desktop_type)
-    : profile(profile),
-      extension_id(extension ? extension->id() : std::string()),
-      container(extensions::LAUNCH_CONTAINER_NONE),
-      disposition(ui::DispositionFromEventFlags(event_flags)),
-      desktop_type(desktop_type),
-      override_url(),
-      override_bounds(),
-      command_line(CommandLine::NO_PROGRAM) {
-  if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) {
-    container = extensions::LAUNCH_CONTAINER_TAB;
-  } else if (disposition == NEW_WINDOW) {
-    container = extensions::LAUNCH_CONTAINER_WINDOW;
-  } else {
-    // Look at preference to find the right launch container.  If no preference
-    // is set, launch as a regular tab.
-    container =
-        extensions::GetLaunchContainer(ExtensionPrefs::Get(profile), extension);
-    disposition = NEW_FOREGROUND_TAB;
-  }
-}
-
-AppLaunchParams::~AppLaunchParams() {
-}
-
 WebContents* OpenApplication(const AppLaunchParams& params) {
   return OpenEnabledApplication(params);
 }
@@ -403,8 +199,15 @@
   if (!service->IsExtensionEnabled(extension->id()) ||
       extensions::ExtensionRegistry::Get(profile)->GetExtensionById(
           extension->id(), extensions::ExtensionRegistry::TERMINATED)) {
-    (new EnableViaAppListFlow(
-        service, profile, params.desktop_type, extension->id(),
+  base::Callback<gfx::NativeWindow(void)> dialog_parent_window_getter;
+  // TODO(pkotwicz): Figure out which window should be used as the parent for
+  // the "enable application" dialog in Athena.
+#if !defined(USE_ATHENA)
+  dialog_parent_window_getter =
+      base::Bind(&ShowAppListAndGetNativeWindow, params.desktop_type);
+#endif
+    (new EnableViaDialogFlow(
+        service, profile, extension->id(), dialog_parent_window_getter,
         base::Bind(base::IgnoreResult(OpenEnabledApplication), params)))->Run();
     return;
   }
@@ -421,7 +224,7 @@
       NEW_WINDOW);
   launch_params.override_url = url;
 
-  WebContents* tab = OpenApplicationWindow(launch_params);
+  WebContents* tab = OpenWebAppWindow(launch_params, url);
 
   if (!tab)
     return NULL;
@@ -437,26 +240,3 @@
   extensions::Feature* feature = feature_provider->GetFeature("app.runtime");
   return feature->IsAvailableToExtension(extension).is_available();
 }
-
-GURL UrlForExtension(const Extension* extension, const GURL& override_url) {
-  if (!extension)
-    return override_url;
-
-  GURL url;
-  if (!override_url.is_empty()) {
-    DCHECK(extension->web_extent().MatchesURL(override_url) ||
-           override_url.GetOrigin() == extension->url());
-    url = override_url;
-  } else {
-    url = extensions::AppLaunchInfo::GetFullLaunchURL(extension);
-  }
-
-  // For extensions lacking launch urls, determine a reasonable fallback.
-  if (!url.is_valid()) {
-    url = extensions::OptionsPageInfo::GetOptionsPage(extension);
-    if (!url.is_valid())
-      url = GURL(chrome::kChromeUIExtensionsURL);
-  }
-
-  return url;
-}
diff --git a/chrome/browser/ui/extensions/application_launch.h b/chrome/browser/ui/extensions/application_launch.h
index 5f07ae0..63a331e7 100644
--- a/chrome/browser/ui/extensions/application_launch.h
+++ b/chrome/browser/ui/extensions/application_launch.h
@@ -5,21 +5,11 @@
 #ifndef CHROME_BROWSER_UI_EXTENSIONS_APPLICATION_LAUNCH_H_
 #define CHROME_BROWSER_UI_EXTENSIONS_APPLICATION_LAUNCH_H_
 
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "chrome/browser/ui/host_desktop.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "ui/base/window_open_disposition.h"
-#include "ui/gfx/rect.h"
+#include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "url/gurl.h"
 
-class Browser;
 class Profile;
 
-namespace base {
-class CommandLine;
-}
-
 namespace content {
 class WebContents;
 }
@@ -28,60 +18,6 @@
 class Extension;
 }
 
-struct AppLaunchParams {
-  AppLaunchParams(Profile* profile,
-                  const extensions::Extension* extension,
-                  extensions::LaunchContainer container,
-                  WindowOpenDisposition disposition);
-
-  // Helper to create AppLaunchParams using extensions::GetLaunchContainer with
-  // LAUNCH_TYPE_REGULAR to check for a user-configured container.
-  AppLaunchParams(Profile* profile,
-                  const extensions::Extension* extension,
-                  WindowOpenDisposition disposition);
-
-  // Helper to create AppLaunchParams using event flags that allows user to
-  // override the user-configured container using modifier keys, falling back to
-  // extensions::GetLaunchContainer() with no modifiers. |desktop_type|
-  // indicates the desktop upon which to launch (Ash or Native).
-  AppLaunchParams(Profile* profile,
-                  const extensions::Extension* extension,
-                  int event_flags,
-                  chrome::HostDesktopType desktop_type);
-
-  ~AppLaunchParams();
-
-  // The profile to load the application from.
-  Profile* profile;
-
-  // The extension to load.
-  std::string extension_id;
-
-  // The container type to launch the application in.
-  extensions::LaunchContainer container;
-
-  // If container is TAB, this field controls how the tab is opened.
-  WindowOpenDisposition disposition;
-
-  // The desktop type to launch on. Uses GetActiveDesktop() if unspecified.
-  chrome::HostDesktopType desktop_type;
-
-  // If non-empty, use override_url in place of the application's launch url.
-  GURL override_url;
-
-  // If non-empty, use override_boudns in place of the application's default
-  // position and dimensions.
-  gfx::Rect override_bounds;
-
-  // If non-empty, information from the command line may be passed on to the
-  // application.
-  base::CommandLine command_line;
-
-  // If non-empty, the current directory from which any relative paths on the
-  // command line should be expanded from.
-  base::FilePath current_directory;
-};
-
 // Opens the application, possibly prompting the user to re-enable it.
 void OpenApplicationWithReenablePrompt(const AppLaunchParams& params);
 
@@ -100,10 +36,4 @@
 // chrome.app.runtime.onLaunched event.
 bool CanLaunchViaEvent(const extensions::Extension* extension);
 
-// Get the launch URL for a given extension, with optional override/fallback.
-// |override_url|, if non-empty, will be preferred over the extension's
-// launch url.
-GURL UrlForExtension(const extensions::Extension* extension,
-                     const GURL& override_url);
-
 #endif  // CHROME_BROWSER_UI_EXTENSIONS_APPLICATION_LAUNCH_H_
diff --git a/chrome/browser/ui/extensions/application_launch_web_app.cc b/chrome/browser/ui/extensions/application_launch_web_app.cc
new file mode 100644
index 0000000..1f8fa3a
--- /dev/null
+++ b/chrome/browser/ui/extensions/application_launch_web_app.cc
@@ -0,0 +1,210 @@
+// Copyright (c) 2012 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/extensions/application_launch_web_app.h"
+
+#include <string>
+
+#include "apps/launcher.h"
+#include "base/metrics/histogram.h"
+#include "chrome/browser/app_mode/app_mode_utils.h"
+#include "chrome/browser/extensions/launch_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/extensions/app_launch_params.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/web_applications/web_app.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/renderer_preferences.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/common/extension.h"
+#include "ui/base/window_open_disposition.h"
+#include "ui/gfx/rect.h"
+
+#if defined(OS_MACOSX)
+#include "chrome/browser/ui/browser_commands_mac.h"
+#endif
+
+using content::WebContents;
+using extensions::Extension;
+using extensions::ExtensionPrefs;
+using extensions::ExtensionRegistry;
+
+namespace {
+
+const Extension* GetExtension(const AppLaunchParams& params) {
+  if (params.extension_id.empty())
+    return NULL;
+  ExtensionRegistry* registry = ExtensionRegistry::Get(params.profile);
+  return registry->GetExtensionById(params.extension_id,
+                                    ExtensionRegistry::ENABLED |
+                                        ExtensionRegistry::DISABLED |
+                                        ExtensionRegistry::TERMINATED);
+}
+
+ui::WindowShowState DetermineWindowShowState(
+    Profile* profile,
+    extensions::LaunchContainer container,
+    const Extension* extension) {
+  if (!extension || container != extensions::LAUNCH_CONTAINER_WINDOW)
+    return ui::SHOW_STATE_DEFAULT;
+
+  if (chrome::IsRunningInForcedAppMode())
+    return ui::SHOW_STATE_FULLSCREEN;
+
+#if defined(USE_ASH)
+  // In ash, LAUNCH_TYPE_FULLSCREEN launches in a maximized app window and
+  // LAUNCH_TYPE_WINDOW launches in a normal app window.
+  extensions::LaunchType launch_type =
+      extensions::GetLaunchType(ExtensionPrefs::Get(profile), extension);
+  if (launch_type == extensions::LAUNCH_TYPE_FULLSCREEN)
+    return ui::SHOW_STATE_MAXIMIZED;
+  else if (launch_type == extensions::LAUNCH_TYPE_WINDOW)
+    return ui::SHOW_STATE_NORMAL;
+#endif
+
+  return ui::SHOW_STATE_DEFAULT;
+}
+
+}  // namespace
+
+WebContents* OpenWebAppWindow(const AppLaunchParams& params, const GURL& url) {
+  Profile* const profile = params.profile;
+  const Extension* const extension = GetExtension(params);
+
+  std::string app_name = extension ?
+      web_app::GenerateApplicationNameFromExtensionId(extension->id()) :
+      web_app::GenerateApplicationNameFromURL(url);
+
+  gfx::Rect initial_bounds;
+  if (!params.override_bounds.IsEmpty()) {
+    initial_bounds = params.override_bounds;
+  } else if (extension) {
+    initial_bounds.set_width(
+        extensions::AppLaunchInfo::GetLaunchWidth(extension));
+    initial_bounds.set_height(
+        extensions::AppLaunchInfo::GetLaunchHeight(extension));
+  }
+
+  Browser::CreateParams browser_params(
+      Browser::CreateParams::CreateForApp(app_name,
+                                          true /* trusted_source */,
+                                          initial_bounds,
+                                          profile,
+                                          params.desktop_type));
+
+  browser_params.initial_show_state = DetermineWindowShowState(profile,
+                                                               params.container,
+                                                               extension);
+
+  Browser* browser = new Browser(browser_params);
+
+  WebContents* web_contents = chrome::AddSelectedTabWithURL(
+      browser, url, ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
+  web_contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
+  web_contents->GetRenderViewHost()->SyncRendererPrefs();
+
+  browser->window()->Show();
+
+  // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
+  //                focus explicitly.
+  web_contents->SetInitialFocus();
+  return web_contents;
+}
+
+WebContents* OpenWebAppTab(const AppLaunchParams& launch_params,
+                           const GURL& url) {
+  const Extension* extension = GetExtension(launch_params);
+  CHECK(extension);
+  Profile* const profile = launch_params.profile;
+  WindowOpenDisposition disposition = launch_params.disposition;
+
+  Browser* browser = chrome::FindTabbedBrowser(profile,
+                                               false,
+                                               launch_params.desktop_type);
+  WebContents* contents = NULL;
+  if (!browser) {
+    // No browser for this profile, need to open a new one.
+    browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED,
+                                                profile,
+                                                launch_params.desktop_type));
+    browser->window()->Show();
+    // There's no current tab in this browser window, so add a new one.
+    disposition = NEW_FOREGROUND_TAB;
+  } else {
+    // For existing browser, ensure its window is shown and activated.
+    browser->window()->Show();
+    browser->window()->Activate();
+  }
+
+  extensions::LaunchType launch_type =
+      extensions::GetLaunchType(ExtensionPrefs::Get(profile), extension);
+  UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
+
+  int add_type = TabStripModel::ADD_ACTIVE;
+  if (launch_type == extensions::LAUNCH_TYPE_PINNED)
+    add_type |= TabStripModel::ADD_PINNED;
+
+  chrome::NavigateParams params(browser, url,
+                                ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
+  params.tabstrip_add_types = add_type;
+  params.disposition = disposition;
+
+  if (disposition == CURRENT_TAB) {
+    WebContents* existing_tab =
+        browser->tab_strip_model()->GetActiveWebContents();
+    TabStripModel* model = browser->tab_strip_model();
+    int tab_index = model->GetIndexOfWebContents(existing_tab);
+
+    existing_tab->OpenURL(content::OpenURLParams(
+          url,
+          content::Referrer(existing_tab->GetURL(),
+                            blink::WebReferrerPolicyDefault),
+          disposition, ui::PAGE_TRANSITION_LINK, false));
+    // Reset existing_tab as OpenURL() may have clobbered it.
+    existing_tab = browser->tab_strip_model()->GetActiveWebContents();
+    if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
+      model->SetTabPinned(tab_index, true);
+      // Pinning may have moved the tab.
+      tab_index = model->GetIndexOfWebContents(existing_tab);
+    }
+    if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
+      model->ActivateTabAt(tab_index, true);
+
+    contents = existing_tab;
+  } else {
+    chrome::Navigate(&params);
+    contents = params.target_contents;
+  }
+
+  // On Chrome OS the host desktop type for a browser window is always set to
+  // HOST_DESKTOP_TYPE_ASH. On Windows 8 it is only the case for Chrome ASH
+  // in metro mode.
+  if (browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH) {
+    // In ash, LAUNCH_FULLSCREEN launches in the OpenApplicationWindow function
+    // i.e. it should not reach here.
+    DCHECK(launch_type != extensions::LAUNCH_TYPE_FULLSCREEN);
+  } else {
+    // TODO(skerner):  If we are already in full screen mode, and the user
+    // set the app to open as a regular or pinned tab, what should happen?
+    // Today we open the tab, but stay in full screen mode.  Should we leave
+    // full screen mode in this case?
+    if (launch_type == extensions::LAUNCH_TYPE_FULLSCREEN &&
+        !browser->window()->IsFullscreen()) {
+#if defined(OS_MACOSX)
+      chrome::ToggleFullscreenWithChromeOrFallback(browser);
+#else
+      chrome::ToggleFullscreenMode(browser);
+#endif
+    }
+  }
+  return contents;
+}
diff --git a/chrome/browser/ui/extensions/application_launch_web_app.h b/chrome/browser/ui/extensions/application_launch_web_app.h
new file mode 100644
index 0000000..e19a272b
--- /dev/null
+++ b/chrome/browser/ui/extensions/application_launch_web_app.h
@@ -0,0 +1,25 @@
+// 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_EXTENSIONS_APPLICATION_LAUNCH_WEB_APP_H_
+#define CHROME_BROWSER_UI_EXTENSIONS_APPLICATION_LAUNCH_WEB_APP_H_
+
+#include "chrome/browser/ui/extensions/app_launch_params.h"
+#include "url/gurl.h"
+
+namespace content {
+class WebContents;
+}
+
+// Helper method to OpenApplication() which opens a web app window with |url|
+// in the way specified by |params|.
+content::WebContents* OpenWebAppWindow(const AppLaunchParams& params,
+                                       const GURL& url);
+
+// Helper method to OpenApplication() which opens a web app tab with |url| in
+// the way specified by |params|.
+content::WebContents* OpenWebAppTab(const AppLaunchParams& params,
+                                    const GURL& url);
+
+#endif  // CHROME_BROWSER_UI_EXTENSIONS_APPLICATION_LAUNCH_WEB_APP_H_
diff --git a/chrome/browser/ui/extensions/extension_enable_flow.cc b/chrome/browser/ui/extensions/extension_enable_flow.cc
index ebfbdb77..8e305e79 100644
--- a/chrome/browser/ui/extensions/extension_enable_flow.cc
+++ b/chrome/browser/ui/extensions/extension_enable_flow.cc
@@ -7,9 +7,7 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
-#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "extensions/browser/extension_prefs.h"
@@ -108,7 +106,7 @@
     parent_window_ = window_getter_.Run();
   prompt_.reset(parent_contents_ ?
       new ExtensionInstallPrompt(parent_contents_) :
-      new ExtensionInstallPrompt(profile_, parent_window_, this));
+      new ExtensionInstallPrompt(profile_, parent_window_));
 }
 
 void ExtensionEnableFlow::StartObserving() {
@@ -171,10 +169,3 @@
   delegate_->ExtensionEnableFlowAborted(user_initiated);
   // |delegate_| may delete us.
 }
-
-content::WebContents* ExtensionEnableFlow::OpenURL(
-    const content::OpenURLParams& params) {
-  chrome::ScopedTabbedBrowserDisplayer displayer(
-      profile_, chrome::GetActiveDesktop());
-  return displayer.browser()->OpenURL(params);
-}
diff --git a/chrome/browser/ui/extensions/extension_enable_flow.h b/chrome/browser/ui/extensions/extension_enable_flow.h
index cfe9bbe0..fc6bf62 100644
--- a/chrome/browser/ui/extensions/extension_enable_flow.h
+++ b/chrome/browser/ui/extensions/extension_enable_flow.h
@@ -14,13 +14,11 @@
 #include "chrome/browser/extensions/extension_install_prompt.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/page_navigator.h"
 #include "extensions/browser/extension_registry_observer.h"
 
 class ExtensionEnableFlowDelegate;
 
 namespace content {
-class PageNavigator;
 class WebContents;
 }
 
@@ -36,7 +34,6 @@
 // shown to user. The extension is enabled when user acknowledges it or the
 // flow is aborted when user declines it.
 class ExtensionEnableFlow : public ExtensionInstallPrompt::Delegate,
-                            public content::PageNavigator,
                             public content::NotificationObserver,
                             public extensions::ExtensionRegistryObserver {
  public:
@@ -95,9 +92,6 @@
   void InstallUIProceed() override;
   void InstallUIAbort(bool user_initiated) override;
 
-  // content::PageNavigator overrides:
-  content::WebContents* OpenURL(const content::OpenURLParams& params) override;
-
   Profile* const profile_;
   const std::string extension_id_;
   ExtensionEnableFlowDelegate* const delegate_;  // Not owned.
diff --git a/chrome/browser/ui/libgtk2ui/PRESUBMIT.py b/chrome/browser/ui/libgtk2ui/PRESUBMIT.py
index 9704b39..daaaa59 100755
--- a/chrome/browser/ui/libgtk2ui/PRESUBMIT.py
+++ b/chrome/browser/ui/libgtk2ui/PRESUBMIT.py
@@ -13,6 +13,6 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_rel_swarming': set(['defaulttests']),
+      'linux_chromium_rel': set(['defaulttests']),
     }
   }
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index 227ddac..4a0f5c1 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -291,7 +291,7 @@
     BookmarkModel* bookmark_model =
         BookmarkModelFactory::GetForProfile(profile);
     ASSERT_TRUE(bookmark_model);
-    test::WaitForBookmarkModelToLoad(bookmark_model);
+    bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
 
     GURL url(entry.url);
     // Add everything in order of time. We don't want to have a time that
diff --git a/chrome/browser/ui/panels/panel_browsertest.cc b/chrome/browser/ui/panels/panel_browsertest.cc
index 24dc3c0..2873a7b 100644
--- a/chrome/browser/ui/panels/panel_browsertest.cc
+++ b/chrome/browser/ui/panels/panel_browsertest.cc
@@ -12,8 +12,6 @@
 #include "chrome/browser/net/url_request_mock_util.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -31,6 +29,8 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.cc b/chrome/browser/ui/prefs/prefs_tab_helper.cc
index ce4397c..9a82d69 100644
--- a/chrome/browser/ui/prefs/prefs_tab_helper.cc
+++ b/chrome/browser/ui/prefs/prefs_tab_helper.cc
@@ -205,6 +205,8 @@
   { prefs::kWebKitFixedFontFamilyTraditionalHan,
     IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN },
 #elif defined(OS_WIN)
+  { prefs::kWebKitSansSerifFontFamilyArabic,
+    IDS_SANS_SERIF_FONT_FAMILY_ARABIC },
   { prefs::kWebKitStandardFontFamilyCyrillic,
     IDS_STANDARD_FONT_FAMILY_CYRILLIC },
   { prefs::kWebKitFixedFontFamilyCyrillic, IDS_FIXED_FONT_FAMILY_CYRILLIC },
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
index 105cdf5..7eca8028 100644
--- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
+++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
@@ -140,7 +140,7 @@
     // Initialize the services we check.
     profile_->CreateBookmarkModel(true);
     model_ = BookmarkModelFactory::GetForProfile(profile_.get());
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
     ASSERT_TRUE(profile_->CreateHistoryService(true, false));
 #if defined(ENABLE_EXTENSIONS)
     extensions::TestExtensionSystem* system =
diff --git a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
index 90aa094..ff68c03 100644
--- a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
+++ b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
@@ -117,19 +117,19 @@
   EXPECT_EQ(extension_c()->id(), browser_actions_bar()->GetExtensionId(2));
 
   // Move C to first position. Order is C A B.
-  model->MoveExtensionIcon(extension_c(), 0);
+  model->MoveExtensionIcon(extension_c()->id(), 0);
   EXPECT_EQ(extension_c()->id(), browser_actions_bar()->GetExtensionId(0));
   EXPECT_EQ(extension_a()->id(), browser_actions_bar()->GetExtensionId(1));
   EXPECT_EQ(extension_b()->id(), browser_actions_bar()->GetExtensionId(2));
 
   // Move B to third position. Order is still C A B.
-  model->MoveExtensionIcon(extension_b(), 2);
+  model->MoveExtensionIcon(extension_b()->id(), 2);
   EXPECT_EQ(extension_c()->id(), browser_actions_bar()->GetExtensionId(0));
   EXPECT_EQ(extension_a()->id(), browser_actions_bar()->GetExtensionId(1));
   EXPECT_EQ(extension_b()->id(), browser_actions_bar()->GetExtensionId(2));
 
   // Move B to middle position. Order is C B A.
-  model->MoveExtensionIcon(extension_b(), 1);
+  model->MoveExtensionIcon(extension_b()->id(), 1);
   EXPECT_EQ(extension_c()->id(), browser_actions_bar()->GetExtensionId(0));
   EXPECT_EQ(extension_b()->id(), browser_actions_bar()->GetExtensionId(1));
   EXPECT_EQ(extension_a()->id(), browser_actions_bar()->GetExtensionId(2));
diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc
new file mode 100644
index 0000000..9764ea8
--- /dev/null
+++ b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.cc
@@ -0,0 +1,51 @@
+// 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/toolbar/component_toolbar_actions_factory.h"
+
+#include "base/lazy_instance.h"
+#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
+#include "extensions/common/feature_switch.h"
+
+namespace {
+
+ComponentToolbarActionsFactory* testing_factory_ = nullptr;
+
+base::LazyInstance<ComponentToolbarActionsFactory> lazy_factory =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+ComponentToolbarActionsFactory::ComponentToolbarActionsFactory() {}
+ComponentToolbarActionsFactory::~ComponentToolbarActionsFactory() {}
+
+// static
+ComponentToolbarActionsFactory* ComponentToolbarActionsFactory::GetInstance() {
+  return testing_factory_ ? testing_factory_ : &lazy_factory.Get();
+}
+
+ScopedVector<ToolbarActionViewController>
+ComponentToolbarActionsFactory::GetComponentToolbarActions() {
+  ScopedVector<ToolbarActionViewController> component_actions;
+
+  // This is currently behind the extension-action-redesign flag, as it is
+  // designed for the new toolbar.
+  if (!extensions::FeatureSwitch::extension_action_redesign()->IsEnabled())
+    return component_actions.Pass();
+
+  // Add component toolbar actions here.
+  // This current design means that the ComponentToolbarActionsFactory is aware
+  // of all actions. Since we should *not* have an excessive amount of these
+  // (since each will have an action in the toolbar or overflow menu), this
+  // should be okay. If this changes, we should rethink this design to have,
+  // e.g., RegisterChromeAction().
+
+  return component_actions.Pass();
+}
+
+// static
+void ComponentToolbarActionsFactory::SetTestingFactory(
+    ComponentToolbarActionsFactory* factory) {
+  testing_factory_ = factory;
+}
diff --git a/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h
new file mode 100644
index 0000000..42c0cdca
--- /dev/null
+++ b/chrome/browser/ui/toolbar/component_toolbar_actions_factory.h
@@ -0,0 +1,37 @@
+// 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_TOOLBAR_COMPONENT_TOOLBAR_ACTIONS_FACTORY_H_
+#define CHROME_BROWSER_UI_TOOLBAR_COMPONENT_TOOLBAR_ACTIONS_FACTORY_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_vector.h"
+
+class Profile;
+class ToolbarActionViewController;
+
+// The registry for all component toolbar actions. Component toolbar actions
+// are actions that live in the toolbar (like extension actions), but are
+// components of chrome, such as ChromeCast.
+class ComponentToolbarActionsFactory {
+ public:
+  ComponentToolbarActionsFactory();
+  ~ComponentToolbarActionsFactory();
+
+  static ComponentToolbarActionsFactory* GetInstance();
+
+  // Returns a collection of controllers for Chrome Actions. Declared virtual
+  // for testing.
+  virtual ScopedVector<ToolbarActionViewController>
+      GetComponentToolbarActions();
+
+  // Sets the factory to use for testing purposes.
+  // Ownership remains with the caller.
+  static void SetTestingFactory(ComponentToolbarActionsFactory* factory);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ComponentToolbarActionsFactory);
+};
+
+#endif  // CHROME_BROWSER_UI_TOOLBAR_COMPONENT_TOOLBAR_ACTIONS_FACTORY_H_
diff --git a/chrome/browser/ui/toolbar/encoding_menu_controller.cc b/chrome/browser/ui/toolbar/encoding_menu_controller.cc
index cd9acd5..8d9089c 100644
--- a/chrome/browser/ui/toolbar/encoding_menu_controller.cc
+++ b/chrome/browser/ui/toolbar/encoding_menu_controller.cc
@@ -18,7 +18,6 @@
 const int EncodingMenuController::kValidEncodingIds[] = {
     IDC_ENCODING_UTF8,
     IDC_ENCODING_UTF16LE,
-    IDC_ENCODING_ISO88591,
     IDC_ENCODING_WINDOWS1252,
     IDC_ENCODING_GBK,
     IDC_ENCODING_GB18030,
diff --git a/chrome/browser/ui/toolbar/toolbar_action_view_controller.h b/chrome/browser/ui/toolbar/toolbar_action_view_controller.h
new file mode 100644
index 0000000..b185ab4
--- /dev/null
+++ b/chrome/browser/ui/toolbar/toolbar_action_view_controller.h
@@ -0,0 +1,89 @@
+// 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_TOOLBAR_TOOLBAR_ACTION_VIEW_CONTROLLER_H_
+#define CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_ACTION_VIEW_CONTROLLER_H_
+
+#include "base/strings/string16.h"
+#include "ui/gfx/image/image.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace gfx {
+class Canvas;
+class Rect;
+}
+
+class ToolbarActionViewDelegate;
+
+// The basic controller class for an action that is shown on the toolbar -
+// an extension action (like browser actions) or a component action (like
+// chromecast).
+class ToolbarActionViewController {
+ public:
+  virtual ~ToolbarActionViewController() {}
+
+  // Returns the unique ID of this particular action. For extensions, this is
+  // the extension id; for component actions, this is the name of the component.
+  virtual const std::string& GetId() const = 0;
+
+  // Sets the view delegate, which can handle most of the front-end logic.
+  virtual void SetDelegate(ToolbarActionViewDelegate* delegate) = 0;
+
+  // Returns the icon to use for the given |web_contents|.
+  virtual gfx::Image GetIcon(content::WebContents* web_contents) = 0;
+
+  // Returns the icon and the badge, if any, for the current tab.
+  virtual gfx::ImageSkia GetIconWithBadge() = 0;
+
+  // Returns the accessible name to use for the given |web_contents|.
+  virtual base::string16 GetAccessibleName(content::WebContents* web_contents)
+      const = 0;
+
+  // Returns the tooltip to use for the given |web_contents|.
+  virtual base::string16 GetTooltip(content::WebContents* web_contents)
+      const = 0;
+
+  // Returns true if the action should be enabled on the given |web_contents|.
+  virtual bool IsEnabled(content::WebContents* web_contents) const = 0;
+
+  // Returns true if the action has a popup for the given |web_contents|.
+  virtual bool HasPopup(content::WebContents* web_contents) const = 0;
+
+  // Hides the current popup, if one is visible.
+  virtual void HidePopup() = 0;
+
+  // Returns the native view for the popup, if one is active.
+  virtual gfx::NativeView GetPopupNativeView() = 0;
+
+  // Returns true if a menu is currently running for the action.
+  virtual bool IsMenuRunning() const = 0;
+
+  // Returns true if this view can be dragged. This should only be true for
+  // extensions right now, since they are the only ones the model currently
+  // supports.
+  // TODO(devlin): Tweak the model so that it supports generic actions.
+  virtual bool CanDrag() const = 0;
+
+  // Executes the default action (which is typically showing the popup). If
+  // |by_user| is true, then this was through a direct user action (as oppposed
+  // to, e.g., an API call).
+  // Returns true if a popup is shown.
+  virtual bool ExecuteAction(bool by_user) = 0;
+
+  // Paints any extra parts of the image (e.g., a badge).
+  virtual void PaintExtra(gfx::Canvas* canvas,
+                          const gfx::Rect& bounds,
+                          content::WebContents* web_contents) const {
+  }
+
+  // Registers an accelerator. Called when the view is added to the hierarchy.
+  // Unregistering any commands is the responsibility of the controller.
+  virtual void RegisterCommand() {
+  }
+};
+
+#endif  // CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_ACTION_VIEW_CONTROLLER_H_
diff --git a/chrome/browser/ui/toolbar/toolbar_model.h b/chrome/browser/ui/toolbar/toolbar_model.h
index d05cccb..98888bb 100644
--- a/chrome/browser/ui/toolbar/toolbar_model.h
+++ b/chrome/browser/ui/toolbar/toolbar_model.h
@@ -23,10 +23,32 @@
   // TODO(wtc): unify ToolbarModel::SecurityLevel with SecurityStyle.  We
   // don't need two sets of security UI levels.  SECURITY_STYLE_AUTHENTICATED
   // needs to be refined into three levels: warning, standard, and EV.
+  //
+  // A Java counterpart will be generated for this enum.
+  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.ui.toolbar
+  // GENERATED_JAVA_CLASS_NAME_OVERRIDE: ToolbarModelSecurityLevel
   enum SecurityLevel {
-#define DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(name,value)  name = value,
-#include "chrome/browser/ui/toolbar/toolbar_model_security_level_list.h"
-#undef DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL
+    // HTTP/no URL/user is editing
+    NONE = 0,
+
+    // HTTPS with valid EV cert
+    EV_SECURE = 1,
+
+    // HTTPS (non-EV)
+    SECURE = 2,
+
+    // HTTPS, but unable to check certificate revocation status or with insecure
+    // content on the page
+    SECURITY_WARNING = 3,
+
+    // HTTPS, but the certificate verification chain is anchored on a
+    // certificate that was installed by the system administrator
+    SECURITY_POLICY_WARNING = 4,
+
+    // Attempted HTTPS and failed, page not authenticated
+    SECURITY_ERROR = 5,
+
+    NUM_SECURITY_LEVELS = 6,
   };
 
   virtual ~ToolbarModel();
diff --git a/chrome/browser/ui/toolbar/toolbar_model_security_level_list.h b/chrome/browser/ui/toolbar/toolbar_model_security_level_list.h
deleted file mode 100644
index f5502a98..0000000
--- a/chrome/browser/ui/toolbar/toolbar_model_security_level_list.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 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.
-
-// Intentionally no include guards because this file is meant to be included
-// inside a macro to generate enum values.
-
-#ifndef DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL
-#error "Please define DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL before including \
-  this file."
-#endif
-
-// HTTP/no URL/user is editing
-DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(NONE, 0)
-
-// HTTPS with valid EV cert
-DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(EV_SECURE, 1)
-
-// HTTPS (non-EV)
-DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(SECURE, 2)
-
-// HTTPS, but unable to check certificate revocation status or with insecure
-// content on the page
-DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(SECURITY_WARNING, 3)
-
-// HTTPS, but the certificate verification chain is anchored on a certificate
-// that was installed by the system administrator
-DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(SECURITY_POLICY_WARNING, 4)
-
-// Attempted HTTPS and failed, page not authenticated
-DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(SECURITY_ERROR, 5)
-
-DEFINE_TOOLBAR_MODEL_SECURITY_LEVEL(NUM_SECURITY_LEVELS, 6)
diff --git a/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc b/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
index 4d4f6614..8f507a8ff 100644
--- a/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
@@ -200,5 +200,5 @@
 TEST_F(EncodingMenuModelTest, IsCommandIdCheckedWithNoTabs) {
   EncodingMenuModel model(browser());
   ASSERT_EQ(NULL, browser()->tab_strip_model()->GetActiveWebContents());
-  EXPECT_FALSE(model.IsCommandIdChecked(IDC_ENCODING_ISO88591));
+  EXPECT_FALSE(model.IsCommandIdChecked(IDC_ENCODING_WINDOWS1252));
 }
diff --git a/chrome/browser/ui/views/PRESUBMIT.py b/chrome/browser/ui/views/PRESUBMIT.py
index 7313069..49c28be 100644
--- a/chrome/browser/ui/views/PRESUBMIT.py
+++ b/chrome/browser/ui/views/PRESUBMIT.py
@@ -11,6 +11,6 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_chromeos_rel_swarming': set(['defaulttests']),
+      'linux_chromium_chromeos_rel': set(['defaulttests']),
     }
   }
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc
index cbb9b1f..773f0758 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc
@@ -101,20 +101,23 @@
     // Create a horizontal container to store the app's links.
     views::View* horizontal_links_container =
         CreateHorizontalStack(kSpacingBetweenAppLinks);
-    if (CanShowAppInWebStore()) {
-      view_in_store_link_ = new views::Link(
-          l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_WEB_STORE_LINK));
-      view_in_store_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-      view_in_store_link_->set_listener(this);
-      horizontal_links_container->AddChildView(view_in_store_link_);
-    }
+
+    // If the app/extension has a custom home page, display a link to the
+    // developer's homepage *instead of* a link to the webstore.
     if (CanShowAppHomePage()) {
       homepage_link_ = new views::Link(
           l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_HOMEPAGE_LINK));
       homepage_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
       homepage_link_->set_listener(this);
       horizontal_links_container->AddChildView(homepage_link_);
+    } else if (CanShowAppInWebStore()) {
+      view_in_store_link_ = new views::Link(
+          l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_WEB_STORE_LINK));
+      view_in_store_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+      view_in_store_link_->set_listener(this);
+      horizontal_links_container->AddChildView(view_in_store_link_);
     }
+
     if (CanDisplayLicenses()) {
       licenses_link_ = new views::Link(
           l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_LICENSES_BUTTON_TEXT));
@@ -173,6 +176,7 @@
       extensions::ManifestURL::GetDetailsURL(app_),
       extension_urls::kWebstoreSourceField,
       extension_urls::kLaunchSourceAppListInfoDialog));
+  Close();
 }
 
 bool AppInfoHeaderPanel::CanShowAppInWebStore() const {
@@ -182,6 +186,7 @@
 void AppInfoHeaderPanel::ShowAppHomePage() {
   DCHECK(CanShowAppHomePage());
   OpenLink(extensions::ManifestURL::GetHomepageURL(app_));
+  Close();
 }
 
 bool AppInfoHeaderPanel::CanShowAppHomePage() const {
@@ -190,34 +195,40 @@
 
 void AppInfoHeaderPanel::DisplayLicenses() {
   DCHECK(CanDisplayLicenses());
-  OpenLink(GetLicenseUrl());
+  for (const auto& license_url : GetLicenseUrls())
+    OpenLink(license_url);
+  Close();
 }
 
 bool AppInfoHeaderPanel::CanDisplayLicenses() const {
-  return !GetLicenseUrl().is_empty();
+  return !GetLicenseUrls().empty();
 }
 
-const GURL& AppInfoHeaderPanel::GetLicenseUrl() const {
-  // Find the first shared module for this app, and return its URL.
-  // TODO(sashab): Support multiple shared modules with licenses once shared
-  // module usage becomes more common.
+const std::vector<GURL> AppInfoHeaderPanel::GetLicenseUrls() const {
   if (!extensions::SharedModuleInfo::ImportsModules(app_))
-    return GURL::EmptyGURL();
+    return std::vector<GURL>();
 
+  std::vector<GURL> license_urls;
   ExtensionService* service =
       extensions::ExtensionSystem::Get(profile_)->extension_service();
   DCHECK(service);
   const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
       extensions::SharedModuleInfo::GetImports(app_);
-  const extensions::Extension* imported_module =
-      service->GetExtensionById(imports[0].extension_id, true);
-  DCHECK(imported_module);
-  return extensions::ManifestURL::GetAboutPage(imported_module);
+
+  for (const auto& shared_module : imports) {
+    const extensions::Extension* imported_module =
+        service->GetExtensionById(shared_module.extension_id, true);
+    DCHECK(imported_module);
+
+    GURL about_page = extensions::ManifestURL::GetAboutPage(imported_module);
+    if (about_page != GURL::EmptyGURL())
+      license_urls.push_back(about_page);
+  }
+  return license_urls;
 }
 
 void AppInfoHeaderPanel::OpenLink(const GURL& url) {
   DCHECK(!url.is_empty());
   chrome::NavigateParams params(profile_, url, ui::PAGE_TRANSITION_LINK);
   chrome::Navigate(&params);
-  Close();
 }
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h
index 566c11d..cdbc73a 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h
@@ -58,9 +58,9 @@
   // CanDisplayLicenses() returns true.
   void DisplayLicenses();
   bool CanDisplayLicenses() const;
-  const GURL& GetLicenseUrl() const;
+  const std::vector<GURL> GetLicenseUrls() const;
 
-  // Opens the given URL in a new browser tab, and closes the dialog.
+  // Opens the given URL in a new browser tab.
   void OpenLink(const GURL& url);
 
   // UI elements on the dialog. Elements are NULL if they are not displayed.
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc
index fb9bc84..c5f8d50e 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.cc
@@ -53,10 +53,6 @@
   return vertically_stacked_view;
 }
 
-views::View* AppInfoPanel::CreateHorizontalStack() const {
-  return CreateVerticalStack(views::kRelatedControlHorizontalSpacing);
-}
-
 views::View* AppInfoPanel::CreateKeyValueField(views::View* key,
                                                views::View* value) const {
   views::View* horizontal_stack =
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h
index 8bef325..8fac49d 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h
@@ -38,10 +38,8 @@
   views::View* CreateVerticalStack() const;
 
   // Create a view with a horizontally-stacked box layout, which can have child
-  // views appended to it. |child_spacing| defaults to the spacing between
-  // related horizontal controls.
+  // views appended to it.
   views::View* CreateHorizontalStack(int child_spacing) const;
-  views::View* CreateHorizontalStack() const;
 
   // Given a key and a value, displays them side-by-side as a field and its
   // value.
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc
index 050c11d..fdfb8109 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.cc
@@ -17,226 +17,240 @@
 #include "extensions/common/permissions/api_permission.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/views/controls/button/label_button.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/resources/grit/ui_resources.h"
+#include "ui/views/border.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/layout/layout_constants.h"
 #include "ui/views/view.h"
 
+namespace {
+
+// IDs for the two bullet column sets.
+const int kBulletColumnSetId = 1;
+const int kNestedBulletColumnSetId = 2;
+
+// Pixel spacing measurements for different parts of the permissions list.
+const int kSpacingBetweenBulletAndStartOfText = 5;
+const int kSpacingBetweenTextAndRevokeButton = 15;
+const int kIndentationBeforeNestedBullet = 13;
+
+// Creates a close button that calls |callback| on click and can be placed to
+// the right of a bullet in the permissions list.
+class RevokeButton : public views::ImageButton, public views::ButtonListener {
+ public:
+  explicit RevokeButton(const base::Closure& callback)
+      : views::ImageButton(this), callback_(callback) {
+    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+    SetImage(views::CustomButton::STATE_NORMAL,
+             rb.GetImageNamed(IDR_DISABLE).ToImageSkia());
+    SetImage(views::CustomButton::STATE_HOVERED,
+             rb.GetImageNamed(IDR_DISABLE_H).ToImageSkia());
+    SetImage(views::CustomButton::STATE_PRESSED,
+             rb.GetImageNamed(IDR_DISABLE_P).ToImageSkia());
+    SetBorder(scoped_ptr<views::Border>());
+    SetSize(GetPreferredSize());
+  }
+  virtual ~RevokeButton() {}
+
+ private:
+  // Overridden from views::ButtonListener.
+  virtual void ButtonPressed(views::Button* sender,
+                             const ui::Event& event) override {
+    DCHECK_EQ(this, sender);
+    if (!callback_.is_null())
+      callback_.Run();
+  }
+
+  const base::Closure callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(RevokeButton);
+};
+
+// A bulleted list of permissions.
+// TODO(sashab): Fix BoxLayout to correctly display multi-line strings and then
+// remove this class (since the GridLayout will no longer be needed).
+class BulletedPermissionsList : public views::View {
+ public:
+  BulletedPermissionsList() {
+    layout_ = new views::GridLayout(this);
+    SetLayoutManager(layout_);
+
+    // Create 3 columns: the bullet, the bullet text, and the revoke button.
+    views::ColumnSet* column_set = layout_->AddColumnSet(kBulletColumnSetId);
+    column_set->AddColumn(views::GridLayout::FILL,
+                          views::GridLayout::LEADING,
+                          0,
+                          views::GridLayout::USE_PREF,
+                          0,
+                          0);
+    column_set->AddPaddingColumn(0, kSpacingBetweenBulletAndStartOfText);
+    column_set->AddColumn(views::GridLayout::FILL,
+                          views::GridLayout::LEADING,
+                          1 /* stretch to fill space */,
+                          views::GridLayout::USE_PREF,
+                          0,
+                          0);
+    column_set->AddPaddingColumn(0, kSpacingBetweenTextAndRevokeButton);
+    column_set->AddColumn(views::GridLayout::FILL,
+                          views::GridLayout::LEADING,
+                          0,
+                          views::GridLayout::USE_PREF,
+                          0,
+                          0);
+
+    views::ColumnSet* nested_column_set =
+        layout_->AddColumnSet(kNestedBulletColumnSetId);
+    nested_column_set->AddPaddingColumn(0, kIndentationBeforeNestedBullet);
+    nested_column_set->AddColumn(views::GridLayout::FILL,
+                                 views::GridLayout::LEADING,
+                                 0,
+                                 views::GridLayout::USE_PREF,
+                                 0,
+                                 0);
+    nested_column_set->AddPaddingColumn(0, kSpacingBetweenBulletAndStartOfText);
+    nested_column_set->AddColumn(views::GridLayout::FILL,
+                                 views::GridLayout::LEADING,
+                                 1 /* stretch to fill space */,
+                                 views::GridLayout::USE_PREF,
+                                 0,
+                                 0);
+    nested_column_set->AddPaddingColumn(0, kSpacingBetweenTextAndRevokeButton);
+    nested_column_set->AddColumn(views::GridLayout::FILL,
+                                 views::GridLayout::LEADING,
+                                 0,
+                                 views::GridLayout::USE_PREF,
+                                 0,
+                                 0);
+  }
+  virtual ~BulletedPermissionsList() {}
+
+  // Given a set of strings for a given permission (|message| for the topmost
+  // bullet and a potentially-empty |submessages| for sub-bullets), adds these
+  // bullets to the given BulletedPermissionsList. If |revoke_callback| is
+  // provided, also adds an X button next to the bullet which calls the callback
+  // when clicked.
+  void AddPermissionBullets(base::string16 message,
+                            std::vector<base::string16> submessages,
+                            gfx::ElideBehavior elide_behavior_for_submessages,
+                            const base::Closure& revoke_callback) {
+    RevokeButton* revoke_button = NULL;
+    if (!revoke_callback.is_null())
+      revoke_button = new RevokeButton(revoke_callback);
+
+    views::Label* permission_label = new views::Label(message);
+    permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+    permission_label->SetMultiLine(true);
+    AddSinglePermissionBullet(false, permission_label, revoke_button);
+
+    for (const auto& submessage : submessages) {
+      views::Label* sub_permission_label = new views::Label(submessage);
+      sub_permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+      sub_permission_label->SetElideBehavior(elide_behavior_for_submessages);
+      AddSinglePermissionBullet(true, sub_permission_label, NULL);
+    }
+  }
+
+ private:
+  void AddSinglePermissionBullet(bool is_nested,
+                                 views::Label* permission_label,
+                                 RevokeButton* revoke_button) {
+    // Add a padding row before every item except the first.
+    if (has_children())
+      layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+    const base::char16 bullet_point[] = {0x2022, 0};
+    views::Label* bullet_label = new views::Label(base::string16(bullet_point));
+
+    layout_->StartRow(
+        1, is_nested ? kNestedBulletColumnSetId : kBulletColumnSetId);
+    layout_->AddView(bullet_label);
+    layout_->AddView(permission_label);
+
+    if (revoke_button != NULL)
+      layout_->AddView(revoke_button);
+    else
+      layout_->SkipColumns(1);
+  }
+
+  views::GridLayout* layout_;
+
+  DISALLOW_COPY_AND_ASSIGN(BulletedPermissionsList);
+};
+
+}  // namespace
+
 AppInfoPermissionsPanel::AppInfoPermissionsPanel(
     Profile* profile,
     const extensions::Extension* app)
-    : AppInfoPanel(profile, app),
-      active_permissions_heading_(NULL),
-      active_permissions_list_(NULL),
-      retained_files_heading_(NULL),
-      retained_files_list_(NULL),
-      revoke_file_permissions_button_(NULL),
-      retained_devices_heading_(NULL),
-      retained_devices_list_(NULL),
-      revoke_device_permissions_button_(NULL) {
-  // Create UI elements.
-  CreateActivePermissionsControl();
-  CreateRetainedFilesControl();
-  CreateRetainedDevicesControl();
+    : AppInfoPanel(profile, app) {
+  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
+                                        0,
+                                        0,
+                                        views::kRelatedControlVerticalSpacing));
 
-  // Layout elements.
-  SetLayoutManager(
-      new views::BoxLayout(views::BoxLayout::kVertical,
-                           0,
-                           0,
-                           views::kUnrelatedControlVerticalSpacing));
-
-  LayoutActivePermissionsControl();
-  LayoutRetainedFilesControl();
-  LayoutRetainedDevicesControl();
+  CreatePermissionsList();
 }
 
 AppInfoPermissionsPanel::~AppInfoPermissionsPanel() {
-  // Destroy view children before their models.
-  RemoveAllChildViews(true);
 }
 
-// Given a list of strings, returns a view containing a list of these strings
-// as bulleted items.
-views::View* AppInfoPermissionsPanel::CreateBulletedListView(
-    const std::vector<base::string16>& messages,
-    bool allow_multiline,
-    gfx::ElideBehavior elide_behavior) {
-  const int kSpacingBetweenBulletAndStartOfText = 5;
+void AppInfoPermissionsPanel::CreatePermissionsList() {
+  views::View* permissions_heading = CreateHeading(
+      l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_APP_PERMISSIONS_TITLE));
+  AddChildView(permissions_heading);
 
-  views::View* list_view = new views::View();
-  views::GridLayout* layout = new views::GridLayout(list_view);
-  list_view->SetLayoutManager(layout);
-
-  // Create 2 columns: one for the bullet, one for the bullet text.
-  static const int kColumnSetId = 1;
-  views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId);
-  column_set->AddColumn(views::GridLayout::FILL,
-                        views::GridLayout::LEADING,
-                        0,
-                        views::GridLayout::USE_PREF,
-                        0,
-                        0);
-  column_set->AddPaddingColumn(0, kSpacingBetweenBulletAndStartOfText);
-  column_set->AddColumn(views::GridLayout::FILL,
-                        views::GridLayout::LEADING,
-                        1,
-                        views::GridLayout::USE_PREF,
-                        0,
-                        0);
-
-  for (std::vector<base::string16>::const_iterator it = messages.begin();
-       it != messages.end();
-       ++it) {
-    views::Label* permission_label = new views::Label(*it);
-    permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-
-    if (allow_multiline)
-      permission_label->SetMultiLine(true);
-    else
-      permission_label->SetElideBehavior(elide_behavior);
-
-    // Extract only the bullet from the IDS_EXTENSION_PERMISSION_LINE text.
-    views::Label* bullet_label = new views::Label(l10n_util::GetStringFUTF16(
-        IDS_EXTENSION_PERMISSION_LINE, base::string16()));
-
-    // Add a padding row before every item except the first
-    if (it != messages.begin())
-      layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
-
-    layout->StartRow(1, kColumnSetId);
-    layout->AddView(bullet_label);
-    layout->AddView(permission_label);
-  }
-
-  return list_view;
-}
-
-void AppInfoPermissionsPanel::CreateActivePermissionsControl() {
-  std::vector<base::string16> permission_strings =
-      GetActivePermissionMessages();
-  if (permission_strings.empty()) {
+  if (!HasActivePermissionMessages() && GetRetainedDeviceCount() == 0 &&
+      GetRetainedFileCount() == 0) {
     views::Label* no_permissions_text =
         new views::Label(l10n_util::GetStringUTF16(
             app_->is_extension()
                 ? IDS_APPLICATION_INFO_EXTENSION_NO_PERMISSIONS_TEXT
                 : IDS_APPLICATION_INFO_APP_NO_PERMISSIONS_TEXT));
     no_permissions_text->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    active_permissions_list_ = no_permissions_text;
-  } else {
-    active_permissions_heading_ = new views::Label(l10n_util::GetStringUTF16(
-        app_->is_extension() ? IDS_APPLICATION_INFO_EXTENSION_PERMISSIONS_TITLE
-                             : IDS_APPLICATION_INFO_APP_PERMISSIONS_TITLE));
-    active_permissions_heading_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    active_permissions_list_ =
-        CreateBulletedListView(permission_strings, true, gfx::NO_ELIDE);
+    AddChildView(no_permissions_text);
+    return;
   }
+
+  BulletedPermissionsList* permissions_list = new BulletedPermissionsList();
+
+  // Add regular permission messages.
+  for (const auto& message : GetActivePermissionMessages()) {
+    permissions_list->AddPermissionBullets(
+        message, std::vector<base::string16>(), gfx::NO_ELIDE, base::Closure());
+  }
+
+  // TODO(sashab): Add host permission messages, if the app has any.
+
+  // Add USB devices, if the app has any.
+  if (GetRetainedDeviceCount() > 0) {
+    permissions_list->AddPermissionBullets(
+        GetRetainedDeviceHeading(),
+        GetRetainedDevices(),
+        gfx::ELIDE_TAIL,
+        base::Bind(&AppInfoPermissionsPanel::RevokeDevicePermissions,
+                   base::Unretained(this)));
+  }
+
+  // Add retained files, if the app has any.
+  if (GetRetainedFileCount() > 0) {
+    permissions_list->AddPermissionBullets(
+        GetRetainedFileHeading(),
+        GetRetainedFilePaths(),
+        gfx::ELIDE_MIDDLE,
+        base::Bind(&AppInfoPermissionsPanel::RevokeFilePermissions,
+                   base::Unretained(this)));
+  }
+
+  AddChildView(permissions_list);
 }
 
-void AppInfoPermissionsPanel::CreateRetainedFilesControl() {
-  const std::vector<base::string16> retained_file_permission_messages =
-      GetRetainedFilePaths();
-
-  if (!retained_file_permission_messages.empty()) {
-    revoke_file_permissions_button_ = new views::LabelButton(
-        this,
-        l10n_util::GetStringUTF16(
-            IDS_APPLICATION_INFO_REVOKE_RETAINED_FILE_PERMISSIONS_BUTTON_TEXT));
-    revoke_file_permissions_button_->SetStyle(views::Button::STYLE_BUTTON);
-
-    retained_files_heading_ = CreateHeading(l10n_util::GetStringUTF16(
-        IDS_APPLICATION_INFO_RETAINED_FILE_PERMISSIONS_TEXT));
-    retained_files_list_ = CreateBulletedListView(
-        retained_file_permission_messages, false, gfx::ELIDE_MIDDLE);
-  }
-}
-
-void AppInfoPermissionsPanel::CreateRetainedDevicesControl() {
-  const std::vector<base::string16> retained_device_permission_messages =
-      GetRetainedDevices();
-
-  if (!retained_device_permission_messages.empty()) {
-    revoke_device_permissions_button_ = new views::LabelButton(
-        this,
-        l10n_util::GetStringUTF16(
-            IDS_APPLICATION_INFO_REVOKE_DEVICE_PERMISSIONS_BUTTON_TEXT));
-    revoke_device_permissions_button_->SetStyle(views::Button::STYLE_BUTTON);
-
-    retained_devices_heading_ = CreateHeading(l10n_util::GetStringUTF16(
-        IDS_APPLICATION_INFO_RETAINED_DEVICE_PERMISSIONS_TEXT));
-    retained_devices_list_ = CreateBulletedListView(
-        retained_device_permission_messages, false, gfx::ELIDE_TAIL);
-  }
-}
-
-void AppInfoPermissionsPanel::LayoutActivePermissionsControl() {
-  if (active_permissions_list_) {
-    views::View* vertical_stack = CreateVerticalStack();
-    if (active_permissions_heading_)
-      vertical_stack->AddChildView(active_permissions_heading_);
-    vertical_stack->AddChildView(active_permissions_list_);
-
-    AddChildView(vertical_stack);
-  }
-}
-
-void AppInfoPermissionsPanel::LayoutRetainedFilesControl() {
-  if (retained_files_list_) {
-    DCHECK(retained_files_heading_);
-    DCHECK(revoke_file_permissions_button_);
-
-    // Add a sub-view so the revoke button is right-aligned.
-    views::View* right_aligned_button = new views::View();
-    views::BoxLayout* right_aligned_horizontal_layout =
-        new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
-    right_aligned_horizontal_layout->set_main_axis_alignment(
-        views::BoxLayout::MAIN_AXIS_ALIGNMENT_END);
-    right_aligned_button->SetLayoutManager(right_aligned_horizontal_layout);
-    right_aligned_button->AddChildView(revoke_file_permissions_button_);
-
-    views::View* vertical_stack = CreateVerticalStack();
-    vertical_stack->AddChildView(retained_files_heading_);
-    vertical_stack->AddChildView(retained_files_list_);
-    vertical_stack->AddChildView(right_aligned_button);
-
-    AddChildView(vertical_stack);
-  }
-}
-
-void AppInfoPermissionsPanel::LayoutRetainedDevicesControl() {
-  if (retained_devices_list_) {
-    DCHECK(retained_devices_heading_);
-    DCHECK(revoke_device_permissions_button_);
-
-    // Add a sub-view so the revoke button is right-aligned.
-    views::View* right_aligned_button = new views::View();
-    views::BoxLayout* right_aligned_horizontal_layout =
-        new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
-    right_aligned_horizontal_layout->set_main_axis_alignment(
-        views::BoxLayout::MAIN_AXIS_ALIGNMENT_END);
-    right_aligned_button->SetLayoutManager(right_aligned_horizontal_layout);
-    right_aligned_button->AddChildView(revoke_device_permissions_button_);
-
-    views::View* vertical_stack = CreateVerticalStack();
-    vertical_stack->AddChildView(retained_devices_heading_);
-    vertical_stack->AddChildView(retained_devices_list_);
-    vertical_stack->AddChildView(right_aligned_button);
-
-    AddChildView(vertical_stack);
-  }
-}
-
-void AppInfoPermissionsPanel::ButtonPressed(views::Button* sender,
-                                            const ui::Event& event) {
-  if (sender == revoke_file_permissions_button_) {
-    RevokeFilePermissions();
-  } else if (sender == revoke_device_permissions_button_) {
-    RevokeDevicePermissions();
-  } else {
-    NOTREACHED();
-  }
+bool AppInfoPermissionsPanel::HasActivePermissionMessages() const {
+  return !GetActivePermissionMessages().empty();
 }
 
 const std::vector<base::string16>
@@ -244,6 +258,32 @@
   return app_->permissions_data()->GetPermissionMessageStrings();
 }
 
+int AppInfoPermissionsPanel::GetRetainedFileCount() const {
+  if (app_->permissions_data()->HasAPIPermission(
+          extensions::APIPermission::kFileSystem)) {
+    return apps::SavedFilesService::Get(profile_)
+        ->GetAllFileEntries(app_->id())
+        .size();
+  }
+  return 0;
+}
+
+base::string16 AppInfoPermissionsPanel::GetRetainedFileHeading() const {
+  const int kRetainedFilesMessageIDs[6] = {
+      IDS_APPLICATION_INFO_RETAINED_FILES_DEFAULT,
+      IDS_APPLICATION_INFO_RETAINED_FILE_SINGULAR,
+      IDS_APPLICATION_INFO_RETAINED_FILES_ZERO,
+      IDS_APPLICATION_INFO_RETAINED_FILES_TWO,
+      IDS_APPLICATION_INFO_RETAINED_FILES_FEW,
+      IDS_APPLICATION_INFO_RETAINED_FILES_MANY,
+  };
+  std::vector<int> message_ids(
+      kRetainedFilesMessageIDs,
+      kRetainedFilesMessageIDs + arraysize(kRetainedFilesMessageIDs));
+
+  return l10n_util::GetPluralStringFUTF16(message_ids, GetRetainedFileCount());
+}
+
 const std::vector<base::string16>
 AppInfoPermissionsPanel::GetRetainedFilePaths() const {
   std::vector<base::string16> retained_file_paths;
@@ -268,6 +308,29 @@
   Close();
 }
 
+int AppInfoPermissionsPanel::GetRetainedDeviceCount() const {
+  return extensions::DevicePermissionsManager::Get(profile_)
+      ->GetPermissionMessageStrings(app_->id())
+      .size();
+}
+
+base::string16 AppInfoPermissionsPanel::GetRetainedDeviceHeading() const {
+  const int kRetainedDevicesMessageIDs[6] = {
+      IDS_APPLICATION_INFO_RETAINED_DEVICES_DEFAULT,
+      IDS_APPLICATION_INFO_RETAINED_DEVICE_SINGULAR,
+      IDS_APPLICATION_INFO_RETAINED_DEVICES_ZERO,
+      IDS_APPLICATION_INFO_RETAINED_DEVICES_TWO,
+      IDS_APPLICATION_INFO_RETAINED_DEVICES_FEW,
+      IDS_APPLICATION_INFO_RETAINED_DEVICES_MANY,
+  };
+  std::vector<int> message_ids(
+      kRetainedDevicesMessageIDs,
+      kRetainedDevicesMessageIDs + arraysize(kRetainedDevicesMessageIDs));
+
+  return l10n_util::GetPluralStringFUTF16(message_ids,
+                                          GetRetainedDeviceCount());
+}
+
 const std::vector<base::string16> AppInfoPermissionsPanel::GetRetainedDevices()
     const {
   return extensions::DevicePermissionsManager::Get(profile_)
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.h b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.h
index 8d41f902..302904c 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.h
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.h
@@ -9,7 +9,6 @@
 
 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_panel.h"
 #include "ui/gfx/text_constants.h"
-#include "ui/views/controls/button/button.h"
 
 class Profile;
 
@@ -22,15 +21,13 @@
 }
 
 namespace views {
-class Label;
-class LabelButton;
+class GridLayout;
 class View;
 }
 
 // The summary panel of the app info dialog, which provides basic information
 // and controls related to the app.
-class AppInfoPermissionsPanel : public AppInfoPanel,
-                                public views::ButtonListener {
+class AppInfoPermissionsPanel : public AppInfoPanel {
  public:
   AppInfoPermissionsPanel(Profile* profile, const extensions::Extension* app);
 
@@ -46,45 +43,25 @@
   FRIEND_TEST_ALL_PREFIXES(AppInfoPermissionsPanelTest,
                            RetainedFilePermissionsObtainedCorrectly);
 
-  // Given a list of strings, returns a view containing a list of these strings
-  // as bulleted items with the given |elide_behavior|. If |allow_multiline| is
-  // true, allow multi-lined bulleted items and ignore the |elide_behavior|.
-  views::View* CreateBulletedListView(
-      const std::vector<base::string16>& messages,
-      bool allow_multiline,
-      gfx::ElideBehavior elide_behavior);
+  // Called in this order, these methods set-up, add permissions to, and layout
+  // the list of permissions.
+  void CreatePermissionsList();
+  void FillPermissionsList();
+  void LayoutPermissionsList();
 
-  // Internal initialisation methods.
-  void CreateActivePermissionsControl();
-  void CreateRetainedFilesControl();
-  void CreateRetainedDevicesControl();
-
-  void LayoutActivePermissionsControl();
-  void LayoutRetainedFilesControl();
-  void LayoutRetainedDevicesControl();
-
-  // Overridden from views::ButtonListener.
-  virtual void ButtonPressed(views::Button* sender,
-                             const ui::Event& event) override;
-
+  bool HasActivePermissionMessages() const;
   const std::vector<base::string16> GetActivePermissionMessages() const;
+
+  int GetRetainedFileCount() const;
+  base::string16 GetRetainedFileHeading() const;
   const std::vector<base::string16> GetRetainedFilePaths() const;
   void RevokeFilePermissions();
+
+  int GetRetainedDeviceCount() const;
+  base::string16 GetRetainedDeviceHeading() const;
   const std::vector<base::string16> GetRetainedDevices() const;
   void RevokeDevicePermissions();
 
-  // UI elements on the dialog.
-  views::Label* active_permissions_heading_;
-  views::View* active_permissions_list_;
-
-  views::Label* retained_files_heading_;
-  views::View* retained_files_list_;
-  views::LabelButton* revoke_file_permissions_button_;
-
-  views::Label* retained_devices_heading_;
-  views::View* retained_devices_list_;
-  views::LabelButton* revoke_device_permissions_button_;
-
   DISALLOW_COPY_AND_ASSIGN(AppInfoPermissionsPanel);
 };
 
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
index 43c8fca..fae9adc 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
@@ -130,17 +130,12 @@
       size_value_(NULL),
       launch_options_combobox_(NULL),
       weak_ptr_factory_(this) {
-  // Layout elements.
-  SetLayoutManager(
-      new views::BoxLayout(views::BoxLayout::kVertical,
-                           0,
-                           0,
-                           views::kUnrelatedControlVerticalSpacing));
+  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
+                                        0,
+                                        0,
+                                        views::kRelatedControlVerticalSpacing));
 
-  // Create UI elements.
-  CreateDescriptionControl();
-  CreateDetailsControl();
-  CreateLaunchOptionControl();
+  AddSubviews();
 }
 
 AppInfoSummaryPanel::~AppInfoSummaryPanel() {
@@ -148,75 +143,88 @@
   RemoveAllChildViews(true);
 }
 
-void AppInfoSummaryPanel::CreateDescriptionControl() {
-  if (!app_->description().empty()) {
-    const size_t kMaxLength = 400;
+void AppInfoSummaryPanel::AddDescriptionControl(views::View* vertical_stack) {
+  if (app_->description().empty())
+    return;
 
-    base::string16 text = base::UTF8ToUTF16(app_->description());
-    if (text.length() > kMaxLength) {
-      text = text.substr(0, kMaxLength);
-      text += base::ASCIIToUTF16(" ... ");
-    }
-
-    views::Label* description_label = new views::Label(text);
-    description_label->SetMultiLine(true);
-    description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    AddChildView(description_label);
+  // TODO(sashab): Clip the app's description to 4 lines, and use Label's
+  // built-in elide behavior to add ellipses at the end: crbug.com/358053
+  const size_t max_length = 400;
+  base::string16 text = base::UTF8ToUTF16(app_->description());
+  if (text.length() > max_length) {
+    text = text.substr(0, max_length);
+    text += base::ASCIIToUTF16(" ... ");
   }
+
+  views::Label* description_label = new views::Label(text);
+  description_label->SetMultiLine(true);
+  description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+
+  vertical_stack->AddChildView(description_label);
 }
 
-void AppInfoSummaryPanel::CreateDetailsControl() {
-  views::View* details_stack =
+void AppInfoSummaryPanel::AddDetailsControl(views::View* vertical_stack) {
+  // Component apps have no details.
+  if (app_->location() == extensions::Manifest::COMPONENT)
+    return;
+
+  views::View* details_list =
       CreateVerticalStack(views::kRelatedControlSmallVerticalSpacing);
 
-  // The size doesn't make sense for component apps.
-  if (app_->location() != extensions::Manifest::COMPONENT) {
-    views::Label* size_title = new views::Label(
-        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_SIZE_LABEL));
-    size_title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  // Add the size.
+  views::Label* size_title = new views::Label(
+      l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_SIZE_LABEL));
+  size_title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
 
-    size_value_ = new views::Label(
-        l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_SIZE_LOADING_LABEL));
-    size_value_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    StartCalculatingAppSize();
+  size_value_ = new views::Label(
+      l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_SIZE_LOADING_LABEL));
+  size_value_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  StartCalculatingAppSize();
 
-    details_stack->AddChildView(CreateKeyValueField(size_title, size_value_));
-  }
+  details_list->AddChildView(CreateKeyValueField(size_title, size_value_));
 
   // The version doesn't make sense for bookmark apps.
   if (!app_->from_bookmark()) {
-    // Display 'Version: Built-in' for component apps.
-    base::string16 version_str = base::ASCIIToUTF16(app_->VersionString());
-    if (app_->location() == extensions::Manifest::COMPONENT)
-      version_str = l10n_util::GetStringUTF16(
-          IDS_APPLICATION_INFO_VERSION_BUILT_IN_LABEL);
-
     views::Label* version_title = new views::Label(
         l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_VERSION_LABEL));
     version_title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
 
-    views::Label* version_value = new views::Label(version_str);
+    views::Label* version_value =
+        new views::Label(base::UTF8ToUTF16(app_->VersionString()));
     version_value->SetHorizontalAlignment(gfx::ALIGN_LEFT);
 
-    details_stack->AddChildView(
+    details_list->AddChildView(
         CreateKeyValueField(version_title, version_value));
   }
 
-  AddChildView(details_stack);
+  vertical_stack->AddChildView(details_list);
 }
 
-void AppInfoSummaryPanel::CreateLaunchOptionControl() {
-  if (CanSetLaunchType()) {
-    launch_options_combobox_model_.reset(new LaunchOptionsComboboxModel());
-    launch_options_combobox_ =
-        new views::Combobox(launch_options_combobox_model_.get());
+void AppInfoSummaryPanel::AddLaunchOptionControl(views::View* vertical_stack) {
+  if (!CanSetLaunchType())
+    return;
 
-    launch_options_combobox_->set_listener(this);
-    launch_options_combobox_->SetSelectedIndex(
-        launch_options_combobox_model_->GetIndexForLaunchType(GetLaunchType()));
+  launch_options_combobox_model_.reset(new LaunchOptionsComboboxModel());
+  launch_options_combobox_ =
+      new views::Combobox(launch_options_combobox_model_.get());
+  launch_options_combobox_->set_listener(this);
+  launch_options_combobox_->SetSelectedIndex(
+      launch_options_combobox_model_->GetIndexForLaunchType(GetLaunchType()));
 
-    AddChildView(launch_options_combobox_);
-  }
+  vertical_stack->AddChildView(launch_options_combobox_);
+}
+
+void AppInfoSummaryPanel::AddSubviews() {
+  AddChildView(CreateHeading(
+      l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_APP_OVERVIEW_TITLE)));
+
+  views::View* vertical_stack =
+      CreateVerticalStack(views::kUnrelatedControlVerticalSpacing);
+  AddChildView(vertical_stack);
+
+  AddDescriptionControl(vertical_stack);
+  AddDetailsControl(vertical_stack);
+  AddLaunchOptionControl(vertical_stack);
 }
 
 void AppInfoSummaryPanel::OnPerformAction(views::Combobox* combobox) {
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h
index 2b77d9a..95ec9d5 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h
@@ -35,9 +35,10 @@
 
  private:
   // Internal initialisation methods.
-  void CreateDescriptionControl();
-  void CreateDetailsControl();
-  void CreateLaunchOptionControl();
+  void AddDescriptionControl(views::View* vertical_stack);
+  void AddDetailsControl(views::View* vertical_stack);
+  void AddLaunchOptionControl(views::View* vertical_stack);
+  void AddSubviews();
 
   // Overridden from views::ComboboxListener:
   virtual void OnPerformAction(views::Combobox* combobox) override;
diff --git a/chrome/browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc b/chrome/browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc
index 5665d66..01ee9fc 100644
--- a/chrome/browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc
+++ b/chrome/browser/ui/views/apps/app_window_desktop_window_tree_host_win.cc
@@ -75,7 +75,7 @@
     gfx::Insets insets = app_window_->glass_frame_view()->GetGlassInsets();
     // The DWM API's expect values in pixels. We need to convert from DIP to
     // pixels here.
-    insets = insets.Scale(gfx::win::GetDeviceScaleFactor());
+    insets = insets.Scale(gfx::GetDPIScale());
     margins.cxLeftWidth = insets.left();
     margins.cxRightWidth = insets.right();
     margins.cyBottomHeight = insets.bottom();
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
index 3030939..0a794c5 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
@@ -524,18 +524,16 @@
         scoped_ptr<ash::wm::WindowStateDelegate>(
             new NativeAppWindowStateDelegate(app_window(), this)).Pass());
 
+    if (IsFrameless())
+      return CreateNonStandardAppFrame();
+
     if (app_window()->window_type_is_panel()) {
-      ash::PanelFrameView::FrameType frame_type = IsFrameless() ?
-          ash::PanelFrameView::FRAME_NONE : ash::PanelFrameView::FRAME_ASH;
       views::NonClientFrameView* frame_view =
-          new ash::PanelFrameView(widget, frame_type);
+          new ash::PanelFrameView(widget, ash::PanelFrameView::FRAME_ASH);
       frame_view->set_context_menu_controller(this);
       return frame_view;
     }
 
-    if (IsFrameless())
-      return CreateNonStandardAppFrame();
-
     ash::CustomFrameViewAsh* custom_frame_view =
         new ash::CustomFrameViewAsh(widget);
     // Non-frameless app windows can be put into immersive fullscreen.
diff --git a/chrome/browser/ui/views/autofill/password_generation_popup_view_views.cc b/chrome/browser/ui/views/autofill/password_generation_popup_view_views.cc
index 47a4cef3..cf90a93 100644
--- a/chrome/browser/ui/views/autofill/password_generation_popup_view_views.cc
+++ b/chrome/browser/ui/views/autofill/password_generation_popup_view_views.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/ui/autofill/password_generation_popup_controller.h"
 #include "chrome/browser/ui/autofill/popup_constants.h"
 #include "grit/theme_resources.h"
+#include "ui/accessibility/ax_view_state.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
 #include "ui/views/background.h"
@@ -84,7 +85,10 @@
   // the text.
   void Init(const base::string16& password,
             const base::string16& suggestion,
+            const base::string16& accessible_name,
             const gfx::FontList& font_list) {
+    accessible_name_ = accessible_name;
+
     views::BoxLayout* box_layout = new views::BoxLayout(
         views::BoxLayout::kHorizontal,
         PasswordGenerationPopupController::kHorizontalPadding,
@@ -103,6 +107,8 @@
     PasswordTextBox* password_text_box = new PasswordTextBox();
     password_text_box->Init(suggestion, password, font_list);
     AddChildView(password_text_box);
+
+    NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
   }
 
   // views::View:
@@ -111,7 +117,14 @@
     return false;
   }
 
+  virtual void GetAccessibleState(ui::AXViewState* state) override {
+    state->role = ui::AX_ROLE_ALERT;
+    state->name = accessible_name_;
+  }
+
  private:
+  base::string16 accessible_name_;
+
   DISALLOW_COPY_AND_ASSIGN(PasswordBox);
 };
 
@@ -162,6 +175,7 @@
   password_view_ = new PasswordBox();
   password_view_->Init(controller_->password(),
                        controller_->SuggestedText(),
+                       controller_->AccessibleName(),
                        font_list_);
   password_view_->SetPosition(gfx::Point(kPopupBorderThickness,
                                          kPopupBorderThickness));
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index 7f3c05b..772d0a9 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -816,9 +816,6 @@
   if (other_bookmarked_button_->visible())
     max_x -= other_bookmarked_pref.width() + kButtonPadding;
 
-  // Next, layout out the buttons. Any buttons that are placed beyond the
-  // visible region are made invisible.
-
   // Start with the apps page shortcut button.
   if (apps_page_shortcut_->visible()) {
     apps_page_shortcut_->SetBounds(x, y, apps_page_shortcut_pref.width(),
@@ -835,18 +832,18 @@
     x += managed_bookmarks_pref.width() + kButtonPadding;
   }
 
-  // Then go through the bookmark buttons.
-  if (GetBookmarkButtonCount() == 0 && model_ && model_->loaded()) {
+  const bool show_instructions =
+      model_ && model_->loaded() &&
+      model_->bookmark_bar_node()->child_count() == 0;
+  instructions_->SetVisible(show_instructions);
+  if (show_instructions) {
     gfx::Size pref = instructions_->GetPreferredSize();
     instructions_->SetBounds(
         x + kInstructionsPadding, y,
         std::min(static_cast<int>(pref.width()),
                  max_x - x),
         height);
-    instructions_->SetVisible(true);
   } else {
-    instructions_->SetVisible(false);
-
     for (int i = 0; i < GetBookmarkButtonCount(); ++i) {
       views::View* child = child_at(i);
       gfx::Size pref = child->GetPreferredSize();
@@ -1167,12 +1164,10 @@
       client_->managed_node()->GetTitle());
   managed_bookmarks_button_->SetText(client_->managed_node()->GetTitle());
   UpdateColors();
-  UpdateButtonsVisibility();
+  UpdateOtherAndManagedButtonsVisibility();
   other_bookmarked_button_->SetEnabled(true);
   managed_bookmarks_button_->SetEnabled(true);
-
-  Layout();
-  SchedulePaint();
+  LayoutAndPaint();
 }
 
 void BookmarkBarView::BookmarkModelBeingDeleted(BookmarkModel* model) {
@@ -1191,16 +1186,21 @@
       throbbing_view_ == DetermineViewToThrobFromRemove(old_parent, old_index);
   if (was_throbbing)
     throbbing_view_->StopThrobbing();
-  BookmarkNodeRemovedImpl(model, old_parent, old_index);
-  BookmarkNodeAddedImpl(model, new_parent, new_index);
+  bool needs_layout_and_paint =
+      BookmarkNodeRemovedImpl(model, old_parent, old_index);
+  if (BookmarkNodeAddedImpl(model, new_parent, new_index))
+    needs_layout_and_paint = true;
   if (was_throbbing)
     StartThrobbing(new_parent->GetChild(new_index), false);
+  if (needs_layout_and_paint)
+    LayoutAndPaint();
 }
 
 void BookmarkBarView::BookmarkNodeAdded(BookmarkModel* model,
                                         const BookmarkNode* parent,
                                         int index) {
-  BookmarkNodeAddedImpl(model, parent, index);
+  if (BookmarkNodeAddedImpl(model, parent, index))
+    LayoutAndPaint();
 }
 
 void BookmarkBarView::BookmarkNodeRemoved(BookmarkModel* model,
@@ -1211,23 +1211,22 @@
   // Close the menu if the menu is showing for the deleted node.
   if (bookmark_menu_ && bookmark_menu_->node() == node)
     bookmark_menu_->Cancel();
-  BookmarkNodeRemovedImpl(model, parent, old_index);
+  if (BookmarkNodeRemovedImpl(model, parent, old_index))
+    LayoutAndPaint();
 }
 
 void BookmarkBarView::BookmarkAllUserNodesRemoved(
     BookmarkModel* model,
     const std::set<GURL>& removed_urls) {
-  UpdateButtonsVisibility();
+  UpdateOtherAndManagedButtonsVisibility();
 
   StopThrobbing(true);
 
   // Remove the existing buttons.
-  while (GetBookmarkButtonCount()) {
+  while (GetBookmarkButtonCount())
     delete GetBookmarkButton(0);
-  }
 
-  Layout();
-  SchedulePaint();
+  LayoutAndPaint();
 }
 
 void BookmarkBarView::BookmarkNodeChanged(BookmarkModel* model,
@@ -1241,19 +1240,14 @@
     return;  // We only care about reordering of the bookmark bar node.
 
   // Remove the existing buttons.
-  while (GetBookmarkButtonCount()) {
-    views::View* button = child_at(0);
-    RemoveChildView(button);
-    base::MessageLoop::current()->DeleteSoon(FROM_HERE, button);
-  }
+  while (GetBookmarkButtonCount())
+    delete child_at(0);
 
   // Create the new buttons.
   for (int i = 0, child_count = node->child_count(); i < child_count; ++i)
     AddChildViewAt(CreateBookmarkButton(node->GetChild(i)), i);
-  UpdateColors();
 
-  Layout();
-  SchedulePaint();
+  LayoutAndPaint();
 }
 
 void BookmarkBarView::BookmarkNodeFaviconChanged(BookmarkModel* model,
@@ -1477,7 +1471,7 @@
                  base::Unretained(this)));
   profile_pref_registrar_.Add(
       bookmarks::prefs::kShowManagedBookmarksInBookmarkBar,
-      base::Bind(&BookmarkBarView::UpdateButtonsVisibility,
+      base::Bind(&BookmarkBarView::OnShowManagedBookmarksPrefChanged,
                  base::Unretained(this)));
   apps_page_shortcut_->SetVisible(
       chrome::ShouldShowAppsShortcutInBookmarkBar(
@@ -1585,13 +1579,12 @@
         this, node->url(), node->GetTitle(), browser_->profile());
     ConfigureButton(node, button);
     return button;
-  } else {
-    views::MenuButton* button = new BookmarkFolderButton(
-        this, node->GetTitle(), this, false);
-    button->SetImage(views::Button::STATE_NORMAL, GetFolderIcon());
-    ConfigureButton(node, button);
-    return button;
   }
+  views::MenuButton* button =
+      new BookmarkFolderButton(this, node->GetTitle(), this, false);
+  button->SetImage(views::Button::STATE_NORMAL, GetFolderIcon());
+  ConfigureButton(node, button);
+  return button;
 }
 
 views::LabelButton* BookmarkBarView::CreateAppsPageShortcutButton() {
@@ -1633,13 +1626,13 @@
   button->SetMaxSize(gfx::Size(kMaxButtonWidth, 0));
 }
 
-void BookmarkBarView::BookmarkNodeAddedImpl(BookmarkModel* model,
+bool BookmarkBarView::BookmarkNodeAddedImpl(BookmarkModel* model,
                                             const BookmarkNode* parent,
                                             int index) {
-  UpdateButtonsVisibility();
+  const bool needs_layout_and_paint = UpdateOtherAndManagedButtonsVisibility();
   if (parent != model->bookmark_bar_node()) {
-    // We only care about nodes on the bookmark bar.
-    return;
+    // Only children of the bookmark_bar_node get buttons.
+    return needs_layout_and_paint;
   }
   DCHECK(index >= 0 && index <= GetBookmarkButtonCount());
   const BookmarkNode* node = parent->GetChild(index);
@@ -1648,30 +1641,24 @@
   if (!throbbing_view_ && sync_service && sync_service->FirstSetupInProgress())
     StartThrobbing(node, true);
   AddChildViewAt(CreateBookmarkButton(node), index);
-  UpdateColors();
-  Layout();
-  SchedulePaint();
+  return true;
 }
 
-void BookmarkBarView::BookmarkNodeRemovedImpl(BookmarkModel* model,
+bool BookmarkBarView::BookmarkNodeRemovedImpl(BookmarkModel* model,
                                               const BookmarkNode* parent,
                                               int index) {
-  UpdateButtonsVisibility();
+  const bool needs_layout = UpdateOtherAndManagedButtonsVisibility();
 
   StopThrobbing(true);
   // No need to start throbbing again as the bookmark bubble can't be up at
   // the same time as the user reorders.
 
   if (parent != model->bookmark_bar_node()) {
-    // We only care about nodes on the bookmark bar.
-    return;
+    // Only children of the bookmark_bar_node get buttons.
+    return needs_layout;
   }
-  DCHECK(index >= 0 && index < GetBookmarkButtonCount());
-  views::View* button = child_at(index);
-  RemoveChildView(button);
-  base::MessageLoop::current()->DeleteSoon(FROM_HERE, button);
-  Layout();
-  SchedulePaint();
+  delete child_at(index);
+  return true;
 }
 
 void BookmarkBarView::BookmarkNodeChangedImpl(BookmarkModel* model,
@@ -1695,8 +1682,7 @@
   ConfigureButton(node, button);
   gfx::Size new_pref = button->GetPreferredSize();
   if (old_pref.width() != new_pref.width()) {
-    Layout();
-    SchedulePaint();
+    LayoutAndPaint();
   } else if (button->visible()) {
     button->SchedulePaint();
   }
@@ -1934,7 +1920,7 @@
     apps_page_shortcut_->SetTextColor(views::Button::STATE_NORMAL, color);
 }
 
-void BookmarkBarView::UpdateButtonsVisibility() {
+bool BookmarkBarView::UpdateOtherAndManagedButtonsVisibility() {
   bool has_other_children = !model_->other_node()->empty();
   bool update_other = has_other_children != other_bookmarked_button_->visible();
   if (update_other) {
@@ -1949,10 +1935,7 @@
   if (update_managed)
     managed_bookmarks_button_->SetVisible(show_managed);
 
-  if (update_other || update_managed) {
-    Layout();
-    SchedulePaint();
-  }
+  return update_other || update_managed;
 }
 
 void BookmarkBarView::UpdateBookmarksSeparatorVisibility() {
@@ -1972,5 +1955,10 @@
     return;
   apps_page_shortcut_->SetVisible(visible);
   UpdateBookmarksSeparatorVisibility();
-  Layout();
+  LayoutAndPaint();
+}
+
+void BookmarkBarView::OnShowManagedBookmarksPrefChanged() {
+  if (UpdateOtherAndManagedButtonsVisibility())
+    LayoutAndPaint();
 }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
index 6678cc8..1796f13 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -29,6 +29,7 @@
 #include "ui/views/drag_controller.h"
 
 class BookmarkBarViewObserver;
+class BookmarkBarViewTestHelper;
 class BookmarkContextMenu;
 class BookmarkModel;
 class Browser;
@@ -264,12 +265,8 @@
   struct DropInfo;
   struct DropLocation;
 
+  friend class BookmarkBarViewTestHelper;
   friend class BookmarkBarViewEventTestBase;
-  FRIEND_TEST_ALL_PREFIXES(BookmarkBarViewTest, SwitchProfile);
-  FRIEND_TEST_ALL_PREFIXES(BookmarkBarViewTest,
-                           ManagedShowAppsShortcutInBookmarksBar);
-  FRIEND_TEST_ALL_PREFIXES(BookmarkBarViewInstantExtendedTest,
-                           AppsShortcutVisibility);
 
   // Used to identify what the user is dropping onto.
   enum DropButtonType {
@@ -324,13 +321,15 @@
   // and icon.
   void ConfigureButton(const BookmarkNode* node, views::LabelButton* button);
 
-  // Implementation for BookmarkNodeAddedImpl.
-  void BookmarkNodeAddedImpl(BookmarkModel* model,
+  // Implementation for BookmarkNodeAddedImpl. Returns true if LayoutAndPaint()
+  // is required.
+  bool BookmarkNodeAddedImpl(BookmarkModel* model,
                              const BookmarkNode* parent,
                              int index);
 
-  // Implementation for BookmarkNodeRemoved.
-  void BookmarkNodeRemovedImpl(BookmarkModel* model,
+  // Implementation for BookmarkNodeRemoved. Returns true if LayoutAndPaint() is
+  // required.
+  bool BookmarkNodeRemovedImpl(BookmarkModel* model,
                                const BookmarkNode* parent,
                                int index);
 
@@ -374,7 +373,8 @@
 
   // Updates the visibility of |other_bookmarked_button_| and
   // |managed_bookmarks_button_|. Also shows or hides the separator if required.
-  void UpdateButtonsVisibility();
+  // Returns true if something changed and a LayoutAndPaint() is needed.
+  bool UpdateOtherAndManagedButtonsVisibility();
 
   // Updates the visibility of |bookmarks_separator_view_|.
   void UpdateBookmarksSeparatorVisibility();
@@ -382,6 +382,13 @@
   // Updates the visibility of the apps shortcut based on the pref value.
   void OnAppsPageShortcutVisibilityPrefChanged();
 
+  void OnShowManagedBookmarksPrefChanged();
+
+  void LayoutAndPaint() {
+    Layout();
+    SchedulePaint();
+  }
+
   // Needed to react to kShowAppsShortcutInBookmarkBar changes.
   PrefChangeRegistrar profile_pref_registrar_;
 
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
index 197f926d..08f27c9 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -264,7 +264,7 @@
     profile_.reset(new TestingProfile());
     profile_->CreateBookmarkModel(true);
     model_ = BookmarkModelFactory::GetForProfile(profile_.get());
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
     profile_->GetPrefs()->SetBoolean(bookmarks::prefs::kShowBookmarkBar, true);
 
     Browser::CreateParams native_params(profile_.get(),
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h
new file mode 100644
index 0000000..ea24bbb
--- /dev/null
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h
@@ -0,0 +1,26 @@
+// 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_BOOKMARKS_BOOKMARK_BAR_VIEW_TEST_HELPER_H_
+#define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_BAR_VIEW_TEST_HELPER_H_
+
+#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
+
+// Used to access private state of BookmarkBarView for testing.
+class BookmarkBarViewTestHelper {
+ public:
+  explicit BookmarkBarViewTestHelper(BookmarkBarView* bbv) : bbv_(bbv) {}
+  ~BookmarkBarViewTestHelper() {}
+
+  int GetBookmarkButtonCount() { return bbv_->GetBookmarkButtonCount(); }
+
+  views::LabelButton* apps_page_shortcut() { return bbv_->apps_page_shortcut_; }
+
+ private:
+  BookmarkBarView* bbv_;
+
+  DISALLOW_COPY_AND_ASSIGN(BookmarkBarViewTestHelper);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_BAR_VIEW_TEST_HELPER_H_
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
index a711b3c4..14609fb 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
@@ -10,33 +10,67 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/ui/app_list/app_list_util.h"
+#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_pref_service_syncable.h"
+#include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/test/bookmark_test_helpers.h"
 #include "components/search_engines/search_terms_data.h"
 #include "components/search_engines/template_url_service.h"
 #include "components/search_engines/template_url_service_client.h"
 #include "ui/views/controls/button/label_button.h"
 
-class BookmarkBarViewInstantExtendedTest : public BrowserWithTestWindowTest {
+class BookmarkBarViewTest : public BrowserWithTestWindowTest {
  public:
-  BookmarkBarViewInstantExtendedTest() {
+  BookmarkBarViewTest() {}
+
+  void SetUp() override {
+    BrowserWithTestWindowTest::SetUp();
+    local_state_.reset(
+        new ScopedTestingLocalState(TestingBrowserProcess::GetGlobal()));
+  }
+
+  void TearDown() override {
+    test_helper_.reset();
+    bookmark_bar_view_.reset();
+    local_state_.reset();
+    BrowserWithTestWindowTest::TearDown();
   }
 
  protected:
-  virtual TestingProfile* CreateProfile() override {
+  TestingProfile* CreateProfile() override {
     TestingProfile* profile = BrowserWithTestWindowTest::CreateProfile();
     // TemplateURLService is normally NULL during testing. Instant extended
     // needs this service so set a custom factory function.
     TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
-        profile, &BookmarkBarViewInstantExtendedTest::CreateTemplateURLService);
+        profile, &BookmarkBarViewTest::CreateTemplateURLService);
     return profile;
   }
 
+  // Creates the BookmarkBarView and BookmarkBarViewTestHelper. Generally you'll
+  // want to use CreateBookmarkModelAndBookmarkBarView(), but use this if
+  // need to create the BookmarkBarView after the model has populated.
+  void CreateBookmarkBarView() {
+    bookmark_bar_view_.reset(new BookmarkBarView(browser(), nullptr));
+    test_helper_.reset(new BookmarkBarViewTestHelper(bookmark_bar_view_.get()));
+  }
+
+  // Creates the model, blocking until it loads, then creates the
+  // BookmarkBarView.
+  void CreateBookmarkModelAndBookmarkBarView() {
+    profile()->CreateBookmarkModel(true);
+    bookmarks::test::WaitForBookmarkModelToLoad(
+        BookmarkModelFactory::GetForProfile(profile()));
+    CreateBookmarkBarView();
+  }
+
+  scoped_ptr<BookmarkBarViewTestHelper> test_helper_;
+  scoped_ptr<BookmarkBarView> bookmark_bar_view_;
+
  private:
   static KeyedService* CreateTemplateURLService(
       content::BrowserContext* profile) {
@@ -46,65 +80,54 @@
         scoped_ptr<TemplateURLServiceClient>(), NULL, NULL, base::Closure());
   }
 
-  DISALLOW_COPY_AND_ASSIGN(BookmarkBarViewInstantExtendedTest);
+  scoped_ptr<ScopedTestingLocalState> local_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(BookmarkBarViewTest);
 };
 
 // Verify that in instant extended mode the visibility of the apps shortcut
 // button properly follows the pref value.
-TEST_F(BookmarkBarViewInstantExtendedTest, AppsShortcutVisibility) {
-  ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal());
-  profile()->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(
-      BookmarkModelFactory::GetForProfile(profile()));
-  BookmarkBarView bookmark_bar_view(browser(), NULL);
-  bookmark_bar_view.set_owned_by_client();
+TEST_F(BookmarkBarViewTest, AppsShortcutVisibility) {
+  CreateBookmarkModelAndBookmarkBarView();
   browser()->profile()->GetPrefs()->SetBoolean(
       bookmarks::prefs::kShowAppsShortcutInBookmarkBar, false);
-  EXPECT_FALSE(bookmark_bar_view.apps_page_shortcut_->visible());
+  EXPECT_FALSE(test_helper_->apps_page_shortcut()->visible());
 
   // Try to make the Apps shortcut visible. Its visibility depends on whether
   // the app launcher is enabled.
   browser()->profile()->GetPrefs()->SetBoolean(
       bookmarks::prefs::kShowAppsShortcutInBookmarkBar, true);
   if (IsAppLauncherEnabled()) {
-    EXPECT_FALSE(bookmark_bar_view.apps_page_shortcut_->visible());
+    EXPECT_FALSE(test_helper_->apps_page_shortcut()->visible());
   } else {
-    EXPECT_TRUE(bookmark_bar_view.apps_page_shortcut_->visible());
+    EXPECT_TRUE(test_helper_->apps_page_shortcut()->visible());
   }
 
   // Make sure we can also properly transition from true to false.
   browser()->profile()->GetPrefs()->SetBoolean(
       bookmarks::prefs::kShowAppsShortcutInBookmarkBar, false);
-  EXPECT_FALSE(bookmark_bar_view.apps_page_shortcut_->visible());
+  EXPECT_FALSE(test_helper_->apps_page_shortcut()->visible());
 }
 
 #if !defined(OS_CHROMEOS)
-typedef BrowserWithTestWindowTest BookmarkBarViewTest;
-
 // Verifies that the apps shortcut is shown or hidden following the policy
 // value. This policy (and the apps shortcut) isn't present on ChromeOS.
 TEST_F(BookmarkBarViewTest, ManagedShowAppsShortcutInBookmarksBar) {
-  ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal());
-  profile()->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(
-      BookmarkModelFactory::GetForProfile(profile()));
-  BookmarkBarView bookmark_bar_view(browser(), NULL);
-  bookmark_bar_view.set_owned_by_client();
-
+  CreateBookmarkModelAndBookmarkBarView();
   // By default, the pref is not managed and the apps shortcut is shown.
   TestingPrefServiceSyncable* prefs = profile()->GetTestingPrefService();
   EXPECT_FALSE(prefs->IsManagedPreference(
       bookmarks::prefs::kShowAppsShortcutInBookmarkBar));
-  EXPECT_TRUE(bookmark_bar_view.apps_page_shortcut_->visible());
+  EXPECT_TRUE(test_helper_->apps_page_shortcut()->visible());
 
   // Hide the apps shortcut by policy, via the managed pref.
   prefs->SetManagedPref(bookmarks::prefs::kShowAppsShortcutInBookmarkBar,
                         new base::FundamentalValue(false));
-  EXPECT_FALSE(bookmark_bar_view.apps_page_shortcut_->visible());
+  EXPECT_FALSE(test_helper_->apps_page_shortcut()->visible());
 
   // And try showing it via policy too.
   prefs->SetManagedPref(bookmarks::prefs::kShowAppsShortcutInBookmarkBar,
                         new base::FundamentalValue(true));
-  EXPECT_TRUE(bookmark_bar_view.apps_page_shortcut_->visible());
+  EXPECT_TRUE(test_helper_->apps_page_shortcut()->visible());
 }
 #endif
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
index 9ac3e9f..e4d4c0d 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
@@ -31,7 +31,7 @@
     profile()->CreateBookmarkModel(true);
     BookmarkModel* bookmark_model =
         BookmarkModelFactory::GetForProfile(profile());
-    test::WaitForBookmarkModelToLoad(bookmark_model);
+    bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
 
     bookmarks::AddIfNotBookmarked(
         bookmark_model, GURL(kTestBookmarkURL), base::string16());
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc
index 4d8a3826..06f2794 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_context_menu_unittest.cc
@@ -69,7 +69,7 @@
     profile_->CreateBookmarkModel(true);
 
     model_ = BookmarkModelFactory::GetForProfile(profile_.get());
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
 
     AddTestData();
   }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
index 9ab145e..6f74b09c 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view_unittest.cc
@@ -40,7 +40,7 @@
     profile_->CreateBookmarkModel(true);
 
     model_ = BookmarkModelFactory::GetForProfile(profile_.get());
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
 
     AddTestData();
   }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
index d1329c1b2..aa9a559 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
@@ -28,7 +28,7 @@
     profile()->CreateBookmarkModel(true);
 
     model_ = BookmarkModelFactory::GetForProfile(profile());
-    test::WaitForBookmarkModelToLoad(model_);
+    bookmarks::test::WaitForBookmarkModelToLoad(model_);
 
     AddTestData();
   }
diff --git a/chrome/browser/ui/views/extensions/extension_action_view_controller.cc b/chrome/browser/ui/views/extensions/extension_action_view_controller.cc
index e17e5ce7..cd0410e9 100644
--- a/chrome/browser/ui/views/extensions/extension_action_view_controller.cc
+++ b/chrome/browser/ui/views/extensions/extension_action_view_controller.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/views/extensions/extension_action_view_controller.h"
 
 #include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/api/commands/command_service.h"
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 #include "chrome/browser/extensions/extension_action.h"
@@ -12,9 +13,16 @@
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/extensions/accelerator_priority.h"
-#include "chrome/browser/ui/views/extensions/extension_action_view_delegate.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_action_view_delegate.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/common/extensions/api/extension_action/action_info.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
+#include "extensions/browser/notification_types.h"
 #include "extensions/common/extension.h"
+#include "extensions/common/manifest_constants.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/image/image_skia_operations.h"
 #include "ui/views/controls/menu/menu_controller.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/view.h"
@@ -36,19 +44,28 @@
 ExtensionActionViewController::ExtensionActionViewController(
     const extensions::Extension* extension,
     Browser* browser,
-    ExtensionAction* extension_action,
-    ExtensionActionViewDelegate* delegate)
+    ExtensionAction* extension_action)
     : extension_(extension),
       browser_(browser),
       extension_action_(extension_action),
-      delegate_(delegate),
+      delegate_(nullptr),
       icon_factory_(browser->profile(), extension, extension_action, this),
-      popup_(NULL),
+      icon_observer_(nullptr),
+      popup_(nullptr),
       weak_factory_(this) {
   DCHECK(extension_action);
   DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
          extension_action->action_type() == ActionInfo::TYPE_BROWSER);
   DCHECK(extension);
+
+  content::NotificationSource notification_source =
+      content::Source<Profile>(browser->profile()->GetOriginalProfile());
+  registrar_.Add(this,
+                 extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED,
+                 notification_source);
+  registrar_.Add(this,
+                 extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED,
+                 notification_source);
 }
 
 ExtensionActionViewController::~ExtensionActionViewController() {
@@ -58,24 +75,53 @@
   UnregisterCommand(false);
 }
 
-void ExtensionActionViewController::InspectPopup() {
-  ExecuteAction(ExtensionPopup::SHOW_AND_INSPECT, true);
+const std::string& ExtensionActionViewController::GetId() const {
+  return extension_->id();
 }
 
-void ExtensionActionViewController::ExecuteActionByUser() {
-  ExecuteAction(ExtensionPopup::SHOW, true);
+void ExtensionActionViewController::SetDelegate(
+    ToolbarActionViewDelegate* delegate) {
+  delegate_ = delegate;
+  delegate_->GetAsView()->set_context_menu_controller(this);
 }
 
-bool ExtensionActionViewController::ExecuteAction(
-    ExtensionPopup::ShowAction show_action, bool grant_tab_permissions) {
-  if (extensions::ExtensionActionAPI::Get(browser_->profile())->
-          ExecuteExtensionAction(extension_, browser_, grant_tab_permissions) ==
-      ExtensionAction::ACTION_SHOW_POPUP) {
-    GURL popup_url = extension_action_->GetPopupUrl(GetCurrentTabId());
-    return delegate_->GetPreferredPopupViewController()->ShowPopupWithUrl(
-        show_action, popup_url, grant_tab_permissions);
-  }
-  return false;
+gfx::Image ExtensionActionViewController::GetIcon(
+    content::WebContents* web_contents) {
+  return icon_factory_.GetIcon(SessionTabHelper::IdForTab(web_contents));
+}
+
+gfx::ImageSkia ExtensionActionViewController::GetIconWithBadge() {
+  content::WebContents* web_contents = delegate_->GetCurrentWebContents();
+  gfx::Size spacing(0, ToolbarView::kVertSpacing);
+  gfx::ImageSkia icon = *GetIcon(web_contents).ToImageSkia();
+  if (!IsEnabled(web_contents))
+    icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
+  return extension_action_->GetIconWithBadge(
+      icon, SessionTabHelper::IdForTab(web_contents), spacing);
+}
+
+base::string16 ExtensionActionViewController::GetAccessibleName(
+    content::WebContents* web_contents) const {
+  std::string title =
+      extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents));
+  return base::UTF8ToUTF16(title.empty() ? extension()->name() : title);
+}
+
+base::string16 ExtensionActionViewController::GetTooltip(
+    content::WebContents* web_contents) const {
+  return GetAccessibleName(web_contents);
+}
+
+bool ExtensionActionViewController::IsEnabled(
+    content::WebContents* web_contents) const {
+  return extension_action_->GetIsVisible(
+      SessionTabHelper::IdForTab(web_contents));
+}
+
+bool ExtensionActionViewController::HasPopup(
+    content::WebContents* web_contents) const {
+  int tab_id = SessionTabHelper::IdForTab(web_contents);
+  return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id);
 }
 
 void ExtensionActionViewController::HidePopup() {
@@ -83,13 +129,29 @@
     CleanupPopup(true);
 }
 
-gfx::Image ExtensionActionViewController::GetIcon(int tab_id) {
-  return icon_factory_.GetIcon(tab_id);
+gfx::NativeView ExtensionActionViewController::GetPopupNativeView() {
+  return popup_ ? popup_->GetWidget()->GetNativeView() : nullptr;
 }
 
-int ExtensionActionViewController::GetCurrentTabId() const {
-  content::WebContents* web_contents = delegate_->GetCurrentWebContents();
-  return web_contents ? SessionTabHelper::IdForTab(web_contents) : -1;
+bool ExtensionActionViewController::IsMenuRunning() const {
+  return menu_runner_.get() != NULL;
+}
+
+bool ExtensionActionViewController::CanDrag() const {
+  return true;
+}
+
+bool ExtensionActionViewController::ExecuteAction(bool by_user) {
+  return ExecuteAction(ExtensionPopup::SHOW, by_user);
+}
+
+void ExtensionActionViewController::PaintExtra(
+    gfx::Canvas* canvas,
+    const gfx::Rect& bounds,
+    content::WebContents* web_contents) const {
+  int tab_id = SessionTabHelper::IdForTab(web_contents);
+  if (tab_id >= 0)
+    extension_action_->PaintBadge(canvas, bounds, tab_id);
 }
 
 void ExtensionActionViewController::RegisterCommand() {
@@ -110,25 +172,28 @@
   }
 }
 
-void ExtensionActionViewController::UnregisterCommand(bool only_if_removed) {
-  views::FocusManager* focus_manager =
-      delegate_->GetFocusManagerForAccelerator();
-  if (!focus_manager || !action_keybinding_.get())
-    return;
+void ExtensionActionViewController::InspectPopup() {
+  ExecuteAction(ExtensionPopup::SHOW_AND_INSPECT, true);
+}
 
-  // If |only_if_removed| is true, it means that we only need to unregister
-  // ourselves as an accelerator if the command was removed. Otherwise, we need
-  // to unregister ourselves no matter what (likely because we are shutting
-  // down).
-  extensions::Command extension_command;
-  if (!only_if_removed || !GetExtensionCommand(&extension_command)) {
-    focus_manager->UnregisterAccelerator(*action_keybinding_, this);
-    action_keybinding_.reset();
+bool ExtensionActionViewController::ExecuteAction(
+    ExtensionPopup::ShowAction show_action, bool grant_tab_permissions) {
+  if (extensions::ExtensionActionAPI::Get(browser_->profile())->
+          ExecuteExtensionAction(extension_, browser_, grant_tab_permissions) ==
+      ExtensionAction::ACTION_SHOW_POPUP) {
+    GURL popup_url = extension_action_->GetPopupUrl(
+        SessionTabHelper::IdForTab(delegate_->GetCurrentWebContents()));
+    return static_cast<ExtensionActionViewController*>(
+        delegate_->GetPreferredPopupViewController())->ShowPopupWithUrl(
+            show_action, popup_url, grant_tab_permissions);
   }
+  return false;
 }
 
 void ExtensionActionViewController::OnIconUpdated() {
   delegate_->OnIconUpdated();
+  if (icon_observer_)
+    icon_observer_->OnIconUpdated();
 }
 
 bool ExtensionActionViewController::AcceleratorPressed(
@@ -144,7 +209,7 @@
       ui::AcceleratorManager::kNormalPriority)
     return false;
 
-  ExecuteActionByUser();
+  ExecuteAction(true);
   return true;
 }
 
@@ -166,7 +231,6 @@
     views::View* source,
     const gfx::Point& point,
     ui::MenuSourceType source_type) {
-
   // If there's another active menu that won't be dismissed by opening this one,
   // then we can't show this one right away, since we can only show one nested
   // menu at a time.
@@ -189,6 +253,25 @@
   DoShowContextMenu(source_type);
 }
 
+void ExtensionActionViewController::Observe(
+    int type,
+    const content::NotificationSource& source,
+    const content::NotificationDetails& details) {
+  DCHECK(type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED ||
+         type == extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED);
+  std::pair<const std::string, const std::string>* payload =
+      content::Details<std::pair<const std::string, const std::string> >(
+          details).ptr();
+  if (extension_->id() == payload->first &&
+      payload->second ==
+          extensions::manifest_values::kBrowserActionCommandEvent) {
+    if (type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED)
+      RegisterCommand();
+    else
+      UnregisterCommand(true);
+  }
+}
+
 void ExtensionActionViewController::DoShowContextMenu(
     ui::MenuSourceType source_type) {
   if (!extension_->ShowConfigureContextMenus())
@@ -282,6 +365,23 @@
       extension_->id(), CommandService::ACTIVE_ONLY, command, NULL);
 }
 
+void ExtensionActionViewController::UnregisterCommand(bool only_if_removed) {
+  views::FocusManager* focus_manager =
+      delegate_->GetFocusManagerForAccelerator();
+  if (!focus_manager || !action_keybinding_.get())
+    return;
+
+  // If |only_if_removed| is true, it means that we only need to unregister
+  // ourselves as an accelerator if the command was removed. Otherwise, we need
+  // to unregister ourselves no matter what (likely because we are shutting
+  // down).
+  extensions::Command extension_command;
+  if (!only_if_removed || !GetExtensionCommand(&extension_command)) {
+    focus_manager->UnregisterAccelerator(*action_keybinding_, this);
+    action_keybinding_.reset();
+  }
+}
+
 bool ExtensionActionViewController::CloseActiveMenuIfNeeded() {
   // If this view is shown inside another menu, there's a possibility that there
   // is another context menu showing that we have to close before we can
diff --git a/chrome/browser/ui/views/extensions/extension_action_view_controller.h b/chrome/browser/ui/views/extensions/extension_action_view_controller.h
index 9efc499..dd8ab81 100644
--- a/chrome/browser/ui/views/extensions/extension_action_view_controller.h
+++ b/chrome/browser/ui/views/extensions/extension_action_view_controller.h
@@ -7,7 +7,10 @@
 
 #include "chrome/browser/extensions/extension_action_icon_factory.h"
 #include "chrome/browser/extensions/extension_context_menu_model.h"
+#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
 #include "chrome/browser/ui/views/extensions/extension_popup.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/gfx/image/image.h"
 #include "ui/views/context_menu_controller.h"
@@ -15,7 +18,7 @@
 
 class Browser;
 class ExtensionAction;
-class ExtensionActionViewDelegate;
+class ToolbarActionViewDelegate;
 
 namespace content {
 class WebContents;
@@ -42,10 +45,12 @@
 // implementations for page actions/browser actions are different types of
 // views.
 // All common logic for executing extension actions should go in this class;
-// ExtensionActionViewDelegate classes should only have knowledge relating to
+// ToolbarActionViewDelegate classes should only have knowledge relating to
 // the views::View wrapper.
 class ExtensionActionViewController
-    : public ExtensionActionIconFactory::Observer,
+    : public ToolbarActionViewController,
+      public content::NotificationObserver,
+      public ExtensionActionIconFactory::Observer,
       public ExtensionContextMenuModel::PopupDelegate,
       public ui::AcceleratorTarget,
       public views::ContextMenuController,
@@ -53,18 +58,33 @@
  public:
   ExtensionActionViewController(const extensions::Extension* extension,
                                 Browser* browser,
-                                ExtensionAction* extension_action,
-                                ExtensionActionViewDelegate* delegate);
+                                ExtensionAction* extension_action);
   virtual ~ExtensionActionViewController();
 
+  // ToolbarActionViewController:
+  virtual const std::string& GetId() const override;
+  virtual void SetDelegate(ToolbarActionViewDelegate* delegate) override;
+  virtual gfx::Image GetIcon(content::WebContents* web_contents) override;
+  virtual gfx::ImageSkia GetIconWithBadge() override;
+  virtual base::string16 GetAccessibleName(content::WebContents* web_contents)
+      const override;
+  virtual base::string16 GetTooltip(content::WebContents* web_contents)
+      const override;
+  virtual bool IsEnabled(content::WebContents* web_contents) const override;
+  virtual bool HasPopup(content::WebContents* web_contents) const override;
+  virtual void HidePopup() override;
+  virtual gfx::NativeView GetPopupNativeView() override;
+  virtual bool IsMenuRunning() const override;
+  virtual bool CanDrag() const override;
+  virtual bool ExecuteAction(bool by_user) override;
+  virtual void PaintExtra(gfx::Canvas* canvas,
+                          const gfx::Rect& bounds,
+                          content::WebContents* web_contents) const override;
+  virtual void RegisterCommand() override;
+
   // ExtensionContextMenuModel::PopupDelegate:
   virtual void InspectPopup() override;
 
-  // Executes the default extension action (typically showing the popup), and
-  // attributes the action to a user (thus, only use this for actions that
-  // *were* done by the user).
-  void ExecuteActionByUser();
-
   // Executes the extension action with |show_action|. If
   // |grant_tab_permissions| is true, this will grant the extension active tab
   // permissions. Only do this if this was done through a user action (and not
@@ -72,30 +92,15 @@
   bool ExecuteAction(ExtensionPopup::ShowAction show_action,
                      bool grant_tab_permissions);
 
-  // Hides the popup, if one is open.
-  void HidePopup();
-
-  // Returns the icon from the |icon_factory_|.
-  gfx::Image GetIcon(int tab_id);
-
-  // Returns the current tab id.
-  int GetCurrentTabId() const;
-
-  // Registers an accelerator for the extension action's command, if one
-  // exists.
-  void RegisterCommand();
-
-  // Unregisters the accelerator for the extension action's command, if one
-  // exists. If |only_if_removed| is true, then this will only unregister if the
-  // command has been removed.
-  void UnregisterCommand(bool only_if_removed);
+  void set_icon_observer(ExtensionActionIconFactory::Observer* icon_observer) {
+    icon_observer_ = icon_observer;
+  }
 
   const extensions::Extension* extension() const { return extension_; }
   Browser* browser() { return browser_; }
   ExtensionAction* extension_action() { return extension_action_; }
   const ExtensionAction* extension_action() const { return extension_action_; }
   ExtensionPopup* popup() { return popup_; }
-  bool is_menu_running() const { return menu_runner_.get() != NULL; }
 
  private:
   // ExtensionActionIconFactory::Observer:
@@ -113,6 +118,11 @@
                                       const gfx::Point& point,
                                       ui::MenuSourceType source_type) override;
 
+  // content::NotificationObserver:
+  virtual void Observe(int type,
+                       const content::NotificationSource& source,
+                       const content::NotificationDetails& details) override;
+
   // Shows the context menu for extension action.
   void DoShowContextMenu(ui::MenuSourceType source_type);
 
@@ -129,6 +139,11 @@
   // exists. Returns true if |command| was populated.
   bool GetExtensionCommand(extensions::Command* command);
 
+  // Unregisters the accelerator for the extension action's command, if one
+  // exists. If |only_if_removed| is true, then this will only unregister if the
+  // command has been removed.
+  void UnregisterCommand(bool only_if_removed);
+
   // Closes the currently-active menu, if needed. This is the case when there
   // is an active menu that wouldn't close automatically when a new one is
   // opened.
@@ -151,7 +166,7 @@
   ExtensionAction* extension_action_;
 
   // Our delegate.
-  ExtensionActionViewDelegate* delegate_;
+  ToolbarActionViewDelegate* delegate_;
 
   // The object that will be used to get the browser action icon for us.
   // It may load the icon asynchronously (in which case the initial icon
@@ -159,6 +174,10 @@
   // updates to the icon.
   ExtensionActionIconFactory icon_factory_;
 
+  // The observer that we need to notify when the icon of the button has been
+  // updated.
+  ExtensionActionIconFactory::Observer* icon_observer_;
+
   // Responsible for running the menu.
   scoped_ptr<views::MenuRunner> menu_runner_;
 
@@ -169,6 +188,8 @@
   // for (to show the popup).
   scoped_ptr<ui::Accelerator> action_keybinding_;
 
+  content::NotificationRegistrar registrar_;
+
   // If non-NULL, this is the next ExtensionActionViewController context menu
   // which wants to run once the current owner (this one) is done.
   base::Closure followup_context_menu_task_;
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
index 5eefc580..53582e6e 100644
--- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -19,6 +19,8 @@
 #include "chrome/browser/extensions/extension_install_prompt_experiment.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "chrome/browser/ui/views/constrained_window_views.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/grit/generated_resources.h"
@@ -170,9 +172,12 @@
     ExtensionInstallPrompt::Delegate* delegate,
     scoped_refptr<ExtensionInstallPrompt::Prompt> prompt) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  CreateBrowserModalDialogViews(
-      new ExtensionInstallDialogView(show_params.navigator, delegate, prompt),
-      show_params.parent_window)->Show();
+  ExtensionInstallDialogView* dialog =
+      new ExtensionInstallDialogView(show_params.profile,
+                                     show_params.parent_web_contents,
+                                     delegate,
+                                     prompt);
+  CreateBrowserModalDialogViews(dialog, show_params.parent_window)->Show();
 }
 
 CustomScrollableView::CustomScrollableView() {}
@@ -184,10 +189,12 @@
 }
 
 ExtensionInstallDialogView::ExtensionInstallDialogView(
+    Profile* profile,
     content::PageNavigator* navigator,
     ExtensionInstallPrompt::Delegate* delegate,
     scoped_refptr<ExtensionInstallPrompt::Prompt> prompt)
-    : navigator_(navigator),
+    : profile_(profile),
+      navigator_(navigator),
       delegate_(delegate),
       prompt_(prompt),
       scroll_view_(NULL),
@@ -851,7 +858,14 @@
         store_url, Referrer(), NEW_FOREGROUND_TAB,
         ui::PAGE_TRANSITION_LINK,
         false);
-    navigator_->OpenURL(params);
+
+    if (navigator_) {
+      navigator_->OpenURL(params);
+    } else {
+      chrome::ScopedTabbedBrowserDisplayer displayer(
+          profile_, chrome::GetActiveDesktop());
+      displayer.browser()->OpenURL(params);
+    }
     GetWidget()->Close();
   }
 }
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.h b/chrome/browser/ui/views/extensions/extension_install_dialog_view.h
index 38263482..ee88a13 100644
--- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.h
+++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.h
@@ -15,6 +15,7 @@
 
 typedef std::vector<base::string16> PermissionDetails;
 class ExpandableContainerView;
+class Profile;
 
 namespace content {
 class PageNavigator;
@@ -53,6 +54,7 @@
                                    public views::ButtonListener {
  public:
   ExtensionInstallDialogView(
+      Profile* profile,
       content::PageNavigator* navigator,
       ExtensionInstallPrompt::Delegate* delegate,
       scoped_refptr<ExtensionInstallPrompt::Prompt> prompt);
@@ -126,6 +128,7 @@
   // "Show permissions" links were shown and/or clicked.
   void UpdateLinkActionHistogram(int action_type) const;
 
+  Profile* profile_;
   content::PageNavigator* navigator_;
   ExtensionInstallPrompt::Delegate* delegate_;
   scoped_refptr<ExtensionInstallPrompt::Prompt> prompt_;
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc
index c75101c..cecada13 100644
--- a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc
@@ -163,7 +163,10 @@
 bool ScrollbarTest::IsScrollbarVisible() {
   ExtensionInstallPrompt::ShowParams show_params(web_contents());
   ExtensionInstallDialogView* dialog = new ExtensionInstallDialogView(
-      show_params.navigator, delegate(), prompt());
+      show_params.profile,
+      show_params.parent_web_contents,
+      delegate(),
+      prompt());
 
   // Create the modal view around the install dialog view.
   views::Widget* modal =
@@ -223,7 +226,8 @@
     // The user confirms the install.
     MockExtensionInstallPromptDelegate delegate;
     scoped_ptr<ExtensionInstallDialogView> dialog(
-        new ExtensionInstallDialogView(web_contents(), &delegate, prompt()));
+        new ExtensionInstallDialogView(
+            profile(), web_contents(), &delegate, prompt()));
     views::DialogDelegateView* delegate_view = dialog.get();
 
     delegate_view->Accept();
@@ -238,7 +242,8 @@
     // The user cancels the install.
     MockExtensionInstallPromptDelegate delegate;
     scoped_ptr<ExtensionInstallDialogView> dialog(
-        new ExtensionInstallDialogView(web_contents(), &delegate, prompt()));
+        new ExtensionInstallDialogView(
+            profile(), web_contents(), &delegate, prompt()));
     views::DialogDelegateView* delegate_view = dialog.get();
 
     delegate_view->Cancel();
@@ -254,7 +259,8 @@
     // proceed or cancel.
     MockExtensionInstallPromptDelegate delegate;
     scoped_ptr<ExtensionInstallDialogView> dialog(
-        new ExtensionInstallDialogView(web_contents(), &delegate, prompt()));
+        new ExtensionInstallDialogView(
+            profile(), web_contents(), &delegate, prompt()));
     dialog.reset();
 
     EXPECT_EQ(1, delegate.abort_count());
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc
index cdec6d8..3660422 100644
--- a/chrome/browser/ui/views/find_bar_host.cc
+++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -46,11 +46,6 @@
 
 bool FindBarHost::MaybeForwardKeyEventToWebpage(
     const ui::KeyEvent& key_event) {
-  if (!ShouldForwardKeyEventToWebpageNative(key_event)) {
-    // Native implementation says not to forward these events.
-    return false;
-  }
-
   switch (key_event.key_code()) {
     case ui::VKEY_DOWN:
     case ui::VKEY_UP:
@@ -161,6 +156,12 @@
     ResetFocusTracker();
 }
 
+void FindBarHost::AudibleAlert() {
+#if defined(OS_WIN)
+  MessageBeep(MB_OK);
+#endif
+}
+
 bool FindBarHost::IsFindBarVisible() {
   return DropdownBarHost::IsVisible();
 }
diff --git a/chrome/browser/ui/views/find_bar_host.h b/chrome/browser/ui/views/find_bar_host.h
index c48215f..2f1d6d2 100644
--- a/chrome/browser/ui/views/find_bar_host.h
+++ b/chrome/browser/ui/views/find_bar_host.h
@@ -127,9 +127,6 @@
   // Allows implementation to tweak widget position.
   void GetWidgetPositionNative(gfx::Rect* avoid_overlapping_rect);
 
-  // Allows native implementation to prevent key events from being forwarded.
-  bool ShouldForwardKeyEventToWebpageNative(const ui::KeyEvent& key_event);
-
   // Returns the FindBarView.
   FindBarView* find_bar_view() { return static_cast<FindBarView*>(view()); }
 
diff --git a/chrome/browser/ui/views/find_bar_host_aura.cc b/chrome/browser/ui/views/find_bar_host_aura.cc
deleted file mode 100644
index 9b92984b..0000000
--- a/chrome/browser/ui/views/find_bar_host_aura.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2012 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/find_bar_host.h"
-
-#include "base/logging.h"
-#include "ui/events/event.h"
-
-void FindBarHost::AudibleAlert() {
-#if defined(OS_WIN)
-  MessageBeep(MB_OK);
-#endif
-}
-
-bool FindBarHost::ShouldForwardKeyEventToWebpageNative(
-    const ui::KeyEvent& key_event) {
-  return true;
-}
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
index b3b53972..c81f1f8 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -24,6 +24,7 @@
 #include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
 #include "chrome/browser/ui/views/tab_icon_view.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
+#include "components/signin/core/common/profile_management_switches.h"
 #include "content/public/browser/web_contents.h"
 #include "grit/ash_resources.h"
 #include "grit/theme_resources.h"
@@ -56,6 +57,8 @@
 // There are 2 px on each side of the avatar (between the frame border and
 // it on the left, and between it and the tabstrip on the right).
 const int kAvatarSideSpacing = 2;
+// Space between the new avatar button and the minimize button.
+const int kNewAvatarButtonOffset = 5;
 // Space between left edge of window and tabstrip.
 const int kTabstripLeftSpacing = 0;
 // Space between right edge of tabstrip and maximize button.
@@ -126,8 +129,12 @@
     window_icon_->Update();
   }
 
-  // Create incognito icon if necessary.
-  UpdateAvatarInfo();
+  if (browser_view()->IsRegularOrGuestSession() &&
+      switches::IsNewAvatarMenu()) {
+    UpdateNewStyleAvatarInfo(this, NewAvatarButton::NATIVE_BUTTON);
+  } else {
+    UpdateAvatarInfo();
+  }
 
   // HeaderPainter handles layout.
   if (UsePackagedAppHeaderStyle()) {
@@ -238,12 +245,17 @@
   int hit_test = ash::FrameBorderHitTestController::NonClientHitTest(this,
       caption_button_container_, point);
 
-  // See if the point is actually within the avatar menu button.d
+  // See if the point is actually within either of the avatar menu buttons.
   if (hit_test == HTCAPTION && avatar_button() &&
       ConvertedHitTest(this, avatar_button(), point)) {
     return HTCLIENT;
   }
 
+  if (hit_test == HTCAPTION && new_avatar_button() &&
+      ConvertedHitTest(this, new_avatar_button(), point)) {
+    return HTCLIENT;
+  }
+
   // See if the point is actually within the web app back button.
   if (hit_test == HTCAPTION && web_app_back_button_ &&
       ConvertedHitTest(this, web_app_back_button_, point)) {
@@ -349,10 +361,13 @@
     painted_height = GetTopInset();
   }
   header_painter_->SetHeaderHeightForPainting(painted_height);
+
   if (avatar_button()) {
     LayoutAvatar();
     header_painter_->UpdateLeftViewXInset(avatar_button()->bounds().right());
   } else {
+    if (new_avatar_button())
+      LayoutNewStyleAvatar();
     header_painter_->UpdateLeftViewXInset(
         ash::HeaderPainterUtil::GetDefaultLeftViewXInset());
   }
@@ -443,8 +458,12 @@
 
 void BrowserNonClientFrameViewAsh::ButtonPressed(views::Button* sender,
                                                  const ui::Event& event) {
-  DCHECK_EQ(sender, web_app_back_button_);
-  chrome::ExecuteCommand(browser_view()->browser(), IDC_BACK);
+  if (sender == web_app_back_button_)
+    chrome::ExecuteCommand(browser_view()->browser(), IDC_BACK);
+  else if (sender == new_avatar_button())
+    chrome::ExecuteCommand(browser_view()->browser(), IDC_SHOW_AVATAR_MENU);
+  else
+    NOTREACHED();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -487,8 +506,12 @@
 }
 
 int BrowserNonClientFrameViewAsh::GetTabStripRightInset() const {
-  return caption_button_container_->GetPreferredSize().width() +
-      kTabstripRightSpacing;
+  int tabstrip_width = kTabstripRightSpacing +
+      caption_button_container_->GetPreferredSize().width();
+
+  return new_avatar_button() ? kNewAvatarButtonOffset +
+      new_avatar_button()->GetPreferredSize().width() + tabstrip_width :
+      tabstrip_width;
 }
 
 bool BrowserNonClientFrameViewAsh::UseImmersiveLightbarHeaderStyle() const {
@@ -542,6 +565,23 @@
   avatar_button()->SetVisible(avatar_visible);
 }
 
+void BrowserNonClientFrameViewAsh::LayoutNewStyleAvatar() {
+  DCHECK(switches::IsNewAvatarMenu());
+  if (!new_avatar_button())
+    return;
+
+  gfx::Size button_size = new_avatar_button()->GetPreferredSize();
+  int button_x = width() -
+      caption_button_container_->GetPreferredSize().width() -
+      kNewAvatarButtonOffset - button_size.width();
+
+  new_avatar_button()->SetBounds(
+      button_x,
+      0,
+      button_size.width(),
+      caption_button_container_->GetPreferredSize().height());
+}
+
 bool BrowserNonClientFrameViewAsh::ShouldPaint() const {
   if (!frame()->IsFullscreen())
     return true;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
index ba9ff93..63efd70 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
@@ -115,8 +115,9 @@
   // accoutrements.
   bool UseWebAppHeaderStyle() const;
 
-  // Layout the incognito icon.
+  // Layout the avatar button.
   void LayoutAvatar();
+  void LayoutNewStyleAvatar();
 
   // Returns true if there is anything to paint. Some fullscreen windows do not
   // need their frames painted.
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index bc84ca9..b6c4a17 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -37,8 +37,6 @@
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
 #include "chrome/browser/ui/bookmarks/bookmark_bar_constants.h"
 #include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
 #include "chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h"
@@ -100,6 +98,8 @@
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/locale_settings.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
+#include "components/app_modal_dialogs/app_modal_dialog_queue.h"
 #include "components/signin/core/common/profile_management_switches.h"
 #include "components/translate/core/browser/language_state.h"
 #include "content/app/resources/grit/content_resources.h"
diff --git a/chrome/browser/ui/views/frame/minimize_button_metrics_win.cc b/chrome/browser/ui/views/frame/minimize_button_metrics_win.cc
index 4408e67..3ec7324c 100644
--- a/chrome/browser/ui/views/frame/minimize_button_metrics_win.cc
+++ b/chrome/browser/ui/views/frame/minimize_button_metrics_win.cc
@@ -32,7 +32,7 @@
   // returning it.
   POINT minimize_button_corner = { titlebar_info.rgrect[2].left, 0 };
   MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
-  return minimize_button_corner.x / gfx::win::GetDeviceScaleFactor();
+  return minimize_button_corner.x / gfx::GetDPIScale();
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/javascript_app_modal_dialog_views.cc b/chrome/browser/ui/views/javascript_app_modal_dialog_views.cc
index adfcac3..a237c54 100644
--- a/chrome/browser/ui/views/javascript_app_modal_dialog_views.cc
+++ b/chrome/browser/ui/views/javascript_app_modal_dialog_views.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/ui/views/javascript_app_modal_dialog_views.h"
 
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
 #include "chrome/browser/ui/views/constrained_window_views.h"
-#include "chrome/grit/generated_resources.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/views/controls/message_box_view.h"
diff --git a/chrome/browser/ui/views/javascript_app_modal_dialog_views.h b/chrome/browser/ui/views/javascript_app_modal_dialog_views.h
index b8f86c95..e7efd9f 100644
--- a/chrome/browser/ui/views/javascript_app_modal_dialog_views.h
+++ b/chrome/browser/ui/views/javascript_app_modal_dialog_views.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_VIEWS_JAVASCRIPT_APP_MODAL_DIALOG_VIEWS_H_
 
 #include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "ui/views/window/dialog_delegate.h"
 
 class JavaScriptAppModalDialog;
diff --git a/chrome/browser/ui/views/location_bar/bubble_icon_view.cc b/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
index 68949b4b..d74f329 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
@@ -49,17 +49,14 @@
     return;
   }
 
-  if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location())) {
-    OnExecuting(EXECUTE_SOURCE_MOUSE);
-    command_updater_->ExecuteCommand(command_id_);
-  }
+  if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location()))
+    ExecuteCommand(EXECUTE_SOURCE_MOUSE);
 }
 
 bool BubbleIconView::OnKeyPressed(const ui::KeyEvent& event) {
   if (event.key_code() == ui::VKEY_SPACE ||
       event.key_code() == ui::VKEY_RETURN) {
-    OnExecuting(EXECUTE_SOURCE_KEYBOARD);
-    command_updater_->ExecuteCommand(command_id_);
+    ExecuteCommand(EXECUTE_SOURCE_KEYBOARD);
     return true;
   }
   return false;
@@ -67,8 +64,13 @@
 
 void BubbleIconView::OnGestureEvent(ui::GestureEvent* event) {
   if (event->type() == ui::ET_GESTURE_TAP) {
-    OnExecuting(EXECUTE_SOURCE_GESTURE);
-    command_updater_->ExecuteCommand(command_id_);
+    ExecuteCommand(EXECUTE_SOURCE_GESTURE);
     event->SetHandled();
   }
 }
+
+void BubbleIconView::ExecuteCommand(ExecuteSource source) {
+  OnExecuting(source);
+  if (command_updater_)
+    command_updater_->ExecuteCommand(command_id_);
+}
diff --git a/chrome/browser/ui/views/location_bar/bubble_icon_view.h b/chrome/browser/ui/views/location_bar/bubble_icon_view.h
index 98d4a92..76428243 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.h
+++ b/chrome/browser/ui/views/location_bar/bubble_icon_view.h
@@ -19,7 +19,7 @@
   };
 
   explicit BubbleIconView(CommandUpdater* command_updater, int command_id);
-  virtual ~BubbleIconView();
+  ~BubbleIconView() override;
 
   // Returns true if a related bubble is showing.
   virtual bool IsBubbleShowing() const = 0;
@@ -28,17 +28,20 @@
   virtual void OnExecuting(ExecuteSource execute_source) = 0;
 
   // views::ImageView:
-  virtual void GetAccessibleState(ui::AXViewState* state) override;
-  virtual bool GetTooltipText(const gfx::Point& p, base::string16* tooltip)
-      const override;
-  virtual bool OnMousePressed(const ui::MouseEvent& event) override;
-  virtual void OnMouseReleased(const ui::MouseEvent& event) override;
-  virtual bool OnKeyPressed(const ui::KeyEvent& event) override;
+  void GetAccessibleState(ui::AXViewState* state) override;
+  bool GetTooltipText(const gfx::Point& p, base::string16* tooltip) const
+      override;
+  bool OnMousePressed(const ui::MouseEvent& event) override;
+  void OnMouseReleased(const ui::MouseEvent& event) override;
+  bool OnKeyPressed(const ui::KeyEvent& event) override;
 
   // ui::EventHandler:
-  virtual void OnGestureEvent(ui::GestureEvent* event) override;
+  void OnGestureEvent(ui::GestureEvent* event) override;
 
  private:
+  // Calls OnExecuting and runs |command_id_| with a valid |command_updater_|.
+  void ExecuteCommand(ExecuteSource source);
+
   // The CommandUpdater for the Browser object that owns the location bar.
   CommandUpdater* command_updater_;
 
diff --git a/chrome/browser/ui/views/location_bar/page_action_image_view.cc b/chrome/browser/ui/views/location_bar/page_action_image_view.cc
index bc0cc1c6..1c59eeb 100644
--- a/chrome/browser/ui/views/location_bar/page_action_image_view.cc
+++ b/chrome/browser/ui/views/location_bar/page_action_image_view.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "extensions/browser/extension_registry.h"
@@ -26,16 +27,15 @@
           extensions::ExtensionRegistry::Get(browser->profile())->
               enabled_extensions().GetByID(page_action->extension_id()),
           browser,
-          page_action,
-          this)),
+          page_action)),
       owner_(owner),
       preview_enabled_(false) {
   // There should be an associated focus manager so that we can safely register
   // accelerators for commands.
   DCHECK(GetFocusManagerForAccelerator());
   SetAccessibilityFocusable(true);
+  view_controller_->SetDelegate(this);
   view_controller_->RegisterCommand();
-  set_context_menu_controller(view_controller_.get());
 }
 
 PageActionImageView::~PageActionImageView() {
@@ -67,13 +67,13 @@
     return;
   }
 
-  view_controller_->ExecuteActionByUser();
+  view_controller_->ExecuteAction(true);
 }
 
 bool PageActionImageView::OnKeyPressed(const ui::KeyEvent& event) {
   if (event.key_code() == ui::VKEY_SPACE ||
       event.key_code() == ui::VKEY_RETURN) {
-    view_controller_->ExecuteActionByUser();
+    view_controller_->ExecuteAction(true);
     return true;
   }
   return false;
@@ -81,14 +81,13 @@
 
 void PageActionImageView::OnGestureEvent(ui::GestureEvent* event) {
   if (event->type() == ui::ET_GESTURE_TAP) {
-    view_controller_->ExecuteActionByUser();
+    view_controller_->ExecuteAction(true);
     event->SetHandled();
   }
 }
 
 void PageActionImageView::UpdateVisibility(content::WebContents* contents) {
-  int tab_id = view_controller_->GetCurrentTabId();
-
+  int tab_id = SessionTabHelper::IdForTab(contents);
   if (!contents ||
       tab_id == -1 ||
       (!preview_enabled_ && !extension_action()->GetIsVisible(tab_id))) {
@@ -101,7 +100,7 @@
   SetTooltipText(base::UTF8ToUTF16(tooltip_));
 
   // Set the image.
-  gfx::Image icon = view_controller_->GetIcon(tab_id);
+  gfx::Image icon = view_controller_->GetIcon(contents);
   if (!icon.IsEmpty())
     SetImage(*icon.ToImageSkia());
 
@@ -111,7 +110,7 @@
 void PageActionImageView::PaintChildren(gfx::Canvas* canvas,
                                         const views::CullSet& cull_set) {
   View::PaintChildren(canvas, cull_set);
-  int tab_id = view_controller_->GetCurrentTabId();
+  int tab_id = SessionTabHelper::IdForTab(GetCurrentWebContents());
   if (tab_id >= 0) {
     view_controller_->extension_action()->PaintBadge(
         canvas, GetLocalBounds(), tab_id);
@@ -151,7 +150,7 @@
   return NULL;  // No menu button for page action views.
 }
 
-content::WebContents* PageActionImageView::GetCurrentWebContents() {
+content::WebContents* PageActionImageView::GetCurrentWebContents() const {
   return owner_->GetWebContents();
 }
 
diff --git a/chrome/browser/ui/views/location_bar/page_action_image_view.h b/chrome/browser/ui/views/location_bar/page_action_image_view.h
index 8796663..576468b 100644
--- a/chrome/browser/ui/views/location_bar/page_action_image_view.h
+++ b/chrome/browser/ui/views/location_bar/page_action_image_view.h
@@ -9,7 +9,7 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "chrome/browser/ui/views/extensions/extension_action_view_controller.h"
-#include "chrome/browser/ui/views/extensions/extension_action_view_delegate.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_action_view_delegate.h"
 #include "ui/views/controls/image_view.h"
 
 class Browser;
@@ -22,7 +22,7 @@
 
 // PageActionImageView is used by the LocationBarView to display the icon for a
 // given PageAction and notify the extension when the icon is clicked.
-class PageActionImageView : public ExtensionActionViewDelegate,
+class PageActionImageView : public ToolbarActionViewDelegate,
                             public views::ImageView {
  public:
   PageActionImageView(LocationBarView* owner,
@@ -59,7 +59,7 @@
   virtual void PaintChildren(gfx::Canvas* canvas,
                              const views::CullSet& cull_set) override;
 
-  // Overridden from ExtensionActionViewDelegate:
+  // ToolbarActionViewDelegate:
   virtual void OnIconUpdated() override;
   virtual views::View* GetAsView() override;
   virtual bool IsShownInMenu() override;
@@ -69,7 +69,7 @@
       override;
   virtual views::View* GetReferenceViewForPopup() override;
   virtual views::MenuButton* GetContextMenuButton() override;
-  virtual content::WebContents* GetCurrentWebContents() override;
+  virtual content::WebContents* GetCurrentWebContents() const override;
   virtual void HideActivePopup() override;
 
   // The controller for this ExtensionAction view.
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
index 93cd822..081b8b2e 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -112,8 +112,9 @@
 
 // static
 bool ZoomBubbleView::IsShowing() {
-  // The bubble may be in the process of closing.
-  return zoom_bubble_ != NULL && zoom_bubble_->GetWidget()->IsVisible();
+  // The bubble is considered showing while closing.
+  return zoom_bubble_ != NULL && (zoom_bubble_->GetWidget()->IsVisible() ||
+                                  zoom_bubble_->GetWidget()->IsClosed());
 }
 
 // static
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
index 3440de5..fd4d932a 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_VIEW_H_
 
 #include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
 #include "content/public/browser/notification_observer.h"
@@ -50,6 +51,8 @@
   static const ZoomBubbleView* GetZoomBubbleForTest();
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(ZoomBubbleBrowserTest, ImmersiveFullscreen);
+
   // Stores information about the extension that initiated the zoom change, if
   // any.
   struct ZoomBubbleExtensionInfo {
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
index c8135e1..c5269243 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -96,7 +96,7 @@
       immersive_controller->GetRevealedLock(
           ImmersiveModeController::ANIMATE_REVEAL_NO));
   ASSERT_TRUE(immersive_controller->IsRevealed());
-  EXPECT_FALSE(ZoomBubbleView::IsShowing());
+  EXPECT_TRUE(ZoomBubbleView::zoom_bubble_->GetWidget()->IsClosed());
 
   // The zoom bubble should be anchored when it is shown in immersive fullscreen
   // and the top-of-window views are revealed.
diff --git a/chrome/browser/ui/views/location_bar/zoom_view.cc b/chrome/browser/ui/views/location_bar/zoom_view.cc
index a71860e..c2dbf04 100644
--- a/chrome/browser/ui/views/location_bar/zoom_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_view.cc
@@ -16,8 +16,8 @@
 #include "ui/gfx/size.h"
 
 ZoomView::ZoomView(LocationBarView::Delegate* location_bar_delegate)
-    : location_bar_delegate_(location_bar_delegate) {
-  SetAccessibilityFocusable(true);
+    : BubbleIconView(nullptr, 0),
+      location_bar_delegate_(location_bar_delegate) {
   Update(NULL);
 }
 
@@ -39,44 +39,15 @@
   SetVisible(true);
 }
 
-void ZoomView::GetAccessibleState(ui::AXViewState* state) {
-  state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_ZOOM);
-  state->role = ui::AX_ROLE_BUTTON;
+bool ZoomView::IsBubbleShowing() const {
+  return ZoomBubbleView::IsShowing();
 }
 
-bool ZoomView::GetTooltipText(const gfx::Point& p,
-                              base::string16* tooltip) const {
-  // Don't show tooltip if the zoom bubble is displayed.
-  return !ZoomBubbleView::IsShowing() && ImageView::GetTooltipText(p, tooltip);
-}
-
-bool ZoomView::OnMousePressed(const ui::MouseEvent& event) {
-  // Do nothing until mouse is released.
-  return true;
-}
-
-void ZoomView::OnMouseReleased(const ui::MouseEvent& event) {
-  if (event.IsOnlyLeftMouseButton() && HitTestPoint(event.location()))
-    ActivateBubble();
-}
-
-bool ZoomView::OnKeyPressed(const ui::KeyEvent& event) {
-  if (event.key_code() != ui::VKEY_SPACE &&
-      event.key_code() != ui::VKEY_RETURN) {
-    return false;
-  }
-
-  ActivateBubble();
-  return true;
-}
-
-void ZoomView::OnGestureEvent(ui::GestureEvent* event) {
-  if (event->type() == ui::ET_GESTURE_TAP) {
-    ActivateBubble();
-    event->SetHandled();
-  }
-}
-
-void ZoomView::ActivateBubble() {
+void ZoomView::OnExecuting(BubbleIconView::ExecuteSource source) {
   ZoomBubbleView::ShowBubble(location_bar_delegate_->GetWebContents(), false);
 }
+
+void ZoomView::GetAccessibleState(ui::AXViewState* state) {
+  BubbleIconView::GetAccessibleState(state);
+  state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_ZOOM);
+}
diff --git a/chrome/browser/ui/views/location_bar/zoom_view.h b/chrome/browser/ui/views/location_bar/zoom_view.h
index bd732362..7242ac1 100644
--- a/chrome/browser/ui/views/location_bar/zoom_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_view.h
@@ -5,44 +5,33 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_VIEW_H_
 #define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_VIEW_H_
 
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
-#include "ui/views/controls/image_view.h"
 
 class ZoomController;
 
 // View for the zoom icon in the Omnibox.
-class ZoomView : public views::ImageView {
+class ZoomView : public BubbleIconView {
  public:
   // Clicking on the ZoomView shows a ZoomBubbleView, which requires the current
   // WebContents. Because the current WebContents changes as the user switches
-  // tabs, it cannot be provided in the constructor. Instead, a
-  // LocationBarView::Delegate is passed here so that it can be queried for the
-  // current WebContents as needed.
+  // tabs, a LocationBarView::Delegate is supplied to queried for the current
+  // WebContents when needed.
   explicit ZoomView(LocationBarView::Delegate* location_bar_delegate);
-  virtual ~ZoomView();
+  ~ZoomView() override;
 
   // Updates the image and its tooltip appropriately, hiding or showing the icon
   // as needed.
   void Update(ZoomController* zoom_controller);
 
+ protected:
+  // BubbleIconView:
+  bool IsBubbleShowing() const override;
+  void OnExecuting(BubbleIconView::ExecuteSource source) override;
+  void GetAccessibleState(ui::AXViewState* state) override;
+
  private:
-  // views::ImageView:
-  virtual void GetAccessibleState(ui::AXViewState* state) override;
-  virtual bool GetTooltipText(const gfx::Point& p,
-                              base::string16* tooltip) const override;
-  virtual bool OnMousePressed(const ui::MouseEvent& event) override;
-  virtual void OnMouseReleased(const ui::MouseEvent& event) override;
-  virtual bool OnKeyPressed(const ui::KeyEvent& event) override;
-
-  // ui::EventHandler:
-  virtual void OnGestureEvent(ui::GestureEvent* event) override;
-
-  // Helper method to show and focus the zoom bubble associated with this
-  // widget.
-  void ActivateBubble();
-
   // The delegate used to get the currently visible WebContents.
   LocationBarView::Delegate* location_bar_delegate_;
 
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
index 1e85492..cf8bbcc1 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
@@ -4,8 +4,10 @@
 
 #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h"
 
+#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/passwords/save_password_refusal_combobox_model.h"
@@ -14,6 +16,7 @@
 #include "chrome/browser/ui/views/passwords/manage_password_item_view.h"
 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_view.h"
 #include "chrome/grit/generated_resources.h"
+#include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/aura/window.h"
@@ -30,6 +33,7 @@
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/layout/layout_constants.h"
+#include "ui/wm/core/window_animations.h"
 
 
 // Helpers --------------------------------------------------------------------
@@ -775,6 +779,13 @@
   if (anchor_view)
     anchor_view->SetActive(true);
   mouse_handler_.reset(new WebContentMouseHandler(this));
+
+  // Add observers to close the bubble if the fullscreen state changes.
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
+  registrar_.Add(
+      this,
+      chrome::NOTIFICATION_FULLSCREEN_CHANGED,
+      content::Source<FullscreenController>(browser->fullscreen_controller()));
 }
 
 ManagePasswordsBubbleView::~ManagePasswordsBubbleView() {
@@ -856,3 +867,13 @@
 views::View* ManagePasswordsBubbleView::GetInitiallyFocusedView() {
   return initially_focused_view_;
 }
+
+void ManagePasswordsBubbleView::Observe(
+    int type,
+    const content::NotificationSource& source,
+    const content::NotificationDetails& details) {
+  DCHECK_EQ(type, chrome::NOTIFICATION_FULLSCREEN_CHANGED);
+  aura::Window* window = GetWidget()->GetNativeView();
+  wm::SetWindowVisibilityAnimationTransition(window, wm::ANIMATE_NONE);
+  CloseBubble();
+}
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
index 3b3b2b8..bd07c13 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h
@@ -6,6 +6,8 @@
 #define CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORDS_BUBBLE_VIEW_H_
 
 #include "chrome/browser/ui/passwords/manage_passwords_bubble.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
 #include "ui/views/bubble/bubble_delegate.h"
 
 class ManagePasswordsIconView;
@@ -23,7 +25,8 @@
 // 3. BlacklistedView: Informs the user that the current page is blacklisted.
 //
 class ManagePasswordsBubbleView : public ManagePasswordsBubble,
-                                  public views::BubbleDelegateView {
+                                  public views::BubbleDelegateView,
+                                  public content::NotificationObserver {
  public:
   // Shows the bubble.
   static void ShowBubble(content::WebContents* web_contents,
@@ -90,9 +93,14 @@
   virtual void Init() override;
   virtual void WindowClosing() override;
 
-  // views::WidgetDelegate
+  // views::WidgetDelegate:
   virtual views::View* GetInitiallyFocusedView() override;
 
+  // content::NotificationObserver:
+  virtual void Observe(int type,
+                       const content::NotificationSource& source,
+                       const content::NotificationDetails& details) override;
+
   void set_initially_focused_view(views::View* view) {
     DCHECK(!initially_focused_view_);
     initially_focused_view_ = view;
@@ -116,6 +124,9 @@
   class WebContentMouseHandler;
   scoped_ptr<WebContentMouseHandler> mouse_handler_;
 
+  // Used to register for fullscreen change notifications.
+  content::NotificationRegistrar registrar_;
+
   DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleView);
 };
 
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc
index 8892d2d..e31caa7 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc
@@ -212,13 +212,7 @@
   EXPECT_FALSE(ManagePasswordsBubbleView::IsShowing());
 }
 
-// Fails on linux rel32, see crbug.com/421792
-#if defined(OS_LINUX)
-#define MAYBE_TwoTabsWithBubble DISABLED_TwoTabsWithBubble
-#else
-#define MAYBE_TwoTabsWithBubble TwoTabsWithBubble
-#endif
-IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, MAYBE_TwoTabsWithBubble) {
+IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, TwoTabsWithBubble) {
   // Set up the first tab with the bubble.
   SetupPendingPassword();
   EXPECT_TRUE(ManagePasswordsBubbleView::IsShowing());
diff --git a/chrome/browser/ui/views/profiles/new_avatar_button.cc b/chrome/browser/ui/views/profiles/new_avatar_button.cc
index 03b3fd6..e02afc3 100644
--- a/chrome/browser/ui/views/profiles/new_avatar_button.cc
+++ b/chrome/browser/ui/views/profiles/new_avatar_button.cc
@@ -53,8 +53,6 @@
   SetTextColor(views::Button::STATE_NORMAL, SK_ColorWHITE);
   SetTextColor(views::Button::STATE_HOVERED, SK_ColorWHITE);
   SetTextColor(views::Button::STATE_PRESSED, SK_ColorWHITE);
-  SetTextShadows(gfx::ShadowValues(10,
-      gfx::ShadowValue(gfx::Point(), 1.0f, SK_ColorDKGRAY)));
   SetTextSubpixelRenderingEnabled(false);
   SetHorizontalAlignment(gfx::ALIGN_CENTER);
 
@@ -74,7 +72,8 @@
     generic_avatar_ =
         *rb->GetImageNamed(IDR_AVATAR_THEMED_BUTTON_AVATAR).ToImageSkia();
 #if defined(OS_WIN)
-  } else if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
+  } else if (base::win::GetVersion() >= base::win::VERSION_WIN8 ||
+             browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH) {
     const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_NORMAL);
     const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_HOVER);
     const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_PRESSED);
@@ -185,6 +184,12 @@
 
   SetText(use_generic_button ? base::string16() :
       profiles::GetAvatarButtonTextForProfile(browser_->profile()));
+
+  // If the button has no text, clear the text shadows to make sure the
+  // image is centered correctly.
+  SetTextShadows(use_generic_button ? gfx::ShadowValues() : gfx::ShadowValues(
+      10, gfx::ShadowValue(gfx::Point(), 1.0f, SK_ColorDKGRAY)));
+
   // We want the button to resize if the new text is shorter.
   SetMinSize(gfx::Size());
 
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index ba5a27e..f96693e 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -39,6 +39,7 @@
 #include "components/signin/core/browser/signin_error_controller.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/signin/core/common/profile_management_switches.h"
+#include "content/public/browser/render_widget_host_view.h"
 #include "grit/theme_resources.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -1446,7 +1447,10 @@
   web_view->LoadInitialURL(url);
   web_view->SetPreferredSize(
       gfx::Size(kFixedGaiaViewWidth, kFixedGaiaViewHeight));
-
+  content::RenderWidgetHostView* rwhv =
+      web_view->GetWebContents()->GetRenderWidgetHostView();
+  if (rwhv)
+    rwhv->SetBackgroundColor(profiles::kAvatarBubbleGaiaBackgroundColor);
   TitleCard* title_card = new TitleCard(l10n_util::GetStringUTF16(message_id),
                                         this,
                                         &gaia_signin_cancel_button_);
diff --git a/chrome/browser/ui/views/profiles/user_manager_view.cc b/chrome/browser/ui/views/profiles/user_manager_view.cc
index 0d1ec36..330e451 100644
--- a/chrome/browser/ui/views/profiles/user_manager_view.cc
+++ b/chrome/browser/ui/views/profiles/user_manager_view.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profile_metrics.h"
 #include "chrome/browser/profiles/profile_window.h"
@@ -17,6 +18,7 @@
 #include "chrome/browser/ui/user_manager.h"
 #include "chrome/browser/ui/views/auto_keep_alive.h"
 #include "chrome/grit/chromium_strings.h"
+#include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/screen.h"
@@ -148,10 +150,16 @@
           guest_profile->GetPath()),
       views::HWNDForWidget(GetWidget()));
 #endif
-  GetWidget()->Show();
 
   web_view_->LoadInitialURL(url);
+  content::RenderWidgetHostView* rwhv =
+      web_view_->GetWebContents()->GetRenderWidgetHostView();
+  if (rwhv)
+    rwhv->SetBackgroundColor(profiles::kUserManagerBackgroundColor);
+
   web_view_->RequestFocus();
+
+  GetWidget()->Show();
 }
 
 bool UserManagerView::AcceleratorPressed(const ui::Accelerator& accelerator) {
diff --git a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc b/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc
index fcf5fd9b..9d06e86 100644
--- a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc
+++ b/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc
@@ -10,10 +10,12 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/browser_window_testing_views.h"
+#include "chrome/browser/ui/views/extensions/extension_action_view_controller.h"
 #include "chrome/browser/ui/views/extensions/extension_popup.h"
 #include "chrome/browser/ui/views/toolbar/browser_action_view.h"
 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
+#include "ui/aura/window.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/rect.h"
 #include "ui/gfx/size.h"
@@ -35,15 +37,11 @@
   return GetContainer(browser_)->VisibleBrowserActions();
 }
 
-ExtensionAction* BrowserActionTestUtil::GetExtensionAction(int index) {
-  return extensions::ExtensionActionManager::Get(browser_->profile())->
-      GetBrowserAction(*GetContainer(browser_)->GetBrowserActionViewAt(index)->
-                       extension());
-}
-
 void BrowserActionTestUtil::InspectPopup(int index) {
-  GetContainer(browser_)->GetBrowserActionViewAt(index)->
-      view_controller()->InspectPopup();
+  BrowserActionView* view =
+      GetContainer(browser_)->GetBrowserActionViewAt(index);
+  static_cast<ExtensionActionViewController*>(view->view_controller())->
+      InspectPopup();
 }
 
 bool BrowserActionTestUtil::HasIcon(int index) {
@@ -59,12 +57,12 @@
 
 void BrowserActionTestUtil::Press(int index) {
   GetContainer(browser_)->GetBrowserActionViewAt(index)->
-      view_controller()->ExecuteActionByUser();
+      view_controller()->ExecuteAction(true);
 }
 
 std::string BrowserActionTestUtil::GetExtensionId(int index) {
   return GetContainer(browser_)->GetBrowserActionViewAt(index)->
-      extension()->id();
+      view_controller()->GetId();
 }
 
 std::string BrowserActionTestUtil::GetTooltip(int index) {
@@ -75,7 +73,7 @@
 }
 
 gfx::NativeView BrowserActionTestUtil::GetPopupNativeView() {
-  return GetContainer(browser_)->TestGetPopup()->GetWidget()->GetNativeView();
+  return GetContainer(browser_)->TestGetPopup();
 }
 
 bool BrowserActionTestUtil::HasPopup() {
diff --git a/chrome/browser/ui/views/toolbar/browser_action_view.cc b/chrome/browser/ui/views/toolbar/browser_action_view.cc
index 3f710dd..f1534ca8 100644
--- a/chrome/browser/ui/views/toolbar/browser_action_view.cc
+++ b/chrome/browser/ui/views/toolbar/browser_action_view.cc
@@ -6,31 +6,26 @@
 
 #include <string>
 
-#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/extension_action.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/grit/generated_resources.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/manifest_constants.h"
 #include "grit/theme_resources.h"
 #include "ui/accessibility/ax_view_state.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
 #include "ui/events/event.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/image/image_skia_source.h"
 #include "ui/views/controls/button/label_button_border.h"
 
-using extensions::Extension;
 using views::LabelButtonBorder;
 
 namespace {
@@ -44,32 +39,20 @@
 ////////////////////////////////////////////////////////////////////////////////
 // BrowserActionView
 
-BrowserActionView::BrowserActionView(const Extension* extension,
-                                     ExtensionAction* extension_action,
-                                     Browser* browser,
-                                     BrowserActionView::Delegate* delegate)
+BrowserActionView::BrowserActionView(
+    scoped_ptr<ToolbarActionViewController> view_controller,
+    Browser* browser,
+    BrowserActionView::Delegate* delegate)
     : MenuButton(this, base::string16(), NULL, false),
-      view_controller_(new ExtensionActionViewController(
-          extension,
-          browser,
-          extension_action,
-          this)),
+      view_controller_(view_controller.Pass()),
+      browser_(browser),
       delegate_(delegate),
-      called_registered_extension_command_(false),
-      icon_observer_(NULL) {
+      called_register_command_(false) {
   set_id(VIEW_ID_BROWSER_ACTION);
+  view_controller_->SetDelegate(this);
   SetHorizontalAlignment(gfx::ALIGN_CENTER);
-  set_context_menu_controller(view_controller_.get());
-  set_drag_controller(delegate_);
-
-  content::NotificationSource notification_source =
-      content::Source<Profile>(browser->profile()->GetOriginalProfile());
-  registrar_.Add(this,
-                 extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED,
-                 notification_source);
-  registrar_.Add(this,
-                 extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED,
-                 notification_source);
+  if (view_controller_->CanDrag())
+    set_drag_controller(delegate_);
 
   // We also listen for browser theme changes on linux because a switch from or
   // to GTK requires that we regrab our browser action images.
@@ -87,10 +70,9 @@
 
 void BrowserActionView::ViewHierarchyChanged(
     const ViewHierarchyChangedDetails& details) {
-  if (details.is_add && !called_registered_extension_command_ &&
-      GetFocusManager()) {
+  if (details.is_add && !called_register_command_ && GetFocusManager()) {
     view_controller_->RegisterCommand();
-    called_registered_extension_command_ = true;
+    called_register_command_ = true;
   }
 
   MenuButton::ViewHierarchyChanged(details);
@@ -108,9 +90,8 @@
 void BrowserActionView::PaintChildren(gfx::Canvas* canvas,
                                       const views::CullSet& cull_set) {
   View::PaintChildren(canvas, cull_set);
-  int tab_id = view_controller_->GetCurrentTabId();
-  if (tab_id >= 0)
-    extension_action()->PaintBadge(canvas, GetLocalBounds(), tab_id);
+  view_controller_->PaintExtra(
+      canvas, GetLocalBounds(), GetCurrentWebContents());
 }
 
 void BrowserActionView::GetAccessibleState(ui::AXViewState* state) {
@@ -120,80 +101,51 @@
 
 void BrowserActionView::ButtonPressed(views::Button* sender,
                                       const ui::Event& event) {
-  view_controller_->ExecuteActionByUser();
+  view_controller_->ExecuteAction(true);
 }
 
 void BrowserActionView::UpdateState() {
-  int tab_id = view_controller_->GetCurrentTabId();
-  if (tab_id < 0)
+  content::WebContents* web_contents = GetCurrentWebContents();
+  if (SessionTabHelper::IdForTab(web_contents) < 0)
     return;
 
-  if (!IsEnabled(tab_id))
+  bool enabled = view_controller_->IsEnabled(web_contents);
+  if (!enabled)
     SetState(views::CustomButton::STATE_DISABLED);
 
-  gfx::ImageSkia icon = *view_controller_->GetIcon(tab_id).ToImageSkia();
+  gfx::ImageSkia icon = *view_controller_->GetIcon(web_contents).ToImageSkia();
 
   if (!icon.isNull()) {
-    if (!extension_action()->GetIsVisible(tab_id))
+    if (!enabled)
       icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
 
-    ThemeService* theme = ThemeServiceFactory::GetForProfile(
-        view_controller_->browser()->profile());
+    ThemeService* theme =
+        ThemeServiceFactory::GetForProfile(browser_->profile());
 
     gfx::ImageSkia bg = *theme->GetImageSkiaNamed(IDR_BROWSER_ACTION);
     SetImage(views::Button::STATE_NORMAL,
              gfx::ImageSkiaOperations::CreateSuperimposedImage(bg, icon));
   }
 
-  // If the browser action name is empty, show the extension name instead.
-  std::string title = extension_action()->GetTitle(tab_id);
-  base::string16 name =
-      base::UTF8ToUTF16(title.empty() ? extension()->name() : title);
-  SetTooltipText(name);
-  SetAccessibleName(name);
+  SetTooltipText(view_controller_->GetTooltip(web_contents));
+  SetAccessibleName(view_controller_->GetAccessibleName(web_contents));
 
   Layout();  // We need to layout since we may have added an icon as a result.
   SchedulePaint();
 }
 
-bool BrowserActionView::IsPopup() {
-  int tab_id = view_controller_->GetCurrentTabId();
-  return (tab_id < 0) ? false : extension_action()->HasPopup(tab_id);
-}
-
 void BrowserActionView::Observe(int type,
                                 const content::NotificationSource& source,
                                 const content::NotificationDetails& details) {
-  switch (type) {
-    case extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED:
-    case extensions::NOTIFICATION_EXTENSION_COMMAND_REMOVED: {
-      std::pair<const std::string, const std::string>* payload =
-          content::Details<std::pair<const std::string, const std::string> >(
-              details).ptr();
-      if (extension()->id() == payload->first &&
-          payload->second ==
-              extensions::manifest_values::kBrowserActionCommandEvent) {
-        if (type == extensions::NOTIFICATION_EXTENSION_COMMAND_ADDED)
-          view_controller_->RegisterCommand();
-        else
-          view_controller_->UnregisterCommand(true);
-      }
-      break;
-    }
-    case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
-      UpdateState();
-      break;
-    default:
-      NOTREACHED();
-      break;
-  }
+  DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type);
+  UpdateState();
 }
 
 bool BrowserActionView::Activate() {
-  if (!IsPopup())
+  if (!view_controller_->HasPopup(GetCurrentWebContents()))
     return true;
 
-  view_controller_->ExecuteActionByUser();
+  view_controller_->ExecuteAction(true);
 
   // TODO(erikkay): Run a nested modal loop while the mouse is down to
   // enable menu-like drag-select behavior.
@@ -207,14 +159,15 @@
 
 bool BrowserActionView::OnMousePressed(const ui::MouseEvent& event) {
   if (!event.IsRightMouseButton()) {
-    return IsPopup() ? MenuButton::OnMousePressed(event) :
-                       LabelButton::OnMousePressed(event);
+    return view_controller_->HasPopup(GetCurrentWebContents()) ?
+        MenuButton::OnMousePressed(event) : LabelButton::OnMousePressed(event);
   }
   return false;
 }
 
 void BrowserActionView::OnMouseReleased(const ui::MouseEvent& event) {
-  if (IsPopup() || view_controller_->is_menu_running()) {
+  if (view_controller_->HasPopup(GetCurrentWebContents()) ||
+      view_controller_->IsMenuRunning()) {
     // TODO(erikkay) this never actually gets called (probably because of the
     // loss of focus).
     MenuButton::OnMouseReleased(event);
@@ -224,19 +177,20 @@
 }
 
 void BrowserActionView::OnMouseExited(const ui::MouseEvent& event) {
-  if (IsPopup() || view_controller_->is_menu_running())
+  if (view_controller_->HasPopup(GetCurrentWebContents()) ||
+      view_controller_->IsMenuRunning())
     MenuButton::OnMouseExited(event);
   else
     LabelButton::OnMouseExited(event);
 }
 
 bool BrowserActionView::OnKeyReleased(const ui::KeyEvent& event) {
-  return IsPopup() ? MenuButton::OnKeyReleased(event) :
-                     LabelButton::OnKeyReleased(event);
+  return view_controller_->HasPopup(GetCurrentWebContents()) ?
+      MenuButton::OnKeyReleased(event) : LabelButton::OnKeyReleased(event);
 }
 
 void BrowserActionView::OnGestureEvent(ui::GestureEvent* event) {
-  if (IsPopup())
+  if (view_controller_->HasPopup(GetCurrentWebContents()))
     MenuButton::OnGestureEvent(event);
   else
     LabelButton::OnGestureEvent(event);
@@ -249,27 +203,12 @@
   return border.Pass();
 }
 
-bool BrowserActionView::IsEnabled(int tab_id) const {
-  return view_controller_->extension_action()->GetIsVisible(tab_id);
-}
-
-gfx::ImageSkia BrowserActionView::GetIconWithBadge() {
-  int tab_id = view_controller_->GetCurrentTabId();
-  gfx::Size spacing(0, ToolbarView::kVertSpacing);
-  gfx::ImageSkia icon = *view_controller_->GetIcon(tab_id).ToImageSkia();
-  if (!IsEnabled(tab_id))
-    icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25);
-  return extension_action()->GetIconWithBadge(icon, tab_id, spacing);
-}
-
 gfx::ImageSkia BrowserActionView::GetIconForTest() {
   return GetImage(views::Button::STATE_NORMAL);
 }
 
 void BrowserActionView::OnIconUpdated() {
   UpdateState();
-  if (icon_observer_)
-    icon_observer_->OnIconUpdated(GetIconWithBadge());
 }
 
 views::View* BrowserActionView::GetAsView() {
@@ -288,15 +227,15 @@
   // RunMenuAt expects a nested menu to be parented by the same widget as the
   // already visible menu, in this case the Chrome menu.
   return delegate_->ShownInsideMenu() ?
-      BrowserView::GetBrowserViewForBrowser(view_controller_->browser())
+      BrowserView::GetBrowserViewForBrowser(browser_)
           ->toolbar()->app_menu()->GetWidget() :
       GetWidget();
 }
 
-ExtensionActionViewController*
+ToolbarActionViewController*
 BrowserActionView::GetPreferredPopupViewController() {
   return delegate_->ShownInsideMenu() ?
-      delegate_->GetMainViewForExtension(extension())->view_controller() :
+      delegate_->GetMainViewForAction(this)->view_controller() :
       view_controller();
 }
 
@@ -312,7 +251,7 @@
   return this;
 }
 
-content::WebContents* BrowserActionView::GetCurrentWebContents() {
+content::WebContents* BrowserActionView::GetCurrentWebContents() const {
   return delegate_->GetCurrentWebContents();
 }
 
diff --git a/chrome/browser/ui/views/toolbar/browser_action_view.h b/chrome/browser/ui/views/toolbar/browser_action_view.h
index 190e545a..8f864c77 100644
--- a/chrome/browser/ui/views/toolbar/browser_action_view.h
+++ b/chrome/browser/ui/views/toolbar/browser_action_view.h
@@ -5,8 +5,7 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_
 #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_VIEW_H_
 
-#include "chrome/browser/ui/views/extensions/extension_action_view_controller.h"
-#include "chrome/browser/ui/views/extensions/extension_action_view_delegate.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_action_view_delegate.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "ui/views/controls/button/menu_button.h"
@@ -27,14 +26,14 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // BrowserActionView
-// A wrapper around an ExtensionActionViewController to display an extension
+// A wrapper around a ToolbarActionViewController to display a toolbar action
 // action in the BrowserActionsContainer.
-// Despite its name, this class can handle either Browser Actions or Page
-// Actions.
+// Despite its name, this class can handle any type of toolbar action, including
+// extension actions (browser and page actions) and component actions.
 // TODO(devlin): Rename this and BrowserActionsContainer when more of the
 // toolbar redesign is done.
 class BrowserActionView : public views::MenuButton,
-                          public ExtensionActionViewDelegate,
+                          public ToolbarActionViewDelegate,
                           public views::ButtonListener,
                           public content::NotificationObserver {
  public:
@@ -66,48 +65,21 @@
 
     // Returns the primary BrowserActionView associated with the given
     // |extension|.
-    virtual BrowserActionView* GetMainViewForExtension(
-        const extensions::Extension* extension) = 0;
+    virtual BrowserActionView* GetMainViewForAction(
+        BrowserActionView* view) = 0;
 
    protected:
     virtual ~Delegate() {}
   };
 
-  // The IconObserver will receive a notification when the button's icon has
-  // been updated.
-  class IconObserver {
-   public:
-    virtual void OnIconUpdated(const gfx::ImageSkia& icon) = 0;
-
-   protected:
-    virtual ~IconObserver() {}
-  };
-
-  BrowserActionView(const extensions::Extension* extension,
-                    ExtensionAction* extension_action,
+  BrowserActionView(scoped_ptr<ToolbarActionViewController> view_controller,
                     Browser* browser,
-                    BrowserActionView::Delegate* delegate);
+                    Delegate* delegate);
   virtual ~BrowserActionView();
 
-  const extensions::Extension* extension() const {
-    return view_controller_->extension();
-  }
-  ExtensionAction* extension_action() {
-    return view_controller_->extension_action();
-  }
-  ExtensionActionViewController* view_controller() {
-    return view_controller_.get();
-  }
-  void set_icon_observer(IconObserver* icon_observer) {
-    icon_observer_ = icon_observer;
-  }
-
   // Called to update the display to match the browser action's state.
   void UpdateState();
 
-  // Does this button's action have a popup?
-  bool IsPopup();
-
   // Overridden from views::View:
   virtual void GetAccessibleState(ui::AXViewState* state) override;
 
@@ -134,13 +106,13 @@
   virtual scoped_ptr<views::LabelButtonBorder> CreateDefaultBorder() const
       override;
 
-  // Whether the browser action is enabled on this tab. Note that we cannot use
-  // the built-in views enabled/SetEnabled because disabled views do not
-  // receive drag events.
-  bool IsEnabled(int tab_id) const;
+  // ToolbarActionViewDelegate: (public because called by others).
+  virtual content::WebContents* GetCurrentWebContents() const override;
 
-  // Gets the icon of this button and its badge.
-  gfx::ImageSkia GetIconWithBadge();
+  ToolbarActionViewController* view_controller() {
+    return view_controller_.get();
+  }
+  Browser* browser() { return browser_; }
 
   // Returns button icon so it can be accessed during tests.
   gfx::ImageSkia GetIconForTest();
@@ -154,16 +126,15 @@
   virtual void PaintChildren(gfx::Canvas* canvas,
                              const views::CullSet& cull_set) override;
 
-  // ExtensionActionViewDelegate:
+  // ToolbarActionViewDelegate:
   virtual views::View* GetAsView() override;
   virtual bool IsShownInMenu() override;
   virtual views::FocusManager* GetFocusManagerForAccelerator() override;
   virtual views::Widget* GetParentForContextMenu() override;
-  virtual ExtensionActionViewController* GetPreferredPopupViewController()
+  virtual ToolbarActionViewController* GetPreferredPopupViewController()
       override;
   virtual views::View* GetReferenceViewForPopup() override;
   virtual views::MenuButton* GetContextMenuButton() override;
-  virtual content::WebContents* GetCurrentWebContents() override;
   virtual void HideActivePopup() override;
   virtual void OnIconUpdated() override;
   virtual void OnPopupShown(bool grant_tab_permissions) override;
@@ -175,21 +146,20 @@
   // object.
   scoped_ptr<views::MenuButton::PressedLock> pressed_lock_;
 
-  // The controller for this ExtensionAction view.
-  scoped_ptr<ExtensionActionViewController> view_controller_;
+  // The controller for this toolbar action view.
+  scoped_ptr<ToolbarActionViewController> view_controller_;
+
+  // The associated browser.
+  Browser* browser_;
 
   // Delegate that usually represents a container for BrowserActionView.
-  BrowserActionView::Delegate* delegate_;
+  Delegate* delegate_;
 
   // Used to make sure we only register the command once.
-  bool called_registered_extension_command_;
+  bool called_register_command_;
 
   content::NotificationRegistrar registrar_;
 
-  // The observer that we need to notify when the icon of the button has been
-  // updated.
-  IconObserver* icon_observer_;
-
   DISALLOW_COPY_AND_ASSIGN(BrowserActionView);
 };
 
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.cc b/chrome/browser/ui/views/toolbar/browser_actions_container.cc
index 55fcfe2..080617f3 100644
--- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc
+++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc
@@ -12,14 +12,17 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
+#include "chrome/browser/ui/views/extensions/extension_action_view_controller.h"
 #include "chrome/browser/ui/views/extensions/extension_popup.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/toolbar/browser_actions_container_observer.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/common/extensions/command.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/crx_file/id_util.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/runtime_data.h"
 #include "extensions/common/feature_switch.h"
@@ -46,6 +49,37 @@
 // Horizontal spacing before the chevron (if visible).
 const int kChevronSpacing = ToolbarView::kStandardSpacing - 2;
 
+// Returns the set of controllers for all actions.
+// TODO(devlin): We should move this to the model, once it supports component
+// actions.
+ScopedVector<ToolbarActionViewController> GetToolbarActions(
+    extensions::ExtensionToolbarModel* model,
+    Browser* browser) {
+  ScopedVector<ToolbarActionViewController> actions;
+
+  // Extension actions come first.
+  extensions::ExtensionActionManager* action_manager =
+      extensions::ExtensionActionManager::Get(browser->profile());
+  const extensions::ExtensionList& toolbar_items = model->toolbar_items();
+  for (const scoped_refptr<const Extension>& extension : toolbar_items) {
+    actions.push_back(new ExtensionActionViewController(
+        extension.get(),
+        browser,
+        action_manager->GetExtensionAction(*extension)));
+  }
+
+  // Component actions come second.
+  ScopedVector<ToolbarActionViewController> component_actions =
+      ComponentToolbarActionsFactory::GetInstance()->
+          GetComponentToolbarActions();
+  DCHECK(extensions::FeatureSwitch::extension_action_redesign()->IsEnabled() ||
+         component_actions.empty());
+  actions.insert(
+      actions.end(), component_actions.begin(), component_actions.end());
+  component_actions.weak_clear();
+  return actions.Pass();
+}
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -146,10 +180,14 @@
   initialized_ = true;
 }
 
+const std::string& BrowserActionsContainer::GetIdAt(size_t index) {
+  return browser_action_views_[index]->view_controller()->GetId();
+}
+
 BrowserActionView* BrowserActionsContainer::GetViewForExtension(
     const Extension* extension) {
   for (BrowserActionView* view : browser_action_views_) {
-    if (view->extension() == extension)
+    if (view->view_controller()->GetId() == extension->id())
       return view;
   }
   return NULL;
@@ -165,18 +203,15 @@
   if (!model_)
     return;
 
-  extensions::ExtensionActionManager* action_manager =
-      extensions::ExtensionActionManager::Get(profile_);
-  const extensions::ExtensionList& toolbar_items = model_->toolbar_items();
-  for (const scoped_refptr<const Extension>& extension : toolbar_items) {
+  ScopedVector<ToolbarActionViewController> actions =
+      GetToolbarActions(model_, browser_);
+  for (ToolbarActionViewController* controller : actions) {
     BrowserActionView* view =
-        new BrowserActionView(extension.get(),
-                              action_manager->GetExtensionAction(*extension),
-                              browser_,
-                              this);
+        new BrowserActionView(make_scoped_ptr(controller), browser_, this);
     browser_action_views_.push_back(view);
     AddChildView(view);
   }
+  actions.weak_clear();
 }
 
 void BrowserActionsContainer::DeleteBrowserActionViews() {
@@ -254,11 +289,21 @@
     popup_owner_->view_controller()->HidePopup();
 }
 
-BrowserActionView* BrowserActionsContainer::GetMainViewForExtension(
-    const Extension* extension) {
-  return in_overflow_mode() ?
-      main_container_->GetViewForExtension(extension) :
-      GetViewForExtension(extension);
+BrowserActionView* BrowserActionsContainer::GetMainViewForAction(
+    BrowserActionView* view) {
+  if (!in_overflow_mode())
+    return view;  // This is the main view.
+
+  // The overflow container and main container each have the same views and
+  // view indices, so we can return the view of the index that |view| has in
+  // this container.
+  BrowserActionViews::const_iterator iter =
+      std::find(browser_action_views_.begin(),
+                browser_action_views_.end(),
+                view);
+  DCHECK(iter != browser_action_views_.end());
+  size_t index = iter - browser_action_views_.begin();
+  return main_container_->browser_action_views_[index];
 }
 
 void BrowserActionsContainer::AddObserver(
@@ -479,8 +524,7 @@
     return ui::DragDropTypes::DRAG_NONE;
 
   // Make sure we have the same view as we started with.
-  DCHECK_EQ(browser_action_views_[data.index()]->extension()->id(),
-            data.id());
+  DCHECK_EQ(GetIdAt(data.index()), data.id());
   DCHECK(model_);
 
   size_t i = drop_position_->row * icons_per_overflow_menu_row_ +
@@ -499,8 +543,7 @@
   // visible icons.
   bool drag_between_containers =
       !browser_action_views_[data.index()]->visible();
-  model_->MoveExtensionIcon(
-      browser_action_views_[data.index()]->extension(), i);
+  model_->MoveExtensionIcon(GetIdAt(data.index()), i);
 
   if (drag_between_containers) {
     // Let the main container update the model.
@@ -529,11 +572,13 @@
                                                 browser_action_views_.end(),
                                                 sender);
   DCHECK(iter != browser_action_views_.end());
-  drag_utils::SetDragImageOnDataObject((*iter)->GetIconWithBadge(),
-                                       press_pt.OffsetFromOrigin(),
-                                       data);
+  ToolbarActionViewController* view_controller = (*iter)->view_controller();
+  drag_utils::SetDragImageOnDataObject(
+      view_controller->GetIconWithBadge(),
+      press_pt.OffsetFromOrigin(),
+      data);
   // Fill in the remaining info.
-  BrowserActionDragData drag_data((*iter)->extension()->id(),
+  BrowserActionDragData drag_data(view_controller->GetId(),
                                   iter - browser_action_views_.begin());
   drag_data.Write(profile_, data);
 }
@@ -605,8 +650,10 @@
       active_tab_permission_granter();
 }
 
-ExtensionPopup* BrowserActionsContainer::TestGetPopup() {
-  return popup_owner_ ? popup_owner_->view_controller()->popup() : NULL;
+gfx::NativeView BrowserActionsContainer::TestGetPopup() {
+  return popup_owner_ ?
+      popup_owner_->view_controller()->GetPopupNativeView() :
+      NULL;
 }
 
 void BrowserActionsContainer::OnPaint(gfx::Canvas* canvas) {
@@ -709,23 +756,20 @@
 
 void BrowserActionsContainer::ToolbarExtensionAdded(const Extension* extension,
                                                     int index) {
-#if defined(DEBUG)
-  for (size_t i = 0; i < browser_action_views_.size(); ++i) {
-    DCHECK(browser_action_views_[i]->extension() != extension) <<
-           "Asked to add a browser action view for an extension that already "
-           "exists.";
-  }
-#endif
+  DCHECK(!GetViewForExtension(extension)) <<
+      "Asked to add a browser action view for an extension that already exists";
   if (chevron_)
     chevron_->CloseMenu();
 
   // Add the new browser action to the vector and the view hierarchy.
-  BrowserActionView* view =
-      new BrowserActionView(extension,
-                            extensions::ExtensionActionManager::Get(profile_)->
-                                GetExtensionAction(*extension),
-                            browser_,
-                            this);
+  BrowserActionView* view = new BrowserActionView(
+      make_scoped_ptr(new ExtensionActionViewController(
+          extension,
+          browser_,
+          extensions::ExtensionActionManager::Get(profile_)->
+              GetExtensionAction(*extension))),
+      browser_,
+      this);
   browser_action_views_.insert(browser_action_views_.begin() + index, view);
   AddChildViewAt(view, index);
 
@@ -765,7 +809,7 @@
   size_t visible_actions = VisibleBrowserActionsAfterAnimation();
   for (BrowserActionViews::iterator i(browser_action_views_.begin());
        i != browser_action_views_.end(); ++i) {
-    if ((*i)->extension() == extension) {
+    if ((*i)->view_controller()->GetId() == extension->id()) {
       delete *i;
       browser_action_views_.erase(i);
 
@@ -799,9 +843,8 @@
 
   BrowserActionViews::iterator iter = browser_action_views_.begin();
   while (iter != browser_action_views_.end() &&
-         (*iter)->extension() != extension) {
+         (*iter)->view_controller()->GetId() != extension->id())
     ++iter;
-  }
 
   DCHECK(iter != browser_action_views_.end());
   if (iter - browser_action_views_.begin() == index)
@@ -833,8 +876,7 @@
     return false;
 
   BrowserActionView* view = GetViewForExtension(extension);
-  return view && view->view_controller()->ExecuteAction(ExtensionPopup::SHOW,
-                                                        grant_active_tab);
+  return view && view->view_controller()->ExecuteAction(grant_active_tab);
 }
 
 void BrowserActionsContainer::ToolbarVisibleCountChanged() {
@@ -960,13 +1002,24 @@
   size_t absolute_model_visible_size = model_visible_size == -1 ?
       model_->toolbar_items().size() : model_visible_size;
 
+#if !defined(NDEBUG)
   // Good time for some sanity checks: We should never try to display more
   // icons than we have, and we should always have a view per item in the model.
   // (The only exception is if this is in initialization.)
   if (initialized_) {
-    DCHECK_LE(absolute_model_visible_size, browser_action_views_.size());
-    DCHECK_EQ(model_->toolbar_items().size(), browser_action_views_.size());
+    size_t num_extension_actions = 0u;
+    for (BrowserActionView* view : browser_action_views_) {
+      // No component action should ever have a valid extension id, so we can
+      // use this to check the extension amount.
+      // TODO(devlin): Fix this to just check model size when the model also
+      // includes component actions.
+      if (crx_file::id_util::IdIsValid(view->view_controller()->GetId()))
+        ++num_extension_actions;
+    }
+    DCHECK_LE(absolute_model_visible_size, num_extension_actions);
+    DCHECK_EQ(model_->toolbar_items().size(), num_extension_actions);
   }
+#endif
 
   // The overflow displays any icons not shown by the main bar.
   return in_overflow_mode() ?
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.h b/chrome/browser/ui/views/toolbar/browser_actions_container.h
index 17907b95..98d2464e 100644
--- a/chrome/browser/ui/views/toolbar/browser_actions_container.h
+++ b/chrome/browser/ui/views/toolbar/browser_actions_container.h
@@ -164,6 +164,9 @@
     return browser_action_views_[index];
   }
 
+  // Returns the ID of the action represented by the view at |index|.
+  const std::string& GetIdAt(size_t index);
+
   // Returns the BrowserActionView* associated with the given |extension|, or
   // NULL if none exists.
   BrowserActionView* GetViewForExtension(
@@ -238,15 +241,15 @@
   virtual views::MenuButton* GetOverflowReferenceView() override;
   virtual void SetPopupOwner(BrowserActionView* popup_owner) override;
   virtual void HideActivePopup() override;
-  virtual BrowserActionView* GetMainViewForExtension(
-      const extensions::Extension* extension) override;
+  virtual BrowserActionView* GetMainViewForAction(
+      BrowserActionView* view) override;
 
   // Overridden from extension::ExtensionKeybindingRegistry::Delegate:
   virtual extensions::ActiveTabPermissionGranter*
       GetActiveTabPermissionGranter() override;
 
   // Retrieve the current popup.  This should only be used by unit tests.
-  ExtensionPopup* TestGetPopup();
+  gfx::NativeView TestGetPopup();
 
   // Returns the width of an icon, optionally with its padding.
   static int IconWidth(bool include_padding);
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
index 5b32f1a..2949596f 100644
--- a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
+++ b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
@@ -241,12 +241,12 @@
   // is right now A B C.
   EXPECT_EQ(3u, first->VisibleBrowserActions());
   EXPECT_EQ(3u, second->VisibleBrowserActions());
-  EXPECT_EQ(extension_a(), first->GetBrowserActionViewAt(0u)->extension());
-  EXPECT_EQ(extension_a(), second->GetBrowserActionViewAt(0u)->extension());
-  EXPECT_EQ(extension_b(), first->GetBrowserActionViewAt(1u)->extension());
-  EXPECT_EQ(extension_b(), second->GetBrowserActionViewAt(1u)->extension());
-  EXPECT_EQ(extension_c(), first->GetBrowserActionViewAt(2u)->extension());
-  EXPECT_EQ(extension_c(), second->GetBrowserActionViewAt(2u)->extension());
+  EXPECT_EQ(extension_a()->id(), first->GetIdAt(0u));
+  EXPECT_EQ(extension_a()->id(), second->GetIdAt(0u));
+  EXPECT_EQ(extension_b()->id(), first->GetIdAt(1u));
+  EXPECT_EQ(extension_b()->id(), second->GetIdAt(1u));
+  EXPECT_EQ(extension_c()->id(), first->GetIdAt(2u));
+  EXPECT_EQ(extension_c()->id(), second->GetIdAt(2u));
 
   // Simulate a drag and drop to the right.
   ui::OSExchangeData drop_data;
@@ -265,12 +265,12 @@
 
   // The new order, B A C, should be reflected in *both* containers, even
   // though the drag only happened in the first one.
-  EXPECT_EQ(extension_b(), first->GetBrowserActionViewAt(0u)->extension());
-  EXPECT_EQ(extension_b(), second->GetBrowserActionViewAt(0u)->extension());
-  EXPECT_EQ(extension_a(), first->GetBrowserActionViewAt(1u)->extension());
-  EXPECT_EQ(extension_a(), second->GetBrowserActionViewAt(1u)->extension());
-  EXPECT_EQ(extension_c(), first->GetBrowserActionViewAt(2u)->extension());
-  EXPECT_EQ(extension_c(), second->GetBrowserActionViewAt(2u)->extension());
+  EXPECT_EQ(extension_b()->id(), first->GetIdAt(0u));
+  EXPECT_EQ(extension_b()->id(), second->GetIdAt(0u));
+  EXPECT_EQ(extension_a()->id(), first->GetIdAt(1u));
+  EXPECT_EQ(extension_a()->id(), second->GetIdAt(1u));
+  EXPECT_EQ(extension_c()->id(), first->GetIdAt(2u));
+  EXPECT_EQ(extension_c()->id(), second->GetIdAt(2u));
 
   // Next, simulate a resize by shrinking the container.
   first->OnResize(1, true);
@@ -399,8 +399,7 @@
       overflow_bar_->num_browser_actions())
     return false;
   for (size_t i = 0; i < main_bar_->num_browser_actions(); ++i) {
-    if (main_bar_->GetBrowserActionViewAt(i)->extension() !=
-        overflow_bar_->GetBrowserActionViewAt(i)->extension())
+    if (main_bar_->GetIdAt(i) != overflow_bar_->GetIdAt(i))
       return false;
   }
   return true;
@@ -442,27 +441,27 @@
   // All actions are showing, and are in the installation order.
   EXPECT_EQ(-1, model()->GetVisibleIconCount());
   ASSERT_EQ(3u, main_bar()->num_browser_actions());
-  EXPECT_EQ(extension_a(), main_bar()->GetBrowserActionViewAt(0)->extension());
-  EXPECT_EQ(extension_b(), main_bar()->GetBrowserActionViewAt(1)->extension());
-  EXPECT_EQ(extension_c(), main_bar()->GetBrowserActionViewAt(2)->extension());
+  EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
+  EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(1u));
+  EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
   EXPECT_TRUE(VerifyVisibleCount(3u));
 
   // Reduce the visible count to 2. Order should be unchanged (A B C), but
   // only A and B should be visible on the main bar.
   model()->SetVisibleIconCount(2u);
   overflow_bar()->Layout();  // Kick.
-  EXPECT_EQ(extension_a(), main_bar()->GetBrowserActionViewAt(0)->extension());
-  EXPECT_EQ(extension_b(), main_bar()->GetBrowserActionViewAt(1)->extension());
-  EXPECT_EQ(extension_c(), main_bar()->GetBrowserActionViewAt(2)->extension());
+  EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
+  EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(1u));
+  EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
   EXPECT_TRUE(VerifyVisibleCount(2u));
 
   // Move extension C to the first position. Order should now be C A B, with
   // C and A visible in the main bar.
-  model()->MoveExtensionIcon(extension_c(), 0);
+  model()->MoveExtensionIcon(extension_c()->id(), 0);
   overflow_bar()->Layout();  // Kick.
-  EXPECT_EQ(extension_c(), main_bar()->GetBrowserActionViewAt(0)->extension());
-  EXPECT_EQ(extension_a(), main_bar()->GetBrowserActionViewAt(1)->extension());
-  EXPECT_EQ(extension_b(), main_bar()->GetBrowserActionViewAt(2)->extension());
+  EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(0u));
+  EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(1u));
+  EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(2u));
   EXPECT_TRUE(VerifyVisibleCount(2u));
 
   // Hide action A. This results in it being sent to overflow, and reducing the
@@ -473,9 +472,9 @@
       extension_a()->id(),
       false);
   overflow_bar()->Layout();  // Kick.
-  EXPECT_EQ(extension_c(), main_bar()->GetBrowserActionViewAt(0)->extension());
-  EXPECT_EQ(extension_a(), main_bar()->GetBrowserActionViewAt(1)->extension());
-  EXPECT_EQ(extension_b(), main_bar()->GetBrowserActionViewAt(2)->extension());
+  EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(0u));
+  EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(1u));
+  EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(2u));
   EXPECT_TRUE(VerifyVisibleCount(1u));
 }
 
@@ -490,9 +489,9 @@
 
   // Verify starting state is A B [C].
   ASSERT_EQ(3u, main_bar()->num_browser_actions());
-  EXPECT_EQ(extension_a(), main_bar()->GetBrowserActionViewAt(0)->extension());
-  EXPECT_EQ(extension_b(), main_bar()->GetBrowserActionViewAt(1)->extension());
-  EXPECT_EQ(extension_c(), main_bar()->GetBrowserActionViewAt(2)->extension());
+  EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
+  EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(1u));
+  EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
   EXPECT_TRUE(VerifyVisibleCount(2u));
 
   // Drag extension A (on the main bar) to the left of extension C (in
@@ -510,9 +509,9 @@
   overflow_bar()->Layout();
 
   // Order should now be B [A C].
-  EXPECT_EQ(extension_b(), main_bar()->GetBrowserActionViewAt(0)->extension());
-  EXPECT_EQ(extension_a(), main_bar()->GetBrowserActionViewAt(1)->extension());
-  EXPECT_EQ(extension_c(), main_bar()->GetBrowserActionViewAt(2)->extension());
+  EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(0u));
+  EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(1u));
+  EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
   VerifyVisibleCount(1u);
 
   // Drag extension A back from overflow to the main bar.
@@ -528,9 +527,9 @@
   main_bar()->OnPerformDrop(target_event2);
 
   // Order should be A B [C] again.
-  EXPECT_EQ(extension_a(), main_bar()->GetBrowserActionViewAt(0)->extension());
-  EXPECT_EQ(extension_b(), main_bar()->GetBrowserActionViewAt(1)->extension());
-  EXPECT_EQ(extension_c(), main_bar()->GetBrowserActionViewAt(2)->extension());
+  EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
+  EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(1u));
+  EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(2u));
   VerifyVisibleCount(2u);
 
   // Drag extension C from overflow to the main bar (before extension B).
@@ -545,8 +544,8 @@
   main_bar()->OnPerformDrop(target_event3);
 
   // Order should be A C B, and there should be no extensions in overflow.
-  EXPECT_EQ(extension_a(), main_bar()->GetBrowserActionViewAt(0)->extension());
-  EXPECT_EQ(extension_c(), main_bar()->GetBrowserActionViewAt(1)->extension());
-  EXPECT_EQ(extension_b(), main_bar()->GetBrowserActionViewAt(2)->extension());
+  EXPECT_EQ(extension_a()->id(), main_bar()->GetIdAt(0u));
+  EXPECT_EQ(extension_c()->id(), main_bar()->GetIdAt(1u));
+  EXPECT_EQ(extension_b()->id(), main_bar()->GetIdAt(2u));
   VerifyVisibleCount(3u);
 }
diff --git a/chrome/browser/ui/views/toolbar/chevron_menu_button.cc b/chrome/browser/ui/views/toolbar/chevron_menu_button.cc
index 207bcf6b..66d000fa 100644
--- a/chrome/browser/ui/views/toolbar/chevron_menu_button.cc
+++ b/chrome/browser/ui/views/toolbar/chevron_menu_button.cc
@@ -8,16 +8,16 @@
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/extension_action.h"
+#include "chrome/browser/extensions/extension_action_icon_factory.h"
 #include "chrome/browser/extensions/extension_context_menu_model.h"
 #include "chrome/browser/extensions/extension_toolbar_model.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
+#include "chrome/browser/ui/views/extensions/extension_action_view_controller.h"
 #include "chrome/browser/ui/views/toolbar/browser_action_view.h"
 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
-#include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension.h"
-#include "extensions/common/extension_set.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/button/label_button_border.h"
 #include "ui/views/controls/menu/menu_delegate.h"
@@ -33,31 +33,32 @@
 // is read from file system in another thread.
 // The IconUpdater will update the menu item view's icon when the browser
 // action's icon has been updated.
-class IconUpdater : public BrowserActionView::IconObserver {
+class IconUpdater : public ExtensionActionIconFactory::Observer {
  public:
-  IconUpdater(views::MenuItemView* menu_item_view, BrowserActionView* view)
+  IconUpdater(views::MenuItemView* menu_item_view,
+              ExtensionActionViewController* view_controller)
       : menu_item_view_(menu_item_view),
-        view_(view) {
+        view_controller_(view_controller) {
     DCHECK(menu_item_view);
-    DCHECK(view);
-    view->set_icon_observer(this);
+    DCHECK(view_controller);
+    view_controller->set_icon_observer(this);
   }
   virtual ~IconUpdater() {
-    view_->set_icon_observer(NULL);
+    view_controller_->set_icon_observer(NULL);
   }
 
   // BrowserActionView::IconObserver:
-  virtual void OnIconUpdated(const gfx::ImageSkia& icon) override {
-    menu_item_view_->SetIcon(icon);
+  virtual void OnIconUpdated() override {
+    menu_item_view_->SetIcon(view_controller_->GetIconWithBadge());
   }
 
  private:
   // The menu item view whose icon might be updated.
   views::MenuItemView* menu_item_view_;
 
-  // The view to be observed. When its icon changes, update the corresponding
-  // menu item view's icon.
-  BrowserActionView* view_;
+  // The view controller to be observed. When its icon changes, update the
+  // corresponding menu item view's icon.
+  ExtensionActionViewController* view_controller_;
 
   DISALLOW_COPY_AND_ASSIGN(IconUpdater);
 };
@@ -159,18 +160,19 @@
        i < browser_actions_container_->num_browser_actions(); ++i) {
     BrowserActionView* view =
         browser_actions_container_->GetBrowserActionViewAt(i);
+    ExtensionActionViewController* view_controller =
+        static_cast<ExtensionActionViewController*>(view->view_controller());
     views::MenuItemView* menu_item = menu_->AppendMenuItemWithIcon(
         command_id,
-        base::UTF8ToUTF16(view->extension()->name()),
-        view->GetIconWithBadge());
+        base::UTF8ToUTF16(view_controller->extension()->name()),
+        view_controller->GetIconWithBadge());
 
     // Set the tooltip for this item.
-    base::string16 tooltip = base::UTF8ToUTF16(
-        view->extension_action()->GetTitle(
-            view->view_controller()->GetCurrentTabId()));
-    menu_->SetTooltip(tooltip, command_id);
+    menu_->SetTooltip(
+        view_controller->GetTooltip(view->GetCurrentWebContents()),
+        command_id);
 
-    icon_updaters_.push_back(new IconUpdater(menu_item, view));
+    icon_updaters_.push_back(new IconUpdater(menu_item, view_controller));
 
     ++command_id;
   }
@@ -211,12 +213,12 @@
 bool ChevronMenuButton::MenuController::IsCommandEnabled(int id) const {
   BrowserActionView* view =
       browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1);
-  return view->IsEnabled(view->view_controller()->GetCurrentTabId());
+  return view->view_controller()->IsEnabled(view->GetCurrentWebContents());
 }
 
 void ChevronMenuButton::MenuController::ExecuteCommand(int id) {
   browser_actions_container_->GetBrowserActionViewAt(start_index_ + id - 1)->
-      view_controller()->ExecuteActionByUser();
+      view_controller()->ExecuteAction(true);
 }
 
 bool ChevronMenuButton::MenuController::ShowContextMenu(
@@ -226,13 +228,15 @@
     ui::MenuSourceType source_type) {
   BrowserActionView* view = browser_actions_container_->GetBrowserActionViewAt(
       start_index_ + id - 1);
-  if (!view->extension()->ShowConfigureContextMenus())
+  ExtensionActionViewController* view_controller =
+      static_cast<ExtensionActionViewController*>(view->view_controller());
+  if (!view_controller->extension()->ShowConfigureContextMenus())
     return false;
 
   scoped_refptr<ExtensionContextMenuModel> context_menu_contents =
-      new ExtensionContextMenuModel(view->extension(),
-                                    view->view_controller()->browser(),
-                                    view->view_controller());
+      new ExtensionContextMenuModel(view_controller->extension(),
+                                    view->browser(),
+                                    view_controller);
   views::MenuRunner context_menu_runner(context_menu_contents.get(),
                                         views::MenuRunner::HAS_MNEMONICS |
                                             views::MenuRunner::IS_NESTED |
@@ -316,12 +320,9 @@
 
   Profile* profile = browser_actions_container_->profile();
   // Move the extension in the model.
-  const extensions::Extension* extension =
-      extensions::ExtensionRegistry::Get(profile)->
-          enabled_extensions().GetByID(drop_data.id());
   extensions::ExtensionToolbarModel* toolbar_model =
       extensions::ExtensionToolbarModel::Get(profile);
-  toolbar_model->MoveExtensionIcon(extension, drop_index);
+  toolbar_model->MoveExtensionIcon(drop_data.id(), drop_index);
 
   // If the extension was moved to the overflow menu from the main bar, notify
   // the owner.
@@ -340,10 +341,8 @@
 void ChevronMenuButton::MenuController::WriteDragData(
     views::MenuItemView* sender, OSExchangeData* data) {
   size_t drag_index = IndexForId(sender->GetCommand());
-  const extensions::Extension* extension =
-      browser_actions_container_->GetBrowserActionViewAt(drag_index)->
-          extension();
-  BrowserActionDragData drag_data(extension->id(), drag_index);
+  BrowserActionDragData drag_data(
+      browser_actions_container_->GetIdAt(drag_index), drag_index);
   drag_data.Write(browser_actions_container_->profile(), data);
 }
 
diff --git a/chrome/browser/ui/views/toolbar/component_toolbar_actions_browsertest.cc b/chrome/browser/ui/views/toolbar/component_toolbar_actions_browsertest.cc
new file mode 100644
index 0000000..131f5c5
--- /dev/null
+++ b/chrome/browser/ui/views/toolbar/component_toolbar_actions_browsertest.cc
@@ -0,0 +1,142 @@
+// 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 "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
+#include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/toolbar/browser_action_view.h"
+#include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "extensions/common/feature_switch.h"
+#include "grit/theme_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+
+namespace {
+
+const char kMockId[] = "mock_action";
+
+class MockComponentAction : public ToolbarActionViewController {
+ public:
+  MockComponentAction() : click_count_(0u), id_(kMockId) {}
+  virtual ~MockComponentAction() {}
+
+  // ToolbarActionButtonController:
+  virtual const std::string& GetId() const override { return id_; }
+  virtual void SetDelegate(ToolbarActionViewDelegate* delegate) override {}
+  virtual gfx::Image GetIcon(content::WebContents* web_contents) override {
+    return ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+        IDR_BROWSER_ACTION);
+  }
+  virtual gfx::ImageSkia GetIconWithBadge() override {
+    return *GetIcon(nullptr).ToImageSkia();
+  }
+  virtual base::string16 GetAccessibleName(content::WebContents* web_contents)
+      const override {
+    return base::ASCIIToUTF16("Component Action");
+  }
+  virtual base::string16 GetTooltip(content::WebContents* web_contents)
+      const override {
+    return GetAccessibleName(web_contents);
+  }
+  virtual bool IsEnabled(content::WebContents* web_contents) const override {
+    return true;
+  }
+  virtual bool HasPopup(content::WebContents* web_contents) const override {
+    return true;
+  }
+  virtual void HidePopup() override {}
+  virtual gfx::NativeView GetPopupNativeView() override { return nullptr; }
+  virtual bool CanDrag() const override { return false; }
+  virtual bool IsMenuRunning() const override { return false; }
+  virtual bool ExecuteAction(bool by_user) override {
+    ++click_count_;
+    return false;
+  }
+
+  size_t click_count() const { return click_count_; }
+
+ private:
+  size_t click_count_;
+  std::string id_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockComponentAction);
+};
+
+class MockComponentToolbarActionsFactory
+    : public ComponentToolbarActionsFactory {
+ public:
+  MockComponentToolbarActionsFactory();
+  virtual ~MockComponentToolbarActionsFactory();
+
+  // ComponentToolbarActionsFactory:
+  virtual ScopedVector<ToolbarActionViewController>
+      GetComponentToolbarActions() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockComponentToolbarActionsFactory);
+};
+
+MockComponentToolbarActionsFactory::MockComponentToolbarActionsFactory() {
+  ComponentToolbarActionsFactory::SetTestingFactory(this);
+}
+
+MockComponentToolbarActionsFactory::~MockComponentToolbarActionsFactory() {
+  ComponentToolbarActionsFactory::SetTestingFactory(nullptr);
+}
+
+ScopedVector<ToolbarActionViewController>
+MockComponentToolbarActionsFactory::GetComponentToolbarActions() {
+  ScopedVector<ToolbarActionViewController> component_actions;
+  component_actions.push_back(new MockComponentAction());
+  return component_actions.Pass();
+}
+
+}  // namespace
+
+class ComponentToolbarActionsBrowserTest : public InProcessBrowserTest {
+ protected:
+  ComponentToolbarActionsBrowserTest() {}
+  virtual ~ComponentToolbarActionsBrowserTest() {}
+
+  virtual void SetUpCommandLine(base::CommandLine* command_line) override {
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+    enable_redesign_.reset(new extensions::FeatureSwitch::ScopedOverride(
+        extensions::FeatureSwitch::extension_action_redesign(), true));
+    mock_actions_factory_.reset(new MockComponentToolbarActionsFactory());
+  }
+
+ private:
+  scoped_ptr<extensions::FeatureSwitch::ScopedOverride> enable_redesign_;
+  scoped_ptr<MockComponentToolbarActionsFactory> mock_actions_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ComponentToolbarActionsBrowserTest);
+};
+
+// Test that Component Toolbar Actions appear in the browser actions container
+// and can receive click events properly.
+IN_PROC_BROWSER_TEST_F(ComponentToolbarActionsBrowserTest,
+                       ComponentToolbarActionsShowUpAndRespondToClicks) {
+  BrowserActionsContainer* browser_actions_container =
+      BrowserView::GetBrowserViewForBrowser(browser())
+          ->toolbar()->browser_actions();
+
+  // There should be only one component action view.
+  ASSERT_EQ(1u, browser_actions_container->num_browser_actions());
+
+  BrowserActionView* view =
+      browser_actions_container->GetBrowserActionViewAt(0u);
+  ASSERT_EQ(kMockId, view->view_controller()->GetId());
+  MockComponentAction* mock_component_action =
+      static_cast<MockComponentAction*>(view->view_controller());
+
+  // Test that clicking on the component action works.
+  EXPECT_EQ(0u, mock_component_action->click_count());
+  view->Activate();
+  EXPECT_EQ(1u, mock_component_action->click_count());
+}
diff --git a/chrome/browser/ui/views/extensions/extension_action_view_delegate.h b/chrome/browser/ui/views/toolbar/toolbar_action_view_delegate.h
similarity index 72%
rename from chrome/browser/ui/views/extensions/extension_action_view_delegate.h
rename to chrome/browser/ui/views/toolbar/toolbar_action_view_delegate.h
index 0b445c0..733b031 100644
--- a/chrome/browser/ui/views/extensions/extension_action_view_delegate.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_action_view_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_ACTION_VIEW_DELEGATE_H_
-#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_ACTION_VIEW_DELEGATE_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ACTION_VIEW_DELEGATE_H_
+#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ACTION_VIEW_DELEGATE_H_
 
 namespace content {
 class WebContents;
@@ -16,12 +16,12 @@
 class Widget;
 }
 
-class ExtensionActionViewController;
+class ToolbarActionViewController;
 
-// The view that surrounds an ExtensionAction and owns the
-// ExtensionActionViewController. Since different actions can subclass
+// The view that surrounds an ToolbarAction and owns the
+// ToolbarActionViewController. Since different actions can subclass
 // different views, we don't derive views::View directly here.
-class ExtensionActionViewDelegate {
+class ToolbarActionViewDelegate {
  public:
   // Returns |this| as a view. We need this because our subclasses implement
   // different kinds of views, and inheriting View here is a really bad idea.
@@ -37,9 +37,9 @@
   virtual views::Widget* GetParentForContextMenu() = 0;
 
   // In some cases (such as when an action is shown in a menu), a substitute
-  // ExtensionActionViewController should be used for showing popups. This
+  // ToolbarActionViewController should be used for showing popups. This
   // returns the preferred control.
-  virtual ExtensionActionViewController* GetPreferredPopupViewController() = 0;
+  virtual ToolbarActionViewController* GetPreferredPopupViewController() = 0;
 
   // Returns the reference view for the extension action's popup.
   virtual views::View* GetReferenceViewForPopup() = 0;
@@ -49,7 +49,7 @@
   virtual views::MenuButton* GetContextMenuButton() = 0;
 
   // Returns the current web contents.
-  virtual content::WebContents* GetCurrentWebContents() = 0;
+  virtual content::WebContents* GetCurrentWebContents() const = 0;
 
   // Hides whatever popup is active (even if it's not this one).
   virtual void HideActivePopup() = 0;
@@ -65,7 +65,7 @@
   virtual void CleanupPopup() {}
 
  protected:
-  virtual ~ExtensionActionViewDelegate() {}
+  virtual ~ToolbarActionViewDelegate() {}
 };
 
-#endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_ACTION_VIEW_DELEGATE_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ACTION_VIEW_DELEGATE_H_
diff --git a/chrome/browser/ui/views/toolbar/wrench_menu.cc b/chrome/browser/ui/views/toolbar/wrench_menu.cc
index d0c2cfd9..acb8976b 100644
--- a/chrome/browser/ui/views/toolbar/wrench_menu.cc
+++ b/chrome/browser/ui/views/toolbar/wrench_menu.cc
@@ -816,12 +816,12 @@
                                // so we get the taller menu style.
   PopulateMenu(root_, model);
 
-#if defined(DEBUG)
+#if !defined(NDEBUG)
   // Verify that the reserved command ID's for bookmarks menu are not used.
-  for (int i = WrenchMenuModel:kMinBookmarkCommandId;
+  for (int i = WrenchMenuModel::kMinBookmarkCommandId;
        i <= WrenchMenuModel::kMaxBookmarkCommandId; ++i)
     DCHECK(command_id_to_entry_.find(i) == command_id_to_entry_.end());
-#endif  // defined(DEBUG)
+#endif  // !defined(NDEBUG)
 
   int32 types = views::MenuRunner::HAS_MNEMONICS;
   if (for_drop()) {
diff --git a/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc b/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
index 3f75adc..7b8e080 100644
--- a/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
+++ b/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
@@ -27,13 +27,6 @@
 #include "ui/wm/core/window_modality_controller.h"
 #endif
 
-// TODO(wittman): this code should not depend on ash.
-#if defined(USE_ASH)
-#include "ash/ash_constants.h"
-#include "ash/frame/custom_frame_view_ash.h"
-#include "ash/shell.h"
-#endif
-
 using web_modal::NativeWebContentsModalDialog;
 using web_modal::SingleWebContentsDialogManager;
 using web_modal::SingleWebContentsDialogManagerDelegate;
@@ -83,9 +76,7 @@
     wm::SetWindowVisibilityAnimationType(
         widget->GetNativeWindow(),
         wm::WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE);
-#endif
 
-#if defined(USE_ASH)
     gfx::NativeView parent = platform_util::GetParent(widget->GetNativeView());
     wm::SetChildWindowVisibilityChangesAnimated(parent);
     // No animations should get performed on the window since that will re-order
@@ -143,7 +134,7 @@
     if (widget->widget_delegate() &&
         widget->widget_delegate()->GetInitiallyFocusedView())
       widget->widget_delegate()->GetInitiallyFocusedView()->RequestFocus();
-#if defined(USE_ASH)
+#if defined(USE_AURA)
     // We don't necessarily have a RootWindow yet.
     if (widget->GetNativeView()->GetRootWindow())
       widget->GetNativeView()->Focus();
@@ -221,7 +212,7 @@
   }
 
   void WidgetClosing(views::Widget* widget) {
-#if defined(USE_ASH)
+#if defined(USE_AURA)
     gfx::NativeView view = platform_util::GetParent(widget->GetNativeView());
     // Allow the parent to animate again.
     if (view && view->parent())
diff --git a/chrome/browser/ui/website_settings/website_settings.cc b/chrome/browser/ui/website_settings/website_settings.cc
index 632bff3..f19d2b0 100644
--- a/chrome/browser/ui/website_settings/website_settings.cc
+++ b/chrome/browser/ui/website_settings/website_settings.cc
@@ -337,7 +337,13 @@
 void WebsiteSettings::Init(Profile* profile,
                            const GURL& url,
                            const content::SSLStatus& ssl) {
-  if (url.SchemeIs(content::kChromeUIScheme)) {
+  bool isChromeUINativeScheme = false;
+#if defined(OS_ANDROID)
+  isChromeUINativeScheme = url.SchemeIs(chrome::kChromeUINativeScheme);
+#endif
+
+  if (url.SchemeIs(content::kChromeUIScheme) ||
+      url.SchemeIs(url::kAboutScheme) || isChromeUINativeScheme) {
     site_identity_status_ = SITE_IDENTITY_STATUS_INTERNAL_PAGE;
     site_identity_details_ =
         l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE);
diff --git a/chrome/browser/ui/website_settings/website_settings_ui.cc b/chrome/browser/ui/website_settings/website_settings_ui.cc
index 123a36d..4232aa7 100644
--- a/chrome/browser/ui/website_settings/website_settings_ui.cc
+++ b/chrome/browser/ui/website_settings/website_settings_ui.cc
@@ -257,6 +257,7 @@
   int resource_id = IDR_PAGEINFO_INFO;
   switch (status) {
     case WebsiteSettings::SITE_IDENTITY_STATUS_UNKNOWN:
+    case WebsiteSettings::SITE_IDENTITY_STATUS_INTERNAL_PAGE:
       break;
     case WebsiteSettings::SITE_IDENTITY_STATUS_CERT:
     case WebsiteSettings::SITE_IDENTITY_STATUS_EV_CERT:
@@ -297,6 +298,7 @@
   int resource_id = IDR_PAGEINFO_INFO;
   switch (status) {
     case WebsiteSettings::SITE_CONNECTION_STATUS_UNKNOWN:
+    case WebsiteSettings::SITE_CONNECTION_STATUS_INTERNAL_PAGE:
       break;
     case WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED:
       resource_id = IDR_PAGEINFO_GOOD;
@@ -337,25 +339,3 @@
   ResourceBundle& rb = ResourceBundle::GetSharedInstance();
   return rb.GetNativeImageNamed(GetFirstVisitIconID(first_visit));
 }
-
-// static
-int WebsiteSettingsUI::GetConnectionSummaryMessageID(
-    WebsiteSettings::SiteConnectionStatus status) {
-  switch (status) {
-    case WebsiteSettings::SITE_CONNECTION_STATUS_UNKNOWN:
-      return IDS_PAGE_INFO_UNENCRYPTED_CONNECTION_SUMMARY_TEXT;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED:
-      return IDS_PAGE_INFO_ENCRYPTED_CONNECTION_SUMMARY_TEXT;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_MIXED_CONTENT:
-      return IDS_PAGE_INFO_MIXED_CONTENT_CONNECTION_SUMMARY_TEXT;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_UNENCRYPTED:
-      return IDS_PAGE_INFO_UNENCRYPTED_CONNECTION_SUMMARY_TEXT;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED_ERROR:
-      return IDS_PAGE_INFO_UNENCRYPTED_CONNECTION_SUMMARY_TEXT;
-    case WebsiteSettings::SITE_CONNECTION_STATUS_INTERNAL_PAGE:
-      return IDS_PAGE_INFO_INTERNAL_PAGE;
-    default:
-      NOTREACHED();
-      return 0;
-  }
-}
diff --git a/chrome/browser/ui/website_settings/website_settings_ui.h b/chrome/browser/ui/website_settings/website_settings_ui.h
index 2bb2e33e..314b20a 100644
--- a/chrome/browser/ui/website_settings/website_settings_ui.h
+++ b/chrome/browser/ui/website_settings/website_settings_ui.h
@@ -154,10 +154,6 @@
   // Returns the icon to show along with the first visit information.
   static const gfx::Image& GetFirstVisitIcon(const base::string16& first_visit);
 
-  // Returns the ID of a short message for the given connection |status|.
-  static int GetConnectionSummaryMessageID(
-      WebsiteSettings::SiteConnectionStatus status);
-
   // Sets cookie information.
   virtual void SetCookieInfo(const CookieInfoList& cookie_info_list) = 0;
 
diff --git a/chrome/browser/ui/website_settings/website_settings_unittest.cc b/chrome/browser/ui/website_settings/website_settings_unittest.cc
index f979fcc6..7426a87 100644
--- a/chrome/browser/ui/website_settings/website_settings_unittest.cc
+++ b/chrome/browser/ui/website_settings/website_settings_unittest.cc
@@ -118,6 +118,8 @@
     EXPECT_CALL(*mock_ui, SetFirstVisit(base::string16()));
   }
 
+  void SetURL(std::string url) { url_ = GURL(url); }
+
   const GURL& url() const { return url_; }
   MockCertStore* cert_store() { return &cert_store_; }
   int cert_id() { return cert_id_; }
@@ -391,3 +393,23 @@
 
   infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0));
 }
+
+TEST_F(WebsiteSettingsTest, AboutBlankPage) {
+  SetURL("about:blank");
+  SetDefaultUIExpectations(mock_ui());
+  EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_INTERNAL_PAGE,
+            website_settings()->site_connection_status());
+  EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_INTERNAL_PAGE,
+            website_settings()->site_identity_status());
+  EXPECT_EQ(base::string16(), website_settings()->organization_name());
+}
+
+TEST_F(WebsiteSettingsTest, InternalPage) {
+  SetURL("chrome://bookmarks");
+  SetDefaultUIExpectations(mock_ui());
+  EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_INTERNAL_PAGE,
+            website_settings()->site_connection_status());
+  EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_INTERNAL_PAGE,
+            website_settings()->site_identity_status());
+  EXPECT_EQ(base::string16(), website_settings()->organization_name());
+}
diff --git a/chrome/browser/ui/webui/PRESUBMIT.py b/chrome/browser/ui/webui/PRESUBMIT.py
index 37e0c8c..ca67923 100644
--- a/chrome/browser/ui/webui/PRESUBMIT.py
+++ b/chrome/browser/ui/webui/PRESUBMIT.py
@@ -11,6 +11,6 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_chromeos_rel_swarming': set(['defaulttests']),
+      'linux_chromium_chromeos_rel': set(['defaulttests']),
     }
   }
diff --git a/chrome/browser/ui/webui/chromeos/DEPS b/chrome/browser/ui/webui/chromeos/DEPS
index 42a8243..22dfaa2 100644
--- a/chrome/browser/ui/webui/chromeos/DEPS
+++ b/chrome/browser/ui/webui/chromeos/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
+  "+components/login",
   "+components/user_manager",
 ]
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
index 8f7a79b..fbb6f64c 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
@@ -11,7 +11,7 @@
 #include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/strings/string16.h"
-#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.h"
+#include "components/login/base_screen_handler_utils.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_message_handler.h"
 #include "ui/gfx/native_widget_types.h"
@@ -115,13 +115,15 @@
 
   template<typename A1>
   void CallJS(const std::string& method, const A1& arg1) {
-    web_ui()->CallJavascriptFunction(FullMethodPath(method), MakeValue(arg1));
+    web_ui()->CallJavascriptFunction(FullMethodPath(method),
+                                     ::login::MakeValue(arg1));
   }
 
   template<typename A1, typename A2>
   void CallJS(const std::string& method, const A1& arg1, const A2& arg2) {
-    web_ui()->CallJavascriptFunction(FullMethodPath(method), MakeValue(arg1),
-                                     MakeValue(arg2));
+    web_ui()->CallJavascriptFunction(FullMethodPath(method),
+                                     ::login::MakeValue(arg1),
+                                     ::login::MakeValue(arg2));
   }
 
   template<typename A1, typename A2, typename A3>
@@ -130,9 +132,9 @@
               const A2& arg2,
               const A3& arg3) {
     web_ui()->CallJavascriptFunction(FullMethodPath(method),
-                                     MakeValue(arg1),
-                                     MakeValue(arg2),
-                                     MakeValue(arg3));
+                                     ::login::MakeValue(arg1),
+                                     ::login::MakeValue(arg2),
+                                     ::login::MakeValue(arg3));
   }
 
   template<typename A1, typename A2, typename A3, typename A4>
@@ -142,10 +144,10 @@
               const A3& arg3,
               const A4& arg4) {
     web_ui()->CallJavascriptFunction(FullMethodPath(method),
-                                     MakeValue(arg1),
-                                     MakeValue(arg2),
-                                     MakeValue(arg3),
-                                     MakeValue(arg4));
+                                     ::login::MakeValue(arg1),
+                                     ::login::MakeValue(arg2),
+                                     ::login::MakeValue(arg3),
+                                     ::login::MakeValue(arg4));
   }
 
   // Shortcut methods for adding WebUI callbacks.
@@ -162,7 +164,7 @@
     base::Callback<void()> callback =
         base::Bind(method, base::Unretained(static_cast<T*>(this)));
     web_ui()->RegisterMessageCallback(
-        name, base::Bind(&CallbackWrapper0, callback));
+        name, base::Bind(&::login::CallbackWrapper0, callback));
   }
 
   template<typename T, typename A1>
@@ -170,7 +172,7 @@
     base::Callback<void(A1)> callback =
         base::Bind(method, base::Unretained(static_cast<T*>(this)));
     web_ui()->RegisterMessageCallback(
-        name, base::Bind(&CallbackWrapper1<A1>, callback));
+        name, base::Bind(&::login::CallbackWrapper1<A1>, callback));
   }
 
   template<typename T, typename A1, typename A2>
@@ -179,7 +181,7 @@
     base::Callback<void(A1, A2)> callback =
         base::Bind(method, base::Unretained(static_cast<T*>(this)));
     web_ui()->RegisterMessageCallback(
-        name, base::Bind(&CallbackWrapper2<A1, A2>, callback));
+        name, base::Bind(&::login::CallbackWrapper2<A1, A2>, callback));
   }
 
   template<typename T, typename A1, typename A2, typename A3>
@@ -188,7 +190,7 @@
     base::Callback<void(A1, A2, A3)> callback =
         base::Bind(method, base::Unretained(static_cast<T*>(this)));
     web_ui()->RegisterMessageCallback(
-        name, base::Bind(&CallbackWrapper3<A1, A2, A3>, callback));
+        name, base::Bind(&::login::CallbackWrapper3<A1, A2, A3>, callback));
   }
 
   template<typename T, typename A1, typename A2, typename A3, typename A4>
@@ -197,7 +199,7 @@
     base::Callback<void(A1, A2, A3, A4)> callback =
         base::Bind(method, base::Unretained(static_cast<T*>(this)));
     web_ui()->RegisterMessageCallback(
-        name, base::Bind(&CallbackWrapper4<A1, A2, A3, A4>, callback));
+        name, base::Bind(&::login::CallbackWrapper4<A1, A2, A3, A4>, callback));
   }
 
   template <typename Method>
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.h b/chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.h
deleted file mode 100644
index abe4298..0000000
--- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 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_UI_WEBUI_CHROMEOS_LOGIN_BASE_SCREEN_HANDLER_UTILS_H_
-#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_BASE_SCREEN_HANDLER_UTILS_H_
-
-#include <cstddef>
-#include <string>
-
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/strings/string16.h"
-#include "base/values.h"
-
-namespace chromeos {
-
-typedef std::vector<std::string> StringList;
-typedef std::vector<base::string16> String16List;
-
-template<typename T>
-struct UnwrapConstRef {
-  typedef T Type;
-};
-
-template<typename T>
-struct UnwrapConstRef<const T&> {
-  typedef T Type;
-};
-
-bool ParseValue(const base::Value* value, bool* out_value);
-bool ParseValue(const base::Value* value, int* out_value);
-bool ParseValue(const base::Value* value, double* out_value);
-bool ParseValue(const base::Value* value, std::string* out_value);
-bool ParseValue(const base::Value* value, base::string16* out_value);
-bool ParseValue(const base::Value* value,
-                const base::DictionaryValue** out_value);
-bool ParseValue(const base::Value* value, StringList* out_value);
-bool ParseValue(const base::Value* value, String16List* out_value);
-
-template<typename T>
-inline bool GetArg(const base::ListValue* args, size_t index, T* out_value) {
-  const base::Value* value;
-  if (!args->Get(index, &value))
-    return false;
-  return ParseValue(value, out_value);
-}
-
-base::FundamentalValue MakeValue(bool v);
-base::FundamentalValue MakeValue(int v);
-base::FundamentalValue MakeValue(double v);
-base::StringValue MakeValue(const std::string& v);
-base::StringValue MakeValue(const base::string16& v);
-
-template<typename T>
-inline const T& MakeValue(const T& v) {
-  return v;
-}
-
-void CallbackWrapper0(base::Callback<void()> callback,
-                      const base::ListValue* args);
-
-template<typename A1>
-void CallbackWrapper1(base::Callback<void(A1)> callback,
-                      const base::ListValue* args) {
-  DCHECK(args);
-  DCHECK_EQ(1u, args->GetSize());
-  typename UnwrapConstRef<A1>::Type arg1;
-  if (!GetArg(args, 0, &arg1)) {
-    NOTREACHED();
-    return;
-  }
-  callback.Run(arg1);
-}
-
-template<typename A1, typename A2>
-void CallbackWrapper2(base::Callback<void(A1, A2)> callback,
-                      const base::ListValue* args) {
-  DCHECK(args);
-  DCHECK_EQ(2u, args->GetSize());
-  typename UnwrapConstRef<A1>::Type arg1;
-  typename UnwrapConstRef<A2>::Type arg2;
-  if (!GetArg(args, 0, &arg1) || !GetArg(args, 1, &arg2)) {
-    NOTREACHED();
-    return;
-  }
-  callback.Run(arg1, arg2);
-}
-
-template<typename A1, typename A2, typename A3>
-void CallbackWrapper3(base::Callback<void(A1, A2, A3)> callback,
-                      const base::ListValue* args) {
-  DCHECK(args);
-  DCHECK_EQ(3u, args->GetSize());
-  typename UnwrapConstRef<A1>::Type arg1;
-  typename UnwrapConstRef<A2>::Type arg2;
-  typename UnwrapConstRef<A3>::Type arg3;
-  if (!GetArg(args, 0, &arg1) ||
-      !GetArg(args, 1, &arg2) ||
-      !GetArg(args, 2, &arg3)) {
-    NOTREACHED();
-    return;
-  }
-  callback.Run(arg1, arg2, arg3);
-}
-
-template<typename A1, typename A2, typename A3, typename A4>
-void CallbackWrapper4(base::Callback<void(A1, A2, A3, A4)> callback,
-                      const base::ListValue* args) {
-  DCHECK(args);
-  DCHECK_EQ(4u, args->GetSize());
-  typename UnwrapConstRef<A1>::Type arg1;
-  typename UnwrapConstRef<A2>::Type arg2;
-  typename UnwrapConstRef<A3>::Type arg3;
-  typename UnwrapConstRef<A4>::Type arg4;
-  if (!GetArg(args, 0, &arg1) ||
-      !GetArg(args, 1, &arg2) ||
-      !GetArg(args, 2, &arg3) ||
-      !GetArg(args, 3, &arg4)) {
-    NOTREACHED();
-    return;
-  }
-  callback.Run(arg1, arg2, arg3, arg4);
-}
-
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_BASE_SCREEN_HANDLER_UTILS_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
index aacbd4b..dc5c4d8 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -333,6 +333,10 @@
 }
 
 void CoreOobeHandler::UpdateOobeUIVisibility() {
+#if defined(USE_ATHENA)
+  // Athena builds have their own way to display version so hide ours.
+  bool should_show_version = false;
+#else
   // Don't show version label on the stable channel by default.
   bool should_show_version = true;
   chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
@@ -340,6 +344,7 @@
       channel == chrome::VersionInfo::CHANNEL_BETA) {
     should_show_version = false;
   }
+#endif
   CallJS("showVersion", should_show_version);
   CallJS("showOobeUI", show_oobe_ui_);
   if (system::InputDeviceSettings::Get()->ForceKeyboardDrivenUINavigation())
diff --git a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc
new file mode 100644
index 0000000..0ec8a0ce
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc
@@ -0,0 +1,70 @@
+// 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/webui/chromeos/login/device_disabled_screen_handler.h"
+
+#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
+#include "chrome/grit/generated_resources.h"
+
+namespace {
+
+const char kJsScreenPath[] = "login.DeviceDisabledScreen";
+
+}  // namespace
+
+namespace chromeos {
+
+DeviceDisabledScreenHandler::DeviceDisabledScreenHandler()
+    : BaseScreenHandler(kJsScreenPath),
+      delegate_(NULL),
+      show_on_init_(false) {
+}
+
+DeviceDisabledScreenHandler::~DeviceDisabledScreenHandler() {
+  if (delegate_)
+    delegate_->OnActorDestroyed(this);
+}
+
+void DeviceDisabledScreenHandler::Show(const std::string& message) {
+  if (!page_is_ready()) {
+    show_on_init_ = true;
+    message_ = message;
+    return;
+  }
+
+  CallJS("setMessage", message);
+  ShowScreen(OobeUI::kScreenDeviceDisabled, NULL);
+}
+
+void DeviceDisabledScreenHandler::Hide() {
+  show_on_init_ = false;
+}
+
+void DeviceDisabledScreenHandler::SetDelegate(Delegate* delegate) {
+  delegate_ = delegate;
+  if (page_is_ready())
+    Initialize();
+}
+
+void DeviceDisabledScreenHandler::DeclareLocalizedValues(
+    LocalizedValuesBuilder* builder) {
+  builder->Add("deviceDisabledHeading", IDS_DEVICE_DISABLED_HEADING);
+  builder->Add("deviceDisabledExplanation", IDS_DEVICE_DISABLED_EXPLANATION);
+}
+
+void DeviceDisabledScreenHandler::Initialize() {
+  if (!page_is_ready() || !delegate_)
+    return;
+
+  if (show_on_init_) {
+    Show(message_);
+    show_on_init_ = false;
+  }
+}
+
+void DeviceDisabledScreenHandler::RegisterMessages() {
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h
new file mode 100644
index 0000000..f794b3c
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h
@@ -0,0 +1,50 @@
+// 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_WEBUI_CHROMEOS_LOGIN_DEVICE_DISABLED_SCREEN_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_DEVICE_DISABLED_SCREEN_HANDLER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/login/screens/device_disabled_screen_actor.h"
+#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
+
+namespace chromeos {
+
+// WebUI implementation of DeviceDisabledScreenActor.
+class DeviceDisabledScreenHandler : public DeviceDisabledScreenActor,
+                                    public BaseScreenHandler {
+ public:
+  DeviceDisabledScreenHandler();
+  ~DeviceDisabledScreenHandler() override;
+
+  // DeviceDisabledScreenActor:
+  void Show(const std::string& message) override;
+  void Hide() override;
+  void SetDelegate(Delegate* delegate) override;
+
+  // BaseScreenHandler:
+  void DeclareLocalizedValues(LocalizedValuesBuilder* builder) override;
+  void Initialize() override;
+
+ private:
+  // WebUIMessageHandler:
+  void RegisterMessages() override;
+
+  Delegate* delegate_;
+
+  // Indicates whether the screen should be shown right after initialization.
+  bool show_on_init_;
+
+  // The message to show to the user.
+  std::string message_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeviceDisabledScreenHandler);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_DEVICE_DISABLED_SCREEN_HANDLER_H_
+
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
index 7e423ef..1d78088b 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -17,11 +17,11 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/browsing_data_remover.h"
+#include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
 #include "chrome/browser/extensions/signin/gaia_auth_extension_loader.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/chromeos/login/authenticated_user_email_retriever.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/network/network_state.h"
@@ -116,6 +116,7 @@
       frame_error_(net::OK),
       network_state_informer_(network_state_informer),
       error_screen_actor_(error_screen_actor),
+      histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")),
       weak_ptr_factory_(this) {
   set_async_assets_load_id(OobeUI::kScreenOobeEnrollment);
   DCHECK(network_state_informer_.get());
@@ -146,8 +147,6 @@
 // EnrollmentScreenHandler, WebUIMessageHandler implementation --
 
 void EnrollmentScreenHandler::RegisterMessages() {
-  AddCallback("oauthEnrollRetrieveAuthenticatedUserEmail",
-              &EnrollmentScreenHandler::HandleRetrieveAuthenticatedUserEmail);
   AddCallback("oauthEnrollClose",
               &EnrollmentScreenHandler::HandleClose);
   AddCallback("oauthEnrollCompleteLogin",
@@ -497,6 +496,7 @@
                               &params,
                               base::Bind(&EnrollmentScreenHandler::DoShow,
                                          weak_ptr_factory_.GetWeakPtr()));
+    histogram_helper_->OnErrorShow(error_screen_actor_->error_state());
   }
 }
 
@@ -505,6 +505,7 @@
     ErrorScreenActor::ErrorReason reason) {
   if (IsEnrollmentScreenHiddenByError())
     error_screen_actor_->Hide();
+  histogram_helper_->OnErrorHide();
 }
 
 void EnrollmentScreenHandler::OnFrameError(
@@ -515,16 +516,6 @@
 }
 // EnrollmentScreenHandler, private -----------------------------
 
-void EnrollmentScreenHandler::HandleRetrieveAuthenticatedUserEmail(
-    double attempt_token) {
-  email_retriever_.reset(new AuthenticatedUserEmailRetriever(
-      base::Bind(&EnrollmentScreenHandler::CallJS<double, std::string>,
-                 base::Unretained(this),
-                 "setAuthenticatedUserEmail",
-                 attempt_token),
-      Profile::FromWebUI(web_ui())->GetRequestContext()));
-}
-
 void EnrollmentScreenHandler::HandleClose(const std::string& reason) {
   DCHECK(controller_);
 
@@ -598,6 +589,7 @@
   screen_data.SetString("management_domain", management_domain_);
 
   ShowScreen(OobeUI::kScreenOobeEnrollment, &screen_data);
+  histogram_helper_->OnScreenShow();
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
index fb9dfac..004ddb1e 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
@@ -24,7 +24,7 @@
 
 namespace chromeos {
 
-class AuthenticatedUserEmailRetriever;
+class ErrorScreensHistogramHelper;
 
 // WebUIMessageHandler implementation which handles events occurring on the
 // page, such as the user pressing the signin button.
@@ -74,7 +74,6 @@
 
  private:
   // Handlers for WebUI messages.
-  void HandleRetrieveAuthenticatedUserEmail(double attempt_token);
   void HandleClose(const std::string& reason);
   void HandleCompleteLogin(const std::string& user);
   void HandleRetry();
@@ -139,9 +138,6 @@
   // The callbacks to invoke after browsing data has been cleared.
   std::vector<base::Closure> auth_reset_callbacks_;
 
-  // Helper that retrieves the authenticated user's e-mail address.
-  scoped_ptr<AuthenticatedUserEmailRetriever> email_retriever_;
-
   // Latest enrollment frame error.
   net::Error frame_error_;
 
@@ -150,6 +146,8 @@
 
   ErrorScreenActor* error_screen_actor_;
 
+  scoped_ptr<ErrorScreensHistogramHelper> histogram_helper_;
+
   base::WeakPtrFactory<EnrollmentScreenHandler> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(EnrollmentScreenHandler);
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 4325274..4e4f710 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -267,7 +267,8 @@
                IDS_LOGIN_CONSUMER_MANAGEMENT_ENROLLMENT);
 
   // Strings used by the SAML fatal error dialog.
-  builder->Add("fatalErrorMessageNoEmail", IDS_LOGIN_FATAL_ERROR_NO_EMAIL);
+  builder->Add("fatalErrorMessageNoAccountDetails",
+               IDS_LOGIN_FATAL_ERROR_NO_ACCOUNT_DETAILS);
   builder->Add("fatalErrorMessageNoPassword",
                IDS_LOGIN_FATAL_ERROR_NO_PASSWORD);
   builder->Add("fatalErrorMessageVerificationFailed",
@@ -319,23 +320,29 @@
 }
 
 void GaiaScreenHandler::HandleCompleteAuthentication(
+    const std::string& gaia_id,
     const std::string& email,
     const std::string& password,
     const std::string& auth_code) {
   if (!Delegate())
     return;
+
+  DCHECK(!email.empty());
+  DCHECK(!gaia_id.empty());
   Delegate()->SetDisplayEmail(gaia::SanitizeEmail(email));
   UserContext user_context(email);
+  user_context.SetGaiaID(gaia_id);
   user_context.SetKey(Key(password));
   user_context.SetAuthCode(auth_code);
   Delegate()->CompleteLogin(user_context);
 }
 
-void GaiaScreenHandler::HandleCompleteLogin(const std::string& typed_email,
+void GaiaScreenHandler::HandleCompleteLogin(const std::string& gaia_id,
+                                            const std::string& typed_email,
                                             const std::string& password,
                                             bool using_saml) {
   if (!is_enrolling_consumer_management_) {
-    DoCompleteLogin(typed_email, password, using_saml);
+    DoCompleteLogin(gaia_id, typed_email, password, using_saml);
     return;
   }
 
@@ -354,6 +361,7 @@
   consumer_management_->SetOwner(owner_email,
                                  base::Bind(&GaiaScreenHandler::OnSetOwnerDone,
                                             weak_factory_.GetWeakPtr(),
+                                            gaia_id,
                                             typed_email,
                                             password,
                                             using_saml));
@@ -417,7 +425,8 @@
     SubmitLoginFormForTest();
 }
 
-void GaiaScreenHandler::OnSetOwnerDone(const std::string& typed_email,
+void GaiaScreenHandler::OnSetOwnerDone(const std::string& gaia_id,
+                                       const std::string& typed_email,
                                        const std::string& password,
                                        bool using_saml,
                                        bool success) {
@@ -433,10 +442,11 @@
     // We should continue logging in the user, as there's not much we can do
     // here.
   }
-  DoCompleteLogin(typed_email, password, using_saml);
+  DoCompleteLogin(gaia_id, typed_email, password, using_saml);
 }
 
-void GaiaScreenHandler::DoCompleteLogin(const std::string& typed_email,
+void GaiaScreenHandler::DoCompleteLogin(const std::string& gaia_id,
+                                        const std::string& typed_email,
                                         const std::string& password,
                                         bool using_saml) {
   if (!Delegate())
@@ -445,9 +455,12 @@
   if (using_saml && !using_saml_api_)
     RecordSAMLScrapingVerificationResultInHistogram(true);
 
+  DCHECK(!typed_email.empty());
+  DCHECK(!gaia_id.empty());
   const std::string sanitized_email = gaia::SanitizeEmail(typed_email);
   Delegate()->SetDisplayEmail(sanitized_email);
   UserContext user_context(sanitized_email);
+  user_context.SetGaiaID(gaia_id);
   user_context.SetKey(Key(password));
   user_context.SetAuthFlow(using_saml
                                ? UserContext::AUTH_FLOW_GAIA_WITH_SAML
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
index 4d5c411..c90428d9f 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -100,10 +100,12 @@
 
   // WebUI message handlers.
   void HandleFrameLoadingCompleted(int status);
-  void HandleCompleteAuthentication(const std::string& email,
+  void HandleCompleteAuthentication(const std::string& gaia_id,
+                                    const std::string& email,
                                     const std::string& password,
                                     const std::string& auth_code);
-  void HandleCompleteLogin(const std::string& typed_email,
+  void HandleCompleteLogin(const std::string& gaia_id,
+                           const std::string& typed_email,
                            const std::string& password,
                            bool using_saml);
 
@@ -114,13 +116,15 @@
   void HandleGaiaUIReady();
 
   // This is called when ConsumerManagementService::SetOwner() returns.
-  void OnSetOwnerDone(const std::string& typed_email,
+  void OnSetOwnerDone(const std::string& gaia_id,
+                      const std::string& typed_email,
                       const std::string& password,
                       bool using_saml,
                       bool success);
 
   // Really handles the complete login message.
-  void DoCompleteLogin(const std::string& typed_email,
+  void DoCompleteLogin(const std::string& gaia_id,
+                       const std::string& typed_email,
                        const std::string& password,
                        bool using_saml);
 
diff --git a/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.h
index bc4c2609..f01271a9 100644
--- a/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.h
@@ -7,8 +7,8 @@
 
 #include "base/macros.h"
 #include "chrome/browser/chromeos/login/screens/host_pairing_screen_actor.h"
-#include "chrome/browser/chromeos/login/screens/screen_context.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
+#include "components/login/screens/screen_context.h"
 
 namespace chromeos {
 
@@ -39,7 +39,7 @@
   bool js_context_ready_;
 
   // Caches context changes while JS part is not ready to receive messages.
-  ScreenContext context_cache_;
+  ::login::ScreenContext context_cache_;
 
   DISALLOW_COPY_AND_ASSIGN(HostPairingScreenHandler);
 };
diff --git a/chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc
index a3a722e92..12e5ae2 100644
--- a/chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc
+++ b/chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.cc
@@ -4,13 +4,17 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/inline_login_handler_chromeos.h"
 
+#include <string>
+
 #include "chrome/browser/chromeos/login/signin/oauth2_token_fetcher.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/signin/signin_promo.h"
 #include "chrome/common/url_constants.h"
+#include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_client.h"
 #include "components/signin/core/browser/signin_manager.h"
@@ -72,10 +76,20 @@
   dict->GetString("sessionIndex", &session_index);
   CHECK(!session_index.empty()) << "Session index is empty.";
 
-  std::string account_id;
-  dict->GetString("email", &account_id);
-  CHECK(!account_id.empty()) << "Account ID is empty.";
+  std::string email;
+  dict->GetString("email", &email);
+  CHECK(!email.empty()) << "Email is empty.";
 
+  std::string gaia_id;
+  dict->GetString("gaiaId", &gaia_id);
+  CHECK(!gaia_id.empty()) << "Gaia ID is empty.";
+
+  AccountTrackerService* account_tracker =
+      AccountTrackerServiceFactory::GetForProfile(profile);
+  account_tracker->SeedAccountInfo(gaia_id, email);
+
+  const std::string account_id =
+      account_tracker->PickAccountIdForAccount(gaia_id, email);
   oauth2_delegate_.reset(new InlineLoginUIOAuth2Delegate(web_ui(), account_id));
   net::URLRequestContextGetter* request_context =
       content::BrowserContext::GetStoragePartitionForSite(
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
index 317f6ca80..6e56f104 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -107,7 +107,7 @@
   if (selected_language_code_.empty()) {
     const StartupCustomizationDocument* startup_manifest =
         StartupCustomizationDocument::GetInstance();
-    HandleOnLanguageChanged(startup_manifest->initial_locale_default());
+    SetApplicationLocale(startup_manifest->initial_locale_default());
   }
 
   PrefService* prefs = g_browser_process->local_state();
@@ -209,11 +209,11 @@
 void NetworkScreenHandler::RegisterMessages() {
   AddCallback(kJsApiNetworkOnExit, &NetworkScreenHandler::HandleOnExit);
   AddCallback(kJsApiNetworkOnLanguageChanged,
-              &NetworkScreenHandler::HandleOnLanguageChanged);
+              &NetworkScreenHandler::SetApplicationLocale);
   AddCallback(kJsApiNetworkOnInputMethodChanged,
-              &NetworkScreenHandler::HandleOnInputMethodChanged);
+              &NetworkScreenHandler::SetInputMethod);
   AddCallback(kJsApiNetworkOnTimezoneChanged,
-              &NetworkScreenHandler::HandleOnTimezoneChanged);
+              &NetworkScreenHandler::SetTimezone);
 }
 
 
@@ -270,11 +270,24 @@
   AccessibilityManager::Get()->OnLocaleChanged();
 }
 
-void NetworkScreenHandler::HandleOnLanguageChanged(const std::string& locale) {
+std::string NetworkScreenHandler::GetApplicationLocale() const {
+  return locale_;
+}
+
+std::string NetworkScreenHandler::GetInputMethod() const {
+  return input_method_;
+}
+
+std::string NetworkScreenHandler::GetTimezone() const {
+  return timezone_;
+}
+
+void NetworkScreenHandler::SetApplicationLocale(const std::string& locale) {
   const std::string app_locale = g_browser_process->GetApplicationLocale();
   if (app_locale == locale)
     return;
 
+  locale_ = locale;
   base::WeakPtr<NetworkScreenHandler> weak_self =
       weak_ptr_factory_.GetWeakPtr();
   scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> callback_data(
@@ -289,19 +302,21 @@
                               callback.Pass());
 }
 
-void NetworkScreenHandler::HandleOnInputMethodChanged(const std::string& id) {
+void NetworkScreenHandler::SetInputMethod(const std::string& input_method) {
+  input_method_ = input_method;
   input_method::InputMethodManager::Get()
       ->GetActiveIMEState()
-      ->ChangeInputMethod(id, false /* show_message */);
+      ->ChangeInputMethod(input_method, false /* show_message */);
 }
 
-void NetworkScreenHandler::HandleOnTimezoneChanged(
+void NetworkScreenHandler::SetTimezone(
     const std::string& timezone_id) {
   std::string current_timezone_id;
   CrosSettings::Get()->GetString(kSystemTimezone, &current_timezone_id);
   if (current_timezone_id == timezone_id)
     return;
 
+  timezone_ = timezone_id;
   CrosSettings::Get()->SetString(kSystemTimezone, timezone_id);
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h
index 195afba..5e0d95f 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.h
@@ -32,6 +32,7 @@
   explicit NetworkScreenHandler(CoreOobeActor* core_oobe_actor);
   virtual ~NetworkScreenHandler();
 
+ private:
   // NetworkScreenActor implementation:
   virtual void SetDelegate(NetworkScreenActor::Delegate* screen) override;
   virtual void PrepareToShow() override;
@@ -42,6 +43,12 @@
   virtual void ShowConnectingStatus(bool connecting,
                                     const base::string16& network_id) override;
   virtual void EnableContinue(bool enabled) override;
+  virtual std::string GetApplicationLocale() const override;
+  virtual std::string GetInputMethod() const override;
+  virtual std::string GetTimezone() const override;
+  virtual void SetApplicationLocale(const std::string& locale) override;
+  virtual void SetInputMethod(const std::string& input_method) override;
+  virtual void SetTimezone(const std::string& timezone) override;
 
   // BaseScreenHandler implementation:
   virtual void DeclareLocalizedValues(LocalizedValuesBuilder* builder) override;
@@ -58,13 +65,9 @@
   // Reloads localized contents.
   void ReloadLocalizedContent();
 
- private:
   // Handles moving off the screen.
   void HandleOnExit();
 
-  // Handles change of the language.
-  void HandleOnLanguageChanged(const std::string& locale);
-
   // Async callback after ReloadResourceBundle(locale) completed.
   static void OnLanguageChangedCallback(
       scoped_ptr<NetworkScreenHandlerOnLanguageChangedCallbackData> context,
@@ -72,12 +75,6 @@
       const std::string& loaded_locale,
       const bool success);
 
-  // Handles change of the input method.
-  void HandleOnInputMethodChanged(const std::string& id);
-
-  // Handles change of the time zone
-  void HandleOnTimezoneChanged(const std::string& timezone);
-
   // Callback when the system timezone settings is changed.
   void OnSystemTimezoneChanged();
 
@@ -100,6 +97,10 @@
   // The exact language code selected by user in the menu.
   std::string selected_language_code_;
 
+  std::string locale_;
+  std::string input_method_;
+  std::string timezone_;
+
   base::WeakPtrFactory<NetworkScreenHandler> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkScreenHandler);
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 7427cce..9e3ac1c 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -23,6 +23,7 @@
 #include "chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h"
@@ -178,6 +179,7 @@
 const char OobeUI::kScreenFatalError[] = "fatal-error";
 const char OobeUI::kScreenControllerPairing[] = "controller-pairing";
 const char OobeUI::kScreenHostPairing[] = "host-pairing";
+const char OobeUI::kScreenDeviceDisabled[] = "device-disabled";
 
 OobeUI::OobeUI(content::WebUI* web_ui, const GURL& url)
     : WebUIController(web_ui),
@@ -193,6 +195,10 @@
       wrong_hwid_screen_actor_(NULL),
       auto_enrollment_check_screen_actor_(NULL),
       supervised_user_creation_screen_actor_(NULL),
+      app_launch_splash_screen_actor_(NULL),
+      controller_pairing_screen_actor_(NULL),
+      host_pairing_screen_actor_(NULL),
+      device_disabled_screen_actor_(NULL),
       error_screen_handler_(NULL),
       signin_screen_handler_(NULL),
       terms_of_service_screen_actor_(NULL),
@@ -316,6 +322,11 @@
     AddScreenHandler(handler);
   }
 
+  DeviceDisabledScreenHandler* device_disabled_screen_handler =
+      new DeviceDisabledScreenHandler;
+  device_disabled_screen_actor_ = device_disabled_screen_handler;
+  AddScreenHandler(device_disabled_screen_handler);
+
   // Initialize KioskAppMenuHandler. Note that it is NOT a screen handler.
   kiosk_app_menu_handler_ = new KioskAppMenuHandler(network_state_informer_);
   web_ui->AddMessageHandler(kiosk_app_menu_handler_);
@@ -405,6 +416,10 @@
   return host_pairing_screen_actor_;
 }
 
+DeviceDisabledScreenActor* OobeUI::GetDeviceDisabledScreenActor() {
+  return device_disabled_screen_actor_;
+}
+
 UserImageScreenActor* OobeUI::GetUserImageScreenActor() {
   return user_image_screen_actor_;
 }
@@ -480,6 +495,7 @@
   screen_names_[SCREEN_FATAL_ERROR] = kScreenFatalError;
   screen_names_[SCREEN_OOBE_CONTROLLER_PAIRING] = kScreenControllerPairing;
   screen_names_[SCREEN_OOBE_HOST_PAIRING] = kScreenHostPairing;
+  screen_names_[SCREEN_DEVICE_DISABLED] = kScreenDeviceDisabled;
 
   screen_ids_.clear();
   for (size_t i = 0; i < screen_names_.size(); ++i)
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
index 281760b2..ee73c32 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -24,6 +24,7 @@
 class AppLaunchSplashScreenActor;
 class BaseScreenHandler;
 class ControllerPairingScreenActor;
+class DeviceDisabledScreenActor;
 class ErrorScreenHandler;
 class HostPairingScreenActor;
 class KioskAppMenuHandler;
@@ -85,6 +86,7 @@
   static const char kScreenHIDDetection[];
   static const char kScreenControllerPairing[];
   static const char kScreenHostPairing[];
+  static const char kScreenDeviceDisabled[];
 
   OobeUI(content::WebUI* web_ui, const GURL& url);
   virtual ~OobeUI();
@@ -115,6 +117,7 @@
   virtual ControllerPairingScreenActor* GetControllerPairingScreenActor()
       override;
   virtual HostPairingScreenActor* GetHostPairingScreenActor() override;
+  DeviceDisabledScreenActor* GetDeviceDisabledScreenActor() override;
 
   // Collects localized strings from the owned handlers.
   void GetLocalizedStrings(base::DictionaryValue* localized_strings);
@@ -197,6 +200,7 @@
   AppLaunchSplashScreenActor* app_launch_splash_screen_actor_;
   ControllerPairingScreenActor* controller_pairing_screen_actor_;
   HostPairingScreenActor* host_pairing_screen_actor_;
+  DeviceDisabledScreenActor* device_disabled_screen_actor_;
 
   // Reference to ErrorScreenHandler that handles error screen
   // requests and forward calls from native code to JS side.
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index d8565b1..463373d 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/bind_helpers.h"
 #include "base/debug/trace_event.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -29,6 +28,7 @@
 #include "chrome/browser/chromeos/boot_times_loader.h"
 #include "chrome/browser/chromeos/input_method/input_method_util.h"
 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
+#include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
 #include "chrome/browser/chromeos/login/hwid_checker.h"
 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
 #include "chrome/browser/chromeos/login/screens/core_oobe_actor.h"
@@ -46,7 +46,6 @@
 #include "chrome/browser/io_thread.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/easy_unlock_service.h"
-#include "chrome/browser/ui/webui/chromeos/login/authenticated_user_email_retriever.h"
 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
 #include "chrome/browser/ui/webui/chromeos/login/native_window_delegate.h"
@@ -72,7 +71,6 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "google_apis/gaia/gaia_auth_util.h"
-#include "net/url_request/url_request_context_getter.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 #include "ui/base/webui/web_ui_util.h"
 
@@ -255,6 +253,7 @@
                              ->CapsLockIsEnabled()),
       gaia_screen_handler_(gaia_screen_handler),
       oobe_ui_observer_added_(false),
+      histogram_helper_(new ErrorScreensHistogramHelper("Signin")),
       weak_factory_(this) {
   DCHECK(network_state_informer_.get());
   DCHECK(error_screen_actor_);
@@ -431,6 +430,7 @@
   }
   gaia_screen_handler_->PopulateEmail(email);
   ShowImpl();
+  histogram_helper_->OnScreenShow();
 }
 
 void SigninScreenHandler::ShowRetailModeLoginSpinner() {
@@ -688,6 +688,7 @@
     params.SetString("lastNetworkType", network_type);
     error_screen_actor_->SetUIState(ErrorScreen::UI_STATE_SIGNIN);
     error_screen_actor_->Show(OobeUI::SCREEN_GAIA_SIGNIN, &params);
+    histogram_helper_->OnErrorShow(error_screen_actor_->error_state());
   }
 }
 
@@ -698,6 +699,7 @@
     return;
 
   error_screen_actor_->Hide();
+  histogram_helper_->OnErrorHide();
 
   // Forces a reload for Gaia screen on hiding error message.
   if (IsGaiaVisible() || IsGaiaHiddenByError())
@@ -772,8 +774,6 @@
               &SigninScreenHandler::HandleUpdateOfflineLogin);
   AddCallback("focusPod", &SigninScreenHandler::HandleFocusPod);
   AddCallback("hardlockPod", &SigninScreenHandler::HandleHardlockPod);
-  AddCallback("retrieveAuthenticatedUserEmail",
-              &SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail);
   AddCallback("getPublicSessionKeyboardLayouts",
               &SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts);
   AddCallback("cancelConsumerManagementEnrollment",
@@ -1024,10 +1024,6 @@
   user_context.SetKey(Key(secret));
   user_context.GetKey()->SetLabel(key_label);
 
-  // TODO(tbarzic): Handle empty secret. The delegate will end up ignoring login
-  // attempt if the key is not set, and the UI will remain disabled.
-  DCHECK(!secret.empty());
-
   delegate_->Login(user_context, SigninSpecifics());
 }
 
@@ -1380,17 +1376,6 @@
   service->SetHardlockState(EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
 }
 
-void SigninScreenHandler::HandleRetrieveAuthenticatedUserEmail(
-    double attempt_token) {
-  // TODO(antrim) : move GaiaSigninScreen dependency to GaiaSigninScreen.
-  email_retriever_.reset(new AuthenticatedUserEmailRetriever(
-      base::Bind(&SigninScreenHandler::CallJS<double, std::string>,
-                 base::Unretained(this),
-                 "login.GaiaSigninScreen.setAuthenticatedUserEmail",
-                 attempt_token),
-      Profile::FromWebUI(web_ui())->GetRequestContext()));
-}
-
 void SigninScreenHandler::HandleGetPublicSessionKeyboardLayouts(
     const std::string& user_id,
     const std::string& locale) {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index 86f1709..22277e3d 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -46,9 +46,9 @@
 
 namespace chromeos {
 
-class AuthenticatedUserEmailRetriever;
 class CaptivePortalWindowProxy;
 class CoreOobeActor;
+class ErrorScreensHistogramHelper;
 class GaiaScreenHandler;
 class NativeWindowDelegate;
 class SupervisedUserCreationScreenHandler;
@@ -394,7 +394,6 @@
   void HandleFocusPod(const std::string& user_id);
   void HandleHardlockPod(const std::string& user_id);
   void HandleLaunchKioskApp(const std::string& app_id, bool diagnostic_mode);
-  void HandleRetrieveAuthenticatedUserEmail(double attempt_token);
   void HandleGetPublicSessionKeyboardLayouts(const std::string& user_id,
                                              const std::string& locale);
   void HandleCancelConsumerManagementEnrollment();
@@ -519,9 +518,6 @@
   // TODO(ygorshenin@): remove this dependency.
   GaiaScreenHandler* gaia_screen_handler_;
 
-  // Helper that retrieves the authenticated user's e-mail address.
-  scoped_ptr<AuthenticatedUserEmailRetriever> email_retriever_;
-
   // Maximized mode controller delegate.
   scoped_ptr<TouchViewControllerDelegate> max_mode_delegate_;
 
@@ -537,6 +533,8 @@
   // True if SigninScreenHandler has already been added to OobeUI observers.
   bool oobe_ui_observer_added_;
 
+  scoped_ptr<ErrorScreensHistogramHelper> histogram_helper_;
+
   base::WeakPtrFactory<SigninScreenHandler> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SigninScreenHandler);
diff --git a/chrome/browser/ui/webui/downloads_ui_browsertest.js b/chrome/browser/ui/webui/downloads_ui_browsertest.js
index 4329f4f9..dfa5e89 100644
--- a/chrome/browser/ui/webui/downloads_ui_browsertest.js
+++ b/chrome/browser/ui/webui/downloads_ui_browsertest.js
@@ -13,14 +13,6 @@
   testDone();
 });
 
-// Test that clicking <a href=#> doesn't actually go to #.
-TEST_F('BaseDownloadsWebUITest', 'PoundLinkClicksDontChangeUrl', function() {
-  assertEquals(this.browsePreload, document.location.href);
-  document.querySelector('.clear-all-link').click();
-  assertEquals(this.browsePreload, document.location.href);
-  testDone();
-});
-
 /**
  * Fixture for Downloads WebUI testing when deletions are prohibited.
  * @extends {BaseDownloadsWebUITest}
diff --git a/chrome/browser/ui/webui/extensions/extension_loader_handler.cc b/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
index 6dc631b4..bf47de24 100644
--- a/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
@@ -219,27 +219,14 @@
 
 void ExtensionLoaderHandler::LoadUnpackedExtensionImpl(
     const base::FilePath& file_path) {
-  if (EndsWith(file_path.AsUTF16Unsafe(),
-               base::ASCIIToUTF16(".zip"),
-               false /* case insensitive */)) {
-    scoped_refptr<ZipFileInstaller> installer = ZipFileInstaller::Create(
-        ExtensionSystem::Get(profile_)->extension_service());
+  scoped_refptr<UnpackedInstaller> installer = UnpackedInstaller::Create(
+      ExtensionSystem::Get(profile_)->extension_service());
 
-    // We do our own error handling, so we don't want a load failure to trigger
-    // a dialog.
-    installer->set_be_noisy_on_failure(false);
+  // We do our own error handling, so we don't want a load failure to trigger
+  // a dialog.
+  installer->set_be_noisy_on_failure(false);
 
-    installer->LoadFromZipFile(file_path);
-  } else {
-    scoped_refptr<UnpackedInstaller> installer = UnpackedInstaller::Create(
-        ExtensionSystem::Get(profile_)->extension_service());
-
-    // We do our own error handling, so we don't want a load failure to trigger
-    // a dialog.
-    installer->set_be_noisy_on_failure(false);
-
-    installer->Load(file_path);
-  }
+  installer->Load(file_path);
 }
 
 void ExtensionLoaderHandler::OnLoadFailure(
diff --git a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
index d4da0c4..bc97cf2 100644
--- a/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_settings_handler.cc
@@ -108,10 +108,23 @@
 using content::WebContents;
 
 namespace {
+
 const char kAppsDeveloperToolsExtensionId[] =
     "ohmmkhmmmpcnpikjeljgnaoabkaalbgc";
+
+// Returns true if the extensions page should display the new-style extension
+// info dialog. If false, display the old permissions dialog.
+bool ShouldDisplayExtensionInfoDialog() {
+#if defined(OS_MACOSX)
+  return false;
+#else
+  return !base::CommandLine::ForCurrentProcess()->HasSwitch(
+      extensions::switches::kDisableExtensionInfoDialog);
+#endif
 }
 
+}  // namespace
+
 namespace extensions {
 
 ExtensionPage::ExtensionPage(const GURL& url,
@@ -289,6 +302,8 @@
                              OptionsPageInfo::ShouldOpenInTab(extension));
   extension_data->SetString("optionsPageHref",
                             OptionsPageInfo::GetOptionsPage(extension).spec());
+  extension_data->SetBoolean("enableExtensionInfoDialog",
+                             ShouldDisplayExtensionInfoDialog());
 
   // Add dependent extensions.
   base::ListValue* dependents_list = new base::ListValue;
@@ -537,8 +552,7 @@
       l10n_util::GetStringUTF16(IDS_EXTENSIONS_RELOAD_UNPACKED));
   source->AddString("extensionSettingsOptions",
       l10n_util::GetStringUTF16(IDS_EXTENSIONS_OPTIONS_LINK));
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableExtensionInfoDialog)) {
+  if (ShouldDisplayExtensionInfoDialog()) {
     source->AddString("extensionSettingsPermissions",
                       l10n_util::GetStringUTF16(IDS_EXTENSIONS_INFO_LINK));
   } else {
@@ -1199,8 +1213,7 @@
 
   // Show the new-style extensions dialog when the flag is set. The flag cannot
   // be set on Mac platforms.
-  if (CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableExtensionInfoDialog)) {
+  if (ShouldDisplayExtensionInfoDialog()) {
     UMA_HISTOGRAM_ENUMERATION("Apps.AppInfoDialog.Launches",
                               AppInfoLaunchSource::FROM_EXTENSIONS_PAGE,
                               AppInfoLaunchSource::NUM_LAUNCH_SOURCES);
diff --git a/chrome/browser/ui/webui/history_ui.cc b/chrome/browser/ui/webui/history_ui.cc
index 568a8b3..cff1769 100644
--- a/chrome/browser/ui/webui/history_ui.cc
+++ b/chrome/browser/ui/webui/history_ui.cc
@@ -173,6 +173,8 @@
   source->AddLocalizedString("cancel", IDS_CANCEL);
   source->AddLocalizedString("deleteConfirm",
                              IDS_HISTORY_DELETE_PRIOR_VISITS_CONFIRM_BUTTON);
+  source->AddLocalizedString("bookmarked", IDS_HISTORY_ENTRY_BOOKMARKED);
+  source->AddLocalizedString("entrySummary", IDS_HISTORY_ENTRY_SUMMARY);
   source->AddBoolean("isFullHistorySyncEnabled",
                      WebHistoryServiceFactory::GetForProfile(profile) != NULL);
   source->AddBoolean("groupByDomain",
diff --git a/chrome/browser/ui/webui/metrics_handler.cc b/chrome/browser/ui/webui/metrics_handler.cc
index 99fb592..58cc102 100644
--- a/chrome/browser/ui/webui/metrics_handler.cc
+++ b/chrome/browser/ui/webui/metrics_handler.cc
@@ -10,12 +10,9 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/metrics/metric_event_duration_details.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
 #include "chrome/common/ntp_logging_events.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
@@ -94,8 +91,6 @@
 
   base::TimeDelta duration =
       base::TimeTicks::Now() - core_tab_helper->new_tab_start_time();
-  MetricEventDurationDetails details(event_name,
-      static_cast<int>(duration.InMilliseconds()));
 
   if (event_name == "Tab.NewTabScriptStart") {
     UMA_HISTOGRAM_TIMES("Tab.NewTabScriptStart", duration);
@@ -109,10 +104,6 @@
   } else {
     NOTREACHED();
   }
-  content::NotificationService::current()->Notify(
-      chrome::NOTIFICATION_METRIC_EVENT_DURATION,
-      content::Source<WebContents>(tab),
-      content::Details<MetricEventDurationDetails>(&details));
 }
 
 void MetricsHandler::HandleLogMouseover(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
index 3f7c258..7ee614d 100644
--- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -81,7 +81,11 @@
 
 // The URL for the Learn More page shown on guest session new tab.
 const char kLearnMoreGuestSessionUrl[] =
+#if defined(OS_CHROMEOS)
     "https://www.google.com/support/chromeos/bin/answer.py?answer=1057090";
+#else
+    "https://support.google.com/chrome/answer/95464#guest";
+#endif
 
 std::string SkColorToRGBAString(SkColor color) {
   // We convert the alpha using DoubleToString because StringPrintf will use
@@ -343,7 +347,6 @@
 
 #if defined(OS_CHROMEOS)
   guest_tab_ids = IDR_GUEST_SESSION_TAB_HTML;
-  guest_tab_link = kLearnMoreGuestSessionUrl;
 
   policy::BrowserPolicyConnectorChromeOS* connector =
       g_browser_process->platform_part()->browser_policy_connector_chromeos();
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index b8cf8c1..cc0428a 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -1039,8 +1039,6 @@
   // On Chrome OS we use different UI for multi-profiles.
   return false;
 #else
-  if (helper::GetDesktopType(web_ui()) != chrome::HOST_DESKTOP_TYPE_NATIVE)
-    return false;
   Profile* profile = Profile::FromWebUI(web_ui());
   if (profile->IsGuestSession())
     return false;
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
index a57ae5e..cb37d18 100644
--- a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
@@ -142,7 +142,6 @@
   for (size_t i = 0; i < new_list->GetSize(); ++i) {
     std::string whitelisted_user;
     new_list->GetString(i, &whitelisted_user);
-    LOG(ERROR) << gaia::ExtractDomainName(whitelisted_user);
     if (gaia::ExtractDomainName(whitelisted_user) ==
         chromeos::login::kSupervisedUserDomain) {
       new_list->Remove(i, NULL);
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc
index e5f02cc..48a8751 100644
--- a/chrome/browser/ui/webui/options/content_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -323,7 +323,7 @@
     { "plugins_header", IDS_PLUGIN_HEADER },
     { "pluginsAsk", IDS_PLUGIN_ASK_RADIO },
     { "pluginsAllow", IDS_PLUGIN_LOAD_RADIO },
-    { "pluginsBlock", IDS_PLUGIN_NOLOAD_RADIO },
+    { "pluginsBlock", IDS_PLUGIN_ASK_MENU_RADIO },
     { "disableIndividualPlugins", IDS_PLUGIN_SELECTIVE_DISABLE },
     // Pop-ups filter.
     { "popupsTabLabel", IDS_POPUP_TAB_LABEL },
@@ -388,6 +388,8 @@
     // Multiple automatic downloads
     { "multipleAutomaticDownloadsTabLabel",
       IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL },
+    { "multiple-automatic-downloads_header",
+      IDS_AUTOMATIC_DOWNLOADS_TAB_LABEL },
     { "multipleAutomaticDownloadsAllow",
       IDS_AUTOMATIC_DOWNLOADS_ALLOW_RADIO },
     { "multipleAutomaticDownloadsAsk",
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
index a3d56d6..b54ac9d 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc
@@ -33,10 +33,10 @@
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_error_controller.h"
-#include "components/signin/core/browser/signin_oauth_helper.h"
 #include "components/signin/core/common/profile_management_switches.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_ui.h"
+#include "google_apis/gaia/gaia_auth_consumer.h"
 #include "google_apis/gaia/gaia_auth_fetcher.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "google_apis/gaia/gaia_constants.h"
@@ -45,7 +45,7 @@
 
 namespace {
 
-class InlineSigninHelper : public SigninOAuthHelper::Consumer {
+class InlineSigninHelper : public GaiaAuthConsumer {
  public:
   InlineSigninHelper(
       base::WeakPtr<InlineLoginHandlerImpl> handler,
@@ -53,6 +53,7 @@
       Profile* profile,
       const GURL& current_url,
       const std::string& email,
+      const std::string& gaia_id,
       const std::string& password,
       const std::string& session_index,
       const std::string& signin_scoped_device_id,
@@ -60,19 +61,17 @@
       bool confirm_untrusted_signin);
 
  private:
-  // Overriden from SigninOAuthHelper::Consumer.
-  void OnSigninOAuthInformationAvailable(
-      const std::string& email,
-      const std::string& display_email,
-      const std::string& refresh_token) override;
-  void OnSigninOAuthInformationFailure(
-      const GoogleServiceAuthError& error) override;
+  // Overridden from GaiaAuthConsumer.
+  void OnClientOAuthSuccess(const ClientOAuthResult& result) override;
+  void OnClientOAuthFailure(const GoogleServiceAuthError& error)
+      override;
 
-  SigninOAuthHelper signin_oauth_helper_;
+  GaiaAuthFetcher gaia_auth_fetcher_;
   base::WeakPtr<InlineLoginHandlerImpl> handler_;
   Profile* profile_;
   GURL current_url_;
   std::string email_;
+  std::string gaia_id_;
   std::string password_;
   std::string session_index_;
   bool choose_what_to_sync_;
@@ -87,29 +86,29 @@
     Profile* profile,
     const GURL& current_url,
     const std::string& email,
+    const std::string& gaia_id,
     const std::string& password,
     const std::string& session_index,
     const std::string& signin_scoped_device_id,
     bool choose_what_to_sync,
     bool confirm_untrusted_signin)
-    : signin_oauth_helper_(getter, session_index, signin_scoped_device_id,
-                           this),
+    : gaia_auth_fetcher_(this, GaiaConstants::kChromeSource, getter),
       handler_(handler),
       profile_(profile),
       current_url_(current_url),
       email_(email),
+      gaia_id_(gaia_id),
       password_(password),
       session_index_(session_index),
       choose_what_to_sync_(choose_what_to_sync),
       confirm_untrusted_signin_(confirm_untrusted_signin) {
   DCHECK(profile_);
   DCHECK(!email_.empty());
+  gaia_auth_fetcher_.StartCookieForOAuthLoginTokenExchangeWithDeviceId(
+      session_index, signin_scoped_device_id);
 }
 
-void InlineSigninHelper::OnSigninOAuthInformationAvailable(
-    const std::string& email,
-    const std::string& display_email,
-    const std::string& refresh_token) {
+void InlineSigninHelper::OnClientOAuthSuccess(const ClientOAuthResult& result) {
   content::WebContents* contents = NULL;
   Browser* browser = NULL;
   if (handler_) {
@@ -121,11 +120,19 @@
       AboutSigninInternalsFactory::GetForProfile(profile_);
   about_signin_internals->OnRefreshTokenReceived("Successful");
 
+  AccountTrackerService* account_tracker =
+      AccountTrackerServiceFactory::GetForProfile(profile_);
+  std::string account_id =
+      account_tracker->PickAccountIdForAccount(gaia_id_, email_);
+
+  // Prime the account tracker with this combination of gaia id/display email.
+  account_tracker->SeedAccountInfo(gaia_id_, email_);
+
   signin::Source source = signin::GetSourceForPromoURL(current_url_);
 
   std::string primary_email =
       SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername();
-  if (gaia::AreEmailsSame(email, primary_email) &&
+  if (gaia::AreEmailsSame(email_, primary_email) &&
       source == signin::SOURCE_REAUTH &&
       switches::IsNewProfileManagement()) {
     chrome::SetLocalAuthCredentials(profile_, password_);
@@ -133,14 +140,8 @@
 
   if (source == signin::SOURCE_AVATAR_BUBBLE_ADD_ACCOUNT ||
       source == signin::SOURCE_REAUTH) {
-    // TODO(rogerta): the javascript code will need to pass in the gaia-id
-    // of the account instead of the email when chrome uses gaia-id as key.
-    DCHECK_EQ(AccountTrackerService::MIGRATION_NOT_STARTED,
-              AccountTrackerServiceFactory::GetForProfile(profile_)->
-                  GetMigrationState());
-    const std::string account_id = gaia::CanonicalizeEmail(email);
     ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->
-        UpdateCredentials(account_id, refresh_token);
+        UpdateCredentials(account_id, result.refresh_token);
 
     if (signin::IsAutoCloseEnabledInURL(current_url_)) {
       // Close the gaia sign in tab via a task to make sure we aren't in the
@@ -192,7 +193,7 @@
     bool start_signin =
         !OneClickSigninHelper::HandleCrossAccountError(
             profile_, "",
-            email, password_, refresh_token,
+            email_, password_, result.refresh_token,
             OneClickSigninHelper::AUTO_ACCEPT_EXPLICIT,
             source, start_mode,
             base::Bind(&InlineLoginHandlerImpl::SyncStarterCallback,
@@ -202,7 +203,7 @@
       // OneClickSigninSyncStarter will delete itself once the job is done.
       new OneClickSigninSyncStarter(
           profile_, browser,
-          email, password_, refresh_token,
+          account_id, password_, result.refresh_token,
           start_mode,
           contents,
           confirmation_required,
@@ -214,7 +215,7 @@
   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
 }
 
-void InlineSigninHelper::OnSigninOAuthInformationFailure(
+void InlineSigninHelper::OnClientOAuthFailure(
   const GoogleServiceAuthError& error) {
   if (handler_)
     handler_->HandleLoginError(error.ToString());
@@ -312,6 +313,11 @@
   dict->GetString("password", &password_string16);
   std::string password(base::UTF16ToASCII(password_string16));
 
+  base::string16 gaia_id_string16;
+  dict->GetString("gaiaId", &gaia_id_string16);
+  DCHECK(!gaia_id_string16.empty());
+  std::string gaia_id = base::UTF16ToASCII(gaia_id_string16);
+
   // When doing a SAML sign in, this email check may result in a false
   // positive.  This happens when the user types one email address in the
   // gaia sign in page, but signs in to a different account in the SAML sign in
@@ -378,10 +384,12 @@
   about_signin_internals->OnAuthenticationResultReceived(
       "GAIA Auth Successful");
 
+  GURL partition_url(switches::IsEnableWebviewBasedSignin() ?
+      "chrome-guest://chrome-signin/?" :
+      chrome::kChromeUIChromeSigninURL);
   content::StoragePartition* partition =
       content::BrowserContext::GetStoragePartitionForSite(
-          contents->GetBrowserContext(),
-          GURL(chrome::kChromeUIChromeSigninURL));
+          contents->GetBrowserContext(), partition_url);
 
   SigninClient* signin_client =
       ChromeSigninClientFactory::GetForProfile(Profile::FromWebUI(web_ui()));
@@ -390,7 +398,7 @@
   // InlineSigninHelper will delete itself.
   new InlineSigninHelper(GetWeakPtr(), partition->GetURLRequestContext(),
                          Profile::FromWebUI(web_ui()), current_url,
-                         email, password, session_index,
+                         email, gaia_id, password, session_index,
                          signin_scoped_device_id, choose_what_to_sync,
                          confirm_untrusted_signin_);
 
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc
index cf3ec66..9fd5b1e 100644
--- a/chrome/browser/ui/webui/signin/inline_login_ui.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/sessions/session_tab_helper.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/chromium_strings.h"
+#include "components/signin/core/common/profile_management_switches.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
@@ -28,9 +29,13 @@
   source->OverrideContentSecurityPolicyObjectSrc("object-src *;");
   source->SetJsonPath("strings.js");
 
-  source->SetDefaultResource(IDR_INLINE_LOGIN_HTML);
+  bool is_webview_signin_enabled = switches::IsEnableWebviewBasedSignin();
+  source->SetDefaultResource(is_webview_signin_enabled ?
+      IDR_NEW_INLINE_LOGIN_HTML : IDR_INLINE_LOGIN_HTML);
   source->AddResourcePath("inline_login.css", IDR_INLINE_LOGIN_CSS);
   source->AddResourcePath("inline_login.js", IDR_INLINE_LOGIN_JS);
+  source->AddResourcePath("gaia_auth_host.js", is_webview_signin_enabled ?
+      IDR_GAIA_AUTH_AUTHENTICATOR_JS : IDR_GAIA_AUTH_HOST_JS);
 
   source->AddLocalizedString("title", IDS_CHROME_SIGNIN_TITLE);
   return source;
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
index 4673f304..d609641 100644
--- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
+++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
@@ -480,6 +480,15 @@
                   state == GoogleServiceAuthError::ACCOUNT_DELETED ||
                   state == GoogleServiceAuthError::ACCOUNT_DISABLED ||
                   state == GoogleServiceAuthError::WEB_LOGIN_REQUIRED);
+
+  // If the password was correct, the user must have changed it since the
+  // profile was locked.  Save the password to streamline future unlocks.
+  if (success) {
+    DCHECK(!password_attempt_.empty());
+    chrome::SetLocalAuthCredentials(authenticating_profile_index_,
+                                    password_attempt_);
+  }
+
   bool offline = (state == GoogleServiceAuthError::CONNECTION_FAILED ||
                   state == GoogleServiceAuthError::SERVICE_UNAVAILABLE ||
                   state == GoogleServiceAuthError::REQUEST_CANCELED);
diff --git a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
index 2be813b..2c4c273 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
@@ -25,11 +25,6 @@
   ~TestScreen() override {}
 
   // Overridden from gfx::Screen:
-  bool IsDIPEnabled() override {
-    NOTREACHED();
-    return false;
-  }
-
   gfx::Point GetCursorScreenPoint() override {
     NOTREACHED();
     return gfx::Point();
diff --git a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc
index 08879de..c49e0d3 100644
--- a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc
+++ b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc
@@ -78,7 +78,8 @@
     // Since we're calling this before setting up zoom_subscription_ below we
     // don't need to worry that host_zoom_dictionary is indirectly affected
     // by calls to HostZoomMap::SetZoomLevelForHost().
-    ExtractPerHostZoomLevels(host_zoom_dictionary);
+    ExtractPerHostZoomLevels(host_zoom_dictionary,
+                             true /* sanitize_partition_host_zoom_levels */);
   }
   zoom_subscription_ = host_zoom_map_->AddZoomLevelChangedCallback(base::Bind(
       &ChromeZoomLevelPrefs::OnZoomLevelChanged, base::Unretained(this)));
@@ -144,8 +145,11 @@
     host_zoom_dictionary->SetDoubleWithoutPathExpansion(change.host, level);
 }
 
+// TODO(wjmaclean): Remove the dictionary_path once the migration code is
+// removed. crbug.com/420643
 void ChromeZoomLevelPrefs::ExtractPerHostZoomLevels(
-    const base::DictionaryValue* host_zoom_dictionary) {
+    const base::DictionaryValue* host_zoom_dictionary,
+    bool sanitize_partition_host_zoom_levels) {
   std::vector<std::string> keys_to_remove;
   scoped_ptr<base::DictionaryValue> host_zoom_dictionary_copy(
       host_zoom_dictionary->DeepCopyWithoutEmptyChildren());
@@ -174,6 +178,14 @@
     host_zoom_map_->SetZoomLevelForHost(host, zoom_level);
   }
 
+  // We don't bother sanitizing non-partition dictionaries as they will be
+  // discarded in the migration process. Note: since the structure of partition
+  // per-host zoom level dictionaries is different from the legacy profile
+  // per-host zoom level dictionaries, the following code will fail if run
+  // on the legacy dictionaries.
+  if (!sanitize_partition_host_zoom_levels)
+    return;
+
   // Sanitize prefs to remove entries that match the default zoom level and/or
   // have an empty host.
   {
diff --git a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.h b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.h
index 8506eb7..ff0eb849 100644
--- a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.h
+++ b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.h
@@ -53,7 +53,8 @@
       const base::Closure& callback);
 
   void ExtractPerHostZoomLevels(
-      const base::DictionaryValue* host_zoom_dictionary);
+      const base::DictionaryValue* host_zoom_dictionary,
+      bool sanitize_partition_host_zoom_levels);
 
  private:
   // This is a callback function that receives notifications from HostZoomMap
diff --git a/chrome/browser/undo/bookmark_undo_service_test.cc b/chrome/browser/undo/bookmark_undo_service_test.cc
index 9d5fa3c9..54976e70 100644
--- a/chrome/browser/undo/bookmark_undo_service_test.cc
+++ b/chrome/browser/undo/bookmark_undo_service_test.cc
@@ -39,7 +39,7 @@
 void BookmarkUndoServiceTest::SetUp() {
   profile_.reset(new TestingProfile);
   profile_->CreateBookmarkModel(true);
-  test::WaitForBookmarkModelToLoad(GetModel());
+  bookmarks::test::WaitForBookmarkModelToLoad(GetModel());
 }
 
 BookmarkModel* BookmarkUndoServiceTest::GetModel() {
diff --git a/chrome/browser/unload_browsertest.cc b/chrome/browser/unload_browsertest.cc
index 4481adf..2378f02 100644
--- a/chrome/browser/unload_browsertest.cc
+++ b/chrome/browser/unload_browsertest.cc
@@ -11,8 +11,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/net/url_request_mock_util.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -20,6 +18,8 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/web_dev_style/css_checker.py b/chrome/browser/web_dev_style/css_checker.py
index e27097db..bfc0507 100644
--- a/chrome/browser/web_dev_style/css_checker.py
+++ b/chrome/browser/web_dev_style/css_checker.py
@@ -93,10 +93,10 @@
     def close_brace_on_new_line(line):
       # Ignore single frames in a @keyframe, i.e. 0% { margin: 50px; }
       frame_reg = re.compile(r"""
-          \s*\d+%\s*{       # 50% {
-          \s*[\w-]+:        # rule:
-          (\s*[\w-]+)+\s*;  # value;
-          \s*}\s*           # }""",
+          \s*(from|to|\d+%)\s*{  # 50% {
+          \s*[\w-]+:             # rule:
+          (\s*[\w-]+)+\s*;       # value;
+          \s*}\s*                # }""",
           re.VERBOSE)
       return ('}' in line and re.search(r'[^ }]', line) and
               not frame_reg.match(line))
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 2b6197b4..835be51 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -587,6 +587,8 @@
             'chrome_strings_grd',
             'chrome_version_java',
             'profile_account_management_metrics_java',
+            'content_setting_java',
+            'content_settings_type_java',
             'page_info_connection_type_java',
             'profile_sync_service_model_type_selection_java',
             'resource_id_java',
@@ -632,6 +634,24 @@
           ],
         },
         {
+          # GN: //chrome:content_setting_javagen
+          'target_name': 'content_setting_java',
+          'type': 'none',
+          'variables': {
+            'source_file': '../components/content_settings/core/common/content_settings.h',
+          },
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
+        },
+        {
+          # GN: //chrome:content_settings_type_javagen
+          'target_name': 'content_settings_type_java',
+          'type': 'none',
+          'variables': {
+            'source_file': '../components/content_settings/core/common/content_settings_types.h',
+          },
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
+        },
+        {
           # GN: //chrome:page_info_connection_type_javagen
           'target_name': 'page_info_connection_type_java',
           'type': 'none',
diff --git a/chrome/chrome_android_paks.gypi b/chrome/chrome_android_paks.gypi
index 622ff61f..90f0238 100644
--- a/chrome/chrome_android_paks.gypi
+++ b/chrome/chrome_android_paks.gypi
@@ -104,10 +104,10 @@
       ['icu_use_data_file_flag==1', {
         'chrome_android_pak_input_resources': [
           '<(PRODUCT_DIR)/icudtl.dat',
-	],
+        ],
         'chrome_android_pak_output_resources': [
           '<(chrome_android_pak_output_folder)/icudtl.dat',
-	],
+        ],
       }],
     ],
   },
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index ddd5176..031eb5b 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -82,6 +82,8 @@
       'browser/android/omnibox/omnibox_prerender.h',
       'browser/android/password_ui_view_android.cc',
       'browser/android/password_ui_view_android.h',
+      'browser/android/preferences/pref_service_bridge.cc',
+      'browser/android/preferences/pref_service_bridge.h',
       'browser/android/profiles/profile_downloader_android.cc',
       'browser/android/profiles/profile_downloader_android.h',
       'browser/android/provider/blocking_ui_thread_async_request.cc',
@@ -677,7 +679,6 @@
       'browser/metrics/field_trial_synchronizer.h',
       'browser/metrics/google_update_metrics_provider_win.cc',
       'browser/metrics/google_update_metrics_provider_win.h',
-      'browser/metrics/metric_event_duration_details.h',
       'browser/metrics/metrics_reporting_state.cc',
       'browser/metrics/metrics_reporting_state.h',
       'browser/metrics/metrics_service_accessor.cc',
@@ -1106,6 +1107,8 @@
       'browser/services/gcm/gcm_profile_service_factory.h',
       'browser/services/gcm/push_messaging_application_id.cc',
       'browser/services/gcm/push_messaging_application_id.h',
+      'browser/services/gcm/push_messaging_constants.cc',
+      'browser/services/gcm/push_messaging_constants.h',
       'browser/services/gcm/push_messaging_infobar_delegate.cc',
       'browser/services/gcm/push_messaging_infobar_delegate.h',
       'browser/services/gcm/push_messaging_permission_context.cc',
@@ -1116,6 +1119,9 @@
       'browser/services/gcm/push_messaging_service_impl.h',
       'browser/sessions/base_session_service.cc',
       'browser/sessions/base_session_service.h',
+      'browser/sessions/base_session_service_delegate_impl.cc',
+      'browser/sessions/base_session_service_delegate_impl.h',
+      'browser/sessions/base_session_service_delegate.h',
       'browser/sessions/session_data_deleter.cc',
       'browser/sessions/session_data_deleter.h',
       'browser/sessions/session_restore_android.cc',
@@ -2741,6 +2747,7 @@
       'android/java/src/org/chromium/chrome/browser/omnibox/OmniboxViewUtil.java',
       'android/java/src/org/chromium/chrome/browser/password_manager/PasswordAuthenticationManager.java',
       'android/java/src/org/chromium/chrome/browser/PasswordUIView.java',
+      'android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java',
       'android/java/src/org/chromium/chrome/browser/profiles/MostVisitedSites.java',
       'android/java/src/org/chromium/chrome/browser/profiles/Profile.java',
       'android/java/src/org/chromium/chrome/browser/profiles/ProfileDownloader.java',
@@ -2753,7 +2760,6 @@
       'android/java/src/org/chromium/chrome/browser/signin/OAuth2TokenService.java',
       'android/java/src/org/chromium/chrome/browser/signin/SigninManager.java',
       'android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java',
-      'android/java/src/org/chromium/chrome/browser/tabmodel/TabModelBase.java',
       'android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java',
       'android/java/src/org/chromium/chrome/browser/Tab.java',
       'android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java',
@@ -2894,6 +2900,11 @@
       'sources': [
         '<@(chrome_browser_undo_sources)',
       ],
+      'includes': [
+        # Disable LTO due to ELF section name out of range
+        # crbug.com/422251
+        '../build/android/disable_lto.gypi',
+      ],
       'conditions': [
         ['OS != "ios"', {
           'dependencies': [
@@ -2909,7 +2920,7 @@
             '../components/components.gyp:password_manager_content_browser',
             '../components/components.gyp:power',
             '../components/components.gyp:precache_content',
-            '../components/components.gyp:sessions',
+            '../components/components.gyp:sessions_content',
             '../components/components.gyp:storage_monitor',
             '../components/components.gyp:translate_content_browser',
             '../components/components.gyp:url_matcher',
@@ -3507,17 +3518,13 @@
           'includes': [ '../build/jni_generator.gypi' ],
         },
         {
-          # GN: //chrome/android:activity_type_ids_javagen
+          # GN: //chrome/android:chrome_android_java_enums_srcjar
           'target_name': 'activity_type_ids_java',
           'type': 'none',
-          'sources': [
-            'android/java/ActivityTypeIds.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/chrome/browser',
-            'template_deps': ['browser/android/activity_type_id_list.h'],
+            'source_file': 'browser/android/activity_type_ids.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
         {
           # GN: //chrome/android:app_banner_metrics_ids_javagen
@@ -3546,56 +3553,40 @@
           'includes': [ '../build/android/java_cpp_template.gypi' ],
         },
         {
-          # GN: //chrome/android/profile_account_management_metrics_javagen
+          # GN: //chrome/android:chrome_android_java_enums_srcjar
           'target_name': 'profile_account_management_metrics_java',
           'type': 'none',
-          'sources': [
-            'android/java/ProfileAccountManagementMetrics.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/chrome/browser/profiles',
-            'template_deps': ['browser/profiles/profile_metrics_list.h'],
+            'source_file': 'browser/profiles/profile_metrics.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
         {
-          # GN: //chrome/android:profile_sync_service_model_type_selection_javagen
+          # GN: //chrome/android:chrome_android_java_enums_srcjar
           'target_name': 'profile_sync_service_model_type_selection_java',
           'type': 'none',
-          'sources': [
-            'android/java/ModelTypeSelection.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/chrome/browser/sync',
-            'template_deps': ['browser/sync/profile_sync_service_model_type_selection_android.h'],
+            'source_file': 'browser/sync/profile_sync_service_android.cc',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
         {
-          # GN: //chrome/android:toolbar_model_security_levels_javagen
+          # GN: //chrome/android:chrome_android_java_enums_srcjar
           'target_name': 'toolbar_model_security_levels_java',
           'type': 'none',
-          'sources': [
-            'android/java/ToolbarModelSecurityLevel.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/chrome/browser/ui/toolbar',
-            'template_deps': ['browser/ui/toolbar/toolbar_model_security_level_list.h'],
+            'source_file': 'browser/ui/toolbar/toolbar_model.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
         {
-          # GN: //chrome/android:tab_load_status_javagen
+          # GN: //chrome/android:chrome_android_java_enums_srcjar
           'target_name': 'tab_load_status_java',
           'type': 'none',
-          'sources': [
-            'android/java/TabLoadStatus.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/chrome/browser',
-            'template_deps': ['browser/android/tab_load_status.h'],
+            'source_file': 'browser/android/tab_android.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
       ],
     },],
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index 0d05511..551ef681 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -213,8 +213,6 @@
         'browser/chromeos/extensions/device_local_account_external_policy_loader.h',
         'browser/chromeos/extensions/device_local_account_management_policy_provider.cc',
         'browser/chromeos/extensions/device_local_account_management_policy_provider.h',
-        'browser/chromeos/extensions/echo_private_api.cc',
-        'browser/chromeos/extensions/echo_private_api.h',
         'browser/chromeos/extensions/extension_system_event_observer.cc',
         'browser/chromeos/extensions/extension_system_event_observer.h',
         'browser/chromeos/extensions/external_cache.cc',
@@ -429,8 +427,8 @@
         'browser/chromeos/login/auth/auth_prewarmer.h',
         'browser/chromeos/login/auth/chrome_cryptohome_authenticator.cc',
         'browser/chromeos/login/auth/chrome_cryptohome_authenticator.h',
-        'browser/chromeos/login/auth/login_performer.cc',
-        'browser/chromeos/login/auth/login_performer.h',
+        'browser/chromeos/login/auth/chrome_login_performer.cc',
+        'browser/chromeos/login/auth/chrome_login_performer.h',
         'browser/chromeos/login/chrome_restart_request.cc',
         'browser/chromeos/login/chrome_restart_request.h',
         'browser/chromeos/login/default_pinned_apps_field_trial.cc',
@@ -443,10 +441,14 @@
         'browser/chromeos/login/easy_unlock/easy_unlock_get_keys_operation.h',
         'browser/chromeos/login/easy_unlock/easy_unlock_key_manager.cc',
         'browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h',
+        'browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc',
+        'browser/chromeos/login/easy_unlock/easy_unlock_metrics.h',
         'browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.cc',
         'browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.h',
         'browser/chromeos/login/easy_unlock/easy_unlock_types.cc',
         'browser/chromeos/login/easy_unlock/easy_unlock_types.h',
+        'browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc',
+        'browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.h',
         'browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc',
         'browser/chromeos/login/enrollment/auto_enrollment_check_screen.h',
         'browser/chromeos/login/enrollment/auto_enrollment_check_screen_actor.h',
@@ -455,6 +457,8 @@
         'browser/chromeos/login/enrollment/enrollment_screen.cc',
         'browser/chromeos/login/enrollment/enrollment_screen.h',
         'browser/chromeos/login/enrollment/enrollment_screen_actor.h',
+        'browser/chromeos/login/error_screens_histogram_helper.cc',
+        'browser/chromeos/login/error_screens_histogram_helper.h',
         'browser/chromeos/login/existing_user_controller.cc',
         'browser/chromeos/login/existing_user_controller.h',
         'browser/chromeos/login/help_app_launcher.cc',
@@ -492,6 +496,9 @@
         'browser/chromeos/login/screens/controller_pairing_screen_actor.cc',
         'browser/chromeos/login/screens/controller_pairing_screen_actor.h',
         'browser/chromeos/login/screens/core_oobe_actor.h',
+        'browser/chromeos/login/screens/device_disabled_screen.cc',
+        'browser/chromeos/login/screens/device_disabled_screen.h',
+        'browser/chromeos/login/screens/device_disabled_screen_actor.h',
         'browser/chromeos/login/screens/error_screen.cc',
         'browser/chromeos/login/screens/error_screen.h',
         'browser/chromeos/login/screens/error_screen_actor.cc',
@@ -521,8 +528,6 @@
         'browser/chromeos/login/screens/reset_screen.cc',
         'browser/chromeos/login/screens/reset_screen.h',
         'browser/chromeos/login/screens/reset_screen_actor.h',
-        'browser/chromeos/login/screens/screen_context.cc',
-        'browser/chromeos/login/screens/screen_context.h',
         'browser/chromeos/login/screens/screen_flow.h',
         'browser/chromeos/login/screens/screen_observer.h',
         'browser/chromeos/login/screens/terms_of_service_screen.cc',
@@ -1050,6 +1055,7 @@
         '../chromeos/chromeos.gyp:power_manager_proto',
         '../chromeos/ime/input_method.gyp:gencode',
         '../components/components.gyp:cloud_policy_proto',
+        '../components/components.gyp:login',
         '../components/components.gyp:onc_component',
         '../components/components.gyp:ownership',
         '../components/components.gyp:pairing',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 92b1dea..9e92ec9 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -53,8 +53,6 @@
       'browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.h',
       'browser/ui/android/tab_model/tab_model.cc',
       'browser/ui/android/tab_model/tab_model.h',
-      'browser/ui/android/tab_model/tab_model_base.cc',
-      'browser/ui/android/tab_model/tab_model_base.h',
       'browser/ui/android/tab_model/tab_model_jni_bridge.cc',
       'browser/ui/android/tab_model/tab_model_jni_bridge.h',
       'browser/ui/android/tab_model/tab_model_list.cc',
@@ -68,25 +66,11 @@
       'browser/ui/android/website_settings_popup_legacy_android.h',
       'browser/ui/android/window_android_helper.cc',
       'browser/ui/android/window_android_helper.h',
-      'browser/ui/app_list/app_list_service.h',
       'browser/ui/app_list/app_list_util.cc',
       'browser/ui/app_list/app_list_util.h',
-      'browser/ui/app_modal_dialogs/app_modal_dialog.cc',
-      'browser/ui/app_modal_dialogs/app_modal_dialog.h',
-      'browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc',
-      'browser/ui/app_modal_dialogs/app_modal_dialog_queue.h',
-      'browser/ui/app_modal_dialogs/javascript_app_modal_dialog.cc',
-      'browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h',
+      # All other browser/ui/app_list files go in chrome_browser_ui_app_list_sources.
       'browser/ui/app_modal_dialogs/javascript_dialog_manager.cc',
       'browser/ui/app_modal_dialogs/javascript_dialog_manager.h',
-      'browser/ui/app_modal_dialogs/native_app_modal_dialog.h',
-      'browser/ui/apps/app_info_dialog.h',
-      'browser/ui/apps/apps_metro_handler_win.cc',
-      'browser/ui/apps/apps_metro_handler_win.h',
-      'browser/ui/apps/chrome_app_window_client.cc',
-      'browser/ui/apps/chrome_app_window_client.h',
-      'browser/ui/apps/directory_access_confirmation_dialog.cc',
-      'browser/ui/apps/directory_access_confirmation_dialog.h',
       'browser/ui/autofill/autofill_dialog_controller.cc',
       'browser/ui/autofill/autofill_dialog_controller.h',
       'browser/ui/autofill/autofill_dialog_models.cc',
@@ -460,8 +444,8 @@
       'browser/ui/cocoa/find_bar/find_bar_text_field.mm',
       'browser/ui/cocoa/find_bar/find_bar_text_field_cell.h',
       'browser/ui/cocoa/find_bar/find_bar_text_field_cell.mm',
-      'browser/ui/cocoa/find_bar/find_bar_view.h',
-      'browser/ui/cocoa/find_bar/find_bar_view.mm',
+      'browser/ui/cocoa/find_bar/find_bar_view_cocoa.h',
+      'browser/ui/cocoa/find_bar/find_bar_view_cocoa.mm',
       'browser/ui/cocoa/first_run_bubble_controller.h',
       'browser/ui/cocoa/first_run_bubble_controller.mm',
       'browser/ui/cocoa/first_run_dialog.h',
@@ -729,14 +713,14 @@
       'browser/ui/cocoa/themed_window.mm',
       'browser/ui/cocoa/toolbar/back_forward_menu_controller.h',
       'browser/ui/cocoa/toolbar/back_forward_menu_controller.mm',
-      'browser/ui/cocoa/toolbar/reload_button.h',
-      'browser/ui/cocoa/toolbar/reload_button.mm',
-      'browser/ui/cocoa/toolbar/toolbar_button.h',
-      'browser/ui/cocoa/toolbar/toolbar_button.mm',
+      'browser/ui/cocoa/toolbar/reload_button_cocoa.h',
+      'browser/ui/cocoa/toolbar/reload_button_cocoa.mm',
+      'browser/ui/cocoa/toolbar/toolbar_button_cocoa.h',
+      'browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm',
       'browser/ui/cocoa/toolbar/toolbar_controller.h',
       'browser/ui/cocoa/toolbar/toolbar_controller.mm',
-      'browser/ui/cocoa/toolbar/toolbar_view.h',
-      'browser/ui/cocoa/toolbar/toolbar_view.mm',
+      'browser/ui/cocoa/toolbar/toolbar_view_cocoa.h',
+      'browser/ui/cocoa/toolbar/toolbar_view_cocoa.mm',
       'browser/ui/cocoa/toolbar/wrench_toolbar_button_cell.h',
       'browser/ui/cocoa/toolbar/wrench_toolbar_button_cell.mm',
       'browser/ui/cocoa/translate/translate_bubble_controller.h',
@@ -956,14 +940,14 @@
       'browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.h',
       'browser/ui/webui/chromeos/login/base_screen_handler.cc',
       'browser/ui/webui/chromeos/login/base_screen_handler.h',
-      'browser/ui/webui/chromeos/login/base_screen_handler_utils.cc',
-      'browser/ui/webui/chromeos/login/base_screen_handler_utils.h',
       'browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc',
       'browser/ui/webui/chromeos/login/controller_pairing_screen_handler.h',
       'browser/ui/webui/chromeos/login/core_oobe_handler.cc',
       'browser/ui/webui/chromeos/login/core_oobe_handler.h',
       'browser/ui/webui/chromeos/login/demo_mode_detector.cc',
       'browser/ui/webui/chromeos/login/demo_mode_detector.h',
+      'browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc',
+      'browser/ui/webui/chromeos/login/device_disabled_screen_handler.h',
       'browser/ui/webui/chromeos/login/enrollment_screen_handler.cc',
       'browser/ui/webui/chromeos/login/enrollment_screen_handler.h',
       'browser/ui/webui/chromeos/login/error_screen_handler.cc',
@@ -1132,8 +1116,6 @@
       'browser/ui/window_sizer/window_sizer_mac.mm',
       'browser/ui/zoom/chrome_zoom_level_prefs.cc',
       'browser/ui/zoom/chrome_zoom_level_prefs.h',
-      'browser/ui/zoom/zoom_controller.cc',
-      'browser/ui/zoom/zoom_controller.h',
       'browser/ui/zoom/zoom_event_manager.cc',
       'browser/ui/zoom/zoom_event_manager.h',
       'browser/ui/zoom/zoom_observer.h',
@@ -1141,16 +1123,6 @@
     # Note that we assume app list is enabled on all views builds, so the
     # views-specific app list files are in the views section.
     'chrome_browser_ui_app_list_sources': [
-      'browser/ui/views/app_list/app_list_dialog_container.cc',
-      'browser/ui/views/app_list/app_list_dialog_container.h',
-      'browser/ui/views/app_list/win/activation_tracker_win.cc',
-      'browser/ui/views/app_list/win/activation_tracker_win.h',
-      'browser/ui/views/app_list/win/app_list_controller_delegate_win.cc',
-      'browser/ui/views/app_list/win/app_list_controller_delegate_win.h',
-      'browser/ui/views/app_list/win/app_list_service_win.cc',
-      'browser/ui/views/app_list/win/app_list_service_win.h',
-      'browser/ui/views/app_list/win/app_list_win.cc',
-      'browser/ui/views/app_list/win/app_list_win.h',
       'browser/ui/app_list/app_context_menu.cc',
       'browser/ui/app_list/app_context_menu.h',
       'browser/ui/app_list/app_context_menu_delegate.h',
@@ -1167,6 +1139,7 @@
       'browser/ui/app_list/app_list_prefs_factory.cc',
       'browser/ui/app_list/app_list_prefs_factory.h',
       'browser/ui/app_list/app_list_service.cc',
+      'browser/ui/app_list/app_list_service.h',
       'browser/ui/app_list/app_list_service_impl.cc',
       'browser/ui/app_list/app_list_service_impl.h',
       'browser/ui/app_list/app_list_service_mac.h',
@@ -1237,6 +1210,16 @@
       'browser/ui/app_list/start_page_service.h',
       'browser/ui/app_list/start_page_service_factory.cc',
       'browser/ui/app_list/start_page_service_factory.h',
+      'browser/ui/views/app_list/app_list_dialog_container.cc',
+      'browser/ui/views/app_list/app_list_dialog_container.h',
+      'browser/ui/views/app_list/win/activation_tracker_win.cc',
+      'browser/ui/views/app_list/win/activation_tracker_win.h',
+      'browser/ui/views/app_list/win/app_list_controller_delegate_win.cc',
+      'browser/ui/views/app_list/win/app_list_controller_delegate_win.h',
+      'browser/ui/views/app_list/win/app_list_service_win.cc',
+      'browser/ui/views/app_list/win/app_list_service_win.h',
+      'browser/ui/views/app_list/win/app_list_win.cc',
+      'browser/ui/views/app_list/win/app_list_win.h',
       'browser/ui/webui/app_list/start_page_handler.cc',
       'browser/ui/webui/app_list/start_page_handler.h',
       'browser/ui/webui/app_list/start_page_ui.cc',
@@ -1354,8 +1337,15 @@
       'browser/ui/screen_capture_notification_ui_stub.cc',
     ],
     'chrome_browser_ui_non_android_sources': [
+      'browser/ui/apps/app_info_dialog.h',
+      'browser/ui/apps/apps_metro_handler_win.cc',
+      'browser/ui/apps/apps_metro_handler_win.h',
       'browser/ui/apps/chrome_app_delegate.cc',
       'browser/ui/apps/chrome_app_delegate.h',
+      'browser/ui/apps/chrome_app_window_client.cc',
+      'browser/ui/apps/chrome_app_window_client.h',
+      'browser/ui/apps/directory_access_confirmation_dialog.cc',
+      'browser/ui/apps/directory_access_confirmation_dialog.h',
       'browser/ui/autofill/account_chooser_model.cc',
       'browser/ui/autofill/account_chooser_model.h',
       'browser/ui/autofill/autofill_dialog_sign_in_delegate.cc',
@@ -1421,11 +1411,6 @@
       'browser/ui/content_settings/content_setting_media_menu_model.h',
       'browser/ui/elide_url.cc',
       'browser/ui/elide_url.h',
-      'browser/ui/extensions/application_launch.cc',
-      'browser/ui/extensions/application_launch.h',
-      'browser/ui/extensions/extension_install_ui_default.cc',
-      'browser/ui/extensions/extension_install_ui_default.h',
-      'browser/ui/extensions/extension_install_ui_factory.h',
       'browser/ui/fast_unload_controller.cc',
       'browser/ui/fast_unload_controller.h',
       'browser/ui/find_bar/find_bar_controller.cc',
@@ -1566,10 +1551,13 @@
       'browser/ui/toolbar/back_forward_menu_model.h',
       'browser/ui/toolbar/bookmark_sub_menu_model.cc',
       'browser/ui/toolbar/bookmark_sub_menu_model.h',
+      'browser/ui/toolbar/component_toolbar_actions_factory.cc',
+      'browser/ui/toolbar/component_toolbar_actions_factory.h',
       'browser/ui/toolbar/encoding_menu_controller.cc',
       'browser/ui/toolbar/encoding_menu_controller.h',
       'browser/ui/toolbar/recent_tabs_sub_menu_model.cc',
       'browser/ui/toolbar/recent_tabs_sub_menu_model.h',
+      'browser/ui/toolbar/toolbar_action_view_controller.h',
       'browser/ui/toolbar/wrench_menu_badge_controller.cc',
       'browser/ui/toolbar/wrench_menu_badge_controller.h',
       'browser/ui/toolbar/wrench_icon_painter.cc',
@@ -1806,6 +1794,8 @@
       'browser/ui/webui/uber/uber_ui.h',
       'browser/ui/window_sizer/window_sizer.cc',
       'browser/ui/window_sizer/window_sizer.h',
+      'browser/ui/zoom/zoom_controller.cc',
+      'browser/ui/zoom/zoom_controller.h',
     ],
     'chrome_browser_ui_print_preview_sources': [
       'browser/ui/webui/print_preview/print_preview_handler.cc',
@@ -1981,7 +1971,6 @@
       'browser/ui/views/extensions/bundle_installed_bubble.cc',
       'browser/ui/views/extensions/extension_action_view_controller.cc',
       'browser/ui/views/extensions/extension_action_view_controller.h',
-      'browser/ui/views/extensions/extension_action_view_delegate.h',
       'browser/ui/views/extensions/extension_dialog.cc',
       'browser/ui/views/extensions/extension_dialog.h',
       'browser/ui/views/extensions/extension_dialog_observer.cc',
@@ -2004,11 +1993,6 @@
       'browser/ui/views/extensions/media_gallery_checkbox_view.h',
       'browser/ui/views/extensions/device_permissions_dialog_view.cc',
       'browser/ui/views/extensions/device_permissions_dialog_view.h',
-      'browser/ui/views/find_bar_host_aura.cc',
-      'browser/ui/views/find_bar_host.cc',
-      'browser/ui/views/find_bar_host.h',
-      'browser/ui/views/find_bar_view.cc',
-      'browser/ui/views/find_bar_view.h',
       'browser/ui/views/first_run_bubble.cc',
       'browser/ui/views/first_run_bubble.h',
       'browser/ui/views/frame/browser_frame.cc',
@@ -2229,31 +2213,6 @@
       'browser/ui/views/tabs/window_finder_win.cc',
       'browser/ui/views/theme_image_mapper.cc',
       'browser/ui/views/theme_image_mapper.h',
-      'browser/ui/views/toolbar/back_button.cc',
-      'browser/ui/views/toolbar/back_button.h',
-      'browser/ui/views/toolbar/browser_actions_container.cc',
-      'browser/ui/views/toolbar/browser_actions_container.h',
-      'browser/ui/views/toolbar/browser_actions_container_observer.h',
-      'browser/ui/views/toolbar/browser_action_test_util_views.cc',
-      'browser/ui/views/toolbar/browser_action_view.cc',
-      'browser/ui/views/toolbar/browser_action_view.h',
-      'browser/ui/views/toolbar/chevron_menu_button.cc',
-      'browser/ui/views/toolbar/chevron_menu_button.h',
-      'browser/ui/views/toolbar/extension_toolbar_menu_view.cc',
-      'browser/ui/views/toolbar/extension_toolbar_menu_view.h',
-      'browser/ui/views/toolbar/home_button.cc',
-      'browser/ui/views/toolbar/home_button.h',
-      'browser/ui/views/toolbar/reload_button.cc',
-      'browser/ui/views/toolbar/reload_button.h',
-      'browser/ui/views/toolbar/toolbar_button.cc',
-      'browser/ui/views/toolbar/toolbar_button.h',
-      'browser/ui/views/toolbar/toolbar_view.cc',
-      'browser/ui/views/toolbar/toolbar_view.h',
-      'browser/ui/views/toolbar/wrench_menu.cc',
-      'browser/ui/views/toolbar/wrench_menu.h',
-      'browser/ui/views/toolbar/wrench_menu_observer.h',
-      'browser/ui/views/toolbar/wrench_toolbar_button.cc',
-      'browser/ui/views/toolbar/wrench_toolbar_button.h',
       'browser/ui/views/touch_uma/touch_uma.h',
       'browser/ui/views/translate/translate_bubble_view.cc',
       'browser/ui/views/translate/translate_bubble_view.h',
@@ -2285,6 +2244,36 @@
       'browser/ui/views/chrome_browser_main_extra_parts_views.h',
       'browser/ui/views/chrome_views_delegate.cc',
       'browser/ui/views/chrome_views_delegate.h',
+      'browser/ui/views/find_bar_host.cc',
+      'browser/ui/views/find_bar_host.h',
+      'browser/ui/views/find_bar_view.cc',
+      'browser/ui/views/find_bar_view.h',
+      'browser/ui/views/toolbar/back_button.cc',
+      'browser/ui/views/toolbar/back_button.h',
+      'browser/ui/views/toolbar/browser_actions_container.cc',
+      'browser/ui/views/toolbar/browser_actions_container.h',
+      'browser/ui/views/toolbar/browser_actions_container_observer.h',
+      'browser/ui/views/toolbar/browser_action_test_util_views.cc',
+      'browser/ui/views/toolbar/browser_action_view.cc',
+      'browser/ui/views/toolbar/browser_action_view.h',
+      'browser/ui/views/toolbar/chevron_menu_button.cc',
+      'browser/ui/views/toolbar/chevron_menu_button.h',
+      'browser/ui/views/toolbar/extension_toolbar_menu_view.cc',
+      'browser/ui/views/toolbar/extension_toolbar_menu_view.h',
+      'browser/ui/views/toolbar/home_button.cc',
+      'browser/ui/views/toolbar/home_button.h',
+      'browser/ui/views/toolbar/reload_button.cc',
+      'browser/ui/views/toolbar/reload_button.h',
+      'browser/ui/views/toolbar/toolbar_action_view_delegate.h',
+      'browser/ui/views/toolbar/toolbar_button.cc',
+      'browser/ui/views/toolbar/toolbar_button.h',
+      'browser/ui/views/toolbar/toolbar_view.cc',
+      'browser/ui/views/toolbar/toolbar_view.h',
+      'browser/ui/views/toolbar/wrench_menu.cc',
+      'browser/ui/views/toolbar/wrench_menu.h',
+      'browser/ui/views/toolbar/wrench_menu_observer.h',
+      'browser/ui/views/toolbar/wrench_toolbar_button.cc',
+      'browser/ui/views/toolbar/wrench_toolbar_button.h',
     ],
     # Views files for everwhere but ChromeOS.
     'chrome_browser_ui_views_non_chromeos_sources': [
@@ -2467,13 +2456,15 @@
     ],
     # Used when not using android and not using Athena.
     'chrome_browser_ui_non_athena_non_android_sources': [
-      'browser/ui/extensions/extension_install_ui_factory.cc', 
+      'browser/ui/extensions/application_launch_web_app.cc',
+      'browser/ui/extensions/extension_install_ui_factory.cc',
     ],
     # Used when athena is enabled.
     'chrome_browser_ui_athena_sources': [
       #TODO(mukai): Port AppListService to Athena (crbug.com/417571)
       'browser/ui/app_list/app_list_service_disabled.cc',
 
+      'browser/ui/athena/extensions/application_launch_web_app_athena.cc',
       'browser/ui/athena/extensions/extension_install_ui_factory_athena.cc', 
       'browser/ui/views/athena/athena_util.cc',
       'browser/ui/views/athena/athena_util.h',
@@ -2529,11 +2520,19 @@
     'chrome_browser_ui_extensions_sources': [
       'browser/ui/extensions/accelerator_priority.cc',
       'browser/ui/extensions/accelerator_priority.h',
-      'browser/ui/extensions/extension_installed_bubble.cc',
-      'browser/ui/extensions/extension_installed_bubble.h',
+      'browser/ui/extensions/application_launch.cc',
+      'browser/ui/extensions/application_launch.h',
+      'browser/ui/extensions/application_launch_web_app.h',
+      'browser/ui/extensions/app_launch_params.cc',
+      'browser/ui/extensions/app_launch_params.h',
       'browser/ui/extensions/extension_enable_flow.cc',
       'browser/ui/extensions/extension_enable_flow.h',
       'browser/ui/extensions/extension_enable_flow_delegate.h',
+      'browser/ui/extensions/extension_install_ui_default.cc',
+      'browser/ui/extensions/extension_install_ui_default.h',
+      'browser/ui/extensions/extension_install_ui_factory.h',
+      'browser/ui/extensions/extension_installed_bubble.cc',
+      'browser/ui/extensions/extension_installed_bubble.h',
       'browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc',
       'browser/ui/webui/extensions/chromeos/kiosk_apps_handler.h',
       'browser/ui/webui/extensions/extension_basic_info.cc',
@@ -2616,6 +2615,11 @@
         '../components/components.gyp:dom_distiller_core',
         '../sync/sync.gyp:sync',
       ],
+      'includes': [
+        # Disable LTO due to undefined reference
+        # crbug.com/422252
+        '../build/android/disable_lto.gypi',
+      ],
       'conditions': [
         ['OS != "ios"', {
           'sources': [
@@ -2626,6 +2630,7 @@
             'chrome_web_ui_mojo_bindings.gyp:web_ui_mojo_bindings',
             'debugger',
             'installer_util',
+            '../components/components.gyp:app_modal_dialogs',
             '../components/components.gyp:autofill_content_risk_proto',
             '../components/components.gyp:translate_content_common',
             '../content/app/resources/content_resources.gyp:content_resources',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 7844282..3e0c727 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -51,20 +51,6 @@
       'common/custom_handlers/protocol_handler.cc',
       'common/custom_handlers/protocol_handler.h',
       'common/descriptors_android.h',
-      'common/extensions/chrome_extension_messages.h',
-      'common/extensions/chrome_extensions_client.cc',
-      'common/extensions/chrome_extensions_client.h',
-      'common/extensions/chrome_utility_extensions_messages.h',
-      'common/extensions/extension_constants.cc',
-      'common/extensions/extension_constants.h',
-      'common/extensions/features/chrome_channel_feature_filter.cc',
-      'common/extensions/features/chrome_channel_feature_filter.h',
-      'common/extensions/features/feature_channel.cc',
-      'common/extensions/features/feature_channel.h',
-      'common/extensions/permissions/chrome_api_permissions.cc',
-      'common/extensions/permissions/chrome_api_permissions.h',
-      'common/extensions/permissions/chrome_permission_message_provider.cc',
-      'common/extensions/permissions/chrome_permission_message_provider.h',
       'common/favicon/favicon_url_parser.cc',
       'common/favicon/favicon_url_parser.h',
       'common/icon_with_badge_image_source.cc',
@@ -172,16 +158,26 @@
       'common/extensions/api/url_handlers/url_handlers_parser.h',
       'common/extensions/api/webstore/webstore_api_constants.cc',
       'common/extensions/api/webstore/webstore_api_constants.h',
+      'common/extensions/chrome_extension_messages.h',
+      'common/extensions/chrome_extensions_client.cc',
+      'common/extensions/chrome_extensions_client.h',
       'common/extensions/chrome_manifest_handlers.cc',
       'common/extensions/chrome_manifest_handlers.h',
       'common/extensions/chrome_manifest_url_handlers.cc',
       'common/extensions/chrome_manifest_url_handlers.h',
+      'common/extensions/chrome_utility_extensions_messages.h',
       'common/extensions/command.cc',
       'common/extensions/command.h',
+      'common/extensions/extension_constants.cc',
+      'common/extensions/extension_constants.h',
       'common/extensions/extension_file_util.cc',
       'common/extensions/extension_file_util.h',
       'common/extensions/extension_process_policy.cc',
       'common/extensions/extension_process_policy.h',
+      'common/extensions/features/chrome_channel_feature_filter.cc',
+      'common/extensions/features/chrome_channel_feature_filter.h',
+      'common/extensions/features/feature_channel.cc',
+      'common/extensions/features/feature_channel.h',
       'common/extensions/image_writer/image_writer_util_mac.cc',
       'common/extensions/image_writer/image_writer_util_mac.h',
       'common/extensions/manifest_handlers/app_isolation_info.cc',
@@ -204,6 +200,10 @@
       'common/extensions/manifest_handlers/theme_handler.h',
       'common/extensions/manifest_handlers/ui_overrides_handler.cc',
       'common/extensions/manifest_handlers/ui_overrides_handler.h',
+      'common/extensions/permissions/chrome_api_permissions.cc',
+      'common/extensions/permissions/chrome_api_permissions.h',
+      'common/extensions/permissions/chrome_permission_message_provider.cc',
+      'common/extensions/permissions/chrome_permission_message_provider.h',
       'common/extensions/sync_helper.cc',
       'common/extensions/sync_helper.h',
     ],
@@ -311,8 +311,7 @@
         '<(DEPTH)/components/components.gyp:variations',
         '<(DEPTH)/content/content.gyp:content_common',
         '<(DEPTH)/crypto/crypto.gyp:crypto',
-        '<(DEPTH)/extensions/extensions_resources.gyp:extensions_resources',
-        '<(DEPTH)/extensions/extensions_strings.gyp:extensions_strings',
+        '<(DEPTH)/extensions/extensions.gyp:extensions_common_constants',
         '<(DEPTH)/media/cast/cast.gyp:cast_net',
         '<(DEPTH)/net/net.gyp:net',
         '<(DEPTH)/skia/skia.gyp:skia',
@@ -335,6 +334,9 @@
             '<(DEPTH)/device/usb/usb.gyp:device_usb',
             '<(DEPTH)/chrome/common/extensions/api/api.gyp:chrome_api',
             '<(DEPTH)/extensions/common/api/api.gyp:extensions_api',
+            '<(DEPTH)/extensions/extensions.gyp:extensions_common',
+            '<(DEPTH)/extensions/extensions_resources.gyp:extensions_resources',
+            '<(DEPTH)/extensions/extensions_strings.gyp:extensions_strings',
           ],
           'export_dependent_settings': [
             '<(DEPTH)/chrome/common/extensions/api/api.gyp:chrome_api',
@@ -361,7 +363,6 @@
             '<(DEPTH)/components/components.gyp:signin_core_common',
             '<(DEPTH)/components/components.gyp:translate_content_common',
             '<(DEPTH)/components/components.gyp:visitedlink_common',
-            '<(DEPTH)/extensions/extensions.gyp:extensions_common',
             '<(DEPTH)/ipc/ipc.gyp:ipc',
             '<(DEPTH)/third_party/re2/re2.gyp:re2',
             '<(DEPTH)/third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h',
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi
index 58d233d..3fe83f1 100644
--- a/chrome/chrome_exe.gypi
+++ b/chrome/chrome_exe.gypi
@@ -674,6 +674,8 @@
           'type': 'none',
           'dependencies': [
             'chrome',
+            # Runtime dependencies
+            '../third_party/mesa/mesa.gyp:osmesa',
           ],
           'includes': [
             '../build/isolate.gypi',
diff --git a/chrome/chrome_ios_bundle_resources.gypi b/chrome/chrome_ios_bundle_resources.gypi
index efcb5f8..e9aaf6cd 100644
--- a/chrome/chrome_ios_bundle_resources.gypi
+++ b/chrome/chrome_ios_bundle_resources.gypi
@@ -9,6 +9,7 @@
   'mac_bundle_resources': [
     '<(SHARED_INTERMEDIATE_DIR)/repack/chrome_100_percent.pak',
     '<(SHARED_INTERMEDIATE_DIR)/repack/chrome_200_percent.pak',
+    '<(SHARED_INTERMEDIATE_DIR)/repack/chrome_300_percent.pak',
     '<(SHARED_INTERMEDIATE_DIR)/repack/resources.pak',
     '<!@pymod_do_main(repack_locales -o -p <(OS) -g <(grit_out_dir) -s <(SHARED_INTERMEDIATE_DIR) -x <(SHARED_INTERMEDIATE_DIR) <(locales))',
   ],
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index dc89fcc..19aa32d8 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -272,7 +272,6 @@
         '../content/app/resources/content_resources.gyp:content_resources',
         '../content/app/strings/content_strings.gyp:content_strings',
         '../content/content.gyp:content_renderer',
-        '../extensions/extensions_resources.gyp:extensions_resources',
         '../media/cast/cast.gyp:cast_logging_proto',
         '../media/cast/cast.gyp:cast_net',
         '../media/cast/cast.gyp:cast_sender',
@@ -337,6 +336,7 @@
         ['enable_extensions==1', {
           'dependencies': [
             '../extensions/extensions.gyp:extensions_renderer',
+            '../extensions/extensions_resources.gyp:extensions_resources',
             # TODO(hclam): See crbug.com/298380 for details.
             # We should isolate the APIs needed by the renderer.
             '<(DEPTH)/chrome/common/extensions/api/api.gyp:chrome_api',
diff --git a/chrome/chrome_repack_chrome_300_percent.gypi b/chrome/chrome_repack_chrome_300_percent.gypi
new file mode 100644
index 0000000..5ac082c
--- /dev/null
+++ b/chrome/chrome_repack_chrome_300_percent.gypi
@@ -0,0 +1,20 @@
+# Copyright (c) 2012 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.
+{
+  # GN version: //chrome:repack_chrome_300_percent
+  'action_name': 'repack_chrome_resources_300_percent',
+  'variables': {
+    'pak_inputs': [
+      # Only iOS generates 300 percent pak files so the inputs will need to be
+      # updated if other platforms need 300 percent support.
+      '<(SHARED_INTERMEDIATE_DIR)/components/components_resources_300_percent.pak',
+      '<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_300_percent.pak',
+      # TODO(ios): Remove the dependency on renderer_resources.
+      '<(grit_out_dir)/renderer_resources_300_percent.pak',
+      '<(grit_out_dir)/theme_resources_300_percent.pak',
+    ],
+    'pak_output': '<(SHARED_INTERMEDIATE_DIR)/repack/chrome_300_percent.pak',
+  },
+  'includes': [ '../build/repack_action.gypi' ],
+}
diff --git a/chrome/chrome_repack_resources.gypi b/chrome/chrome_repack_resources.gypi
index a3ebfab..e7ba8c2 100644
--- a/chrome/chrome_repack_resources.gypi
+++ b/chrome/chrome_repack_resources.gypi
@@ -31,8 +31,6 @@
           '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_resources.pak',
           '<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing/tracing_resources.pak',
           '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.pak',
-          '<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_renderer_resources.pak',
-          '<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_resources.pak',
         ],
       }],
       ['OS != "ios" and OS != "android"', {
@@ -47,6 +45,8 @@
       }],
       ['enable_extensions==1', {
         'pak_inputs': [
+          '<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_renderer_resources.pak',
+          '<(SHARED_INTERMEDIATE_DIR)/extensions/extensions_resources.pak',
           '<(grit_out_dir)/extensions_api_resources.pak',
         ],
       }],
diff --git a/chrome/chrome_resources.gyp b/chrome/chrome_resources.gyp
index 52aabc9..eb1914d 100644
--- a/chrome/chrome_resources.gyp
+++ b/chrome/chrome_resources.gyp
@@ -443,6 +443,16 @@
             '<(DEPTH)/content/app/strings/content_strings.gyp:content_strings',
             '<(DEPTH)/third_party/WebKit/public/blink_resources.gyp:blink_resources',
           ],
+        }, {  # else
+          'actions': [
+            {
+              'conditions': [
+                ['OS == "ios"', {
+                  'includes': ['chrome_repack_chrome_300_percent.gypi']
+                }],
+              ],
+            },
+          ],
         }],
         ['use_ash==1', {
           'dependencies': [
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index cfe894ed..fd4e170 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -526,6 +526,7 @@
       'browser/service_process/service_process_control_browsertest.cc',
       'browser/services/gcm/fake_gcm_profile_service.cc',
       'browser/services/gcm/fake_gcm_profile_service.h',
+      'browser/services/gcm/push_messaging_browsertest.cc',
       'browser/sessions/better_session_restore_browsertest.cc',
       'browser/sessions/persistent_tab_restore_service_browsertest.cc',
       'browser/sessions/session_restore_browsertest.cc',
@@ -646,6 +647,7 @@
       'browser/ui/views/profiles/profile_chooser_view_browsertest.cc',
       'browser/ui/views/select_file_dialog_extension_browsertest.cc',
       'browser/ui/views/toolbar/browser_actions_container_browsertest.cc',
+      'browser/ui/views/toolbar/component_toolbar_actions_browsertest.cc',
       'browser/ui/views/toolbar/toolbar_view_browsertest.cc',
       'browser/ui/views/translate/translate_bubble_view_browsertest.cc',
       'browser/ui/views/web_dialog_view_browsertest.cc',
@@ -813,7 +815,507 @@
       # TODO(craig): Rename this and run from base_unittests when the test
       # is safe to run there. See http://crbug.com/78722 for details.
       '../base/files/file_path_watcher_browsertest.cc',
-    ]
+    ],
+    'chrome_interactive_ui_test_sources': [
+      '../chrome/browser/ui/webui/options/language_options_interactive_uitest.cc',
+      '../extensions/browser/app_window/app_window_interactive_uitest.cc',
+      '../ui/base/clipboard/clipboard_unittest.cc',
+      '../ui/views/controls/webview/webview_interactive_uitest.cc',
+      '../ui/views/corewm/desktop_capture_controller_unittest.cc',
+      '../ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc',
+      '../ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc',
+      '../ui/views/widget/widget_interactive_uitest.cc',
+      'browser/apps/app_browsertest_util.cc',
+      'browser/apps/app_browsertest_util.h',
+      'browser/apps/app_pointer_lock_interactive_uitest.cc',
+      'browser/apps/app_shim/app_shim_interactive_uitest_mac.mm',
+      'browser/apps/app_shim/app_shim_quit_interactive_uitest_mac.mm',
+      'browser/apps/app_window_interactive_uitest.cc',
+      'browser/apps/web_view_interactive_browsertest.cc',
+      'browser/autofill/autofill_interactive_uitest.cc',
+      'browser/browser_keyevents_browsertest.cc',
+      'browser/chrome_plugin_interactive_test.cc',
+      'browser/extensions/api/extension_action/browser_action_interactive_test.cc',
+      'browser/extensions/api/omnibox/omnibox_api_interactive_test.cc',
+      'browser/extensions/api/tabs/tabs_interactive_test.cc',
+      'browser/extensions/browsertest_util.cc',
+      'browser/extensions/extension_apitest.cc',
+      'browser/extensions/extension_browsertest.cc',
+      'browser/extensions/extension_test_notification_observer.cc',
+      'browser/extensions/extension_crash_recovery_browsertest.cc',
+      'browser/extensions/extension_fullscreen_apitest.cc',
+      'browser/extensions/extension_function_test_utils.cc',
+      'browser/extensions/extension_commands_global_registry_apitest.cc',
+      'browser/extensions/extension_keybinding_apitest.cc',
+      'browser/extensions/notifications_apitest.cc',
+      'browser/extensions/updater/extension_cache_fake.h',
+      'browser/extensions/updater/extension_cache_fake.cc',
+      'browser/extensions/window_open_interactive_apitest.cc',
+      'browser/mouseleave_browsertest.cc',
+      'browser/notifications/notification_browsertest.cc',
+      'browser/password_manager/password_generation_interactive_uitest.cc',
+      'browser/renderer_context_menu/render_view_context_menu_browsertest_util.cc',
+      'browser/renderer_context_menu/render_view_context_menu_browsertest_util.h',
+      'browser/task_manager/task_manager_browsertest_util.cc',
+      'browser/ui/app_list/app_list_service_interactive_uitest.cc',
+      'browser/ui/app_list/app_list_service_mac_interactive_uitest.mm',
+      'browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc',
+      'browser/ui/browser_focus_uitest.cc',
+      'browser/ui/cocoa/apps/quit_with_apps_controller_mac_interactive_uitest.cc',
+      'browser/ui/cocoa/panels/panel_cocoa_browsertest.mm',
+      'browser/ui/find_bar/find_bar_host_interactive_uitest.cc',
+      'browser/ui/fullscreen/fullscreen_controller_interactive_browsertest.cc',
+      'browser/ui/fullscreen/fullscreen_controller_state_interactive_browsertest.cc',
+      'browser/ui/omnibox/omnibox_view_browsertest.cc',
+      'browser/ui/panels/base_panel_browser_test.cc',
+      'browser/ui/panels/base_panel_browser_test.h',
+      'browser/ui/panels/detached_panel_browsertest.cc',
+      'browser/ui/panels/docked_panel_browsertest.cc',
+      'browser/ui/panels/panel_browsertest.cc',
+      'browser/ui/panels/panel_drag_browsertest.cc',
+      'browser/ui/panels/panel_resize_browsertest.cc',
+      'browser/ui/panels/stacked_panel_browsertest.cc',
+      'browser/ui/panels/test_panel_active_state_observer.cc',
+      'browser/ui/panels/test_panel_active_state_observer.h',
+      'browser/ui/panels/test_panel_mouse_watcher.cc',
+      'browser/ui/panels/test_panel_mouse_watcher.h',
+      'browser/ui/panels/test_panel_notification_observer.cc',
+      'browser/ui/panels/test_panel_notification_observer.h',
+      'browser/ui/panels/test_panel_collection_squeeze_observer.cc',
+      'browser/ui/panels/test_panel_collection_squeeze_observer.h',
+      'browser/ui/passwords/manage_passwords_test.cc',
+      'browser/ui/passwords/manage_passwords_test.h',
+      'browser/ui/search/instant_extended_interactive_uitest.cc',
+      'browser/ui/pdf/pdf_interactive_browsertest.cc',
+      'browser/ui/search/instant_extended_manual_interactive_uitest.cc',
+      'browser/ui/search/instant_test_utils.h',
+      'browser/ui/search/instant_test_utils.cc',
+      'browser/ui/search/local_ntp_browsertest.cc',
+      'browser/ui/startup/startup_browser_creator_interactive_uitest.cc',
+      'browser/ui/toolbar/test_toolbar_model.cc',
+      'browser/ui/toolbar/test_toolbar_model.h',
+      'browser/ui/views/ash/tab_scrubber_browsertest.cc',
+      'browser/ui/views/bookmarks/bookmark_bar_view_test.cc',
+      'browser/ui/views/bookmarks/bookmark_bar_view_test_helper.h',
+      'browser/ui/views/constrained_window_views_browsertest.cc',
+      'browser/ui/views/find_bar_controller_interactive_uitest.cc',
+      'browser/ui/views/find_bar_host_interactive_uitest.cc',
+      'browser/ui/views/frame/browser_view_focus_uitest.cc',
+      'browser/ui/views/frame/browser_view_interactive_uitest.cc',
+      'browser/ui/views/keyboard_access_browsertest.cc',
+      'browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc',
+      'browser/ui/views/location_bar/star_view_browsertest.cc',
+      'browser/ui/views/menu_controller_interactive_uitest.cc',
+      'browser/ui/views/menu_item_view_interactive_uitest.cc',
+      'browser/ui/views/menu_test_base.cc',
+      'browser/ui/views/menu_test_base.h',
+      'browser/ui/views/menu_model_adapter_test.cc',
+      'browser/ui/views/menu_view_drag_and_drop_test.cc',
+      'browser/ui/views/message_center/web_notification_tray_browsertest.cc',
+      'browser/ui/views/omnibox/omnibox_view_views_browsertest.cc',
+      'browser/ui/views/panels/panel_view_browsertest.cc',
+      'browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc',
+      'browser/ui/views/passwords/manage_passwords_icon_view_browsertest.cc',
+      'browser/ui/views/ssl_client_certificate_selector_browsertest.cc',
+      'browser/ui/views/status_icons/status_tray_state_changer_interactive_uitest_win.cc',
+      'browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc',
+      'browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h',
+      'browser/ui/views/tabs/tab_drag_controller_interactive_uitest_win.cc',
+      'browser/ui/views/toolbar/toolbar_button_test.cc',
+      'browser/ui/views/toolbar/toolbar_view_interactive_uitest.cc',
+      'test/base/interactive_test_utils.cc',
+      'test/base/interactive_test_utils.h',
+      'test/base/interactive_test_utils_aura.cc',
+      'test/base/interactive_test_utils_aura.h',
+      'test/base/interactive_test_utils_mac.mm',
+      'test/base/interactive_test_utils_views.cc',
+      'test/base/interactive_test_utils_win.cc',
+      'test/base/interactive_ui_tests_main.cc',
+      'test/base/view_event_test_base.cc',
+      'test/base/view_event_test_base.h',
+      'test/base/view_event_test_platform_part.h',
+      'test/base/view_event_test_platform_part_ash.cc',
+      'test/base/view_event_test_platform_part_chromeos.cc',
+      'test/base/view_event_test_platform_part_mac.mm',
+      'test/ppapi/ppapi_interactive_browsertest.cc',
+    ],
+    'chrome_interactive_ui_test_chromeos_sources': [
+      'browser/chromeos/accessibility/speech_monitor.cc',
+      'browser/chromeos/accessibility/speech_monitor.h',
+      'browser/chromeos/accessibility/spoken_feedback_browsertest.cc',
+      'browser/chromeos/accessibility/sticky_keys_browsertest.cc',
+      'browser/chromeos/input_method/textinput_browsertest.cc',
+      'browser/chromeos/input_method/textinput_surroundingtext_browsertest.cc',
+      'browser/chromeos/input_method/textinput_test_helper.cc',
+      'browser/chromeos/input_method/textinput_test_helper.h',
+      'browser/chromeos/login/eula_browsertest.cc',
+      'browser/chromeos/login/lock/screen_locker_browsertest.cc',
+      'browser/chromeos/login/lock/screen_locker_tester.cc',
+      'browser/chromeos/login/lock/screen_locker_tester.h',
+      'browser/chromeos/login/login_browsertest.cc',
+      'browser/chromeos/login/login_manager_test.cc',
+      'browser/chromeos/login/login_manager_test.h',
+      'browser/chromeos/login/login_ui_browsertest.cc',
+      'browser/chromeos/login/mixin_based_browser_test.cc',
+      'browser/chromeos/login/mixin_based_browser_test.h',
+      'browser/chromeos/login/oobe_browsertest.cc',
+      'browser/chromeos/login/screenshot_testing/screenshot_tester.cc',
+      'browser/chromeos/login/screenshot_testing/screenshot_tester.h',
+      'browser/chromeos/login/screenshot_testing/screenshot_tester.h',
+      'browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc',
+      'browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.h',
+      'browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric.h',
+      'browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric_cpu.cpp',
+      'browser/chromeos/login/screenshot_testing/SkImageDiffer.cpp',
+      'browser/chromeos/login/screenshot_testing/SkImageDiffer.h',
+      'browser/chromeos/login/screenshot_testing/SkPMetric.cpp',
+      'browser/chromeos/login/screenshot_testing/SkPMetric.h',
+      'browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc',
+      'browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc',
+      'browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h',
+      'test/data/chromeos/service_login.html',
+    ],
+    'chrome_automation_client_lib_sources': [
+      '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/js.cc',
+      '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/js.h',
+      '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/user_data_dir.cc',
+      '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/user_data_dir.h',
+      '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/embedded_automation_extension.cc',
+      '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/embedded_automation_extension.h',
+      'test/chromedriver/chrome/adb.h',
+      'test/chromedriver/chrome/adb_impl.cc',
+      'test/chromedriver/chrome/adb_impl.h',
+      'test/chromedriver/chrome/automation_extension.cc',
+      'test/chromedriver/chrome/automation_extension.h',
+      'test/chromedriver/chrome/chrome.h',
+      'test/chromedriver/chrome/chrome_android_impl.cc',
+      'test/chromedriver/chrome/chrome_android_impl.h',
+      'test/chromedriver/chrome/chrome_desktop_impl.cc',
+      'test/chromedriver/chrome/chrome_desktop_impl.h',
+      'test/chromedriver/chrome/chrome_finder.cc',
+      'test/chromedriver/chrome/chrome_finder.h',
+      'test/chromedriver/chrome/chrome_finder_mac.mm',
+      'test/chromedriver/chrome/chrome_impl.cc',
+      'test/chromedriver/chrome/chrome_impl.h',
+      'test/chromedriver/chrome/chrome_remote_impl.cc',
+      'test/chromedriver/chrome/chrome_remote_impl.h',
+      'test/chromedriver/chrome/console_logger.cc',
+      'test/chromedriver/chrome/console_logger.h',
+      'test/chromedriver/chrome/debugger_tracker.cc',
+      'test/chromedriver/chrome/debugger_tracker.h',
+      'test/chromedriver/chrome/device_manager.cc',
+      'test/chromedriver/chrome/device_manager.h',
+      'test/chromedriver/chrome/device_metrics.cc',
+      'test/chromedriver/chrome/device_metrics.h',
+      'test/chromedriver/chrome/devtools_client.h',
+      'test/chromedriver/chrome/devtools_client_impl.cc',
+      'test/chromedriver/chrome/devtools_client_impl.h',
+      'test/chromedriver/chrome/devtools_event_listener.cc',
+      'test/chromedriver/chrome/devtools_event_listener.h',
+      'test/chromedriver/chrome/devtools_http_client.cc',
+      'test/chromedriver/chrome/devtools_http_client.h',
+      'test/chromedriver/chrome/dom_tracker.cc',
+      'test/chromedriver/chrome/dom_tracker.h',
+      'test/chromedriver/chrome/frame_tracker.cc',
+      'test/chromedriver/chrome/frame_tracker.h',
+      'test/chromedriver/chrome/geolocation_override_manager.cc',
+      'test/chromedriver/chrome/geolocation_override_manager.h',
+      'test/chromedriver/chrome/geoposition.h',
+      'test/chromedriver/chrome/heap_snapshot_taker.cc',
+      'test/chromedriver/chrome/heap_snapshot_taker.h',
+      'test/chromedriver/chrome/javascript_dialog_manager.cc',
+      'test/chromedriver/chrome/javascript_dialog_manager.h',
+      'test/chromedriver/chrome/log.h',
+      'test/chromedriver/chrome/log.cc',
+      'test/chromedriver/chrome/mobile_device.cc',
+      'test/chromedriver/chrome/mobile_device.h',
+      'test/chromedriver/chrome/mobile_device_list.cc',
+      'test/chromedriver/chrome/mobile_device_list.h',
+      'test/chromedriver/chrome/mobile_emulation_override_manager.cc',
+      'test/chromedriver/chrome/mobile_emulation_override_manager.h',
+      'test/chromedriver/chrome/navigation_tracker.cc',
+      'test/chromedriver/chrome/navigation_tracker.h',
+      'test/chromedriver/chrome/status.cc',
+      'test/chromedriver/chrome/status.h',
+      'test/chromedriver/chrome/ui_events.cc',
+      'test/chromedriver/chrome/ui_events.h',
+      'test/chromedriver/chrome/util.cc',
+      'test/chromedriver/chrome/util.h',
+      'test/chromedriver/chrome/version.cc',
+      'test/chromedriver/chrome/version.h',
+      'test/chromedriver/chrome/web_view.h',
+      'test/chromedriver/chrome/web_view_impl.cc',
+      'test/chromedriver/chrome/web_view_impl.h',
+      'test/chromedriver/net/adb_client_socket.cc',
+      'test/chromedriver/net/adb_client_socket.h',
+      'test/chromedriver/net/net_util.cc',
+      'test/chromedriver/net/net_util.h',
+      'test/chromedriver/net/port_server.cc',
+      'test/chromedriver/net/port_server.h',
+      'test/chromedriver/net/sync_websocket.h',
+      'test/chromedriver/net/sync_websocket_factory.cc',
+      'test/chromedriver/net/sync_websocket_factory.h',
+      'test/chromedriver/net/sync_websocket_impl.cc',
+      'test/chromedriver/net/sync_websocket_impl.h',
+      'test/chromedriver/net/url_request_context_getter.cc',
+      'test/chromedriver/net/url_request_context_getter.h',
+      'test/chromedriver/net/websocket.cc',
+      'test/chromedriver/net/websocket.h',
+    ],
+    'performance_browser_tests_sources': [
+      '../components/autofill/content/renderer/test_password_autofill_agent.cc',
+      '../components/autofill/content/renderer/test_password_autofill_agent.h',
+      '../components/autofill/content/renderer/test_password_generation_agent.cc',
+      '../components/autofill/content/renderer/test_password_generation_agent.h',
+      'app/chrome_command_ids.h',
+      'app/chrome_dll.rc',
+      'app/chrome_dll_resource.h',
+      'app/chrome_version.rc.version',
+      'browser/extensions/api/tab_capture/tab_capture_performancetest.cc',
+      'browser/extensions/api/cast_streaming/performance_test.cc',
+      'browser/extensions/browsertest_util.cc',
+      'browser/extensions/extension_apitest.cc',
+      'browser/extensions/extension_browsertest.cc',
+      'browser/extensions/extension_test_notification_observer.cc',
+      'browser/extensions/updater/extension_cache_fake.h',
+      'browser/extensions/updater/extension_cache_fake.cc',
+      'test/base/browser_perf_tests_main.cc',
+      'test/base/chrome_render_view_test.cc',
+      'test/base/chrome_render_view_test.h',
+      'test/perf/browser_perf_test.cc',
+      'test/perf/browser_perf_test.h',
+      'test/perf/mach_ports_performancetest.cc',
+    ],
+    'chrome_driver_lib_sources': [
+      '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/version.cc',
+      '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/version.h',
+      '../third_party/webdriver/atoms.cc',
+      '../third_party/webdriver/atoms.h',
+      'common/chrome_constants.cc',
+      'common/chrome_constants.h',
+      'test/chromedriver/alert_commands.cc',
+      'test/chromedriver/alert_commands.h',
+      'test/chromedriver/basic_types.cc',
+      'test/chromedriver/basic_types.h',
+      'test/chromedriver/capabilities.cc',
+      'test/chromedriver/capabilities.h',
+      'test/chromedriver/chrome/browser_info.cc',
+      'test/chromedriver/chrome/browser_info.h',
+      'test/chromedriver/chrome_launcher.cc',
+      'test/chromedriver/chrome_launcher.h',
+      'test/chromedriver/command_listener.h',
+      'test/chromedriver/command_listener_proxy.cc',
+      'test/chromedriver/command_listener_proxy.h',
+      'test/chromedriver/command.h',
+      'test/chromedriver/commands.cc',
+      'test/chromedriver/commands.h',
+      'test/chromedriver/element_commands.cc',
+      'test/chromedriver/element_commands.h',
+      'test/chromedriver/element_util.cc',
+      'test/chromedriver/element_util.h',
+      'test/chromedriver/key_converter.cc',
+      'test/chromedriver/key_converter.h',
+      'test/chromedriver/keycode_text_conversion.h',
+      'test/chromedriver/keycode_text_conversion_mac.mm',
+      'test/chromedriver/keycode_text_conversion_ozone.cc',
+      'test/chromedriver/keycode_text_conversion_win.cc',
+      'test/chromedriver/keycode_text_conversion_x.cc',
+      'test/chromedriver/logging.cc',
+      'test/chromedriver/logging.h',
+      'test/chromedriver/performance_logger.cc',
+      'test/chromedriver/performance_logger.h',
+      'test/chromedriver/server/http_handler.cc',
+      'test/chromedriver/server/http_handler.h',
+      'test/chromedriver/session.cc',
+      'test/chromedriver/session.h',
+      'test/chromedriver/session_commands.cc',
+      'test/chromedriver/session_commands.h',
+      'test/chromedriver/session_thread_map.h',
+      'test/chromedriver/util.cc',
+      'test/chromedriver/util.h',
+      'test/chromedriver/window_commands.cc',
+      'test/chromedriver/window_commands.h',
+    ],
+    'chrome_driver_unittests_sources': [
+      'test/chromedriver/capabilities_unittest.cc',
+      'test/chromedriver/chrome/browser_info_unittest.cc',
+      'test/chromedriver/chrome/chrome_finder_unittest.cc',
+      'test/chromedriver/chrome/console_logger_unittest.cc',
+      'test/chromedriver/chrome/device_manager_unittest.cc',
+      'test/chromedriver/chrome/devtools_client_impl_unittest.cc',
+      'test/chromedriver/chrome/devtools_http_client_unittest.cc',
+      'test/chromedriver/chrome/dom_tracker_unittest.cc',
+      'test/chromedriver/chrome/frame_tracker_unittest.cc',
+      'test/chromedriver/chrome/geolocation_override_manager_unittest.cc',
+      'test/chromedriver/chrome/heap_snapshot_taker_unittest.cc',
+      'test/chromedriver/chrome/javascript_dialog_manager_unittest.cc',
+      'test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc',
+      'test/chromedriver/chrome/navigation_tracker_unittest.cc',
+      'test/chromedriver/chrome/status_unittest.cc',
+      'test/chromedriver/chrome/stub_chrome.cc',
+      'test/chromedriver/chrome/stub_chrome.h',
+      'test/chromedriver/chrome/stub_devtools_client.cc',
+      'test/chromedriver/chrome/stub_devtools_client.h',
+      'test/chromedriver/chrome/stub_web_view.cc',
+      'test/chromedriver/chrome/stub_web_view.h',
+      'test/chromedriver/chrome/web_view_impl_unittest.cc',
+      'test/chromedriver/chrome_launcher_unittest.cc',
+      'test/chromedriver/command_listener_proxy_unittest.cc',
+      'test/chromedriver/commands_unittest.cc',
+      'test/chromedriver/logging_unittest.cc',
+      'test/chromedriver/performance_logger_unittest.cc',
+      'test/chromedriver/server/http_handler_unittest.cc',
+      'test/chromedriver/session_commands_unittest.cc',
+      'test/chromedriver/session_unittest.cc',
+      'test/chromedriver/util_unittest.cc',
+    ],
+    'chrome_driver_tests_sources': [
+      'test/chromedriver/key_converter_unittest.cc',
+      'test/chromedriver/keycode_text_conversion_unittest.cc',
+      'test/chromedriver/net/net_util_unittest.cc',
+      'test/chromedriver/net/port_server_unittest.cc',
+      'test/chromedriver/net/sync_websocket_impl_unittest.cc',
+      'test/chromedriver/net/test_http_server.cc',
+      'test/chromedriver/net/test_http_server.h',
+      'test/chromedriver/net/websocket_unittest.cc',
+      'test/chromedriver/test_util.cc',
+      'test/chromedriver/test_util.h',
+    ],
+    'sync_integration_tests_sources': [
+      'app/chrome_command_ids.h',
+      'app/chrome_dll.rc',
+      'app/chrome_dll_resource.h',
+      'app/chrome_version.rc.version',
+      'test/base/browser_tests_main.cc',
+      'test/data/resource.rc',
+      'browser/sync/test/integration/cross_platform_sync_test.cc',
+      'browser/sync/test/integration/enable_disable_test.cc',
+      'browser/sync/test/integration/migration_test.cc',
+      'browser/sync/test/integration/multiple_client_bookmarks_sync_test.cc',
+      'browser/sync/test/integration/multiple_client_dictionary_sync_test.cc',
+      'browser/sync/test/integration/multiple_client_passwords_sync_test.cc',
+      'browser/sync/test/integration/multiple_client_preferences_sync_test.cc',
+      'browser/sync/test/integration/multiple_client_sessions_sync_test.cc',
+      'browser/sync/test/integration/multiple_client_typed_urls_sync_test.cc',
+      'browser/sync/test/integration/passwords_helper.cc',
+      'browser/sync/test/integration/passwords_helper.h',
+      'browser/sync/test/integration/preferences_helper.cc',
+      'browser/sync/test/integration/preferences_helper.h',
+      'browser/sync/test/integration/search_engines_helper.cc',
+      'browser/sync/test/integration/search_engines_helper.h',
+      'browser/sync/test/integration/sessions_helper.cc',
+      'browser/sync/test/integration/sessions_helper.h',
+      'browser/sync/test/integration/single_client_app_list_sync_test.cc',
+      'browser/sync/test/integration/single_client_apps_sync_test.cc',
+      'browser/sync/test/integration/single_client_backup_rollback_test.cc',
+      'browser/sync/test/integration/single_client_bookmarks_sync_test.cc',
+      'browser/sync/test/integration/single_client_dictionary_sync_test.cc',
+      'browser/sync/test/integration/single_client_extensions_sync_test.cc',
+      'browser/sync/test/integration/single_client_passwords_sync_test.cc',
+      'browser/sync/test/integration/single_client_preferences_sync_test.cc',
+      'browser/sync/test/integration/single_client_search_engines_sync_test.cc',
+      'browser/sync/test/integration/single_client_sessions_sync_test.cc',
+      'browser/sync/test/integration/single_client_supervised_user_settings_sync_test.cc',
+      'browser/sync/test/integration/single_client_themes_sync_test.cc',
+      'browser/sync/test/integration/single_client_typed_urls_sync_test.cc',
+      'browser/sync/test/integration/sync_auth_test.cc',
+      'browser/sync/test/integration/sync_errors_test.cc',
+      'browser/sync/test/integration/sync_exponential_backoff_test.cc',
+      'browser/sync/test/integration/two_client_app_list_sync_test.cc',
+      'browser/sync/test/integration/two_client_apps_sync_test.cc',
+      'browser/sync/test/integration/two_client_autofill_sync_test.cc',
+      'browser/sync/test/integration/two_client_bookmarks_sync_test.cc',
+      'browser/sync/test/integration/two_client_dictionary_sync_test.cc',
+      'browser/sync/test/integration/two_client_extension_settings_and_app_settings_sync_test.cc',
+      'browser/sync/test/integration/two_client_extensions_sync_test.cc',
+      'browser/sync/test/integration/two_client_passwords_sync_test.cc',
+      'browser/sync/test/integration/two_client_preferences_sync_test.cc',
+      'browser/sync/test/integration/two_client_search_engines_sync_test.cc',
+      'browser/sync/test/integration/two_client_sessions_sync_test.cc',
+      'browser/sync/test/integration/two_client_themes_sync_test.cc',
+      'browser/sync/test/integration/two_client_typed_urls_sync_test.cc',
+    ],
+    'test_support_sync_integration_sources': [
+      'browser/sync/test/integration/apps_helper.cc',
+      'browser/sync/test/integration/apps_helper.h',
+      'browser/sync/test/integration/autofill_helper.cc',
+      'browser/sync/test/integration/autofill_helper.h',
+      'browser/sync/test/integration/bookmarks_helper.cc',
+      'browser/sync/test/integration/bookmarks_helper.h',
+      'browser/sync/test/integration/dictionary_helper.cc',
+      'browser/sync/test/integration/dictionary_helper.h',
+      'browser/sync/test/integration/dictionary_load_observer.cc',
+      'browser/sync/test/integration/dictionary_load_observer.h',
+      'browser/sync/test/integration/extension_settings_helper.cc',
+      'browser/sync/test/integration/extension_settings_helper.h',
+      'browser/sync/test/integration/extensions_helper.cc',
+      'browser/sync/test/integration/extensions_helper.h',
+      'browser/sync/test/integration/fake_server_invalidation_service.cc',
+      'browser/sync/test/integration/fake_server_invalidation_service.h',
+      'browser/sync/test/integration/migration_waiter.cc',
+      'browser/sync/test/integration/migration_waiter.h',
+      'browser/sync/test/integration/migration_watcher.cc',
+      'browser/sync/test/integration/migration_watcher.h',
+      'browser/sync/test/integration/multi_client_status_change_checker.cc',
+      'browser/sync/test/integration/multi_client_status_change_checker.h',
+      'browser/sync/test/integration/passwords_helper.cc',
+      'browser/sync/test/integration/passwords_helper.h',
+      'browser/sync/test/integration/p2p_invalidation_forwarder.cc',
+      'browser/sync/test/integration/p2p_invalidation_forwarder.h',
+      'browser/sync/test/integration/preferences_helper.cc',
+      'browser/sync/test/integration/preferences_helper.h',
+      'browser/sync/test/integration/profile_sync_service_harness.cc',
+      'browser/sync/test/integration/profile_sync_service_harness.h',
+      'browser/sync/test/integration/quiesce_status_change_checker.cc',
+      'browser/sync/test/integration/quiesce_status_change_checker.h',
+      'browser/sync/test/integration/retry_verifier.cc',
+      'browser/sync/test/integration/retry_verifier.h',
+      'browser/sync/test/integration/search_engines_helper.cc',
+      'browser/sync/test/integration/search_engines_helper.h',
+      'browser/sync/test/integration/sessions_helper.cc',
+      'browser/sync/test/integration/sessions_helper.h',
+      'browser/sync/test/integration/single_client_status_change_checker.cc',
+      'browser/sync/test/integration/single_client_status_change_checker.h',
+      'browser/sync/test/integration/status_change_checker.cc',
+      'browser/sync/test/integration/status_change_checker.h',
+      'browser/sync/test/integration/sync_app_helper.cc',
+      'browser/sync/test/integration/sync_app_helper.h',
+      'browser/sync/test/integration/sync_app_list_helper.cc',
+      'browser/sync/test/integration/sync_app_list_helper.h',
+      'browser/sync/test/integration/sync_datatype_helper.cc',
+      'browser/sync/test/integration/sync_datatype_helper.h',
+      'browser/sync/test/integration/sync_extension_helper.cc',
+      'browser/sync/test/integration/sync_extension_helper.h',
+      'browser/sync/test/integration/sync_extension_installer.cc',
+      'browser/sync/test/integration/sync_extension_installer.h',
+      'browser/sync/test/integration/sync_integration_test_util.cc',
+      'browser/sync/test/integration/sync_integration_test_util.h',
+      'browser/sync/test/integration/sync_test.cc',
+      'browser/sync/test/integration/sync_test.h',
+      'browser/sync/test/integration/themes_helper.cc',
+      'browser/sync/test/integration/themes_helper.h',
+      'browser/sync/test/integration/typed_urls_helper.cc',
+      'browser/sync/test/integration/typed_urls_helper.h',
+      'browser/sync/test/integration/updated_progress_marker_checker.cc',
+      'browser/sync/test/integration/updated_progress_marker_checker.h',
+    ],
+    'sync_performance_tests_sources': [
+      'app/chrome_command_ids.h',
+      'app/chrome_dll.rc',
+      'app/chrome_dll_resource.h',
+      'app/chrome_version.rc.version',
+      'browser/sync/test/integration/performance/autofill_sync_perf_test.cc',
+      'browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc',
+      'browser/sync/test/integration/performance/dictionary_sync_perf_test.cc',
+      'browser/sync/test/integration/performance/extensions_sync_perf_test.cc',
+      'browser/sync/test/integration/performance/sync_timing_helper.cc',
+      'browser/sync/test/integration/performance/sync_timing_helper.h',
+      'browser/sync/test/integration/performance/passwords_sync_perf_test.cc',
+      'browser/sync/test/integration/performance/sessions_sync_perf_test.cc',
+      'browser/sync/test/integration/performance/typed_urls_sync_perf_test.cc',
+      'test/base/browser_perf_tests_main.cc',
+      'test/data/resource.rc',
+    ],
   },
   'includes': [
     'js_unittest_vars.gypi',
@@ -860,126 +1362,7 @@
         'HAS_OUT_OF_PROC_TEST_RUNNER',
       ],
       'sources': [
-        '../chrome/browser/ui/webui/options/language_options_interactive_uitest.cc',
-        '../extensions/browser/app_window/app_window_interactive_uitest.cc',
-        '../ui/base/clipboard/clipboard_unittest.cc',
-        '../ui/views/controls/webview/webview_interactive_uitest.cc',
-        '../ui/views/corewm/desktop_capture_controller_unittest.cc',
-        '../ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc',
-        '../ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc',
-        '../ui/views/widget/widget_interactive_uitest.cc',
-        'browser/apps/app_browsertest_util.cc',
-        'browser/apps/app_browsertest_util.h',
-        'browser/apps/app_pointer_lock_interactive_uitest.cc',
-        'browser/apps/app_shim/app_shim_interactive_uitest_mac.mm',
-        'browser/apps/app_shim/app_shim_quit_interactive_uitest_mac.mm',
-        'browser/apps/app_window_interactive_uitest.cc',
-        'browser/apps/web_view_interactive_browsertest.cc',
-        'browser/autofill/autofill_interactive_uitest.cc',
-        'browser/browser_keyevents_browsertest.cc',
-        'browser/chrome_plugin_interactive_test.cc',
-        'browser/extensions/api/extension_action/browser_action_interactive_test.cc',
-        'browser/extensions/api/omnibox/omnibox_api_interactive_test.cc',
-        'browser/extensions/api/tabs/tabs_interactive_test.cc',
-        'browser/extensions/browsertest_util.cc',
-        'browser/extensions/extension_apitest.cc',
-        'browser/extensions/extension_browsertest.cc',
-        'browser/extensions/extension_test_notification_observer.cc',
-        'browser/extensions/extension_crash_recovery_browsertest.cc',
-        'browser/extensions/extension_fullscreen_apitest.cc',
-        'browser/extensions/extension_function_test_utils.cc',
-        'browser/extensions/extension_commands_global_registry_apitest.cc',
-        'browser/extensions/extension_keybinding_apitest.cc',
-        'browser/extensions/notifications_apitest.cc',
-        'browser/extensions/updater/extension_cache_fake.h',
-        'browser/extensions/updater/extension_cache_fake.cc',
-        'browser/extensions/window_open_interactive_apitest.cc',
-        'browser/mouseleave_browsertest.cc',
-        'browser/notifications/notification_browsertest.cc',
-        'browser/password_manager/password_generation_interactive_uitest.cc',
-        'browser/renderer_context_menu/render_view_context_menu_browsertest_util.cc',
-        'browser/renderer_context_menu/render_view_context_menu_browsertest_util.h',
-        'browser/task_manager/task_manager_browsertest_util.cc',
-        'browser/ui/app_list/app_list_service_interactive_uitest.cc',
-        'browser/ui/app_list/app_list_service_mac_interactive_uitest.mm',
-        'browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc',
-        'browser/ui/browser_focus_uitest.cc',
-        'browser/ui/cocoa/apps/quit_with_apps_controller_mac_interactive_uitest.cc',
-        'browser/ui/cocoa/panels/panel_cocoa_browsertest.mm',
-        'browser/ui/find_bar/find_bar_host_interactive_uitest.cc',
-        'browser/ui/fullscreen/fullscreen_controller_interactive_browsertest.cc',
-        'browser/ui/fullscreen/fullscreen_controller_state_interactive_browsertest.cc',
-        'browser/ui/omnibox/omnibox_view_browsertest.cc',
-        'browser/ui/panels/base_panel_browser_test.cc',
-        'browser/ui/panels/base_panel_browser_test.h',
-        'browser/ui/panels/detached_panel_browsertest.cc',
-        'browser/ui/panels/docked_panel_browsertest.cc',
-        'browser/ui/panels/panel_browsertest.cc',
-        'browser/ui/panels/panel_drag_browsertest.cc',
-        'browser/ui/panels/panel_resize_browsertest.cc',
-        'browser/ui/panels/stacked_panel_browsertest.cc',
-        'browser/ui/panels/test_panel_active_state_observer.cc',
-        'browser/ui/panels/test_panel_active_state_observer.h',
-        'browser/ui/panels/test_panel_mouse_watcher.cc',
-        'browser/ui/panels/test_panel_mouse_watcher.h',
-        'browser/ui/panels/test_panel_notification_observer.cc',
-        'browser/ui/panels/test_panel_notification_observer.h',
-        'browser/ui/panels/test_panel_collection_squeeze_observer.cc',
-        'browser/ui/panels/test_panel_collection_squeeze_observer.h',
-        'browser/ui/passwords/manage_passwords_test.cc',
-        'browser/ui/passwords/manage_passwords_test.h',
-        'browser/ui/search/instant_extended_interactive_uitest.cc',
-        'browser/ui/pdf/pdf_interactive_browsertest.cc',
-        'browser/ui/search/instant_extended_manual_interactive_uitest.cc',
-        'browser/ui/search/instant_test_utils.h',
-        'browser/ui/search/instant_test_utils.cc',
-        'browser/ui/search/local_ntp_browsertest.cc',
-        'browser/ui/startup/startup_browser_creator_interactive_uitest.cc',
-        'browser/ui/toolbar/test_toolbar_model.cc',
-        'browser/ui/toolbar/test_toolbar_model.h',
-        'browser/ui/views/ash/tab_scrubber_browsertest.cc',
-        'browser/ui/views/bookmarks/bookmark_bar_view_test.cc',
-        'browser/ui/views/constrained_window_views_browsertest.cc',
-        'browser/ui/views/find_bar_controller_interactive_uitest.cc',
-        'browser/ui/views/find_bar_host_interactive_uitest.cc',
-        'browser/ui/views/frame/browser_view_focus_uitest.cc',
-        'browser/ui/views/frame/browser_view_interactive_uitest.cc',
-        'browser/ui/views/keyboard_access_browsertest.cc',
-        'browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc',
-        'browser/ui/views/location_bar/star_view_browsertest.cc',
-        'browser/ui/views/menu_controller_interactive_uitest.cc',
-        'browser/ui/views/menu_item_view_interactive_uitest.cc',
-        'browser/ui/views/menu_test_base.cc',
-        'browser/ui/views/menu_test_base.h',
-        'browser/ui/views/menu_model_adapter_test.cc',
-        'browser/ui/views/menu_view_drag_and_drop_test.cc',
-        'browser/ui/views/message_center/web_notification_tray_browsertest.cc',
-        'browser/ui/views/omnibox/omnibox_view_views_browsertest.cc',
-        'browser/ui/views/panels/panel_view_browsertest.cc',
-        'browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc',
-        'browser/ui/views/passwords/manage_passwords_icon_view_browsertest.cc',
-        'browser/ui/views/ssl_client_certificate_selector_browsertest.cc',
-        'browser/ui/views/status_icons/status_tray_state_changer_interactive_uitest_win.cc',
-        'browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc',
-        'browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h',
-        'browser/ui/views/tabs/tab_drag_controller_interactive_uitest_win.cc',
-        'browser/ui/views/toolbar/toolbar_button_test.cc',
-        'browser/ui/views/toolbar/toolbar_view_interactive_uitest.cc',
-        'test/base/interactive_test_utils.cc',
-        'test/base/interactive_test_utils.h',
-        'test/base/interactive_test_utils_aura.cc',
-        'test/base/interactive_test_utils_aura.h',
-        'test/base/interactive_test_utils_mac.mm',
-        'test/base/interactive_test_utils_views.cc',
-        'test/base/interactive_test_utils_win.cc',
-        'test/base/interactive_ui_tests_main.cc',
-        'test/base/view_event_test_base.cc',
-        'test/base/view_event_test_base.h',
-        'test/base/view_event_test_platform_part.h',
-        'test/base/view_event_test_platform_part_ash.cc',
-        'test/base/view_event_test_platform_part_chromeos.cc',
-        'test/base/view_event_test_platform_part_mac.mm',
-        'test/ppapi/ppapi_interactive_browsertest.cc',
+        '<@(chrome_interactive_ui_test_sources)',
       ],
       'conditions': [
         ['use_x11==1', {
@@ -1103,40 +1486,7 @@
             }],
           ],
           'sources': [
-            'browser/chromeos/accessibility/speech_monitor.cc',
-            'browser/chromeos/accessibility/speech_monitor.h',
-            'browser/chromeos/accessibility/spoken_feedback_browsertest.cc',
-            'browser/chromeos/accessibility/sticky_keys_browsertest.cc',
-            'browser/chromeos/input_method/textinput_browsertest.cc',
-            'browser/chromeos/input_method/textinput_surroundingtext_browsertest.cc',
-            'browser/chromeos/input_method/textinput_test_helper.cc',
-            'browser/chromeos/input_method/textinput_test_helper.h',
-            'browser/chromeos/login/eula_browsertest.cc',
-            'browser/chromeos/login/lock/screen_locker_browsertest.cc',
-            'browser/chromeos/login/lock/screen_locker_tester.cc',
-            'browser/chromeos/login/lock/screen_locker_tester.h',
-            'browser/chromeos/login/login_browsertest.cc',
-            'browser/chromeos/login/login_manager_test.cc',
-            'browser/chromeos/login/login_manager_test.h',
-            'browser/chromeos/login/login_ui_browsertest.cc',
-            'browser/chromeos/login/mixin_based_browser_test.cc',
-            'browser/chromeos/login/mixin_based_browser_test.h',
-            'browser/chromeos/login/oobe_browsertest.cc',
-            'browser/chromeos/login/screenshot_testing/screenshot_tester.cc',
-            'browser/chromeos/login/screenshot_testing/screenshot_tester.h',
-            'browser/chromeos/login/screenshot_testing/screenshot_tester.h',
-            'browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc',
-            'browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.h',
-            'browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric.h',
-            'browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric_cpu.cpp',
-            'browser/chromeos/login/screenshot_testing/SkImageDiffer.cpp',
-            'browser/chromeos/login/screenshot_testing/SkImageDiffer.h',
-            'browser/chromeos/login/screenshot_testing/SkPMetric.cpp',
-            'browser/chromeos/login/screenshot_testing/SkPMetric.h',
-            'browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc',
-            'browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.cc',
-            'browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h',
-            'test/data/chromeos/service_login.html',
+            '<@(chrome_interactive_ui_test_chromeos_sources)',
           ],
           'sources!': [
             '../ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc',
@@ -1247,91 +1597,7 @@
         ],
       },
       'sources': [
-        '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/js.cc',
-        '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/js.h',
-        '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/user_data_dir.cc',
-        '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/user_data_dir.h',
-        '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/embedded_automation_extension.cc',
-        '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/chrome/embedded_automation_extension.h',
-        'test/chromedriver/chrome/adb.h',
-        'test/chromedriver/chrome/adb_impl.cc',
-        'test/chromedriver/chrome/adb_impl.h',
-        'test/chromedriver/chrome/automation_extension.cc',
-        'test/chromedriver/chrome/automation_extension.h',
-        'test/chromedriver/chrome/chrome.h',
-        'test/chromedriver/chrome/chrome_android_impl.cc',
-        'test/chromedriver/chrome/chrome_android_impl.h',
-        'test/chromedriver/chrome/chrome_desktop_impl.cc',
-        'test/chromedriver/chrome/chrome_desktop_impl.h',
-        'test/chromedriver/chrome/chrome_finder.cc',
-        'test/chromedriver/chrome/chrome_finder.h',
-        'test/chromedriver/chrome/chrome_finder_mac.mm',
-        'test/chromedriver/chrome/chrome_impl.cc',
-        'test/chromedriver/chrome/chrome_impl.h',
-        'test/chromedriver/chrome/chrome_remote_impl.cc',
-        'test/chromedriver/chrome/chrome_remote_impl.h',
-        'test/chromedriver/chrome/console_logger.cc',
-        'test/chromedriver/chrome/console_logger.h',
-        'test/chromedriver/chrome/debugger_tracker.cc',
-        'test/chromedriver/chrome/debugger_tracker.h',
-        'test/chromedriver/chrome/device_manager.cc',
-        'test/chromedriver/chrome/device_manager.h',
-        'test/chromedriver/chrome/device_metrics.cc',
-        'test/chromedriver/chrome/device_metrics.h',
-        'test/chromedriver/chrome/devtools_client.h',
-        'test/chromedriver/chrome/devtools_client_impl.cc',
-        'test/chromedriver/chrome/devtools_client_impl.h',
-        'test/chromedriver/chrome/devtools_event_listener.cc',
-        'test/chromedriver/chrome/devtools_event_listener.h',
-        'test/chromedriver/chrome/devtools_http_client.cc',
-        'test/chromedriver/chrome/devtools_http_client.h',
-        'test/chromedriver/chrome/dom_tracker.cc',
-        'test/chromedriver/chrome/dom_tracker.h',
-        'test/chromedriver/chrome/frame_tracker.cc',
-        'test/chromedriver/chrome/frame_tracker.h',
-        'test/chromedriver/chrome/geolocation_override_manager.cc',
-        'test/chromedriver/chrome/geolocation_override_manager.h',
-        'test/chromedriver/chrome/geoposition.h',
-        'test/chromedriver/chrome/heap_snapshot_taker.cc',
-        'test/chromedriver/chrome/heap_snapshot_taker.h',
-        'test/chromedriver/chrome/javascript_dialog_manager.cc',
-        'test/chromedriver/chrome/javascript_dialog_manager.h',
-        'test/chromedriver/chrome/log.h',
-        'test/chromedriver/chrome/log.cc',
-        'test/chromedriver/chrome/mobile_device.cc',
-        'test/chromedriver/chrome/mobile_device.h',
-        'test/chromedriver/chrome/mobile_device_list.cc',
-        'test/chromedriver/chrome/mobile_device_list.h',
-        'test/chromedriver/chrome/mobile_emulation_override_manager.cc',
-        'test/chromedriver/chrome/mobile_emulation_override_manager.h',
-        'test/chromedriver/chrome/navigation_tracker.cc',
-        'test/chromedriver/chrome/navigation_tracker.h',
-        'test/chromedriver/chrome/status.cc',
-        'test/chromedriver/chrome/status.h',
-        'test/chromedriver/chrome/ui_events.cc',
-        'test/chromedriver/chrome/ui_events.h',
-        'test/chromedriver/chrome/util.cc',
-        'test/chromedriver/chrome/util.h',
-        'test/chromedriver/chrome/version.cc',
-        'test/chromedriver/chrome/version.h',
-        'test/chromedriver/chrome/web_view.h',
-        'test/chromedriver/chrome/web_view_impl.cc',
-        'test/chromedriver/chrome/web_view_impl.h',
-        'test/chromedriver/net/adb_client_socket.cc',
-        'test/chromedriver/net/adb_client_socket.h',
-        'test/chromedriver/net/net_util.cc',
-        'test/chromedriver/net/net_util.h',
-        'test/chromedriver/net/port_server.cc',
-        'test/chromedriver/net/port_server.h',
-        'test/chromedriver/net/sync_websocket.h',
-        'test/chromedriver/net/sync_websocket_factory.cc',
-        'test/chromedriver/net/sync_websocket_factory.h',
-        'test/chromedriver/net/sync_websocket_impl.cc',
-        'test/chromedriver/net/sync_websocket_impl.h',
-        'test/chromedriver/net/url_request_context_getter.cc',
-        'test/chromedriver/net/url_request_context_getter.h',
-        'test/chromedriver/net/websocket.cc',
-        'test/chromedriver/net/websocket.h',
+        '<@(chrome_automation_client_lib_sources)',
       ],
       'actions': [
         {
@@ -1432,54 +1698,7 @@
         '..',
       ],
       'sources': [
-        '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/version.cc',
-        '<(SHARED_INTERMEDIATE_DIR)/chrome/test/chromedriver/version.h',
-        '../third_party/webdriver/atoms.cc',
-        '../third_party/webdriver/atoms.h',
-        'common/chrome_constants.cc',
-        'common/chrome_constants.h',
-        'test/chromedriver/alert_commands.cc',
-        'test/chromedriver/alert_commands.h',
-        'test/chromedriver/basic_types.cc',
-        'test/chromedriver/basic_types.h',
-        'test/chromedriver/capabilities.cc',
-        'test/chromedriver/capabilities.h',
-        'test/chromedriver/chrome/browser_info.cc',
-        'test/chromedriver/chrome/browser_info.h',
-        'test/chromedriver/chrome_launcher.cc',
-        'test/chromedriver/chrome_launcher.h',
-        'test/chromedriver/command_listener.h',
-        'test/chromedriver/command_listener_proxy.cc',
-        'test/chromedriver/command_listener_proxy.h',
-        'test/chromedriver/command.h',
-        'test/chromedriver/commands.cc',
-        'test/chromedriver/commands.h',
-        'test/chromedriver/element_commands.cc',
-        'test/chromedriver/element_commands.h',
-        'test/chromedriver/element_util.cc',
-        'test/chromedriver/element_util.h',
-        'test/chromedriver/key_converter.cc',
-        'test/chromedriver/key_converter.h',
-        'test/chromedriver/keycode_text_conversion.h',
-        'test/chromedriver/keycode_text_conversion_mac.mm',
-        'test/chromedriver/keycode_text_conversion_ozone.cc',
-        'test/chromedriver/keycode_text_conversion_win.cc',
-        'test/chromedriver/keycode_text_conversion_x.cc',
-        'test/chromedriver/logging.cc',
-        'test/chromedriver/logging.h',
-        'test/chromedriver/performance_logger.cc',
-        'test/chromedriver/performance_logger.h',
-        'test/chromedriver/server/http_handler.cc',
-        'test/chromedriver/server/http_handler.h',
-        'test/chromedriver/session.cc',
-        'test/chromedriver/session.h',
-        'test/chromedriver/session_commands.cc',
-        'test/chromedriver/session_commands.h',
-        'test/chromedriver/session_thread_map.h',
-        'test/chromedriver/util.cc',
-        'test/chromedriver/util.h',
-        'test/chromedriver/window_commands.cc',
-        'test/chromedriver/window_commands.h',
+        '<@(chrome_driver_lib_sources)',
       ],
       'actions': [
         {
@@ -1552,37 +1771,7 @@
         '..,'
       ],
       'sources': [
-        'test/chromedriver/capabilities_unittest.cc',
-        'test/chromedriver/chrome/browser_info_unittest.cc',
-        'test/chromedriver/chrome/chrome_finder_unittest.cc',
-        'test/chromedriver/chrome/console_logger_unittest.cc',
-        'test/chromedriver/chrome/device_manager_unittest.cc',
-        'test/chromedriver/chrome/devtools_client_impl_unittest.cc',
-        'test/chromedriver/chrome/devtools_http_client_unittest.cc',
-        'test/chromedriver/chrome/dom_tracker_unittest.cc',
-        'test/chromedriver/chrome/frame_tracker_unittest.cc',
-        'test/chromedriver/chrome/geolocation_override_manager_unittest.cc',
-        'test/chromedriver/chrome/heap_snapshot_taker_unittest.cc',
-        'test/chromedriver/chrome/javascript_dialog_manager_unittest.cc',
-        'test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc',
-        'test/chromedriver/chrome/navigation_tracker_unittest.cc',
-        'test/chromedriver/chrome/status_unittest.cc',
-        'test/chromedriver/chrome/stub_chrome.cc',
-        'test/chromedriver/chrome/stub_chrome.h',
-        'test/chromedriver/chrome/stub_devtools_client.cc',
-        'test/chromedriver/chrome/stub_devtools_client.h',
-        'test/chromedriver/chrome/stub_web_view.cc',
-        'test/chromedriver/chrome/stub_web_view.h',
-        'test/chromedriver/chrome/web_view_impl_unittest.cc',
-        'test/chromedriver/chrome_launcher_unittest.cc',
-        'test/chromedriver/command_listener_proxy_unittest.cc',
-        'test/chromedriver/commands_unittest.cc',
-        'test/chromedriver/logging_unittest.cc',
-        'test/chromedriver/performance_logger_unittest.cc',
-        'test/chromedriver/server/http_handler_unittest.cc',
-        'test/chromedriver/session_commands_unittest.cc',
-        'test/chromedriver/session_unittest.cc',
-        'test/chromedriver/util_unittest.cc',
+        '<@(chrome_driver_unittests_sources)',
       ],
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
       'msvs_disabled_warnings': [ 4267, ],
@@ -1606,16 +1795,7 @@
         '..,'
       ],
       'sources': [
-        'test/chromedriver/key_converter_unittest.cc',
-        'test/chromedriver/keycode_text_conversion_unittest.cc',
-        'test/chromedriver/net/net_util_unittest.cc',
-        'test/chromedriver/net/port_server_unittest.cc',
-        'test/chromedriver/net/sync_websocket_impl_unittest.cc',
-        'test/chromedriver/net/test_http_server.cc',
-        'test/chromedriver/net/test_http_server.h',
-        'test/chromedriver/net/websocket_unittest.cc',
-        'test/chromedriver/test_util.cc',
-        'test/chromedriver/test_util.h',
+        '<@(chrome_driver_tests_sources)',
       ],
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
       'msvs_disabled_warnings': [ 4267, ],
@@ -2261,28 +2441,7 @@
         'HAS_OUT_OF_PROC_TEST_RUNNER',
       ],
       'sources': [
-        '../components/autofill/content/renderer/test_password_autofill_agent.cc',
-        '../components/autofill/content/renderer/test_password_autofill_agent.h',
-        '../components/autofill/content/renderer/test_password_generation_agent.cc',
-        '../components/autofill/content/renderer/test_password_generation_agent.h',
-        'app/chrome_command_ids.h',
-        'app/chrome_dll.rc',
-        'app/chrome_dll_resource.h',
-        'app/chrome_version.rc.version',
-        'browser/extensions/api/tab_capture/tab_capture_performancetest.cc',
-        'browser/extensions/api/cast_streaming/performance_test.cc',
-        'browser/extensions/browsertest_util.cc',
-        'browser/extensions/extension_apitest.cc',
-        'browser/extensions/extension_browsertest.cc',
-        'browser/extensions/extension_test_notification_observer.cc',
-        'browser/extensions/updater/extension_cache_fake.h',
-        'browser/extensions/updater/extension_cache_fake.cc',
-        'test/base/browser_perf_tests_main.cc',
-        'test/base/chrome_render_view_test.cc',
-        'test/base/chrome_render_view_test.h',
-        'test/perf/browser_perf_test.cc',
-        'test/perf/browser_perf_test.h',
-        'test/perf/mach_ports_performancetest.cc',
+        '<@(performance_browser_tests_sources)',
       ],
       'rules': [
         {
@@ -2422,68 +2581,7 @@
         'browser',
       ],
       'sources': [
-        'browser/sync/test/integration/apps_helper.cc',
-        'browser/sync/test/integration/apps_helper.h',
-        'browser/sync/test/integration/autofill_helper.cc',
-        'browser/sync/test/integration/autofill_helper.h',
-        'browser/sync/test/integration/bookmarks_helper.cc',
-        'browser/sync/test/integration/bookmarks_helper.h',
-        'browser/sync/test/integration/dictionary_helper.cc',
-        'browser/sync/test/integration/dictionary_helper.h',
-        'browser/sync/test/integration/dictionary_load_observer.cc',
-        'browser/sync/test/integration/dictionary_load_observer.h',
-        'browser/sync/test/integration/extension_settings_helper.cc',
-        'browser/sync/test/integration/extension_settings_helper.h',
-        'browser/sync/test/integration/extensions_helper.cc',
-        'browser/sync/test/integration/extensions_helper.h',
-        'browser/sync/test/integration/fake_server_invalidation_service.cc',
-        'browser/sync/test/integration/fake_server_invalidation_service.h',
-        'browser/sync/test/integration/migration_waiter.cc',
-        'browser/sync/test/integration/migration_waiter.h',
-        'browser/sync/test/integration/migration_watcher.cc',
-        'browser/sync/test/integration/migration_watcher.h',
-        'browser/sync/test/integration/multi_client_status_change_checker.cc',
-        'browser/sync/test/integration/multi_client_status_change_checker.h',
-        'browser/sync/test/integration/passwords_helper.cc',
-        'browser/sync/test/integration/passwords_helper.h',
-        'browser/sync/test/integration/p2p_invalidation_forwarder.cc',
-        'browser/sync/test/integration/p2p_invalidation_forwarder.h',
-        'browser/sync/test/integration/preferences_helper.cc',
-        'browser/sync/test/integration/preferences_helper.h',
-        'browser/sync/test/integration/profile_sync_service_harness.cc',
-        'browser/sync/test/integration/profile_sync_service_harness.h',
-        'browser/sync/test/integration/quiesce_status_change_checker.cc',
-        'browser/sync/test/integration/quiesce_status_change_checker.h',
-        'browser/sync/test/integration/retry_verifier.cc',
-        'browser/sync/test/integration/retry_verifier.h',
-        'browser/sync/test/integration/search_engines_helper.cc',
-        'browser/sync/test/integration/search_engines_helper.h',
-        'browser/sync/test/integration/sessions_helper.cc',
-        'browser/sync/test/integration/sessions_helper.h',
-        'browser/sync/test/integration/single_client_status_change_checker.cc',
-        'browser/sync/test/integration/single_client_status_change_checker.h',
-        'browser/sync/test/integration/status_change_checker.cc',
-        'browser/sync/test/integration/status_change_checker.h',
-        'browser/sync/test/integration/sync_app_helper.cc',
-        'browser/sync/test/integration/sync_app_helper.h',
-        'browser/sync/test/integration/sync_app_list_helper.cc',
-        'browser/sync/test/integration/sync_app_list_helper.h',
-        'browser/sync/test/integration/sync_datatype_helper.cc',
-        'browser/sync/test/integration/sync_datatype_helper.h',
-        'browser/sync/test/integration/sync_extension_helper.cc',
-        'browser/sync/test/integration/sync_extension_helper.h',
-        'browser/sync/test/integration/sync_extension_installer.cc',
-        'browser/sync/test/integration/sync_extension_installer.h',
-        'browser/sync/test/integration/sync_integration_test_util.cc',
-        'browser/sync/test/integration/sync_integration_test_util.h',
-        'browser/sync/test/integration/sync_test.cc',
-        'browser/sync/test/integration/sync_test.h',
-        'browser/sync/test/integration/themes_helper.cc',
-        'browser/sync/test/integration/themes_helper.h',
-        'browser/sync/test/integration/typed_urls_helper.cc',
-        'browser/sync/test/integration/typed_urls_helper.h',
-        'browser/sync/test/integration/updated_progress_marker_checker.cc',
-        'browser/sync/test/integration/updated_progress_marker_checker.h',
+        '<@(test_support_sync_integration_sources)',
       ],
       'conditions': [
         ['OS=="mac"', {
@@ -2534,58 +2632,7 @@
         'HAS_OUT_OF_PROC_TEST_RUNNER',
       ],
       'sources': [
-        'app/chrome_command_ids.h',
-        'app/chrome_dll.rc',
-        'app/chrome_dll_resource.h',
-        'app/chrome_version.rc.version',
-        'test/base/browser_tests_main.cc',
-        'test/data/resource.rc',
-        'browser/sync/test/integration/cross_platform_sync_test.cc',
-        'browser/sync/test/integration/enable_disable_test.cc',
-        'browser/sync/test/integration/migration_test.cc',
-        'browser/sync/test/integration/multiple_client_bookmarks_sync_test.cc',
-        'browser/sync/test/integration/multiple_client_dictionary_sync_test.cc',
-        'browser/sync/test/integration/multiple_client_passwords_sync_test.cc',
-        'browser/sync/test/integration/multiple_client_preferences_sync_test.cc',
-        'browser/sync/test/integration/multiple_client_sessions_sync_test.cc',
-        'browser/sync/test/integration/multiple_client_typed_urls_sync_test.cc',
-        'browser/sync/test/integration/passwords_helper.cc',
-        'browser/sync/test/integration/passwords_helper.h',
-        'browser/sync/test/integration/preferences_helper.cc',
-        'browser/sync/test/integration/preferences_helper.h',
-        'browser/sync/test/integration/search_engines_helper.cc',
-        'browser/sync/test/integration/search_engines_helper.h',
-        'browser/sync/test/integration/sessions_helper.cc',
-        'browser/sync/test/integration/sessions_helper.h',
-        'browser/sync/test/integration/single_client_app_list_sync_test.cc',
-        'browser/sync/test/integration/single_client_apps_sync_test.cc',
-        'browser/sync/test/integration/single_client_backup_rollback_test.cc',
-        'browser/sync/test/integration/single_client_bookmarks_sync_test.cc',
-        'browser/sync/test/integration/single_client_dictionary_sync_test.cc',
-        'browser/sync/test/integration/single_client_extensions_sync_test.cc',
-        'browser/sync/test/integration/single_client_passwords_sync_test.cc',
-        'browser/sync/test/integration/single_client_preferences_sync_test.cc',
-        'browser/sync/test/integration/single_client_search_engines_sync_test.cc',
-        'browser/sync/test/integration/single_client_sessions_sync_test.cc',
-        'browser/sync/test/integration/single_client_supervised_user_settings_sync_test.cc',
-        'browser/sync/test/integration/single_client_themes_sync_test.cc',
-        'browser/sync/test/integration/single_client_typed_urls_sync_test.cc',
-        'browser/sync/test/integration/sync_auth_test.cc',
-        'browser/sync/test/integration/sync_errors_test.cc',
-        'browser/sync/test/integration/sync_exponential_backoff_test.cc',
-        'browser/sync/test/integration/two_client_app_list_sync_test.cc',
-        'browser/sync/test/integration/two_client_apps_sync_test.cc',
-        'browser/sync/test/integration/two_client_autofill_sync_test.cc',
-        'browser/sync/test/integration/two_client_bookmarks_sync_test.cc',
-        'browser/sync/test/integration/two_client_dictionary_sync_test.cc',
-        'browser/sync/test/integration/two_client_extension_settings_and_app_settings_sync_test.cc',
-        'browser/sync/test/integration/two_client_extensions_sync_test.cc',
-        'browser/sync/test/integration/two_client_passwords_sync_test.cc',
-        'browser/sync/test/integration/two_client_preferences_sync_test.cc',
-        'browser/sync/test/integration/two_client_search_engines_sync_test.cc',
-        'browser/sync/test/integration/two_client_sessions_sync_test.cc',
-        'browser/sync/test/integration/two_client_themes_sync_test.cc',
-        'browser/sync/test/integration/two_client_typed_urls_sync_test.cc',
+        '<@(sync_integration_tests_sources)',
       ],
       'conditions': [
         ['OS=="linux"', {
@@ -2680,21 +2727,7 @@
         'HAS_OUT_OF_PROC_TEST_RUNNER',
       ],
       'sources': [
-        'app/chrome_command_ids.h',
-        'app/chrome_dll.rc',
-        'app/chrome_dll_resource.h',
-        'app/chrome_version.rc.version',
-        'browser/sync/test/integration/performance/autofill_sync_perf_test.cc',
-        'browser/sync/test/integration/performance/bookmarks_sync_perf_test.cc',
-        'browser/sync/test/integration/performance/dictionary_sync_perf_test.cc',
-        'browser/sync/test/integration/performance/extensions_sync_perf_test.cc',
-        'browser/sync/test/integration/performance/sync_timing_helper.cc',
-        'browser/sync/test/integration/performance/sync_timing_helper.h',
-        'browser/sync/test/integration/performance/passwords_sync_perf_test.cc',
-        'browser/sync/test/integration/performance/sessions_sync_perf_test.cc',
-        'browser/sync/test/integration/performance/typed_urls_sync_perf_test.cc',
-        'test/base/browser_perf_tests_main.cc',
-        'test/data/resource.rc',
+        '<@(sync_performance_tests_sources)',
       ],
       'conditions': [
         ['OS=="linux"', {
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 75f5df9..6c3850e 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -17,6 +17,7 @@
       # All unittests in browser, common, renderer and service.
       'browser/about_flags_unittest.cc',
       'browser/android/bookmarks/partner_bookmarks_shim_unittest.cc',
+      'browser/android/preferences/pref_service_bridge_unittest.cc',
       'browser/android/thumbnail/scoped_ptr_expiring_cache_unittest.cc',
       # mock_google_location_settings_helper could logically go in
       # test_support_unit. However tests suites in the internal repository
@@ -198,11 +199,12 @@
       'browser/chromeos/locale_change_guard_unittest.cc',
       'browser/chromeos/login/auth/cryptohome_authenticator_unittest.cc',
       'browser/chromeos/login/auth/online_attempt_unittest.cc',
+      'browser/chromeos/login/error_screens_histogram_helper_unittest.cc',
       'browser/chromeos/login/existing_user_controller_auto_login_unittest.cc',
       'browser/chromeos/login/hwid_checker_unittest.cc',
       'browser/chromeos/login/profile_auth_data_unittest.cc',
       'browser/chromeos/login/saml/saml_offline_signin_limiter_unittest.cc',
-      'browser/chromeos/login/screens/screen_context_unittest.cc',
+      'browser/chromeos/login/screens/device_disabled_screen_unittest.cc',
       'browser/chromeos/login/signin/merge_session_load_page_unittest.cc',
       'browser/chromeos/login/supervised/supervised_user_authentication_unittest.cc',
       'browser/chromeos/login/users/multi_profile_user_controller_unittest.cc',
@@ -217,6 +219,7 @@
       'browser/chromeos/net/onc_utils_unittest.cc',
       'browser/chromeos/offline/offline_load_page_unittest.cc',
       'browser/chromeos/options/network_property_ui_data_unittest.cc',
+      'browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc',
       'browser/chromeos/policy/auto_enrollment_client_unittest.cc',
       'browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc',
       'browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc',
@@ -1530,8 +1533,6 @@
         'browser/download/download_test_file_activity_observer.h',
         'browser/download/test_download_shelf.cc',
         'browser/download/test_download_shelf.h',
-        'browser/extensions/extension_action_test_util.cc',
-        'browser/extensions/extension_action_test_util.h',
         'browser/invalidation/fake_invalidation_service.cc',
         'browser/invalidation/fake_invalidation_service.h',
         'browser/media/fake_desktop_media_list.cc',
@@ -1595,8 +1596,6 @@
         'browser/ui/views/find_bar_host_unittest_util_views.cc',
         'browser/ui/website_settings/mock_permission_bubble_request.cc',
         'browser/ui/website_settings/mock_permission_bubble_request.h',
-        'common/extensions/extension_test_util.cc',
-        'common/extensions/extension_test_util.h',
         'renderer/chrome_mock_render_thread.cc',
         'renderer/chrome_mock_render_thread.h',
         'renderer/safe_browsing/mock_feature_extractor_clock.cc',
@@ -1715,14 +1714,8 @@
             'browser/chromeos/login/fake_login_utils.h',
             'browser/chromeos/login/mock_login_utils.cc',
             'browser/chromeos/login/mock_login_utils.h',
-            'browser/chromeos/login/users/avatar/mock_user_image_manager.cc',
-            'browser/chromeos/login/users/avatar/mock_user_image_manager.h',
-            'browser/chromeos/login/users/fake_supervised_user_manager.cc',
-            'browser/chromeos/login/users/fake_supervised_user_manager.h',
-            'browser/chromeos/login/users/fake_user_manager.cc',
-            'browser/chromeos/login/users/fake_user_manager.h',
-            'browser/chromeos/login/users/mock_user_manager.cc',
-            'browser/chromeos/login/users/mock_user_manager.h',
+            'browser/chromeos/login/screens/mock_device_disabled_screen_actor.cc',
+            'browser/chromeos/login/screens/mock_device_disabled_screen_actor.h',
             'browser/chromeos/login/test/oobe_screen_waiter.cc',
             'browser/chromeos/login/test/oobe_screen_waiter.h',
             'browser/chromeos/login/test/js_checker.cc',
@@ -1731,6 +1724,14 @@
             'browser/chromeos/login/ui/mock_login_display.h',
             'browser/chromeos/login/ui/mock_login_display_host.cc',
             'browser/chromeos/login/ui/mock_login_display_host.h',
+            'browser/chromeos/login/users/avatar/mock_user_image_manager.cc',
+            'browser/chromeos/login/users/avatar/mock_user_image_manager.h',
+            'browser/chromeos/login/users/fake_supervised_user_manager.cc',
+            'browser/chromeos/login/users/fake_supervised_user_manager.h',
+            'browser/chromeos/login/users/fake_user_manager.cc',
+            'browser/chromeos/login/users/fake_user_manager.h',
+            'browser/chromeos/login/users/mock_user_manager.cc',
+            'browser/chromeos/login/users/mock_user_manager.h',
             'browser/chromeos/net/network_portal_detector_test_utils.cc',
             'browser/chromeos/net/network_portal_detector_test_utils.h',
             'browser/chromeos/policy/cloud_external_data_manager_base_test_util.cc',
@@ -1798,6 +1799,8 @@
             'browser/drive/test_util.h',
             'browser/extensions/api/messaging/native_messaging_test_util.cc',
             'browser/extensions/api/messaging/native_messaging_test_util.h',
+            'browser/extensions/extension_action_test_util.cc',
+            'browser/extensions/extension_action_test_util.h',
             'browser/extensions/extension_notification_observer.cc',
             'browser/extensions/extension_notification_observer.h',
             'browser/extensions/mock_extension_special_storage_policy.cc',
@@ -1816,6 +1819,8 @@
             'browser/extensions/test_extension_system.h',
             'browser/media_galleries/media_galleries_test_util.cc',
             'browser/media_galleries/media_galleries_test_util.h',
+            'common/extensions/extension_test_util.cc',
+            'common/extensions/extension_test_util.h',
           ],
         }],
         ['OS=="win"', {
@@ -2055,6 +2060,7 @@
             ['exclude', '^browser/extensions/'],
             ['exclude', '^browser/sync/glue/extensions_activity_monitor_unittest.cc'],
             ['exclude', '^browser/sync_file_system/'],
+            ['exclude', '^browser/web_applications/'],
             ['exclude', '^common/extensions/'],
             ['exclude', '^utility/extensions/'],
             ['exclude', '^utility/image_writer/'],
@@ -2080,6 +2086,7 @@
             'browser/extensions/webstore_inline_installer_unittest.cc',
             'browser/extensions/webstore_installer_unittest.cc',
             'browser/metrics/extensions_metrics_provider_unittest.cc',
+            'browser/renderer_context_menu/context_menu_content_type_unittest.cc',
             'browser/search/hotword_service_unittest.cc',
             'browser/signin/easy_unlock_screenlock_state_handler_unittest.cc',
             'common/extensions/features/chrome_channel_feature_filter_unittest.cc',
@@ -2589,6 +2596,7 @@
             'browser/ui/webui/web_dialog_web_contents_delegate_unittest.cc',
             'browser/ui/window_sizer/window_sizer_common_unittest.cc',
             'browser/ui/window_sizer/window_sizer_unittest.cc',
+            'browser/ui/zoom/zoom_controller_unittest.cc',
             'browser/upgrade_detector_impl_unittest.cc',
             'common/net/x509_certificate_model_unittest.cc',
             'test/base/browser_with_test_window_test.cc',
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index d295f52..046475c 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -24,6 +24,8 @@
 
 # GYP version: chrome/chrome_resources.gyp:chrome_resources
 #              (generate_extensions_api_resources action)
+if (enable_extensions) {
+
 grit("extensions_api_resources") {
   source = "extensions_api_resources.grd"
   output_dir = "$root_gen_dir/chrome"
@@ -33,6 +35,8 @@
   ]
 }
 
+}
+
 # GYP version: chrome/chrome_common.gyp:common
 static_library("common") {
   sources = rebase_path(gypi_values.chrome_common_sources, ".", "//chrome")
@@ -62,8 +66,7 @@
     "//components/variations",
     "//content/public/common",
     "//crypto",
-    "//extensions:extensions_resources",
-    "//extensions/strings",
+    "//extensions/common:common_constants",
     "//media/cast:net",
     "//net",
     "//skia",
@@ -106,6 +109,8 @@
       "//chrome/common/extensions/api",
       "//extensions/common",
       "//extensions/common/api",
+      "//extensions:extensions_resources",
+      "//extensions/strings",
     ]
   }
 
@@ -288,8 +293,6 @@
   visibility = [ "//chrome/test:test_support" ]
 
   sources = [
-    "extensions/extension_test_util.cc",
-    "extensions/extension_test_util.h",
   ]
 
   deps = [
@@ -307,4 +310,11 @@
     ]
   }
 
+  if (enable_extensions) {
+    sources += [
+      "extensions/extension_test_util.cc",
+      "extensions/extension_test_util.h",
+    ]
+  }
+
 }
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc
index 1b0b5cc..66501e2 100644
--- a/chrome/common/chrome_constants.cc
+++ b/chrome/common/chrome_constants.cc
@@ -214,8 +214,6 @@
 
 const bool kRecordModeEnabled = true;
 
-const int kJavaScriptMessageExpectedDelay = 1000;
-
 #if defined(OS_ANDROID) || defined(OS_IOS)
 const bool kEnableTouchIcon = true;
 #else
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h
index 3d2fd7b5..ca4bc86c 100644
--- a/chrome/common/chrome_constants.h
+++ b/chrome/common/chrome_constants.h
@@ -109,11 +109,6 @@
 
 extern const bool kRecordModeEnabled;
 
-// If a WebContents is impolite and displays a second JavaScript alert within
-// kJavaScriptMessageExpectedDelay of a previous JavaScript alert being
-// dismissed, display an option to suppress future alerts from this WebContents.
-extern const int kJavaScriptMessageExpectedDelay;
-
 // Are touch icons enabled? False by default.
 extern const bool kEnableTouchIcon;
 
diff --git a/chrome/common/chrome_content_client_unittest.cc b/chrome/common/chrome_content_client_unittest.cc
index 4fe2853e..63dd2353 100644
--- a/chrome/common/chrome_content_client_unittest.cc
+++ b/chrome/common/chrome_content_client_unittest.cc
@@ -65,7 +65,7 @@
 #if !defined(OS_ANDROID)
   CheckUserAgentStringOrdering(false);
 #else
-  const char* kArguments[] = {"chrome"};
+  const char* const kArguments[] = {"chrome"};
   CommandLine::Reset();
   CommandLine::Init(1, kArguments);
   CommandLine* command_line = CommandLine::ForCurrentProcess();
diff --git a/chrome/common/chrome_paths_android.cc b/chrome/common/chrome_paths_android.cc
index edbac864..a78b48d 100644
--- a/chrome/common/chrome_paths_android.cc
+++ b/chrome/common/chrome_paths_android.cc
@@ -51,11 +51,9 @@
 }
 
 bool ProcessNeedsProfileDir(const std::string& process_type) {
-  // SELinux prohibits accessing the data directory for isolated services.
-  if (process_type == switches::kRendererProcess)
-    return false;
-
-  return true;
+  // SELinux prohibits accessing the data directory from isolated services. Only
+  // the browser (empty process type) should access the profile directory.
+  return process_type.empty();
 }
 
 }  // namespace chrome
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc
index 9befa21..9a03923 100644
--- a/chrome/common/crash_keys.cc
+++ b/chrome/common/crash_keys.cc
@@ -166,12 +166,6 @@
     { "channel_error_bt", kMediumSize },
     { "remove_route_bt", kMediumSize },
     { "rwhvm_window", kMediumSize },
-    // The following keys are for diagnosing crashes in http://crbug.com/369661.
-    // They will not be permanent.
-    { "renderer_page_id", kSmallSize },
-    { "browser_page_id", kSmallSize },
-    { "last_committed_page_id", kSmallSize },
-    // End http://crbug.com/369661
     // media/:
     { "VideoCaptureDeviceQTKit", kSmallSize },
 #endif
@@ -271,7 +265,7 @@
          flag == "--flag-switches-begin" ||
          flag == "--flag-switches-end";
 #elif defined(OS_CHROMEOS)
-  static const char* kIgnoreSwitches[] = {
+  static const char* const kIgnoreSwitches[] = {
     ::switches::kEnableImplSidePainting,
     ::switches::kEnableLogging,
     ::switches::kFlagSwitchesBegin,
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 5cc6684..8e109cf 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -719,7 +719,8 @@
       "0EEDFC0EED87871237213F34EBC7B4982A195C95",  // http://crbug.com/374955
       "D2DAA9362153E8A5E3CF593E6DF4666421ABAD21",  // http://crbug.com/374965
       "D7986543275120831B39EF28D1327552FC343960",  // http://crbug.com/378067
-      "A291B26E088FA6BA53FFD72F0916F06EBA7C585A"   // http://crbug.com/378067
+      "A291B26E088FA6BA53FFD72F0916F06EBA7C585A",  // http://crbug.com/378067
+      "62CCAAD339E6451BBF97C4BBDF758E934A05AD0B"   // Hotword triggering
     ]
   },
   "mdns": {
diff --git a/chrome/common/extensions/api/copresence_private.idl b/chrome/common/extensions/api/copresence_private.idl
index 9b0e12df..91d777b 100644
--- a/chrome/common/extensions/api/copresence_private.idl
+++ b/chrome/common/extensions/api/copresence_private.idl
@@ -5,6 +5,10 @@
 // Use the <code>chrome.copresencePrivate</code> API to interface with Chrome
 // from the whispernet_proxy extension.
 namespace copresencePrivate {
+  dictionary DecodeSamplesParameters {
+    boolean decodeAudible;
+    boolean decodeInaudible;
+  };
 
   dictionary PlayParameters {
     double sampleRate;
@@ -47,7 +51,8 @@
     // Fired to request encoding of the given token.
     static void onEncodeTokenRequest(DOMString base64Token, boolean audible);
     // Fired when we have new samples to decode.
-    static void onDecodeSamplesRequest(ArrayBuffer audioSamples);
+    static void onDecodeSamplesRequest(ArrayBuffer samples,
+                                       DecodeSamplesParameters request);
     // Fired to request a DetectBroadcast.
     static void onDetectBroadcastRequest();
   };
diff --git a/chrome/common/extensions/api/file_system.idl b/chrome/common/extensions/api/file_system.idl
index ce56768..8cb65f5 100644
--- a/chrome/common/extensions/api/file_system.idl
+++ b/chrome/common/extensions/api/file_system.idl
@@ -84,14 +84,14 @@
   };
 
   // Change to an entry within a tracked directory.
-  dictionary ChildChange {
+  [nodoc] dictionary ChildChange {
     [instanceOf=Entry] object entry;
     ChildChangeType type;
   };
 
   // Event notifying about a change in a file or a directory, including its
   // contents.
-  dictionary EntryChangedEvent {
+  [nodoc] dictionary EntryChangedEvent {
     // Tracked entry.
     [instanceOf=Entry] object target;
 
@@ -101,7 +101,7 @@
   };
 
   // Event notifying about a tracked file or a directory being removed.
-  dictionary EntryRemovedEvent {
+  [nodoc] dictionary EntryRemovedEvent {
     [instanceOf=Entry] object target;
   };
 
@@ -112,7 +112,7 @@
       [instanceOf=FileEntry] optional object[] fileEntries);
   callback IsWritableCallback = void (boolean isWritable);
   callback IsRestorableCallback = void (boolean isRestorable);
-  callback GetObservedEntriesCallback = void (
+  [nodoc] callback GetObservedEntriesCallback = void (
       [instanceOf=Entry] object[] entries);
 
   interface Functions {
diff --git a/chrome/common/extensions/api/input_ime.json b/chrome/common/extensions/api/input_ime.json
index 5d9b212..10671c4f 100644
--- a/chrome/common/extensions/api/input_ime.json
+++ b/chrome/common/extensions/api/input_ime.json
@@ -31,7 +31,10 @@
         "description": "Describes an input Context",
         "properties": {
           "contextID": {"type": "integer", "description": "This is used to specify targets of text field operations.  This ID becomes invalid as soon as onBlur is called."},
-          "type": {"type": "string", "description": "Type of value this text field edits, (Text, Number, URL, etc)", "enum": ["text", "search", "tel", "url", "email", "number", "password"]}
+          "type": {"type": "string", "description": "Type of value this text field edits, (Text, Number, URL, etc)", "enum": ["text", "search", "tel", "url", "email", "number", "password"]},
+          "autoCorrect": {"type": "boolean", "description": "Whether the text field wants auto-correct."},
+          "autoComplete": {"type": "boolean", "description": "Whether the text field wants auto-complete."},
+          "spellCheck": {"type": "boolean", "description": "Whether the text field wants spell-check."}
         }
       },
       {
diff --git a/chrome/common/extensions/api/input_method_private.json b/chrome/common/extensions/api/input_method_private.json
index 0d11f64..d7d2074 100644
--- a/chrome/common/extensions/api/input_method_private.json
+++ b/chrome/common/extensions/api/input_method_private.json
@@ -9,6 +9,28 @@
     "description": "none",
     "functions": [
       {
+        "name": "getInputMethodConfig",
+        "type": "function",
+        "description": "Gets configurations for input methods.",
+        "parameters": [
+          {
+            "name": "callback",
+            "type": "function",
+            "optional": false,
+            "description": "Callback which is called with the config object.",
+            "parameters": [
+              {
+                "name": "config",
+                "type": "object",
+                "description": "The input method config object.",
+                "properties": {
+                  "isPhysicalKeyboardAutocorrectEnabled": {"type": "boolean"}
+                }
+              }
+            ]
+          }
+        ]
+      }, {
         "name": "getInputMethods",
         "type": "function",
         "description": "Gets all whitelisted input methods.",
diff --git a/chrome/common/extensions/api/webstore/webstore_api_constants.cc b/chrome/common/extensions/api/webstore/webstore_api_constants.cc
index 5aa92b15..04cd627 100644
--- a/chrome/common/extensions/api/webstore/webstore_api_constants.cc
+++ b/chrome/common/extensions/api/webstore/webstore_api_constants.cc
@@ -14,7 +14,7 @@
 // IMPORTANT: Keep this list in sync with both the definition in
 // chrome/common/extensions/api/webstore.json and
 // chrome/common/extensions/webstore_install_result.h!
-const char* kInstallResultCodes[] = {
+const char* const kInstallResultCodes[] = {
   "success",
   "otherError",
   "aborted",
diff --git a/chrome/common/extensions/api/webstore/webstore_api_constants.h b/chrome/common/extensions/api/webstore/webstore_api_constants.h
index f42327e9..8a6b490 100644
--- a/chrome/common/extensions/api/webstore/webstore_api_constants.h
+++ b/chrome/common/extensions/api/webstore/webstore_api_constants.h
@@ -26,7 +26,7 @@
 // IMPORTANT: Keep this list in sync with both the definition in
 // chrome/common/extensions/api/webstore.json and
 // chrome/common/extensions/webstore_install_result.h!
-extern const char* kInstallResultCodes[];
+extern const char* const kInstallResultCodes[];
 
 extern const char kInstallStageDownloading[];
 extern const char kInstallStageInstalling[];
diff --git a/chrome/common/extensions/docs/server2/api_data_source.py b/chrome/common/extensions/docs/server2/api_data_source.py
index c28dbe8..c28984c 100644
--- a/chrome/common/extensions/docs/server2/api_data_source.py
+++ b/chrome/common/extensions/docs/server2/api_data_source.py
@@ -53,7 +53,7 @@
 
     # Parsing samples on the preview server takes forever, so disable it.
     if IsPreviewServer():
-      samples_futures = Future(value=[])
+      samples_future = Future(value=[])
     else:
       samples_future = (self._platform_bundle.GetSamplesModel(platform)
           .FilterSamples(api_name))
diff --git a/chrome/common/extensions/docs/server2/appengine_wrappers.py b/chrome/common/extensions/docs/server2/appengine_wrappers.py
index 4c554393..18542bd 100644
--- a/chrome/common/extensions/docs/server2/appengine_wrappers.py
+++ b/chrome/common/extensions/docs/server2/appengine_wrappers.py
@@ -166,8 +166,9 @@
 
     class Client(object):
       def set_multi_async(self, mapping, namespace='', time=0):
-        for k, v in mapping.iteritems():
-          memcache.set(k, v, namespace=namespace, time=time)
+        return _RPC(result=dict(
+          (k, memcache.set(k, v, namespace=namespace, time=time))
+           for k, v in mapping.iteritems()))
 
       def get_multi_async(self, keys, namespace='', time=0):
         return _RPC(result=dict(
diff --git a/chrome/common/extensions/docs/server2/cache_chain_object_store.py b/chrome/common/extensions/docs/server2/cache_chain_object_store.py
index 6741d5f5..6fba846 100644
--- a/chrome/common/extensions/docs/server2/cache_chain_object_store.py
+++ b/chrome/common/extensions/docs/server2/cache_chain_object_store.py
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-from future import Future
+from future import All, Future
 from object_store import ObjectStore
 
 
@@ -29,8 +29,8 @@
 
   def SetMulti(self, mapping):
     self._cache.update(mapping)
-    for object_store in self._object_stores:
-      object_store.SetMulti(mapping)
+    return All([object_store.SetMulti(mapping)
+                for object_store in self._object_stores])
 
   def GetMulti(self, keys):
     missing_keys = list(keys)
diff --git a/chrome/common/extensions/docs/server2/memcache_object_store.py b/chrome/common/extensions/docs/server2/memcache_object_store.py
index 78d9241..9f1a4250 100644
--- a/chrome/common/extensions/docs/server2/memcache_object_store.py
+++ b/chrome/common/extensions/docs/server2/memcache_object_store.py
@@ -5,9 +5,10 @@
 import logging
 
 from appengine_wrappers import memcache
+from future import Future
 from object_store import ObjectStore
 
-class _AsyncMemcacheGetFuture(object):
+class _AsyncMemcacheIOFuture(object):
   def __init__(self, rpc):
     self._rpc = rpc
 
@@ -22,16 +23,18 @@
     # talking_alarm_clock always fails because the zip is too big.
     # TODO(kalman): store example zips in blobstore.
     if any(key.find('talking_alarm_clock') != -1 for key in mapping.iterkeys()):
-      return
+      return Future(value=None)
     try:
-      memcache.Client().set_multi_async(mapping, namespace=self._namespace)
+      rpc = memcache.Client().set_multi_async(mapping,
+          namespace=self._namespace)
+      return _AsyncMemcacheIOFuture(rpc)
     except ValueError as e:
       logging.error('Caught "ValueError: %s" when mapping keys %s' % (
           e, mapping.keys()))
 
   def GetMulti(self, keys):
     rpc = memcache.Client().get_multi_async(keys, namespace=self._namespace)
-    return _AsyncMemcacheGetFuture(rpc)
+    return _AsyncMemcacheIOFuture(rpc)
 
   def DelMulti(self, keys):
     memcache.delete_multi(keys, namespace=self._namespace)
diff --git a/chrome/common/extensions/docs/server2/object_store.py b/chrome/common/extensions/docs/server2/object_store.py
index 51dedd0..b56986b 100644
--- a/chrome/common/extensions/docs/server2/object_store.py
+++ b/chrome/common/extensions/docs/server2/object_store.py
@@ -21,12 +21,14 @@
     raise NotImplementedError(self.__class__)
 
   def Set(self, key, value):
-    '''Sets key -> value in the object store.
+    '''Sets key -> value in the object store. Returns a |Future| which is
+    resolved once the key's new value has been stored.
     '''
-    self.SetMulti({ key: value })
+    return self.SetMulti({ key: value })
 
   def SetMulti(self, items):
     '''Atomically sets the mapping of keys to values in the object store.
+    Returns a |Future| which is resolved once the new mapping has been stored.
     '''
     raise NotImplementedError(self.__class__)
 
diff --git a/chrome/common/extensions/docs/server2/persistent_object_store.py b/chrome/common/extensions/docs/server2/persistent_object_store.py
index 0feb6d81..c0ae873 100644
--- a/chrome/common/extensions/docs/server2/persistent_object_store.py
+++ b/chrome/common/extensions/docs/server2/persistent_object_store.py
@@ -5,7 +5,7 @@
 from appengine_wrappers import db
 from datastore_models import PersistentObjectStoreItem
 from environment import IsDevServer
-from future import Future
+from future import All, Future
 from object_store import ObjectStore
 
 
@@ -16,14 +16,14 @@
     self._namespace = namespace
 
   def SetMulti(self, mapping):
-    futures = []
-    for key, value in mapping.items():
-      futures.append(db.put_async(
-          PersistentObjectStoreItem.CreateItem(self._namespace, key, value)))
+    rpcs = [db.put_async(
+        PersistentObjectStoreItem.CreateItem(self._namespace, key, value))
+        for key, value in mapping.iteritems()]
     # If running the dev server, the futures don't complete until the server is
     # *quitting*. This is annoying. Flush now.
     if IsDevServer():
-      [future.wait() for future in futures]
+      [rpc.wait() for rpc in rpcs]
+    return All(Future(callback=lambda: rpc.get_result()) for rpc in rpcs)
 
   def GetMulti(self, keys):
     db_futures = dict(
diff --git a/chrome/common/extensions/docs/server2/test_object_store.py b/chrome/common/extensions/docs/server2/test_object_store.py
index 65f6249..386828c 100644
--- a/chrome/common/extensions/docs/server2/test_object_store.py
+++ b/chrome/common/extensions/docs/server2/test_object_store.py
@@ -34,6 +34,7 @@
   def SetMulti(self, mapping):
     self._set_count += 1
     self._store.update(mapping)
+    return Future(value=None)
 
   def DelMulti(self, keys):
     self._del_count += 1
diff --git a/chrome/common/extensions/manifest_handlers/app_launch_info.cc b/chrome/common/extensions/manifest_handlers/app_launch_info.cc
index 69748693..7fab5b3 100644
--- a/chrome/common/extensions/manifest_handlers/app_launch_info.cc
+++ b/chrome/common/extensions/manifest_handlers/app_launch_info.cc
@@ -306,7 +306,7 @@
 }
 
 const std::vector<std::string> AppLaunchManifestHandler::Keys() const {
-  static const char* keys[] = {
+  static const char* const keys[] = {
     keys::kLaunchLocalPath,
     keys::kLaunchWebURL,
     keys::kLaunchContainer,
diff --git a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
index e10c88f3..7f7cba97 100644
--- a/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
+++ b/chrome/common/extensions/manifest_handlers/content_scripts_handler.cc
@@ -387,7 +387,7 @@
 }
 
 const std::vector<std::string> ContentScriptsHandler::Keys() const {
-  static const char* keys[] = {
+  static const char* const keys[] = {
     keys::kContentScripts
   };
   return std::vector<std::string>(keys, keys + arraysize(keys));
diff --git a/chrome/common/extensions/manifest_handlers/settings_overrides_handler.cc b/chrome/common/extensions/manifest_handlers/settings_overrides_handler.cc
index 55b3247..67683db8 100644
--- a/chrome/common/extensions/manifest_handlers/settings_overrides_handler.cc
+++ b/chrome/common/extensions/manifest_handlers/settings_overrides_handler.cc
@@ -27,7 +27,7 @@
 namespace extensions {
 namespace {
 
-const char* kWwwPrefix = "www.";
+const char kWwwPrefix[] = "www.";
 
 scoped_ptr<GURL> CreateManifestURL(const std::string& url) {
   scoped_ptr<GURL> manifest_url(new GURL(url));
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
index 6c168e0a..296030c09 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
@@ -102,7 +102,7 @@
 TEST_F(PlatformAppsManifestTest, CertainApisRequirePlatformApps) {
   // Put APIs here that should be restricted to platform apps, but that haven't
   // yet graduated from experimental.
-  const char* kPlatformAppExperimentalApis[] = {
+  const char* const kPlatformAppExperimentalApis[] = {
     "dns",
     "serial",
   };
diff --git a/chrome/common/extensions/update_manifest_unittest.cc b/chrome/common/extensions/update_manifest_unittest.cc
index 75ee71c..36ea5d5b 100644
--- a/chrome/common/extensions/update_manifest_unittest.cc
+++ b/chrome/common/extensions/update_manifest_unittest.cc
@@ -7,7 +7,7 @@
 #include "libxml/globals.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-static const char* kValidXml =
+static const char kValidXml[] =
 "<?xml version='1.0' encoding='UTF-8'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <app appid='12345'>"
@@ -16,7 +16,7 @@
 " </app>"
 "</gupdate>";
 
-const char *valid_xml_with_hash =
+static const char valid_xml_with_hash[] =
 "<?xml version='1.0' encoding='UTF-8'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <app appid='12345'>"
@@ -26,7 +26,7 @@
 " </app>"
 "</gupdate>";
 
-static const char*  kMissingAppId =
+static const char kMissingAppId[] =
 "<?xml version='1.0'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <app>"
@@ -35,7 +35,7 @@
 " </app>"
 "</gupdate>";
 
-static const char*  kInvalidCodebase =
+static const char kInvalidCodebase[] =
 "<?xml version='1.0'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <app appid='12345' status='ok'>"
@@ -44,7 +44,7 @@
 " </app>"
 "</gupdate>";
 
-static const char*  kMissingVersion =
+static const char kMissingVersion[] =
 "<?xml version='1.0'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <app appid='12345' status='ok'>"
@@ -52,7 +52,7 @@
 " </app>"
 "</gupdate>";
 
-static const char*  kInvalidVersion =
+static const char kInvalidVersion[] =
 "<?xml version='1.0'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <app appid='12345' status='ok'>"
@@ -61,7 +61,7 @@
 " </app>"
 "</gupdate>";
 
-static const char* kUsesNamespacePrefix =
+static const char kUsesNamespacePrefix[] =
 "<?xml version='1.0' encoding='UTF-8'?>"
 "<g:gupdate xmlns:g='http://www.google.com/update2/response' protocol='2.0'>"
 " <g:app appid='12345'>"
@@ -72,7 +72,7 @@
 
 // Includes unrelated <app> tags from other xml namespaces - this should
 // not cause problems.
-static const char* kSimilarTagnames =
+static const char kSimilarTagnames[] =
 "<?xml version='1.0' encoding='UTF-8'?>"
 "<gupdate xmlns='http://www.google.com/update2/response'"
 "         xmlns:a='http://a' protocol='2.0'>"
@@ -85,7 +85,7 @@
 "</gupdate>";
 
 // Includes a <daystart> tag.
-static const char* kWithDaystart =
+static const char kWithDaystart[] =
 "<?xml version='1.0' encoding='UTF-8'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <daystart elapsed_seconds='456' />"
@@ -96,7 +96,7 @@
 "</gupdate>";
 
 // Indicates no updates available - this should not be a parse error.
-static const char* kNoUpdate =
+static const char kNoUpdate[] =
 "<?xml version='1.0' encoding='UTF-8'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <app appid='12345'>"
@@ -105,7 +105,7 @@
 "</gupdate>";
 
 // Includes two <app> tags, one with an error.
-static const char* kTwoAppsOneError =
+static const char kTwoAppsOneError[] =
 "<?xml version='1.0' encoding='UTF-8'?>"
 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
 " <app appid='aaaaaaaa' status='error-unknownApplication'>"
diff --git a/chrome/common/mac/mock_launchd.cc b/chrome/common/mac/mock_launchd.cc
index 6f48482..237e3ed 100644
--- a/chrome/common/mac/mock_launchd.cc
+++ b/chrome/common/mac/mock_launchd.cc
@@ -51,7 +51,7 @@
 
   chrome::VersionInfo version_info;
 
-  const char* info_plist_format =
+  const char info_plist_format[] =
       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
       "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
           "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
diff --git a/chrome/common/mac/objc_zombie.mm b/chrome/common/mac/objc_zombie.mm
index b869993..7fb9aee 100644
--- a/chrome/common/mac/objc_zombie.mm
+++ b/chrome/common/mac/objc_zombie.mm
@@ -175,7 +175,7 @@
 // easy to use DCHECK to dump only in debug builds.
 BOOL DumpDeallocTrace(const void* const* array, int size) {
   // Async-signal safe version of fputs, consistent with StackTrace::Print().
-  const char* message = "Backtrace from -dealloc:\n";
+  const char message[] = "Backtrace from -dealloc:\n";
   ignore_result(HANDLE_EINTR(write(STDERR_FILENO, message, strlen(message))));
   base::debug::StackTrace(array, size).Print();
 
diff --git a/chrome/common/net/PRESUBMIT.py b/chrome/common/net/PRESUBMIT.py
index 05acff5..20f41f6d 100644
--- a/chrome/common/net/PRESUBMIT.py
+++ b/chrome/common/net/PRESUBMIT.py
@@ -11,12 +11,12 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_rel_swarming': set(['defaulttests']),
+      'linux_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.mac': {
-      'mac_chromium_rel_swarming': set(['defaulttests']),
+      'mac_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.win': {
-      'win_chromium_rel_swarming': set(['defaulttests']),
+      'win_chromium_rel': set(['defaulttests']),
     }
   }
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index b28a53d8..fdf2232 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -999,11 +999,6 @@
 // If a value is not set, it means the setting is allowed.
 const char kOverrideContentSettings[] = "profile.override_content_settings";
 
-// Boolean indicating whether the clear on exit pref was migrated to content
-// settings yet.
-const char kContentSettingsClearOnExitMigrated[] =
-    "profile.content_settings.clear_on_exit_migrated";
-
 // Version of the pattern format used to define content settings.
 const char kContentSettingsVersion[] = "profile.content_settings.pref_version";
 
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 0c98324..ae7998c 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -324,7 +324,6 @@
 extern const char kUseCustomChromeFrame[];
 extern const char kDefaultContentSettings[];
 extern const char kOverrideContentSettings[];
-extern const char kContentSettingsClearOnExitMigrated[];
 extern const char kContentSettingsVersion[];
 extern const char kContentSettingsPatternPairs[];
 extern const char kContentSettingsPluginWhitelist[];
diff --git a/chrome/common/service_process_util_win.cc b/chrome/common/service_process_util_win.cc
index 8e3cde3..9e358a7 100644
--- a/chrome/common/service_process_util_win.cc
+++ b/chrome/common/service_process_util_win.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-const char* kTerminateEventSuffix = "_service_terminate_evt";
+const char kTerminateEventSuffix[] = "_service_terminate_evt";
 
 base::string16 GetServiceProcessReadyEventName() {
   return base::UTF8ToWide(
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 851a14a..e7989f4 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -96,6 +96,7 @@
 const char kChromeUIVoiceSearchURL[] = "chrome://voicesearch/";
 
 #if defined(OS_ANDROID)
+const char kChromeUINativeScheme[] = "chrome-native";
 const char kChromeUINativeNewTabURL[] = "chrome-native://newtab/";
 const char kChromeUINativeBookmarksURL[] = "chrome-native://bookmarks/";
 const char kChromeUINativeRecentTabsURL[] = "chrome-native://recent-tabs/";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 0f15bad..d8fd8cd 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -89,6 +89,7 @@
 extern const char kChromeUIVoiceSearchURL[];
 
 #if defined(OS_ANDROID)
+extern const char kChromeUINativeScheme[];
 extern const char kChromeUINativeNewTabURL[];
 extern const char kChromeUINativeBookmarksURL[];
 extern const char kChromeUINativeRecentTabsURL[];
diff --git a/chrome/installer/linux/sysroot_scripts/install-debian.wheezy.sysroot.py b/chrome/installer/linux/sysroot_scripts/install-debian.wheezy.sysroot.py
index 35b5a94..91c168a 100755
--- a/chrome/installer/linux/sysroot_scripts/install-debian.wheezy.sysroot.py
+++ b/chrome/installer/linux/sysroot_scripts/install-debian.wheezy.sysroot.py
@@ -26,15 +26,20 @@
 
 
 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-URL_PREFIX = 'https://commondatastorage.googleapis.com'
+URL_PREFIX = 'http://storage.googleapis.com'
 URL_PATH = 'chrome-linux-sysroot/toolchain'
-REVISION = 264817
+REVISION_AMD64 = 264817
+REVISION_I386 = 264817
+REVISION_ARM = 285950
 TARBALL_AMD64 = 'debian_wheezy_amd64_sysroot.tgz'
 TARBALL_I386 = 'debian_wheezy_i386_sysroot.tgz'
+TARBALL_ARM = 'debian_wheezy_arm_sysroot.tgz'
 TARBALL_AMD64_SHA1SUM = '74b7231e12aaf45c5c5489d9aebb56bd6abb3653'
 TARBALL_I386_SHA1SUM = 'fe3d284926839683b00641bc66c9023f872ea4b4'
+TARBALL_ARM_SHA1SUM = 'fc2f54db168887c5190c4c6686c869bedf668b4e'
 SYSROOT_DIR_AMD64 = 'debian_wheezy_amd64-sysroot'
 SYSROOT_DIR_I386 = 'debian_wheezy_i386-sysroot'
+SYSROOT_DIR_ARM = 'debian_wheezy_arm-sysroot'
 
 
 def get_sha1(filename):
@@ -50,7 +55,7 @@
 
 
 def main(args):
-  if options.arch not in ['amd64', 'i386']:
+  if options.arch not in ['amd64', 'i386', 'arm']:
     print 'Unknown architecture: %s' % options.arch
     return 1
 
@@ -60,27 +65,33 @@
     if not sys.platform.startswith('linux'):
       return 0
 
-    # Only install the sysroot for an Official Chrome Linux build.
-    defined = ['branding=Chrome', 'buildtype=Official']
-    undefined = ['chromeos=1']
     gyp_defines = os.environ.get('GYP_DEFINES', '')
-    for option in defined:
-      if option not in gyp_defines:
-        return 0
-    for option in undefined:
-      if option in gyp_defines:
-        return 0
+
+    # Only install the sysroot for an Official Chrome Linux build, except
+    # for ARM where we always use a sysroot.
+    if options.arch != 'arm':
+      defined = ['branding=Chrome', 'buildtype=Official']
+      undefined = ['chromeos=1']
+      for option in defined:
+        if option not in gyp_defines:
+          return 0
+      for option in undefined:
+        if option in gyp_defines:
+          return 0
 
     # Check for optional target_arch and only install for that architecture.
     # If target_arch is not specified, then only install for the host
     # architecture.
-    host_arch = ''
+    target_arch = ''
     if 'target_arch=x64' in gyp_defines:
-      host_arch = 'amd64'
+      target_arch = 'amd64'
     elif 'target_arch=ia32' in gyp_defines:
-      host_arch = 'i386'
+      target_arch = 'i386'
+    elif 'target_arch=arm' in gyp_defines:
+      target_arch = 'arm'
     else:
-      # Figure out host arch using build/detect_host_arch.py.
+      # Figure out host arch using build/detect_host_arch.py and
+      # set target_arch to host arch
       SRC_DIR = os.path.abspath(
           os.path.join(SCRIPT_DIR, '..', '..', '..', '..'))
       sys.path.append(os.path.join(SRC_DIR, 'build'))
@@ -88,10 +99,13 @@
 
       detected_host_arch = detect_host_arch.HostArch()
       if detected_host_arch == 'x64':
-        host_arch = 'amd64'
+        target_arch = 'amd64'
       elif detected_host_arch == 'ia32':
-        host_arch = 'i386'
-    if host_arch != options.arch:
+        target_arch = 'i386'
+      elif detected_host_arch == 'arm':
+        target_arch = 'arm'
+
+    if target_arch != options.arch:
       return 0
 
   # The sysroot directory should match the one specified in build/common.gypi.
@@ -102,11 +116,22 @@
     sysroot = os.path.join(linux_dir, SYSROOT_DIR_AMD64)
     tarball_filename = TARBALL_AMD64
     tarball_sha1sum = TARBALL_AMD64_SHA1SUM
-  else:
+    revision = REVISION_AMD64
+  elif options.arch == 'arm':
+    sysroot = os.path.join(linux_dir, SYSROOT_DIR_ARM)
+    tarball_filename = TARBALL_ARM
+    tarball_sha1sum = TARBALL_ARM_SHA1SUM
+    revision = REVISION_ARM
+  elif options.arch == 'i386':
     sysroot = os.path.join(linux_dir, SYSROOT_DIR_I386)
     tarball_filename = TARBALL_I386
     tarball_sha1sum = TARBALL_I386_SHA1SUM
-  url = '%s/%s/%s/%s' % (URL_PREFIX, URL_PATH, REVISION, tarball_filename)
+    revision = REVISION_I386
+  else:
+    assert(false)
+
+
+  url = '%s/%s/%s/%s' % (URL_PREFIX, URL_PATH, revision, tarball_filename)
 
   stamp = os.path.join(sysroot, '.stamp')
   if os.path.exists(stamp):
@@ -121,7 +146,10 @@
     shutil.rmtree(sysroot)
   os.mkdir(sysroot)
   tarball = os.path.join(sysroot, tarball_filename)
-  subprocess.check_call(['curl', '-L', url, '-o', tarball])
+  print 'Downloading %s' % url
+  sys.stdout.flush()
+  sys.stderr.flush()
+  subprocess.check_call(['curl', '--fail', '-L', url, '-o', tarball])
   sha1sum = get_sha1(tarball)
   if sha1sum != tarball_sha1sum:
     print 'Tarball sha1sum is wrong.'
@@ -137,10 +165,9 @@
 
 if __name__ == '__main__':
   parser = optparse.OptionParser('usage: %prog [OPTIONS]')
-  parser.add_option('', '--linux-only', dest='linux_only', action='store_true',
+  parser.add_option('--linux-only', action='store_true',
                     default=False, help='Only install sysroot for official '
                                         'Linux builds')
-  parser.add_option('', '--arch', dest='arch',
-                    help='Sysroot architecture, i386 or amd64')
+  parser.add_option('--arch', help='Sysroot architecture: i386, amd64 or arm')
   options, args = parser.parse_args()
-  sys.exit(main(options))
+  sys.exit(main(args))
diff --git a/chrome/installer/util/master_preferences_unittest.cc b/chrome/installer/util/master_preferences_unittest.cc
index 6c162d79..56c7f8c1 100644
--- a/chrome/installer/util/master_preferences_unittest.cc
+++ b/chrome/installer/util/master_preferences_unittest.cc
@@ -80,7 +80,7 @@
   installer::MasterPreferences prefs(prefs_file());
   EXPECT_TRUE(prefs.read_from_file());
 
-  const char* expected_true[] = {
+  const char* const expected_true[] = {
     installer::master_preferences::kDistroImportSearchPref,
     installer::master_preferences::kDistroImportHistoryPref,
     installer::master_preferences::kDistroImportBookmarksPref,
@@ -153,7 +153,7 @@
     EXPECT_EQ(value, expected_bool[i].expected_value) << expected_bool[i].name;
   }
 
-  const char* missing_bools[] = {
+  const char* const missing_bools[] = {
     installer::master_preferences::kDistroImportHomePagePref,
     installer::master_preferences::kDoNotRegisterForUpdateLaunch,
     installer::master_preferences::kMakeChromeDefault,
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index cf901ba..fd1a6c3 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -2445,7 +2445,7 @@
   app_info.file_type_name = file_type_name;
   app_info.file_type_icon_path = icon_path.value();
   app_info.file_type_icon_index = 0;
-  app_info.command_line = command_line.GetCommandLineString();
+  app_info.command_line = command_line.GetCommandLineStringWithPlaceholders();
   RegistryEntry::GetProgIdEntries(app_info, &entries);
 
   // Associate each extension that the app can handle with the class. Set this
diff --git a/chrome/installer/util/shell_util_unittest.cc b/chrome/installer/util/shell_util_unittest.cc
index a6de4c5..1897e8b3 100644
--- a/chrome/installer/util/shell_util_unittest.cc
+++ b/chrome/installer/util/shell_util_unittest.cc
@@ -825,7 +825,10 @@
 
   static base::CommandLine OpenCommand() {
     base::FilePath open_command_path(kTestOpenCommand);
-    return base::CommandLine(open_command_path);
+    base::CommandLine open_command(open_command_path);
+    // The "%1" should automatically be quoted.
+    open_command.AppendArg("%1");
+    return open_command;
   }
 
   static std::set<base::string16> FileExtensions() {
@@ -868,7 +871,7 @@
                      L"Software\\Classes\\TestApp\\shell\\open\\command",
                      KEY_READ));
   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(L"", &value));
-  EXPECT_EQ(L"\"C:\\test.exe\"", value);
+  EXPECT_EQ(L"\"C:\\test.exe\" \"%1\"", value);
 
   // .test1 should be default-associated with our test app.
   ASSERT_EQ(
diff --git a/chrome/renderer/autofill/password_generation_agent_browsertest.cc b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
index 1e85b948..52d8100d 100644
--- a/chrome/renderer/autofill/password_generation_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
@@ -207,9 +207,21 @@
   // textFieldDidChange posts a task, so we need to wait until it's been
   // processed.
   base::MessageLoop::current()->RunUntilIdle();
-
   EXPECT_EQ(edited_password, first_password_element.value());
   EXPECT_EQ(edited_password, second_password_element.value());
+
+  // Verify that password mirroring works correctly even when the password
+  // is deleted.
+  base::string16 empty_password;
+  first_password_element.setValue(empty_password);
+  // Cast to WebAutofillClient where textFieldDidChange() is public.
+  static_cast<blink::WebAutofillClient*>(autofill_agent_)->textFieldDidChange(
+      first_password_element);
+  // textFieldDidChange posts a task, so we need to wait until it's been
+  // processed.
+  base::MessageLoop::current()->RunUntilIdle();
+  EXPECT_EQ(empty_password, first_password_element.value());
+  EXPECT_EQ(empty_password, second_password_element.value());
 }
 
 TEST_F(PasswordGenerationAgentTest, BlacklistedTest) {
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index b0ff9203..9f99262d 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -19,9 +19,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/chrome_version_info.h"
 #include "chrome/common/crash_keys.h"
-#include "chrome/common/extensions/chrome_extensions_client.h"
 #include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/extension_process_policy.h"
 #include "chrome/common/localized_error.h"
 #include "chrome/common/pepper_permission_util.h"
 #include "chrome/common/render_messages.h"
@@ -79,10 +77,6 @@
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/render_view_visitor.h"
 #include "extensions/common/constants.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/extension_set.h"
-#include "extensions/common/extension_urls.h"
-#include "extensions/common/switches.h"
 #include "ipc/ipc_sync_channel.h"
 #include "net/base/net_errors.h"
 #include "ppapi/c/private/ppb_nacl_private.h"
@@ -112,11 +106,17 @@
 #endif
 
 #if defined(ENABLE_EXTENSIONS)
+#include "chrome/common/extensions/chrome_extensions_client.h"
+#include "chrome/common/extensions/extension_process_policy.h"
 #include "chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.h"
 #include "chrome/renderer/extensions/chrome_extensions_renderer_client.h"
 #include "chrome/renderer/extensions/extension_frame_helper.h"
 #include "chrome/renderer/extensions/renderer_permissions_policy_delegate.h"
 #include "chrome/renderer/extensions/resource_request_policy.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_set.h"
+#include "extensions/common/extension_urls.h"
+#include "extensions/common/switches.h"
 #include "extensions/renderer/dispatcher.h"
 #include "extensions/renderer/extension_helper.h"
 #include "extensions/renderer/extensions_render_frame_observer.h"
@@ -268,9 +268,9 @@
 ChromeContentRendererClient::ChromeContentRendererClient() {
   g_current_client = this;
 
+#if defined(ENABLE_EXTENSIONS)
   extensions::ExtensionsClient::Set(
       extensions::ChromeExtensionsClient::GetInstance());
-#if defined(ENABLE_EXTENSIONS)
   extensions::ExtensionsRendererClient::Set(
       ChromeExtensionsRendererClient::GetInstance());
 #endif
@@ -704,7 +704,7 @@
         break;
       }
       case ChromeViewHostMsg_GetPluginInfo_Status::kAllowed: {
-#if !defined(DISABLE_NACL)
+#if !defined(DISABLE_NACL) && defined(ENABLE_EXTENSIONS)
         const bool is_nacl_plugin =
             plugin.name == ASCIIToUTF16(nacl::kNaClPluginName);
         const bool is_nacl_mime_type =
@@ -769,7 +769,7 @@
             break;
           }
         }
-#endif  // !defined(DISABLE_NACL)
+#endif  // !defined(DISABLE_NACL) && defined(ENABLE_EXTENSIONS)
 
         // Delay loading plugins if prerendering.
         // TODO(mmenke):  In the case of prerendering, feed into
@@ -940,7 +940,7 @@
     const std::string& actual_mime_type,
     const content::WebPluginInfo& plugin) {
   // Look for the manifest URL among the MIME type's additonal parameters.
-  const char* kNaClPluginManifestAttribute = "nacl";
+  const char kNaClPluginManifestAttribute[] = "nacl";
   base::string16 nacl_attr = ASCIIToUTF16(kNaClPluginManifestAttribute);
   for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
     if (plugin.mime_types[i].mime_type == actual_mime_type) {
@@ -955,6 +955,7 @@
   return GURL();
 }
 
+#if !defined(DISABLE_NACL)
 //  static
 bool ChromeContentRendererClient::IsNaClAllowed(
     const GURL& manifest_url,
@@ -996,17 +997,21 @@
 
   bool is_whitelisted_app = is_photo_app || is_hangouts_app;
 
-  bool is_extension_from_webstore = extension &&
-      extension->from_webstore();
+  bool is_extension_from_webstore = false;
+  bool is_invoked_by_hosted_app = false;
+  bool is_extension_unrestricted = false;
+#if defined(ENABLE_EXTENSIONS)
+  is_extension_from_webstore = extension && extension->from_webstore();
 
-  bool is_invoked_by_hosted_app = extension &&
+  is_invoked_by_hosted_app = extension &&
       extension->is_hosted_app() &&
       extension->web_extent().MatchesURL(app_url);
 
   // Allow built-in extensions and extensions under development.
-  bool is_extension_unrestricted = extension &&
+  is_extension_unrestricted = extension &&
       (extension->location() == extensions::Manifest::COMPONENT ||
        extensions::Manifest::IsUnpackedLocation(extension->location()));
+#endif  // defined(ENABLE_EXTENSIONS)
 
   bool is_invoked_by_extension = app_url.SchemeIs("chrome-extension");
 
@@ -1056,6 +1061,7 @@
   }
   return is_nacl_allowed;
 }
+#endif  // defined(DISABLE_NACL)
 
 bool ChromeContentRendererClient::HasErrorPage(int http_status_code,
                                                std::string* error_domain) {
@@ -1491,13 +1497,17 @@
 }
 
 void ChromeContentRendererClient::AddKeySystems(
-    std::vector<content::KeySystemInfo>* key_systems) {
+    std::vector<media::KeySystemInfo>* key_systems) {
   AddChromeKeySystems(key_systems);
 }
 
 bool ChromeContentRendererClient::ShouldReportDetailedMessageForSource(
     const base::string16& source) const {
+#if defined(ENABLE_EXTENSIONS)
   return extensions::IsSourceFromAnExtension(source);
+#else
+  return false;
+#endif
 }
 
 bool ChromeContentRendererClient::ShouldEnableSiteIsolationPolicy() const {
@@ -1506,8 +1516,12 @@
   // running a normal web page from the Internet. We only turn on
   // SiteIsolationPolicy for a renderer process that does not have the extension
   // flag on.
+#if defined(ENABLE_EXTENSIONS)
   CommandLine* command_line = CommandLine::ForCurrentProcess();
   return !command_line->HasSwitch(extensions::switches::kExtensionProcess);
+#else
+  return true;
+#endif
 }
 
 blink::WebWorkerPermissionClientProxy*
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index c5590c0..e28b9ebf 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -134,7 +134,7 @@
       content::RenderFrame* render_frame,
       blink::WebFrame* frame) override;
   bool AllowPepperMediaStreamAPI(const GURL& url) override;
-  void AddKeySystems(std::vector<content::KeySystemInfo>* key_systems) override;
+  void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override;
   bool IsPluginAllowedToUseDevChannelAPIs() override;
   bool IsPluginAllowedToUseCompositorAPI(const GURL& url) override;
   bool IsPluginAllowedToUseVideoDecodeAPI(const GURL& url) override;
@@ -191,6 +191,7 @@
   static GURL GetNaClContentHandlerURL(const std::string& actual_mime_type,
                                        const content::WebPluginInfo& plugin);
 
+#if !defined(DISABLE_NACL)
   // Determines if a NaCl app is allowed, and modifies params to pass the app's
   // permissions to the trusted NaCl plugin.
   static bool IsNaClAllowed(const GURL& manifest_url,
@@ -198,6 +199,7 @@
                             bool is_nacl_unrestricted,
                             const extensions::Extension* extension,
                             blink::WebPluginParams* params);
+#endif
 
   scoped_ptr<ChromeRenderProcessObserver> chrome_observer_;
   scoped_ptr<web_cache::WebCacheRenderProcessObserver> web_cache_observer_;
diff --git a/chrome/renderer/chrome_content_renderer_client_unittest.cc b/chrome/renderer/chrome_content_renderer_client_unittest.cc
index 6e6876c..3c07a12a 100644
--- a/chrome/renderer/chrome_content_renderer_client_unittest.cc
+++ b/chrome/renderer/chrome_content_renderer_client_unittest.cc
@@ -9,47 +9,65 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/renderer/searchbox/search_bouncer.h"
 #include "content/public/common/webplugininfo.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+#if defined(ENABLE_EXTENSIONS)
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/manifest_constants.h"
-#include "testing/gtest/include/gtest/gtest.h"
+#endif
+
+#if !defined(DISABLE_NACL)
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebVector.h"
 #include "third_party/WebKit/public/web/WebPluginParams.h"
-#include "url/gurl.h"
+#endif
 
+#if !defined(DISABLE_NACL)
 using blink::WebPluginParams;
 using blink::WebString;
 using blink::WebVector;
+#endif
+
 using content::WebPluginInfo;
 using content::WebPluginMimeType;
 
 namespace {
+
+#if !defined(DISABLE_NACL)
 const bool kNaClRestricted = false;
 const bool kNaClUnrestricted = true;
 const bool kExtensionRestricted = false;
 const bool kExtensionUnrestricted = true;
 const bool kExtensionNotFromWebStore = false;
 const bool kExtensionFromWebStore = true;
+#endif
+
+#if defined(ENABLE_EXTENSIONS)
 const bool kNotHostedApp = false;
 const bool kHostedApp = true;
+#endif
 
+#if !defined(DISABLE_NACL)
 const char kExtensionUrl[] = "chrome-extension://extension_id/background.html";
 
 const char kPhotosAppURL1[] = "https://foo.plus.google.com";
 const char kPhotosAppURL2[] = "https://foo.plus.sandbox.google.com";
 const char kPhotosManifestURL1[] = "https://ssl.gstatic.com/s2/oz/nacl/foo";
 const char kPhotosManifestURL2[] = "https://ssl.gstatic.com/photos/nacl/foo";
-
-const char kChatAppURL1[] = "https://foo.talkgadget.google.com/hangouts/foo";
-const char kChatAppURL2[] = "https://foo.plus.google.com/hangouts/foo";
-const char kChatAppURL3[] = "https://foo.plus.sandbox.google.com/hangouts/foo";
 const char kChatManifestFS1[] =
   "filesystem:https://foo.talkgadget.google.com/foo";
 const char kChatManifestFS2[] = "filesystem:https://foo.plus.google.com/foo";
 const char kChatManifestFS3[] =
   "filesystem:https://foo.plus.sandbox.google.com/foo";
+#endif
 
+const char kChatAppURL1[] = "https://foo.talkgadget.google.com/hangouts/foo";
+const char kChatAppURL2[] = "https://foo.plus.google.com/hangouts/foo";
+const char kChatAppURL3[] = "https://foo.plus.sandbox.google.com/hangouts/foo";
+
+#if !defined(DISABLE_NACL)
 bool AllowsDevInterfaces(const WebPluginParams& params) {
   for (size_t i = 0; i < params.attributeNames.size(); ++i) {
     if (params.attributeNames[i] == WebString::fromUTF8("@dev"))
@@ -66,6 +84,7 @@
   params->attributeNames.swap(names);
   params->attributeValues.swap(values);
 }
+#endif
 
 void AddContentTypeHandler(content::WebPluginInfo* info,
                            const char* mime_type,
@@ -77,11 +96,13 @@
       base::UTF8ToUTF16(manifest_url));
   info->mime_types.push_back(mime_type_info);
 }
+
 }  // namespace
 
 typedef testing::Test ChromeContentRendererClientTest;
 
 
+#if defined(ENABLE_EXTENSIONS)
 scoped_refptr<const extensions::Extension> CreateTestExtension(
     bool is_unrestricted, bool is_from_webstore, bool is_hosted_app,
     const std::string& app_url) {
@@ -118,6 +139,7 @@
   return CreateTestExtension(is_unrestricted, is_from_webstore, kHostedApp,
                              app_url);
 }
+#endif  // defined(ENABLE_EXTENSIONS)
 
 TEST_F(ChromeContentRendererClientTest, NaClRestriction) {
   // Unknown content types have no NaCl module.
@@ -135,6 +157,7 @@
               ChromeContentRendererClient::GetNaClContentHandlerURL(
                   "application/x-foo", info));
   }
+#if !defined(DISABLE_NACL)
   // --enable-nacl allows all NaCl apps, with 'dev' interfaces.
   {
     WebPluginParams params;
@@ -372,6 +395,7 @@
                         "http://example.com/").get(),
         &params));
   }
+#endif  // !defined(DISABLE_NACL)
 }
 
 TEST_F(ChromeContentRendererClientTest, AllowPepperMediaStreamAPI) {
diff --git a/chrome/renderer/extensions/app_bindings.cc b/chrome/renderer/extensions/app_bindings.cc
index f08213c..ccbd2e8 100644
--- a/chrome/renderer/extensions/app_bindings.cc
+++ b/chrome/renderer/extensions/app_bindings.cc
@@ -53,7 +53,7 @@
   return true;
 }
 
-const char* kInvalidCallbackIdError = "Invalid callbackId";
+const char kInvalidCallbackIdError[] = "Invalid callbackId";
 
 }  // namespace
 
diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc
index e23e360e..7ebb4fe 100644
--- a/chrome/renderer/media/chrome_key_systems.cc
+++ b/chrome/renderer/media/chrome_key_systems.cc
@@ -13,8 +13,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/common/render_messages.h"
 #include "components/cdm/renderer/widevine_key_systems.h"
-#include "content/public/common/eme_constants.h"
 #include "content/public/renderer/render_thread.h"
+#include "media/base/eme_constants.h"
 
 #if defined(OS_ANDROID)
 #include "components/cdm/renderer/android_key_systems.h"
@@ -29,8 +29,8 @@
 #include "base/version.h"
 #endif
 
-using content::KeySystemInfo;
-using content::SupportedCodecs;
+using media::KeySystemInfo;
+using media::SupportedCodecs;
 
 #if defined(ENABLE_PEPPER_CDMS)
 static bool IsPepperCdmAvailable(
@@ -74,11 +74,11 @@
 
   KeySystemInfo info(kExternalClearKeyKeySystem);
 
-  info.supported_codecs = content::EME_CODEC_WEBM_ALL;
-  info.supported_init_data_types = content::EME_INIT_DATA_TYPE_WEBM;
+  info.supported_codecs = media::EME_CODEC_WEBM_ALL;
+  info.supported_init_data_types = media::EME_INIT_DATA_TYPE_WEBM;
 #if defined(USE_PROPRIETARY_CODECS)
-  info.supported_codecs |= content::EME_CODEC_MP4_ALL;
-  info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_CENC;
+  info.supported_codecs |= media::EME_CODEC_MP4_ALL;
+  info.supported_init_data_types |= media::EME_INIT_DATA_TYPE_CENC;
 #endif  // defined(USE_PROPRIETARY_CODECS)
 
   info.pepper_type = kExternalClearKeyPepperType;
@@ -156,19 +156,19 @@
                                  additional_param_values,
                                  &codecs);
 
-  SupportedCodecs supported_codecs = content::EME_CODEC_NONE;
+  SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
   for (size_t i = 0; i < codecs.size(); ++i) {
     if (codecs[i] == kCdmSupportedCodecVorbis)
-      supported_codecs |= content::EME_CODEC_WEBM_VORBIS;
+      supported_codecs |= media::EME_CODEC_WEBM_VORBIS;
     if (codecs[i] == kCdmSupportedCodecVp8)
-      supported_codecs |= content::EME_CODEC_WEBM_VP8;
+      supported_codecs |= media::EME_CODEC_WEBM_VP8;
     if (codecs[i] == kCdmSupportedCodecVp9)
-      supported_codecs |= content::EME_CODEC_WEBM_VP9;
+      supported_codecs |= media::EME_CODEC_WEBM_VP9;
 #if defined(USE_PROPRIETARY_CODECS)
     if (codecs[i] == kCdmSupportedCodecAac)
-      supported_codecs |= content::EME_CODEC_MP4_AAC;
+      supported_codecs |= media::EME_CODEC_MP4_AAC;
     if (codecs[i] == kCdmSupportedCodecAvc1)
-      supported_codecs |= content::EME_CODEC_MP4_AVC1;
+      supported_codecs |= media::EME_CODEC_MP4_AVC1;
 #endif  // defined(USE_PROPRIETARY_CODECS)
   }
 
diff --git a/chrome/renderer/media/chrome_key_systems.h b/chrome/renderer/media/chrome_key_systems.h
index 13acd39..dfec84f 100644
--- a/chrome/renderer/media/chrome_key_systems.h
+++ b/chrome/renderer/media/chrome_key_systems.h
@@ -7,8 +7,8 @@
 
 #include <vector>
 
-#include "content/public/renderer/key_system_info.h"
+#include "media/base/key_system_info.h"
 
-void AddChromeKeySystems(std::vector<content::KeySystemInfo>* key_systems_info);
+void AddChromeKeySystems(std::vector<media::KeySystemInfo>* key_systems_info);
 
 #endif  // CHROME_RENDERER_MEDIA_CHROME_KEY_SYSTEMS_H_
diff --git a/chrome/renderer/pepper/pepper_flash_renderer_host.cc b/chrome/renderer/pepper/pepper_flash_renderer_host.cc
index fbb1007..4d66f24 100644
--- a/chrome/renderer/pepper/pepper_flash_renderer_host.cc
+++ b/chrome/renderer/pepper/pepper_flash_renderer_host.cc
@@ -50,7 +50,7 @@
 //
 // TODO(yzshen): We should be able to remove the histogram recording code once
 // we get the answer.
-const char* kRejectedHttpRequestHeaders[] = {
+const char* const kRejectedHttpRequestHeaders[] = {
     "authorization",     //
     "cache-control",     //
     "content-encoding",  //
diff --git a/chrome/renderer/plugins/plugin_uma.cc b/chrome/renderer/plugins/plugin_uma.cc
index a66d26b..4040f63 100644
--- a/chrome/renderer/plugins/plugin_uma.cc
+++ b/chrome/renderer/plugins/plugin_uma.cc
@@ -23,15 +23,15 @@
 
 // Arrays containing file extensions connected with specific plugins.
 // Note: THE ARRAYS MUST BE SORTED BECAUSE BINARY SEARCH IS USED ON THEM!
-const char* kWindowsMediaPlayerExtensions[] = {".asx"};
+const char* const kWindowsMediaPlayerExtensions[] = {".asx"};
 
-const char* kRealPlayerExtensions[] = {".ra",  ".ram", ".rm",
-                                       ".rmm", ".rmp", ".rpm"};
+const char* const kRealPlayerExtensions[] = {".ra",  ".ram", ".rm",
+                                             ".rmm", ".rmp", ".rpm"};
 
-const char* kQuickTimeExtensions[] = {".moov", ".mov", ".qif",
-                                      ".qt",   ".qti", ".qtif"};
+const char* const kQuickTimeExtensions[] = {".moov", ".mov", ".qif",
+                                            ".qt",   ".qti", ".qtif"};
 
-const char* kShockwaveFlashExtensions[] = {".spl", ".swf"};
+const char* const kShockwaveFlashExtensions[] = {".spl", ".swf"};
 
 }  // namespace.
 
@@ -87,7 +87,7 @@
   return strcmp(first, second) < 0;
 }
 
-bool PluginUMAReporter::CStringArrayContainsCString(const char** array,
+bool PluginUMAReporter::CStringArrayContainsCString(const char* const* array,
                                                     size_t array_size,
                                                     const char* str) {
   return std::binary_search(array, array + array_size, str, CompareCStrings);
diff --git a/chrome/renderer/plugins/plugin_uma.h b/chrome/renderer/plugins/plugin_uma.h
index ae63c67..6dbef19 100644
--- a/chrome/renderer/plugins/plugin_uma.h
+++ b/chrome/renderer/plugins/plugin_uma.h
@@ -66,7 +66,7 @@
   ~PluginUMAReporter();
 
   static bool CompareCStrings(const char* first, const char* second);
-  bool CStringArrayContainsCString(const char** array,
+  bool CStringArrayContainsCString(const char* const* array,
                                    size_t array_size,
                                    const char* str);
   // Extracts file extension from url.
diff --git a/chrome/renderer/principals_extension_bindings.cc b/chrome/renderer/principals_extension_bindings.cc
index f862c41..9118c8d6 100644
--- a/chrome/renderer/principals_extension_bindings.cc
+++ b/chrome/renderer/principals_extension_bindings.cc
@@ -37,8 +37,8 @@
   DISALLOW_COPY_AND_ASSIGN(PrincipalsExtensionWrapper);
 };
 
-const char* kPrincipalsExtensionName = "v8/Principals";
-const char* kPrincipalsExtensionCode =
+const char kPrincipalsExtensionName[] = "v8/Principals";
+const char kPrincipalsExtensionCode[] =
     "var chrome;"
     "if (!chrome)"
     "  chrome = {};"
diff --git a/mojo/examples/wm_flow/app/DEPS b/chrome/renderer/resources/default_300_percent/DELETE_ME
similarity index 100%
copy from mojo/examples/wm_flow/app/DEPS
copy to chrome/renderer/resources/default_300_percent/DELETE_ME
diff --git a/chrome/renderer/resources/renderer_resources.grd b/chrome/renderer/resources/renderer_resources.grd
index 21fa550..6b529fb 100644
--- a/chrome/renderer/resources/renderer_resources.grd
+++ b/chrome/renderer/resources/renderer_resources.grd
@@ -6,6 +6,7 @@
     </output>
     <output filename="renderer_resources_100_percent.pak" type="data_package" context="default_100_percent" />
     <output filename="renderer_resources_200_percent.pak" type="data_package" context="default_200_percent" />
+    <output filename="renderer_resources_300_percent.pak" type="data_package" context="default_300_percent" />
   </outputs>
   <release seq="1">
     <structures fallback_to_low_resolution="true">
diff --git a/chrome/renderer/safe_browsing/malware_dom_details_browsertest.cc b/chrome/renderer/safe_browsing/malware_dom_details_browsertest.cc
index 7ea474c..e4ef1e6 100644
--- a/chrome/renderer/safe_browsing/malware_dom_details_browsertest.cc
+++ b/chrome/renderer/safe_browsing/malware_dom_details_browsertest.cc
@@ -18,7 +18,7 @@
   // debug build takes a while.
   details->kMaxNodes = 50;
 
-  const char* urlprefix = "data:text/html;charset=utf-8,";
+  const char urlprefix[] = "data:text/html;charset=utf-8,";
 
   { // An page with an internal script
     std::string html = "<html><head><script></script></head></html>";
@@ -127,5 +127,4 @@
     details->ExtractResources(&params);
     ASSERT_EQ(51u, params.size());
   }
-
 }
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc b/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
index c73470b..c2a84843 100644
--- a/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
+++ b/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
@@ -21,7 +21,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/renderer/render_view.h"
-#include "content/public/test/routing_id_mangling_disabler.h"
 #include "crypto/sha2.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -200,7 +199,6 @@
   scoped_ptr<Scorer> scorer_;
   scoped_ptr<PhishingClassifier> classifier_;
   MockFeatureExtractorClock* clock_;  // Owned by classifier_.
-  content::RoutingIDManglingDisabler mangling_disabler_;
 
   // Features that are in the model.
   const std::string url_tld_token_net_;
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
index eb1654d..af26992b 100644
--- a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
+++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
@@ -26,7 +26,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/test/browser_test_utils.h"
-#include "content/public/test/routing_id_mangling_disabler.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
 #include "net/dns/mock_host_resolver.h"
@@ -264,7 +263,6 @@
   StrictMock<MockPhishingClassifier>* classifier_;  // Owned by |delegate_|.
   PhishingClassifierDelegate* delegate_;  // Owned by the RenderView.
   scoped_refptr<content::MessageLoopRunner> runner_;
-  content::RoutingIDManglingDisabler mangling_disabler_;
 };
 
 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, Navigation) {
diff --git a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
index 70642f7..fa778122 100644
--- a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
+++ b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
@@ -29,7 +29,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/test/browser_test_utils.h"
-#include "content/public/test/routing_id_mangling_disabler.h"
 #include "content/public/test/test_utils.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -180,7 +179,6 @@
   // Any urls not in this map are served a 404 error.
   std::map<std::string, std::string> responses_;
 
-  content::RoutingIDManglingDisabler mangling_disabler_;
   scoped_ptr<net::test_server::EmbeddedTestServer> embedded_test_server_;
   MockFeatureExtractorClock clock_;
   scoped_ptr<PhishingDOMFeatureExtractor> extractor_;
diff --git a/chrome/renderer/spellchecker/spellcheck_unittest.cc b/chrome/renderer/spellchecker/spellcheck_unittest.cc
index 04d60eba..e599145 100644
--- a/chrome/renderer/spellchecker/spellcheck_unittest.cc
+++ b/chrome/renderer/spellchecker/spellcheck_unittest.cc
@@ -375,7 +375,6 @@
     {L"2012", true},
     {L"100,000,000", true},
     {L"3.141592653", true},
-
   };
 
   for (size_t i = 0; i < arraysize(kTestCases); ++i) {
@@ -1197,7 +1196,7 @@
     {"movies", true},
   };
 
-  static const char* kLocales[] = { "en-GB", "en-US", "en-CA", "en-AU" };
+  static const char* const kLocales[] = { "en-GB", "en-US", "en-CA", "en-AU" };
 
   for (size_t j = 0; j < arraysize(kLocales); ++j) {
     ReinitializeSpellCheck(kLocales[j]);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index ef17904..15e72a0 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -7,6 +7,7 @@
 
 # GYP version: chrome/chrome_tests_unit.gypi:test_support_common
 source_set("test_support") {
+  defines = []
   testonly = true
 
   sources = [
@@ -109,7 +110,6 @@
 
   if (!is_ios) {
     deps += [
-      "//chrome/common/extensions/api",
       "//chrome/plugin",
       "//chrome/renderer",
       "//chrome/utility",
@@ -122,7 +122,6 @@
       "//components/captive_portal:test_support",
       "//components/infobars/core",
       "//components/sessions:test_support",
-      "//extensions:test_support",
       "//google_apis:test_support",
       "//ipc:test_support",
       "//media:test_support",
@@ -135,6 +134,13 @@
     ]
   }
 
+  if (enable_extensions) {
+    deps += [
+      "//chrome/common/extensions/api",
+      "//extensions:test_support",
+    ]
+  }
+
   if (is_linux) {
     deps += [ "//crypto:platform" ]
   }
@@ -164,6 +170,17 @@
   if (toolkit_views) {
     deps += [ "//ui/views:test_support" ]
   }
+
+  if (enable_background) {
+    defines += [ "ENABLE_BACKGROUND=1" ]
+  }
+
+  if (enable_extensions) {
+    deps += [
+      "//chrome/common/extensions/api",
+      "//extensions:test_support",
+    ]
+  }
 }
 
 source_set("test_support_unit") {
diff --git a/chrome/test/android/unit_tests_apk/AndroidManifest.xml b/chrome/test/android/unit_tests_apk/AndroidManifest.xml
index ac76d618..54520fd 100644
--- a/chrome/test/android/unit_tests_apk/AndroidManifest.xml
+++ b/chrome/test/android/unit_tests_apk/AndroidManifest.xml
@@ -10,7 +10,7 @@
       android:versionCode="1"
       android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
 
     <application android:label="ChromeNativeTests"
             android:name="org.chromium.chrome.unit_tests_apk.ChromeNativeTestApplication">
diff --git a/chrome/test/base/chrome_unit_test_suite.cc b/chrome/test/base/chrome_unit_test_suite.cc
index 2ea8d38..d2911472 100644
--- a/chrome/test/base/chrome_unit_test_suite.cc
+++ b/chrome/test/base/chrome_unit_test_suite.cc
@@ -27,8 +27,6 @@
 
 #if !defined(OS_IOS)
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
-#include "chrome/common/extensions/chrome_extensions_client.h"
-#include "extensions/common/extension_paths.h"
 #include "ui/gl/gl_surface.h"
 #endif
 
@@ -36,6 +34,11 @@
 #include "base/memory/shared_memory.h"
 #endif
 
+#if defined(ENABLE_EXTENSIONS)
+#include "chrome/common/extensions/chrome_extensions_client.h"
+#include "extensions/common/extension_paths.h"
+#endif
+
 namespace {
 
 // Creates a TestingBrowserProcess for each test.
@@ -127,12 +130,14 @@
   chromeos::RegisterPathProvider();
 #endif
 
-#if !defined(OS_IOS)
+#if defined(ENABLE_EXTENSIONS)
   extensions::RegisterPathProvider();
 
   extensions::ExtensionsClient::Set(
       extensions::ChromeExtensionsClient::GetInstance());
+#endif
 
+#if !defined(OS_IOS)
   content::WebUIControllerFactory::RegisterFactory(
       ChromeWebUIControllerFactory::GetInstance());
 
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index be0e04f..9e09f2e 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -531,6 +531,11 @@
       this, GetPath().Append(chrome::kTopSitesFilename));
 }
 
+void TestingProfile::SetTopSites(history::TopSites* top_sites) {
+  DestroyTopSites();
+  top_sites_ = top_sites;
+}
+
 void TestingProfile::DestroyTopSites() {
   if (top_sites_.get()) {
     top_sites_->Shutdown();
@@ -837,6 +842,7 @@
 }
 
 HostContentSettingsMap* TestingProfile::GetHostContentSettingsMap() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!host_content_settings_map_.get()) {
     host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false);
 #if defined(ENABLE_EXTENSIONS)
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index b7f887b692..df2c135 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -182,6 +182,10 @@
   // loading.
   void CreateTopSites();
 
+  // Allows to set a test implementation |top_sites|. Testing profile owns
+  // the reference and is responsible for releasing memory.
+  void SetTopSites(history::TopSites* top_sites);
+
   // Shuts down and nulls out the reference to TopSites.
   void DestroyTopSites();
 
diff --git a/chrome/test/base/tracing_browsertest.cc b/chrome/test/base/tracing_browsertest.cc
index b0b7c10b..d029a19 100644
--- a/chrome/test/base/tracing_browsertest.cc
+++ b/chrome/test/base/tracing_browsertest.cc
@@ -22,8 +22,8 @@
 using tracing::WaitForWatchEvent;
 using tracing::EndTracing;
 
-const char* g_category = "test_tracing";
-const char* g_event = "TheEvent";
+const char g_category[] = "test_tracing";
+const char g_event[] = "TheEvent";
 
 class TracingBrowserTest : public InProcessBrowserTest {
  protected:
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc
index e017345..64f5115 100644
--- a/chrome/test/base/ui_test_utils.cc
+++ b/chrome/test/base/ui_test_utils.cc
@@ -30,8 +30,6 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -48,6 +46,8 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/find_in_page_observer.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
+#include "components/app_modal_dialogs/app_modal_dialog_queue.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/search_engines/template_url_service.h"
 #include "content/public/browser/dom_operation_notification_details.h"
@@ -107,6 +107,38 @@
   return new_browser;
 }
 
+class AppModalDialogWaiter : public AppModalDialogObserver {
+ public:
+  AppModalDialogWaiter()
+      : dialog_(NULL) {
+  }
+  ~AppModalDialogWaiter() override {
+  }
+
+  AppModalDialog* Wait() {
+    if (dialog_)
+      return dialog_;
+    message_loop_runner_ = new content::MessageLoopRunner;
+    message_loop_runner_->Run();
+    EXPECT_TRUE(dialog_);
+    return dialog_;
+  }
+
+  // AppModalDialogWaiter:
+  virtual void Notify(AppModalDialog* dialog) override {
+    DCHECK(!dialog_);
+    dialog_ = dialog;
+    if (message_loop_runner_.get() && message_loop_runner_->loop_running())
+      message_loop_runner_->Quit();
+  }
+
+ private:
+  AppModalDialog* dialog_;
+  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(AppModalDialogWaiter);
+};
+
 }  // namespace
 
 bool GetCurrentTabTitle(const Browser* browser, base::string16* title) {
@@ -296,12 +328,8 @@
   AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance();
   if (dialog_queue->HasActiveDialog())
     return dialog_queue->active_dialog();
-
-  content::WindowedNotificationObserver observer(
-      chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
-      content::NotificationService::AllSources());
-  observer.Wait();
-  return content::Source<AppModalDialog>(observer.source()).ptr();
+  AppModalDialogWaiter waiter;
+  return waiter.Wait();
 }
 
 int FindInPage(WebContents* tab,
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc
index 9e403af..548b951 100644
--- a/chrome/test/chromedriver/capabilities.cc
+++ b/chrome/test/chromedriver/capabilities.cc
@@ -210,7 +210,7 @@
   } else if (proxy_type == "autodetect") {
     capabilities->switches.SetSwitch("proxy-auto-detect");
   } else if (proxy_type == "manual") {
-    const char* proxy_servers_options[][2] = {
+    const char* const proxy_servers_options[][2] = {
         {"ftpProxy", "ftp"}, {"httpProxy", "http"}, {"sslProxy", "https"}};
     const base::Value* option_value = NULL;
     std::string proxy_servers;
@@ -354,8 +354,8 @@
      Status status = parser_map[it.key()].Run(it.value(), capabilities);
      if (status.IsError())
        return Status(kUnknownError, "cannot parse " + it.key(), status);
-   }
-   return Status(kOk);
+  }
+  return Status(kOk);
 }
 
 Status ParseChromeOptions(
diff --git a/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc b/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc
index 14d596ea..52762f3 100644
--- a/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc
+++ b/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc
@@ -86,8 +86,13 @@
   if (!quit_) {
     base::FilePath user_data_dir = user_data_dir_.Take();
     base::FilePath extension_dir = extension_dir_.Take();
-    LOG(WARNING) << "chrome detaches, user should take care of directory:"
-                 << user_data_dir.value() << " and " << extension_dir.value();
+    LOG(WARNING) << "chrome quit unexpectedly, leaving behind temporary "
+        "directories for debugging:";
+    if (user_data_dir_.IsValid())
+      LOG(WARNING) << "chrome user data directory: " << user_data_dir.value();
+    if (extension_dir_.IsValid())
+      LOG(WARNING) << "chromedriver automation extension directory: "
+                   << extension_dir.value();
   }
   base::CloseProcessHandle(process_);
 }
diff --git a/chrome/test/chromedriver/chrome/device_manager.cc b/chrome/test/chromedriver/chrome/device_manager.cc
index 8bedee4..8e77f0c 100644
--- a/chrome/test/chromedriver/chrome/device_manager.cc
+++ b/chrome/test/chromedriver/chrome/device_manager.cc
@@ -17,8 +17,8 @@
 #include "chrome/test/chromedriver/chrome/status.h"
 
 // TODO(craigdh): Remove once Chromedriver no longer supports pre-m33 Chrome.
-const char* kChromeCmdLineFileBeforeM33 = "/data/local/chrome-command-line";
-const char* kChromeCmdLineFile = "/data/local/tmp/chrome-command-line";
+const char kChromeCmdLineFileBeforeM33[] = "/data/local/chrome-command-line";
+const char kChromeCmdLineFile[] = "/data/local/tmp/chrome-command-line";
 
 Device::Device(
     const std::string& device_serial, Adb* adb,
@@ -114,16 +114,16 @@
 
     active_package_ = package;
   }
-  this->ForwardDevtoolsPort(package, process, device_socket, port);
+  this->ForwardDevtoolsPort(package, process, port, &device_socket);
 
   return status;
 }
 
 Status Device::ForwardDevtoolsPort(const std::string& package,
                                    const std::string& process,
-                                   std::string& device_socket,
-                                   int port) {
-  if (device_socket.empty()) {
+                                   int port,
+                                   std::string* device_socket) {
+  if (device_socket->empty()) {
     // Assume this is a WebView app.
     int pid;
     Status status = adb_->GetPidByName(serial_,
@@ -135,10 +135,10 @@
             "process name must be specified if not equal to package name");
       return status;
     }
-    device_socket = base::StringPrintf("webview_devtools_remote_%d", pid);
+    *device_socket = base::StringPrintf("webview_devtools_remote_%d", pid);
   }
 
-  return adb_->ForwardPort(serial_, port, device_socket);
+  return adb_->ForwardPort(serial_, port, *device_socket);
 }
 
 Status Device::TearDown() {
diff --git a/chrome/test/chromedriver/chrome/device_manager.h b/chrome/test/chromedriver/chrome/device_manager.h
index 6b812c5..d27aa50 100644
--- a/chrome/test/chromedriver/chrome/device_manager.h
+++ b/chrome/test/chromedriver/chrome/device_manager.h
@@ -40,8 +40,8 @@
 
   Status ForwardDevtoolsPort(const std::string& package,
                              const std::string& process,
-                             std::string& device_socket,
-                             int port);
+                             int port,
+                             std::string* device_socket);
 
   const std::string serial_;
   std::string active_package_;
diff --git a/chrome/test/chromedriver/chrome/devtools_client_impl.cc b/chrome/test/chromedriver/chrome/devtools_client_impl.cc
index 543cc90d..be2ac177 100644
--- a/chrome/test/chromedriver/chrome/devtools_client_impl.cc
+++ b/chrome/test/chromedriver/chrome/devtools_client_impl.cc
@@ -19,7 +19,7 @@
 
 namespace {
 
-const char* kInspectorContextError =
+const char kInspectorContextError[] =
     "Execution context with given id not found.";
 
 Status ParseInspectorError(const std::string& error_json) {
diff --git a/chrome/test/chromedriver/chrome/devtools_http_client.cc b/chrome/test/chromedriver/chrome/devtools_http_client.cc
index 9e4599b..7f3a49e 100644
--- a/chrome/test/chromedriver/chrome/devtools_http_client.cc
+++ b/chrome/test/chromedriver/chrome/devtools_http_client.cc
@@ -234,8 +234,7 @@
 
 namespace internal {
 
-Status ParseWebViewsInfo(const std::string& data,
-                         WebViewsInfo* views_info) {
+Status ParseWebViewsInfo(const std::string& data, WebViewsInfo* views_info) {
   scoped_ptr<base::Value> value(base::JSONReader::Read(data));
   if (!value.get())
     return Status(kUnknownError, "DevTools returned invalid JSON");
@@ -260,25 +259,36 @@
     std::string debugger_url;
     info->GetString("webSocketDebuggerUrl", &debugger_url);
     WebViewInfo::Type type;
-    if (type_as_string == "app")
-      type = WebViewInfo::kApp;
-    else if (type_as_string == "background_page")
-      type = WebViewInfo::kBackgroundPage;
-    else if (type_as_string == "page")
-      type = WebViewInfo::kPage;
-    else if (type_as_string == "worker")
-      type = WebViewInfo::kWorker;
-    else if (type_as_string == "webview")
-      type = WebViewInfo::kWebView;
-    else if (type_as_string == "other")
-      type = WebViewInfo::kOther;
-    else
-      return Status(kUnknownError,
-                    "DevTools returned unknown type:" + type_as_string);
+    Status status = ParseType(type_as_string, &type);
+    if (status.IsError())
+      return status;
     temp_views_info.push_back(WebViewInfo(id, debugger_url, url, type));
   }
   *views_info = WebViewsInfo(temp_views_info);
   return Status(kOk);
 }
 
+Status ParseType(const std::string& type_as_string, WebViewInfo::Type* type) {
+  if (type_as_string == "app")
+    *type = WebViewInfo::kApp;
+  else if (type_as_string == "background_page")
+    *type = WebViewInfo::kBackgroundPage;
+  else if (type_as_string == "page")
+    *type = WebViewInfo::kPage;
+  else if (type_as_string == "worker")
+    *type = WebViewInfo::kWorker;
+  else if (type_as_string == "webview")
+    *type = WebViewInfo::kWebView;
+  else if (type_as_string == "iframe")
+    *type = WebViewInfo::kIFrame;
+  else if (type_as_string == "other")
+    *type = WebViewInfo::kOther;
+  else if (type_as_string == "service_worker")
+    *type = WebViewInfo::kServiceWorker;
+  else
+    return Status(kUnknownError,
+                  "DevTools returned unknown type:" + type_as_string);
+  return Status(kOk);
+}
+
 }  // namespace internal
diff --git a/chrome/test/chromedriver/chrome/devtools_http_client.h b/chrome/test/chromedriver/chrome/devtools_http_client.h
index d0ee87be..ba8098b 100644
--- a/chrome/test/chromedriver/chrome/devtools_http_client.h
+++ b/chrome/test/chromedriver/chrome/devtools_http_client.h
@@ -30,7 +30,9 @@
     kPage,
     kWorker,
     kWebView,
-    kOther
+    kIFrame,
+    kOther,
+    kServiceWorker
   };
 
   WebViewInfo(const std::string& id,
@@ -100,8 +102,8 @@
 };
 
 namespace internal {
-Status ParseWebViewsInfo(const std::string& data,
-                         WebViewsInfo* views_info);
+Status ParseWebViewsInfo(const std::string& data, WebViewsInfo* views_info);
+Status ParseType(const std::string& data, WebViewInfo::Type* type);
 }  // namespace internal
 
 #endif  // CHROME_TEST_CHROMEDRIVER_CHROME_DEVTOOLS_HTTP_CLIENT_H_
diff --git a/chrome/test/chromedriver/chrome/devtools_http_client_unittest.cc b/chrome/test/chromedriver/chrome/devtools_http_client_unittest.cc
index 1af04b7..509df091 100644
--- a/chrome/test/chromedriver/chrome/devtools_http_client_unittest.cc
+++ b/chrome/test/chromedriver/chrome/devtools_http_client_unittest.cc
@@ -95,7 +95,10 @@
   AssertTypeIsOk("background_page", WebViewInfo::kBackgroundPage);
   AssertTypeIsOk("page", WebViewInfo::kPage);
   AssertTypeIsOk("worker", WebViewInfo::kWorker);
+  AssertTypeIsOk("webview", WebViewInfo::kWebView);
+  AssertTypeIsOk("iframe", WebViewInfo::kIFrame);
   AssertTypeIsOk("other", WebViewInfo::kOther);
+  AssertTypeIsOk("service_worker", WebViewInfo::kServiceWorker);
   AssertFails("[{\"type\": \"\", \"id\": \"1\", \"url\": \"http://page1\"}]");
 }
 
diff --git a/chrome/test/chromedriver/chrome/heap_snapshot_taker.cc b/chrome/test/chromedriver/chrome/heap_snapshot_taker.cc
index 996d78d..0f119e0 100644
--- a/chrome/test/chromedriver/chrome/heap_snapshot_taker.cc
+++ b/chrome/test/chromedriver/chrome/heap_snapshot_taker.cc
@@ -43,7 +43,7 @@
 
 Status HeapSnapshotTaker::TakeSnapshotInternal() {
   base::DictionaryValue params;
-  const char* kMethods[] = {
+  const char* const kMethods[] = {
       "Debugger.enable",
       "HeapProfiler.collectGarbage",
       "HeapProfiler.takeHeapSnapshot"
diff --git a/chrome/test/chromedriver/chrome/heap_snapshot_taker_unittest.cc b/chrome/test/chromedriver/chrome/heap_snapshot_taker_unittest.cc
index 342ae8f..0301efa 100644
--- a/chrome/test/chromedriver/chrome/heap_snapshot_taker_unittest.cc
+++ b/chrome/test/chromedriver/chrome/heap_snapshot_taker_unittest.cc
@@ -14,7 +14,7 @@
 
 namespace {
 
-const char* chunks[] = {"{\"a\": 1,", "\"b\": 2}"};
+const char* const chunks[] = {"{\"a\": 1,", "\"b\": 2}"};
 
 scoped_ptr<base::Value> GetSnapshotAsValue() {
   scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
index 6b31d9e..793f834 100644
--- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
+++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager.cc
@@ -67,5 +67,13 @@
                     overridden_device_metrics_->text_autosizing);
   params.SetDouble("fontScaleFactor",
                    overridden_device_metrics_->font_scale_factor);
-  return client_->SendCommand("Page.setDeviceMetricsOverride", params);
+  Status status = client_->SendCommand("Page.setDeviceMetricsOverride", params);
+  if (status.IsError())
+    return status;
+
+  // Always emulate touch.
+  base::DictionaryValue emulate_touch_params;
+  emulate_touch_params.SetBoolean("enabled", true);
+  return client_->SendCommand(
+      "Page.setTouchEmulationEnabled", emulate_touch_params);
 }
diff --git a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc
index ab9232d..15c91859 100644
--- a/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc
+++ b/chrome/test/chromedriver/chrome/mobile_emulation_override_manager_unittest.cc
@@ -89,11 +89,11 @@
   ASSERT_EQ(0u, client.commands_.size());
   ASSERT_EQ(kOk, manager.OnConnected(&client).code());
 
-  ASSERT_EQ(1u, client.commands_.size());
-  ASSERT_EQ(kOk, manager.OnConnected(&client).code());
   ASSERT_EQ(2u, client.commands_.size());
+  ASSERT_EQ(kOk, manager.OnConnected(&client).code());
+  ASSERT_EQ(4u, client.commands_.size());
   ASSERT_NO_FATAL_FAILURE(
-      AssertDeviceMetricsCommand(client.commands_[1], device_metrics));
+      AssertDeviceMetricsCommand(client.commands_[2], device_metrics));
 }
 
 TEST(MobileEmulationOverrideManager, SendsCommandOnNavigation) {
@@ -107,18 +107,18 @@
   ASSERT_EQ(kOk,
             manager.OnEvent(&client, "Page.frameNavigated", main_frame_params)
                 .code());
-  ASSERT_EQ(1u, client.commands_.size());
+  ASSERT_EQ(2u, client.commands_.size());
   ASSERT_EQ(kOk,
             manager.OnEvent(&client, "Page.frameNavigated", main_frame_params)
                 .code());
-  ASSERT_EQ(2u, client.commands_.size());
+  ASSERT_EQ(4u, client.commands_.size());
   ASSERT_NO_FATAL_FAILURE(
-      AssertDeviceMetricsCommand(client.commands_[1], device_metrics));
+      AssertDeviceMetricsCommand(client.commands_[2], device_metrics));
 
   base::DictionaryValue sub_frame_params;
   sub_frame_params.SetString("frame.parentId", "id");
   ASSERT_EQ(
       kOk,
       manager.OnEvent(&client, "Page.frameNavigated", sub_frame_params).code());
-  ASSERT_EQ(2u, client.commands_.size());
+  ASSERT_EQ(4u, client.commands_.size());
 }
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc
index f1ab9b4d..28577ae9 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.cc
+++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -510,7 +510,7 @@
   if (status.IsError())
     return status;
 
-  const char* kDocUnloadError = "document unloaded while waiting for result";
+  const char kDocUnloadError[] = "document unloaded while waiting for result";
   std::string kQueryResult = base::StringPrintf(
       "function() {"
       "  var info = document.$chrome_asyncScriptInfo;"
diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc
index 21595b0..b8653f2 100644
--- a/chrome/test/chromedriver/chrome_launcher.cc
+++ b/chrome/test/chromedriver/chrome_launcher.cc
@@ -55,11 +55,11 @@
 
 namespace {
 
-const char* kCommonSwitches[] = {
+const char* const kCommonSwitches[] = {
     "ignore-certificate-errors", "metrics-recording-only"};
 
 #if defined(OS_LINUX)
-const char* kEnableCrashReport = "enable-crash-reporter-for-testing";
+const char kEnableCrashReport[] = "enable-crash-reporter-for-testing";
 #endif
 
 Status UnpackAutomationExtension(const base::FilePath& temp_dir,
@@ -128,28 +128,33 @@
     switches.RemoveSwitch(*iter);
   }
   switches.SetFromSwitches(capabilities.switches);
-
+  base::FilePath user_data_dir_path;
   if (!switches.HasSwitch("user-data-dir")) {
     command.AppendArg("data:,");
     if (!user_data_dir->CreateUniqueTempDir())
       return Status(kUnknownError, "cannot create temp dir for user data dir");
     switches.SetSwitch("user-data-dir", user_data_dir->path().value());
-    Status status = internal::PrepareUserDataDir(
-        user_data_dir->path(), capabilities.prefs.get(),
-        capabilities.local_state.get());
-    if (status.IsError())
-      return status;
+    user_data_dir_path = user_data_dir->path();
+  } else {
+    user_data_dir_path = base::FilePath(
+        switches.GetSwitchValueNative("user-data-dir"));
   }
 
+  Status status = internal::PrepareUserDataDir(user_data_dir_path,
+                                               capabilities.prefs.get(),
+                                               capabilities.local_state.get());
+  if (status.IsError())
+    return status;
+
   if (!extension_dir->CreateUniqueTempDir()) {
     return Status(kUnknownError,
                   "cannot create temp dir for unpacking extensions");
   }
-  Status status = internal::ProcessExtensions(capabilities.extensions,
-                                              extension_dir->path(),
-                                              true,
-                                              &switches,
-                                              extension_bg_pages);
+  status = internal::ProcessExtensions(capabilities.extensions,
+                                       extension_dir->path(),
+                                       true,
+                                       &switches,
+                                       extension_bg_pages);
   if (status.IsError())
     return status;
   switches.AppendToCommandLine(&command);
@@ -197,7 +202,7 @@
     const NetAddress& address,
     const PerfLoggingPrefs& perf_logging_prefs,
     const SyncWebSocketFactory& socket_factory,
-    ScopedVector<DevToolsEventListener>& devtools_event_listeners,
+    const ScopedVector<DevToolsEventListener>& devtools_event_listeners,
     scoped_ptr<DevToolsClient>* browser_client) {
   scoped_ptr<DevToolsClient> client(new DevToolsClientImpl(
       socket_factory, base::StringPrintf("ws://%s/devtools/browser/",
@@ -231,7 +236,7 @@
     URLRequestContextGetter* context_getter,
     const SyncWebSocketFactory& socket_factory,
     const Capabilities& capabilities,
-    ScopedVector<DevToolsEventListener>& devtools_event_listeners,
+    ScopedVector<DevToolsEventListener>* devtools_event_listeners,
     scoped_ptr<Chrome>* chrome) {
   Status status(kOk);
   scoped_ptr<DevToolsHttpClient> devtools_http_client;
@@ -247,7 +252,7 @@
   scoped_ptr<DevToolsClient> devtools_websocket_client;
   status = CreateBrowserwideDevToolsClientAndConnect(
       capabilities.debugger_address, capabilities.perf_logging_prefs,
-      socket_factory, devtools_event_listeners, &devtools_websocket_client);
+      socket_factory, *devtools_event_listeners, &devtools_websocket_client);
   if (status.IsError()) {
     LOG(WARNING) << "Browser-wide DevTools client failed to connect: "
                  << status.message();
@@ -255,7 +260,7 @@
 
   chrome->reset(new ChromeRemoteImpl(devtools_http_client.Pass(),
                                      devtools_websocket_client.Pass(),
-                                     devtools_event_listeners));
+                                     *devtools_event_listeners));
   return Status(kOk);
 }
 
@@ -265,7 +270,7 @@
     scoped_ptr<PortReservation> port_reservation,
     const SyncWebSocketFactory& socket_factory,
     const Capabilities& capabilities,
-    ScopedVector<DevToolsEventListener>& devtools_event_listeners,
+    ScopedVector<DevToolsEventListener>* devtools_event_listeners,
     scoped_ptr<Chrome>* chrome) {
   CommandLine command(CommandLine::NO_PROGRAM);
   base::ScopedTempDir user_data_dir;
@@ -373,7 +378,7 @@
   scoped_ptr<DevToolsClient> devtools_websocket_client;
   status = CreateBrowserwideDevToolsClientAndConnect(
       NetAddress(port), capabilities.perf_logging_prefs, socket_factory,
-      devtools_event_listeners, &devtools_websocket_client);
+      *devtools_event_listeners, &devtools_websocket_client);
   if (status.IsError()) {
     LOG(WARNING) << "Browser-wide DevTools client failed to connect: "
                  << status.message();
@@ -382,7 +387,7 @@
   scoped_ptr<ChromeDesktopImpl> chrome_desktop(
       new ChromeDesktopImpl(devtools_http_client.Pass(),
                             devtools_websocket_client.Pass(),
-                            devtools_event_listeners,
+                            *devtools_event_listeners,
                             port_reservation.Pass(),
                             process,
                             command,
@@ -410,7 +415,7 @@
     scoped_ptr<PortReservation> port_reservation,
     const SyncWebSocketFactory& socket_factory,
     const Capabilities& capabilities,
-    ScopedVector<DevToolsEventListener>& devtools_event_listeners,
+    ScopedVector<DevToolsEventListener>* devtools_event_listeners,
     DeviceManager* device_manager,
     scoped_ptr<Chrome>* chrome) {
   Status status(kOk);
@@ -454,7 +459,7 @@
   scoped_ptr<DevToolsClient> devtools_websocket_client;
   status = CreateBrowserwideDevToolsClientAndConnect(
       NetAddress(port), capabilities.perf_logging_prefs, socket_factory,
-      devtools_event_listeners, &devtools_websocket_client);
+      *devtools_event_listeners, &devtools_websocket_client);
   if (status.IsError()) {
     LOG(WARNING) << "Browser-wide DevTools client failed to connect: "
                  << status.message();
@@ -462,7 +467,7 @@
 
   chrome->reset(new ChromeAndroidImpl(devtools_http_client.Pass(),
                                       devtools_websocket_client.Pass(),
-                                      devtools_event_listeners,
+                                      *devtools_event_listeners,
                                       port_reservation.Pass(),
                                       device.Pass()));
   return Status(kOk);
@@ -477,7 +482,7 @@
     PortServer* port_server,
     PortManager* port_manager,
     const Capabilities& capabilities,
-    ScopedVector<DevToolsEventListener>& devtools_event_listeners,
+    ScopedVector<DevToolsEventListener>* devtools_event_listeners,
     scoped_ptr<Chrome>* chrome) {
   if (capabilities.IsRemoteBrowser()) {
     return LaunchRemoteChromeSession(
@@ -772,14 +777,32 @@
   if (!base::CreateDirectory(default_dir))
     return Status(kUnknownError, "cannot create default profile directory");
 
+  std::string preferences;
+  base::FilePath preferences_path =
+      default_dir.Append(chrome::kPreferencesFilename);
+
+  if (base::PathExists(preferences_path))
+    base::ReadFileToString(preferences_path, &preferences);
+  else
+    preferences = kPreferences;
+
   Status status =
-      WritePrefsFile(kPreferences,
+      WritePrefsFile(preferences,
                      custom_prefs,
                      default_dir.Append(chrome::kPreferencesFilename));
   if (status.IsError())
     return status;
 
-  status = WritePrefsFile(kLocalState,
+  std::string local_state;
+  base::FilePath local_state_path =
+      user_data_dir.Append(chrome::kLocalStateFilename);
+
+  if (base::PathExists(local_state_path))
+    base::ReadFileToString(local_state_path, &local_state);
+  else
+    local_state = kLocalState;
+
+  status = WritePrefsFile(local_state,
                           custom_local_state,
                           user_data_dir.Append(chrome::kLocalStateFilename));
   if (status.IsError())
diff --git a/chrome/test/chromedriver/chrome_launcher.h b/chrome/test/chromedriver/chrome_launcher.h
index c9dee2c..e85994e 100644
--- a/chrome/test/chromedriver/chrome_launcher.h
+++ b/chrome/test/chromedriver/chrome_launcher.h
@@ -35,7 +35,7 @@
     PortServer* port_server,
     PortManager* port_manager,
     const Capabilities& capabilities,
-    ScopedVector<DevToolsEventListener>& devtools_event_listeners,
+    ScopedVector<DevToolsEventListener>* devtools_event_listeners,
     scoped_ptr<Chrome>* chrome);
 
 namespace internal {
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py
index fb1aa2b2..2d5a89a 100644
--- a/chrome/test/chromedriver/client/chromedriver.py
+++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -66,7 +66,7 @@
                chrome_extensions=None, chrome_log_path=None,
                debugger_address=None, browser_log_level=None,
                performance_log_level=None, mobile_emulation=None,
-               experimental_options=None):
+               experimental_options=None, download_dir=None):
     self._executor = command_executor.CommandExecutor(server_url)
 
     options = {}
@@ -115,6 +115,14 @@
       assert performance_log_level in log_levels
       logging_prefs['performance'] = performance_log_level
 
+    download_prefs = {}
+    if download_dir:
+      if 'prefs' not in options:
+        options['prefs'] = {}
+      if 'download' not in options['prefs']:
+        options['prefs']['download'] = {}
+      options['prefs']['download']['default_directory'] = download_dir
+
     params = {
       'desiredCapabilities': {
         'chromeOptions': options,
diff --git a/chrome/test/chromedriver/element_util.cc b/chrome/test/chromedriver/element_util.cc
index 04cce675..b5a7b99 100644
--- a/chrome/test/chromedriver/element_util.cc
+++ b/chrome/test/chromedriver/element_util.cc
@@ -357,7 +357,7 @@
   std::string target_element_id = element_id;
   if (tag_name == "area") {
     // Scroll the image into view instead of the area.
-    const char* kGetImageElementForArea =
+    const char kGetImageElementForArea[] =
         "function (element) {"
         "  var map = element.parentElement;"
         "  if (map.tagName.toLowerCase() != 'map')"
@@ -614,7 +614,7 @@
       center, clickable_element_id, &region_offset);
   if (status.IsError())
     return status;
-  const char* kFindSubFrameScript =
+  const char kFindSubFrameScript[] =
       "function(xpath) {"
       "  return document.evaluate(xpath, document, null,"
       "      XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;"
diff --git a/chrome/test/chromedriver/logging.cc b/chrome/test/chromedriver/logging.cc
index 6ac50fa..240ac14d 100644
--- a/chrome/test/chromedriver/logging.cc
+++ b/chrome/test/chromedriver/logging.cc
@@ -32,7 +32,7 @@
 int64 g_start_time = 0;
 
 // Array indices are the Log::Level enum values.
-const char* kLevelToName[] = {
+const char* const kLevelToName[] = {
   "ALL",  // kAll
   "DEBUG",  // kDebug
   "INFO",  // kInfo
diff --git a/chrome/test/chromedriver/net/sync_websocket_impl.h b/chrome/test/chromedriver/net/sync_websocket_impl.h
index 32896ee..46251132 100644
--- a/chrome/test/chromedriver/net/sync_websocket_impl.h
+++ b/chrome/test/chromedriver/net/sync_websocket_impl.h
@@ -17,7 +17,6 @@
 #include "chrome/test/chromedriver/net/sync_websocket.h"
 #include "chrome/test/chromedriver/net/websocket.h"
 #include "net/base/completion_callback.h"
-#include "net/socket_stream/socket_stream.h"
 
 namespace base {
 class WaitableEvent;
diff --git a/chrome/test/chromedriver/server/chromedriver_server.cc b/chrome/test/chromedriver/server/chromedriver_server.cc
index 9684e3c..653064b 100644
--- a/chrome/test/chromedriver/server/chromedriver_server.cc
+++ b/chrome/test/chromedriver/server/chromedriver_server.cc
@@ -37,7 +37,7 @@
 
 namespace {
 
-const char* kLocalHostAddress = "127.0.0.1";
+const char kLocalHostAddress[] = "127.0.0.1";
 const int kBufferSize = 100 * 1024 * 1024;  // 100 MB
 
 typedef base::Callback<
@@ -227,7 +227,7 @@
   scoped_ptr<PortServer> port_server;
   if (cmd_line->HasSwitch("h") || cmd_line->HasSwitch("help")) {
     std::string options;
-    const char* kOptionAndDescriptions[] = {
+    const char* const kOptionAndDescriptions[] = {
         "port=PORT", "port to listen on",
         "adb-port=PORT", "adb server port",
         "log-path=FILE", "write server log to file instead of stderr, "
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc
index 99dbbda..d7c4c7e4 100644
--- a/chrome/test/chromedriver/session_commands.cc
+++ b/chrome/test/chromedriver/session_commands.cc
@@ -145,7 +145,7 @@
                         bound_params.port_server,
                         bound_params.port_manager,
                         capabilities,
-                        devtools_event_listeners,
+                        &devtools_event_listeners,
                         &session->chrome);
   if (status.IsError())
     return status;
diff --git a/chrome/test/chromedriver/session_commands_unittest.cc b/chrome/test/chromedriver/session_commands_unittest.cc
index 957da7b..cc62b79 100644
--- a/chrome/test/chromedriver/session_commands_unittest.cc
+++ b/chrome/test/chromedriver/session_commands_unittest.cc
@@ -27,7 +27,7 @@
   scoped_ptr<base::Value> value;
   // Zip file entry that contains a single file with contents 'COW\n', base64
   // encoded following RFC 1521.
-  const char* kBase64ZipEntry =
+  const char kBase64ZipEntry[] =
       "UEsDBBQAAAAAAMROi0K/wAzGBAAAAAQAAAADAAAAbW9vQ09XClBLAQIUAxQAAAAAAMROi0K/"
       "wAzG\nBAAAAAQAAAADAAAAAAAAAAAAAACggQAAAABtb29QSwUGAAAAAAEAAQAxAAAAJQAAAA"
       "AA\n";
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 8b8c310..1fdb4d0 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -18,6 +18,7 @@
 import time
 import unittest
 import urllib2
+import shutil
 
 _THIS_DIR = os.path.abspath(os.path.dirname(__file__))
 sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir))
@@ -56,6 +57,18 @@
     # https://code.google.com/p/chromedriver/issues/detail?id=913
     'ChromeDriverTest.testChromeDriverReceiveAndSendLargeData',
 ]
+_VERSION_SPECIFIC_FILTER['37'] = [
+    # https://code.google.com/p/chromedriver/issues/detail?id=954
+    'MobileEmulationCapabilityTest.testClickElement',
+    'MobileEmulationCapabilityTest.testHoverOverElement',
+    'MobileEmulationCapabilityTest.testSingleTapElement',
+]
+_VERSION_SPECIFIC_FILTER['36'] = [
+    # https://code.google.com/p/chromedriver/issues/detail?id=954
+    'MobileEmulationCapabilityTest.testClickElement',
+    'MobileEmulationCapabilityTest.testHoverOverElement',
+    'MobileEmulationCapabilityTest.testSingleTapElement',
+]
 
 _OS_SPECIFIC_FILTER = {}
 _OS_SPECIFIC_FILTER['win'] = [
@@ -104,6 +117,7 @@
         'ChromeSwitchesCapabilityTest.*',
         'ChromeExtensionsCapabilityTest.*',
         'MobileEmulationCapabilityTest.*',
+        'ChromeDownloadDirTest.*',
         # https://crbug.com/274650
         'ChromeDriverTest.testCloseWindow',
         # https://code.google.com/p/chromedriver/issues/detail?id=270
@@ -120,6 +134,8 @@
         'PerfTest.testColdExecuteScript',
         # https://code.google.com/p/chromedriver/issues/detail?id=459
         'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
+        # https://code.google.com/p/chromedriver/issues/detail?id=913
+        'ChromeDriverTest.testChromeDriverReceiveAndSendLargeData',
     ]
 )
 _ANDROID_NEGATIVE_FILTER['chrome_stable'] = (
@@ -132,8 +148,6 @@
         'ChromeDriverTest.testGetWindowHandles',
         'ChromeDriverTest.testSwitchToWindow',
         'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
-        # https://code.google.com/p/chromedriver/issues/detail?id=913
-        'ChromeDriverTest.testChromeDriverReceiveAndSendLargeData',
     ]
 )
 _ANDROID_NEGATIVE_FILTER['chromedriver_webview_shell'] = (
@@ -159,7 +173,7 @@
       except:
         pass
 
-  def CreateDriver(self, server_url=None, **kwargs):
+  def CreateDriver(self, server_url=None, download_dir=None, **kwargs):
     if server_url is None:
       server_url = _CHROMEDRIVER_SERVER_URL
 
@@ -177,6 +191,7 @@
                                        android_package=android_package,
                                        android_activity=android_activity,
                                        android_process=android_process,
+                                       download_dir=download_dir,
                                        **kwargs)
     self._drivers += [driver]
     return driver
@@ -230,8 +245,8 @@
     Returns:
       Handle to a new window. None if timeout.
     """
-    timeout = time.time() + 20
-    while time.time() < timeout:
+    deadline = time.time() + 20
+    while time.time() < deadline:
       new_handles = self._driver.GetWindowHandles()
       if len(new_handles) > len(old_handles):
         for index, old_handle in enumerate(old_handles):
@@ -767,6 +782,66 @@
     self._drivers[0].Quit()
     self._drivers[0] = self.CreateDriver()
 
+class ChromeDownloadDirTest(ChromeDriverBaseTest):
+
+  def __init__(self, *args, **kwargs):
+    super(ChromeDownloadDirTest, self).__init__(*args, **kwargs)
+    self._temp_dirs = []
+
+  def CreateTempDir(self):
+    temp_dir = tempfile.mkdtemp()
+    self._temp_dirs.append(temp_dir)
+    return temp_dir
+
+  def tearDown(self):
+    # Call the superclass tearDown() method before deleting temp dirs, so that
+    # Chrome has a chance to exit before its user data dir is blown away from
+    # underneath it.
+    super(ChromeDownloadDirTest, self).tearDown()
+    for temp_dir in self._temp_dirs:
+      shutil.rmtree(temp_dir)
+
+  def testFileDownload(self):
+    download_dir = self.CreateTempDir()
+    download_name = os.path.join(download_dir, 'a_red_dot.png')
+    driver = self.CreateDriver(download_dir=download_dir)
+    driver.Load(ChromeDriverTest.GetHttpUrlForFile(
+        '/chromedriver/download.html'))
+    driver.FindElement('id', 'red-dot').Click()
+    deadline = time.time() + 60
+    while True:
+      time.sleep(0.1)
+      if os.path.isfile(download_name) or time.time() > deadline:
+        break
+    self.assertTrue(os.path.isfile(download_name), "Failed to download file!")
+
+  def testDownloadDirectoryOverridesExistingPreferences(self):
+    user_data_dir = self.CreateTempDir()
+    download_dir = self.CreateTempDir()
+    sub_dir = os.path.join(user_data_dir, 'Default')
+    os.mkdir(sub_dir)
+    prefs_file_path = os.path.join(sub_dir, 'Preferences')
+
+    prefs = {
+      'test': 'this should not be changed',
+      'download': {
+        'default_directory': '/old/download/directory'
+      }
+    }
+
+    with open(prefs_file_path, 'w') as f:
+      json.dump(prefs, f)
+
+    driver = self.CreateDriver(
+        chrome_switches=['user-data-dir=' + user_data_dir],
+        download_dir=download_dir)
+
+    with open(prefs_file_path) as f:
+      prefs = json.load(f)
+
+    self.assertEqual('this should not be changed', prefs['test'])
+    download = prefs['download']
+    self.assertEqual(download['default_directory'], download_dir)
 
 class ChromeSwitchesCapabilityTest(ChromeDriverBaseTest):
   """Tests that chromedriver properly processes chromeOptions.args capabilities.
@@ -849,24 +924,57 @@
   @staticmethod
   def GlobalSetUp():
     def respondWithUserAgentString(request):
-      return request.GetHeader('User-Agent')
+      return """
+        <html>
+        <body>%s</body>
+        </html>""" % request.GetHeader('User-Agent')
+
+    def respondWithUserAgentStringUseDeviceWidth(request):
+      return """
+        <html>
+        <head>
+        <meta name="viewport" content="width=device-width,minimum-scale=1.0">
+        </head>
+        <body>%s</body>
+        </html>""" % request.GetHeader('User-Agent')
 
     MobileEmulationCapabilityTest._http_server = webserver.WebServer(
         chrome_paths.GetTestData())
     MobileEmulationCapabilityTest._http_server.SetCallbackForPath(
         '/userAgent', respondWithUserAgentString)
+    MobileEmulationCapabilityTest._http_server.SetCallbackForPath(
+        '/userAgentUseDeviceWidth', respondWithUserAgentStringUseDeviceWidth)
 
   @staticmethod
   def GlobalTearDown():
     MobileEmulationCapabilityTest._http_server.Shutdown()
 
-  def testDeviceMetrics(self):
+  def testDeviceMetricsWithStandardWidth(self):
     driver = self.CreateDriver(
         mobile_emulation = {
-            'deviceMetrics': {'width': 360, 'height': 640, 'pixelRatio': 3}})
+            'deviceMetrics': {'width': 360, 'height': 640, 'pixelRatio': 3},
+            'userAgent': 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Bui'
+                         'ld/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chr'
+                         'ome/18.0.1025.166 Mobile Safari/535.19'
+            })
+    driver.SetWindowSize(600, 400)
+    driver.Load(self._http_server.GetUrl() + '/userAgent')
     self.assertTrue(driver.capabilities['mobileEmulationEnabled'])
-    self.assertEqual(360, driver.ExecuteScript('return window.innerWidth'))
-    self.assertEqual(640, driver.ExecuteScript('return window.innerHeight'))
+    self.assertEqual(360, driver.ExecuteScript('return window.screen.width'))
+    self.assertEqual(640, driver.ExecuteScript('return window.screen.height'))
+
+  def testDeviceMetricsWithDeviceWidth(self):
+    driver = self.CreateDriver(
+        mobile_emulation = {
+            'deviceMetrics': {'width': 360, 'height': 640, 'pixelRatio': 3},
+            'userAgent': 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Bui'
+                         'ld/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chr'
+                         'ome/18.0.1025.166 Mobile Safari/535.19'
+            })
+    driver.Load(self._http_server.GetUrl() + '/userAgentUseDeviceWidth')
+    self.assertTrue(driver.capabilities['mobileEmulationEnabled'])
+    self.assertEqual(360, driver.ExecuteScript('return window.screen.width'))
+    self.assertEqual(640, driver.ExecuteScript('return window.screen.height'))
 
   def testUserAgent(self):
     driver = self.CreateDriver(
@@ -878,9 +986,9 @@
   def testDeviceName(self):
     driver = self.CreateDriver(
         mobile_emulation = {'deviceName': 'Google Nexus 5'})
-    driver.Load(self._http_server.GetUrl() + '/userAgent')
-    self.assertEqual(360, driver.ExecuteScript('return window.innerWidth'))
-    self.assertEqual(640, driver.ExecuteScript('return window.innerHeight'))
+    driver.Load(self._http_server.GetUrl() + '/userAgentUseDeviceWidth')
+    self.assertEqual(360, driver.ExecuteScript('return window.screen.width'))
+    self.assertEqual(640, driver.ExecuteScript('return window.screen.height'))
     body_tag = driver.FindElement('tag name', 'body')
     self.assertEqual(
         'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleW'
@@ -906,6 +1014,7 @@
   def testHoverOverElement(self):
     driver = self.CreateDriver(
         mobile_emulation = {'deviceName': 'Google Nexus 5'})
+    driver.Load('about:blank')
     div = driver.ExecuteScript(
         'document.body.innerHTML = "<div>old</div>";'
         'var div = document.getElementsByTagName("div")[0];'
@@ -919,6 +1028,7 @@
   def testClickElement(self):
     driver = self.CreateDriver(
         mobile_emulation = {'deviceName': 'Google Nexus 5'})
+    driver.Load('about:blank')
     div = driver.ExecuteScript(
         'document.body.innerHTML = "<div>old</div>";'
         'var div = document.getElementsByTagName("div")[0];'
@@ -932,6 +1042,7 @@
   def testSingleTapElement(self):
     driver = self.CreateDriver(
         mobile_emulation = {'deviceName': 'Google Nexus 5'})
+    driver.Load('about:blank')
     div = driver.ExecuteScript(
         'document.body.innerHTML = "<div>old</div>";'
         'var div = document.getElementsByTagName("div")[0];'
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations
index 05220b29..0b47abd7 100644
--- a/chrome/test/chromedriver/test/test_expectations
+++ b/chrome/test/chromedriver/test/test_expectations
@@ -192,6 +192,9 @@
     'CorrectEventFiringTest.testShouldIssueMouseUpEvents',
     'CorrectEventFiringTest.testsShouldIssueMouseDownEvents',
     'CorrectEventFiringTest.testMouseEventsShouldBubbleUpToContainingElements',
+
+    # https://code.google.com/p/chromedriver/issues/detail?id=955
+    'TypingTest.testShiftSelectionDeletes',
 ]
 _OS_NEGATIVE_FILTER['android:chrome_stable'] = (
     _OS_NEGATIVE_FILTER['android:chrome'])
diff --git a/chrome/test/chromedriver/test/webview_shell/java/AndroidManifest.xml b/chrome/test/chromedriver/test/webview_shell/java/AndroidManifest.xml
index c42928a..41573845 100644
--- a/chrome/test/chromedriver/test/webview_shell/java/AndroidManifest.xml
+++ b/chrome/test/chromedriver/test/webview_shell/java/AndroidManifest.xml
@@ -9,7 +9,7 @@
     package="org.chromium.chromedriver_webview_shell" android:versionCode="1"
     android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="21" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 
diff --git a/chrome/test/chromedriver/util_unittest.cc b/chrome/test/chromedriver/util_unittest.cc
index 8ccb8d3..d68dd36 100644
--- a/chrome/test/chromedriver/util_unittest.cc
+++ b/chrome/test/chromedriver/util_unittest.cc
@@ -18,7 +18,7 @@
   std::string data;
   // A zip entry sent from a Java WebDriver client (v2.20) that contains a
   // file with the contents "COW\n".
-  const char* kBase64ZipEntry =
+  const char kBase64ZipEntry[] =
       "UEsDBBQACAAIAJpyXEAAAAAAAAAAAAAAAAAEAAAAdGVzdHP2D+"
       "cCAFBLBwi/wAzGBgAAAAQAAAA=";
   ASSERT_TRUE(base::Base64Decode(kBase64ZipEntry, &data));
@@ -36,7 +36,7 @@
   std::string data;
   // A zip archive sent from a Python WebDriver client that contains a
   // file with the contents "COW\n".
-  const char* kBase64ZipArchive =
+  const char kBase64ZipArchive[] =
       "UEsDBBQAAAAAAMROi0K/wAzGBAAAAAQAAAADAAAAbW9vQ09XClBLAQIUAxQAAAAAAMROi0K/"
       "wAzGBAAAAAQAAAADAAAAAAAAAAAAAACggQAAAABtb29QSwUGAAAAAAEAAQAxAAAAJQAAAAA"
       "A";
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index aa07400..930456e 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -343,7 +343,7 @@
     return Status(kUnknownError, "fail to locate the sub frame element");
 
   std::string chrome_driver_id = GenerateId();
-  const char* kSetFrameIdentifier =
+  const char kSetFrameIdentifier[] =
       "function(frame, id) {"
       "  frame.setAttribute('cd_frame_id_', id);"
       "}";
@@ -373,7 +373,7 @@
     WebView* web_view,
     const base::DictionaryValue& params,
     scoped_ptr<base::Value>* value) {
-  const char* kGetTitleScript =
+  const char kGetTitleScript[] =
       "function() {"
       "  if (document.title)"
       "    return document.title;"
@@ -389,7 +389,7 @@
     WebView* web_view,
     const base::DictionaryValue& params,
     scoped_ptr<base::Value>* value) {
-  const char* kGetPageSource =
+  const char kGetPageSource[] =
       "function() {"
       "  return new XMLSerializer().serializeToString(document);"
       "}";
diff --git a/chrome/test/data/autofill/heuristics/input/20_checkout_alaskaair.com.html b/chrome/test/data/autofill/heuristics/input/20_checkout_alaskaair.com.html
new file mode 100644
index 0000000..8f5d5e9
--- /dev/null
+++ b/chrome/test/data/autofill/heuristics/input/20_checkout_alaskaair.com.html
@@ -0,0 +1,2650 @@
+<!DOCTYPE html>
+<!-- saved from url=(0040)https://www.alaskaair.com/booking/addons -->
+<html ><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+    <title>Checkout: Review and Payment - Alaska Airlines</title>
+    <meta name="keywords" content="checkout review payment">
+    <meta name="description" content="Review your itinerary and purchase">
+    
+
+<meta http-equiv="X-UA-Compatible" content="IE=9">
+  
+</head>
+<body>
+
+<form action="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?CurrentForm=UCSignInStart" method="post" onsubmit="if(s_gi){var s=s_gi(&#39;alaskacom&#39;);s.linkTrackVars=&#39;prop16&#39;;s.linkTrackEvents=&#39;None&#39;;s.prop16=&#39;[pagename] : myaccountsignin&#39;;s.tl(this,&#39;o&#39;,&#39;[pagename] : myaccountsignin&#39;);s.prop16=&#39;&#39;;}">
+    <div >
+        <div id="divUserId">
+            <label for="UserId" >User ID or MP #</label>
+            <a id="forgotIdLink" title="Help Retrieving User ID" tabindex="5" href="https://www.alaskaair.com/myaccount/forgotcredentials/userid" onclick="if(s_gi){var s=s_gi(&#39;alaskacom&#39;);s.linkTrackVars=&#39;prop16&#39;;s.linkTrackEvents=&#39;None&#39;;s.prop16=&#39;MyAccount:Forgot User ID&#39;;s.tl(this,&#39;o&#39;,&#39;MyAccount:Forgot User ID&#39;);s.prop16=&#39;&#39;;}as.authentication.forgotUserId(this.href);return false;" >Forgot User ID?</a>
+        </div>
+        <div><input  id="UserId" maxlength="50" autocorrect="off" tabindex="1" name="UserId" type="text" value=""></div>
+    </div>
+    <div >
+        <div id="divPassword">
+            <label for="Password" >Password</label>
+            <a id="forgotPasswordLink" title="Help Retrieving Password" tabindex="6" href="https://www.alaskaair.com/myaccount/forgotcredentials/password" onclick="if(s_gi){var s=s_gi(&#39;alaskacom&#39;);s.linkTrackVars=&#39;prop16&#39;;s.linkTrackEvents=&#39;None&#39;;s.prop16=&#39;MyAccount:Forgot Password&#39;;s.tl(this,&#39;o&#39;,&#39;MyAccount:Forgot Password&#39;);s.prop16=&#39;&#39;;}as.authentication.forgotPassword(this.href);return false;" >Forgot Password?</a>
+        </div>
+        <div> <input  id="Password" maxlength="50" tabindex="2" name="Password" type="password" autocomplete="off" value=""></div>
+    </div>
+    <div>
+        <div><label for="jumpToSelection"><span >Jump To </span>Section</label></div>
+        <div>
+<select id="jumpToSelection" name="JumpToSelection" tabindex="3">
+<option selected="selected" value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx">Profile Overview &amp; Tier Status</option>
+<option value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?view=miles">Mileage Activity</option>
+<option value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?view=trips">My Trips</option>
+<option value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?view=wallet">My Wallet</option>
+<option value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?view=discounts">Discount Codes</option>
+<option value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?view=benefits">Mileage Plan Benefits</option>
+<option value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?view=tprofiles">Traveler Profiles</option>
+<option value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?view=myinformation">My Info &amp; Email Subscriptions</option>
+<option value="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?view=tpreferences">Travel Preferences</option>
+</select>
+    </div>
+    </div>
+    <div >
+        <input id="RememberMe" name="RememberMe" type="checkbox" tabindex="4" value="true">
+        <label id="RememberMeLabel" for="RememberMe">Remember my User ID on this computer.</label>
+        <div ></div>
+    </div>
+    <div >
+        <a id="signUpLink" title="Sign Up" tabindex="8" href="https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx?CurrentForm=UCMyAccountCreate&lid=MyAccount:Sign%20Up">Sign Up</a>
+    </div>
+    <div >
+        <input id="myAccoutnSignInButton"  tabindex="7" type="submit" value="SIGN IN">
+    </div>
+    <input id="signInClient" name="signInClient" type="hidden" value="signInWidget">
+    <div ></div>
+</form>
+
+                    <form id="PaymentForm" action="https://www.alaskaair.com/booking/payment" method="post" autocorrect="off" onsubmit="ShowInterstitial();">
+                    
+<fieldset id="CheckOutData" style="display:none;">
+	<input type="hidden" id="BookingStateWrapper" name="BookingStateWrapper" value="4622B99E-EFBA-4e3b-9AE0-9C19EC60C045|001|gAAI1UhDFCpWUJrQB3m3YVTUuh/0tBYvUVGEWS3otj341fjTjMutNT5Eglh1UhWzJQLkW4NCl9q4UE1BY10rLG2gXUAdJy69/KnStAdlTqJTzW49hXbbzRykHOQPKEF2dPaG5GyxqthU7bh2LJKFQ1tT76PgqX08rPjUu3+/vjsQNvioZBvTGervYv+CCuYsEiiz3U/PYJI9GQsyB4GavY9GEZ2GSYloWTPMkRvbGMIk2OgAirvJngq6ymK2YxiGVeWqNAPkf0BKSpF6qQCSTj6drfhAWPEwaCMq8j4FBPyupUnrF9QwZcxdTnYgtSTkbdJqYvhCxyJmYOrGRjlLXW1xrl8ga98xNV9Odlts7yFYPTyqU+/NrSqtfSr2MlGQprOH65XiZKxMJoSs5X1kmu6/rE5tbSCVce0HXos9H7julgWhFFkX0LMpmu7Bot8c0zlVo9ibGtalHeNflOD5ESMA3QVTvgrpzd0oEdPYpz7dTsQey3Jd0OC1OJ6+dJ7RGlwcgyC18QoDY34Tbd+ZLicG6LHp/emU6odpDiHPyPBLobnyDrhTBw3g7mk6e1W6dhHuXhdE469Eo+xTeqCBAIUuE0mhPtzxBAntDvvIbq/2BdiRDchk1NPvRDD2HxvNdCukURNtL005AUrisClqZX2fTuI+bRyeovCCDdzonooo1lcO3N8zorOHcHizkYbYf4rrYBcH1dnUk8Hz4NVjPN9eZukeWLXY5fnqJh2uTxA6I8gK7/0ymxVmmy1tI/UoigBOoSlub8Lqy9I61AWAiXhPAgb48Th6RaaSXbC4bww/0KMhXcAuzEJVY458R2ukS6TMXCaPYOR1E+4c9xv/KMsDfEi0hu/pELXxTtCYMwjHzE0kS4mnt/Z+3iCqt+DsQt/TFbAg1Nxi4iGYOmZGuMNX/xMmE5DIPZ1lc0H7YFqc1A5S+wMcrwn5woHLmyAiN7n/HGjRnJWLHB/qI5fRYBgqMmnAuVw4jyOKuXEFcY+dIjLVQ51HALpft/j46tfmll2GB2wmwNqJleUGD8lHdjjEjXOJBLBypukggl31txwsY9HGtRxyCuf63fGL5NtDmHwdXjyK1khEii+w3nYLDI9aq65YIVBW4wYBDhwHHg9QlqfC8DKW5txnFEQG7qW5fdpPWdKw9PEeCQzdq3hLWMQsL0UdUrWx9B357vVvmiSM4dN0j//dt1kK94wNsr6BMchqbKZfkPJmegooKlBQER3pWnmnnidmcSIKq8QvoIsaLSzk5GdwXshdW/Sr7fH94dNvMfY7nrOjUaMOUG7g81KaFuuNU9w1Uubc79DzJNxcX8aWD1LxU1SzLZmzrLXDAoX2aGg3F+75KsnojifGi7YQU+4+bL/xvlkNBwx9YPl2zOHRBqcU/x6Bgurry2nmyUESCX9hOIug9DmI/8XBXoX1SZARdYjDuR9ISzQQoWWgxoTWku3O4SiSQiVfuI9DN5dZbLOnLyvutBuubXE1HCfM4MTaXXBZmPA+tPwWDmFum/3NOl4gXihBvYQx36kWq8owl+maqawi1jsPFrowJhAt+8o46TGurs5OxfmBhjyZ8FDlxpIeLEJ+fa1xBhB3s2ivbfJfni8AiapH5rbV/hsTfokL+0Fd2OYMNysYws+w0z7Hxv0yK+Wv5ipIRvxvPTzOKh3YaciQIdwGI8wYa/hZtD0ew4SQaJWqurygtRRYXCWS0hX09tiDEuyUrZgekrnXvahPrX4wjCJZ/D6TaCaIsCaIOGTpPVEARQ1f+SZYpdjosg+iejdTbaB29/pvOjETMO8jm1nbfg3DeJI+MlAaxz5o7itTUywYgixJcbk5+J5D9PObKeWa3j23Y5T00mahCGBkFC2VKqYxSOQxd35zSmgfecXsiyrY8aRlE0Gm3eb1zTOIqqVNXyM8KxFFI7b/yIZGQL8iU5M3E6z17AkGyMROfbYKFEJRsmmqUzdFZkC1qw3sF5Fl8ejr+9SesbzXxjaIMLyKMTIBcWAS6LyOJX0W0DF4O+MgMaO7Z8sKuk9T6ks1CGy0B2ubKNNxWrTljgzAv+OBCQuyThtJ7OCqso1dXDi/tcYslPhwiElNYC5tzJ0aTDjd+tVw2RLmtCqJsBF3tiuU+qbhN5DsbQVf1dvtPc7w0JamOk3ny9Q5gmE/5+SOqgs4zhCRr08wKMkS0qFJId0LWHEUEKT9C5rpSBiJnuz28ZthSsWc+RgjYF7fGEP5Z0emXTw45zhdO6rMlW1uUCk8NNboEHum7zLPsZuRAwCMRB0pz0t/TGGJUoqp4JEehQ48maD8EZTnAwfJjZPrG2djeE5hODDjF19zJAkWxxlmxwvwTtIBuV2rLIRzfD+XKI2wUP2H3S6PLFZDGLoV2Z38r2sBB4KWiy+YeNfWRWpEKnrbgK6UQOORwcCGupdO6nkC4rRKRRzh6D1z7WHljihqPo2bNxl5EpDSpxO+w5uShEN10JBHqnCm1urU4frWF+VB2FBTCFCKNVxtbwJd0IgKx73w3c62BceI6WVSM34qBqyrfblZf56/UMGS/DJ4V/6EIolp5ytfMmHozDwRsAbysZnSPBYcetAUbOhfWREggt+kSOczq7/fyM5FjTzePIPBzwiWjefKTXqfiEIRR6w8DRJXLxkHpKEZBmmDp7Jv9wdsXBDW7WKajcH/PWZcW9lWjAmFDqP5F1fYf0l80lhQysUFIj4I+PJRqiSjdTq9tNAgSG4l8eEKJvdvSEWA4yzh2GlNQuJnOgC0979ARPaTGYd2ch08GUpb6IbkRjnVCwAWMVGN9REv9+0e9bm3bfbdi66VTy3Nri0PEzzsk8kD/cUabv8Bkh+n+4Fhcm/i15nPCbQdj0pXMBjP2CYUyj10apxoeh5m7G3gHpqWIRldxiWKzbB+N1KEXcVi+FUmlioJV3ljWL4+e1PnpFjLSF2zTBNdppHr8pRDk7fq24iq+28yQ3xqq4RuAqeX3oJ8Kixip6rs3Ntjsek3dLLta1Bb2ZS302dI1RZaNApyP6a4jMjKXyEsChBW4XdsVLziJ86y/hn10qFuZIbnR+flxAAqRJ2B7UBIkXI44bxmKQRR0rDRAk+3v15PlzlNMpyNmALcamwYybWxbhQQlx8Rt2ie0vYUf4cXto7m55P3GDf2pYWNVA6sRSk/WpRJz36N9Ux4dQSirjOuQcCvIelSrO2xLjDmlggAEy3/A7NTf/RIZSfzHfF2mDKWSq3zOduk0+KyFaaDVaYJypz1+GWnlRZKyEtc0iceTAGhApLC/ODGJD3bM/uKC88izO8UG9CMO9qlgEjhw2AWQ3gCUBtwYbLfXfXrM7gklYSNqFBXmMt1G4W4lahC7Begxdagz+Z2sNofoB/gxTq8m+IUYLr4PLFdwrcU9y93uBRc6GExgAggGcHAYC5sb2gz5jHjKMm6h1vr2O30ECjmCkmtwI6alfMTFtYU40xKjs/kliNNA9ZWZRWZdHyeD+eDwzjPfo8IepHWyWvgtYNTwJK/RL+2Hj+6aPVS/tA4Jm0sOOOkj8ApF+yg3nVE64JGnYLu6kw73dERWa+WKZcWobe097ilu5IIfXWqOFLIa/qeofi45QHOD7aQLK+BE9o9Ch6NeMF7S5dUFCd7fnGZ16a6IwRHm/WqnAI5ZvHGXAZEY0o/4zpALleNEonXFUdDb/ARfTYlrXMt9ncg6kyaccI8w296gV3FekcS7l+Y7o+uUrqaok3qC0k60tRwZMGysYg+ujsMkZFfgxdL6j5ur0Yq6dmjDD+oHL7DiBXXyrYtCYyMAwTV76X0BAWDTbEHTmwXxDD/r5Beq6iIZuFSd1wNW8Xm52wvEC0+wgiWPHavaV/2VXkeYb4uSr+icDRHfPMyfLveNCM3uEIG7wlNRJghni/lXRAJVGI4mXGfwTZXSVqHJ4UpfwBlUnGeXQa8pw6SD3PreY8znKeDAwqKDPBEJChwt/TMAqkJ+wrIRSMkPduEbI4D8yGc3IeHY6qcMVAVfhJPIDSgqrI53lp3xr34OFHxt1WNL2o2+MNie4nhJQHTMf3vMN4ls3Ckibsk4usX/UFRh7VKbUSr5yjuNckQOW3gZIVtzVUb6yT1Z8YS0PAlsCHeqHiqmFdBxS1dWNC3Spu3zsy9GQeSj3sNiJthdZUfFb/h/Aylak5mLFof3MBUQUWW3eIuhwAGmLqNdlk0uNVkPQSGp8lGG80zPl9Ak4hV8zyYfkUEGaxlWXtKmeTRlzwQ4t6oI9tSpU6/zGqrTkRyGNQ2fzo20Zmz0N/rcilDVla8DldZwaZ4TVdOJZ2zS5+xF7Dj3mPbjTtZCLJ4OQSogQXkwrZUZwQPlt7s8DOztkdEJMamq+JB9ORz0ni327WRwl4GUFnHHZ7nd8aXSqWSLJdCZ9to+/AP9IboVoKvfx7Hgw7+Z/rR8fB/TI5l6hO2fXviYIbuRg9/Hrie17/liRx8noFy7uEPRFBnUAQnhtsEAHsPObLbCTRZWfWN/WgC0zrKVZgayGhWcyRsQHECL9CUXYmSCAgSbjiIj6dXKNpSkHxrW6zaCIBPjtnHgNmlciaAHRK+wTW+Ly2Kv+LusE4sWqocctcUR8fdG/Xa9++EOxc8TzZLoO85Rc510yMjURkm97ez80LIoaolo5XSNU7+iyI36GqA6VmHSexuejb0iCpHCSEkSQNiPC5Xqko9AjeY3JcbRhKmDL+B6N5XbtoSw0AQTT0zGxYkfkCo3AAxzQHBwiHjSNSMvTliDASkJ8fsqqmpZx2mGKi7y9deyqIrcdC9ZgUgYjZcFP+1t586MDgc53zPgvCVqciWsE+9ZQtS73AFtIBZlfrQ0SQyKI+44WmFfrIHfwMc9lXxQiw1yIaAkfTKJr7sqL/iuM58ZscUDxy9s4fd43zWFkT1EmAaVTgMVOLygNekGv3++9UUpmgIPSpXTwyx6NeIg5WLpBzAwdfx0Tk/YkrMhfqyB9XR/DBnQt573tXuYUPbakPQs2vZ2d/xopddACC6MPEHxovoFTKPujV4RypsYCRKpCfdGHZFEVlaQ0AifGL2uWSPS6yv0B0MKVfrD01M9ovpyND+wVRfpjTadgpBPfXyIpT/1fwYxY9jfjTf5/UWTH42/Jge+jQ+emXwxDZJIg9y68q70/gdVnSmGHbfyZFkCumI3o8v7SOItZNJ5aGsjj2TQkDvvqs2OmPiCvbKrUrpQg/Eja5cMd1HNwK8zmhY1NTf19ybvth0Cb4QJBz2Yg3XW2JJ9hNCvF7b2h+arKFAbfFfGZkCSbsJ9OUcBkMzZFKIsAml/zs8Fn63EcSYh4fRffJ+28C/+T1AE944qhGedWXDPCbYyH82QXt71o2bFfsQIpYzwhU/MnNFuSXwWjaH7MZpGajbXjnMTO+pZGob1E4mmBo2sRW6r0YmDmmpVx1FwJORmn5qRzMsc7SZtt0wZwHHTcYccx8=">
+	<input type="hidden" id="CheckOutStepOutModelEncrypted" name="CheckOutStepOutModelEncrypted" value="4622B99E-EFBA-4e3b-9AE0-9C19EC60C045|001|gACQ/3rP7u6M5T8GW1/CPbflZiQojPuPrNA/b5za3tARQx7TKsUu0HdpDzxvRp0AlAgUmlKyRMiOrkpiUJnFnSQu0IdyLBHyiigPKuWepRhCh/Zl94I+VQuHaMciZK/WDzVDs0B/FRL/htO/AC0TwmnDZHPVBpvF6lIedEP3dUxCNpGh5MDE1trbn2jA7n89AkL8h9GpXbdPVpTj1kA3kBVKOpUMeQAY+zrKGpWtcRWOt0D9r0uK1G9q25j65f8zW3s=">
+	<input type="hidden" id="StepoutSessionData" name="StepoutSessionData" value="4622B99E-EFBA-4e3b-9AE0-9C19EC60C045|001|gACAGQstFoZDTNXwhoWGYSYjQmRy4c6KIhtrcDeXj5ny6n1veGjIR9BxTgyvmipFywwUQjLUEdg+Z84oWRbWqPOy6a1bAEpYkjBYNXJRsqIbodURdHUrCzVrszeJJo7R8iNAi2AeQBoaREyY1MAiJefD+O9YrPiAPZGJh/jihniQUC0G1QYe0VUXCYqylaDlv5fMhjpy9xvdg365c4qoEh4XnLRIA+S/G5F29T8oi3dGpxXNDVFqSGoDm/AdE1h5QsQ=">
+    <input type="hidden" name="AccountToken" id="AccountToken" value="">
+	<input type="hidden" name="SkipSignIn" id="SkipSignIn" value="False">
+	<input type="hidden" name="ZeroDue" id="ZeroDue" value="False">
+	<input type="hidden" name="AddonPageStyle" id="AddonPageStyle" value="Lookup">
+</fieldset>
+<input type="hidden" id="CheckOutExpirationTimestamp" name="CheckOutExpirationTimestamp" value="4622B99E-EFBA-4e3b-9AE0-9C19EC60C045|001|gAAMNRi2osGYk5V/c8UTIB0gHGadgVirNlPPFaaWQxHx2ZamRVkuty4Nfrv8eO+iX/90dgSnbDBUyhD5dnedv58Nf7sht4BwkgoCaz/oZgwbHh+OFNYq3Nnv7n96/7zVPO4QZH/qlAsDe7hxuJYjYr5plfdfATz4e/VH2RX6Yy+nqyy1X+eDPXWC4sRE+6WbokJqmIFpx+soxxtVQbfKpCqkjJVZxVOEzkTQQASIKyunctA24AwTtBkPOu3Rc8SxZ1iZgv+fnsJfRyCr0aAUq196">
+
+                    
+                    <div style="margin-bottom: 10px;">
+                        <span >*</span> Required</div>
+                    
+                    <div id="TRAVELERDETAILS"  style="padding-top: 15px;">
+                        <h2>
+                            Traveler Information</h2>
+                        
+	<table>
+	<thead>		
+		<tr>
+			
+			<th style="width:280px; font-weight:bold; font-size:1.17em;padding-bottom:0.83em; color:#00245A;">Traveler</th>
+			<th style="width:200px; font-weight:bold; font-size:1.17em;padding-bottom:0.83em; color:#00245A;">Seats</th>
+			<th style="width:275px; font-weight:bold; font-size:1.17em;padding-bottom:0.83em; color:#00245A;">Services Requested</th>
+			<th></th>
+		</tr>
+	</thead>
+	<tbody>
+	
+	
+		<tr>
+			
+
+			<td>
+				<div id="TravelerInfo" style="margin-right:15px;">
+					<div  style="float:left; width:53px; text-align:right">Name:&nbsp;&nbsp;</div>
+					<div style="float:left;">
+						<!-- mp_trans_disable_start -->
+						Shorty Nge
+						
+						<!-- mp_trans_disable_end -->
+					</div>
+
+					<div ></div>  
+                                       
+					<div style="float:left; width:53px; text-align:right"><abbr title="Mileage Plan Number">MP#</abbr>:&nbsp;&nbsp;</div>
+					<div style="float:left;">
+						None entered
+					</div>
+
+					<div ></div> 
+				</div>
+			</td>
+
+			<td style="text-align:left">
+				<div id="Seats">
+					No Seats
+					 
+				</div>
+			</td>
+			
+			<td>
+				<div id="AdditionalServices" style="margin-right:15px;">
+					
+						None requested
+					
+				</div>
+			</td>
+
+			<td style="width:150px;">
+				<!---->
+				<div id="EasyBizCustomFields" style="width:150px;" >
+					<!--margin-right:15px;-->
+					
+					 
+					
+				</div>
+				<input id="TravelerDetails_Travelers_0__PassengerId" name="TravelerDetails.Travelers[0].PassengerId" type="hidden" value="0"> 
+			</td>
+		</tr>
+		<tr>
+			
+				<td colspan="4" style="line-height:.5em;">&nbsp;</td>
+			
+		</tr>
+	
+	</tbody>
+	</table>
+    
+
+    <div ></div>
+	<hr style="margin-top:5px;">
+                    </div>
+                    
+                    <h2>
+                        Flights</h2>
+                    <input id="OptOutOfAutoUpgrade_ShowOptOut" name="OptOutOfAutoUpgrade.ShowOptOut" type="hidden" value="False">
+                    <div style="margin-bottom: 5px;">
+                        
+<table  style="width:680px;float:left;">	
+		<tbody><tr>
+			
+			<th style="width:280px;">Flight</th>
+			<th style="width:200px;">Departs</th>
+			<th style="width:200px;">Arrives</th>
+		</tr>
+		<tr>
+			<td colspan="3" >
+				
+			</td>
+		</tr>
+							
+					<tr>
+						
+						<td>
+							<div>
+								
+								
+								<span>
+									
+									<!-- mp_trans_disable_start -->American<!-- mp_trans_disable_end -->&nbsp;160
+									
+										&nbsp;(Alaska&nbsp;1852)
+									
+								</span>
+
+								
+										<div >Operated by <!-- mp_trans_disable_start -->American Airlines<!-- mp_trans_disable_end --></div>
+								
+										<div >Check in with <!-- mp_trans_disable_start -->American Airlines<!-- mp_trans_disable_end --></div>
+								
+
+							</div>
+
+							
+<div  style="margin-bottom:4px;">							
+	<span >
+		Coach
+(G)	</span>
+	
+
+	
+		<span  aria-hidden="true">|</span>
+Nonstop	
+	<span >
+		<span  aria-hidden="true">|</span>
+		<a href="javascript://Show Flight Details" onclick="showFlightDetails($(this), &#39;1&#39;);" data-track-link="%7B%22section%22%3A%22flights%22%2C%22linkName%22%3A%22details%22%7D">Details</a>
+	</span>
+	
+</div>
+							
+							<div>
+								<div id="FlightDetailInfo_1" style="display: none;">
+									<h2 style="padding-bottom:2px;">Details for Flights</h2>
+									
+<div >
+
+	<div >
+
+		<div >
+
+		<div >
+			American Airlines  160
+		</div>
+
+		<div >
+			Depart 
+			<!-- mp_trans_disable_start -->Los Angeles, CA (LAX)<!-- mp_trans_disable_end -->
+		</div>
+
+		<div >
+			<span >
+				6:50
+				<strong><abbr>am</abbr></strong>, 
+				<abbr title="Wednesday">Wed</abbr>, <abbr title="November">Nov</abbr> 12
+			</span>
+		</div>
+	</div>
+
+
+	<div >
+		<div ></div>
+		<div >
+		</div>
+		<div >
+			Arrive 
+			<!-- mp_trans_disable_start -->San Francisco (SFO)<!-- mp_trans_disable_end -->
+		</div>
+		<div >
+			<span >
+				8:10
+				<strong><abbr>am</abbr></strong>, 
+				<abbr title="Wednesday">Wed</abbr>, <abbr title="November">Nov</abbr> 12
+			</span>
+		</div>
+	</div>
+
+		<div >
+				<ul >
+					<li>
+						Aircraft: Boeing 737-800
+					</li>
+					<li>
+						% on-time:
+86%
+					</li>
+					<li>
+						% late 30+ min:
+7%
+					</li>
+					<li>
+						% cancelled:
+							n/a
+					</li>
+				</ul>	   
+		</div>
+
+	<div >
+		<ul >
+			<li>
+				Duration: 
+1h<span >ours</span>
+20m<span >inutes</span>
+			</li>
+				<li>
+					Meal: None
+				</li>
+		</ul>
+	</div>
+	 
+
+</div>
+									<div style="padding-bottom: 5px; line-height: 10px; padding-left: 0px; padding-right: 0px; padding-top: 5px;">
+										<div style="background-color: #999999; height: 1px;">
+										</div>
+									</div>
+									
+<div >
+		<div >Performance data is based on previous month.</div>
+</div>
+								</div>
+							</div>							
+						</td>
+						<td>
+							<!-- mp_trans_disable_start -->Los Angeles, CA (LAX) <!-- mp_trans_disable_end --><br>
+							<strong>6:50 <abbr>am</abbr></strong>&nbsp;&nbsp;<abbr title="Wednesday">Wed</abbr>, <abbr title="November">Nov</abbr> 12
+						</td>
+						<td>
+							<!-- mp_trans_disable_start -->San Francisco (SFO)<!-- mp_trans_disable_end --><br>
+							
+							<strong>8:10 <abbr>am</abbr></strong>&nbsp;&nbsp;<abbr title="Wednesday">Wed</abbr>, <abbr title="November">Nov</abbr> 12
+						</td>									
+					</tr>
+							
+				
+				<tr>
+					
+					<td colspan="3">
+						
+									<a href="javascript://About Distance" onclick="showDistanceLB($(this));">Distance</a>: 
+								337 <abbr title="miles">mi</abbr>
+							 <span  aria-hidden="true">|</span> 		
+								Duration: 1h<span >ours</span> 20m<span >inutes</span>
+							
+					</td>
+				</tr>
+				
+				
+					<tr><td colspan="3"><div  style="width:650px;padding-bottom:0;"></div></td></tr>
+									
+					<tr>
+						
+						<td>
+							<div>
+								
+								
+								<span>
+									
+									<!-- mp_trans_disable_start -->American<!-- mp_trans_disable_end -->&nbsp;2378
+									
+										&nbsp;(Alaska&nbsp;1873)
+									
+								</span>
+
+								
+										<div >Operated by <!-- mp_trans_disable_start -->American Airlines<!-- mp_trans_disable_end --></div>
+								
+										<div >Check in with <!-- mp_trans_disable_start -->American Airlines<!-- mp_trans_disable_end --></div>
+								
+
+							</div>
+
+							
+<div  style="margin-bottom:4px;">							
+	<span >
+		Coach
+(G)	</span>
+	
+
+	
+		<span  aria-hidden="true">|</span>
+Nonstop	
+	<span >
+		<span  aria-hidden="true">|</span>
+		<a href="javascript://Show Flight Details" onclick="showFlightDetails($(this), &#39;2&#39;);" data-track-link="%7B%22section%22%3A%22flights%22%2C%22linkName%22%3A%22details%22%7D">Details</a>
+	</span>
+	
+</div>
+							
+							<div>
+								<div id="FlightDetailInfo_2" style="display: none;">
+									<h2 style="padding-bottom:2px;">Details for Flights</h2>
+									
+<div >
+
+	<div >
+
+		<div >
+
+		<div >
+			American Airlines  2378
+		</div>
+
+		<div >
+			Depart 
+			<!-- mp_trans_disable_start -->San Francisco (SFO)<!-- mp_trans_disable_end -->
+		</div>
+
+		<div >
+			<span >
+				12:40
+				<strong><abbr>pm</abbr></strong>, 
+				<abbr title="Tuesday">Tue</abbr>, <abbr title="November">Nov</abbr> 18
+			</span>
+		</div>
+	</div>
+
+
+	<div >
+		<div ></div>
+		<div >
+		</div>
+		<div >
+			Arrive 
+			<!-- mp_trans_disable_start -->Los Angeles, CA (LAX)<!-- mp_trans_disable_end -->
+		</div>
+		<div >
+			<span >
+				2:00
+				<strong><abbr>pm</abbr></strong>, 
+				<abbr title="Tuesday">Tue</abbr>, <abbr title="November">Nov</abbr> 18
+			</span>
+		</div>
+	</div>
+
+		<div >
+				<ul >
+					<li>
+						Aircraft: Boeing 737-800
+					</li>
+					<li>
+						% on-time:
+62%
+					</li>
+					<li>
+						% late 30+ min:
+38%
+					</li>
+					<li>
+						% cancelled:
+							n/a
+					</li>
+				</ul>	   
+		</div>
+
+	<div >
+		<ul >
+			<li>
+				Duration: 
+1h<span >ours</span>
+20m<span >inutes</span>
+			</li>
+				<li>
+					Meal: None
+				</li>
+		</ul>
+	</div>
+	 
+
+</div>
+									<div style="padding-bottom: 5px; line-height: 10px; padding-left: 0px; padding-right: 0px; padding-top: 5px;">
+										<div style="background-color: #999999; height: 1px;">
+										</div>
+									</div>
+									
+<div >
+		<div >Performance data is based on previous month.</div>
+</div>
+								</div>
+							</div>							
+						</td>
+						<td>
+							<!-- mp_trans_disable_start -->San Francisco (SFO) <!-- mp_trans_disable_end --><br>
+							<strong>12:40 <abbr>pm</abbr></strong>&nbsp;&nbsp;<abbr title="Tuesday">Tue</abbr>, <abbr title="November">Nov</abbr> 18
+						</td>
+						<td>
+							<!-- mp_trans_disable_start -->Los Angeles, CA (LAX)<!-- mp_trans_disable_end --><br>
+							
+							<strong>2:00 <abbr>pm</abbr></strong>&nbsp;&nbsp;<abbr title="Tuesday">Tue</abbr>, <abbr title="November">Nov</abbr> 18
+						</td>									
+					</tr>
+							
+				
+				<tr>
+					
+					<td colspan="3">
+						
+									<a href="javascript://About Distance" onclick="showDistanceLB($(this));">Distance</a>: 
+								337 <abbr title="miles">mi</abbr>
+							 <span  aria-hidden="true">|</span> 		
+								Duration: 1h<span >ours</span> 20m<span >inutes</span>
+							
+					</td>
+				</tr>
+				
+								
+	
+</tbody></table>
+<div >
+	<div>
+		<h4 style="margin:0;">Total Price for 1 Traveler</h4>	
+	</div>
+	<div >
+		<span >$152.20</span>
+		
+	
+	<div ></div>
+
+	
+		<div style="padding-top:3px;padding-bottom:5px;"><a  href="javascript:void(0);" onclick="showFareAndTaxes($(this))">Taxes, Fees and Charges</a></div>
+	
+	<div id="divFareAndTaxesLB" style="display:none;overflow:auto;max-height:480px;">
+		<h2>Taxes, Fees and Charges</h2>
+		
+<style type="text/css">
+	#divFareAndTaxes {width:400px;line-height:18px;margin-top:15px;}
+	#divFareAndTaxes div.header1 {width:400px;background-color:#E2EEFF;font-weight:bold;}
+	#divFareAndTaxes div.header2 {width:400px;background-color:#ECEFE1;} /* need width on header rows otherwise background color doesn't show in IE7 */
+	#divFareAndTaxes div.header1 h5{margin:0;color:inherit;font-weight:bold;}
+	#divFareAndTaxes div.header2 h6{margin:0;color:inherit;}
+	#divFareAndTaxes div.indent0 {display:table-cell;width:239px;padding-left:1px;} /* display:table-cell doesn't work in IE7, so in the next section we will add float:left just for IE7 */
+	#divFareAndTaxes div.indent1 {display:table-cell;width:220px;padding-left:20px;}
+	#divFareAndTaxes div.indent2 {display:table-cell;width:200px;padding-left:40px;}
+	#divFareAndTaxes div.indent2wide {display:table-cell;width:260px;padding-left:60px;text-indent:-20px;}
+	#divFareAndTaxes div.amount {display:table-cell;width:155px;padding-right:5px;text-align:right;vertical-align:bottom;}
+	#divFareAndTaxes div.amount2 {display:table-cell;width:75px;padding-right:5px;text-align:right;vertical-align:bottom;}
+</style>
+<!--[if lte IE 7]>
+<style type="text/css">
+	#divFareAndTaxes div.indent0,
+	#divFareAndTaxes div.indent1,
+	#divFareAndTaxes div.indent2,
+	#divFareAndTaxes div.indent2wide,
+	#divFareAndTaxes div.amount,
+	#divFareAndTaxes div.amount2 {float:left;}
+</style>
+<![endif]-->
+
+<div id="divFareAndTaxes">
+	<div >
+		<div >
+			<h5>Total per Traveler</h5>
+		</div>
+		<div >$152.20</div>
+	</div>
+	<div >
+		<div ><h6>Fare</h6></div>
+		<div >$115.34</div>
+	</div>
+	<div >
+		<div>
+			<div >Base Fare</div>
+			<div >$115.34</div>
+		</div>
+	</div>
+		<div >
+			<div ><h6>Taxes and Fees</h6></div>
+			<div >$36.86</div>
+		</div>
+		<div >
+			 <div>
+				<div >US Flight Segment Tax</div>
+				<div >$8.00</div>
+			 </div>
+			 <div>
+				<div >US Psgr. Facility Charge</div>
+				<div >$9.00</div>
+			 </div>
+			 <div>
+				<div >US Sept. 11 Security Fee</div>
+				<div >$11.20</div>
+			 </div>
+			 <div>
+				<div >US Transportation Tax</div>
+				<div >$8.66</div>
+			 </div>
+		</div>
+
+	<div ></div>
+</div>
+		<div ></div>
+		
+
+		<div >Each ticket and any booking or change fees will be a separate charge on your credit card statement.</div>
+	</div>
+
+
+<div style="padding-top:5px;">
+	
+</div>	
+
+<div style="padding-top:10px;">
+	
+</div>
+			
+		
+
+
+
+
+</div>
+</div>
+<div ></div>
+<div id="DistanceLB" style="display:none;">
+	<h2 style="margin-bottom:0.83em;">Distance</h2>
+	<p>Distance noted reflects trip length, and may not accurately reflect frequent flyer miles earned. Please refer to your frequent flyer program terms and conditions to determine miles earned.</p>
+</div>
+
+
+
+                    </div>
+                    
+					<div  style="display: none;">
+                        <div  style="margin-top:10px;"></div>
+						
+	<div style="margin-bottom:0.83em;">
+		<h2 style="display:inline;margin-right:5px;">Trip Protection By Allianz Travel Insurance</h2>
+		<a href="javascript:void(0);" onclick="showRemoveTripInsurance(this);">Remove</a>
+	</div>
+
+	<div >
+		<div >
+			<h4>Name</h4>
+			
+				<div>
+				<!-- mp_trans_disable_start -->Shorty&nbsp;Nge
+				
+				<!-- mp_trans_disable_end -->
+				</div>
+			
+		</div>	
+		<div >
+			&nbsp;
+		</div>	
+		<div >
+			&nbsp;
+		</div>   
+		<div ></div>
+	</div>
+	<div >
+		<h4>Total Price</h4>
+		<span >0</span>
+	</div>
+	<div ></div>
+
+                    </div>		
+
+                    <div >
+                        
+
+<div>
+	<div id="grandTotalLeftColumn" style="width:57%; float:left;">
+		
+	</div>
+	<div id="grandTotalRightColumn" style="width:43%; float:right; text-align:right;">
+		<div style="display:block;padding-right:10px;">
+			
+				<div>
+					<div style="width:40%;float:left;text-align:right;"><h4 style="margin-bottom:5px;display:inline-block;">Total Due Now</h4></div><div style="width:60%;float:left;text-align:left;"><h4 style="display:inline-block;">&nbsp;&nbsp;&nbsp;<span id="divTotalDueNowAmount">$152.20 USD</span></h4></div>
+					<div ></div>
+				</div>
+			
+				<div>
+
+<a id="ShowCurrencyConverterLink" href="https://www.alaskaair.com/booking/addons#">Currency Converter</a>
+
+<!-- We load the contents via ajax so that we don't have to bind a model on every page that wants the converter -->
+<div id="CurrencyConverterContainer" style="display: none">
+
+	<div id="CurrencyConverterLoading" style="display: none">
+	</div>
+	<div id="CurrencyConverterForm"></div>
+
+	<div id="ErrorResults" style="display:none;">
+		<h1>Error Encountered</h1>
+		<div >
+			<p>We are unable to complete your transaction at this time. Please try again.</p>
+			<p>If this problem continues use the "Contact Us" page to send the code listed below, 
+			or call us at 1-800-654-5669, Monday-Friday 8:00 a.m. - 5:45 p.m. (PT) and Saturday 8:00 a.m. - 5:00 p.m. (PT).</p>
+		</div>
+	</div>
+</div>
+
+<a href="https://www.alaskaair.com/Shopping/CurrencyConverter" id="CurrencyConverterURL" style="display: none;">.</a>
+<a href="https://www.alaskaair.com/Shopping/CurrencyConverter/GetContents" id="CurrencyContentsURL" style="display: none;">.</a></div>
+					<div ></div>
+				</div>
+			
+		</div>
+		<div ></div>
+	</div>
+	<div ></div>
+</div>
+
+                        <div >
+                        </div>
+                    </div>
+                    <div  onclick="toggle(&#39;priceSummaryArrow&#39;, &#39;priceSummaryContent&#39;);">
+                        <div id="priceSummaryArrow" ></div>
+                        <h4 id="priceSummaryHeading" style="padding-top: 4px;"><a href="javascript://Show/hide section">PRICE SUMMARY</a></h4>
+                    </div>
+                    <div id="priceSummaryContent" >
+                        
+	<div  style="padding-bottom:18px;">
+		
+
+<table  cellspacing="0">
+	<thead>
+		<tr>
+			<th>&nbsp;</th>
+			<th>Fare</th><th>Taxes, Fees and Charges</th>
+				<th>Total</th>
+						
+		</tr>
+	</thead>
+	<tbody>
+		
+			<tr>
+				<td>
+					Airfare for <!-- mp_trans_disable_start -->Shorty Nge <!-- mp_trans_disable_end -->:
+				</td>
+				<td>$115.34</td><td>$36.86</td>
+				<td>$152.20</td>
+			</tr>
+		
+					<tr id="trTripInsuranceBreakdown" style="display: none;">
+						<td>Trip Protection for 1  
+						 Traveler :</td>
+						<td>&nbsp;</td><td>&nbsp;</td>
+						<td id="tdTripInsuranceBreakdown">$0.00</td>
+					</tr>
+				
+				<tr><td colspan="4" >Total Due Now:&nbsp; <span id="spFareSummaryAmount">$152.20</span></td></tr>
+			
+	</tbody>
+</table>
+
+	</div>
+	<div ></div>
+
+	<div id="taxesFees" style="text-align:left; display:none;font-weight:normal;">
+		
+       <div id="TaxesAndFeesSub" style="min-height:500px;"></div>
+	</div>
+	<div id="fareExplanations" style="font-weight:normal;text-align:left; display:none;"></div>
+
+
+                        <div >Each ticket and any booking or change fees will be a separate charge on your credit card statement.</div>
+                    </div>
+                    <div  style="margin-left: -20px; width: 973px;">
+                    </div>
+                    <!--  These ShowHeader flags look for Reissue and Government Fare-->
+                    
+                    <h2>
+                        My Wallet / Certificates / Gift Cards </h2>
+                    
+                    <div id="MYWALLETCHECKBOX">
+                        
+                        <!--TODO:  THis should only show when logged in but funds as disabled ... for not AS/QX-->
+                        
+                        <div >
+                            <a title="Why can&#39;t I use these funds?" href="javascript:void(0);" onclick="showWhyCantUseFundsTip(this);return false;">
+                                Why can't I use these funds?</a></div>
+                        
+                        <div style="float: left; margin-right: 5px; vertical-align: middle;">
+                            <input disabled="disabled" id="MyWalletInformation_UseMyWalletFunds" name="MyWalletInformation.UseMyWalletFunds" type="checkbox" value="true"><input name="MyWalletInformation.UseMyWalletFunds" type="hidden" value="false"></div>
+                        <div  style="vertical-align: middle;">
+                            <label for="MyWalletInformation_UseMyWalletFunds">Use My Wallet Funds</label></div>
+                        
+                        <div  style="margin-left: 24px;">
+                            <a  title="My Wallet Terms and Conditions" href="javascript:void(0);" onclick="showMyWalletTerms(this);return false;">Terms and Conditions</a>
+                        </div>
+                        <div  style="height: 8px;">
+                        </div>
+                    </div>
+                    <input id="MyWalletInformation_ShowCheckbox" name="MyWalletInformation.ShowCheckbox" type="hidden" value="True">
+                    
+                    <div id="GIFTCARDSANDCERTIFICATESCHECKBOX">
+                        
+                        <div style="float: left; margin-right: 5px; vertical-align: middle;">
+                            <input disabled="disabled" id="GiftCardsAndCertificatesInformation_UseGiftCardsOrCertificates" name="GiftCardsAndCertificatesInformation.UseGiftCardsOrCertificates" type="checkbox" value="true"><input name="GiftCardsAndCertificatesInformation.UseGiftCardsOrCertificates" type="hidden" value="false"></div>
+                        <div style="float: left; vertical-align: middle;">
+                            <label for="GiftCardsAndCertificatesInformation_UseGiftCardsOrCertificates">Use Certificates or Gift Cards (not deposited in a My Wallet account)</label></div>
+                        
+                        <div >
+                        </div>
+                    </div>
+                    <input id="GiftCardsAndCertificatesInformation_ShowCheckbox" name="GiftCardsAndCertificatesInformation.ShowCheckbox" type="hidden" value="True">
+                    <div id="GIFTCARDSANDCERTIFICATES" style="display: none;">
+                        
+                    </div>
+                    <div id="GIFTCARDSANDCERTIFICATESSUMMARY">
+                        
+                    </div>
+                    <input id="GiftCardsAndCertificatesInformation_ShowGiftCardOrCertificateEntries" name="GiftCardsAndCertificatesInformation.ShowGiftCardOrCertificateEntries" type="hidden" value="False">
+                    <input id="GiftCardsAndCertificatesInformation_ShowGiftCardsOrCertificates" name="GiftCardsAndCertificatesInformation.ShowGiftCardsOrCertificates" type="hidden" value="False">
+                    <input id="GiftCardsAndCertificatesInformation_GrandTotalAmountToCollect" name="GiftCardsAndCertificatesInformation.GrandTotalAmountToCollect" type="hidden" value="0">
+                    <div id="MYWALLETINFORMATION" style="display: none;">
+                        <input id="MyWalletInformation_ShowMyWalletSummaryAndDetail" name="MyWalletInformation.ShowMyWalletSummaryAndDetail" type="hidden" value="False">
+                        <input id="MyWalletInformation_GrandTotalAmountToCollect" name="MyWalletInformation.GrandTotalAmountToCollect" type="hidden" value="0">
+                    </div>
+                    
+                    <div id="CREDITCARDANDTIPBOX">
+                        <div >
+                        </div>
+                        
+                        <hr >
+                        
+                        <div id="CREDITCARD">
+							<h2> Credit Card Information</h2>
+							<!--Show Booking Engine Credit Card Error here-->
+<!--Non Ticket Credit Card Error-->
+<!--CreditCardRequiredText-->
+<!--Government Fare Advisory-->
+<div id="CreditCardInformation">
+<div >
+    <h5 >
+        Billing Information</h5>
+</div>
+<div >
+</div>
+    <div id="BILLINGCREDITCARDENTRY">
+        <!--Billing Credit Card Error-->
+        <!--  For error messages that need to bubble from within the validation method, instead of for a specific form element -- example -- credit card doesn't validate--->
+        
+        <!--Card Types-->
+        
+        <div id="CardTypesSelected">
+			<div id="CardTypesSelectedLabel" >Card Type<span >*</span></div>
+			<div>
+<input checked="checked" id="CreditCard" name="CreditCardInformation.BillingCreditCardEntry.CardTypes_Selected" onclick="SetCreditCardPaymentType(&#39;creditcard&#39;);" style="margin-bottom:20px;" type="radio" value="CreditCard">				<label  for="CreditCard">
+			</div>
+			<div >
+<input id="CommercialAccount" name="CreditCardInformation.BillingCreditCardEntry.CardTypes_Selected" onclick="SetCreditCardPaymentType(&#39;as&#39;);" type="radio" value="AS">                <label  for="CommercialAccount">Alaska Airlines Commercial Account</label>
+			</div>
+        </div>
+        <div >
+        </div>
+        <!--Card Number-->
+        
+        <div id="CardNumberLabel"><label for="CreditCardInformation_BillingCreditCardEntry_CardNumber">Card Number</label><span >*</span></div>
+        <div id="CardNumber">
+            <!-- mp_trans_disable_start -->
+<input autocomplete="off" id="CreditCardInformation_BillingCreditCardEntry_CardNumber" maxlength="24" name="CreditCardInformation.BillingCreditCardEntry.CardNumber" type="text" value="">            <!-- mp_trans_disable_end -->
+        </div>
+        <div >
+        </div>
+        <!--Generic Expiration Date Errors-->
+        
+        
+        <div>
+            Expiration<span >*</span></div>
+        <div id="ExpirationMonths" style="float: left; padding-right: 10px;">
+            <!-- mp_trans_disable_start -->
+            <select id="CreditCardInformation_BillingCreditCardEntry_ExpirationMonths_Selected" name="CreditCardInformation.BillingCreditCardEntry.ExpirationMonths_Selected" style="width:65px;"><option value="">Month</option>
+<option value="1">1</option>
+<option value="2">2</option>
+<option value="3">3</option>
+<option value="4">4</option>
+<option value="5">5</option>
+<option value="6">6</option>
+<option value="7">7</option>
+<option value="8">8</option>
+<option value="9">9</option>
+<option value="10">10</option>
+<option value="11">11</option>
+<option value="12">12</option>
+<option value="None">None</option>
+</select>
+            <!-- mp_trans_disable_end -->
+        </div>
+        <div id="ExpirationYears" style="float: left;">
+            <!-- mp_trans_disable_start -->
+            <select id="CreditCardInformation_BillingCreditCardEntry_ExpirationYears_Selected" name="CreditCardInformation.BillingCreditCardEntry.ExpirationYears_Selected" style="width:65px;"><option value="">Year</option>
+<option value="2014">2014</option>
+<option value="2015">2015</option>
+<option value="2016">2016</option>
+<option value="2017">2017</option>
+<option value="2018">2018</option>
+<option value="2019">2019</option>
+<option value="2020">2020</option>
+<option value="2021">2021</option>
+<option value="2022">2022</option>
+<option value="2023">2023</option>
+<option value="2024">2024</option>
+<option value="None">None</option>
+</select>
+            <!-- mp_trans_disable_end -->
+        </div>
+        <div >
+        </div>
+        <!--Name on Card-->
+        
+        <div id="CardPersonNameLabel"><label for="CreditCardInformation_BillingCreditCardEntry_CardPersonName">Name on Card</label><span >*</span></div>
+        <div id="CardPersonName">
+            <!-- mp_trans_disable_start -->
+            <input id="CreditCardInformation_BillingCreditCardEntry_CardPersonName" maxlength="38" name="CreditCardInformation.BillingCreditCardEntry.CardPersonName" size="41" type="text" value="">
+            <!-- mp_trans_disable_end -->
+        </div>
+    </div>
+    <div >
+    </div>
+<input id="CreditCardInformation_ShowBillingCreditCardEntry" name="CreditCardInformation.ShowBillingCreditCardEntry" type="hidden" value="True">
+<input id="CreditCardInformation_ShowBillingCreditCards" name="CreditCardInformation.ShowBillingCreditCards" type="hidden" value="False">
+<input id="CreditCardInformation_SelectedBillingCardType" name="CreditCardInformation.SelectedBillingCardType" type="hidden" value="creditcard">
+
+<div >
+</div>
+    <div style="float: left">
+        <h5 >
+            Billing Address</h5>
+    </div>
+    <div id="BILLINGADDRESSENTRY">
+        <div >
+        </div>
+        <!--Countries-->
+        
+        <div id="CountriesLabel"><label for="CreditCardInformation_BillingAddressEntry_Countries_Selected">Country</label><span >*</span></div>
+        <div id="Countries">
+            <!-- mp_trans_disable_start -->
+            <select  id="CreditCardInformation_BillingAddressEntry_Countries_Selected" name="CreditCardInformation.BillingAddressEntry.Countries_Selected"><option value="US">United States</option>
+<option value="CA">Canada</option>
+<option value="MX">Mexico</option>
+<option value="AF">Afghanistan</option>
+<option value="AL">Albania</option>
+<option value="DZ">Algeria</option>
+<option value="AS">American Samoa</option>
+<option value="AD">Andorra</option>
+<option value="AO">Angola</option>
+<option value="AI">Anguilla</option>
+<option value="AQ">Antarctica</option>
+<option value="AG">Antigua And Barbuda</option>
+<option value="AR">Argentina</option>
+<option value="AM">Armenia</option>
+<option value="AW">Aruba</option>
+<option value="AU">Australia</option>
+<option value="AT">Austria</option>
+<option value="AZ">Azerbaijan</option>
+<option value="BS">Bahamas</option>
+<option value="BH">Bahrain</option>
+<option value="BD">Bangladesh</option>
+<option value="BB">Barbados</option>
+<option value="BY">Belarus</option>
+<option value="BE">Belgium</option>
+<option value="BZ">Belize</option>
+<option value="BJ">Benin</option>
+<option value="BM">Bermuda</option>
+<option value="BT">Bhutan</option>
+<option value="BO">Bolivia</option>
+<option value="BQ">Bonaire, Saint Eustatius and Saba</option>
+<option value="BA">Bosnia And Herzegovina</option>
+<option value="BW">Botswana</option>
+<option value="BR">Brazil</option>
+<option value="IO">British Indian Ocean Territory</option>
+<option value="VG">British Virgin Islands</option>
+<option value="BN">Brunei Darussalam</option>
+<option value="BG">Bulgaria</option>
+<option value="BF">Burkina Faso</option>
+<option value="BI">Burundi</option>
+<option value="KH">Cambodia</option>
+<option value="CM">Cameroon</option>
+<option value="CA">Canada</option>
+<option value="CV">Cape Verde</option>
+<option value="KY">Cayman Islands</option>
+<option value="CF">Central African Republic</option>
+<option value="TD">Chad</option>
+<option value="CL">Chile</option>
+<option value="CN">China</option>
+<option value="CX">Christmas Island</option>
+<option value="CC">Cocos (Keeling) Islands</option>
+<option value="CO">Colombia</option>
+<option value="KM">Comoros</option>
+<option value="CG">Congo</option>
+<option value="CD">Congo (DRC)</option>
+<option value="CK">Cook Islands</option>
+<option value="CR">Costa Rica</option>
+<option value="CI">Cote D`ivoire</option>
+<option value="HR">Croatia</option>
+<option value="CU">Cuba</option>
+<option value="CW">Curacao</option>
+<option value="CY">Cyprus</option>
+<option value="CZ">Czech Republic</option>
+<option value="DK">Denmark</option>
+<option value="DJ">Djibouti</option>
+<option value="DM">Dominica</option>
+<option value="DO">Dominican Republic</option>
+<option value="TP">East Timor</option>
+<option value="EC">Ecuador</option>
+<option value="EG">Egypt</option>
+<option value="SV">El Salvador</option>
+<option value="GQ">Equatorial Guinea</option>
+<option value="ER">Eritrea</option>
+<option value="EE">Estonia</option>
+<option value="ET">Ethiopia</option>
+<option value="FK">Falkland Islands (Malvinas)</option>
+<option value="FO">Faroe Islands</option>
+<option value="FJ">Fiji</option>
+<option value="FI">Finland</option>
+<option value="FR">France</option>
+<option value="GF">French Guiana</option>
+<option value="PF">French Polynesia</option>
+<option value="GA">Gabon</option>
+<option value="GM">Gambia</option>
+<option value="GE">Georgia</option>
+<option value="DE">Germany</option>
+<option value="GH">Ghana</option>
+<option value="GI">Gibraltar</option>
+<option value="GR">Greece</option>
+<option value="GL">Greenland</option>
+<option value="GD">Grenada</option>
+<option value="GP">Guadeloupe</option>
+<option value="GU">Guam</option>
+<option value="GT">Guatemala</option>
+<option value="GN">Guinea</option>
+<option value="GW">Guinea-Bissau</option>
+<option value="GY">Guyana</option>
+<option value="HT">Haiti</option>
+<option value="VA">Holy See (Vatican City State)</option>
+<option value="HN">Honduras</option>
+<option value="HK">Hong Kong</option>
+<option value="HU">Hungary</option>
+<option value="IS">Iceland</option>
+<option value="IN">India</option>
+<option value="ID">Indonesia</option>
+<option value="IQ">Iraq</option>
+<option value="IE">Ireland</option>
+<option value="IR">Islamic Republic Of Iran</option>
+<option value="IL">Israel</option>
+<option value="IT">Italy</option>
+<option value="JM">Jamaica</option>
+<option value="JP">Japan</option>
+<option value="JO">Jordan</option>
+<option value="KZ">Kazakhstan</option>
+<option value="KE">Kenya</option>
+<option value="KI">Kiribati</option>
+<option value="KP">Korea (DPRK)</option>
+<option value="KR">Korea (ROK)</option>
+<option value="CS">Kosovo</option>
+<option value="KW">Kuwait</option>
+<option value="KG">Kyrgyzstan</option>
+<option value="LA">Laos</option>
+<option value="LV">Latvia</option>
+<option value="LB">Lebanon</option>
+<option value="LS">Lesotho</option>
+<option value="LR">Liberia</option>
+<option value="LY">Libya</option>
+<option value="LI">Liechtenstein</option>
+<option value="LT">Lithuania</option>
+<option value="LU">Luxembourg</option>
+<option value="MO">Macao</option>
+<option value="MK">Macedonia</option>
+<option value="MG">Madagascar</option>
+<option value="MW">Malawi</option>
+<option value="MY">Malaysia</option>
+<option value="MV">Maldives</option>
+<option value="ML">Mali</option>
+<option value="MT">Malta</option>
+<option value="MH">Marshall Islands</option>
+<option value="MQ">Martinique</option>
+<option value="MR">Mauritania</option>
+<option value="MU">Mauritius</option>
+<option value="YT">Mayotte</option>
+<option value="MX">Mexico</option>
+<option value="FM">Micronesia</option>
+<option value="MD">Moldova, Republic Of</option>
+<option value="MC">Monaco</option>
+<option value="MN">Mongolia</option>
+<option value="ME">Montenegro</option>
+<option value="MS">Montserrat</option>
+<option value="MA">Morocco</option>
+<option value="MZ">Mozambique</option>
+<option value="MM">Myanmar</option>
+<option value="NA">Namibia</option>
+<option value="NR">Nauru</option>
+<option value="NP">Nepal</option>
+<option value="NL">Netherlands</option>
+<option value="NC">New Caledonia</option>
+<option value="NZ">New Zealand</option>
+<option value="NI">Nicaragua</option>
+<option value="NE">Niger</option>
+<option value="NG">Nigeria</option>
+<option value="NU">Niue</option>
+<option value="NF">Norfolk Island</option>
+<option value="MP">Northern Mariana Islands</option>
+<option value="NO">Norway</option>
+<option value="OM">Oman</option>
+<option value="PK">Pakistan</option>
+<option value="PW">Palau</option>
+<option value="PA">Panama</option>
+<option value="PG">Papua New Guinea</option>
+<option value="PY">Paraguay</option>
+<option value="PE">Peru</option>
+<option value="PH">Philippines</option>
+<option value="PN">Pitcairn</option>
+<option value="PL">Poland</option>
+<option value="PT">Portugal</option>
+<option value="PR">Puerto Rico</option>
+<option value="QA">Qatar</option>
+<option value="RE">Reunion</option>
+<option value="RO">Romania</option>
+<option value="RU">Russian Federation</option>
+<option value="RW">Rwanda</option>
+<option value="WS">Samoa</option>
+<option value="SM">San Marino</option>
+<option value="ST">Sao Tome And Principe</option>
+<option value="SA">Saudi Arabia</option>
+<option value="SN">Senegal</option>
+<option value="RS">Serbia</option>
+<option value="SC">Seychelles</option>
+<option value="SL">Sierra Leone</option>
+<option value="SG">Singapore</option>
+<option value="SK">Slovakia</option>
+<option value="SI">Slovenia</option>
+<option value="SB">Solomon Islands</option>
+<option value="SO">Somalia</option>
+<option value="ZA">South Africa</option>
+<option value="ES">Spain</option>
+<option value="LK">Sri Lanka</option>
+<option value="SH">St. Helena</option>
+<option value="KN">St. Kitts And Nevis</option>
+<option value="LC">St. Lucia</option>
+<option value="SX">St. Maarten</option>
+<option value="PM">St. Pierre And Miquelon</option>
+<option value="VC">St. Vincent And The Grenadines</option>
+<option value="SD">Sudan</option>
+<option value="SR">Suriname</option>
+<option value="SZ">Swaziland</option>
+<option value="SE">Sweden</option>
+<option value="CH">Switzerland</option>
+<option value="SY">Syrian Arab Republic</option>
+<option value="TW">Taiwan, R.O.C.</option>
+<option value="TJ">Tajikistan</option>
+<option value="TH">Thailand</option>
+<option value="TG">Togo</option>
+<option value="TK">Tokelau</option>
+<option value="TO">Tonga</option>
+<option value="TT">Trinidad And Tobago</option>
+<option value="TN">Tunisia</option>
+<option value="TR">Turkey</option>
+<option value="TM">Turkmenistan</option>
+<option value="TC">Turks And Caicos Islands</option>
+<option value="TV">Tuvalu</option>
+<option value="UM">U.S. Minor Outlying Islands</option>
+<option value="VI">U.S. Virgin Islands</option>
+<option value="UG">Uganda</option>
+<option value="UA">Ukraine</option>
+<option value="AE">United Arab Emirates</option>
+<option value="GB">United Kingdom</option>
+<option value="TZ">United Republic Of Tanzania</option>
+<option value="US">United States</option>
+<option value="UY">Uruguay</option>
+<option value="UZ">Uzbekistan</option>
+<option value="VU">Vanuatu</option>
+<option value="VE">Venezuela</option>
+<option value="VN">Viet Nam</option>
+<option value="WF">Wallis And Futuna</option>
+<option value="EH">Western Sahara</option>
+<option value="YE">Yemen</option>
+<option value="ZM">Zambia</option>
+<option value="ZW">Zimbabwe</option>
+</select>
+            <!-- mp_trans_disable_end -->
+        </div>
+        <div >
+        </div>
+        
+        <div id="Address1Label"><label for="CreditCardInformation_BillingAddressEntry_Address1">Address</label><span >*</span></div>
+        <div id="Address1" style="margin-bottom: 5px;">
+            <!-- mp_trans_disable_start -->
+            <input id="CreditCardInformation_BillingAddressEntry_Address1" maxlength="29" name="CreditCardInformation.BillingAddressEntry.Address1" size="27" type="text" value="">
+            <!-- mp_trans_disable_end -->
+        </div>
+        
+        <div id="Address2Label">
+            <span ><label for="CreditCardInformation_BillingAddressEntry_Address2">Address Line 2</label></span>
+        </div>
+        <div id="Address2">
+            <!-- mp_trans_disable_start -->
+            <input id="CreditCardInformation_BillingAddressEntry_Address2" maxlength="29" name="CreditCardInformation.BillingAddressEntry.Address2" size="27" type="text" value="">
+            <!-- mp_trans_disable_end -->
+        </div>
+        <div >
+        </div>
+        <!--City-->
+        
+        <div id="CityLabel"><label for="CreditCardInformation_BillingAddressEntry_City">City</label><span >*</span></div>
+        <div id="City">
+            <!-- mp_trans_disable_start -->
+            <input id="CreditCardInformation_BillingAddressEntry_City" maxlength="28" name="CreditCardInformation.BillingAddressEntry.City" size="27" type="text" value="">
+            <!-- mp_trans_disable_end -->
+        </div>
+        <div >
+        </div>
+        <div id="USSTATES" style="display: block;">
+            
+            <div><label for="CreditCardInformation_BillingAddressEntry_USStates_Selected">State/Province</label><span >*</span></div>
+            <div>
+                <!-- mp_trans_disable_start -->
+                <select  id="CreditCardInformation_BillingAddressEntry_USStates_Selected" name="CreditCardInformation.BillingAddressEntry.USStates_Selected"><option value="">Select</option>
+<option value="AL">Alabama</option>
+<option value="AK">Alaska</option>
+<option value="AZ">Arizona</option>
+<option value="AR">Arkansas</option>
+<option value="CA">California</option>
+<option value="CO">Colorado</option>
+<option value="CT">Connecticut</option>
+<option value="DE">Delaware</option>
+<option value="FL">Florida</option>
+<option value="GA">Georgia</option>
+<option value="HI">Hawaii</option>
+<option value="ID">Idaho</option>
+<option value="IL">Illinois</option>
+<option value="IN">Indiana</option>
+<option value="IA">Iowa</option>
+<option value="KS">Kansas</option>
+<option value="KY">Kentucky</option>
+<option value="LA">Louisiana</option>
+<option value="ME">Maine</option>
+<option value="MD">Maryland</option>
+<option value="MA">Massachusetts</option>
+<option value="MI">Michigan</option>
+<option value="MN">Minnesota</option>
+<option value="MS">Mississippi</option>
+<option value="MO">Missouri</option>
+<option value="MT">Montana</option>
+<option value="NE">Nebraska</option>
+<option value="NV">Nevada</option>
+<option value="NH">New Hampshire</option>
+<option value="NJ">New Jersey</option>
+<option value="NM">New Mexico</option>
+<option value="NY">New York</option>
+<option value="NC">North Carolina</option>
+<option value="ND">North Dakota</option>
+<option value="OH">Ohio</option>
+<option value="OK">Oklahoma</option>
+<option value="OR">Oregon</option>
+<option value="PA">Pennsylvania</option>
+<option value="RI">Rhode Island</option>
+<option value="SC">South Carolina</option>
+<option value="SD">South Dakota</option>
+<option value="TN">Tennessee</option>
+<option value="TX">Texas</option>
+<option value="UT">Utah</option>
+<option value="VT">Vermont</option>
+<option value="VA">Virginia</option>
+<option value="WA">Washington</option>
+<option value="WV">West Virginia</option>
+<option value="WI">Wisconsin</option>
+<option value="WY">Wyoming</option>
+<option value=" ">------------------------------------</option>
+<option value="AS">American Samoa</option>
+<option value="DC">District Of Columbia</option>
+<option value="FM">Federated States Of Micronesia</option>
+<option value="GU">Guam</option>
+<option value="MH">Marshall Islands</option>
+<option value="MP">Northern Mariana Islands</option>
+<option value="PW">Palau</option>
+<option value="PR">Puerto Rico</option>
+<option value="VI">Virgin Islands</option>
+<option value=" ">------------------------------------</option>
+<option value="AA">AA - Armed Forces America</option>
+<option value="AE">AE - Armed Forces Europe</option>
+<option value="AP">AP - Armed Forces Pacific</option>
+</select>
+                <!-- mp_trans_disable_end -->
+            </div>
+        </div>
+        <div id="CASTATES" style="display: none;">
+            
+            <div><label for="CreditCardInformation_BillingAddressEntry_CAStates_Selected">State/Province</label><span >*</span></div>
+            <div>
+                <!-- mp_trans_disable_start -->
+                <select  id="CreditCardInformation_BillingAddressEntry_CAStates_Selected" name="CreditCardInformation.BillingAddressEntry.CAStates_Selected"><option value="">Select</option>
+<option value="AB">Alberta</option>
+<option value="BC">British Columbia</option>
+<option value="MB">Manitoba</option>
+<option value="NB">New Brunswick</option>
+<option value="NF">Newfoundland</option>
+<option value="NT">Northwest Territories</option>
+<option value="NS">Nova Scotia</option>
+<option value="NU">Nunavut</option>
+<option value="ON">Ontario</option>
+<option value="PE">Prince Edward Island</option>
+<option value="QC">Quebec</option>
+<option value="SK">Saskatchewan</option>
+<option value="YT">Yukon Territory</option>
+</select>
+                <!-- mp_trans_disable_end -->
+            </div>
+        </div>
+        <div id="MXSTATES" style="display: none;">
+            
+            <div><label for="CreditCardInformation_BillingAddressEntry_MXStates_Selected">State/Province</label><span >*</span></div>
+            <div>
+                <!-- mp_trans_disable_start -->
+                <select  id="CreditCardInformation_BillingAddressEntry_MXStates_Selected" name="CreditCardInformation.BillingAddressEntry.MXStates_Selected"><option value="">Select</option>
+<option value="AGS">Aguascalientes</option>
+<option value="BCN">Baja California</option>
+<option value="BCS">Baja California Sur</option>
+<option value="CAM">Campeche</option>
+<option value="CHIS">Chiapas</option>
+<option value="CHIH">Chihuahua</option>
+<option value="COAH">Coahuila</option>
+<option value="COL">Colima</option>
+<option value="DF">Distrito Federal</option>
+<option value="DGO">Durango</option>
+<option value="GTO">Guanajuato</option>
+<option value="GRO">Guerrero</option>
+<option value="HGO">Hidalgo</option>
+<option value="JAL">Jalisco</option>
+<option value="MEX">Mexico</option>
+<option value="MICH">Michoacan</option>
+<option value="MOR">Morelos</option>
+<option value="NAY">Nayarit</option>
+<option value="NL">Nuevo Leon</option>
+<option value="OAX">Oaxaca</option>
+<option value="PUE">Puebla</option>
+<option value="QRO">Queretaro</option>
+<option value="QROO">Quintana Roo</option>
+<option value="SLP">San Luis Potosi</option>
+<option value="SIN">Sinaloa</option>
+<option value="SON">Sonora</option>
+<option value="TAB">Tabasco</option>
+<option value="TAMPS">Tamaulipas</option>
+<option value="TLAX">Tlaxcala</option>
+<option value="VER">Veracruz</option>
+<option value="YUC">Yucatan</option>
+<option value="ZAC">Zacatecas</option>
+</select>
+                <!-- mp_trans_disable_end -->
+            </div>
+        </div>
+        <div id="OTHERSTATES" style="display: none;">
+            
+            <div><label for="CreditCardInformation_BillingAddressEntry_OtherStates_Selected">State/Province</label><span >*</span></div>
+            <div>
+                <!-- mp_trans_disable_start -->
+                <input  id="CreditCardInformation_BillingAddressEntry_OtherStates_Selected" name="CreditCardInformation.BillingAddressEntry.OtherStates_Selected" type="text" value="">
+                <!-- mp_trans_disable_end -->
+            </div>
+        </div>
+        <div >
+        </div>
+        <div id="POSTALCODE">
+            
+            <div><label for="CreditCardInformation_BillingAddressEntry_PostalCode">Zip/Postal Code</label><span >*</span></div>
+            <div>
+                <!-- mp_trans_disable_start -->
+                <input id="CreditCardInformation_BillingAddressEntry_PostalCode" maxlength="10" name="CreditCardInformation.BillingAddressEntry.PostalCode" type="text" value="">
+                <!-- mp_trans_disable_end -->
+            </div>
+            <div >
+            </div>
+        </div>
+    </div>
+<input id="CreditCardInformation_ShowBillingAddressEntry" name="CreditCardInformation.ShowBillingAddressEntry" type="hidden" value="True">
+<input id="CreditCardInformation_ShowBillingAddresses" name="CreditCardInformation.ShowBillingAddresses" type="hidden" value="False">
+<div >
+</div>
+    <div style="float: left">
+        <h5 >
+            Card Holder Phone Number</h5>
+    </div>
+    <div id="BILLINGPHONENUMBERENTRY">
+        <div >
+        </div>
+        <!--Country Code-->
+        
+        <div id="CountryCodeLabel"><label for="CreditCardInformation_BillingPhoneNumberEntry_CountryCode_Selected">Country Code</label><span >*</span></div>
+        <div id="CountryCode">
+            <!-- mp_trans_disable_start -->
+            <select  id="CreditCardInformation_BillingPhoneNumberEntry_CountryCode_Selected" name="CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected"><option value="1">United States/Canada (+1)</option>
+<option value="52">Mexico (+52)</option>
+<option value="93">Afghanistan (+93)</option>
+<option value="355">Albania (+355)</option>
+<option value="213">Algeria (+213)</option>
+<option value="1">American Samoa (+1)</option>
+<option value="376">Andorra (+376)</option>
+<option value="244">Angola (+244)</option>
+<option value="1">Anguilla (+1)</option>
+<option value="672">Antarctica (+672)</option>
+<option value="1">Antigua And Barbuda (+1)</option>
+<option value="54">Argentina (+54)</option>
+<option value="374">Armenia (+374)</option>
+<option value="297">Aruba (+297)</option>
+<option value="61">Australia (+61)</option>
+<option value="43">Austria (+43)</option>
+<option value="994">Azerbaijan (+994)</option>
+<option value="1">Bahamas (+1)</option>
+<option value="973">Bahrain (+973)</option>
+<option value="880">Bangladesh (+880)</option>
+<option value="1">Barbados (+1)</option>
+<option value="375">Belarus (+375)</option>
+<option value="32">Belgium (+32)</option>
+<option value="501">Belize (+501)</option>
+<option value="229">Benin (+229)</option>
+<option value="1">Bermuda (+1)</option>
+<option value="975">Bhutan (+975)</option>
+<option value="591">Bolivia (+591)</option>
+<option value="599">Bonaire, Saint Eustatius and Saba (+599)</option>
+<option value="387">Bosnia And Herzegovina (+387)</option>
+<option value="267">Botswana (+267)</option>
+<option value="55">Brazil (+55)</option>
+<option value="1">British Indian Ocean Territory (+1)</option>
+<option value="1">British Virgin Islands (+1)</option>
+<option value="673">Brunei Darussalam (+673)</option>
+<option value="359">Bulgaria (+359)</option>
+<option value="226">Burkina Faso (+226)</option>
+<option value="257">Burundi (+257)</option>
+<option value="855">Cambodia (+855)</option>
+<option value="237">Cameroon (+237)</option>
+<option value="1">Canada (+1)</option>
+<option value="238">Cape Verde (+238)</option>
+<option value="1">Cayman Islands (+1)</option>
+<option value="236">Central African Republic (+236)</option>
+<option value="235">Chad (+235)</option>
+<option value="56">Chile (+56)</option>
+<option value="86">China (+86)</option>
+<option value="61">Christmas Island (+61)</option>
+<option value="61">Cocos (Keeling) Islands (+61)</option>
+<option value="57">Colombia (+57)</option>
+<option value="269">Comoros (+269)</option>
+<option value="242">Congo (+242)</option>
+<option value="243">Congo (DRC) (+243)</option>
+<option value="682">Cook Islands (+682)</option>
+<option value="506">Costa Rica (+506)</option>
+<option value="225">Cote D`ivoire (+225)</option>
+<option value="385">Croatia (+385)</option>
+<option value="53">Cuba (+53)</option>
+<option value="599">Curacao (+599)</option>
+<option value="357">Cyprus (+357)</option>
+<option value="420">Czech Republic (+420)</option>
+<option value="45">Denmark (+45)</option>
+<option value="253">Djibouti (+253)</option>
+<option value="1">Dominica (+1)</option>
+<option value="1">Dominican Republic (+1)</option>
+<option value="670">East Timor (+670)</option>
+<option value="593">Ecuador (+593)</option>
+<option value="20">Egypt (+20)</option>
+<option value="503">El Salvador (+503)</option>
+<option value="240">Equatorial Guinea (+240)</option>
+<option value="291">Eritrea (+291)</option>
+<option value="372">Estonia (+372)</option>
+<option value="251">Ethiopia (+251)</option>
+<option value="500">Falkland Islands (Malvinas) (+500)</option>
+<option value="298">Faroe Islands (+298)</option>
+<option value="679">Fiji (+679)</option>
+<option value="358">Finland (+358)</option>
+<option value="33">France (+33)</option>
+<option value="594">French Guiana (+594)</option>
+<option value="689">French Polynesia (+689)</option>
+<option value="241">Gabon (+241)</option>
+<option value="220">Gambia (+220)</option>
+<option value="995">Georgia (+995)</option>
+<option value="49">Germany (+49)</option>
+<option value="233">Ghana (+233)</option>
+<option value="350">Gibraltar (+350)</option>
+<option value="30">Greece (+30)</option>
+<option value="299">Greenland (+299)</option>
+<option value="1">Grenada (+1)</option>
+<option value="590">Guadeloupe (+590)</option>
+<option value="1">Guam (+1)</option>
+<option value="502">Guatemala (+502)</option>
+<option value="224">Guinea (+224)</option>
+<option value="245">Guinea-Bissau (+245)</option>
+<option value="592">Guyana (+592)</option>
+<option value="509">Haiti (+509)</option>
+<option value="379">Holy See (Vatican City State) (+379)</option>
+<option value="504">Honduras (+504)</option>
+<option value="852">Hong Kong (+852)</option>
+<option value="36">Hungary (+36)</option>
+<option value="354">Iceland (+354)</option>
+<option value="91">India (+91)</option>
+<option value="62">Indonesia (+62)</option>
+<option value="964">Iraq (+964)</option>
+<option value="353">Ireland (+353)</option>
+<option value="98">Islamic Republic Of Iran (+98)</option>
+<option value="972">Israel (+972)</option>
+<option value="39">Italy (+39)</option>
+<option value="1">Jamaica (+1)</option>
+<option value="81">Japan (+81)</option>
+<option value="962">Jordan (+962)</option>
+<option value="7">Kazakhstan (+7)</option>
+<option value="254">Kenya (+254)</option>
+<option value="686">Kiribati (+686)</option>
+<option value="850">Korea (DPRK) (+850)</option>
+<option value="82">Korea (ROK) (+82)</option>
+<option value="381">Kosovo (+381)</option>
+<option value="965">Kuwait (+965)</option>
+<option value="996">Kyrgyzstan (+996)</option>
+<option value="856">Laos (+856)</option>
+<option value="371">Latvia (+371)</option>
+<option value="961">Lebanon (+961)</option>
+<option value="266">Lesotho (+266)</option>
+<option value="231">Liberia (+231)</option>
+<option value="218">Libya (+218)</option>
+<option value="423">Liechtenstein (+423)</option>
+<option value="370">Lithuania (+370)</option>
+<option value="352">Luxembourg (+352)</option>
+<option value="853">Macao (+853)</option>
+<option value="389">Macedonia (+389)</option>
+<option value="261">Madagascar (+261)</option>
+<option value="265">Malawi (+265)</option>
+<option value="60">Malaysia (+60)</option>
+<option value="960">Maldives (+960)</option>
+<option value="223">Mali (+223)</option>
+<option value="356">Malta (+356)</option>
+<option value="692">Marshall Islands (+692)</option>
+<option value="596">Martinique (+596)</option>
+<option value="222">Mauritania (+222)</option>
+<option value="230">Mauritius (+230)</option>
+<option value="262">Mayotte (+262)</option>
+<option value="52">Mexico (+52)</option>
+<option value="691">Micronesia (+691)</option>
+<option value="373">Moldova, Republic Of (+373)</option>
+<option value="377">Monaco (+377)</option>
+<option value="976">Mongolia (+976)</option>
+<option value="382">Montenegro (+382)</option>
+<option value="1">Montserrat (+1)</option>
+<option value="212">Morocco (+212)</option>
+<option value="258">Mozambique (+258)</option>
+<option value="95">Myanmar (+95)</option>
+<option value="264">Namibia (+264)</option>
+<option value="674">Nauru (+674)</option>
+<option value="977">Nepal (+977)</option>
+<option value="31">Netherlands (+31)</option>
+<option value="687">New Caledonia (+687)</option>
+<option value="64">New Zealand (+64)</option>
+<option value="505">Nicaragua (+505)</option>
+<option value="227">Niger (+227)</option>
+<option value="234">Nigeria (+234)</option>
+<option value="683">Niue (+683)</option>
+<option value="672">Norfolk Island (+672)</option>
+<option value="1">Northern Mariana Islands (+1)</option>
+<option value="47">Norway (+47)</option>
+<option value="968">Oman (+968)</option>
+<option value="92">Pakistan (+92)</option>
+<option value="680">Palau (+680)</option>
+<option value="507">Panama (+507)</option>
+<option value="675">Papua New Guinea (+675)</option>
+<option value="595">Paraguay (+595)</option>
+<option value="51">Peru (+51)</option>
+<option value="63">Philippines (+63)</option>
+<option value="872">Pitcairn (+872)</option>
+<option value="48">Poland (+48)</option>
+<option value="351">Portugal (+351)</option>
+<option value="1">Puerto Rico (+1)</option>
+<option value="974">Qatar (+974)</option>
+<option value="262">Reunion (+262)</option>
+<option value="40">Romania (+40)</option>
+<option value="7">Russian Federation (+7)</option>
+<option value="250">Rwanda (+250)</option>
+<option value="685">Samoa (+685)</option>
+<option value="378">San Marino (+378)</option>
+<option value="239">Sao Tome And Principe (+239)</option>
+<option value="966">Saudi Arabia (+966)</option>
+<option value="221">Senegal (+221)</option>
+<option value="381">Serbia (+381)</option>
+<option value="248">Seychelles (+248)</option>
+<option value="232">Sierra Leone (+232)</option>
+<option value="65">Singapore (+65)</option>
+<option value="421">Slovakia (+421)</option>
+<option value="386">Slovenia (+386)</option>
+<option value="677">Solomon Islands (+677)</option>
+<option value="252">Somalia (+252)</option>
+<option value="27">South Africa (+27)</option>
+<option value="34">Spain (+34)</option>
+<option value="94">Sri Lanka (+94)</option>
+<option value="290">St. Helena (+290)</option>
+<option value="1">St. Kitts And Nevis (+1)</option>
+<option value="1">St. Lucia (+1)</option>
+<option value="599">St. Maarten (+599)</option>
+<option value="508">St. Pierre And Miquelon (+508)</option>
+<option value="1">St. Vincent And The Grenadines (+1)</option>
+<option value="249">Sudan (+249)</option>
+<option value="597">Suriname (+597)</option>
+<option value="268">Swaziland (+268)</option>
+<option value="46">Sweden (+46)</option>
+<option value="41">Switzerland (+41)</option>
+<option value="963">Syrian Arab Republic (+963)</option>
+<option value="886">Taiwan, R.O.C. (+886)</option>
+<option value="992">Tajikistan (+992)</option>
+<option value="66">Thailand (+66)</option>
+<option value="228">Togo (+228)</option>
+<option value="690">Tokelau (+690)</option>
+<option value="676">Tonga (+676)</option>
+<option value="1">Trinidad And Tobago (+1)</option>
+<option value="216">Tunisia (+216)</option>
+<option value="90">Turkey (+90)</option>
+<option value="993">Turkmenistan (+993)</option>
+<option value="1">Turks And Caicos Islands (+1)</option>
+<option value="688">Tuvalu (+688)</option>
+<option value="1">U.S. Minor Outlying Islands (+1)</option>
+<option value="1">U.S. Virgin Islands (+1)</option>
+<option value="256">Uganda (+256)</option>
+<option value="380">Ukraine (+380)</option>
+<option value="971">United Arab Emirates (+971)</option>
+<option value="44">United Kingdom (+44)</option>
+<option value="255">United Republic Of Tanzania (+255)</option>
+<option value="1">United States (+1)</option>
+<option value="598">Uruguay (+598)</option>
+<option value="998">Uzbekistan (+998)</option>
+<option value="678">Vanuatu (+678)</option>
+<option value="58">Venezuela (+58)</option>
+<option value="84">Viet Nam (+84)</option>
+<option value="681">Wallis And Futuna (+681)</option>
+<option value="212">Western Sahara (+212)</option>
+<option value="967">Yemen (+967)</option>
+<option value="260">Zambia (+260)</option>
+<option value="263">Zimbabwe (+263)</option>
+</select>
+            <!-- mp_trans_disable_end -->
+        </div>
+        <div >
+        </div>
+        
+        <div id="PhoneNumberLabel"><label for="CreditCardInformation_BillingPhoneNumberEntry_Number">Phone (with area code)</label><span >*</span></div>
+        <div id="PhoneNumber">
+            <!-- mp_trans_disable_start -->
+            <input id="CreditCardInformation_BillingPhoneNumberEntry_Number" maxlength="15" name="CreditCardInformation.BillingPhoneNumberEntry.Number" size="25" type="text" value="">
+            <!-- mp_trans_disable_end -->
+        </div>
+        <div >
+        </div>
+    </div>
+<input id="CreditCardInformation_ShowBillingPhoneNumberEntry" name="CreditCardInformation.ShowBillingPhoneNumberEntry" type="hidden" value="True">
+<input id="CreditCardInformation_ShowBillingPhoneNumbers" name="CreditCardInformation.ShowBillingPhoneNumbers" type="hidden" value="False">
+<div >
+</div>
+<input id="CreditCardInformation_IsRequiredForHold" name="CreditCardInformation.IsRequiredForHold" type="hidden" value="False">
+<div id="SecurityCodeTip" style="display: none; height: 440px;">
+</div>
+</div>
+
+                        </div>
+                        <!--TipBox-->
+                        <div style="float: left;">
+                            
+                        </div>
+                    </div>
+                    <hr >
+                    
+                    <div >
+                    </div>
+
+                    
+                    <div >
+                    </div>
+                    
+	<div id="BOAFCOFFERPAYMENT" >
+		<div >
+			<div style="position: absolute;">
+				<div >
+					<div >$152.20</div>
+				</div>
+				<div >
+					<div >-$100.00</div>
+				</div>
+				<div >
+					<div >$52.20</div>
+				</div>
+			</div>
+		</div>
+		<div >
+		</div>
+		<hr style="margin: 1.45em 0; display: inline-block;" >
+	</div>
+
+                        <div  style="display:none;">
+
+<div id="TripInsurance" >
+    <div id="TripInsurance_Header" >
+        <h2 style="margin:0; padding-top:4px; padding-bottom:10px;">Highly Recommended: Trip Protection by Allianz Global Assistance</h2></div>
+    <div >
+    </div>
+    <div>
+        <div id="TripInsurance_Intro">
+            <strong>Peace of mind is only a click away</strong><br><br></div>
+        <div style="padding-bottom: 10px; margin: 0px 10px 10px 0px;">
+            <div id="TripInsurance_Body">
+                <ul  style="margin-top:0;"><li>Reimburses non-refundable, prepaid expenses up to the cost of your ticket(s) if you cancel your trip</li><li>Covers emergency medical / dental and emergency medical transportation while traveling</li><li>Helps with trip interruption, lost or damaged baggage, baggage delay, and additional travel delay costs </li></ul>Terms, conditions and exclusions apply, <a id="WASCInsuranceOfferBODYHref0" href="https://gateway.americas.allianz-assistance.com/TC/ALA/TP_6.html" target="_blank" onclick="window.open(&#39;https://gateway.americas.allianz-assistance.com/TC/ALA/TP_6.html&#39;,&#39;OPTION&#39;, &#39;width=580,height=550,resizable=yes,menubar=no,status=no,scrollbars=yes,toolbar=no,directories=no,location=no&#39;); return false;">learn more.</a></div>
+        </div>
+        <div >
+            
+            
+            <div >
+                <input type="radio" id="TripInsurance_QuoteID657566350481481886" name="TripInsurance.QuoteID" value="657566350481481886" onclick="SetTripInsurancePrice(21.0)">
+                <label for="TripInsurance_QuoteID657566350481481886" title="Yes, add trip protection for a total of $21.00. ">
+                    <strong>Yes,</strong> add trip protection for a total of <strong>$21.00</strong>. </label>
+            </div>
+            
+            <div >
+                <input type="radio" id="TripInsurance_QuoteID657566350481481887" name="TripInsurance.QuoteID" value="657566350481481887" onclick="SetTripInsurancePrice(0.00)">
+                <label for="TripInsurance_QuoteID657566350481481887" title="No, I choose not to protect my purchase.">
+                    No, I choose not to protect my purchase.</label>
+            </div>
+            
+        </div>
+        
+        <div id="TripInsurance_Disclaimer" style="clear: both; margin: 15px 10px 0px 0px;">
+            <div >You will see a separate charge for Allianz Travel Insurance on your credit card. Commercial accounts, UATP cards, gift cards, certificates and My Wallet funds are not valid forms of payment.</div></div>
+        
+        <div id="TripInsurance_Footer" style="clear: both; margin-top: 15px;">
+            "It's wise to always consider a travel protection plan to cover your trip costs from the unexpected." – <em>Frommer's, Feb 2014</em><br><br>Product available to residents of all states except: WA. <br>Plans underwritten by Jefferson Insurance Company or BCS Insurance Company. </div>
+        
+    </div>
+</div>
+
+<input id="templateType" name="templateType" type="hidden" value="PFC">
+<input id="TripInsurance_Page" name="TripInsurance.Page" type="hidden" value="BookingInfo">
+<input id="TripInsurance_TripInsuranceAmount" name="TripInsurance.TripInsuranceAmount" type="hidden" value="0">
+<input id="TripInsurance_ZeroValueQuoteID" name="TripInsurance.ZeroValueQuoteID" type="hidden" value="657566350481481887">
+
+                            <div ></div>
+                            <hr id="hrLine" >
+                            
+                        </div>
+                        
+                            <div id="tripInsuranceCreditCardSection"  style="display: none;">
+                            
+                                <div ></div>
+							
+                                
+<div ></div>
+<div >
+    Commercial accounts, UATP cards, gift cards, certificates and My Wallet funds are not valid forms of payment for trip protection. Please select an additional credit card or call Allianz Travel Insurance directly at 800-496-6593. 
+</div>
+<!--Show Booking Engine Credit Card Error here-->
+<!--Non Ticket Credit Card Error-->
+<!--CreditCardRequiredText-->
+
+
+<div ></div>
+<div id="Ancillary_NotSignedIn_CreditCard">
+    
+        <div id="BILLINGCREDITCARDENTRY"  style="float:left;">
+            <!--Billing Credit Card Error-->
+            <!--  For error messages that need to bubble from within the validation method, instead of for a specific form element -- example -- credit card doesn't validate--->
+            
+            <!--Card Types-->
+            
+            <div id="CardTypesSelected">
+			    <div id="CardTypesSelectedLabel" >Card Type</div>
+			    <div>				  
+				    <input id="AncillaryCreditCardInformation_BillingCreditCardEntry_CardTypes_Selected" name="AncillaryCreditCardInformation.BillingCreditCardEntry.CardTypes_Selected" type="hidden" value="CreditCard">
+                    <label>
+			    </div>			
+            </div>
+            <div ></div>
+            <!--Card Number-->
+            
+            <div id="CardNumberLabel"><label for="AncillaryCreditCardInformation_BillingCreditCardEntry_CardNumber">Card Number</label><span >*</span></div>
+            <div id="CardNumber">
+                <!-- mp_trans_disable_start -->
+<input autocomplete="off" id="AncillaryCreditCardInformation_BillingCreditCardEntry_CardNumber" maxlength="24" name="AncillaryCreditCardInformation.BillingCreditCardEntry.CardNumber" type="text" value="">                <!-- mp_trans_disable_end -->
+            </div>
+            <div ></div>
+            <!--Generic Expiration Date Errors-->
+            
+            
+            <div>Expiration<span >*</span></div>
+            <div id="ExpirationMonths" style="float: left; padding-right: 10px;">
+                <!-- mp_trans_disable_start -->
+                <select id="AncillaryCreditCardInformation_BillingCreditCardEntry_ExpirationMonths_Selected" name="AncillaryCreditCardInformation.BillingCreditCardEntry.ExpirationMonths_Selected" style="width:65px;"><option value="">Month</option>
+<option value="1">1</option>
+<option value="2">2</option>
+<option value="3">3</option>
+<option value="4">4</option>
+<option value="5">5</option>
+<option value="6">6</option>
+<option value="7">7</option>
+<option value="8">8</option>
+<option value="9">9</option>
+<option value="10">10</option>
+<option value="11">11</option>
+<option value="12">12</option>
+<option value="None">None</option>
+</select>
+                <!-- mp_trans_disable_end -->
+            </div>
+            <div id="ExpirationYears" style="float: left;">
+                <!-- mp_trans_disable_start -->
+                <select id="AncillaryCreditCardInformation_BillingCreditCardEntry_ExpirationYears_Selected" name="AncillaryCreditCardInformation.BillingCreditCardEntry.ExpirationYears_Selected" style="width:65px;"><option value="">Year</option>
+<option value="2014">2014</option>
+<option value="2015">2015</option>
+<option value="2016">2016</option>
+<option value="2017">2017</option>
+<option value="2018">2018</option>
+<option value="2019">2019</option>
+<option value="2020">2020</option>
+<option value="2021">2021</option>
+<option value="2022">2022</option>
+<option value="2023">2023</option>
+<option value="2024">2024</option>
+<option value="None">None</option>
+</select>
+                <!-- mp_trans_disable_end -->
+            </div>
+            <div ></div>
+            <!--Name on Card-->
+            
+            <div id="CardPersonNameLabel"><label for="AncillaryCreditCardInformation_BillingCreditCardEntry_CardPersonName">Name on Card</label><span >*</span></div>
+            <div id="CardPersonName">
+                <!-- mp_trans_disable_start -->
+                <input id="AncillaryCreditCardInformation_BillingCreditCardEntry_CardPersonName" maxlength="38" name="AncillaryCreditCardInformation.BillingCreditCardEntry.CardPersonName" size="41" type="text" value="">
+                <!-- mp_trans_disable_end -->
+            </div>
+        </div> 
+
+        <div >
+            <div >
+                <div style="float: left">
+                    <h5 >Billing Address</h5>
+                </div>    
+                <div ></div>
+                <div >
+                    <!--Countries-->
+                    
+                    <div id="CountriesLabel"><label for="AncillaryCreditCardInformation_BillingAddressEntry_Countries_Selected">Country</label><span >*</span></div>
+                    <div id="Countries">
+                        <!-- mp_trans_disable_start -->
+                        <select  id="AncillaryCreditCardInformation_BillingAddressEntry_Countries_Selected" name="AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected"><option value="US">United States</option>
+<option value="CA">Canada</option>
+<option value="MX">Mexico</option>
+<option value="AF">Afghanistan</option>
+<option value="AL">Albania</option>
+<option value="DZ">Algeria</option>
+<option value="AS">American Samoa</option>
+<option value="AD">Andorra</option>
+<option value="AO">Angola</option>
+<option value="AI">Anguilla</option>
+<option value="AQ">Antarctica</option>
+<option value="AG">Antigua And Barbuda</option>
+<option value="AR">Argentina</option>
+<option value="AM">Armenia</option>
+<option value="AW">Aruba</option>
+<option value="AU">Australia</option>
+<option value="AT">Austria</option>
+<option value="AZ">Azerbaijan</option>
+<option value="BS">Bahamas</option>
+<option value="BH">Bahrain</option>
+<option value="BD">Bangladesh</option>
+<option value="BB">Barbados</option>
+<option value="BY">Belarus</option>
+<option value="BE">Belgium</option>
+<option value="BZ">Belize</option>
+<option value="BJ">Benin</option>
+<option value="BM">Bermuda</option>
+<option value="BT">Bhutan</option>
+<option value="BO">Bolivia</option>
+<option value="BQ">Bonaire, Saint Eustatius and Saba</option>
+<option value="BA">Bosnia And Herzegovina</option>
+<option value="BW">Botswana</option>
+<option value="BR">Brazil</option>
+<option value="IO">British Indian Ocean Territory</option>
+<option value="VG">British Virgin Islands</option>
+<option value="BN">Brunei Darussalam</option>
+<option value="BG">Bulgaria</option>
+<option value="BF">Burkina Faso</option>
+<option value="BI">Burundi</option>
+<option value="KH">Cambodia</option>
+<option value="CM">Cameroon</option>
+<option value="CA">Canada</option>
+<option value="CV">Cape Verde</option>
+<option value="KY">Cayman Islands</option>
+<option value="CF">Central African Republic</option>
+<option value="TD">Chad</option>
+<option value="CL">Chile</option>
+<option value="CN">China</option>
+<option value="CX">Christmas Island</option>
+<option value="CC">Cocos (Keeling) Islands</option>
+<option value="CO">Colombia</option>
+<option value="KM">Comoros</option>
+<option value="CG">Congo</option>
+<option value="CD">Congo (DRC)</option>
+<option value="CK">Cook Islands</option>
+<option value="CR">Costa Rica</option>
+<option value="CI">Cote D`ivoire</option>
+<option value="HR">Croatia</option>
+<option value="CU">Cuba</option>
+<option value="CW">Curacao</option>
+<option value="CY">Cyprus</option>
+<option value="CZ">Czech Republic</option>
+<option value="DK">Denmark</option>
+<option value="DJ">Djibouti</option>
+<option value="DM">Dominica</option>
+<option value="DO">Dominican Republic</option>
+<option value="TP">East Timor</option>
+<option value="EC">Ecuador</option>
+<option value="EG">Egypt</option>
+<option value="SV">El Salvador</option>
+<option value="GQ">Equatorial Guinea</option>
+<option value="ER">Eritrea</option>
+<option value="EE">Estonia</option>
+<option value="ET">Ethiopia</option>
+<option value="FK">Falkland Islands (Malvinas)</option>
+<option value="FO">Faroe Islands</option>
+<option value="FJ">Fiji</option>
+<option value="FI">Finland</option>
+<option value="FR">France</option>
+<option value="GF">French Guiana</option>
+<option value="PF">French Polynesia</option>
+<option value="GA">Gabon</option>
+<option value="GM">Gambia</option>
+<option value="GE">Georgia</option>
+<option value="DE">Germany</option>
+<option value="GH">Ghana</option>
+<option value="GI">Gibraltar</option>
+<option value="GR">Greece</option>
+<option value="GL">Greenland</option>
+<option value="GD">Grenada</option>
+<option value="GP">Guadeloupe</option>
+<option value="GU">Guam</option>
+<option value="GT">Guatemala</option>
+<option value="GN">Guinea</option>
+<option value="GW">Guinea-Bissau</option>
+<option value="GY">Guyana</option>
+<option value="HT">Haiti</option>
+<option value="VA">Holy See (Vatican City State)</option>
+<option value="HN">Honduras</option>
+<option value="HK">Hong Kong</option>
+<option value="HU">Hungary</option>
+<option value="IS">Iceland</option>
+<option value="IN">India</option>
+<option value="ID">Indonesia</option>
+<option value="IQ">Iraq</option>
+<option value="IE">Ireland</option>
+<option value="IR">Islamic Republic Of Iran</option>
+<option value="IL">Israel</option>
+<option value="IT">Italy</option>
+<option value="JM">Jamaica</option>
+<option value="JP">Japan</option>
+<option value="JO">Jordan</option>
+<option value="KZ">Kazakhstan</option>
+<option value="KE">Kenya</option>
+<option value="KI">Kiribati</option>
+<option value="KP">Korea (DPRK)</option>
+<option value="KR">Korea (ROK)</option>
+<option value="CS">Kosovo</option>
+<option value="KW">Kuwait</option>
+<option value="KG">Kyrgyzstan</option>
+<option value="LA">Laos</option>
+<option value="LV">Latvia</option>
+<option value="LB">Lebanon</option>
+<option value="LS">Lesotho</option>
+<option value="LR">Liberia</option>
+<option value="LY">Libya</option>
+<option value="LI">Liechtenstein</option>
+<option value="LT">Lithuania</option>
+<option value="LU">Luxembourg</option>
+<option value="MO">Macao</option>
+<option value="MK">Macedonia</option>
+<option value="MG">Madagascar</option>
+<option value="MW">Malawi</option>
+<option value="MY">Malaysia</option>
+<option value="MV">Maldives</option>
+<option value="ML">Mali</option>
+<option value="MT">Malta</option>
+<option value="MH">Marshall Islands</option>
+<option value="MQ">Martinique</option>
+<option value="MR">Mauritania</option>
+<option value="MU">Mauritius</option>
+<option value="YT">Mayotte</option>
+<option value="MX">Mexico</option>
+<option value="FM">Micronesia</option>
+<option value="MD">Moldova, Republic Of</option>
+<option value="MC">Monaco</option>
+<option value="MN">Mongolia</option>
+<option value="ME">Montenegro</option>
+<option value="MS">Montserrat</option>
+<option value="MA">Morocco</option>
+<option value="MZ">Mozambique</option>
+<option value="MM">Myanmar</option>
+<option value="NA">Namibia</option>
+<option value="NR">Nauru</option>
+<option value="NP">Nepal</option>
+<option value="NL">Netherlands</option>
+<option value="NC">New Caledonia</option>
+<option value="NZ">New Zealand</option>
+<option value="NI">Nicaragua</option>
+<option value="NE">Niger</option>
+<option value="NG">Nigeria</option>
+<option value="NU">Niue</option>
+<option value="NF">Norfolk Island</option>
+<option value="MP">Northern Mariana Islands</option>
+<option value="NO">Norway</option>
+<option value="OM">Oman</option>
+<option value="PK">Pakistan</option>
+<option value="PW">Palau</option>
+<option value="PA">Panama</option>
+<option value="PG">Papua New Guinea</option>
+<option value="PY">Paraguay</option>
+<option value="PE">Peru</option>
+<option value="PH">Philippines</option>
+<option value="PN">Pitcairn</option>
+<option value="PL">Poland</option>
+<option value="PT">Portugal</option>
+<option value="PR">Puerto Rico</option>
+<option value="QA">Qatar</option>
+<option value="RE">Reunion</option>
+<option value="RO">Romania</option>
+<option value="RU">Russian Federation</option>
+<option value="RW">Rwanda</option>
+<option value="WS">Samoa</option>
+<option value="SM">San Marino</option>
+<option value="ST">Sao Tome And Principe</option>
+<option value="SA">Saudi Arabia</option>
+<option value="SN">Senegal</option>
+<option value="RS">Serbia</option>
+<option value="SC">Seychelles</option>
+<option value="SL">Sierra Leone</option>
+<option value="SG">Singapore</option>
+<option value="SK">Slovakia</option>
+<option value="SI">Slovenia</option>
+<option value="SB">Solomon Islands</option>
+<option value="SO">Somalia</option>
+<option value="ZA">South Africa</option>
+<option value="ES">Spain</option>
+<option value="LK">Sri Lanka</option>
+<option value="SH">St. Helena</option>
+<option value="KN">St. Kitts And Nevis</option>
+<option value="LC">St. Lucia</option>
+<option value="SX">St. Maarten</option>
+<option value="PM">St. Pierre And Miquelon</option>
+<option value="VC">St. Vincent And The Grenadines</option>
+<option value="SD">Sudan</option>
+<option value="SR">Suriname</option>
+<option value="SZ">Swaziland</option>
+<option value="SE">Sweden</option>
+<option value="CH">Switzerland</option>
+<option value="SY">Syrian Arab Republic</option>
+<option value="TW">Taiwan, R.O.C.</option>
+<option value="TJ">Tajikistan</option>
+<option value="TH">Thailand</option>
+<option value="TG">Togo</option>
+<option value="TK">Tokelau</option>
+<option value="TO">Tonga</option>
+<option value="TT">Trinidad And Tobago</option>
+<option value="TN">Tunisia</option>
+<option value="TR">Turkey</option>
+<option value="TM">Turkmenistan</option>
+<option value="TC">Turks And Caicos Islands</option>
+<option value="TV">Tuvalu</option>
+<option value="UM">U.S. Minor Outlying Islands</option>
+<option value="VI">U.S. Virgin Islands</option>
+<option value="UG">Uganda</option>
+<option value="UA">Ukraine</option>
+<option value="AE">United Arab Emirates</option>
+<option value="GB">United Kingdom</option>
+<option value="TZ">United Republic Of Tanzania</option>
+<option value="US">United States</option>
+<option value="UY">Uruguay</option>
+<option value="UZ">Uzbekistan</option>
+<option value="VU">Vanuatu</option>
+<option value="VE">Venezuela</option>
+<option value="VN">Viet Nam</option>
+<option value="WF">Wallis And Futuna</option>
+<option value="EH">Western Sahara</option>
+<option value="YE">Yemen</option>
+<option value="ZM">Zambia</option>
+<option value="ZW">Zimbabwe</option>
+</select>
+                        <!-- mp_trans_disable_end -->
+                    </div>
+                    <div ></div>
+                    
+                    <div id="Address1Label"><label for="AncillaryCreditCardInformation_BillingAddressEntry_Address1">Address</label><span >*</span></div>
+                    <div id="Address1" style="margin-bottom: 5px;">
+                        <!-- mp_trans_disable_start -->
+                        <input id="AncillaryCreditCardInformation_BillingAddressEntry_Address1" maxlength="29" name="AncillaryCreditCardInformation.BillingAddressEntry.Address1" size="27" type="text" value="">
+                        <!-- mp_trans_disable_end -->
+                    </div>
+                    
+                    <div id="Address2Label">
+                        <span ><label for="AncillaryCreditCardInformation_BillingAddressEntry_Address2">Address Line 2</label></span>
+                    </div>
+                    <div id="Address2">
+                        <!-- mp_trans_disable_start -->
+                        <input id="AncillaryCreditCardInformation_BillingAddressEntry_Address2" maxlength="29" name="AncillaryCreditCardInformation.BillingAddressEntry.Address2" size="27" type="text" value="">
+                        <!-- mp_trans_disable_end -->
+                    </div>
+                </div>      
+                <div >
+                    <!--City-->
+                    
+                    <div id="CityLabel"><label for="AncillaryCreditCardInformation_BillingAddressEntry_City">City</label><span >*</span></div>
+                    <div id="City">
+                        <!-- mp_trans_disable_start -->
+                        <input id="AncillaryCreditCardInformation_BillingAddressEntry_City" maxlength="28" name="AncillaryCreditCardInformation.BillingAddressEntry.City" size="27" type="text" value="">
+                        <!-- mp_trans_disable_end -->
+                    </div> 
+                    <div ></div>     
+                    <div id="ANCILLARY_USSTATES" style="display: block;">
+                        
+                        <div><label for="AncillaryCreditCardInformation_BillingAddressEntry_USStates_Selected">State/Province</label><span >*</span></div>
+                        <div>
+                            <!-- mp_trans_disable_start -->
+                            <select  id="AncillaryCreditCardInformation_BillingAddressEntry_USStates_Selected" name="AncillaryCreditCardInformation.BillingAddressEntry.USStates_Selected"><option value="">Select</option>
+<option value="AL">Alabama</option>
+<option value="AK">Alaska</option>
+<option value="AZ">Arizona</option>
+<option value="AR">Arkansas</option>
+<option value="CA">California</option>
+<option value="CO">Colorado</option>
+<option value="CT">Connecticut</option>
+<option value="DE">Delaware</option>
+<option value="FL">Florida</option>
+<option value="GA">Georgia</option>
+<option value="HI">Hawaii</option>
+<option value="ID">Idaho</option>
+<option value="IL">Illinois</option>
+<option value="IN">Indiana</option>
+<option value="IA">Iowa</option>
+<option value="KS">Kansas</option>
+<option value="KY">Kentucky</option>
+<option value="LA">Louisiana</option>
+<option value="ME">Maine</option>
+<option value="MD">Maryland</option>
+<option value="MA">Massachusetts</option>
+<option value="MI">Michigan</option>
+<option value="MN">Minnesota</option>
+<option value="MS">Mississippi</option>
+<option value="MO">Missouri</option>
+<option value="MT">Montana</option>
+<option value="NE">Nebraska</option>
+<option value="NV">Nevada</option>
+<option value="NH">New Hampshire</option>
+<option value="NJ">New Jersey</option>
+<option value="NM">New Mexico</option>
+<option value="NY">New York</option>
+<option value="NC">North Carolina</option>
+<option value="ND">North Dakota</option>
+<option value="OH">Ohio</option>
+<option value="OK">Oklahoma</option>
+<option value="OR">Oregon</option>
+<option value="PA">Pennsylvania</option>
+<option value="RI">Rhode Island</option>
+<option value="SC">South Carolina</option>
+<option value="SD">South Dakota</option>
+<option value="TN">Tennessee</option>
+<option value="TX">Texas</option>
+<option value="UT">Utah</option>
+<option value="VT">Vermont</option>
+<option value="VA">Virginia</option>
+<option value="WA">Washington</option>
+<option value="WV">West Virginia</option>
+<option value="WI">Wisconsin</option>
+<option value="WY">Wyoming</option>
+<option value=" ">------------------------------------</option>
+<option value="AS">American Samoa</option>
+<option value="DC">District Of Columbia</option>
+<option value="FM">Federated States Of Micronesia</option>
+<option value="GU">Guam</option>
+<option value="MH">Marshall Islands</option>
+<option value="MP">Northern Mariana Islands</option>
+<option value="PW">Palau</option>
+<option value="PR">Puerto Rico</option>
+<option value="VI">Virgin Islands</option>
+<option value=" ">------------------------------------</option>
+<option value="AA">AA - Armed Forces America</option>
+<option value="AE">AE - Armed Forces Europe</option>
+<option value="AP">AP - Armed Forces Pacific</option>
+</select>
+                            <!-- mp_trans_disable_end -->
+                        </div>
+                    </div>
+                    <div id="ANCILLARY_CASTATES" style="display: none;">
+                        
+                        <div><label for="AncillaryCreditCardInformation_BillingAddressEntry_CAStates_Selected">State/Province</label><span >*</span></div>
+                        <div>
+                            <!-- mp_trans_disable_start -->
+                            <select  id="AncillaryCreditCardInformation_BillingAddressEntry_CAStates_Selected" name="AncillaryCreditCardInformation.BillingAddressEntry.CAStates_Selected"><option value="">Select</option>
+<option value="AB">Alberta</option>
+<option value="BC">British Columbia</option>
+<option value="MB">Manitoba</option>
+<option value="NB">New Brunswick</option>
+<option value="NF">Newfoundland</option>
+<option value="NT">Northwest Territories</option>
+<option value="NS">Nova Scotia</option>
+<option value="NU">Nunavut</option>
+<option value="ON">Ontario</option>
+<option value="PE">Prince Edward Island</option>
+<option value="QC">Quebec</option>
+<option value="SK">Saskatchewan</option>
+<option value="YT">Yukon Territory</option>
+</select>
+                            <!-- mp_trans_disable_end -->
+                        </div>
+                    </div>
+                    <div id="ANCILLARY_MXSTATES" style="display: none;">
+                        
+                        <div><label for="AncillaryCreditCardInformation_BillingAddressEntry_MXStates_Selected">State/Province</label><span >*</span></div>
+                        <div>
+                            <!-- mp_trans_disable_start -->
+                            <select  id="AncillaryCreditCardInformation_BillingAddressEntry_MXStates_Selected" name="AncillaryCreditCardInformation.BillingAddressEntry.MXStates_Selected"><option value="">Select</option>
+<option value="AGS">Aguascalientes</option>
+<option value="BCN">Baja California</option>
+<option value="BCS">Baja California Sur</option>
+<option value="CAM">Campeche</option>
+<option value="CHIS">Chiapas</option>
+<option value="CHIH">Chihuahua</option>
+<option value="COAH">Coahuila</option>
+<option value="COL">Colima</option>
+<option value="DF">Distrito Federal</option>
+<option value="DGO">Durango</option>
+<option value="GTO">Guanajuato</option>
+<option value="GRO">Guerrero</option>
+<option value="HGO">Hidalgo</option>
+<option value="JAL">Jalisco</option>
+<option value="MEX">Mexico</option>
+<option value="MICH">Michoacan</option>
+<option value="MOR">Morelos</option>
+<option value="NAY">Nayarit</option>
+<option value="NL">Nuevo Leon</option>
+<option value="OAX">Oaxaca</option>
+<option value="PUE">Puebla</option>
+<option value="QRO">Queretaro</option>
+<option value="QROO">Quintana Roo</option>
+<option value="SLP">San Luis Potosi</option>
+<option value="SIN">Sinaloa</option>
+<option value="SON">Sonora</option>
+<option value="TAB">Tabasco</option>
+<option value="TAMPS">Tamaulipas</option>
+<option value="TLAX">Tlaxcala</option>
+<option value="VER">Veracruz</option>
+<option value="YUC">Yucatan</option>
+<option value="ZAC">Zacatecas</option>
+</select>
+                            <!-- mp_trans_disable_end -->
+                        </div>
+                    </div>
+                    <div id="ANCILLARY_OTHERSTATES" style="display: none;">
+                        
+                        <div><label for="AncillaryCreditCardInformation_BillingAddressEntry_OtherStates_Selected">State/Province</label><span >*</span></div>
+                        <div>
+                            <!-- mp_trans_disable_start -->
+                            <input  id="AncillaryCreditCardInformation_BillingAddressEntry_OtherStates_Selected" name="AncillaryCreditCardInformation.BillingAddressEntry.OtherStates_Selected" type="text" value="">
+                            <!-- mp_trans_disable_end -->
+                        </div>
+                    </div>
+                    <div ></div>
+                    <div id="POSTALCODE">
+                        
+                        <div><label for="AncillaryCreditCardInformation_BillingAddressEntry_PostalCode">Zip/Postal Code</label><span >*</span></div>
+                        <div>
+                            <!-- mp_trans_disable_start -->
+                            <input id="AncillaryCreditCardInformation_BillingAddressEntry_PostalCode" maxlength="10" name="AncillaryCreditCardInformation.BillingAddressEntry.PostalCode" type="text" value="">
+                            <!-- mp_trans_disable_end -->
+                        </div>                     
+                    </div>                    
+                </div>
+                <div ></div>
+                <div >
+                    <div style="clear:left;float: left">
+                        <h5 >Card Holder Phone Number</h5>
+                    </div>
+                    <!--Country Code-->
+                    
+                    <div id="CountryCodeLabel"><label for="AncillaryCreditCardInformation_BillingPhoneNumberEntry_CountryCode_Selected">Country Code</label><span >*</span></div>
+                    <div id="CountryCode">
+                        <!-- mp_trans_disable_start -->
+                        <select  id="AncillaryCreditCardInformation_BillingPhoneNumberEntry_CountryCode_Selected" name="AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected"><option value="1">United States/Canada (+1)</option>
+<option value="52">Mexico (+52)</option>
+<option value="93">Afghanistan (+93)</option>
+<option value="355">Albania (+355)</option>
+<option value="213">Algeria (+213)</option>
+<option value="1">American Samoa (+1)</option>
+<option value="376">Andorra (+376)</option>
+<option value="244">Angola (+244)</option>
+<option value="1">Anguilla (+1)</option>
+<option value="672">Antarctica (+672)</option>
+<option value="1">Antigua And Barbuda (+1)</option>
+<option value="54">Argentina (+54)</option>
+<option value="374">Armenia (+374)</option>
+<option value="297">Aruba (+297)</option>
+<option value="61">Australia (+61)</option>
+<option value="43">Austria (+43)</option>
+<option value="994">Azerbaijan (+994)</option>
+<option value="1">Bahamas (+1)</option>
+<option value="973">Bahrain (+973)</option>
+<option value="880">Bangladesh (+880)</option>
+<option value="1">Barbados (+1)</option>
+<option value="375">Belarus (+375)</option>
+<option value="32">Belgium (+32)</option>
+<option value="501">Belize (+501)</option>
+<option value="229">Benin (+229)</option>
+<option value="1">Bermuda (+1)</option>
+<option value="975">Bhutan (+975)</option>
+<option value="591">Bolivia (+591)</option>
+<option value="599">Bonaire, Saint Eustatius and Saba (+599)</option>
+<option value="387">Bosnia And Herzegovina (+387)</option>
+<option value="267">Botswana (+267)</option>
+<option value="55">Brazil (+55)</option>
+<option value="1">British Indian Ocean Territory (+1)</option>
+<option value="1">British Virgin Islands (+1)</option>
+<option value="673">Brunei Darussalam (+673)</option>
+<option value="359">Bulgaria (+359)</option>
+<option value="226">Burkina Faso (+226)</option>
+<option value="257">Burundi (+257)</option>
+<option value="855">Cambodia (+855)</option>
+<option value="237">Cameroon (+237)</option>
+<option value="1">Canada (+1)</option>
+<option value="238">Cape Verde (+238)</option>
+<option value="1">Cayman Islands (+1)</option>
+<option value="236">Central African Republic (+236)</option>
+<option value="235">Chad (+235)</option>
+<option value="56">Chile (+56)</option>
+<option value="86">China (+86)</option>
+<option value="61">Christmas Island (+61)</option>
+<option value="61">Cocos (Keeling) Islands (+61)</option>
+<option value="57">Colombia (+57)</option>
+<option value="269">Comoros (+269)</option>
+<option value="242">Congo (+242)</option>
+<option value="243">Congo (DRC) (+243)</option>
+<option value="682">Cook Islands (+682)</option>
+<option value="506">Costa Rica (+506)</option>
+<option value="225">Cote D`ivoire (+225)</option>
+<option value="385">Croatia (+385)</option>
+<option value="53">Cuba (+53)</option>
+<option value="599">Curacao (+599)</option>
+<option value="357">Cyprus (+357)</option>
+<option value="420">Czech Republic (+420)</option>
+<option value="45">Denmark (+45)</option>
+<option value="253">Djibouti (+253)</option>
+<option value="1">Dominica (+1)</option>
+<option value="1">Dominican Republic (+1)</option>
+<option value="670">East Timor (+670)</option>
+<option value="593">Ecuador (+593)</option>
+<option value="20">Egypt (+20)</option>
+<option value="503">El Salvador (+503)</option>
+<option value="240">Equatorial Guinea (+240)</option>
+<option value="291">Eritrea (+291)</option>
+<option value="372">Estonia (+372)</option>
+<option value="251">Ethiopia (+251)</option>
+<option value="500">Falkland Islands (Malvinas) (+500)</option>
+<option value="298">Faroe Islands (+298)</option>
+<option value="679">Fiji (+679)</option>
+<option value="358">Finland (+358)</option>
+<option value="33">France (+33)</option>
+<option value="594">French Guiana (+594)</option>
+<option value="689">French Polynesia (+689)</option>
+<option value="241">Gabon (+241)</option>
+<option value="220">Gambia (+220)</option>
+<option value="995">Georgia (+995)</option>
+<option value="49">Germany (+49)</option>
+<option value="233">Ghana (+233)</option>
+<option value="350">Gibraltar (+350)</option>
+<option value="30">Greece (+30)</option>
+<option value="299">Greenland (+299)</option>
+<option value="1">Grenada (+1)</option>
+<option value="590">Guadeloupe (+590)</option>
+<option value="1">Guam (+1)</option>
+<option value="502">Guatemala (+502)</option>
+<option value="224">Guinea (+224)</option>
+<option value="245">Guinea-Bissau (+245)</option>
+<option value="592">Guyana (+592)</option>
+<option value="509">Haiti (+509)</option>
+<option value="379">Holy See (Vatican City State) (+379)</option>
+<option value="504">Honduras (+504)</option>
+<option value="852">Hong Kong (+852)</option>
+<option value="36">Hungary (+36)</option>
+<option value="354">Iceland (+354)</option>
+<option value="91">India (+91)</option>
+<option value="62">Indonesia (+62)</option>
+<option value="964">Iraq (+964)</option>
+<option value="353">Ireland (+353)</option>
+<option value="98">Islamic Republic Of Iran (+98)</option>
+<option value="972">Israel (+972)</option>
+<option value="39">Italy (+39)</option>
+<option value="1">Jamaica (+1)</option>
+<option value="81">Japan (+81)</option>
+<option value="962">Jordan (+962)</option>
+<option value="7">Kazakhstan (+7)</option>
+<option value="254">Kenya (+254)</option>
+<option value="686">Kiribati (+686)</option>
+<option value="850">Korea (DPRK) (+850)</option>
+<option value="82">Korea (ROK) (+82)</option>
+<option value="381">Kosovo (+381)</option>
+<option value="965">Kuwait (+965)</option>
+<option value="996">Kyrgyzstan (+996)</option>
+<option value="856">Laos (+856)</option>
+<option value="371">Latvia (+371)</option>
+<option value="961">Lebanon (+961)</option>
+<option value="266">Lesotho (+266)</option>
+<option value="231">Liberia (+231)</option>
+<option value="218">Libya (+218)</option>
+<option value="423">Liechtenstein (+423)</option>
+<option value="370">Lithuania (+370)</option>
+<option value="352">Luxembourg (+352)</option>
+<option value="853">Macao (+853)</option>
+<option value="389">Macedonia (+389)</option>
+<option value="261">Madagascar (+261)</option>
+<option value="265">Malawi (+265)</option>
+<option value="60">Malaysia (+60)</option>
+<option value="960">Maldives (+960)</option>
+<option value="223">Mali (+223)</option>
+<option value="356">Malta (+356)</option>
+<option value="692">Marshall Islands (+692)</option>
+<option value="596">Martinique (+596)</option>
+<option value="222">Mauritania (+222)</option>
+<option value="230">Mauritius (+230)</option>
+<option value="262">Mayotte (+262)</option>
+<option value="52">Mexico (+52)</option>
+<option value="691">Micronesia (+691)</option>
+<option value="373">Moldova, Republic Of (+373)</option>
+<option value="377">Monaco (+377)</option>
+<option value="976">Mongolia (+976)</option>
+<option value="382">Montenegro (+382)</option>
+<option value="1">Montserrat (+1)</option>
+<option value="212">Morocco (+212)</option>
+<option value="258">Mozambique (+258)</option>
+<option value="95">Myanmar (+95)</option>
+<option value="264">Namibia (+264)</option>
+<option value="674">Nauru (+674)</option>
+<option value="977">Nepal (+977)</option>
+<option value="31">Netherlands (+31)</option>
+<option value="687">New Caledonia (+687)</option>
+<option value="64">New Zealand (+64)</option>
+<option value="505">Nicaragua (+505)</option>
+<option value="227">Niger (+227)</option>
+<option value="234">Nigeria (+234)</option>
+<option value="683">Niue (+683)</option>
+<option value="672">Norfolk Island (+672)</option>
+<option value="1">Northern Mariana Islands (+1)</option>
+<option value="47">Norway (+47)</option>
+<option value="968">Oman (+968)</option>
+<option value="92">Pakistan (+92)</option>
+<option value="680">Palau (+680)</option>
+<option value="507">Panama (+507)</option>
+<option value="675">Papua New Guinea (+675)</option>
+<option value="595">Paraguay (+595)</option>
+<option value="51">Peru (+51)</option>
+<option value="63">Philippines (+63)</option>
+<option value="872">Pitcairn (+872)</option>
+<option value="48">Poland (+48)</option>
+<option value="351">Portugal (+351)</option>
+<option value="1">Puerto Rico (+1)</option>
+<option value="974">Qatar (+974)</option>
+<option value="262">Reunion (+262)</option>
+<option value="40">Romania (+40)</option>
+<option value="7">Russian Federation (+7)</option>
+<option value="250">Rwanda (+250)</option>
+<option value="685">Samoa (+685)</option>
+<option value="378">San Marino (+378)</option>
+<option value="239">Sao Tome And Principe (+239)</option>
+<option value="966">Saudi Arabia (+966)</option>
+<option value="221">Senegal (+221)</option>
+<option value="381">Serbia (+381)</option>
+<option value="248">Seychelles (+248)</option>
+<option value="232">Sierra Leone (+232)</option>
+<option value="65">Singapore (+65)</option>
+<option value="421">Slovakia (+421)</option>
+<option value="386">Slovenia (+386)</option>
+<option value="677">Solomon Islands (+677)</option>
+<option value="252">Somalia (+252)</option>
+<option value="27">South Africa (+27)</option>
+<option value="34">Spain (+34)</option>
+<option value="94">Sri Lanka (+94)</option>
+<option value="290">St. Helena (+290)</option>
+<option value="1">St. Kitts And Nevis (+1)</option>
+<option value="1">St. Lucia (+1)</option>
+<option value="599">St. Maarten (+599)</option>
+<option value="508">St. Pierre And Miquelon (+508)</option>
+<option value="1">St. Vincent And The Grenadines (+1)</option>
+<option value="249">Sudan (+249)</option>
+<option value="597">Suriname (+597)</option>
+<option value="268">Swaziland (+268)</option>
+<option value="46">Sweden (+46)</option>
+<option value="41">Switzerland (+41)</option>
+<option value="963">Syrian Arab Republic (+963)</option>
+<option value="886">Taiwan, R.O.C. (+886)</option>
+<option value="992">Tajikistan (+992)</option>
+<option value="66">Thailand (+66)</option>
+<option value="228">Togo (+228)</option>
+<option value="690">Tokelau (+690)</option>
+<option value="676">Tonga (+676)</option>
+<option value="1">Trinidad And Tobago (+1)</option>
+<option value="216">Tunisia (+216)</option>
+<option value="90">Turkey (+90)</option>
+<option value="993">Turkmenistan (+993)</option>
+<option value="1">Turks And Caicos Islands (+1)</option>
+<option value="688">Tuvalu (+688)</option>
+<option value="1">U.S. Minor Outlying Islands (+1)</option>
+<option value="1">U.S. Virgin Islands (+1)</option>
+<option value="256">Uganda (+256)</option>
+<option value="380">Ukraine (+380)</option>
+<option value="971">United Arab Emirates (+971)</option>
+<option value="44">United Kingdom (+44)</option>
+<option value="255">United Republic Of Tanzania (+255)</option>
+<option value="1">United States (+1)</option>
+<option value="598">Uruguay (+598)</option>
+<option value="998">Uzbekistan (+998)</option>
+<option value="678">Vanuatu (+678)</option>
+<option value="58">Venezuela (+58)</option>
+<option value="84">Viet Nam (+84)</option>
+<option value="681">Wallis And Futuna (+681)</option>
+<option value="212">Western Sahara (+212)</option>
+<option value="967">Yemen (+967)</option>
+<option value="260">Zambia (+260)</option>
+<option value="263">Zimbabwe (+263)</option>
+</select>
+                        <!-- mp_trans_disable_end -->
+                    </div>     
+                </div>
+                <div >
+                    <div ></div>
+                    <div>
+                         
+                        <div id="PhoneNumberLabel"><label for="AncillaryCreditCardInformation_BillingPhoneNumberEntry_Number">Phone (with area code)</label><span >*</span></div>
+                        <div id="PhoneNumber">
+                            <!-- mp_trans_disable_start -->
+                            <input id="AncillaryCreditCardInformation_BillingPhoneNumberEntry_Number" maxlength="15" name="AncillaryCreditCardInformation.BillingPhoneNumberEntry.Number" size="25" type="text" value="">
+                            <!-- mp_trans_disable_end -->
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <input id="AncillaryCreditCardInformation_ShowBillingCreditCardEntry" name="AncillaryCreditCardInformation.ShowBillingCreditCardEntry" type="hidden" value="True">
+        <input id="AncillaryCreditCardInformation_ShowBillingCreditCards" name="AncillaryCreditCardInformation.ShowBillingCreditCards" type="hidden" value="False">
+        <input id="AncillaryCreditCardInformation_ShowBillingAddressEntry" name="AncillaryCreditCardInformation.ShowBillingAddressEntry" type="hidden" value="True">
+        <input id="AncillaryCreditCardInformation_ShowBillingAddresses" name="AncillaryCreditCardInformation.ShowBillingAddresses" type="hidden" value="False">
+        <input id="AncillaryCreditCardInformation_ShowBillingPhoneNumberEntry" name="AncillaryCreditCardInformation.ShowBillingPhoneNumberEntry" type="hidden" value="True">
+        <input id="AncillaryCreditCardInformation_ShowBillingPhoneNumbers" name="AncillaryCreditCardInformation.ShowBillingPhoneNumbers" type="hidden" value="False">
+        <input id="AncillaryCreditCardInformation_IsRequiredForHold" name="AncillaryCreditCardInformation.IsRequiredForHold" type="hidden" value="False">
+        <div ></div>
+
+        <div id="SecurityCodeTip" style="display: none; height: 440px;"></div>
+</div>
+
+                                
+							
+                                <hr >
+                            </div>
+                        
+
+                     <div >
+                    </div>
+                    <div id="RULESANDRESTRICTIONS">
+                        <h2>Rules and Restrictions</h2>
+                        
+		<strong>Flight</strong>
+		
+<div id="divRuleLightBox" style="display:none;overflow:auto;height:510px;"></div>
+<div id="fareRules">	
+	<div style="clear:left;">
+		<div style="padding-top:5px;padding-right:5px;">	
+		<ul>
+					
+				<li>This fare is <b>nonrefundable</b>.</li>				
+					
+				<li>Reservations require immediate purchase and may not be held.  Fares and availability are subject to change without notice until purchased.</li>				
+					
+				<li>If travel has not yet commenced, you may make one change to this itinerary <b>OR</b> cancel and refund to original form of payment with no fee within 24 hours of original purchase.</li>				
+					
+				<li>Changes to this itinerary are subject to additional fare and taxes. A fee of $125 USD per person will also be assessed. Change fees are waived for travel wholly within the State of Alaska on flights operated by Alaska Airlines and Horizon Air, and for all MVP® Gold members.</li>				
+					
+				<li><a href="javascript://Show All Rules" data-track-link="%7B%22section%22%3A%22rulesandrestrictions%22%2C%22linkName%22%3A%22viewallrarerules%22%7D" onclick="showAllRules($(this),&#39;7&#39;, &#39;Standard&#39;);return false;" title="View All Fare Rules" alt="View All Fare Rules">View all fare rules</a></li>				
+					
+		</ul>
+		</div>
+	</div>
+	
+	<div id="AllRulesContainer" style="display:none;">
+		<iframe id="AllRulesFrame" src="javascript:void(0);" width="560" height="210" frameborder="0"></iframe>
+		<a id="AllRulesUrl" style="display:none;" href="https://www.alaskaair.com/Shopping/SSL/FareRules.aspx?view=0"></a>
+	</div>	
+	<div id="DiscountCodeTermsContainer" style="display:none;">
+		<iframe id="DiscountCodeTermsFrame" src="javascript:false;" width="565" height="500" frameborder="0"></iframe>
+		<a id="DiscountCodeTermsUrl" style="display:none;" href="https://www.alaskaair.com/shared/tips/AboutDiscountCodes.aspx?view=0"></a>
+	</div>
+	<iframe id="ContractFareFrame" src="javascript:false;" width="720" height="520" frameborder="0" style="display:none;"></iframe>
+	<a id="ContractFareURL" style="display:none;" href="https://easybiz.alaskaair.com/ContractFareInfo?section=popup&lightbox=true"></a>
+	<a id="umnrRulesURL" style="display:none;" href="https://www.alaskaair.com/content/travel-info/policies/children-traveling-alone/children-alone-lightbox.aspx"></a>
+	<a id="standByRulesURL" style="display:none;" href="https://www.alaskaair.com/content/travel-info/at-the-airport/same-day-flight-changes/standby-rules/standby-rules-lightbox.aspx"></a>
+	
+	<div id="AllRulesLB" style="display:none;overflow:auto;">
+		<style type="text/css">ul.discs li {list-style-type:disc;}</style>
+		<h2 style="margin-bottom:0.83em;"></h2>
+		<ul >
+					
+		</ul>
+	</div>
+
+</div>
+
+
+		<strong>Baggage</strong>
+		<style type="text/css">
+	.baggageRules { padding-top:5px;padding-right:5px;width:880px; }
+</style>
+<div >
+	<ul>
+		<li><strong>Carry-on Baggage: </strong> For travel on our partner airlines, please check their rules.</li>
+		<li><strong>Checked Baggage: </strong>Alaska Airlines rules and fees apply for this itinerary. The first and second checked bag fees are $25 each. See www.alaskaair.com/bagrules for details and exceptions.</li>
+	</ul>
+</div>
+
+
+	<div id="divTripInsuranceRules"  style="display: none;">
+        <strong>Add-ons</strong>
+	    <ul>
+		    
+		    <li>Trip Protection Terms and Conditions apply.</li>
+		    
+	    </ul>
+    </div>
+	
+
+                    <!--TODO: there still needs to be work on getting the umnr light box to show data, I modeled it after views/cart/farerules.ascx but there still needs to be work done.  See Vinnie or Holly for help-->
+                    <input id="UMNRRules_ShowUMNRRules" name="UMNRRules.ShowUMNRRules" type="hidden" value="False">
+					<input id="UMNRRules_ShowMexicoMinorRules" name="UMNRRules.ShowMexicoMinorRules" type="hidden" value="False">
+
+                    </div>
+
+                    <div >
+                      <div id="SUBMITBUTTON" >
+                        <div  style="margin:8px;"><strong>By purchasing, I agree to the Rules and Restrictions and <a href="javascript://Show Terms of Use" onclick="showWebsiteTermsOfUse($(this));"><nobr>Website Terms of Use</nobr></a>.</strong></div>
+                        <div id="WebsiteTermsOfUse" style="display: none; height: 520px; width: 560px; overflow: auto;"></div>
+
+                            <input  type="submit" id="PurchaseButton" name="purchase" value="PURCHASE" title="PURCHASE">
+                        
+                      </div>
+                    </div>
+                    <div >
+                    </div>
+                    <div id="GIFTCARDORCERTIFICATEBUTTON" style="display: none;">
+                        <div style="margin-right: 0;" >
+                            Gift card or certificate funds will be applied to your purchase before a credit
+                            card is required.</div>
+                        <div id="GCButton" style="margin-right: 0;" >
+                            <input  type="submit" id="ContinueButton" name="continue" value="CONTINUE" title="CONTINUE">
+                        </div>
+                    </div>
+                    <div >
+                    </div>
+                    <div id="FORMNAME" >
+                        <!--mp_trans_disable_start-->
+                        <span >For customer service purposes </span>FormName:
+                        Payment<!-- mp_trans_disable_end --></div>
+                    <div >
+                    </div>
+                    <input style="display: none;" type="submit" id="Refresh" name="Action" value="Refresh">
+                    <input type="hidden" id="Buttons_ActiveButtonValue" name="Buttons.ActiveButtonValue" value="PURCHASE">
+                    <input type="hidden" id="ReturnFromStepout" name="ReturnFromStepout" value="False">
+                    <input type="hidden" id="ReturnFromStepoutId" name="ReturnFromStepoutId" value="">
+                    <input type="hidden" id="ReturnFromStepoutItem" name="ReturnFromStepoutItem" value="">
+                    <input type="hidden" id="ReturnFromStepoutType" name="ReturnFromStepoutType" value="">
+                                    
+                    <input type="hidden" id="PaymentType" name="PaymentType" value="creditcard">
+                    <input id="TripInsuranceVisibility" name="TripInsuranceVisibility" type="hidden" value="False">
+                    <input id="TripInsuranceCreditCardVisible" name="TripInsuranceCreditCardVisible" type="hidden" value="False">
+                     <input type="hidden" id="AcceptedCardsClassification" name="AcceptedCardsClassification">
+
+                    </form>
+
+</body></html>
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_de.out b/chrome/test/data/autofill/heuristics/output/00_i18n_de.out
index 3189080..1bd7de8b 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_de.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_de.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | Vorname: | 
-NAME_LAST | ln | Nachname: | 
-COMPANY_NAME | cm | Firmenname: | 
-ADDRESS_HOME_LINE1 | a1 | Straße und Hausnummer: | 
-ADDRESS_HOME_LINE2 | a2 | Adresszusatz: | 
-ADDRESS_HOME_CITY | ct | Stadt: | 
-ADDRESS_HOME_ZIP | zc | Postleitzahl: | 
-ADDRESS_HOME_STATE | st | Land: | 
-EMAIL_ADDRESS | em | E-Mail-Adresse: | 
-PHONE_HOME_WHOLE_NUMBER | ph | Telefonnummer: | 
-CREDIT_CARD_NAME | c1 | Karteninhaber: | 
-CREDIT_CARD_NUMBER | c2 | Kartennummer: | 
-CREDIT_CARD_EXP_MONTH | c3 | gültig bis monat: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | gültig bis jahr: | 
+NAME_FIRST | fn | Vorname: |  | fn_1-default
+NAME_LAST | ln | Nachname: |  | fn_1-default
+COMPANY_NAME | cm | Firmenname: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | Straße und Hausnummer: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | Adresszusatz: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | Stadt: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | Postleitzahl: |  | fn_1-default
+ADDRESS_HOME_STATE | st | Land: |  | fn_1-default
+EMAIL_ADDRESS | em | E-Mail-Adresse: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | Telefonnummer: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | Karteninhaber: |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | Kartennummer: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | gültig bis monat: |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | gültig bis jahr: |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_de2.out b/chrome/test/data/autofill/heuristics/output/00_i18n_de2.out
index b1fd0da..19f3726 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_de2.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_de2.out
@@ -1,14 +1,14 @@
-NAME_LAST | ln | Nachname: | 
-NAME_FIRST | fn | Vorname: | 
-COMPANY_NAME | cm | Firmenname: | 
-ADDRESS_HOME_LINE1 | a1 | Straße und Hausnummer: | 
-ADDRESS_HOME_LINE2 | a2 | Adresszusatz: | 
-ADDRESS_HOME_CITY | ct | Stadt: | 
-ADDRESS_HOME_ZIP | zc | Postleitzahl: | 
-ADDRESS_HOME_STATE | st | Land: | 
-EMAIL_ADDRESS | em | E-Mail-Adresse: | 
-PHONE_HOME_WHOLE_NUMBER | ph | Telefonnummer: | 
-CREDIT_CARD_NAME | c1 | Karteninhaber: | 
-CREDIT_CARD_NUMBER | c2 | Kartennummer: | 
-CREDIT_CARD_EXP_MONTH | c3 | gültig bis monat: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | gültig bis jahr: | 
+NAME_LAST | ln | Nachname: |  | ln_1-default
+NAME_FIRST | fn | Vorname: |  | ln_1-default
+COMPANY_NAME | cm | Firmenname: |  | ln_1-default
+ADDRESS_HOME_LINE1 | a1 | Straße und Hausnummer: |  | ln_1-default
+ADDRESS_HOME_LINE2 | a2 | Adresszusatz: |  | ln_1-default
+ADDRESS_HOME_CITY | ct | Stadt: |  | ln_1-default
+ADDRESS_HOME_ZIP | zc | Postleitzahl: |  | ln_1-default
+ADDRESS_HOME_STATE | st | Land: |  | ln_1-default
+EMAIL_ADDRESS | em | E-Mail-Adresse: |  | ln_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | Telefonnummer: |  | ln_1-default
+CREDIT_CARD_NAME | c1 | Karteninhaber: |  | ln_1-cc
+CREDIT_CARD_NUMBER | c2 | Kartennummer: |  | ln_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | gültig bis monat: |  | ln_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | gültig bis jahr: |  | ln_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_en.out b/chrome/test/data/autofill/heuristics/output/00_i18n_en.out
index dc94f70b..a6f6339 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_en.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_en.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | First name: | 
-NAME_LAST | ln | Last name: | 
-COMPANY_NAME | cm | Company Name: | 
-ADDRESS_HOME_LINE1 | a1 | Address line 1: | 
-ADDRESS_HOME_LINE2 | a2 | Address line 2: | 
-ADDRESS_HOME_CITY | ct | City: | 
-ADDRESS_HOME_ZIP | zc | Zip Code: | 
-ADDRESS_HOME_STATE | st | State: | 
-EMAIL_ADDRESS | em | Email: | 
-PHONE_HOME_WHOLE_NUMBER | ph | Phone Number: | 
-CREDIT_CARD_NAME | c1 | Name on card: | 
-CREDIT_CARD_NUMBER | c2 | Card Number: | 
-CREDIT_CARD_EXP_MONTH | c3 | Expiration Month: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Expiration Year: | 
+NAME_FIRST | fn | First name: |  | fn_1-default
+NAME_LAST | ln | Last name: |  | fn_1-default
+COMPANY_NAME | cm | Company Name: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | Address line 1: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | Address line 2: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | City: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | Zip Code: |  | fn_1-default
+ADDRESS_HOME_STATE | st | State: |  | fn_1-default
+EMAIL_ADDRESS | em | Email: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | Phone Number: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | Name on card: |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | Card Number: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | Expiration Month: |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Expiration Year: |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_es.out b/chrome/test/data/autofill/heuristics/output/00_i18n_es.out
index 30230d6..d18bd17 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_es.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_es.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | Nombre: | 
-NAME_LAST | ln | Apellidos: | 
-COMPANY_NAME | cm | Empresa: | 
-ADDRESS_HOME_LINE1 | a1 | Dirección: | 
-ADDRESS_HOME_LINE2 | a2 | Información adicional: | 
-ADDRESS_HOME_CITY | ct | Poblacion: | 
-ADDRESS_HOME_ZIP | zc | Código Postal: | 
-ADDRESS_HOME_STATE | st | Provincia: | 
-EMAIL_ADDRESS | em | E-mail: | 
-PHONE_HOME_WHOLE_NUMBER | ph | Teléfono: | 
-CREDIT_CARD_NAME | c1 | Nombre de Tarjeta: | 
-CREDIT_CARD_NUMBER | c2 | Número de Tarjeta: | 
-CREDIT_CARD_EXP_MONTH | c3 | Fecha de Expiración: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Fecha de Expiración: | 
+NAME_FIRST | fn | Nombre: |  | fn_1-default
+NAME_LAST | ln | Apellidos: |  | fn_1-default
+COMPANY_NAME | cm | Empresa: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | Dirección: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | Información adicional: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | Poblacion: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | Código Postal: |  | fn_1-default
+ADDRESS_HOME_STATE | st | Provincia: |  | fn_1-default
+EMAIL_ADDRESS | em | E-mail: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | Teléfono: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | Nombre de Tarjeta: |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | Número de Tarjeta: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | Fecha de Expiración: |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Fecha de Expiración: |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_fr.out b/chrome/test/data/autofill/heuristics/output/00_i18n_fr.out
index a61c309..8ca3a52 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_fr.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_fr.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | Prénom: | 
-NAME_LAST | ln | Nom: | 
-COMPANY_NAME | cm | Société: | 
-ADDRESS_HOME_LINE1 | a1 | Adresse: | 
-ADDRESS_HOME_LINE2 | a2 | Complément d'adresse: | 
-ADDRESS_HOME_CITY | ct | Ville: | 
-ADDRESS_HOME_ZIP | zc | Code postal: | 
-ADDRESS_HOME_STATE | st | State: | 
-EMAIL_ADDRESS | em | Email: | 
-PHONE_HOME_WHOLE_NUMBER | ph | Téléphone Fixe: | 
-CREDIT_CARD_NAME | c1 | Nom complet du détenteur de la carte: | 
-CREDIT_CARD_NUMBER | c2 | Numéro: | 
-CREDIT_CARD_EXP_MONTH | c3 | Date d'expiration: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Date d'expiration: | 
+NAME_FIRST | fn | Prénom: |  | fn_1-default
+NAME_LAST | ln | Nom: |  | fn_1-default
+COMPANY_NAME | cm | Société: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | Adresse: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | Complément d'adresse: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | Ville: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | Code postal: |  | fn_1-default
+ADDRESS_HOME_STATE | st | State: |  | fn_1-default
+EMAIL_ADDRESS | em | Email: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | Téléphone Fixe: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | Nom complet du détenteur de la carte: |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | Numéro: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | Date d'expiration: |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Date d'expiration: |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_it.out b/chrome/test/data/autofill/heuristics/output/00_i18n_it.out
index 4258e16b..5485bea 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_it.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_it.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | Nome: | 
-NAME_LAST | ln | Cognome: | 
-COMPANY_NAME | cm | Ragione Sociale: | 
-ADDRESS_HOME_LINE1 | a1 | Indirizzo: | 
-ADDRESS_HOME_LINE2 | a2 | Indirizzo 2: | 
-ADDRESS_HOME_CITY | ct | Localita: | 
-ADDRESS_HOME_ZIP | zc | CAP: | 
-ADDRESS_HOME_STATE | st | Provincia: | 
-EMAIL_ADDRESS | em | E-mail: | 
-PHONE_HOME_WHOLE_NUMBER | ph | Telefono: | 
-CREDIT_CARD_NAME | c1 | Nome titolare carta: | 
-CREDIT_CARD_NUMBER | c2 | Numero carta di credito: | 
-CREDIT_CARD_EXP_MONTH | c3 | Data di scadenza: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Data di scadenza: | 
+NAME_FIRST | fn | Nome: |  | fn_1-default
+NAME_LAST | ln | Cognome: |  | fn_1-default
+COMPANY_NAME | cm | Ragione Sociale: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | Indirizzo: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | Indirizzo 2: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | Localita: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | CAP: |  | fn_1-default
+ADDRESS_HOME_STATE | st | Provincia: |  | fn_1-default
+EMAIL_ADDRESS | em | E-mail: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | Telefono: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | Nome titolare carta: |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | Numero carta di credito: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | Data di scadenza: |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Data di scadenza: |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_ja.out b/chrome/test/data/autofill/heuristics/output/00_i18n_ja.out
index e8ee7d3..848edcdd 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_ja.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_ja.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | 名: | 
-NAME_LAST | ln | 姓: | 
-COMPANY_NAME | cm | 会社: | 
-ADDRESS_HOME_LINE1 | a1 | 住所: | 
-ADDRESS_HOME_LINE2 | a2 | Address line 2: | 
-ADDRESS_HOME_CITY | ct | 市区町村: | 
-ADDRESS_HOME_ZIP | zc | 郵便番号: | 
-ADDRESS_HOME_STATE | st | 都道府県: | 
-EMAIL_ADDRESS | em | メールアドレス: | 
-PHONE_HOME_WHOLE_NUMBER | ph | 電話番号: | 
-CREDIT_CARD_NAME | c1 | 名前(フルネーム): | 
-CREDIT_CARD_NUMBER | c2 | カード番号: | 
-CREDIT_CARD_EXP_MONTH | c3 | 有効期限: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | 有効期限: | 
+NAME_FIRST | fn | 名: |  | fn_1-default
+NAME_LAST | ln | 姓: |  | fn_1-default
+COMPANY_NAME | cm | 会社: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | 住所: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | Address line 2: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | 市区町村: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | 郵便番号: |  | fn_1-default
+ADDRESS_HOME_STATE | st | 都道府県: |  | fn_1-default
+EMAIL_ADDRESS | em | メールアドレス: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | 電話番号: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | 名前(フルネーム): |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | カード番号: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | 有効期限: |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | 有効期限: |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_ko.out b/chrome/test/data/autofill/heuristics/output/00_i18n_ko.out
index 7c886143..bc15b025 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_ko.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_ko.out
@@ -1,16 +1,16 @@
-NAME_LAST | ln | 성: | 
-NAME_FIRST | firstname | 이름(名): | 
-COMPANY_NAME | cm1 | 회사: | 
-ADDRESS_HOME_LINE1 | a1 | 주소1: | 
-ADDRESS_HOME_LINE2 | a2 | 주소 2: | 
-ADDRESS_HOME_CITY | ct | 시군구: | 
-ADDRESS_HOME_CITY | ct2 | 시·군·구: | 
-ADDRESS_HOME_ZIP | zc | 우편번호: | 
-ADDRESS_HOME_ZIP | zc2 | 우편 번호: | 
-ADDRESS_HOME_STATE | st | 시도: | 
-ADDRESS_HOME_STATE | st2 | 시・도: | 
-EMAIL_ADDRESS | em | Email: | 
-EMAIL_ADDRESS | em2 | 전자 우편: | 
-EMAIL_ADDRESS | em3 | e-mail 주소 | 
-PHONE_HOME_WHOLE_NUMBER | ph | 전화 번호: | 
-PHONE_HOME_WHOLE_NUMBER | ph2 | 휴대폰번호: | 
+NAME_LAST | ln | 성: |  | ln_1-default
+NAME_FIRST | firstname | 이름(名): |  | ln_1-default
+COMPANY_NAME | cm1 | 회사: |  | ln_1-default
+ADDRESS_HOME_LINE1 | a1 | 주소1: |  | ln_1-default
+ADDRESS_HOME_LINE2 | a2 | 주소 2: |  | ln_1-default
+ADDRESS_HOME_CITY | ct | 시군구: |  | ln_1-default
+ADDRESS_HOME_CITY | ct2 | 시·군·구: |  | ln_1-default
+ADDRESS_HOME_ZIP | zc | 우편번호: |  | ln_1-default
+ADDRESS_HOME_ZIP | zc2 | 우편 번호: |  | ln_1-default
+ADDRESS_HOME_STATE | st | 시도: |  | ln_1-default
+ADDRESS_HOME_STATE | st2 | 시・도: |  | ln_1-default
+EMAIL_ADDRESS | em | Email: |  | ln_1-default
+EMAIL_ADDRESS | em2 | 전자 우편: |  | ln_1-default
+EMAIL_ADDRESS | em3 | e-mail 주소 |  | ln_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | 전화 번호: |  | ln_1-default
+PHONE_HOME_WHOLE_NUMBER | ph2 | 휴대폰번호: |  | ln_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_pt.out b/chrome/test/data/autofill/heuristics/output/00_i18n_pt.out
index 03078c0c..3c613a7 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_pt.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_pt.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | Nome: | 
-NAME_LAST | ln | Sobrenome: | 
-COMPANY_NAME | cm | Empresa: | 
-ADDRESS_HOME_LINE1 | a1 | Endereço: | 
-ADDRESS_HOME_LINE2 | a2 | Complemento: | 
-ADDRESS_HOME_CITY | ct | Cidade: | 
-ADDRESS_HOME_ZIP | zc | CEP: | 
-ADDRESS_HOME_STATE | st | Estado: | 
-EMAIL_ADDRESS | em | email: | 
-PHONE_HOME_WHOLE_NUMBER | ph | Telefone: | 
-CREDIT_CARD_NAME | c1 | Nome do cartão: | 
-CREDIT_CARD_NUMBER | c2 | Número do cartão: | 
-CREDIT_CARD_EXP_MONTH | c3 | Data de validade: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Data de validade: | 
+NAME_FIRST | fn | Nome: |  | fn_1-default
+NAME_LAST | ln | Sobrenome: |  | fn_1-default
+COMPANY_NAME | cm | Empresa: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | Endereço: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | Complemento: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | Cidade: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | CEP: |  | fn_1-default
+ADDRESS_HOME_STATE | st | Estado: |  | fn_1-default
+EMAIL_ADDRESS | em | email: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | Telefone: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | Nome do cartão: |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | Número do cartão: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | Data de validade: |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Data de validade: |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_ru.out b/chrome/test/data/autofill/heuristics/output/00_i18n_ru.out
index e30634ab..c4d138aa 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_ru.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_ru.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | Имя: | 
-NAME_LAST | ln | Фамилия: | 
-COMPANY_NAME | cm | название компании: | 
-ADDRESS_HOME_LINE1 | a1 | Адрес: | 
-ADDRESS_HOME_LINE2 | a2 | Улица: | 
-ADDRESS_HOME_CITY | ct | Город: | 
-ADDRESS_HOME_ZIP | zc | Почтовый Индекс: | 
-ADDRESS_HOME_STATE | st | область: | 
-EMAIL_ADDRESS | em | Электронной Почты: | 
-PHONE_HOME_WHOLE_NUMBER | ph | телефон: | 
-CREDIT_CARD_NAME | c1 | Имя владельца карты: | 
-CREDIT_CARD_NUMBER | c2 | Номер кредитной карты: | 
-CREDIT_CARD_EXP_MONTH | c3 | Срок действия карты : | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Срок действия карты : | 
+NAME_FIRST | fn | Имя: |  | fn_1-default
+NAME_LAST | ln | Фамилия: |  | fn_1-default
+COMPANY_NAME | cm | название компании: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | Адрес: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | Улица: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | Город: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | Почтовый Индекс: |  | fn_1-default
+ADDRESS_HOME_STATE | st | область: |  | fn_1-default
+EMAIL_ADDRESS | em | Электронной Почты: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | телефон: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | Имя владельца карты: |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | Номер кредитной карты: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | Срок действия карты : |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | Срок действия карты : |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_zh_cn.out b/chrome/test/data/autofill/heuristics/output/00_i18n_zh_cn.out
index e51f6a2..80a2103 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_zh_cn.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_zh_cn.out
@@ -1,13 +1,13 @@
-NAME_FULL | fl | 姓名: | 
-COMPANY_NAME | cm | 公司: | 
-ADDRESS_HOME_LINE1 | a1 | 地址: | 
-ADDRESS_HOME_LINE2 | a2 | 地址2: | 
-ADDRESS_HOME_CITY | ct | 市: | 
-ADDRESS_HOME_ZIP | zc | 邮编: | 
-ADDRESS_HOME_STATE | st | 省: | 
-EMAIL_ADDRESS | em | 邮箱: | 
-PHONE_HOME_WHOLE_NUMBER | ph | 电话: | 
-CREDIT_CARD_NAME | c1 | 持卡人姓名: | 
-CREDIT_CARD_NUMBER | c2 | 信用卡号码: | 
-CREDIT_CARD_EXP_MONTH | c3 | 月: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | 年: | 
+NAME_FULL | fl | 姓名: |  | fl_1-default
+COMPANY_NAME | cm | 公司: |  | fl_1-default
+ADDRESS_HOME_LINE1 | a1 | 地址: |  | fl_1-default
+ADDRESS_HOME_LINE2 | a2 | 地址2: |  | fl_1-default
+ADDRESS_HOME_CITY | ct | 市: |  | fl_1-default
+ADDRESS_HOME_ZIP | zc | 邮编: |  | fl_1-default
+ADDRESS_HOME_STATE | st | 省: |  | fl_1-default
+EMAIL_ADDRESS | em | 邮箱: |  | fl_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | 电话: |  | fl_1-default
+CREDIT_CARD_NAME | c1 | 持卡人姓名: |  | fl_1-cc
+CREDIT_CARD_NUMBER | c2 | 信用卡号码: |  | fl_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | 月: |  | fl_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | 年: |  | fl_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/00_i18n_zh_tw.out b/chrome/test/data/autofill/heuristics/output/00_i18n_zh_tw.out
index 8310953..5b85a4d7 100644
--- a/chrome/test/data/autofill/heuristics/output/00_i18n_zh_tw.out
+++ b/chrome/test/data/autofill/heuristics/output/00_i18n_zh_tw.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fn | 名字: | 
-NAME_LAST | ln | 姓氏: | 
-COMPANY_NAME | cm | 公司: | 
-ADDRESS_HOME_LINE1 | a1 | 住家地址: | 
-ADDRESS_HOME_LINE2 | a2 | 地址: | 
-ADDRESS_HOME_CITY | ct | 分區: | 
-ADDRESS_HOME_ZIP | zc | 郵遞區號: | 
-ADDRESS_HOME_STATE | st | 地區: | 
-EMAIL_ADDRESS | em | 電郵地址: | 
-PHONE_HOME_WHOLE_NUMBER | ph | 電話: | 
-CREDIT_CARD_NAME | c1 | 持卡人姓名: | 
-CREDIT_CARD_NUMBER | c2 | 信用卡卡號: | 
-CREDIT_CARD_EXP_MONTH | c3 | 月: | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | 年: | 
+NAME_FIRST | fn | 名字: |  | fn_1-default
+NAME_LAST | ln | 姓氏: |  | fn_1-default
+COMPANY_NAME | cm | 公司: |  | fn_1-default
+ADDRESS_HOME_LINE1 | a1 | 住家地址: |  | fn_1-default
+ADDRESS_HOME_LINE2 | a2 | 地址: |  | fn_1-default
+ADDRESS_HOME_CITY | ct | 分區: |  | fn_1-default
+ADDRESS_HOME_ZIP | zc | 郵遞區號: |  | fn_1-default
+ADDRESS_HOME_STATE | st | 地區: |  | fn_1-default
+EMAIL_ADDRESS | em | 電郵地址: |  | fn_1-default
+PHONE_HOME_WHOLE_NUMBER | ph | 電話: |  | fn_1-default
+CREDIT_CARD_NAME | c1 | 持卡人姓名: |  | fn_1-cc
+CREDIT_CARD_NUMBER | c2 | 信用卡卡號: |  | fn_1-cc
+CREDIT_CARD_EXP_MONTH | c3 | 月: |  | fn_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 | 年: |  | fn_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_advanced.out b/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_advanced.out
index a31ddc8..6d7e7437 100644
--- a/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_advanced.out
+++ b/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_advanced.out
@@ -1,17 +1,17 @@
-PHONE_HOME_WHOLE_NUMBER | 4.phone |  | 
-EMAIL_ADDRESS | 4.email |  | 
-UNKNOWN_TYPE | 4.a |  | 
-UNKNOWN_TYPE | 4.b |  | 
-UNKNOWN_TYPE | 4.c |  | 
-ADDRESS_HOME_CITY | 4.city |  | 
-HTML_TYPE_NAME | 1.n |  | 
-HTML_TYPE_EMAIL | 1.e |  | 
-HTML_TYPE_ADDRESS_LINE1 | 1.a |  | 
-UNKNOWN_TYPE | 2.name |  | 
-UNKNOWN_TYPE | 2.email |  | 
-HTML_TYPE_TEL | 2.t |  | 
-UNKNOWN_TYPE | 2.address |  | 
-UNKNOWN_TYPE | 3.name |  | 
-UNKNOWN_TYPE | 3.email |  | 
-UNKNOWN_TYPE | 3.o |  | 
-UNKNOWN_TYPE | 3.address |  | 
+PHONE_HOME_WHOLE_NUMBER | 4.phone |  |  | 4.phone_1-default
+EMAIL_ADDRESS | 4.email |  |  | 4.phone_1-default
+UNKNOWN_TYPE | 4.a |  |  | 4.phone_1-default
+UNKNOWN_TYPE | 4.b |  |  | 4.phone_1-default
+UNKNOWN_TYPE | 4.c |  |  | 4.phone_1-default
+ADDRESS_HOME_CITY | 4.city |  |  | 4.phone_1-default
+HTML_TYPE_NAME | 1.n |  |  | -default-default
+HTML_TYPE_EMAIL | 1.e |  |  | -default-default
+HTML_TYPE_ADDRESS_LINE1 | 1.a |  |  | one-shipping-default
+UNKNOWN_TYPE | 2.name |  |  | 2.name_1-default
+UNKNOWN_TYPE | 2.email |  |  | 2.name_1-default
+HTML_TYPE_TEL | 2.t |  |  | 2.name_1-default
+UNKNOWN_TYPE | 2.address |  |  | 2.name_1-default
+UNKNOWN_TYPE | 3.name |  |  | 3.name_1-default
+UNKNOWN_TYPE | 3.email |  |  | 3.name_1-default
+UNKNOWN_TYPE | 3.o |  |  | 3.name_1-default
+UNKNOWN_TYPE | 3.address |  |  | 3.name_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_basic.out b/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_basic.out
index 06d0eda..8b617f2 100644
--- a/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_basic.out
+++ b/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_basic.out
@@ -1,53 +1,53 @@
-HTML_TYPE_NAME | na |  | 
-UNKNOWN_TYPE | np |  | 
-HTML_TYPE_GIVEN_NAME | ng |  | 
-HTML_TYPE_ADDITIONAL_NAME | nm |  | 
-HTML_TYPE_ADDITIONAL_NAME_INITIAL | n1 |  | 
-HTML_TYPE_FAMILY_NAME | nf |  | 
-UNKNOWN_TYPE | ns |  | 
-UNKNOWN_TYPE | nn |  | 
-UNKNOWN_TYPE | no |  | 
-HTML_TYPE_ORGANIZATION | ao |  | 
-HTML_TYPE_STREET_ADDRESS | af |  | 
-HTML_TYPE_ADDRESS_LINE1 | a1 |  | 
-HTML_TYPE_ADDRESS_LINE2 | a2 |  | 
-HTML_TYPE_ADDRESS_LINE3 | a3 |  | 
-HTML_TYPE_ADDRESS_LEVEL1 | al1 |  | 
-HTML_TYPE_ADDRESS_LEVEL2 | al2 |  | 
-HTML_TYPE_ADDRESS_LEVEL3 | al3 |  | 
-UNKNOWN_TYPE | al4 |  | 
-HTML_TYPE_COUNTRY_CODE | ac |  | 
-HTML_TYPE_COUNTRY_NAME | an |  | 
-HTML_TYPE_POSTAL_CODE | ap |  | 
-HTML_TYPE_CREDIT_CARD_NAME | cn |  | 
-UNKNOWN_TYPE | cg |  | 
-UNKNOWN_TYPE | ca |  | 
-UNKNOWN_TYPE | cf |  | 
-HTML_TYPE_CREDIT_CARD_NUMBER | cc |  | 
-HTML_TYPE_CREDIT_CARD_EXP | ce |  | 
-HTML_TYPE_CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR | c5 |  | 
-HTML_TYPE_CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | c7 |  | 
-HTML_TYPE_CREDIT_CARD_EXP_MONTH | cm |  | 
-HTML_TYPE_CREDIT_CARD_EXP_YEAR | cy |  | 
-HTML_TYPE_CREDIT_CARD_EXP_2_DIGIT_YEAR | c2 |  | 
-HTML_TYPE_CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 |  | 
-HTML_TYPE_CREDIT_CARD_VERIFICATION_CODE | cs |  | 
-HTML_TYPE_CREDIT_CARD_TYPE | ct |  | 
-UNKNOWN_TYPE | xl |  | 
-UNKNOWN_TYPE | xb |  | 
-UNKNOWN_TYPE | xd |  | 
-UNKNOWN_TYPE | xm |  | 
-UNKNOWN_TYPE | xy |  | 
-UNKNOWN_TYPE | xs |  | 
-UNKNOWN_TYPE | xu |  | 
-UNKNOWN_TYPE | xp |  | 
-HTML_TYPE_EMAIL | em |  | 
-UNKNOWN_TYPE | im |  | 
-HTML_TYPE_TEL | tt |  | 
-HTML_TYPE_TEL_COUNTRY_CODE | tc |  | 
-HTML_TYPE_TEL_NATIONAL | tn |  | 
-HTML_TYPE_TEL_AREA_CODE | ta |  | 
-HTML_TYPE_TEL_LOCAL | tl |  | 
-HTML_TYPE_TEL_LOCAL_PREFIX | tp |  | 
-HTML_TYPE_TEL_LOCAL_SUFFIX | ts |  | 
-UNKNOWN_TYPE | te |  | 
+HTML_TYPE_NAME | na |  |  | na_1-default
+UNKNOWN_TYPE | np |  |  | na_1-default
+HTML_TYPE_GIVEN_NAME | ng |  |  | na_1-default
+HTML_TYPE_ADDITIONAL_NAME | nm |  |  | na_1-default
+HTML_TYPE_ADDITIONAL_NAME_INITIAL | n1 |  |  | na_1-default
+HTML_TYPE_FAMILY_NAME | nf |  |  | na_1-default
+UNKNOWN_TYPE | ns |  |  | na_1-default
+UNKNOWN_TYPE | nn |  |  | na_1-default
+UNKNOWN_TYPE | no |  |  | na_1-default
+HTML_TYPE_ORGANIZATION | ao |  |  | na_1-default
+HTML_TYPE_STREET_ADDRESS | af |  |  | na_1-default
+HTML_TYPE_ADDRESS_LINE1 | a1 |  |  | na_1-default
+HTML_TYPE_ADDRESS_LINE2 | a2 |  |  | na_1-default
+HTML_TYPE_ADDRESS_LINE3 | a3 |  |  | na_1-default
+HTML_TYPE_ADDRESS_LEVEL1 | al1 |  |  | na_1-default
+HTML_TYPE_ADDRESS_LEVEL2 | al2 |  |  | na_1-default
+HTML_TYPE_ADDRESS_LEVEL3 | al3 |  |  | na_1-default
+UNKNOWN_TYPE | al4 |  |  | na_1-default
+HTML_TYPE_COUNTRY_CODE | ac |  |  | na_1-default
+HTML_TYPE_COUNTRY_NAME | an |  |  | na_1-default
+HTML_TYPE_POSTAL_CODE | ap |  |  | na_1-default
+HTML_TYPE_CREDIT_CARD_NAME | cn |  |  | na_1-cc
+UNKNOWN_TYPE | cg |  |  | na_1-default
+UNKNOWN_TYPE | ca |  |  | na_1-default
+UNKNOWN_TYPE | cf |  |  | na_1-default
+HTML_TYPE_CREDIT_CARD_NUMBER | cc |  |  | na_1-cc
+HTML_TYPE_CREDIT_CARD_EXP | ce |  |  | na_1-cc
+HTML_TYPE_CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR | c5 |  |  | na_1-cc
+HTML_TYPE_CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | c7 |  |  | c7_1-cc
+HTML_TYPE_CREDIT_CARD_EXP_MONTH | cm |  |  | c7_1-cc
+HTML_TYPE_CREDIT_CARD_EXP_YEAR | cy |  |  | c7_1-cc
+HTML_TYPE_CREDIT_CARD_EXP_2_DIGIT_YEAR | c2 |  |  | c7_1-cc
+HTML_TYPE_CREDIT_CARD_EXP_4_DIGIT_YEAR | c4 |  |  | c4_1-cc
+HTML_TYPE_CREDIT_CARD_VERIFICATION_CODE | cs |  |  | c4_1-cc
+HTML_TYPE_CREDIT_CARD_TYPE | ct |  |  | c4_1-cc
+UNKNOWN_TYPE | xl |  |  | c4_1-default
+UNKNOWN_TYPE | xb |  |  | c4_1-default
+UNKNOWN_TYPE | xd |  |  | c4_1-default
+UNKNOWN_TYPE | xm |  |  | c4_1-default
+UNKNOWN_TYPE | xy |  |  | c4_1-default
+UNKNOWN_TYPE | xs |  |  | c4_1-default
+UNKNOWN_TYPE | xu |  |  | c4_1-default
+UNKNOWN_TYPE | xp |  |  | c4_1-default
+HTML_TYPE_EMAIL | em |  |  | c4_1-default
+UNKNOWN_TYPE | im |  |  | c4_1-default
+HTML_TYPE_TEL | tt |  |  | c4_1-default
+HTML_TYPE_TEL_COUNTRY_CODE | tc |  |  | c4_1-default
+HTML_TYPE_TEL_NATIONAL | tn |  |  | c4_1-default
+HTML_TYPE_TEL_AREA_CODE | ta |  |  | c4_1-default
+HTML_TYPE_TEL_LOCAL | tl |  |  | c4_1-default
+HTML_TYPE_TEL_LOCAL_PREFIX | tp |  |  | c4_1-default
+HTML_TYPE_TEL_LOCAL_SUFFIX | ts |  |  | c4_1-default
+UNKNOWN_TYPE | te |  |  | c4_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_invalid.out b/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_invalid.out
index aa0f9b3e..52d67e8 100644
--- a/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_invalid.out
+++ b/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_invalid.out
@@ -1,75 +1,75 @@
-HTML_TYPE_EMAIL | valid-pre-garbage |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-HTML_TYPE_EMAIL | valid-pre-order |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-HTML_TYPE_EMAIL | valid-pre-repetition |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-HTML_TYPE_EMAIL | valid-pre-combinations |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
-UNKNOWN_TYPE |  |  | 
+HTML_TYPE_EMAIL | valid-pre-garbage |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-garbage_1-default
+HTML_TYPE_EMAIL | valid-pre-order |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-order_1-default
+HTML_TYPE_EMAIL | valid-pre-repetition |  |  | valid-pre-repetition_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-repetition_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-repetition_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-repetition_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-repetition_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-repetition_1-default
+HTML_TYPE_EMAIL | valid-pre-combinations |  |  | valid-pre-combinations_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-combinations_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-combinations_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-combinations_1-default
+UNKNOWN_TYPE |  |  |  | valid-pre-combinations_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_malicious.out b/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_malicious.out
index e162340..591541e 100644
--- a/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_malicious.out
+++ b/chrome/test/data/autofill/heuristics/output/01_autocomplete_attribute_malicious.out
@@ -1,4 +1,4 @@
-HTML_TYPE_NAME | name |  | 
-HTML_TYPE_EMAIL | email |  | 
-HTML_TYPE_ADDRESS_LEVEL2 | city |  | 
-UNKNOWN_TYPE | malicious |  | 
+HTML_TYPE_NAME | name |  |  | name_1-default
+HTML_TYPE_EMAIL | email |  |  | name_1-default
+HTML_TYPE_ADDRESS_LEVEL2 | city |  |  | name_1-default
+UNKNOWN_TYPE | malicious |  |  | name_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/01_misc_phones.out b/chrome/test/data/autofill/heuristics/output/01_misc_phones.out
index 8eedd0a..ff6c3be6 100644
--- a/chrome/test/data/autofill/heuristics/output/01_misc_phones.out
+++ b/chrome/test/data/autofill/heuristics/output/01_misc_phones.out
@@ -1,27 +1,27 @@
-NAME_FIRST | firstname | First name: | 
-NAME_LAST | lastname | Last name: | 
-ADDRESS_HOME_LINE1 | address | Address: | 
-ADDRESS_HOME_CITY | city | City: | 
-ADDRESS_HOME_STATE | state | State: | 
-ADDRESS_HOME_ZIP | zip | Zip: | 
-PHONE_HOME_WHOLE_NUMBER | phone | Phone: | 
-PHONE_HOME_CITY_CODE | areacode1 | Area Code: | 
-PHONE_HOME_NUMBER | phone1 | Phone: | 
-PHONE_HOME_CITY_CODE | hphone1 | Phone: | 
-PHONE_HOME_NUMBER | hphone2 | - | 
-PHONE_HOME_NUMBER | hphone3 | - | 
-UNKNOWN_TYPE | hphone4 | ext.: | 
-PHONE_HOME_CITY_CODE | hphone1a | Phone:        ( | 
-PHONE_HOME_NUMBER | hphone2a | ) | 
-PHONE_HOME_NUMBER | hphone3a | - | 
-UNKNOWN_TYPE | hphone4a | ext.: | 
-PHONE_HOME_COUNTRY_CODE | hphone1b | Phone: | 
-PHONE_HOME_CITY_CODE | hphone1b |  | 
-PHONE_HOME_NUMBER | hphone2b | - | 
-PHONE_HOME_NUMBER | hphone3b | - | 
-UNKNOWN_TYPE | hphone4b | ext.: | 
-PHONE_HOME_COUNTRY_CODE | hphone1c | Phone: | 
-PHONE_HOME_CITY_CODE | hphone1c | ( | 
-PHONE_HOME_NUMBER | hphone2c | ) | 
-PHONE_HOME_NUMBER | hphone3c | - | 
-UNKNOWN_TYPE | hphone4c | ext.: | 
+NAME_FIRST | firstname | First name: |  | firstname_1-default
+NAME_LAST | lastname | Last name: |  | firstname_1-default
+ADDRESS_HOME_LINE1 | address | Address: |  | firstname_1-default
+ADDRESS_HOME_CITY | city | City: |  | firstname_1-default
+ADDRESS_HOME_STATE | state | State: |  | firstname_1-default
+ADDRESS_HOME_ZIP | zip | Zip: |  | firstname_1-default
+PHONE_HOME_WHOLE_NUMBER | phone | Phone: |  | firstname_1-default
+PHONE_HOME_CITY_CODE | areacode1 | Area Code: |  | firstname_1-default
+PHONE_HOME_NUMBER | phone1 | Phone: |  | firstname_1-default
+PHONE_HOME_CITY_CODE | hphone1 | Phone: |  | firstname_1-default
+PHONE_HOME_NUMBER | hphone2 | - |  | firstname_1-default
+PHONE_HOME_NUMBER | hphone3 | - |  | firstname_1-default
+UNKNOWN_TYPE | hphone4 | ext.: |  | firstname_1-default
+PHONE_HOME_CITY_CODE | hphone1a | Phone:        ( |  | firstname_1-default
+PHONE_HOME_NUMBER | hphone2a | ) |  | firstname_1-default
+PHONE_HOME_NUMBER | hphone3a | - |  | firstname_1-default
+UNKNOWN_TYPE | hphone4a | ext.: |  | firstname_1-default
+PHONE_HOME_COUNTRY_CODE | hphone1b | Phone: |  | firstname_1-default
+PHONE_HOME_CITY_CODE | hphone1b |  |  | firstname_1-default
+PHONE_HOME_NUMBER | hphone2b | - |  | firstname_1-default
+PHONE_HOME_NUMBER | hphone3b | - |  | firstname_1-default
+UNKNOWN_TYPE | hphone4b | ext.: |  | firstname_1-default
+PHONE_HOME_COUNTRY_CODE | hphone1c | Phone: |  | firstname_1-default
+PHONE_HOME_CITY_CODE | hphone1c | ( |  | firstname_1-default
+PHONE_HOME_NUMBER | hphone2c | ) |  | firstname_1-default
+PHONE_HOME_NUMBER | hphone3c | - |  | firstname_1-default
+UNKNOWN_TYPE | hphone4c | ext.: |  | firstname_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/02_checkout_advanceautoparts.com.out b/chrome/test/data/autofill/heuristics/output/02_checkout_advanceautoparts.com.out
index f94e942..1768f09 100644
--- a/chrome/test/data/autofill/heuristics/output/02_checkout_advanceautoparts.com.out
+++ b/chrome/test/data/autofill/heuristics/output/02_checkout_advanceautoparts.com.out
@@ -1,28 +1,28 @@
-UNKNOWN_TYPE | billingShippingSame | Billing AddressUse form below for your billing address:* required fields*First Name: | false
-NAME_FIRST | billFirstName | *First Name: | 
-NAME_LAST | billLastName | *Last Name: | 
-ADDRESS_HOME_LINE1 | billAddress1 | *Street Address 1: | 
-ADDRESS_HOME_LINE2 | billAddress2 | Street Address 2: | 
-ADDRESS_HOME_CITY | billCity | *City: | 
-ADDRESS_HOME_STATE | billState | *State: | AL
-ADDRESS_HOME_ZIP | billZipCode | *Zip Code: | 
-PHONE_HOME_CITY_CODE | billDayPhonePart1 | ( | 
-PHONE_HOME_NUMBER | billDayPhonePart2 | ) | 
-PHONE_HOME_NUMBER | billDayPhonePart3 | *Day Phone: | 
-EMAIL_ADDRESS | billEmail | *Email Address: | 
-UNKNOWN_TYPE | sendMeEmail | *Email Address: | checked
-UNKNOWN_TYPE | billPassword | Password: | 
-UNKNOWN_TYPE | billPasswordVerify | Confirm Password: | 
-NAME_FIRST | shipFirstName | *First Name: | 
-NAME_LAST | shipLastName | *Last Name: | 
-ADDRESS_HOME_LINE1 | shipAddress1 | *Street Address 1: | 
-ADDRESS_HOME_LINE2 | shipAddress2 | Street Address 2: | 
-ADDRESS_HOME_CITY | shipCity | *City: | 
-ADDRESS_HOME_STATE | shipState | *State: | AL
-ADDRESS_HOME_ZIP | shipZipCode | *Zip Code: | 
-PHONE_HOME_CITY_CODE | shipDayPhonePart1 | ( | 
-PHONE_HOME_NUMBER | shipDayPhonePart2 | ) | 
-PHONE_HOME_NUMBER | shipDayPhonePart3 | *Day Phone: | 
-PHONE_HOME_CITY_CODE | shipNightPhonePart1 | ( | 
-PHONE_HOME_NUMBER | shipNightPhonePart2 | ) | 
-PHONE_HOME_NUMBER | shipNightPhonePart3 | Night Phone: | 
+UNKNOWN_TYPE | billingShippingSame | Billing AddressUse form below for your billing address:* required fields*First Name: | false | billingShippingSame_1-default
+NAME_FIRST | billFirstName | *First Name: |  | billingShippingSame_1-default
+NAME_LAST | billLastName | *Last Name: |  | billingShippingSame_1-default
+ADDRESS_HOME_LINE1 | billAddress1 | *Street Address 1: |  | billingShippingSame_1-default
+ADDRESS_HOME_LINE2 | billAddress2 | Street Address 2: |  | billingShippingSame_1-default
+ADDRESS_HOME_CITY | billCity | *City: |  | billingShippingSame_1-default
+ADDRESS_HOME_STATE | billState | *State: | AL | billingShippingSame_1-default
+ADDRESS_HOME_ZIP | billZipCode | *Zip Code: |  | billingShippingSame_1-default
+PHONE_HOME_CITY_CODE | billDayPhonePart1 | ( |  | billingShippingSame_1-default
+PHONE_HOME_NUMBER | billDayPhonePart2 | ) |  | billingShippingSame_1-default
+PHONE_HOME_NUMBER | billDayPhonePart3 | *Day Phone: |  | billingShippingSame_1-default
+EMAIL_ADDRESS | billEmail | *Email Address: |  | billingShippingSame_1-default
+UNKNOWN_TYPE | sendMeEmail | *Email Address: | checked | billingShippingSame_1-default
+UNKNOWN_TYPE | billPassword | Password: |  | billingShippingSame_1-default
+UNKNOWN_TYPE | billPasswordVerify | Confirm Password: |  | billingShippingSame_1-default
+NAME_FIRST | shipFirstName | *First Name: |  | shipFirstName_1-default
+NAME_LAST | shipLastName | *Last Name: |  | shipFirstName_1-default
+ADDRESS_HOME_LINE1 | shipAddress1 | *Street Address 1: |  | shipFirstName_1-default
+ADDRESS_HOME_LINE2 | shipAddress2 | Street Address 2: |  | shipFirstName_1-default
+ADDRESS_HOME_CITY | shipCity | *City: |  | shipFirstName_1-default
+ADDRESS_HOME_STATE | shipState | *State: | AL | shipFirstName_1-default
+ADDRESS_HOME_ZIP | shipZipCode | *Zip Code: |  | shipFirstName_1-default
+PHONE_HOME_CITY_CODE | shipDayPhonePart1 | ( |  | shipFirstName_1-default
+PHONE_HOME_NUMBER | shipDayPhonePart2 | ) |  | shipFirstName_1-default
+PHONE_HOME_NUMBER | shipDayPhonePart3 | *Day Phone: |  | shipFirstName_1-default
+PHONE_HOME_CITY_CODE | shipNightPhonePart1 | ( |  | shipFirstName_1-default
+PHONE_HOME_NUMBER | shipNightPhonePart2 | ) |  | shipFirstName_1-default
+PHONE_HOME_NUMBER | shipNightPhonePart3 | Night Phone: |  | shipFirstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/02_checkout_ae.com.out b/chrome/test/data/autofill/heuristics/output/02_checkout_ae.com.out
index ac9f1563..4266c116 100644
--- a/chrome/test/data/autofill/heuristics/output/02_checkout_ae.com.out
+++ b/chrome/test/data/autofill/heuristics/output/02_checkout_ae.com.out
@@ -1,51 +1,51 @@
-NAME_FIRST | firstName | Search wish lists by name | First Name
-NAME_LAST | lastName |  | Last Name
-EMAIL_ADDRESS | email | Or search wish lists by email | Email
-ADDRESS_HOME_COUNTRY | countryType | Country Type | usa
-ADDRESS_HOME_COUNTRY | country | Country, APO/FPO | US
-NAME_FIRST | firstName | First Name | 
-NAME_LAST | lastName | Last Name | 
-ADDRESS_HOME_LINE1 | address1 | Address | 
-ADDRESS_HOME_LINE2 | address2 | Address | 
-ADDRESS_HOME_CITY | city | City | 
-ADDRESS_HOME_STATE | state | State | 
-ADDRESS_HOME_ZIP | zip | Zip | 
-UNKNOWN_TYPE | shippingChoice | Shipping Method CLOSEWe ship using UPS and USPS Priority Mail within the continental United States, and USPS priority mail outside of the continental United States.Learn More about our shipping methods and prices.Place this order by 1PM EST to get it by the estimated dates below: | Standard
-UNKNOWN_TYPE | shippingChoice | Shipping Method CLOSEWe ship using UPS and USPS Priority Mail within the continental United States, and USPS priority mail outside of the continental United States.Learn More about our shipping methods and prices.Place this order by 1PM EST to get it by the estimated dates below: | SecondDay
-UNKNOWN_TYPE | shippingChoice | Standard3 - 7 business days$7dates: Jun 08 - Jun 14 Two Day2 business days$15date: Jun 07 Overnight1 business day$20date: Jun 06 | Overnight
-CREDIT_CARD_TYPE | ccType | Card Type: | 
-CREDIT_CARD_NUMBER | ccNumber | Card Number: | 
-CREDIT_CARD_EXP_MONTH | expMonth | Expiration: | 1
-CREDIT_CARD_EXP_4_DIGIT_YEAR | expYear | Expiration: | 2011
-CREDIT_CARD_VERIFICATION_CODE | ccSecCode | Security Code: CLOSEVisa, Mastercard & Discover:The security code is a 3-digit number found on the back of the card near the signature strip.American Express:The security code is a 4-digit number found on the front right side of the card. | 
-UNKNOWN_TYPE | birthMonthBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | 
-UNKNOWN_TYPE | birthDayBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | 
-UNKNOWN_TYPE | birthYearBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. | 
-UNKNOWN_TYPE | SSN | Last 4 digits of your social security #: CLOSEWe need the last 4 digits of your SSN for the Bill Me Later® credit check process. If you do not have an SSN, you can still pay by Credit Card or PayPal. | 
-UNKNOWN_TYPE | agree | I agree to have the Terms and Conditions presented electronically. | yes
-UNKNOWN_TYPE | agreeTs | I agree to the Bill Me Later® Terms and Conditions. | yes
-ADDRESS_HOME_COUNTRY | countryType | Country Type | usa
-UNKNOWN_TYPE | billSameAsShip | My Billing & Shipping addresses are the same | yes
-ADDRESS_HOME_COUNTRY | country | Country, APO/FPO | US
-NAME_FIRST | firstName | First Name | 
-NAME_LAST | lastName | Last Name | 
-ADDRESS_HOME_LINE1 | address1 | Address | 
-ADDRESS_HOME_LINE2 | address2 | Address | 
-ADDRESS_HOME_CITY | city | City | 
-ADDRESS_HOME_STATE | state | State | 
-ADDRESS_HOME_ZIP | zip | Zip | 
-EMAIL_ADDRESS | email | Email CLOSEWe use this to send you an order confirmation and tracking info once your order ships. | 
-EMAIL_ADDRESS | confirmEmail | Re-Type Email | 
-PHONE_HOME_WHOLE_NUMBER | billingPhone | Billing Phone Number CLOSEThis must match the phone number on your credit card statement. Don't worry... we never share your number with anyone. | 
-UNKNOWN_TYPE | accessPassNumber | My AEREWARD$ # CLOSEAEREWARD$ NumberEnter the number found on the back of your AEREWARD$ card to earn rewards for your purchase.Learn More about AEREWARD$ | 
-UNKNOWN_TYPE | aeRewardsSignUp | Sign up now and receive 25 points  just for signing up! Learn More | true
-UNKNOWN_TYPE | aeAccount | Create my AE Account.CLOSECreate an AE Account to:Save Your Personal Info For Next TimeCheckout FasterTrack An Order Quicker Sign up now and receive 25 points just for signing up! Learn More | true
-UNKNOWN_TYPE | aeAccountPass | Password (6-15 Letters & Numbers) | 
-UNKNOWN_TYPE | aeAccountPassConfirm | Confirm Password | 
-UNKNOWN_TYPE | birthMonthBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | 
-UNKNOWN_TYPE | birthDayBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | 
-UNKNOWN_TYPE | birthYearBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. | 
-UNKNOWN_TYPE | aeEmail | AE | on
-UNKNOWN_TYPE | aerieEmail | aerie | on
-UNKNOWN_TYPE | kidsEmail | 77kids | on
-UNKNOWN_TYPE | loyaltyTerms | I accept the Terms & Conditions | 
+NAME_FIRST | firstName | Search wish lists by name | First Name | firstName_1-default
+NAME_LAST | lastName |  | Last Name | firstName_1-default
+EMAIL_ADDRESS | email | Or search wish lists by email | Email | firstName_1-default
+ADDRESS_HOME_COUNTRY | countryType | Country Type | usa | countryType_1-default
+ADDRESS_HOME_COUNTRY | country | Country, APO/FPO | US | countryType_1-default
+NAME_FIRST | firstName | First Name |  | countryType_1-default
+NAME_LAST | lastName | Last Name |  | countryType_1-default
+ADDRESS_HOME_LINE1 | address1 | Address |  | countryType_1-default
+ADDRESS_HOME_LINE2 | address2 | Address |  | countryType_1-default
+ADDRESS_HOME_CITY | city | City |  | countryType_1-default
+ADDRESS_HOME_STATE | state | State |  | countryType_1-default
+ADDRESS_HOME_ZIP | zip | Zip |  | countryType_1-default
+UNKNOWN_TYPE | shippingChoice | Shipping Method CLOSEWe ship using UPS and USPS Priority Mail within the continental United States, and USPS priority mail outside of the continental United States.Learn More about our shipping methods and prices.Place this order by 1PM EST to get it by the estimated dates below: | Standard | countryType_1-default
+UNKNOWN_TYPE | shippingChoice | Shipping Method CLOSEWe ship using UPS and USPS Priority Mail within the continental United States, and USPS priority mail outside of the continental United States.Learn More about our shipping methods and prices.Place this order by 1PM EST to get it by the estimated dates below: | SecondDay | countryType_1-default
+UNKNOWN_TYPE | shippingChoice | Standard3 - 7 business days$7dates: Jun 08 - Jun 14 Two Day2 business days$15date: Jun 07 Overnight1 business day$20date: Jun 06 | Overnight | countryType_1-default
+CREDIT_CARD_TYPE | ccType | Card Type: |  | ccType_1-cc
+CREDIT_CARD_NUMBER | ccNumber | Card Number: |  | ccType_1-cc
+CREDIT_CARD_EXP_MONTH | expMonth | Expiration: | 1 | ccType_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | expYear | Expiration: | 2011 | ccType_1-cc
+CREDIT_CARD_VERIFICATION_CODE | ccSecCode | Security Code: CLOSEVisa, Mastercard & Discover:The security code is a 3-digit number found on the back of the card near the signature strip.American Express:The security code is a 4-digit number found on the front right side of the card. |  | ccType_1-cc
+UNKNOWN_TYPE | birthMonthBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. |  | ccType_1-default
+UNKNOWN_TYPE | birthDayBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. |  | ccType_1-default
+UNKNOWN_TYPE | birthYearBMLField | Birthday: CLOSEWe need your birthday for the Bill Me Later® credit check process. |  | ccType_1-default
+UNKNOWN_TYPE | SSN | Last 4 digits of your social security #: CLOSEWe need the last 4 digits of your SSN for the Bill Me Later® credit check process. If you do not have an SSN, you can still pay by Credit Card or PayPal. |  | ccType_1-default
+UNKNOWN_TYPE | agree | I agree to have the Terms and Conditions presented electronically. | yes | ccType_1-default
+UNKNOWN_TYPE | agreeTs | I agree to the Bill Me Later® Terms and Conditions. | yes | ccType_1-default
+ADDRESS_HOME_COUNTRY | countryType | Country Type | usa | ccType_1-default
+UNKNOWN_TYPE | billSameAsShip | My Billing & Shipping addresses are the same | yes | ccType_1-default
+ADDRESS_HOME_COUNTRY | country | Country, APO/FPO | US | country_1-default
+NAME_FIRST | firstName | First Name |  | country_1-default
+NAME_LAST | lastName | Last Name |  | country_1-default
+ADDRESS_HOME_LINE1 | address1 | Address |  | country_1-default
+ADDRESS_HOME_LINE2 | address2 | Address |  | country_1-default
+ADDRESS_HOME_CITY | city | City |  | country_1-default
+ADDRESS_HOME_STATE | state | State |  | country_1-default
+ADDRESS_HOME_ZIP | zip | Zip |  | country_1-default
+EMAIL_ADDRESS | email | Email CLOSEWe use this to send you an order confirmation and tracking info once your order ships. |  | country_1-default
+EMAIL_ADDRESS | confirmEmail | Re-Type Email |  | country_1-default
+PHONE_HOME_WHOLE_NUMBER | billingPhone | Billing Phone Number CLOSEThis must match the phone number on your credit card statement. Don't worry... we never share your number with anyone. |  | country_1-default
+UNKNOWN_TYPE | accessPassNumber | My AEREWARD$ # CLOSEAEREWARD$ NumberEnter the number found on the back of your AEREWARD$ card to earn rewards for your purchase.Learn More about AEREWARD$ |  | country_1-default
+UNKNOWN_TYPE | aeRewardsSignUp | Sign up now and receive 25 points  just for signing up! Learn More | true | country_1-default
+UNKNOWN_TYPE | aeAccount | Create my AE Account.CLOSECreate an AE Account to:Save Your Personal Info For Next TimeCheckout FasterTrack An Order Quicker Sign up now and receive 25 points just for signing up! Learn More | true | country_1-default
+UNKNOWN_TYPE | aeAccountPass | Password (6-15 Letters & Numbers) |  | country_1-default
+UNKNOWN_TYPE | aeAccountPassConfirm | Confirm Password |  | country_1-default
+UNKNOWN_TYPE | birthMonthBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. |  | country_1-default
+UNKNOWN_TYPE | birthDayBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. |  | country_1-default
+UNKNOWN_TYPE | birthYearBillAddField | Birthday: CLOSEWe'd love to wish you a happy birthday when it's time! However, you need to be 13 or older to create an account. |  | country_1-default
+UNKNOWN_TYPE | aeEmail | AE | on | country_1-default
+UNKNOWN_TYPE | aerieEmail | aerie | on | country_1-default
+UNKNOWN_TYPE | kidsEmail | 77kids | on | country_1-default
+UNKNOWN_TYPE | loyaltyTerms | I accept the Terms & Conditions |  | country_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/02_checkout_bedbathandbeyond.com.out b/chrome/test/data/autofill/heuristics/output/02_checkout_bedbathandbeyond.com.out
index 58d36317..08ee466 100644
--- a/chrome/test/data/autofill/heuristics/output/02_checkout_bedbathandbeyond.com.out
+++ b/chrome/test/data/autofill/heuristics/output/02_checkout_bedbathandbeyond.com.out
@@ -1,38 +1,38 @@
-NAME_FIRST | first_nm | *First name | 
-NAME_MIDDLE | mid_nm | Middle name | 
-NAME_LAST | last_nm | *Last name | 
-COMPANY_NAME | company | Company name | 
-ADDRESS_HOME_LINE1 | addr1 | *Address 1 | 
-ADDRESS_HOME_LINE2 | addr2 | Address 2 | 
-ADDRESS_HOME_CITY | city | *City | 
-ADDRESS_HOME_STATE | addr_state | *State | 
-ADDRESS_HOME_ZIP | zip | *Zip Code | 
-PHONE_HOME_CITY_CODE | day_phone_part1 | *Day phone | 
-PHONE_HOME_NUMBER | day_phone_part2 | *Day phone | 
-PHONE_HOME_NUMBER | day_phone_part3 | *Day phone | 
-PHONE_HOME_CITY_CODE | eve_phone_part1 | Evening phone | 
-PHONE_HOME_NUMBER | eve_phone_part2 | Evening phone | 
-PHONE_HOME_NUMBER | eve_phone_part3 | Evening phone | 
-PHONE_HOME_CITY_CODE | mob_phone_part1 | Mobile phone | 
-PHONE_HOME_NUMBER | mob_phone_part2 | Mobile phone | 
-PHONE_HOME_NUMBER | mob_phone_part3 | Mobile phone | 
-EMAIL_ADDRESS | email_addr | *Email | 
-EMAIL_ADDRESS | retype_email_addr | *Re-type email | 
-UNKNOWN_TYPE | promo_email_flag | Receive information on special offers and new arrivals at Bed Bath & Beyond. | Y
-UNKNOWN_TYPE | mobile_offers_opt_in | Bed Bath & Beyond may deliver mobile offers and promotions via text message in the future. Check the box if you would like to receive these mobile offers and promotions on your mobile phone. View our Privacy policy. Message & data rates may apply. | Y
-UNKNOWN_TYPE | shipping_options | Shipping | B
-NAME_FIRST | ship_first_nm | *First name | 
-NAME_MIDDLE | ship_mid_nm | Middle name | 
-NAME_LAST | ship_last_nm | *Last name | 
-COMPANY_NAME | ship_company | Company name | 
-ADDRESS_HOME_LINE1 | ship_addr1 | *Address 1 (No P.O. Boxes) | 
-ADDRESS_HOME_LINE2 | ship_addr2 | Address 2 | 
-ADDRESS_HOME_CITY | ship_city | *City | 
-ADDRESS_HOME_STATE | ship_addr_state | *State | 
-ADDRESS_HOME_ZIP | ship_zip | *Zip Code | 
-PHONE_HOME_CITY_CODE | ship_day_phone_part1 | *Day phone | 
-PHONE_HOME_NUMBER | ship_day_phone_part2 | *Day phone | 
-PHONE_HOME_NUMBER | ship_day_phone_part3 | *Day phone | 
-PHONE_HOME_CITY_CODE | ship_eve_phone_part1 | Evening phone | 
-PHONE_HOME_NUMBER | ship_eve_phone_part2 | Evening phone | 
-PHONE_HOME_NUMBER | ship_eve_phone_part3 | Evening phone | 
+NAME_FIRST | first_nm | *First name |  | first_nm_1-default
+NAME_MIDDLE | mid_nm | Middle name |  | first_nm_1-default
+NAME_LAST | last_nm | *Last name |  | first_nm_1-default
+COMPANY_NAME | company | Company name |  | first_nm_1-default
+ADDRESS_HOME_LINE1 | addr1 | *Address 1 |  | first_nm_1-default
+ADDRESS_HOME_LINE2 | addr2 | Address 2 |  | first_nm_1-default
+ADDRESS_HOME_CITY | city | *City |  | first_nm_1-default
+ADDRESS_HOME_STATE | addr_state | *State |  | first_nm_1-default
+ADDRESS_HOME_ZIP | zip | *Zip Code |  | first_nm_1-default
+PHONE_HOME_CITY_CODE | day_phone_part1 | *Day phone |  | first_nm_1-default
+PHONE_HOME_NUMBER | day_phone_part2 | *Day phone |  | first_nm_1-default
+PHONE_HOME_NUMBER | day_phone_part3 | *Day phone |  | first_nm_1-default
+PHONE_HOME_CITY_CODE | eve_phone_part1 | Evening phone |  | first_nm_1-default
+PHONE_HOME_NUMBER | eve_phone_part2 | Evening phone |  | first_nm_1-default
+PHONE_HOME_NUMBER | eve_phone_part3 | Evening phone |  | first_nm_1-default
+PHONE_HOME_CITY_CODE | mob_phone_part1 | Mobile phone |  | first_nm_1-default
+PHONE_HOME_NUMBER | mob_phone_part2 | Mobile phone |  | first_nm_1-default
+PHONE_HOME_NUMBER | mob_phone_part3 | Mobile phone |  | first_nm_1-default
+EMAIL_ADDRESS | email_addr | *Email |  | first_nm_1-default
+EMAIL_ADDRESS | retype_email_addr | *Re-type email |  | first_nm_1-default
+UNKNOWN_TYPE | promo_email_flag | Receive information on special offers and new arrivals at Bed Bath & Beyond. | Y | first_nm_1-default
+UNKNOWN_TYPE | mobile_offers_opt_in | Bed Bath & Beyond may deliver mobile offers and promotions via text message in the future. Check the box if you would like to receive these mobile offers and promotions on your mobile phone. View our Privacy policy. Message & data rates may apply. | Y | first_nm_1-default
+UNKNOWN_TYPE | shipping_options | Shipping | B | first_nm_1-default
+NAME_FIRST | ship_first_nm | *First name |  | ship_first_nm_1-default
+NAME_MIDDLE | ship_mid_nm | Middle name |  | ship_first_nm_1-default
+NAME_LAST | ship_last_nm | *Last name |  | ship_first_nm_1-default
+COMPANY_NAME | ship_company | Company name |  | ship_first_nm_1-default
+ADDRESS_HOME_LINE1 | ship_addr1 | *Address 1 (No P.O. Boxes) |  | ship_first_nm_1-default
+ADDRESS_HOME_LINE2 | ship_addr2 | Address 2 |  | ship_first_nm_1-default
+ADDRESS_HOME_CITY | ship_city | *City |  | ship_first_nm_1-default
+ADDRESS_HOME_STATE | ship_addr_state | *State |  | ship_first_nm_1-default
+ADDRESS_HOME_ZIP | ship_zip | *Zip Code |  | ship_first_nm_1-default
+PHONE_HOME_CITY_CODE | ship_day_phone_part1 | *Day phone |  | ship_first_nm_1-default
+PHONE_HOME_NUMBER | ship_day_phone_part2 | *Day phone |  | ship_first_nm_1-default
+PHONE_HOME_NUMBER | ship_day_phone_part3 | *Day phone |  | ship_first_nm_1-default
+PHONE_HOME_CITY_CODE | ship_eve_phone_part1 | Evening phone |  | ship_first_nm_1-default
+PHONE_HOME_NUMBER | ship_eve_phone_part2 | Evening phone |  | ship_first_nm_1-default
+PHONE_HOME_NUMBER | ship_eve_phone_part3 | Evening phone |  | ship_first_nm_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/02_checkout_cafepress.com.out b/chrome/test/data/autofill/heuristics/output/02_checkout_cafepress.com.out
index 19b193a..de71518 100644
--- a/chrome/test/data/autofill/heuristics/output/02_checkout_cafepress.com.out
+++ b/chrome/test/data/autofill/heuristics/output/02_checkout_cafepress.com.out
@@ -1,36 +1,36 @@
-NAME_FULL | BillName | Name on Account* | 
-ADDRESS_HOME_COUNTRY | BillCountry | Country* | UNITED STATES
-ADDRESS_HOME_LINE1 | BillStreet1 | Address * | 
-ADDRESS_HOME_LINE2 | BillStreet2 | Address * | 
-UNKNOWN_TYPE | ddlRedoClassification | Address * | 
-ADDRESS_HOME_CITY | BillCity | Town/City* | 
-ADDRESS_HOME_STATE | BillState | State/Province* | 
-UNKNOWN_TYPE | BillStateOther | State/Province* | 
-ADDRESS_HOME_ZIP | BillZip | Zip/Postal Code* | 
-PHONE_HOME_WHOLE_NUMBER | BillPhone | Phone Number* | 
-EMAIL_ADDRESS | BillEmail | Email Address* | 
-UNKNOWN_TYPE | cbStoreSpecial |  | on
-UNKNOWN_TYPE | ShipDestination |  | billaddress
-UNKNOWN_TYPE | ShipDestination | Ship to my billing address | shipaddress
-NAME_FULL | ShipName | Recipient Name* | 
-ADDRESS_HOME_COUNTRY | ShipCountry | Country* | UNITED STATES
-ADDRESS_HOME_LINE1 | ShipStreet1 | Address* | 
-ADDRESS_HOME_LINE2 | ShipStreet2 | Address* | 
-ADDRESS_HOME_CITY | ShipCity | Town/City* | 
-ADDRESS_HOME_STATE | ShipState | State/Province* | 
-UNKNOWN_TYPE | ShipStateOther | State/Province* | 
-ADDRESS_HOME_ZIP | ShipZip | Zip/Postal Code* | 
-UNKNOWN_TYPE | ShowGiftMsg | 2 Shipping Address | on
-ADDRESS_HOME_STREET_ADDRESS | GiftMessage | 2 Shipping Address | 
-UNKNOWN_TYPE | countdown | You have | 300
-UNKNOWN_TYPE | ApplyGiftWrap | 2 Shipping Address | on
-UNKNOWN_TYPE | txtCoupon | Apply Promo Code | 
-UNKNOWN_TYPE | PaymentMethod |  | PayByCafeCash
-UNKNOWN_TYPE | PaymentMethod |  | PayByGC
-UNKNOWN_TYPE | PaymentMethod |  | PayByCCGC
-UNKNOWN_TYPE | PaymentMethod |  | PayByCC
-CREDIT_CARD_NUMBER | txtCCAccount | Credit Card No.* | 
-CREDIT_CARD_EXP_MONTH | ccExp$MonthDrop | Expiration Date* | 06 (June)
-CREDIT_CARD_EXP_4_DIGIT_YEAR | ccExp$YearDrop | Expiration Date* | 2011
-UNKNOWN_TYPE | PaymentMethod | Expiration Date* | PayByCheck
-UNKNOWN_TYPE | PaymentMethod |  | PayByPayPal
+NAME_FULL | BillName | Name on Account* |  | BillName_1-default
+ADDRESS_HOME_COUNTRY | BillCountry | Country* | UNITED STATES | BillName_1-default
+ADDRESS_HOME_LINE1 | BillStreet1 | Address * |  | BillName_1-default
+ADDRESS_HOME_LINE2 | BillStreet2 | Address * |  | BillName_1-default
+UNKNOWN_TYPE | ddlRedoClassification | Address * |  | BillName_1-default
+ADDRESS_HOME_CITY | BillCity | Town/City* |  | BillName_1-default
+ADDRESS_HOME_STATE | BillState | State/Province* |  | BillName_1-default
+UNKNOWN_TYPE | BillStateOther | State/Province* |  | BillName_1-default
+ADDRESS_HOME_ZIP | BillZip | Zip/Postal Code* |  | BillName_1-default
+PHONE_HOME_WHOLE_NUMBER | BillPhone | Phone Number* |  | BillName_1-default
+EMAIL_ADDRESS | BillEmail | Email Address* |  | BillName_1-default
+UNKNOWN_TYPE | cbStoreSpecial |  | on | BillName_1-default
+UNKNOWN_TYPE | ShipDestination |  | billaddress | BillName_1-default
+UNKNOWN_TYPE | ShipDestination | Ship to my billing address | shipaddress | BillName_1-default
+NAME_FULL | ShipName | Recipient Name* |  | ShipName_1-default
+ADDRESS_HOME_COUNTRY | ShipCountry | Country* | UNITED STATES | ShipName_1-default
+ADDRESS_HOME_LINE1 | ShipStreet1 | Address* |  | ShipName_1-default
+ADDRESS_HOME_LINE2 | ShipStreet2 | Address* |  | ShipName_1-default
+ADDRESS_HOME_CITY | ShipCity | Town/City* |  | ShipName_1-default
+ADDRESS_HOME_STATE | ShipState | State/Province* |  | ShipName_1-default
+UNKNOWN_TYPE | ShipStateOther | State/Province* |  | ShipName_1-default
+ADDRESS_HOME_ZIP | ShipZip | Zip/Postal Code* |  | ShipName_1-default
+UNKNOWN_TYPE | ShowGiftMsg | 2 Shipping Address | on | ShipName_1-default
+ADDRESS_HOME_STREET_ADDRESS | GiftMessage | 2 Shipping Address |  | ShipName_1-default
+UNKNOWN_TYPE | countdown | You have | 300 | ShipName_1-default
+UNKNOWN_TYPE | ApplyGiftWrap | 2 Shipping Address | on | ShipName_1-default
+UNKNOWN_TYPE | txtCoupon | Apply Promo Code |  | ShipName_1-default
+UNKNOWN_TYPE | PaymentMethod |  | PayByCafeCash | ShipName_1-default
+UNKNOWN_TYPE | PaymentMethod |  | PayByGC | ShipName_1-default
+UNKNOWN_TYPE | PaymentMethod |  | PayByCCGC | ShipName_1-default
+UNKNOWN_TYPE | PaymentMethod |  | PayByCC | ShipName_1-default
+CREDIT_CARD_NUMBER | txtCCAccount | Credit Card No.* |  | ShipName_1-cc
+CREDIT_CARD_EXP_MONTH | ccExp$MonthDrop | Expiration Date* | 06 (June) | ShipName_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | ccExp$YearDrop | Expiration Date* | 2011 | ShipName_1-cc
+UNKNOWN_TYPE | PaymentMethod | Expiration Date* | PayByCheck | ShipName_1-default
+UNKNOWN_TYPE | PaymentMethod |  | PayByPayPal | ShipName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/03_checkout_cduniverse.com.out b/chrome/test/data/autofill/heuristics/output/03_checkout_cduniverse.com.out
index 7ad6946..3e63981 100644
--- a/chrome/test/data/autofill/heuristics/output/03_checkout_cduniverse.com.out
+++ b/chrome/test/data/autofill/heuristics/output/03_checkout_cduniverse.com.out
@@ -1,22 +1,22 @@
-NAME_FIRST | HT_First_Name | First Name | 
-NAME_LAST | HT_Last_Name | Last Name | 
-UNKNOWN_TYPE | HT_Password | Password | 
-UNKNOWN_TYPE | HT_Conf_Password | Re-enter Password | 
-EMAIL_ADDRESS | HT_email | Email | 
-ADDRESS_HOME_LINE1 | HT_Bill_Address1 | Address 1 | 
-ADDRESS_HOME_LINE2 | HT_Bill_Address2 | Address 2 | 
-ADDRESS_HOME_CITY | HT_Bill_City | City | 
-ADDRESS_HOME_STATE | HT_Bill_State | State/Province | 
-ADDRESS_HOME_ZIP | HT_Bill_Zip | Zip/Postal Code | 
-PHONE_HOME_WHOLE_NUMBER | HT_phone | Phone | 
-ADDRESS_HOME_COUNTRY | HT_Bill_Country | Country | USA
-NAME_FULL | HT_Ship_Name | Full Name | 
-ADDRESS_HOME_LINE1 | HT_Ship_Address1 | Address 1 | 
-ADDRESS_HOME_LINE2 | HT_Ship_Address2 | Address 2 | 
-ADDRESS_HOME_CITY | HT_Ship_City | City | 
-ADDRESS_HOME_STATE | HT_Ship_State | State/Province | 
-ADDRESS_HOME_ZIP | HT_Ship_Zip | Zip/Postal Code | 
-ADDRESS_HOME_COUNTRY | HT_Ship_Country | Country | 
-UNKNOWN_TYPE | HT_OK_to_email | Would it be OK if occasionally we notified you of special sales via email? | -1
-UNKNOWN_TYPE | HT_OK_to_email | Yes | 0
-UNKNOWN_TYPE | HT_PrefersHTML | Would it be OK if occasionally we notified you of special sales via email? | on
+NAME_FIRST | HT_First_Name | First Name |  | HT_First_Name_1-default
+NAME_LAST | HT_Last_Name | Last Name |  | HT_First_Name_1-default
+UNKNOWN_TYPE | HT_Password | Password |  | HT_First_Name_1-default
+UNKNOWN_TYPE | HT_Conf_Password | Re-enter Password |  | HT_First_Name_1-default
+EMAIL_ADDRESS | HT_email | Email |  | HT_First_Name_1-default
+ADDRESS_HOME_LINE1 | HT_Bill_Address1 | Address 1 |  | HT_First_Name_1-default
+ADDRESS_HOME_LINE2 | HT_Bill_Address2 | Address 2 |  | HT_First_Name_1-default
+ADDRESS_HOME_CITY | HT_Bill_City | City |  | HT_First_Name_1-default
+ADDRESS_HOME_STATE | HT_Bill_State | State/Province |  | HT_First_Name_1-default
+ADDRESS_HOME_ZIP | HT_Bill_Zip | Zip/Postal Code |  | HT_First_Name_1-default
+PHONE_HOME_WHOLE_NUMBER | HT_phone | Phone |  | HT_First_Name_1-default
+ADDRESS_HOME_COUNTRY | HT_Bill_Country | Country | USA | HT_First_Name_1-default
+NAME_FULL | HT_Ship_Name | Full Name |  | HT_First_Name_1-default
+ADDRESS_HOME_LINE1 | HT_Ship_Address1 | Address 1 |  | HT_Ship_Address1_1-default
+ADDRESS_HOME_LINE2 | HT_Ship_Address2 | Address 2 |  | HT_Ship_Address1_1-default
+ADDRESS_HOME_CITY | HT_Ship_City | City |  | HT_Ship_Address1_1-default
+ADDRESS_HOME_STATE | HT_Ship_State | State/Province |  | HT_Ship_Address1_1-default
+ADDRESS_HOME_ZIP | HT_Ship_Zip | Zip/Postal Code |  | HT_Ship_Address1_1-default
+ADDRESS_HOME_COUNTRY | HT_Ship_Country | Country |  | HT_Ship_Address1_1-default
+UNKNOWN_TYPE | HT_OK_to_email | Would it be OK if occasionally we notified you of special sales via email? | -1 | HT_Ship_Address1_1-default
+UNKNOWN_TYPE | HT_OK_to_email | Yes | 0 | HT_Ship_Address1_1-default
+UNKNOWN_TYPE | HT_PrefersHTML | Would it be OK if occasionally we notified you of special sales via email? | on | HT_Ship_Address1_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/03_checkout_crutchfield.com.out b/chrome/test/data/autofill/heuristics/output/03_checkout_crutchfield.com.out
index 3891038..486bf8cad 100644
--- a/chrome/test/data/autofill/heuristics/output/03_checkout_crutchfield.com.out
+++ b/chrome/test/data/autofill/heuristics/output/03_checkout_crutchfield.com.out
@@ -1,23 +1,23 @@
-NAME_FIRST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname | First Name | 
-NAME_MIDDLE_INITIAL | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$mi | M.I. | 
-NAME_LAST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$lastname | Last Name | 
-COMPANY_NAME | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$address2 | Company | 
-ADDRESS_HOME_LINE1 | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$address1 | Address | 
-ADDRESS_HOME_CITY | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$city | City | 
-ADDRESS_HOME_STATE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$state | State | Select Your State
-ADDRESS_HOME_ZIP | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$zip | Zip/Postal Code | 
-PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$billphone2 | Billing Phone | 
-EMAIL_ADDRESS | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$email2 | Email | 
-UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$chbox2 | Send me exclusive offers, deals and expert reviews. | on
-UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$same | Shipping Address | same
-UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$giftOrder | Shipping Address | gift
-NAME_FIRST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname | First Name | 
-NAME_MIDDLE_INITIAL | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingMi | M.I. | 
-NAME_LAST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingLastname | Last Name | 
-COMPANY_NAME | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingAddress2 | Company | 
-ADDRESS_HOME_LINE1 | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingAddress1 | Address | 
-ADDRESS_HOME_CITY | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingCity | City | 
-ADDRESS_HOME_STATE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingState | State | Select Your State
-ADDRESS_HOME_ZIP | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingZip | Zip/Postal Code | 
-PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingPhone | Shipping Phone | 
-UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$customerID | Customer # | 
+NAME_FIRST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname | First Name |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+NAME_MIDDLE_INITIAL | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$mi | M.I. |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+NAME_LAST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$lastname | Last Name |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+COMPANY_NAME | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$address2 | Company |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+ADDRESS_HOME_LINE1 | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$address1 | Address |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+ADDRESS_HOME_CITY | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$city | City |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+ADDRESS_HOME_STATE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$state | State | Select Your State | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+ADDRESS_HOME_ZIP | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$zip | Zip/Postal Code |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$billphone2 | Billing Phone |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+EMAIL_ADDRESS | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$email2 | Email |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$chbox2 | Send me exclusive offers, deals and expert reviews. | on | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$same | Shipping Address | same | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$giftOrder | Shipping Address | gift | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$firstname_1-default
+NAME_FIRST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname | First Name |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+NAME_MIDDLE_INITIAL | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingMi | M.I. |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+NAME_LAST | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingLastname | Last Name |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+COMPANY_NAME | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingAddress2 | Company |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+ADDRESS_HOME_LINE1 | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingAddress1 | Address |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+ADDRESS_HOME_CITY | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingCity | City |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+ADDRESS_HOME_STATE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingState | State | Select Your State | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+ADDRESS_HOME_ZIP | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingZip | Zip/Postal Code |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingPhone | Shipping Phone |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
+UNKNOWN_TYPE | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$customerID | Customer # |  | ctl00$ctl00$MainContentPlaceHolder$MainContentPlaceHolder$shippingFirstname_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/03_checkout_gamestop.com.out b/chrome/test/data/autofill/heuristics/output/03_checkout_gamestop.com.out
index c2d2d13..6fa59cc 100644
--- a/chrome/test/data/autofill/heuristics/output/03_checkout_gamestop.com.out
+++ b/chrome/test/data/autofill/heuristics/output/03_checkout_gamestop.com.out
@@ -1,23 +1,23 @@
-UNKNOWN_TYPE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext | DownloadsGames & Add-Ons Pre-OwnedGreat Values Learn How To Join | 
-NAME_FIRST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textFirstName | First Name: | 
-NAME_LAST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textLastName | Last Name: | 
-ADDRESS_HOME_LINE1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textAddressLine1 | Address 1: | 
-ADDRESS_HOME_LINE2 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textAddressLine2 | Address 2: (optional) | 
-ADDRESS_HOME_CITY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textCity | City: | 
-ADDRESS_HOME_STATE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$ddlState | State/Province: | -1
-ADDRESS_HOME_ZIP | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textZip | Zip/Postal: | 
-ADDRESS_HOME_COUNTRY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$ddlCountry | Country: | US
-PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textPhoneNumberDaytime | Phone Number: | 
-EMAIL_ADDRESS | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$txtEmailAddress | Purchaser's Email: | 
-EMAIL_ADDRESS | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$txtEmailAddressConfirm | Confirm Email: | 
-UNKNOWN_TYPE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$chkEmailOptIn | Confirm Email: | on
-NAME_FIRST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName | First Name: | 
-NAME_LAST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textLastName | Last Name: | 
-ADDRESS_HOME_LINE1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textAddressLine1 | Address 1: | 
-ADDRESS_HOME_LINE2 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textAddressLine2 | Address 2: (optional) | 
-ADDRESS_HOME_CITY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textCity | City: | 
-ADDRESS_HOME_STATE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$ddlState | State/Province: | -1
-ADDRESS_HOME_ZIP | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textZip | Zip/Postal: | 
-ADDRESS_HOME_COUNTRY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$ddlCountry | Country: | US
-PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textPhoneNumberDaytime | Phone Number: | 
-UNKNOWN_TYPE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$chkSameAsBillingAddress |  | on
+UNKNOWN_TYPE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext | DownloadsGames & Add-Ons Pre-OwnedGreat Values Learn How To Join |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+NAME_FIRST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textFirstName | First Name: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+NAME_LAST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textLastName | Last Name: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+ADDRESS_HOME_LINE1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textAddressLine1 | Address 1: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+ADDRESS_HOME_LINE2 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textAddressLine2 | Address 2: (optional) |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+ADDRESS_HOME_CITY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textCity | City: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+ADDRESS_HOME_STATE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$ddlState | State/Province: | -1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+ADDRESS_HOME_ZIP | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textZip | Zip/Postal: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+ADDRESS_HOME_COUNTRY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$ddlCountry | Country: | US | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$textPhoneNumberDaytime | Phone Number: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+EMAIL_ADDRESS | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$txtEmailAddress | Purchaser's Email: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+EMAIL_ADDRESS | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$txtEmailAddressConfirm | Confirm Email: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+UNKNOWN_TYPE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$AddressDetails$AddressDetails$chkEmailOptIn | Confirm Email: | on | ctl00$ctl00$ctl00$BaseContentPlaceHolder$cHeader$searchtext_1-default
+NAME_FIRST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName | First Name: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+NAME_LAST | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textLastName | Last Name: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+ADDRESS_HOME_LINE1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textAddressLine1 | Address 1: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+ADDRESS_HOME_LINE2 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textAddressLine2 | Address 2: (optional) |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+ADDRESS_HOME_CITY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textCity | City: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+ADDRESS_HOME_STATE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$ddlState | State/Province: | -1 | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+ADDRESS_HOME_ZIP | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textZip | Zip/Postal: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+ADDRESS_HOME_COUNTRY | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$ddlCountry | Country: | US | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+PHONE_HOME_WHOLE_NUMBER | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textPhoneNumberDaytime | Phone Number: |  | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
+UNKNOWN_TYPE | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$chkSameAsBillingAddress |  | on | ctl00$ctl00$ctl00$BaseContentPlaceHolder$mainContentPlaceHolder$MainContentPlaceHolder$aspShippingAddress$popAddressSelection$AddressDetails1$textFirstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/03_checkout_homedepot.com.out b/chrome/test/data/autofill/heuristics/output/03_checkout_homedepot.com.out
index 9472e14a..8f7b907 100644
--- a/chrome/test/data/autofill/heuristics/output/03_checkout_homedepot.com.out
+++ b/chrome/test/data/autofill/heuristics/output/03_checkout_homedepot.com.out
@@ -1,14 +1,14 @@
-NAME_FIRST | firstName_1 | *First Name: | 
-NAME_LAST | lastName_1 | *Last Name: | 
-ADDRESS_HOME_LINE1 | address1_1 | *Address 1: | 
-ADDRESS_HOME_LINE2 | address2_1 | Address 2: | 
-ADDRESS_HOME_CITY | city_1 | *City: | 
-ADDRESS_HOME_STATE | state_1 | *State: | 
-ADDRESS_HOME_ZIP | zipCode_1 | *ZIP Code: | 
-PHONE_HOME_CITY_CODE | fieldphone1_1 | *Phone Number on Record: | 
-PHONE_HOME_NUMBER | fieldphone2_1 | *Phone Number on Record: | 
-PHONE_HOME_NUMBER | fieldphone3_1 | *Phone Number on Record: | 
-PHONE_HOME_CITY_CODE | altfieldphone1_1 | Alternate Phone: | 
-PHONE_HOME_NUMBER | altfieldphone2_1 | Alternate Phone: | 
-PHONE_HOME_NUMBER | altfieldphone3_1 | Alternate Phone: | 
-UNKNOWN_TYPE | isBillingAddress_1 | Alternate Phone: | on
+NAME_FIRST | firstName_1 | *First Name: |  | firstName_1_1-default
+NAME_LAST | lastName_1 | *Last Name: |  | firstName_1_1-default
+ADDRESS_HOME_LINE1 | address1_1 | *Address 1: |  | firstName_1_1-default
+ADDRESS_HOME_LINE2 | address2_1 | Address 2: |  | firstName_1_1-default
+ADDRESS_HOME_CITY | city_1 | *City: |  | firstName_1_1-default
+ADDRESS_HOME_STATE | state_1 | *State: |  | firstName_1_1-default
+ADDRESS_HOME_ZIP | zipCode_1 | *ZIP Code: |  | firstName_1_1-default
+PHONE_HOME_CITY_CODE | fieldphone1_1 | *Phone Number on Record: |  | firstName_1_1-default
+PHONE_HOME_NUMBER | fieldphone2_1 | *Phone Number on Record: |  | firstName_1_1-default
+PHONE_HOME_NUMBER | fieldphone3_1 | *Phone Number on Record: |  | firstName_1_1-default
+PHONE_HOME_CITY_CODE | altfieldphone1_1 | Alternate Phone: |  | firstName_1_1-default
+PHONE_HOME_NUMBER | altfieldphone2_1 | Alternate Phone: |  | firstName_1_1-default
+PHONE_HOME_NUMBER | altfieldphone3_1 | Alternate Phone: |  | firstName_1_1-default
+UNKNOWN_TYPE | isBillingAddress_1 | Alternate Phone: | on | firstName_1_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/03_checkout_hsn.com.out b/chrome/test/data/autofill/heuristics/output/03_checkout_hsn.com.out
index e537346..de2cbe2 100644
--- a/chrome/test/data/autofill/heuristics/output/03_checkout_hsn.com.out
+++ b/chrome/test/data/autofill/heuristics/output/03_checkout_hsn.com.out
@@ -1,40 +1,40 @@
-UNKNOWN_TYPE | Body$BillingIsShippingCheckboxB | Enter billing information (as it appears on your statement) | on
-NAME_FIRST | Body$BillingAddress$_firstName | First Name | 
-NAME_LAST | Body$BillingAddress$_lastName | Last Name | 
-ADDRESS_HOME_LINE1 | Body$BillingAddress$_address1 | Address Line 1 | 
-ADDRESS_HOME_LINE2 | Body$BillingAddress$_address2 | Address Line 2(optional) | 
-ADDRESS_HOME_CITY | Body$BillingAddress$_city | City | 
-ADDRESS_HOME_STATE | Body$BillingAddress$_state | State |   
-ADDRESS_HOME_ZIP | Body$BillingAddress$_zipcode | Zip Code | 
-PHONE_HOME_WHOLE_NUMBER | Body$BillingAddress$_PrimaryPhone | Primary Phone | 
-UNKNOWN_TYPE | Body$BillingAddress$rdoPrimary |  | H
-UNKNOWN_TYPE | Body$BillingAddress$rdoPrimary |  | M
-UNKNOWN_TYPE | Body$BillingAddress$rdoPrimary |  | W
-PHONE_HOME_WHOLE_NUMBER | Body$BillingAddress$_Alt1Phone | Alternate Phone2(optional) | 
-UNKNOWN_TYPE | Body$BillingAddress$rdoAlt1 |  | H
-UNKNOWN_TYPE | Body$BillingAddress$rdoAlt1 |  | M
-UNKNOWN_TYPE | Body$BillingAddress$rdoAlt1 |  | W
-UNKNOWN_TYPE | Body$MobileAlerts | Enter billing information (as it appears on your statement) | on
-EMAIL_ADDRESS | Body$NewEmailAddress2 | Email Address | 
-UNKNOWN_TYPE | Body$WeeklyNewsletterSignup12 | Email Address | on
-UNKNOWN_TYPE | Body$TSNewsletterSignup2 | Email Address | on
-NAME_FIRST | Body$ShippingAddress$_firstName | First Name | 
-NAME_LAST | Body$ShippingAddress$_lastName | Last Name | 
-ADDRESS_HOME_LINE1 | Body$ShippingAddress$_address1 | Address Line 1 | 
-ADDRESS_HOME_LINE2 | Body$ShippingAddress$_address2 | Address Line 2(optional) | 
-ADDRESS_HOME_CITY | Body$ShippingAddress$_city | City | 
-ADDRESS_HOME_STATE | Body$ShippingAddress$_state | State |   
-ADDRESS_HOME_ZIP | Body$ShippingAddress$_zipcode | Zip Code | 
-PHONE_HOME_WHOLE_NUMBER | Body$ShippingAddress$_telephone | Phone Number | 
-UNKNOWN_TYPE | PaymentTypeSelection |  | 0
-CREDIT_CARD_NUMBER | Body$CCNumber | Card Number | 
-CREDIT_CARD_EXP_MONTH | Body$CCExpirationDateMonth | Expiration Date | 0
-CREDIT_CARD_EXP_4_DIGIT_YEAR | Body$CCExpirationDateYear | Expiration Date | 0
-CREDIT_CARD_NAME | Body$CCNameOnCard | Name on Card | 
-UNKNOWN_TYPE | IsDebitCard | Is this a Debit Card? | 1
-UNKNOWN_TYPE | IsDebitCard | Yes | 0
-UNKNOWN_TYPE | Body$SaveCC4Later | Is this a Debit Card? | on
-UNKNOWN_TYPE | PaymentTypeSelection | OR | 1
-UNKNOWN_TYPE | Body$NewPassword | Create Password (optional) | 
-UNKNOWN_TYPE | Body$RepeatNewPassword | Repeat Password (optional) | 
-UNKNOWN_TYPE | Body$NewPasswordHint | Password Hint (optional) | 
+UNKNOWN_TYPE | Body$BillingIsShippingCheckboxB | Enter billing information (as it appears on your statement) | on | Body$BillingIsShippingCheckboxB_1-default
+NAME_FIRST | Body$BillingAddress$_firstName | First Name |  | Body$BillingIsShippingCheckboxB_1-default
+NAME_LAST | Body$BillingAddress$_lastName | Last Name |  | Body$BillingIsShippingCheckboxB_1-default
+ADDRESS_HOME_LINE1 | Body$BillingAddress$_address1 | Address Line 1 |  | Body$BillingIsShippingCheckboxB_1-default
+ADDRESS_HOME_LINE2 | Body$BillingAddress$_address2 | Address Line 2(optional) |  | Body$BillingIsShippingCheckboxB_1-default
+ADDRESS_HOME_CITY | Body$BillingAddress$_city | City |  | Body$BillingIsShippingCheckboxB_1-default
+ADDRESS_HOME_STATE | Body$BillingAddress$_state | State |    | Body$BillingIsShippingCheckboxB_1-default
+ADDRESS_HOME_ZIP | Body$BillingAddress$_zipcode | Zip Code |  | Body$BillingIsShippingCheckboxB_1-default
+PHONE_HOME_WHOLE_NUMBER | Body$BillingAddress$_PrimaryPhone | Primary Phone |  | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$BillingAddress$rdoPrimary |  | H | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$BillingAddress$rdoPrimary |  | M | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$BillingAddress$rdoPrimary |  | W | Body$BillingIsShippingCheckboxB_1-default
+PHONE_HOME_WHOLE_NUMBER | Body$BillingAddress$_Alt1Phone | Alternate Phone2(optional) |  | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$BillingAddress$rdoAlt1 |  | H | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$BillingAddress$rdoAlt1 |  | M | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$BillingAddress$rdoAlt1 |  | W | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$MobileAlerts | Enter billing information (as it appears on your statement) | on | Body$BillingIsShippingCheckboxB_1-default
+EMAIL_ADDRESS | Body$NewEmailAddress2 | Email Address |  | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$WeeklyNewsletterSignup12 | Email Address | on | Body$BillingIsShippingCheckboxB_1-default
+UNKNOWN_TYPE | Body$TSNewsletterSignup2 | Email Address | on | Body$BillingIsShippingCheckboxB_1-default
+NAME_FIRST | Body$ShippingAddress$_firstName | First Name |  | Body$ShippingAddress$_firstName_1-default
+NAME_LAST | Body$ShippingAddress$_lastName | Last Name |  | Body$ShippingAddress$_firstName_1-default
+ADDRESS_HOME_LINE1 | Body$ShippingAddress$_address1 | Address Line 1 |  | Body$ShippingAddress$_firstName_1-default
+ADDRESS_HOME_LINE2 | Body$ShippingAddress$_address2 | Address Line 2(optional) |  | Body$ShippingAddress$_firstName_1-default
+ADDRESS_HOME_CITY | Body$ShippingAddress$_city | City |  | Body$ShippingAddress$_firstName_1-default
+ADDRESS_HOME_STATE | Body$ShippingAddress$_state | State |    | Body$ShippingAddress$_firstName_1-default
+ADDRESS_HOME_ZIP | Body$ShippingAddress$_zipcode | Zip Code |  | Body$ShippingAddress$_firstName_1-default
+PHONE_HOME_WHOLE_NUMBER | Body$ShippingAddress$_telephone | Phone Number |  | Body$ShippingAddress$_firstName_1-default
+UNKNOWN_TYPE | PaymentTypeSelection |  | 0 | Body$ShippingAddress$_firstName_1-default
+CREDIT_CARD_NUMBER | Body$CCNumber | Card Number |  | Body$ShippingAddress$_firstName_1-cc
+CREDIT_CARD_EXP_MONTH | Body$CCExpirationDateMonth | Expiration Date | 0 | Body$ShippingAddress$_firstName_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | Body$CCExpirationDateYear | Expiration Date | 0 | Body$ShippingAddress$_firstName_1-cc
+CREDIT_CARD_NAME | Body$CCNameOnCard | Name on Card |  | Body$ShippingAddress$_firstName_1-cc
+UNKNOWN_TYPE | IsDebitCard | Is this a Debit Card? | 1 | Body$ShippingAddress$_firstName_1-default
+UNKNOWN_TYPE | IsDebitCard | Yes | 0 | Body$ShippingAddress$_firstName_1-default
+UNKNOWN_TYPE | Body$SaveCC4Later | Is this a Debit Card? | on | Body$ShippingAddress$_firstName_1-default
+UNKNOWN_TYPE | PaymentTypeSelection | OR | 1 | Body$ShippingAddress$_firstName_1-default
+UNKNOWN_TYPE | Body$NewPassword | Create Password (optional) |  | Body$ShippingAddress$_firstName_1-default
+UNKNOWN_TYPE | Body$RepeatNewPassword | Repeat Password (optional) |  | Body$ShippingAddress$_firstName_1-default
+UNKNOWN_TYPE | Body$NewPasswordHint | Password Hint (optional) |  | Body$ShippingAddress$_firstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/04_checkout_ikea.com.out b/chrome/test/data/autofill/heuristics/output/04_checkout_ikea.com.out
index 69a1e5d..18518a1 100644
--- a/chrome/test/data/autofill/heuristics/output/04_checkout_ikea.com.out
+++ b/chrome/test/data/autofill/heuristics/output/04_checkout_ikea.com.out
@@ -1,15 +1,15 @@
-NAME_FIRST | firstName | First Name: | 
-NAME_LAST | lastName | Last Name: | 
-ADDRESS_HOME_LINE1 | address1 | Address 1: | 
-ADDRESS_HOME_LINE2 | address2 | Address 2: (Optional) | 
-ADDRESS_HOME_STATE | state | State: | 
-ADDRESS_HOME_ZIP | zipCode | Zip Code: | 
-ADDRESS_HOME_CITY | city | City: | 
-EMAIL_ADDRESS | email1 | Email: | 
-EMAIL_ADDRESS | email1retype | Re-type Email: | 
-PHONE_HOME_WHOLE_NUMBER | phone1 | Primary Tel Number: | 
-UNKNOWN_TYPE | phone1ext | Ext: (Optional) | 
-PHONE_HOME_WHOLE_NUMBER | phone2 | Alternative Number: | 
-UNKNOWN_TYPE | phone2ext | Ext: (Optional) | 
-UNKNOWN_TYPE | fax1 | Fax Number: (Optional) | 
-UNKNOWN_TYPE | fax1ext | Ext: (Optional) | 
+NAME_FIRST | firstName | First Name: |  | firstName_1-default
+NAME_LAST | lastName | Last Name: |  | firstName_1-default
+ADDRESS_HOME_LINE1 | address1 | Address 1: |  | firstName_1-default
+ADDRESS_HOME_LINE2 | address2 | Address 2: (Optional) |  | firstName_1-default
+ADDRESS_HOME_STATE | state | State: |  | firstName_1-default
+ADDRESS_HOME_ZIP | zipCode | Zip Code: |  | firstName_1-default
+ADDRESS_HOME_CITY | city | City: |  | firstName_1-default
+EMAIL_ADDRESS | email1 | Email: |  | firstName_1-default
+EMAIL_ADDRESS | email1retype | Re-type Email: |  | firstName_1-default
+PHONE_HOME_WHOLE_NUMBER | phone1 | Primary Tel Number: |  | firstName_1-default
+UNKNOWN_TYPE | phone1ext | Ext: (Optional) |  | firstName_1-default
+PHONE_HOME_WHOLE_NUMBER | phone2 | Alternative Number: |  | firstName_1-default
+UNKNOWN_TYPE | phone2ext | Ext: (Optional) |  | firstName_1-default
+UNKNOWN_TYPE | fax1 | Fax Number: (Optional) |  | firstName_1-default
+UNKNOWN_TYPE | fax1ext | Ext: (Optional) |  | firstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/04_checkout_jcrew.com.out b/chrome/test/data/autofill/heuristics/output/04_checkout_jcrew.com.out
index 8dd92382..d09bf68c 100644
--- a/chrome/test/data/autofill/heuristics/output/04_checkout_jcrew.com.out
+++ b/chrome/test/data/autofill/heuristics/output/04_checkout_jcrew.com.out
@@ -1,13 +1,13 @@
-ADDRESS_HOME_COUNTRY | ADDRESS<>country_cd | country * | US
-NAME_FIRST | ADDRESS<>firstName | first name * | 
-NAME_LAST | ADDRESS<>lastName | last name * | 
-COMPANY_NAME | ADDRESS<>address3 | company/care of | 
-ADDRESS_HOME_LINE1 | ADDRESS<>address1 | address line 1 * | 
-ADDRESS_HOME_LINE2 | ADDRESS<>address2 | address line 2 | 
-ADDRESS_HOME_CITY | ADDRESS<>city | city * | 
-ADDRESS_HOME_STATE | ADDRESS<>state_cd | state/province * | 
-ADDRESS_HOME_ZIP | ADDRESS<>postal | zip code * | 
-PHONE_HOME_WHOLE_NUMBER | ADDRESS<>phone | phone number (numbers only) * | 
-UNKNOWN_TYPE | anonPassword | create password | 
-UNKNOWN_TYPE | anonPasswordConfirm | confirm password | 
-UNKNOWN_TYPE | anonPasswordHint | create password hint | 
+ADDRESS_HOME_COUNTRY | ADDRESS<>country_cd | country * | US | ADDRESS<>country_cd_1-default
+NAME_FIRST | ADDRESS<>firstName | first name * |  | ADDRESS<>country_cd_1-default
+NAME_LAST | ADDRESS<>lastName | last name * |  | ADDRESS<>country_cd_1-default
+COMPANY_NAME | ADDRESS<>address3 | company/care of |  | ADDRESS<>country_cd_1-default
+ADDRESS_HOME_LINE1 | ADDRESS<>address1 | address line 1 * |  | ADDRESS<>country_cd_1-default
+ADDRESS_HOME_LINE2 | ADDRESS<>address2 | address line 2 |  | ADDRESS<>country_cd_1-default
+ADDRESS_HOME_CITY | ADDRESS<>city | city * |  | ADDRESS<>country_cd_1-default
+ADDRESS_HOME_STATE | ADDRESS<>state_cd | state/province * |  | ADDRESS<>country_cd_1-default
+ADDRESS_HOME_ZIP | ADDRESS<>postal | zip code * |  | ADDRESS<>country_cd_1-default
+PHONE_HOME_WHOLE_NUMBER | ADDRESS<>phone | phone number (numbers only) * |  | ADDRESS<>country_cd_1-default
+UNKNOWN_TYPE | anonPassword | create password |  | ADDRESS<>country_cd_1-default
+UNKNOWN_TYPE | anonPasswordConfirm | confirm password |  | ADDRESS<>country_cd_1-default
+UNKNOWN_TYPE | anonPasswordHint | create password hint |  | ADDRESS<>country_cd_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/04_checkout_jr.com.out b/chrome/test/data/autofill/heuristics/output/04_checkout_jr.com.out
index 8e53287..d0f8f9a 100644
--- a/chrome/test/data/autofill/heuristics/output/04_checkout_jr.com.out
+++ b/chrome/test/data/autofill/heuristics/output/04_checkout_jr.com.out
@@ -1,28 +1,28 @@
-NAME_FIRST | billingAddress.firstName | * | 
-NAME_LAST | billingAddress.lastName | * | 
-ADDRESS_HOME_LINE1 | billingAddress.address1 | * | 
-ADDRESS_HOME_LINE2 | billingAddress.address2 | Street address or P.O. box | 
-ADDRESS_HOME_CITY | billingAddress.city | * | 
-ADDRESS_HOME_STATE | billingAddress.stateCode | * | XX
-ADDRESS_HOME_ZIP | billingAddress.postalCode | * | 
-ADDRESS_HOME_COUNTRY | billingAddress.country | * | US
-PHONE_HOME_WHOLE_NUMBER | billingAddress.phoneNumber | * | 
-EMAIL_ADDRESS | customer.emailAddress | * | 
-UNKNOWN_TYPE | customer.optIn | Yes, send me J&R's promotional email newsletter. | on
-UNKNOWN_TYPE | storePickup | Pickup In-Store (Park Row, New York NY) | on
-UNKNOWN_TYPE | shipToBillingAddress | Ship to my billing address | on
-NAME_FIRST | shippingAddress.firstName | * | 
-NAME_LAST | shippingAddress.lastName | * | 
-ADDRESS_HOME_LINE1 | shippingAddress.address1 | * | 
-ADDRESS_HOME_LINE2 | shippingAddress.address2 | Street address or P.O. box | 
-ADDRESS_HOME_CITY | shippingAddress.city | * | 
-ADDRESS_HOME_STATE | shippingAddress.stateCode | * | XX
-ADDRESS_HOME_ZIP | shippingAddress.postalCode | * | 
-ADDRESS_HOME_COUNTRY | shippingAddress.country | * | US
-PHONE_HOME_WHOLE_NUMBER | shippingAddress.phoneNumber | * | 
-UNKNOWN_TYPE | customOrderHeader.internationalBilling | International Billing | 
-UNKNOWN_TYPE | customOrderHeader.salespersonNumber | Salesperson Number | 
-UNKNOWN_TYPE | customOrderHeader.giftFromName | Gift From | 
-UNKNOWN_TYPE | customOrderHeader.giftMessage | Gift Message | 
-EMAIL_ADDRESS | customOrderHeader.giftEmailAddress | Gift Email | 
-UNKNOWN_TYPE | customOrderHeader.giftHidePrices | Hide prices on the recipient's invoice and products on gift email. | on
+NAME_FIRST | billingAddress.firstName | * |  | billingAddress.firstName_1-default
+NAME_LAST | billingAddress.lastName | * |  | billingAddress.firstName_1-default
+ADDRESS_HOME_LINE1 | billingAddress.address1 | * |  | billingAddress.firstName_1-default
+ADDRESS_HOME_LINE2 | billingAddress.address2 | Street address or P.O. box |  | billingAddress.firstName_1-default
+ADDRESS_HOME_CITY | billingAddress.city | * |  | billingAddress.firstName_1-default
+ADDRESS_HOME_STATE | billingAddress.stateCode | * | XX | billingAddress.firstName_1-default
+ADDRESS_HOME_ZIP | billingAddress.postalCode | * |  | billingAddress.firstName_1-default
+ADDRESS_HOME_COUNTRY | billingAddress.country | * | US | billingAddress.firstName_1-default
+PHONE_HOME_WHOLE_NUMBER | billingAddress.phoneNumber | * |  | billingAddress.firstName_1-default
+EMAIL_ADDRESS | customer.emailAddress | * |  | billingAddress.firstName_1-default
+UNKNOWN_TYPE | customer.optIn | Yes, send me J&R's promotional email newsletter. | on | billingAddress.firstName_1-default
+UNKNOWN_TYPE | storePickup | Pickup In-Store (Park Row, New York NY) | on | billingAddress.firstName_1-default
+UNKNOWN_TYPE | shipToBillingAddress | Ship to my billing address | on | billingAddress.firstName_1-default
+NAME_FIRST | shippingAddress.firstName | * |  | shippingAddress.firstName_1-default
+NAME_LAST | shippingAddress.lastName | * |  | shippingAddress.firstName_1-default
+ADDRESS_HOME_LINE1 | shippingAddress.address1 | * |  | shippingAddress.firstName_1-default
+ADDRESS_HOME_LINE2 | shippingAddress.address2 | Street address or P.O. box |  | shippingAddress.firstName_1-default
+ADDRESS_HOME_CITY | shippingAddress.city | * |  | shippingAddress.firstName_1-default
+ADDRESS_HOME_STATE | shippingAddress.stateCode | * | XX | shippingAddress.firstName_1-default
+ADDRESS_HOME_ZIP | shippingAddress.postalCode | * |  | shippingAddress.firstName_1-default
+ADDRESS_HOME_COUNTRY | shippingAddress.country | * | US | shippingAddress.firstName_1-default
+PHONE_HOME_WHOLE_NUMBER | shippingAddress.phoneNumber | * |  | shippingAddress.firstName_1-default
+UNKNOWN_TYPE | customOrderHeader.internationalBilling | International Billing |  | shippingAddress.firstName_1-default
+UNKNOWN_TYPE | customOrderHeader.salespersonNumber | Salesperson Number |  | shippingAddress.firstName_1-default
+UNKNOWN_TYPE | customOrderHeader.giftFromName | Gift From |  | shippingAddress.firstName_1-default
+UNKNOWN_TYPE | customOrderHeader.giftMessage | Gift Message |  | shippingAddress.firstName_1-default
+EMAIL_ADDRESS | customOrderHeader.giftEmailAddress | Gift Email |  | shippingAddress.firstName_1-default
+UNKNOWN_TYPE | customOrderHeader.giftHidePrices | Hide prices on the recipient's invoice and products on gift email. | on | shippingAddress.firstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/04_checkout_kohls.com.out b/chrome/test/data/autofill/heuristics/output/04_checkout_kohls.com.out
index 226b6cd0..92c95f3 100644
--- a/chrome/test/data/autofill/heuristics/output/04_checkout_kohls.com.out
+++ b/chrome/test/data/autofill/heuristics/output/04_checkout_kohls.com.out
@@ -1,27 +1,27 @@
-NAME_FIRST | BILL_TO_ADDRESS<>firstName | First Name: | 
-NAME_LAST | BILL_TO_ADDRESS<>lastName | Last Name: | 
-ADDRESS_HOME_LINE1 | BILL_TO_ADDRESS<>address1 | Address: | 
-ADDRESS_HOME_LINE2 | BILL_TO_ADDRESS<>address2 | Apt. or Suite #: | 
-ADDRESS_HOME_CITY | BILL_TO_ADDRESS<>city | City: | 
-ADDRESS_HOME_STATE | BILL_TO_ADDRESS<>state_cd | State: | 
-ADDRESS_HOME_ZIP | BILL_TO_ADDRESS<>postal | ZIP Code: | 
-PHONE_HOME_CITY_CODE | BILL_PHONE<>areacode | Area Code | 
-PHONE_HOME_NUMBER | BILL_PHONE<>exchange | Exchange | 
-UNKNOWN_TYPE | BILL_PHONE<>extension | Extension | 
-PHONE_HOME_WHOLE_NUMBER | bill_phone | Contact Phone: | 
-EMAIL_ADDRESS | CURRENT_USER<>email | E-mail Address: | 
-UNKNOWN_TYPE | EMAIL_OPT_STATUS_ARRAY<>opt_status | Yes, sign me up for Sale Alerts. (optional) | true
-UNKNOWN_TYPE | indShipIsBillTo | Yes | true
-UNKNOWN_TYPE | indShipIsBillTo | Yes No | false
-NAME_FIRST | SHIP_TO_ADDRESS<>firstName | First Name: | 
-NAME_LAST | SHIP_TO_ADDRESS<>lastName | Last Name: | 
-ADDRESS_HOME_LINE1 | SHIP_TO_ADDRESS<>address1 | Address: | 
-ADDRESS_HOME_LINE2 | SHIP_TO_ADDRESS<>address2 | Apt. or Suite #: | 
-ADDRESS_HOME_CITY | SHIP_TO_ADDRESS<>city | City: | 
-ADDRESS_HOME_STATE | SHIP_TO_ADDRESS<>state_cd | State: | 
-ADDRESS_HOME_ZIP | SHIP_TO_ADDRESS<>postal | ZIP Code: | 
-PHONE_HOME_CITY_CODE | SHIP_PHONE<>areacode | Area Code | 
-PHONE_HOME_NUMBER | SHIP_PHONE<>exchange | Exchange | 
-UNKNOWN_TYPE | SHIP_PHONE<>extension | Extension | 
-PHONE_HOME_WHOLE_NUMBER | ship_phone | Contact Phone: | 
-UNKNOWN_TYPE | validShippingMethodList | Shipping Method: | 7037973929746575
+NAME_FIRST | BILL_TO_ADDRESS<>firstName | First Name: |  | BILL_TO_ADDRESS<>firstName_1-default
+NAME_LAST | BILL_TO_ADDRESS<>lastName | Last Name: |  | BILL_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_LINE1 | BILL_TO_ADDRESS<>address1 | Address: |  | BILL_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_LINE2 | BILL_TO_ADDRESS<>address2 | Apt. or Suite #: |  | BILL_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_CITY | BILL_TO_ADDRESS<>city | City: |  | BILL_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_STATE | BILL_TO_ADDRESS<>state_cd | State: |  | BILL_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_ZIP | BILL_TO_ADDRESS<>postal | ZIP Code: |  | BILL_TO_ADDRESS<>firstName_1-default
+PHONE_HOME_CITY_CODE | BILL_PHONE<>areacode | Area Code |  | BILL_TO_ADDRESS<>firstName_1-default
+PHONE_HOME_NUMBER | BILL_PHONE<>exchange | Exchange |  | BILL_TO_ADDRESS<>firstName_1-default
+UNKNOWN_TYPE | BILL_PHONE<>extension | Extension |  | BILL_TO_ADDRESS<>firstName_1-default
+PHONE_HOME_WHOLE_NUMBER | bill_phone | Contact Phone: |  | BILL_TO_ADDRESS<>firstName_1-default
+EMAIL_ADDRESS | CURRENT_USER<>email | E-mail Address: |  | BILL_TO_ADDRESS<>firstName_1-default
+UNKNOWN_TYPE | EMAIL_OPT_STATUS_ARRAY<>opt_status | Yes, sign me up for Sale Alerts. (optional) | true | BILL_TO_ADDRESS<>firstName_1-default
+UNKNOWN_TYPE | indShipIsBillTo | Yes | true | BILL_TO_ADDRESS<>firstName_1-default
+UNKNOWN_TYPE | indShipIsBillTo | Yes No | false | BILL_TO_ADDRESS<>firstName_1-default
+NAME_FIRST | SHIP_TO_ADDRESS<>firstName | First Name: |  | SHIP_TO_ADDRESS<>firstName_1-default
+NAME_LAST | SHIP_TO_ADDRESS<>lastName | Last Name: |  | SHIP_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_LINE1 | SHIP_TO_ADDRESS<>address1 | Address: |  | SHIP_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_LINE2 | SHIP_TO_ADDRESS<>address2 | Apt. or Suite #: |  | SHIP_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_CITY | SHIP_TO_ADDRESS<>city | City: |  | SHIP_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_STATE | SHIP_TO_ADDRESS<>state_cd | State: |  | SHIP_TO_ADDRESS<>firstName_1-default
+ADDRESS_HOME_ZIP | SHIP_TO_ADDRESS<>postal | ZIP Code: |  | SHIP_TO_ADDRESS<>firstName_1-default
+PHONE_HOME_CITY_CODE | SHIP_PHONE<>areacode | Area Code |  | SHIP_TO_ADDRESS<>firstName_1-default
+PHONE_HOME_NUMBER | SHIP_PHONE<>exchange | Exchange |  | SHIP_TO_ADDRESS<>firstName_1-default
+UNKNOWN_TYPE | SHIP_PHONE<>extension | Extension |  | SHIP_TO_ADDRESS<>firstName_1-default
+PHONE_HOME_WHOLE_NUMBER | ship_phone | Contact Phone: |  | SHIP_TO_ADDRESS<>firstName_1-default
+UNKNOWN_TYPE | validShippingMethodList | Shipping Method: | 7037973929746575 | SHIP_TO_ADDRESS<>firstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/04_checkout_lowes.com.out b/chrome/test/data/autofill/heuristics/output/04_checkout_lowes.com.out
index 3286920..3a55078 100644
--- a/chrome/test/data/autofill/heuristics/output/04_checkout_lowes.com.out
+++ b/chrome/test/data/autofill/heuristics/output/04_checkout_lowes.com.out
@@ -1,18 +1,18 @@
-ADDRESS_HOME_COUNTRY | country |  | USA
-ADDRESS_HOME_LINE1 | addressField2 | Address Name: | 
-NAME_FIRST | firstName | First Name: | 
-NAME_LAST | lastName | Last Name: | 
-COMPANY_NAME | addressField1 | Company Name: | 
-ADDRESS_HOME_LINE1 | address1 | Address Line 1: | 
-ADDRESS_HOME_LINE2 | address2 | Address Line 2: | 
-ADDRESS_HOME_CITY | city | City: | 
-ADDRESS_HOME_STATE | state | State: | 
-ADDRESS_HOME_ZIP | zipCode | ZIP Code: | 
-ADDRESS_HOME_CITY | taxGeoCode | Municipality: As an additional way to make sure you receive your order, we ask that you select the name of your municipality (city, town, borough, village, etc.) followed by the county, township, or parish in which you reside. | 
-UNKNOWN_TYPE | billingAddress | Please enter the phone number and e-mail address associated with this billing address.E-mail Address: Contact Phone: | on
-EMAIL_ADDRESS | email1 | E-mail Address: | 
-PHONE_HOME_CITY_CODE | billphone1 | Contact Phone: | 
-PHONE_HOME_NUMBER | billphone2 | Contact Phone: | 
-PHONE_HOME_NUMBER | billphone3 | Contact Phone: | 
-EMAIL_ADDRESS | selfAddress | Please enter the phone number and e-mail address associated with this billing address.E-mail Address: Contact Phone: | 0
-UNKNOWN_TYPE | save-address |  | on
+ADDRESS_HOME_COUNTRY | country |  | USA | country_1-default
+ADDRESS_HOME_LINE1 | addressField2 | Address Name: |  | country_1-default
+NAME_FIRST | firstName | First Name: |  | country_1-default
+NAME_LAST | lastName | Last Name: |  | country_1-default
+COMPANY_NAME | addressField1 | Company Name: |  | country_1-default
+ADDRESS_HOME_LINE1 | address1 | Address Line 1: |  | address1_1-default
+ADDRESS_HOME_LINE2 | address2 | Address Line 2: |  | address1_1-default
+ADDRESS_HOME_CITY | city | City: |  | address1_1-default
+ADDRESS_HOME_STATE | state | State: |  | address1_1-default
+ADDRESS_HOME_ZIP | zipCode | ZIP Code: |  | address1_1-default
+ADDRESS_HOME_CITY | taxGeoCode | Municipality: As an additional way to make sure you receive your order, we ask that you select the name of your municipality (city, town, borough, village, etc.) followed by the county, township, or parish in which you reside. |  | taxGeoCode_1-default
+UNKNOWN_TYPE | billingAddress | Please enter the phone number and e-mail address associated with this billing address.E-mail Address: Contact Phone: | on | taxGeoCode_1-default
+EMAIL_ADDRESS | email1 | E-mail Address: |  | taxGeoCode_1-default
+PHONE_HOME_CITY_CODE | billphone1 | Contact Phone: |  | taxGeoCode_1-default
+PHONE_HOME_NUMBER | billphone2 | Contact Phone: |  | taxGeoCode_1-default
+PHONE_HOME_NUMBER | billphone3 | Contact Phone: |  | taxGeoCode_1-default
+EMAIL_ADDRESS | selfAddress | Please enter the phone number and e-mail address associated with this billing address.E-mail Address: Contact Phone: | 0 | selfAddress_1-default
+UNKNOWN_TYPE | save-address |  | on | selfAddress_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/05_checkout_macys.com.out b/chrome/test/data/autofill/heuristics/output/05_checkout_macys.com.out
index af9430e..c4f7057 100644
--- a/chrome/test/data/autofill/heuristics/output/05_checkout_macys.com.out
+++ b/chrome/test/data/autofill/heuristics/output/05_checkout_macys.com.out
@@ -1,11 +1,11 @@
-UNKNOWN_TYPE | selectedShippingAddress | Add a new shipping address | newAddress
-NAME_FIRST | currentShipment.shipmentAddress.firstName | First Name: | 
-NAME_LAST | currentShipment.shipmentAddress.lastName | Last Name: | 
-ADDRESS_HOME_LINE1 | currentShipment.shipmentAddress.address1 | Address: | 
-ADDRESS_HOME_LINE2 | currentShipment.shipmentAddress.address2 | * Address: | 
-ADDRESS_HOME_CITY | currentShipment.shipmentAddress.city | City: | 
-ADDRESS_HOME_STATE | currentShipment.shipmentAddress.state | State: | NOSELECTION
-ADDRESS_HOME_ZIP | currentShipment.shipmentAddress.zipCode | ZipCode: | 
-PHONE_HOME_CITY_CODE | currentShipment.shipmentAddress.dayPhone.areaCode | Phone: | 
-PHONE_HOME_NUMBER | currentShipment.shipmentAddress.dayPhone.exchangeNbr | - | 
-PHONE_HOME_NUMBER | currentShipment.shipmentAddress.dayPhone.subscriberNbr | - | 
+UNKNOWN_TYPE | selectedShippingAddress | Add a new shipping address | newAddress | selectedShippingAddress_1-default
+NAME_FIRST | currentShipment.shipmentAddress.firstName | First Name: |  | selectedShippingAddress_1-default
+NAME_LAST | currentShipment.shipmentAddress.lastName | Last Name: |  | selectedShippingAddress_1-default
+ADDRESS_HOME_LINE1 | currentShipment.shipmentAddress.address1 | Address: |  | selectedShippingAddress_1-default
+ADDRESS_HOME_LINE2 | currentShipment.shipmentAddress.address2 | * Address: |  | selectedShippingAddress_1-default
+ADDRESS_HOME_CITY | currentShipment.shipmentAddress.city | City: |  | selectedShippingAddress_1-default
+ADDRESS_HOME_STATE | currentShipment.shipmentAddress.state | State: | NOSELECTION | selectedShippingAddress_1-default
+ADDRESS_HOME_ZIP | currentShipment.shipmentAddress.zipCode | ZipCode: |  | selectedShippingAddress_1-default
+PHONE_HOME_CITY_CODE | currentShipment.shipmentAddress.dayPhone.areaCode | Phone: |  | selectedShippingAddress_1-default
+PHONE_HOME_NUMBER | currentShipment.shipmentAddress.dayPhone.exchangeNbr | - |  | selectedShippingAddress_1-default
+PHONE_HOME_NUMBER | currentShipment.shipmentAddress.dayPhone.subscriberNbr | - |  | selectedShippingAddress_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/05_checkout_nordstrom.com.out b/chrome/test/data/autofill/heuristics/output/05_checkout_nordstrom.com.out
index 34583c30..4592aba 100644
--- a/chrome/test/data/autofill/heuristics/output/05_checkout_nordstrom.com.out
+++ b/chrome/test/data/autofill/heuristics/output/05_checkout_nordstrom.com.out
@@ -1,23 +1,23 @@
-EMAIL_ADDRESS | ctl00$mainContentPlaceHolder$emailAddress | E-mail Address | 
-EMAIL_ADDRESS | ctl00$mainContentPlaceHolder$emailAddressConfirm | Confirm E-mail | 
-PHONE_HOME_WHOLE_NUMBER | ctl00$mainContentPlaceHolder$phoneNumber | Phone Number | 
-NAME_FIRST | ctl00$mainContentPlaceHolder$billingAddressForm$firstName | First Name | 
-NAME_MIDDLE_INITIAL | ctl00$mainContentPlaceHolder$billingAddressForm$middleInitial | M.I. | 
-NAME_LAST | ctl00$mainContentPlaceHolder$billingAddressForm$lastName | Last Name | 
-ADDRESS_HOME_LINE1 | ctl00$mainContentPlaceHolder$billingAddressForm$address1 | Address | 
-ADDRESS_HOME_LINE2 | ctl00$mainContentPlaceHolder$billingAddressForm$address2 | Address | 
-ADDRESS_HOME_CITY | ctl00$mainContentPlaceHolder$billingAddressForm$city | City | 
-ADDRESS_HOME_STATE | ctl00$mainContentPlaceHolder$billingAddressForm$stateProvince | State/Province | -1
-ADDRESS_HOME_ZIP | ctl00$mainContentPlaceHolder$billingAddressForm$zipCode | Zip/Postal Code | 
-ADDRESS_HOME_COUNTRY | ctl00$mainContentPlaceHolder$billingAddressForm$country | Country | 249
-UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$shippingSameAsBilling |  | on
-NAME_FIRST | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName | First Name | 
-NAME_MIDDLE_INITIAL | ctl00$mainContentPlaceHolder$shippingAddressForm$middleInitial | M.I. | 
-NAME_LAST | ctl00$mainContentPlaceHolder$shippingAddressForm$lastName | Last Name | 
-ADDRESS_HOME_LINE1 | ctl00$mainContentPlaceHolder$shippingAddressForm$address1 | Address | 
-ADDRESS_HOME_LINE2 | ctl00$mainContentPlaceHolder$shippingAddressForm$address2 | Address | 
-ADDRESS_HOME_CITY | ctl00$mainContentPlaceHolder$shippingAddressForm$city | City | 
-ADDRESS_HOME_STATE | ctl00$mainContentPlaceHolder$shippingAddressForm$stateProvince | State/Province | -1
-ADDRESS_HOME_ZIP | ctl00$mainContentPlaceHolder$shippingAddressForm$zipCode | Zip/Postal Code | 
-UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$registrationPassword | Password | 
-UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$registrationPasswordConfirm | Confirm Password | 
+EMAIL_ADDRESS | ctl00$mainContentPlaceHolder$emailAddress | E-mail Address |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+EMAIL_ADDRESS | ctl00$mainContentPlaceHolder$emailAddressConfirm | Confirm E-mail |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+PHONE_HOME_WHOLE_NUMBER | ctl00$mainContentPlaceHolder$phoneNumber | Phone Number |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+NAME_FIRST | ctl00$mainContentPlaceHolder$billingAddressForm$firstName | First Name |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+NAME_MIDDLE_INITIAL | ctl00$mainContentPlaceHolder$billingAddressForm$middleInitial | M.I. |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+NAME_LAST | ctl00$mainContentPlaceHolder$billingAddressForm$lastName | Last Name |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+ADDRESS_HOME_LINE1 | ctl00$mainContentPlaceHolder$billingAddressForm$address1 | Address |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+ADDRESS_HOME_LINE2 | ctl00$mainContentPlaceHolder$billingAddressForm$address2 | Address |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+ADDRESS_HOME_CITY | ctl00$mainContentPlaceHolder$billingAddressForm$city | City |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+ADDRESS_HOME_STATE | ctl00$mainContentPlaceHolder$billingAddressForm$stateProvince | State/Province | -1 | ctl00$mainContentPlaceHolder$emailAddress_1-default
+ADDRESS_HOME_ZIP | ctl00$mainContentPlaceHolder$billingAddressForm$zipCode | Zip/Postal Code |  | ctl00$mainContentPlaceHolder$emailAddress_1-default
+ADDRESS_HOME_COUNTRY | ctl00$mainContentPlaceHolder$billingAddressForm$country | Country | 249 | ctl00$mainContentPlaceHolder$emailAddress_1-default
+UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$shippingSameAsBilling |  | on | ctl00$mainContentPlaceHolder$emailAddress_1-default
+NAME_FIRST | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName | First Name |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+NAME_MIDDLE_INITIAL | ctl00$mainContentPlaceHolder$shippingAddressForm$middleInitial | M.I. |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+NAME_LAST | ctl00$mainContentPlaceHolder$shippingAddressForm$lastName | Last Name |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+ADDRESS_HOME_LINE1 | ctl00$mainContentPlaceHolder$shippingAddressForm$address1 | Address |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+ADDRESS_HOME_LINE2 | ctl00$mainContentPlaceHolder$shippingAddressForm$address2 | Address |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+ADDRESS_HOME_CITY | ctl00$mainContentPlaceHolder$shippingAddressForm$city | City |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+ADDRESS_HOME_STATE | ctl00$mainContentPlaceHolder$shippingAddressForm$stateProvince | State/Province | -1 | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+ADDRESS_HOME_ZIP | ctl00$mainContentPlaceHolder$shippingAddressForm$zipCode | Zip/Postal Code |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$registrationPassword | Password |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
+UNKNOWN_TYPE | ctl00$mainContentPlaceHolder$registrationPasswordConfirm | Confirm Password |  | ctl00$mainContentPlaceHolder$shippingAddressForm$firstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/05_checkout_officemax.com.out b/chrome/test/data/autofill/heuristics/output/05_checkout_officemax.com.out
index 5d460a1..bb0b7f6 100644
--- a/chrome/test/data/autofill/heuristics/output/05_checkout_officemax.com.out
+++ b/chrome/test/data/autofill/heuristics/output/05_checkout_officemax.com.out
@@ -1,14 +1,14 @@
-NAME_FIRST | fname | * First Name: | 
-NAME_LAST | lname | * Last Name: | 
-COMPANY_NAME | business | Business Name: | 
-ADDRESS_HOME_LINE1 | address | *Address line 1:(no P.O. Boxes) | 
-ADDRESS_HOME_LINE2 | address2 | Address Line 2: | 
-ADDRESS_HOME_CITY | city | *City: | 
-ADDRESS_HOME_STATE | /atg/commerce/order/purchase/ShippingGroupFormHandler.editValue.state | *State: | 
-ADDRESS_HOME_ZIP | zip | *Zip Code: | 
-PHONE_HOME_WHOLE_NUMBER | phone | *Phone number: | 
-EMAIL_ADDRESS | /atg/commerce/order/purchase/ShippingGroupFormHandler.emailAddress | *Email Address: | 
-EMAIL_ADDRESS | /atg/commerce/order/purchase/ShippingGroupFormHandler.confirmEmailAddress | *Confirm Email Address: | 
-UNKNOWN_TYPE | emailOptIn | Yes! Send me exclusive coupons and special online savings via OfficeMax email.OfficeMax is committed to safeguarding your privacy. Our Privacy Policy outlines how OfficeMax handles your information. | https://www.officemax.com:443/
-UNKNOWN_TYPE | /atg/commerce/order/purchase/ShippingGroupFormHandler.maxPerksNumber | MaxPerks® ID: < What is this? | 
-UNKNOWN_TYPE | TaxExemptID | Tax Exempt ID: < What is this? | 
+NAME_FIRST | fname | * First Name: |  | fname_1-default
+NAME_LAST | lname | * Last Name: |  | fname_1-default
+COMPANY_NAME | business | Business Name: |  | fname_1-default
+ADDRESS_HOME_LINE1 | address | *Address line 1:(no P.O. Boxes) |  | fname_1-default
+ADDRESS_HOME_LINE2 | address2 | Address Line 2: |  | fname_1-default
+ADDRESS_HOME_CITY | city | *City: |  | fname_1-default
+ADDRESS_HOME_STATE | /atg/commerce/order/purchase/ShippingGroupFormHandler.editValue.state | *State: |  | fname_1-default
+ADDRESS_HOME_ZIP | zip | *Zip Code: |  | fname_1-default
+PHONE_HOME_WHOLE_NUMBER | phone | *Phone number: |  | fname_1-default
+EMAIL_ADDRESS | /atg/commerce/order/purchase/ShippingGroupFormHandler.emailAddress | *Email Address: |  | fname_1-default
+EMAIL_ADDRESS | /atg/commerce/order/purchase/ShippingGroupFormHandler.confirmEmailAddress | *Confirm Email Address: |  | fname_1-default
+UNKNOWN_TYPE | emailOptIn | Yes! Send me exclusive coupons and special online savings via OfficeMax email.OfficeMax is committed to safeguarding your privacy. Our Privacy Policy outlines how OfficeMax handles your information. | https://www.officemax.com:443/ | fname_1-default
+UNKNOWN_TYPE | /atg/commerce/order/purchase/ShippingGroupFormHandler.maxPerksNumber | MaxPerks® ID: < What is this? |  | fname_1-default
+UNKNOWN_TYPE | TaxExemptID | Tax Exempt ID: < What is this? |  | fname_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/05_checkout_overstock.com.out b/chrome/test/data/autofill/heuristics/output/05_checkout_overstock.com.out
index fa4bf5bc..78e9692 100644
--- a/chrome/test/data/autofill/heuristics/output/05_checkout_overstock.com.out
+++ b/chrome/test/data/autofill/heuristics/output/05_checkout_overstock.com.out
@@ -1,49 +1,49 @@
-NAME_FIRST | BillingFirstName | First Name | David
-NAME_LAST | BillingLastName | Last Name | Yu
-ADDRESS_HOME_LINE1 | BillingAddress1 | Address Line 1 | 7540 Donegal Dr
-ADDRESS_HOME_LINE2 | BillingAddress2 | Address Line 2 | 
-ADDRESS_HOME_CITY | BillingCity | City | Cupertino
-ADDRESS_HOME_STATE | BillingState | State | CA
-ADDRESS_HOME_ZIP | BillingZipCode | Zip | 95014
-PHONE_HOME_WHOLE_NUMBER | BillingDaytimePhone | Day Phone | 4088737223
-PHONE_HOME_WHOLE_NUMBER | BillingEveningPhone | Evening Phone | 
-UNKNOWN_TYPE | checkbox2 | *Required Field | on
-UNKNOWN_TYPE | diffShip | *Required Field | on
-NAME_FIRST | ShippingFirstName | First Name | 
-NAME_LAST | ShippingLastName | Last Name | 
-ADDRESS_HOME_LINE1 | lineone | Address Line 1 | 7540 Donegal Dr
-ADDRESS_HOME_LINE2 | linetwo | Address Line 2 | 
-UNKNOWN_TYPE | ShippingAddressType | Address Type | H
-ADDRESS_HOME_CITY | city | City | Cupertino
-ADDRESS_HOME_STATE | state | State | CA
-ADDRESS_HOME_ZIP | zip | Zip | 95014
-UNKNOWN_TYPE | product6496917 | Black-plated Tungsten Carbide Comfort Fit Band (8 mm) Options: 10 1 | GROUND6496917
-UNKNOWN_TYPE | CC |  | CreditCardValue
-CREDIT_CARD_NUMBER | CC_number | Credit Card #: | 
-CREDIT_CARD_EXP_MONTH | exp_month | Expiration Date: | 0
-CREDIT_CARD_EXP_4_DIGIT_YEAR | exp_year | Expiration Date: | 
-UNKNOWN_TYPE | CC |  | PayPal
-UNKNOWN_TYPE | CC |  | bml
-UNKNOWN_TYPE | UsePromoCode | See Terms | on
-UNKNOWN_TYPE | PromoCode | See Terms | 
-UNKNOWN_TYPE | UseGiftCards | See Terms | on
-UNKNOWN_TYPE | GiftCardNumber0 | Gift Card 1: | 
-UNKNOWN_TYPE | PINNumber0 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber1 | Gift Card 2: | 
-UNKNOWN_TYPE | PINNumber1 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber2 | Gift Card 3: | 
-UNKNOWN_TYPE | PINNumber2 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber3 | Gift Card 4: | 
-UNKNOWN_TYPE | PINNumber3 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber4 | Gift Card 5: | 
-UNKNOWN_TYPE | PINNumber4 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber5 | Gift Card 6: | 
-UNKNOWN_TYPE | PINNumber5 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber6 | Gift Card 7: | 
-UNKNOWN_TYPE | PINNumber6 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber7 | Gift Card 8: | 
-UNKNOWN_TYPE | PINNumber7 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber8 | Gift Card 9: | 
-UNKNOWN_TYPE | PINNumber8 | PIN: | 
-UNKNOWN_TYPE | GiftCardNumber9 | Gift Card 10: | 
-UNKNOWN_TYPE | PINNumber9 | PIN: | 
+NAME_FIRST | BillingFirstName | First Name | David | BillingFirstName_1-default
+NAME_LAST | BillingLastName | Last Name | Yu | BillingFirstName_1-default
+ADDRESS_HOME_LINE1 | BillingAddress1 | Address Line 1 | 7540 Donegal Dr | BillingFirstName_1-default
+ADDRESS_HOME_LINE2 | BillingAddress2 | Address Line 2 |  | BillingFirstName_1-default
+ADDRESS_HOME_CITY | BillingCity | City | Cupertino | BillingFirstName_1-default
+ADDRESS_HOME_STATE | BillingState | State | CA | BillingFirstName_1-default
+ADDRESS_HOME_ZIP | BillingZipCode | Zip | 95014 | BillingFirstName_1-default
+PHONE_HOME_WHOLE_NUMBER | BillingDaytimePhone | Day Phone | 4088737223 | BillingFirstName_1-default
+PHONE_HOME_WHOLE_NUMBER | BillingEveningPhone | Evening Phone |  | BillingFirstName_1-default
+UNKNOWN_TYPE | checkbox2 | *Required Field | on | BillingFirstName_1-default
+UNKNOWN_TYPE | diffShip | *Required Field | on | BillingFirstName_1-default
+NAME_FIRST | ShippingFirstName | First Name |  | ShippingFirstName_1-default
+NAME_LAST | ShippingLastName | Last Name |  | ShippingFirstName_1-default
+ADDRESS_HOME_LINE1 | lineone | Address Line 1 | 7540 Donegal Dr | ShippingFirstName_1-default
+ADDRESS_HOME_LINE2 | linetwo | Address Line 2 |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | ShippingAddressType | Address Type | H | ShippingFirstName_1-default
+ADDRESS_HOME_CITY | city | City | Cupertino | ShippingFirstName_1-default
+ADDRESS_HOME_STATE | state | State | CA | ShippingFirstName_1-default
+ADDRESS_HOME_ZIP | zip | Zip | 95014 | ShippingFirstName_1-default
+UNKNOWN_TYPE | product6496917 | Black-plated Tungsten Carbide Comfort Fit Band (8 mm) Options: 10 1 | GROUND6496917 | ShippingFirstName_1-default
+UNKNOWN_TYPE | CC |  | CreditCardValue | ShippingFirstName_1-default
+CREDIT_CARD_NUMBER | CC_number | Credit Card #: |  | ShippingFirstName_1-cc
+CREDIT_CARD_EXP_MONTH | exp_month | Expiration Date: | 0 | ShippingFirstName_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | exp_year | Expiration Date: |  | ShippingFirstName_1-cc
+UNKNOWN_TYPE | CC |  | PayPal | ShippingFirstName_1-default
+UNKNOWN_TYPE | CC |  | bml | ShippingFirstName_1-default
+UNKNOWN_TYPE | UsePromoCode | See Terms | on | ShippingFirstName_1-default
+UNKNOWN_TYPE | PromoCode | See Terms |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | UseGiftCards | See Terms | on | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber0 | Gift Card 1: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber0 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber1 | Gift Card 2: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber1 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber2 | Gift Card 3: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber2 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber3 | Gift Card 4: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber3 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber4 | Gift Card 5: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber4 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber5 | Gift Card 6: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber5 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber6 | Gift Card 7: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber6 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber7 | Gift Card 8: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber7 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber8 | Gift Card 9: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber8 | PIN: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | GiftCardNumber9 | Gift Card 10: |  | ShippingFirstName_1-default
+UNKNOWN_TYPE | PINNumber9 | PIN: |  | ShippingFirstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/05_checkout_petco.com.out b/chrome/test/data/autofill/heuristics/output/05_checkout_petco.com.out
index 116ec69c..e1f6205 100644
--- a/chrome/test/data/autofill/heuristics/output/05_checkout_petco.com.out
+++ b/chrome/test/data/autofill/heuristics/output/05_checkout_petco.com.out
@@ -1,14 +1,14 @@
-NAME_FIRST | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName | First Name * | 
-NAME_LAST | ctl00$ctl00$cphBody$cphBody$txtSA_LastName | Last Name * | 
-ADDRESS_HOME_LINE1 | ctl00$ctl00$cphBody$cphBody$txtSA_Address1 | Address Line 1 * | 
-UNKNOWN_TYPE | ctl00$ctl00$cphBody$cphBody$cbSA_IsPOBox | P.O. Box | on
-ADDRESS_HOME_LINE2 | ctl00$ctl00$cphBody$cphBody$txtSA_Address2 | Address Line 2 | 
-ADDRESS_HOME_CITY | ctl00$ctl00$cphBody$cphBody$txtSA_City | City * | 
-ADDRESS_HOME_STATE | ctl00$ctl00$cphBody$cphBody$ddlSA_State | State * | 
-ADDRESS_HOME_ZIP | ctl00$ctl00$cphBody$cphBody$txtSA_Zip | ZIP Code * | 
-PHONE_HOME_CITY_CODE | ctl00$ctl00$cphBody$cphBody$txtSA_Phone1 | Phone Number * | 
-PHONE_HOME_NUMBER | ctl00$ctl00$cphBody$cphBody$txtSA_Phone2 | ZIP Code * | 
-PHONE_HOME_NUMBER | ctl00$ctl00$cphBody$cphBody$txtSA_Phone3 | ZIP Code * | 
-UNKNOWN_TYPE | ctl00$ctl00$cphBody$cphBody$txtSA_PhoneExt | Ext. | 
-UNKNOWN_TYPE | ctl00$ctl00$cphBody$cphBody$cbSA_MatchBilling | This is also my billing address | on
-UNKNOWN_TYPE | ctl00$ctl00$cphBody$cphBody$cbSA_EmailSignup | Send me newsletters with exclusive online discounts, special announcements and health and behavior tips for my pet. | on
+NAME_FIRST | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName | First Name * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+NAME_LAST | ctl00$ctl00$cphBody$cphBody$txtSA_LastName | Last Name * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+ADDRESS_HOME_LINE1 | ctl00$ctl00$cphBody$cphBody$txtSA_Address1 | Address Line 1 * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+UNKNOWN_TYPE | ctl00$ctl00$cphBody$cphBody$cbSA_IsPOBox | P.O. Box | on | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+ADDRESS_HOME_LINE2 | ctl00$ctl00$cphBody$cphBody$txtSA_Address2 | Address Line 2 |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+ADDRESS_HOME_CITY | ctl00$ctl00$cphBody$cphBody$txtSA_City | City * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+ADDRESS_HOME_STATE | ctl00$ctl00$cphBody$cphBody$ddlSA_State | State * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+ADDRESS_HOME_ZIP | ctl00$ctl00$cphBody$cphBody$txtSA_Zip | ZIP Code * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+PHONE_HOME_CITY_CODE | ctl00$ctl00$cphBody$cphBody$txtSA_Phone1 | Phone Number * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+PHONE_HOME_NUMBER | ctl00$ctl00$cphBody$cphBody$txtSA_Phone2 | ZIP Code * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+PHONE_HOME_NUMBER | ctl00$ctl00$cphBody$cphBody$txtSA_Phone3 | ZIP Code * |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+UNKNOWN_TYPE | ctl00$ctl00$cphBody$cphBody$txtSA_PhoneExt | Ext. |  | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+UNKNOWN_TYPE | ctl00$ctl00$cphBody$cphBody$cbSA_MatchBilling | This is also my billing address | on | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
+UNKNOWN_TYPE | ctl00$ctl00$cphBody$cphBody$cbSA_EmailSignup | Send me newsletters with exclusive online discounts, special announcements and health and behavior tips for my pet. | on | ctl00$ctl00$cphBody$cphBody$txtSA_FirstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/06_checkout_petsmart.com.out b/chrome/test/data/autofill/heuristics/output/06_checkout_petsmart.com.out
index 28241c7..7cf1b70 100644
--- a/chrome/test/data/autofill/heuristics/output/06_checkout_petsmart.com.out
+++ b/chrome/test/data/autofill/heuristics/output/06_checkout_petsmart.com.out
@@ -1,13 +1,13 @@
-ADDRESS_HOME_COUNTRY | billCountry | • Country: | US
-NAME_FIRST | billFname | • First Name: | 
-NAME_LAST | billLname | • Last Name: | 
-ADDRESS_HOME_LINE1 | billAddr1 | • Address: | 
-ADDRESS_HOME_LINE2 | billAddr2 | Apt / Suite | 
-ADDRESS_HOME_CITY | billCity | • City or APO/FPO: | 
-ADDRESS_HOME_STATE | billState | • State/Province: | 
-UNKNOWN_TYPE | altBillState | • Other State/Province: | 
-ADDRESS_HOME_ZIP | billZip | • Zip/Postal Code: | 
-PHONE_HOME_WHOLE_NUMBER | billPhone | • Telephone: | 
-EMAIL_ADDRESS | guestEmail | • Email Address: | 
-UNKNOWN_TYPE | shipOptions | Enter Addresses | useShip
-UNKNOWN_TYPE | shipOptions | Ship to the above billing address Ship to a different address | provideNew
+ADDRESS_HOME_COUNTRY | billCountry | • Country: | US | billCountry_1-default
+NAME_FIRST | billFname | • First Name: |  | billCountry_1-default
+NAME_LAST | billLname | • Last Name: |  | billCountry_1-default
+ADDRESS_HOME_LINE1 | billAddr1 | • Address: |  | billCountry_1-default
+ADDRESS_HOME_LINE2 | billAddr2 | Apt / Suite |  | billCountry_1-default
+ADDRESS_HOME_CITY | billCity | • City or APO/FPO: |  | billCountry_1-default
+ADDRESS_HOME_STATE | billState | • State/Province: |  | billCountry_1-default
+UNKNOWN_TYPE | altBillState | • Other State/Province: |  | billCountry_1-default
+ADDRESS_HOME_ZIP | billZip | • Zip/Postal Code: |  | billCountry_1-default
+PHONE_HOME_WHOLE_NUMBER | billPhone | • Telephone: |  | billCountry_1-default
+EMAIL_ADDRESS | guestEmail | • Email Address: |  | billCountry_1-default
+UNKNOWN_TYPE | shipOptions | Enter Addresses | useShip | billCountry_1-default
+UNKNOWN_TYPE | shipOptions | Ship to the above billing address Ship to a different address | provideNew | billCountry_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/06_checkout_qvc.com.out b/chrome/test/data/autofill/heuristics/output/06_checkout_qvc.com.out
index cffbd9b..fc52fe0 100644
--- a/chrome/test/data/autofill/heuristics/output/06_checkout_qvc.com.out
+++ b/chrome/test/data/autofill/heuristics/output/06_checkout_qvc.com.out
@@ -1,29 +1,29 @@
-EMAIL_ADDRESS | EmailAddress | * E-mail Address: | 
-EMAIL_ADDRESS | EmailAddressVerify | * Confirm E-mail Address: | 
-UNKNOWN_TYPE | Pin | * PIN: | 
-UNKNOWN_TYPE | PinVerify | * Verify Your PIN: | 
-UNKNOWN_TYPE | Prefix | * Title: | 06
-NAME_FIRST | BilltoFirstName | * First Name: | 
-NAME_LAST | BilltoLastName | * Last Name: | 
-ADDRESS_HOME_LINE1 | BilltoAddress1 | * Address Line 1: | 
-ADDRESS_HOME_LINE2 | BilltoAddress2 | Address Line 2: | 
-ADDRESS_HOME_CITY | BilltoCity | City: | 
-ADDRESS_HOME_STATE | BilltoState | State/Province: | AL
-ADDRESS_HOME_ZIP | BilltoZipCode | * ZIP/Postal Code: | 
-ADDRESS_HOME_COUNTRY | BilltoCountry | * Country: | US
-PHONE_HOME_CITY_CODE | BilltoHpArea | * Home Phone: | 
-PHONE_HOME_NUMBER | BilltoHpExchange | * Home Phone: | 
-UNKNOWN_TYPE | BilltoHpExt | * Home Phone: | 
-PHONE_HOME_CITY_CODE | BilltoWpArea | Work Phone: | 
-PHONE_HOME_NUMBER | BilltoWpExchange | Work Phone: | 
-UNKNOWN_TYPE | BilltoWpExt | Work Phone: | 
-UNKNOWN_TYPE | SameAsBilltoCheckbox | Same as Bill-To: | 1
-UNKNOWN_TYPE | ShiptoFirstName | * Name: | 
-ADDRESS_HOME_LINE1 | ShiptoAddress1 | * Address Line 1: | 
-ADDRESS_HOME_LINE2 | ShiptoAddress2 | Address Line 2: | 
-ADDRESS_HOME_CITY | ShiptoCity | City: | 
-ADDRESS_HOME_STATE | ShiptoState | State/Province: | AL
-ADDRESS_HOME_ZIP | ShiptoZipCode | * Postal Code: | 
-ADDRESS_HOME_COUNTRY | ShiptoCountry | * Country: | US
-UNKNOWN_TYPE | ShiptoRadiobutton | Use this address for: | ThisOrderOnly
-UNKNOWN_TYPE | ShiptoRadiobutton | This order only | PermanentShipto
+EMAIL_ADDRESS | EmailAddress | * E-mail Address: |  | EmailAddress_1-default
+EMAIL_ADDRESS | EmailAddressVerify | * Confirm E-mail Address: |  | EmailAddress_1-default
+UNKNOWN_TYPE | Pin | * PIN: |  | EmailAddress_1-default
+UNKNOWN_TYPE | PinVerify | * Verify Your PIN: |  | EmailAddress_1-default
+UNKNOWN_TYPE | Prefix | * Title: | 06 | EmailAddress_1-default
+NAME_FIRST | BilltoFirstName | * First Name: |  | EmailAddress_1-default
+NAME_LAST | BilltoLastName | * Last Name: |  | EmailAddress_1-default
+ADDRESS_HOME_LINE1 | BilltoAddress1 | * Address Line 1: |  | EmailAddress_1-default
+ADDRESS_HOME_LINE2 | BilltoAddress2 | Address Line 2: |  | EmailAddress_1-default
+ADDRESS_HOME_CITY | BilltoCity | City: |  | EmailAddress_1-default
+ADDRESS_HOME_STATE | BilltoState | State/Province: | AL | EmailAddress_1-default
+ADDRESS_HOME_ZIP | BilltoZipCode | * ZIP/Postal Code: |  | EmailAddress_1-default
+ADDRESS_HOME_COUNTRY | BilltoCountry | * Country: | US | EmailAddress_1-default
+PHONE_HOME_CITY_CODE | BilltoHpArea | * Home Phone: |  | EmailAddress_1-default
+PHONE_HOME_NUMBER | BilltoHpExchange | * Home Phone: |  | EmailAddress_1-default
+UNKNOWN_TYPE | BilltoHpExt | * Home Phone: |  | EmailAddress_1-default
+PHONE_HOME_CITY_CODE | BilltoWpArea | Work Phone: |  | EmailAddress_1-default
+PHONE_HOME_NUMBER | BilltoWpExchange | Work Phone: |  | EmailAddress_1-default
+UNKNOWN_TYPE | BilltoWpExt | Work Phone: |  | EmailAddress_1-default
+UNKNOWN_TYPE | SameAsBilltoCheckbox | Same as Bill-To: | 1 | EmailAddress_1-default
+UNKNOWN_TYPE | ShiptoFirstName | * Name: |  | EmailAddress_1-default
+ADDRESS_HOME_LINE1 | ShiptoAddress1 | * Address Line 1: |  | ShiptoAddress1_1-default
+ADDRESS_HOME_LINE2 | ShiptoAddress2 | Address Line 2: |  | ShiptoAddress1_1-default
+ADDRESS_HOME_CITY | ShiptoCity | City: |  | ShiptoAddress1_1-default
+ADDRESS_HOME_STATE | ShiptoState | State/Province: | AL | ShiptoAddress1_1-default
+ADDRESS_HOME_ZIP | ShiptoZipCode | * Postal Code: |  | ShiptoAddress1_1-default
+ADDRESS_HOME_COUNTRY | ShiptoCountry | * Country: | US | ShiptoAddress1_1-default
+UNKNOWN_TYPE | ShiptoRadiobutton | Use this address for: | ThisOrderOnly | ShiptoAddress1_1-default
+UNKNOWN_TYPE | ShiptoRadiobutton | This order only | PermanentShipto | ShiptoAddress1_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/06_checkout_sears.com.out b/chrome/test/data/autofill/heuristics/output/06_checkout_sears.com.out
index 5fe6242..07cdcee6 100644
--- a/chrome/test/data/autofill/heuristics/output/06_checkout_sears.com.out
+++ b/chrome/test/data/autofill/heuristics/output/06_checkout_sears.com.out
@@ -1,24 +1,24 @@
-EMAIL_ADDRESS | address_email | Email* | ne00_99@yahoo.com
-NAME_FIRST | shipping_firstName | First Name* | 
-NAME_LAST | shipping_lastName | Last Name* | 
-UNKNOWN_TYPE | shipping_country | First Name* | US
-ADDRESS_HOME_LINE1 | shipping_address1 | Street Address Line 1* | 
-ADDRESS_HOME_LINE2 | shipping_address2 | Street Address Line 2 | 
-ADDRESS_HOME_CITY | shipping_city | City* | 
-ADDRESS_HOME_STATE | shipping_state | State* | AL
-ADDRESS_HOME_ZIP | shipping_zipCode | ZIP Code* | 
-PHONE_HOME_WHOLE_NUMBER | shipping_day1 | Phone Number* | 
-UNKNOWN_TYPE | shipping_ext1 | Ext. | 
-ADDRESS_HOME_STATE | shipping_county | County | UNKNOWN
-UNKNOWN_TYPE | billingAddressCheckBox | Same as Delivery/Shipping Address | on
-NAME_FIRST | firstName | First Name* | 
-NAME_LAST | lastName | Last Name* | 
-UNKNOWN_TYPE | country | First Name* | US
-ADDRESS_HOME_LINE1 | address1 | Street Address Line 1* | 
-ADDRESS_HOME_LINE2 | address2 | Street Address Line 2 | 
-ADDRESS_HOME_CITY | city | City* | 
-ADDRESS_HOME_STATE | state | State* State* | AL
-ADDRESS_HOME_ZIP | zipCode | ZIP Code* ZIP Code* | 
-PHONE_HOME_WHOLE_NUMBER | day1 | Phone Number* | 
-UNKNOWN_TYPE | ext1 | Ext. | 
-ADDRESS_HOME_STATE | county | County County | UNKNOWN
+EMAIL_ADDRESS | address_email | Email* | ne00_99@yahoo.com | address_email_1-default
+NAME_FIRST | shipping_firstName | First Name* |  | address_email_1-default
+NAME_LAST | shipping_lastName | Last Name* |  | address_email_1-default
+UNKNOWN_TYPE | shipping_country | First Name* | US | address_email_1-default
+ADDRESS_HOME_LINE1 | shipping_address1 | Street Address Line 1* |  | address_email_1-default
+ADDRESS_HOME_LINE2 | shipping_address2 | Street Address Line 2 |  | address_email_1-default
+ADDRESS_HOME_CITY | shipping_city | City* |  | address_email_1-default
+ADDRESS_HOME_STATE | shipping_state | State* | AL | address_email_1-default
+ADDRESS_HOME_ZIP | shipping_zipCode | ZIP Code* |  | address_email_1-default
+PHONE_HOME_WHOLE_NUMBER | shipping_day1 | Phone Number* |  | address_email_1-default
+UNKNOWN_TYPE | shipping_ext1 | Ext. |  | address_email_1-default
+ADDRESS_HOME_STATE | shipping_county | County | UNKNOWN | shipping_county_1-default
+UNKNOWN_TYPE | billingAddressCheckBox | Same as Delivery/Shipping Address | on | shipping_county_1-default
+NAME_FIRST | firstName | First Name* |  | shipping_county_1-default
+NAME_LAST | lastName | Last Name* |  | shipping_county_1-default
+UNKNOWN_TYPE | country | First Name* | US | shipping_county_1-default
+ADDRESS_HOME_LINE1 | address1 | Street Address Line 1* |  | shipping_county_1-default
+ADDRESS_HOME_LINE2 | address2 | Street Address Line 2 |  | shipping_county_1-default
+ADDRESS_HOME_CITY | city | City* |  | shipping_county_1-default
+ADDRESS_HOME_STATE | state | State* State* | AL | state_1-default
+ADDRESS_HOME_ZIP | zipCode | ZIP Code* ZIP Code* |  | state_1-default
+PHONE_HOME_WHOLE_NUMBER | day1 | Phone Number* |  | state_1-default
+UNKNOWN_TYPE | ext1 | Ext. |  | state_1-default
+ADDRESS_HOME_STATE | county | County County | UNKNOWN | county_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/06_checkout_target.com.out b/chrome/test/data/autofill/heuristics/output/06_checkout_target.com.out
index 50ac7cd..dcf59482 100644
--- a/chrome/test/data/autofill/heuristics/output/06_checkout_target.com.out
+++ b/chrome/test/data/autofill/heuristics/output/06_checkout_target.com.out
@@ -1,10 +1,10 @@
-NAME_FULL | name | Full Name*: | 
-ADDRESS_HOME_LINE1 | address1 | Address 1*: | 
-ADDRESS_HOME_LINE2 | address2 | Address 2 (optional): | 
-ADDRESS_HOME_CITY | city | City*: | 
-ADDRESS_HOME_STATE | state | State*: | 
-ADDRESS_HOME_ZIP | zip | Zip Code*: | 
-PHONE_HOME_WHOLE_NUMBER | voice | Phone Number*: | 
-UNKNOWN_TYPE | order.188:217866256151.ShippingSpeed | (3-5 business days) | std-us
-UNKNOWN_TYPE | order.188:217866256151.ShippingSpeed | (2 business days) | second
-UNKNOWN_TYPE | order.188:217866256151.ShippingSpeed | Standard Shipping Two-Day Shipping One-Day Shipping | next
+NAME_FULL | name | Full Name*: |  | name_1-default
+ADDRESS_HOME_LINE1 | address1 | Address 1*: |  | name_1-default
+ADDRESS_HOME_LINE2 | address2 | Address 2 (optional): |  | name_1-default
+ADDRESS_HOME_CITY | city | City*: |  | name_1-default
+ADDRESS_HOME_STATE | state | State*: |  | name_1-default
+ADDRESS_HOME_ZIP | zip | Zip Code*: |  | name_1-default
+PHONE_HOME_WHOLE_NUMBER | voice | Phone Number*: |  | name_1-default
+UNKNOWN_TYPE | order.188:217866256151.ShippingSpeed | (3-5 business days) | std-us | name_1-default
+UNKNOWN_TYPE | order.188:217866256151.ShippingSpeed | (2 business days) | second | name_1-default
+UNKNOWN_TYPE | order.188:217866256151.ShippingSpeed | Standard Shipping Two-Day Shipping One-Day Shipping | next | name_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/06_checkout_urbanoutfitters.com.out b/chrome/test/data/autofill/heuristics/output/06_checkout_urbanoutfitters.com.out
index 1c59220..ac6ff1b8 100644
--- a/chrome/test/data/autofill/heuristics/output/06_checkout_urbanoutfitters.com.out
+++ b/chrome/test/data/autofill/heuristics/output/06_checkout_urbanoutfitters.com.out
@@ -1,33 +1,33 @@
-UNKNOWN_TYPE | shipto | Select a Saved Shipping Address | 
-NAME_FIRST | shippingFirstName |  | First Name
-NAME_LAST | shippingLastName |  | Last Name
-ADDRESS_HOME_LINE1 | shippingAddress |  | Street Address
-UNKNOWN_TYPE | shippingPobox |  | true
-ADDRESS_HOME_LINE2 | shippingAddress2 |  | Apt / Flr / Bldg (optional)
-ADDRESS_HOME_CITY | shippingCity |  | City
-ADDRESS_HOME_STATE | shippingStates |  | 
-ADDRESS_HOME_ZIP | shippingPostalCode |  | Postal Code
-ADDRESS_HOME_COUNTRY | shippingCountries |  | 
-PHONE_HOME_WHOLE_NUMBER | shippingPhone |  | Phone
-PHONE_HOME_WHOLE_NUMBER | altShippingPhone |  | Alternate Phone (optional)
-UNKNOWN_TYPE | billingIsShipping |  | true
-UNKNOWN_TYPE | defaultShipping |  | true
-NAME_FIRST | billingFirstName |  | First Name
-NAME_LAST | billingLastName |  | Last Name
-ADDRESS_HOME_LINE1 | billingAddress |  | Street Address
-UNKNOWN_TYPE | billingPobox |  | true
-ADDRESS_HOME_LINE2 | billingAddress2 |  | Apt / Flr / Bldg (optional)
-ADDRESS_HOME_CITY | billingCity |  | City
-ADDRESS_HOME_STATE | billingStates |  | 
-ADDRESS_HOME_ZIP | billingPostalCode |  | Postal Code
-ADDRESS_HOME_COUNTRY | billingCountries |  | 
-PHONE_HOME_WHOLE_NUMBER | billingPhone |  | Phone
-PHONE_HOME_WHOLE_NUMBER | altBillingPhone |  | Alternate Phone (optional)
-UNKNOWN_TYPE | defaultBilling |  | true
-UNKNOWN_TYPE | savedCreditCard |  | 
-CREDIT_CARD_TYPE | payment_cardtype |  | 
-CREDIT_CARD_NUMBER | payment_acctnum |  | Card Number (no spaces or dashes)
-CREDIT_CARD_EXP_MONTH | expmonth |  | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | expyear |  | 
-CREDIT_CARD_VERIFICATION_CODE | payment_cidnew |  | CID / Security Code
-UNKNOWN_TYPE | makeDefaultCreditCard |  | true
+UNKNOWN_TYPE | shipto | Select a Saved Shipping Address |  | shipto_1-default
+NAME_FIRST | shippingFirstName |  | First Name | shipto_1-default
+NAME_LAST | shippingLastName |  | Last Name | shipto_1-default
+ADDRESS_HOME_LINE1 | shippingAddress |  | Street Address | shipto_1-default
+UNKNOWN_TYPE | shippingPobox |  | true | shipto_1-default
+ADDRESS_HOME_LINE2 | shippingAddress2 |  | Apt / Flr / Bldg (optional) | shipto_1-default
+ADDRESS_HOME_CITY | shippingCity |  | City | shipto_1-default
+ADDRESS_HOME_STATE | shippingStates |  |  | shipto_1-default
+ADDRESS_HOME_ZIP | shippingPostalCode |  | Postal Code | shipto_1-default
+ADDRESS_HOME_COUNTRY | shippingCountries |  |  | shipto_1-default
+PHONE_HOME_WHOLE_NUMBER | shippingPhone |  | Phone | shipto_1-default
+PHONE_HOME_WHOLE_NUMBER | altShippingPhone |  | Alternate Phone (optional) | shipto_1-default
+UNKNOWN_TYPE | billingIsShipping |  | true | shipto_1-default
+UNKNOWN_TYPE | defaultShipping |  | true | shipto_1-default
+NAME_FIRST | billingFirstName |  | First Name | billingFirstName_1-default
+NAME_LAST | billingLastName |  | Last Name | billingFirstName_1-default
+ADDRESS_HOME_LINE1 | billingAddress |  | Street Address | billingFirstName_1-default
+UNKNOWN_TYPE | billingPobox |  | true | billingFirstName_1-default
+ADDRESS_HOME_LINE2 | billingAddress2 |  | Apt / Flr / Bldg (optional) | billingFirstName_1-default
+ADDRESS_HOME_CITY | billingCity |  | City | billingFirstName_1-default
+ADDRESS_HOME_STATE | billingStates |  |  | billingFirstName_1-default
+ADDRESS_HOME_ZIP | billingPostalCode |  | Postal Code | billingFirstName_1-default
+ADDRESS_HOME_COUNTRY | billingCountries |  |  | billingFirstName_1-default
+PHONE_HOME_WHOLE_NUMBER | billingPhone |  | Phone | billingFirstName_1-default
+PHONE_HOME_WHOLE_NUMBER | altBillingPhone |  | Alternate Phone (optional) | billingFirstName_1-default
+UNKNOWN_TYPE | defaultBilling |  | true | billingFirstName_1-default
+UNKNOWN_TYPE | savedCreditCard |  |  | billingFirstName_1-default
+CREDIT_CARD_TYPE | payment_cardtype |  |  | billingFirstName_1-cc
+CREDIT_CARD_NUMBER | payment_acctnum |  | Card Number (no spaces or dashes) | billingFirstName_1-cc
+CREDIT_CARD_EXP_MONTH | expmonth |  |  | billingFirstName_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | expyear |  |  | billingFirstName_1-cc
+CREDIT_CARD_VERIFICATION_CODE | payment_cidnew |  | CID / Security Code | billingFirstName_1-cc
+UNKNOWN_TYPE | makeDefaultCreditCard |  | true | billingFirstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/07_checkout_vitacost.com.out b/chrome/test/data/autofill/heuristics/output/07_checkout_vitacost.com.out
index 5ac520f..3b74615 100644
--- a/chrome/test/data/autofill/heuristics/output/07_checkout_vitacost.com.out
+++ b/chrome/test/data/autofill/heuristics/output/07_checkout_vitacost.com.out
@@ -1,11 +1,11 @@
-UNKNOWN_TYPE | ucMasterFrame$ctl02$objAddForm$ddPrefix |  | 
-NAME_FIRST | ucMasterFrame$ctl02$objAddForm$txtFirstName | *First Name: | 
-NAME_LAST | ucMasterFrame$ctl02$objAddForm$txtLastName | *Last Name: | 
-COMPANY_NAME | ucMasterFrame$ctl02$objAddForm$txtCompany | Company: | 
-ADDRESS_HOME_LINE1 | ucMasterFrame$ctl02$objAddForm$txtAddress | *Address: | 
-ADDRESS_HOME_LINE2 | ucMasterFrame$ctl02$objAddForm$txtAddress2 | Apt., Suite, Unit: | 
-ADDRESS_HOME_CITY | ucMasterFrame$ctl02$objAddForm$txtCity | *City: | 
-ADDRESS_HOME_STATE | ucMasterFrame$ctl02$objAddForm$ddState | *State: | 
-ADDRESS_HOME_ZIP | ucMasterFrame$ctl02$objAddForm$txtZip | *Zip/Postal Code: | 
-ADDRESS_HOME_COUNTRY | ucMasterFrame$ctl02$objAddForm$ddCountry | Country: | 228
-PHONE_HOME_WHOLE_NUMBER | ucMasterFrame$ctl02$objAddForm$txtPhone | *Phone: | 
+UNKNOWN_TYPE | ucMasterFrame$ctl02$objAddForm$ddPrefix |  |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+NAME_FIRST | ucMasterFrame$ctl02$objAddForm$txtFirstName | *First Name: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+NAME_LAST | ucMasterFrame$ctl02$objAddForm$txtLastName | *Last Name: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+COMPANY_NAME | ucMasterFrame$ctl02$objAddForm$txtCompany | Company: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+ADDRESS_HOME_LINE1 | ucMasterFrame$ctl02$objAddForm$txtAddress | *Address: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+ADDRESS_HOME_LINE2 | ucMasterFrame$ctl02$objAddForm$txtAddress2 | Apt., Suite, Unit: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+ADDRESS_HOME_CITY | ucMasterFrame$ctl02$objAddForm$txtCity | *City: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+ADDRESS_HOME_STATE | ucMasterFrame$ctl02$objAddForm$ddState | *State: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+ADDRESS_HOME_ZIP | ucMasterFrame$ctl02$objAddForm$txtZip | *Zip/Postal Code: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+ADDRESS_HOME_COUNTRY | ucMasterFrame$ctl02$objAddForm$ddCountry | Country: | 228 | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
+PHONE_HOME_WHOLE_NUMBER | ucMasterFrame$ctl02$objAddForm$txtPhone | *Phone: |  | ucMasterFrame$ctl02$objAddForm$ddPrefix_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/07_checkout_williams-sonoma.com.out b/chrome/test/data/autofill/heuristics/output/07_checkout_williams-sonoma.com.out
index 796ea41b..be1e09b 100644
--- a/chrome/test/data/autofill/heuristics/output/07_checkout_williams-sonoma.com.out
+++ b/chrome/test/data/autofill/heuristics/output/07_checkout_williams-sonoma.com.out
@@ -1,13 +1,13 @@
-NAME_FULL | shipTos[0].address.fullName | Full Name* | 
-ADDRESS_HOME_LINE1 | shipTos[0].address.addrLine1 | Address* | 
-ADDRESS_HOME_LINE2 | shipTos[0].address.addrLine2 | Address Line 2 | 
-ADDRESS_HOME_CITY | shipTos[0].address.city | City* | 
-ADDRESS_HOME_STATE | shipTos[0].address.state | State* | 
-ADDRESS_HOME_ZIP | shipTos[0].address.zip | Zip* | 
-PHONE_HOME_WHOLE_NUMBER | shipTos[0].address.dayPhone | Daytime Phone* | 
-PHONE_HOME_WHOLE_NUMBER | shipTos[0].address.eveningPhone | Alternate Phone | 
-UNKNOWN_TYPE | shipTos[0].billingAddressUpdate | Yes, use this shipping address for my billing address. | on
-EMAIL_ADDRESS | shipTos[0].address.emailAddr | Email* | 
-EMAIL_ADDRESS | shipTos[0].confirmEmailAddr | Confirm Email* | 
-UNKNOWN_TYPE | shipTos[0].shipType |  | Standard
-UNKNOWN_TYPE | shipTos[0].shipType | Standard (5-7 business days) Rush (2-3 business days) | Rush
+NAME_FULL | shipTos[0].address.fullName | Full Name* |  | shipTos[0].address.fullName_1-default
+ADDRESS_HOME_LINE1 | shipTos[0].address.addrLine1 | Address* |  | shipTos[0].address.fullName_1-default
+ADDRESS_HOME_LINE2 | shipTos[0].address.addrLine2 | Address Line 2 |  | shipTos[0].address.fullName_1-default
+ADDRESS_HOME_CITY | shipTos[0].address.city | City* |  | shipTos[0].address.fullName_1-default
+ADDRESS_HOME_STATE | shipTos[0].address.state | State* |  | shipTos[0].address.fullName_1-default
+ADDRESS_HOME_ZIP | shipTos[0].address.zip | Zip* |  | shipTos[0].address.fullName_1-default
+PHONE_HOME_WHOLE_NUMBER | shipTos[0].address.dayPhone | Daytime Phone* |  | shipTos[0].address.fullName_1-default
+PHONE_HOME_WHOLE_NUMBER | shipTos[0].address.eveningPhone | Alternate Phone |  | shipTos[0].address.fullName_1-default
+UNKNOWN_TYPE | shipTos[0].billingAddressUpdate | Yes, use this shipping address for my billing address. | on | shipTos[0].address.fullName_1-default
+EMAIL_ADDRESS | shipTos[0].address.emailAddr | Email* |  | shipTos[0].address.fullName_1-default
+EMAIL_ADDRESS | shipTos[0].confirmEmailAddr | Confirm Email* |  | shipTos[0].address.fullName_1-default
+UNKNOWN_TYPE | shipTos[0].shipType |  | Standard | shipTos[0].address.fullName_1-default
+UNKNOWN_TYPE | shipTos[0].shipType | Standard (5-7 business days) Rush (2-3 business days) | Rush | shipTos[0].address.fullName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/08_register_adobe.com.out b/chrome/test/data/autofill/heuristics/output/08_register_adobe.com.out
index 89885f0..be78884c 100644
--- a/chrome/test/data/autofill/heuristics/output/08_register_adobe.com.out
+++ b/chrome/test/data/autofill/heuristics/output/08_register_adobe.com.out
@@ -1,8 +1,8 @@
-EMAIL_ADDRESS | adobeId | E-Mail AddressThis will be your Adobe ID | 
-NAME_FIRST | firstName | First Name | 
-NAME_LAST | lastName | Last Name | 
-ADDRESS_HOME_COUNTRY | countryCode | Country | 
-UNKNOWN_TYPE | subscribePass1 | PasswordMust be between 6-12 characters | 
-UNKNOWN_TYPE | subscribePass2 | Confirm Password | 
-UNKNOWN_TYPE | agreeToTou | I have read and agree to the and the | on
-UNKNOWN_TYPE | hostedOptIn | Yes! I would like to receive communications relating to Adobe, its products and services      including product releases, product upgrades, seminars, events, surveys, training and special offers,      and Adobe, and its agents may use data I have provided in accordance with the | on
+EMAIL_ADDRESS | adobeId | E-Mail AddressThis will be your Adobe ID |  | adobeId_1-default
+NAME_FIRST | firstName | First Name |  | adobeId_1-default
+NAME_LAST | lastName | Last Name |  | adobeId_1-default
+ADDRESS_HOME_COUNTRY | countryCode | Country |  | adobeId_1-default
+UNKNOWN_TYPE | subscribePass1 | PasswordMust be between 6-12 characters |  | adobeId_1-default
+UNKNOWN_TYPE | subscribePass2 | Confirm Password |  | adobeId_1-default
+UNKNOWN_TYPE | agreeToTou | I have read and agree to the and the | on | adobeId_1-default
+UNKNOWN_TYPE | hostedOptIn | Yes! I would like to receive communications relating to Adobe, its products and services      including product releases, product upgrades, seminars, events, surveys, training and special offers,      and Adobe, and its agents may use data I have provided in accordance with the | on | adobeId_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/08_register_amazon.com.out b/chrome/test/data/autofill/heuristics/output/08_register_amazon.com.out
index a0593d5..aa2c888c 100644
--- a/chrome/test/data/autofill/heuristics/output/08_register_amazon.com.out
+++ b/chrome/test/data/autofill/heuristics/output/08_register_amazon.com.out
@@ -1,7 +1,7 @@
-UNKNOWN_TYPE | action |  | new-user
-UNKNOWN_TYPE | action | Create a new account (Recommended for Business accounts) Use existing Amazon customer account | sign-in
-UNKNOWN_TYPE | userName | First and Last Name: | 
-EMAIL_ADDRESS | email | E-mail Address: | 
-EMAIL_ADDRESS | emailCheck | Re-type E-mail Address: | 
-UNKNOWN_TYPE | password | Password: | 
-UNKNOWN_TYPE | passwordCheck | Re-type Password: | 
+UNKNOWN_TYPE | action |  | new-user | action_1-default
+UNKNOWN_TYPE | action | Create a new account (Recommended for Business accounts) Use existing Amazon customer account | sign-in | action_1-default
+UNKNOWN_TYPE | userName | First and Last Name: |  | action_1-default
+EMAIL_ADDRESS | email | E-mail Address: |  | action_1-default
+EMAIL_ADDRESS | emailCheck | Re-type E-mail Address: |  | action_1-default
+UNKNOWN_TYPE | password | Password: |  | action_1-default
+UNKNOWN_TYPE | passwordCheck | Re-type Password: |  | action_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/08_register_aol.com.out b/chrome/test/data/autofill/heuristics/output/08_register_aol.com.out
index 4b6a6fc8..33f2600 100644
--- a/chrome/test/data/autofill/heuristics/output/08_register_aol.com.out
+++ b/chrome/test/data/autofill/heuristics/output/08_register_aol.com.out
@@ -1,16 +1,16 @@
-NAME_FIRST | {actionForm.firstName} | First Name | 
-NAME_LAST | {actionForm.lastName} | Last Name | 
-UNKNOWN_TYPE | {actionForm.desiredSN} | NEW! Pick a username: What's new? | 
-UNKNOWN_TYPE | {actionForm.password} | Password | 
-UNKNOWN_TYPE | verifyPasswordHint | Password | Retype password
-UNKNOWN_TYPE | {actionForm.verifyPassword} | Password | 
-UNKNOWN_TYPE | wlw-select_key:{actionForm.dobMonth} | Select Month | 
-UNKNOWN_TYPE | {actionForm.dobDay} | Select Month | Day (dd)
-UNKNOWN_TYPE | {actionForm.dobYear} | Select Month | Year (yyyy)
-UNKNOWN_TYPE | wlw-radio_button_group_key:{actionForm.gender} | Gender | Female
-UNKNOWN_TYPE | wlw-radio_button_group_key:{actionForm.gender} | Gender | Male
-ADDRESS_HOME_ZIP | {actionForm.zipCode} | Zip Code | 
-UNKNOWN_TYPE | wlw-select_key:{actionForm.acctSecurityQuestion} | Set a Security Question | 
-UNKNOWN_TYPE | {actionForm.acctSecurityAnswer} | Set a Security Question | Your Answer
-EMAIL_ADDRESS | {actionForm.altEMail} | Alternate Email(optional) | 
-UNKNOWN_TYPE | {actionForm.wordVerify} | Enter what you see above | 
+NAME_FIRST | {actionForm.firstName} | First Name |  | {actionForm.firstName}_1-default
+NAME_LAST | {actionForm.lastName} | Last Name |  | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | {actionForm.desiredSN} | NEW! Pick a username: What's new? |  | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | {actionForm.password} | Password |  | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | verifyPasswordHint | Password | Retype password | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | {actionForm.verifyPassword} | Password |  | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | wlw-select_key:{actionForm.dobMonth} | Select Month |  | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | {actionForm.dobDay} | Select Month | Day (dd) | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | {actionForm.dobYear} | Select Month | Year (yyyy) | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | wlw-radio_button_group_key:{actionForm.gender} | Gender | Female | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | wlw-radio_button_group_key:{actionForm.gender} | Gender | Male | {actionForm.firstName}_1-default
+ADDRESS_HOME_ZIP | {actionForm.zipCode} | Zip Code |  | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | wlw-select_key:{actionForm.acctSecurityQuestion} | Set a Security Question |  | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | {actionForm.acctSecurityAnswer} | Set a Security Question | Your Answer | {actionForm.firstName}_1-default
+EMAIL_ADDRESS | {actionForm.altEMail} | Alternate Email(optional) |  | {actionForm.firstName}_1-default
+UNKNOWN_TYPE | {actionForm.wordVerify} | Enter what you see above |  | {actionForm.firstName}_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/08_register_bestbuy.com.out b/chrome/test/data/autofill/heuristics/output/08_register_bestbuy.com.out
index 8e53e04..b5e6a877 100644
--- a/chrome/test/data/autofill/heuristics/output/08_register_bestbuy.com.out
+++ b/chrome/test/data/autofill/heuristics/output/08_register_bestbuy.com.out
@@ -1,9 +1,9 @@
-NAME_FIRST | TxtFirstName | *First Name | 
-NAME_MIDDLE_INITIAL | TxtMI | MI | 
-NAME_LAST | TxtLastName | *Last Name | 
-EMAIL_ADDRESS | TxtEmail | *E-Mail Address | 
-EMAIL_ADDRESS | TxtEmailConfirm | *Retype E-Mail Address | 
-UNKNOWN_TYPE | PwdPassword | *Password (6 to 30 characters. At least one number.) | 
-UNKNOWN_TYPE | PwdPasswordConfirm | *Retype Password (must match exactly) | 
-ADDRESS_HOME_ZIP | TxtPostalCode | *ZIP Code | 
-UNKNOWN_TYPE | TxtRzMembershipId | Enter 10-Digit Member ID (optional) | 
+NAME_FIRST | TxtFirstName | *First Name |  | TxtFirstName_1-default
+NAME_MIDDLE_INITIAL | TxtMI | MI |  | TxtFirstName_1-default
+NAME_LAST | TxtLastName | *Last Name |  | TxtFirstName_1-default
+EMAIL_ADDRESS | TxtEmail | *E-Mail Address |  | TxtFirstName_1-default
+EMAIL_ADDRESS | TxtEmailConfirm | *Retype E-Mail Address |  | TxtFirstName_1-default
+UNKNOWN_TYPE | PwdPassword | *Password (6 to 30 characters. At least one number.) |  | TxtFirstName_1-default
+UNKNOWN_TYPE | PwdPasswordConfirm | *Retype Password (must match exactly) |  | TxtFirstName_1-default
+ADDRESS_HOME_ZIP | TxtPostalCode | *ZIP Code |  | TxtFirstName_1-default
+UNKNOWN_TYPE | TxtRzMembershipId | Enter 10-Digit Member ID (optional) |  | TxtFirstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/08_register_continental.com.out b/chrome/test/data/autofill/heuristics/output/08_register_continental.com.out
index c21a015f..c3fb50f 100644
--- a/chrome/test/data/autofill/heuristics/output/08_register_continental.com.out
+++ b/chrome/test/data/autofill/heuristics/output/08_register_continental.com.out
@@ -1,44 +1,44 @@
-ADDRESS_HOME_STATE | ctl00$CustomerHeader$ddlCountries | CountryClose Please select your location or where you receive credit card billing  statements to see pricing in your local currency.Available Languages: | US
-UNKNOWN_TYPE | ctl00$CustomerHeader$rdlang | Available Languages: | en-us
-UNKNOWN_TYPE | ctl00$CustomerHeader$rdlang | Available Languages: | es
-UNKNOWN_TYPE | ctl00$CustomerHeader$rdlang | Available Languages: | rd3
-UNKNOWN_TYPE | ctl00$CustomerHeader$chkSave | Save this preference | on
-UNKNOWN_TYPE | ctl00$ContentInfo$Name$cboTitle$cboTitle | Title: | 
-NAME_FIRST | ctl00$ContentInfo$Name$FName$txtFName | First Name: | 
-NAME_MIDDLE_INITIAL | ctl00$ContentInfo$Name$MName$txtMName | Middle Initial (optional): | 
-NAME_LAST | ctl00$ContentInfo$Name$LName$txtLName | Last Name: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$Name$suffix$txtSuffix | Suffix (optional): | 
-UNKNOWN_TYPE | ctl00$ContentInfo$MemberAge$EnrollmentAge |  | rdoAdult
-UNKNOWN_TYPE | ctl00$ContentInfo$MemberAge$EnrollmentAge | This OnePass account is for an adult 18 years of age or older. This OnePass account is for a minor under the age of 18. | rdoMinor
-UNKNOWN_TYPE | ctl00$ContentInfo$BirthDate$txtDOB | Minor’s Date of Birth: | mm/dd/yyyy
-UNKNOWN_TYPE | ctl00$ContentInfo$AddressType$AddressType | Address Type: | rdoAddTypeHome
-UNKNOWN_TYPE | ctl00$ContentInfo$AddressType$AddressType | Home Business/Other | rdoAddTypeBusiness
-ADDRESS_HOME_LINE1 | ctl00$ContentInfo$Address$address1$txtAddress1 | Street Address: | 
-ADDRESS_HOME_LINE2 | ctl00$ContentInfo$Address$address2$txtAddress2 | Street Address: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$Address$address3$txtAddress2 | Street Address: | 
-ADDRESS_HOME_CITY | ctl00$ContentInfo$Address$city$txtCity | City/Town/Department: | 
-ADDRESS_HOME_STATE | ctl00$ContentInfo$Address$state$txtState | State/Province/Region/County: | 
-ADDRESS_HOME_ZIP | ctl00$ContentInfo$Address$zip$txtZip | ZIP/Postal Code: | 
-ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$Address$country$cboCountry | Country: | US
-PHONE_HOME_WHOLE_NUMBER | ctl00$ContentInfo$HomePhone$txtNumber$txtPhone | Home PhoneNumber: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$HomePhone$txtExt$txtPhoneExt | Ext./PIN (optional): | 
-ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry | Country: | US
-PHONE_HOME_WHOLE_NUMBER | ctl00$ContentInfo$BusinessPhone$txtNumber$txtPhone | Business/Other PhoneNumber: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$BusinessPhone$txtExt$txtPhoneExt | Ext./PIN (optional): | 
-ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry | Country: | US
-UNKNOWN_TYPE | ctl00$ContentInfo$HomeAirport$txtAirport | Home Airport (optional): | 
-EMAIL_ADDRESS | ctl00$ContentInfo$Email$txtEmail | E-mail Address: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$chkSubOpStatement |  | on
-UNKNOWN_TYPE | ctl00$ContentInfo$chkSubopnewsoffers |  | on
-UNKNOWN_TYPE | ctl00$ContentInfo$chkSubcocomspecials |  | on
-UNKNOWN_TYPE | ctl00$ContentInfo$chkSubtripnotes |  | on
-UNKNOWN_TYPE | ctl00$ContentInfo$NewPin$txtNewPin$txtNewPin | New PIN: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$NewPin$txtConfPin$txtConfPin | Re-type New PIN: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$username$txtUsername | Username: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$password$txtPassword | Password: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$passwordRetype$txtPassword | Re-type Password: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$PINPasswordReminder$PINReminder1$txtPINReminder | PIN Reminder: (cannot include any numbers) | 
-UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$Question$txtSecurity | Security Question: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$Answer$txtSecurity | Answer: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$AnswerReType$txtSecurity | Re-type Answer: | 
-UNKNOWN_TYPE | ctl00$ContentInfo$txtAgreement | Username and Password (optional)You have the option to create your own easy to remember username or password to sign in to continental.com.  The username can be used in place of your OnePass account number and a password can be used in place of your PIN. PIN/Password ReminderIf you forget your PIN or password, we will provide this reminder to access your account.PIN Reminder: (cannot include any numbers)Security Question | Agreement Between User And Continental AirlinesThis Web site is offered to the user conditioned on acceptance by the user ("User") without modification of the terms, conditions, and notices contained herein. By accessing and using this Web site, the User is deemed to have agreed to all such terms, conditions, and notices (the "Agreement").OnePass Terms and ConditionsContinental Airlines and all OnePass partners reserve the right to change any aspect of the OnePass program at any time within 30 days notice to active members. This right includes, but is not limited to, changes in partner affiliation, rules for earning mileage credit and mileage redemption levels. However, rules for use of travel rewards, cities served, flight schedules, limited seating or space availability, restricted travel dates and specific features of promotional offers are subject to change with or without notice at the discretion of Continental Airlines or the OnePass partner. Continental Airlines is not responsible for unilateral action
+ADDRESS_HOME_STATE | ctl00$CustomerHeader$ddlCountries | CountryClose Please select your location or where you receive credit card billing  statements to see pricing in your local currency.Available Languages: | US | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$CustomerHeader$rdlang | Available Languages: | en-us | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$CustomerHeader$rdlang | Available Languages: | es | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$CustomerHeader$rdlang | Available Languages: | rd3 | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$CustomerHeader$chkSave | Save this preference | on | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$Name$cboTitle$cboTitle | Title: |  | ctl00$CustomerHeader$ddlCountries_1-default
+NAME_FIRST | ctl00$ContentInfo$Name$FName$txtFName | First Name: |  | ctl00$CustomerHeader$ddlCountries_1-default
+NAME_MIDDLE_INITIAL | ctl00$ContentInfo$Name$MName$txtMName | Middle Initial (optional): |  | ctl00$CustomerHeader$ddlCountries_1-default
+NAME_LAST | ctl00$ContentInfo$Name$LName$txtLName | Last Name: |  | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$Name$suffix$txtSuffix | Suffix (optional): |  | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$MemberAge$EnrollmentAge |  | rdoAdult | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$MemberAge$EnrollmentAge | This OnePass account is for an adult 18 years of age or older. This OnePass account is for a minor under the age of 18. | rdoMinor | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$BirthDate$txtDOB | Minor’s Date of Birth: | mm/dd/yyyy | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$AddressType$AddressType | Address Type: | rdoAddTypeHome | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$AddressType$AddressType | Home Business/Other | rdoAddTypeBusiness | ctl00$CustomerHeader$ddlCountries_1-default
+ADDRESS_HOME_LINE1 | ctl00$ContentInfo$Address$address1$txtAddress1 | Street Address: |  | ctl00$CustomerHeader$ddlCountries_1-default
+ADDRESS_HOME_LINE2 | ctl00$ContentInfo$Address$address2$txtAddress2 | Street Address: |  | ctl00$CustomerHeader$ddlCountries_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$Address$address3$txtAddress2 | Street Address: |  | ctl00$CustomerHeader$ddlCountries_1-default
+ADDRESS_HOME_CITY | ctl00$ContentInfo$Address$city$txtCity | City/Town/Department: |  | ctl00$CustomerHeader$ddlCountries_1-default
+ADDRESS_HOME_STATE | ctl00$ContentInfo$Address$state$txtState | State/Province/Region/County: |  | ctl00$ContentInfo$Address$state$txtState_1-default
+ADDRESS_HOME_ZIP | ctl00$ContentInfo$Address$zip$txtZip | ZIP/Postal Code: |  | ctl00$ContentInfo$Address$state$txtState_1-default
+ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$Address$country$cboCountry | Country: | US | ctl00$ContentInfo$Address$state$txtState_1-default
+PHONE_HOME_WHOLE_NUMBER | ctl00$ContentInfo$HomePhone$txtNumber$txtPhone | Home PhoneNumber: |  | ctl00$ContentInfo$Address$state$txtState_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$HomePhone$txtExt$txtPhoneExt | Ext./PIN (optional): |  | ctl00$ContentInfo$Address$state$txtState_1-default
+ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry | Country: | US | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_1-default
+PHONE_HOME_WHOLE_NUMBER | ctl00$ContentInfo$BusinessPhone$txtNumber$txtPhone | Business/Other PhoneNumber: |  | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$BusinessPhone$txtExt$txtPhoneExt | Ext./PIN (optional): |  | ctl00$ContentInfo$HomePhone$cboCountry$cboCountry_1-default
+ADDRESS_HOME_COUNTRY | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry | Country: | US | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$HomeAirport$txtAirport | Home Airport (optional): |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+EMAIL_ADDRESS | ctl00$ContentInfo$Email$txtEmail | E-mail Address: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$chkSubOpStatement |  | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$chkSubopnewsoffers |  | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$chkSubcocomspecials |  | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$chkSubtripnotes |  | on | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$NewPin$txtNewPin$txtNewPin | New PIN: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$NewPin$txtConfPin$txtConfPin | Re-type New PIN: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$username$txtUsername | Username: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$password$txtPassword | Password: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$UsernamePassword$passwordRetype$txtPassword | Re-type Password: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$PINPasswordReminder$PINReminder1$txtPINReminder | PIN Reminder: (cannot include any numbers) |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$Question$txtSecurity | Security Question: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$Answer$txtSecurity | Answer: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$SecurityQuestionAnswer$AnswerReType$txtSecurity | Re-type Answer: |  | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
+UNKNOWN_TYPE | ctl00$ContentInfo$txtAgreement | Username and Password (optional)You have the option to create your own easy to remember username or password to sign in to continental.com.  The username can be used in place of your OnePass account number and a password can be used in place of your PIN. PIN/Password ReminderIf you forget your PIN or password, we will provide this reminder to access your account.PIN Reminder: (cannot include any numbers)Security Question | Agreement Between User And Continental AirlinesThis Web site is offered to the user conditioned on acceptance by the user ("User") without modification of the terms, conditions, and notices contained herein. By accessing and using this Web site, the User is deemed to have agreed to all such terms, conditions, and notices (the "Agreement").OnePass Terms and ConditionsContinental Airlines and all OnePass partners reserve the right to change any aspect of the OnePass program at any time within 30 days notice to active members. This right includes, but is not limited to, changes in partner affiliation, rules for earning mileage credit and mileage redemption levels. However, rules for use of travel rewards, cities served, flight schedules, limited seating or space availability, restricted travel dates and specific features of promotional offers are subject to change with or without notice at the discretion of Continental Airlines or the OnePass partner. Continental Airlines is not responsible for unilateral action | ctl00$ContentInfo$BusinessPhone$cboCountry$cboCountry_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/09_register_deviantart.com.out b/chrome/test/data/autofill/heuristics/output/09_register_deviantart.com.out
index e5f47d7..6f56fdb5 100644
--- a/chrome/test/data/autofill/heuristics/output/09_register_deviantart.com.out
+++ b/chrome/test/data/autofill/heuristics/output/09_register_deviantart.com.out
@@ -1,9 +1,9 @@
-UNKNOWN_TYPE | existingAccount | Are you a new customer? | 0
-UNKNOWN_TYPE | existingAccount | Are you a new customer? Create a new Buyer Account I have an existing deviantART account (email or username) | 1
-EMAIL_ADDRESS | emailAddress | Email Address | 
-UNKNOWN_TYPE | password | Password | 
-UNKNOWN_TYPE | remember_me | Stay logged in | 1
-UNKNOWN_TYPE | passwordNew | Password | 
-UNKNOWN_TYPE | passwordConfirm | Password (confirm) | 
-NAME_FULL | name | Full Name | 
-ADDRESS_HOME_COUNTRY | country | Country | 0
+UNKNOWN_TYPE | existingAccount | Are you a new customer? | 0 | existingAccount_1-default
+UNKNOWN_TYPE | existingAccount | Are you a new customer? Create a new Buyer Account I have an existing deviantART account (email or username) | 1 | existingAccount_1-default
+EMAIL_ADDRESS | emailAddress | Email Address |  | existingAccount_1-default
+UNKNOWN_TYPE | password | Password |  | existingAccount_1-default
+UNKNOWN_TYPE | remember_me | Stay logged in | 1 | existingAccount_1-default
+UNKNOWN_TYPE | passwordNew | Password |  | existingAccount_1-default
+UNKNOWN_TYPE | passwordConfirm | Password (confirm) |  | existingAccount_1-default
+NAME_FULL | name | Full Name |  | existingAccount_1-default
+ADDRESS_HOME_COUNTRY | country | Country | 0 | existingAccount_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/09_register_ebay.com.out b/chrome/test/data/autofill/heuristics/output/09_register_ebay.com.out
index 2a53dbb..e9df41a 100644
--- a/chrome/test/data/autofill/heuristics/output/09_register_ebay.com.out
+++ b/chrome/test/data/autofill/heuristics/output/09_register_ebay.com.out
@@ -1,27 +1,27 @@
-NAME_FIRST | firstname | First name | 
-NAME_LAST | lastname | Last name | 
-ADDRESS_HOME_LINE1 | address1 | Street address | 
-ADDRESS_HOME_LINE2 | address2 | Street address continued. Apartment number, floor number, suite number, etc. - optional | 
-ADDRESS_HOME_CITY | city | City | 
-ADDRESS_HOME_STATE | state | State / Province | default
-ADDRESS_HOME_ZIP | zip | ZIP / Postal code | 
-ADDRESS_HOME_COUNTRY | countryId | Country or region | 1
-PHONE_HOME_CITY_CODE | dayphone1 | Primary telephone number | 
-PHONE_HOME_NUMBER | dayphone2 | - | 
-PHONE_HOME_NUMBER | dayphone3 | - | 
-UNKNOWN_TYPE | dayphone4 | ext.: | 
-EMAIL_ADDRESS | email | Email address | 
-EMAIL_ADDRESS | retype_email | Re-enter email address | 
-UNKNOWN_TYPE | userid | Create your eBay user ID | 
-UNKNOWN_TYPE | pass | Create your password | 
-UNKNOWN_TYPE | rpass | Re-enter your password | 
-UNKNOWN_TYPE | canned | Pick a secret question | 0
-UNKNOWN_TYPE | myanswer | Your secret answer | 
-UNKNOWN_TYPE | birthdate2 | Date of birth, Month | 0
-UNKNOWN_TYPE | birthdate1 | Date of birth, Day | 0
-UNKNOWN_TYPE | birthdate3 | Year of birth, four digit format. | 0
-UNKNOWN_TYPE | tokentext | For added security - opens in a new window or tab, please enter the verification code hidden in the image. | 
-UNKNOWN_TYPE | acceptq1 | I agree that:I accept the User Agreement - opens in a new window or tab and Privacy Policy.I may receive communications from eBay and can change my notification preferences in My eBay.I'm at least 18 years old. | 1
-UNKNOWN_TYPE | uword1 | Give us some word and we'll suggest some user IDs for you. Word 1 | 
-UNKNOWN_TYPE | uword2 | Word 2 | 
-UNKNOWN_TYPE | uword3 | Word 3 | 
+NAME_FIRST | firstname | First name |  | firstname_1-default
+NAME_LAST | lastname | Last name |  | firstname_1-default
+ADDRESS_HOME_LINE1 | address1 | Street address |  | firstname_1-default
+ADDRESS_HOME_LINE2 | address2 | Street address continued. Apartment number, floor number, suite number, etc. - optional |  | firstname_1-default
+ADDRESS_HOME_CITY | city | City |  | firstname_1-default
+ADDRESS_HOME_STATE | state | State / Province | default | firstname_1-default
+ADDRESS_HOME_ZIP | zip | ZIP / Postal code |  | firstname_1-default
+ADDRESS_HOME_COUNTRY | countryId | Country or region | 1 | firstname_1-default
+PHONE_HOME_CITY_CODE | dayphone1 | Primary telephone number |  | firstname_1-default
+PHONE_HOME_NUMBER | dayphone2 | - |  | firstname_1-default
+PHONE_HOME_NUMBER | dayphone3 | - |  | firstname_1-default
+UNKNOWN_TYPE | dayphone4 | ext.: |  | firstname_1-default
+EMAIL_ADDRESS | email | Email address |  | firstname_1-default
+EMAIL_ADDRESS | retype_email | Re-enter email address |  | firstname_1-default
+UNKNOWN_TYPE | userid | Create your eBay user ID |  | firstname_1-default
+UNKNOWN_TYPE | pass | Create your password |  | firstname_1-default
+UNKNOWN_TYPE | rpass | Re-enter your password |  | firstname_1-default
+UNKNOWN_TYPE | canned | Pick a secret question | 0 | firstname_1-default
+UNKNOWN_TYPE | myanswer | Your secret answer |  | firstname_1-default
+UNKNOWN_TYPE | birthdate2 | Date of birth, Month | 0 | firstname_1-default
+UNKNOWN_TYPE | birthdate1 | Date of birth, Day | 0 | firstname_1-default
+UNKNOWN_TYPE | birthdate3 | Year of birth, four digit format. | 0 | firstname_1-default
+UNKNOWN_TYPE | tokentext | For added security - opens in a new window or tab, please enter the verification code hidden in the image. |  | firstname_1-default
+UNKNOWN_TYPE | acceptq1 | I agree that:I accept the User Agreement - opens in a new window or tab and Privacy Policy.I may receive communications from eBay and can change my notification preferences in My eBay.I'm at least 18 years old. | 1 | firstname_1-default
+UNKNOWN_TYPE | uword1 | Give us some word and we'll suggest some user IDs for you. Word 1 |  | uword1_1-default
+UNKNOWN_TYPE | uword2 | Word 2 |  | uword1_1-default
+UNKNOWN_TYPE | uword3 | Word 3 |  | uword1_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/09_register_ecomm.dell.com.out b/chrome/test/data/autofill/heuristics/output/09_register_ecomm.dell.com.out
index f04da5a5..3487e1ce 100644
--- a/chrome/test/data/autofill/heuristics/output/09_register_ecomm.dell.com.out
+++ b/chrome/test/data/autofill/heuristics/output/09_register_ecomm.dell.com.out
@@ -1,14 +1,14 @@
-NAME_FIRST | name$ctl00$name$_EditView$first | First NameMILast Name | 
-NAME_MIDDLE_INITIAL | name$ctl00$name$_EditView$mi | First NameMILast Name | 
-NAME_LAST | name$ctl00$name$_EditView$last | First NameMILast Name | 
-ADDRESS_HOME_LINE1 | address$ctl00$address$addressValidator$_EditView$line1 | Address Please see address guidelines. Learn More | 
-ADDRESS_HOME_LINE2 | address$ctl00$address$addressValidator$_EditView$line2 | Address Please see address guidelines. Learn More | 
-ADDRESS_HOME_CITY | address$ctl00$address$addressValidator$_EditView$city | CityState | 
-ADDRESS_HOME_STATE | address$ctl00$address$addressValidator$_EditView$region$ctl01 | CityState | 
-ADDRESS_HOME_ZIP | address$ctl00$address$addressValidator$_EditView$postal_code | Zip Code4-digit Ext. | 
-UNKNOWN_TYPE | address$ctl00$address$addressValidator$_EditView$postal_code2 | Zip Code4-digit Ext. | 
-UNKNOWN_TYPE | address$ctl00$address$addressValidator$OverrideAddress | Problems? | on
-EMAIL_ADDRESS | email$ctl07 | Email Address (used to sign into your account) | 
-UNKNOWN_TYPE | CreateNewPassword$ctl07 | Create New Password | 
-UNKNOWN_TYPE | ConfirmPassword$ctl07 | Confirm New Password | 
-UNKNOWN_TYPE | Subscription |  | on
+NAME_FIRST | name$ctl00$name$_EditView$first | First NameMILast Name |  | name$ctl00$name$_EditView$first_1-default
+NAME_MIDDLE_INITIAL | name$ctl00$name$_EditView$mi | First NameMILast Name |  | name$ctl00$name$_EditView$first_1-default
+NAME_LAST | name$ctl00$name$_EditView$last | First NameMILast Name |  | name$ctl00$name$_EditView$first_1-default
+ADDRESS_HOME_LINE1 | address$ctl00$address$addressValidator$_EditView$line1 | Address Please see address guidelines. Learn More |  | name$ctl00$name$_EditView$first_1-default
+ADDRESS_HOME_LINE2 | address$ctl00$address$addressValidator$_EditView$line2 | Address Please see address guidelines. Learn More |  | name$ctl00$name$_EditView$first_1-default
+ADDRESS_HOME_CITY | address$ctl00$address$addressValidator$_EditView$city | CityState |  | name$ctl00$name$_EditView$first_1-default
+ADDRESS_HOME_STATE | address$ctl00$address$addressValidator$_EditView$region$ctl01 | CityState |  | name$ctl00$name$_EditView$first_1-default
+ADDRESS_HOME_ZIP | address$ctl00$address$addressValidator$_EditView$postal_code | Zip Code4-digit Ext. |  | name$ctl00$name$_EditView$first_1-default
+UNKNOWN_TYPE | address$ctl00$address$addressValidator$_EditView$postal_code2 | Zip Code4-digit Ext. |  | name$ctl00$name$_EditView$first_1-default
+UNKNOWN_TYPE | address$ctl00$address$addressValidator$OverrideAddress | Problems? | on | name$ctl00$name$_EditView$first_1-default
+EMAIL_ADDRESS | email$ctl07 | Email Address (used to sign into your account) |  | name$ctl00$name$_EditView$first_1-default
+UNKNOWN_TYPE | CreateNewPassword$ctl07 | Create New Password |  | name$ctl00$name$_EditView$first_1-default
+UNKNOWN_TYPE | ConfirmPassword$ctl07 | Confirm New Password |  | name$ctl00$name$_EditView$first_1-default
+UNKNOWN_TYPE | Subscription |  | on | name$ctl00$name$_EditView$first_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/09_register_epson.com.out b/chrome/test/data/autofill/heuristics/output/09_register_epson.com.out
index d196e6b..bb77f01d 100644
--- a/chrome/test/data/autofill/heuristics/output/09_register_epson.com.out
+++ b/chrome/test/data/autofill/heuristics/output/09_register_epson.com.out
@@ -1,6 +1,6 @@
-NAME_FIRST | fname | * First Name | 
-NAME_LAST | lname | * Last Name | 
-EMAIL_ADDRESS | emLogin | * E-mail address | 
-UNKNOWN_TYPE | pw | * Password | 
-UNKNOWN_TYPE | verifypw | * Re-Confirm Password | 
-UNKNOWN_TYPE | wantMsg |  | on
+NAME_FIRST | fname | * First Name |  | fname_1-default
+NAME_LAST | lname | * Last Name |  | fname_1-default
+EMAIL_ADDRESS | emLogin | * E-mail address |  | fname_1-default
+UNKNOWN_TYPE | pw | * Password |  | fname_1-default
+UNKNOWN_TYPE | verifypw | * Re-Confirm Password |  | fname_1-default
+UNKNOWN_TYPE | wantMsg |  | on | fname_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/09_register_google.com.out b/chrome/test/data/autofill/heuristics/output/09_register_google.com.out
index a3a96935..e012e54 100644
--- a/chrome/test/data/autofill/heuristics/output/09_register_google.com.out
+++ b/chrome/test/data/autofill/heuristics/output/09_register_google.com.out
@@ -1,16 +1,16 @@
-NAME_FIRST | FirstName | First name: | 
-NAME_LAST | LastName | Last name: | 
-UNKNOWN_TYPE | UsernameSelector |  | header
-EMAIL_ADDRESS | Email |  | 
-UNKNOWN_TYPE | Passwd |  | 
-UNKNOWN_TYPE | PasswdAgain | Re-enter password: | 
-UNKNOWN_TYPE | PersistentCookie | Re-enter password: | yes
-UNKNOWN_TYPE | smhck | Re-enter password: | 1
-UNKNOWN_TYPE | selection | Security question: | choosequestion
-UNKNOWN_TYPE | ownquestion | Security question: | 
-UNKNOWN_TYPE | IdentityAnswer | Answer: | 
-EMAIL_ADDRESS | SecondaryEmail | Recovery email: | 
-ADDRESS_HOME_COUNTRY | loc | Location: | US
-UNKNOWN_TYPE | Birthday | Birthday: | 
-UNKNOWN_TYPE | newaccountcaptcha | Type the characters you see in the picture below. | 
-UNKNOWN_TYPE |  | Printable Version | Google Terms of ServiceWelcome to Google!1. Your relationship with Google    1.1 Your use of Google’s products, software, services and web sites (referred to collectively as the “Services” in this document and excluding any services provided to you by Google under a separate written agreement) is subject to the terms of a legal agreement between you and Google. “Google” means Google Inc., whose principal place of business is at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States. This document explains how the agreement is made up, and sets out some of the terms of that agreement.    1.2 Unless otherwise agreed in writing with Google, your agreement with Google will always include, at a minimum, the terms and conditions set out in this document. These are referred to below as the “Universal Terms”.    1.3 Your agreement with Google will also include the terms of any Legal Notices applicable to the Services, in addition to the Universal Terms. All of these are referred to below a
+NAME_FIRST | FirstName | First name: |  | FirstName_1-default
+NAME_LAST | LastName | Last name: |  | FirstName_1-default
+UNKNOWN_TYPE | UsernameSelector |  | header | FirstName_1-default
+EMAIL_ADDRESS | Email |  |  | FirstName_1-default
+UNKNOWN_TYPE | Passwd |  |  | FirstName_1-default
+UNKNOWN_TYPE | PasswdAgain | Re-enter password: |  | FirstName_1-default
+UNKNOWN_TYPE | PersistentCookie | Re-enter password: | yes | FirstName_1-default
+UNKNOWN_TYPE | smhck | Re-enter password: | 1 | FirstName_1-default
+UNKNOWN_TYPE | selection | Security question: | choosequestion | FirstName_1-default
+UNKNOWN_TYPE | ownquestion | Security question: |  | FirstName_1-default
+UNKNOWN_TYPE | IdentityAnswer | Answer: |  | FirstName_1-default
+EMAIL_ADDRESS | SecondaryEmail | Recovery email: |  | SecondaryEmail_1-default
+ADDRESS_HOME_COUNTRY | loc | Location: | US | SecondaryEmail_1-default
+UNKNOWN_TYPE | Birthday | Birthday: |  | SecondaryEmail_1-default
+UNKNOWN_TYPE | newaccountcaptcha | Type the characters you see in the picture below. |  | SecondaryEmail_1-default
+UNKNOWN_TYPE |  | Printable Version | Google Terms of ServiceWelcome to Google!1. Your relationship with Google    1.1 Your use of Google’s products, software, services and web sites (referred to collectively as the “Services” in this document and excluding any services provided to you by Google under a separate written agreement) is subject to the terms of a legal agreement between you and Google. “Google” means Google Inc., whose principal place of business is at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States. This document explains how the agreement is made up, and sets out some of the terms of that agreement.    1.2 Unless otherwise agreed in writing with Google, your agreement with Google will always include, at a minimum, the terms and conditions set out in this document. These are referred to below as the “Universal Terms”.    1.3 Your agreement with Google will also include the terms of any Legal Notices applicable to the Services, in addition to the Universal Terms. All of these are referred to below a | SecondaryEmail_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/10_register_gymboree.com.out b/chrome/test/data/autofill/heuristics/output/10_register_gymboree.com.out
index 7baa4d8..5638f76 100644
--- a/chrome/test/data/autofill/heuristics/output/10_register_gymboree.com.out
+++ b/chrome/test/data/autofill/heuristics/output/10_register_gymboree.com.out
@@ -1,17 +1,17 @@
-EMAIL_ADDRESS | LOYALTY_ACCOUNT<>email | Email* | 
-ADDRESS_HOME_COUNTRY | LOYALTY_ADDRESS<>country_cd | Country* | US
-NAME_FIRST | USER_ACCOUNT<>firstName | First Name* | 
-NAME_LAST | USER_ACCOUNT<>lastName | Last Name* | 
-ADDRESS_HOME_LINE1 | LOYALTY_ADDRESS<>address1 | Address Line 1* | 
-ADDRESS_HOME_LINE2 | LOYALTY_ADDRESS<>address2 | Address Line 2 | 
-UNKNOWN_TYPE | LOYALTY_ADDRESS<>address3 | Address Line 3 | 
-ADDRESS_HOME_CITY | LOYALTY_ADDRESS<>city | City* | 
-ADDRESS_HOME_STATE | LOYALTY_ADDRESS<>state_cd | State/Province* | 
-ADDRESS_HOME_ZIP | LOYALTY_ADDRESS<>postal | Zip/Postal Code*! | 
-PHONE_HOME_WHOLE_NUMBER | LOYALTY_ADDRESS<>phone | Daytime Phone* | 
-UNKNOWN_TYPE | LOYALTY_ACCOUNT<>password | Password*! | 
-UNKNOWN_TYPE | LOYALTY_ACCOUNT<>confirmPassword | Confirm Password* | 
-UNKNOWN_TYPE | LOYALTY_ACCOUNT<>ATR_USER_Password_Hint | Password Hint* | 
-UNKNOWN_TYPE | LOYALTY_ADDRESS<>ATR_indBillAsRewards | Password Hint*! | true
-UNKNOWN_TYPE | LOYALTY_ACCOUNT<>sendEmail | Save the address above as my default billing address. I would like to receive promotions and special offers from Gymboree. | true
-UNKNOWN_TYPE | accept | I have read and accept the terms and conditions of Gymboree Rewards. (Rewards information and offers will be emailed to you.) | on
+EMAIL_ADDRESS | LOYALTY_ACCOUNT<>email | Email* |  | LOYALTY_ACCOUNT<>email_1-default
+ADDRESS_HOME_COUNTRY | LOYALTY_ADDRESS<>country_cd | Country* | US | LOYALTY_ACCOUNT<>email_1-default
+NAME_FIRST | USER_ACCOUNT<>firstName | First Name* |  | LOYALTY_ACCOUNT<>email_1-default
+NAME_LAST | USER_ACCOUNT<>lastName | Last Name* |  | LOYALTY_ACCOUNT<>email_1-default
+ADDRESS_HOME_LINE1 | LOYALTY_ADDRESS<>address1 | Address Line 1* |  | LOYALTY_ACCOUNT<>email_1-default
+ADDRESS_HOME_LINE2 | LOYALTY_ADDRESS<>address2 | Address Line 2 |  | LOYALTY_ACCOUNT<>email_1-default
+UNKNOWN_TYPE | LOYALTY_ADDRESS<>address3 | Address Line 3 |  | LOYALTY_ACCOUNT<>email_1-default
+ADDRESS_HOME_CITY | LOYALTY_ADDRESS<>city | City* |  | LOYALTY_ACCOUNT<>email_1-default
+ADDRESS_HOME_STATE | LOYALTY_ADDRESS<>state_cd | State/Province* |  | LOYALTY_ACCOUNT<>email_1-default
+ADDRESS_HOME_ZIP | LOYALTY_ADDRESS<>postal | Zip/Postal Code*! |  | LOYALTY_ACCOUNT<>email_1-default
+PHONE_HOME_WHOLE_NUMBER | LOYALTY_ADDRESS<>phone | Daytime Phone* |  | LOYALTY_ACCOUNT<>email_1-default
+UNKNOWN_TYPE | LOYALTY_ACCOUNT<>password | Password*! |  | LOYALTY_ACCOUNT<>email_1-default
+UNKNOWN_TYPE | LOYALTY_ACCOUNT<>confirmPassword | Confirm Password* |  | LOYALTY_ACCOUNT<>email_1-default
+UNKNOWN_TYPE | LOYALTY_ACCOUNT<>ATR_USER_Password_Hint | Password Hint* |  | LOYALTY_ACCOUNT<>email_1-default
+UNKNOWN_TYPE | LOYALTY_ADDRESS<>ATR_indBillAsRewards | Password Hint*! | true | LOYALTY_ACCOUNT<>email_1-default
+UNKNOWN_TYPE | LOYALTY_ACCOUNT<>sendEmail | Save the address above as my default billing address. I would like to receive promotions and special offers from Gymboree. | true | LOYALTY_ACCOUNT<>email_1-default
+UNKNOWN_TYPE | accept | I have read and accept the terms and conditions of Gymboree Rewards. (Rewards information and offers will be emailed to you.) | on | LOYALTY_ACCOUNT<>email_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/10_register_hotels.com.out b/chrome/test/data/autofill/heuristics/output/10_register_hotels.com.out
index 8db70c3..25d87b2 100644
--- a/chrome/test/data/autofill/heuristics/output/10_register_hotels.com.out
+++ b/chrome/test/data/autofill/heuristics/output/10_register_hotels.com.out
@@ -1,19 +1,19 @@
-EMAIL_ADDRESS | profileInformation.email | Email address* | 
-EMAIL_ADDRESS | confirmEmail | Confirm email address* | 
-UNKNOWN_TYPE | profileInformation.password | Password* | 
-UNKNOWN_TYPE | confirmPassword | Confirm password* | 
-UNKNOWN_TYPE | profileInformation.customerContact.title | Title | NONE
-NAME_FIRST | profileInformation.customerContact.firstName | First name* | 
-NAME_LAST | profileInformation.customerContact.lastName | Last name* | 
-ADDRESS_HOME_LINE1 | profileInformation.customerContact.address1 | Address line 1* | 
-ADDRESS_HOME_LINE2 | profileInformation.customerContact.address2 | Address line 2 | 
-ADDRESS_HOME_CITY | profileInformation.customerContact.city | City or APO/FPO* | 
-ADDRESS_HOME_STATE | profileInformation.customerContact.stateOrProvince | State/Province* | 
-ADDRESS_HOME_ZIP | profileInformation.customerContact.zipOrPostalCode | Zip/Postal code | 
-ADDRESS_HOME_COUNTRY | profileInformation.customerContact.country | Country* | US
-PHONE_HOME_WHOLE_NUMBER | profileInformation.customerContact.primaryPhone | Phone number | 
-COMPANY_NAME | profileInformation.businessName | Company name | 
-UNKNOWN_TYPE | profileInformation.currency | Preferred currency | USD
-UNKNOWN_TYPE | profileInformation.customerContact.loyaltyAccountDesired | Sign me up to get 1 free night anywhere for every 10 nights I stay with Hotels.com. By enrolling, I agree to the full Terms and Conditions of the program. Learn more. | true
-UNKNOWN_TYPE | subscribeNewsletter | Email me exclusive coupons, deals and travel information from hotels.com | true
-UNKNOWN_TYPE | termsConditionsConfirm | I have read and accepted the Terms and Conditions and Privacy Policy for this website* | true
+EMAIL_ADDRESS | profileInformation.email | Email address* |  | profileInformation.email_1-default
+EMAIL_ADDRESS | confirmEmail | Confirm email address* |  | profileInformation.email_1-default
+UNKNOWN_TYPE | profileInformation.password | Password* |  | profileInformation.email_1-default
+UNKNOWN_TYPE | confirmPassword | Confirm password* |  | profileInformation.email_1-default
+UNKNOWN_TYPE | profileInformation.customerContact.title | Title | NONE | profileInformation.email_1-default
+NAME_FIRST | profileInformation.customerContact.firstName | First name* |  | profileInformation.email_1-default
+NAME_LAST | profileInformation.customerContact.lastName | Last name* |  | profileInformation.email_1-default
+ADDRESS_HOME_LINE1 | profileInformation.customerContact.address1 | Address line 1* |  | profileInformation.email_1-default
+ADDRESS_HOME_LINE2 | profileInformation.customerContact.address2 | Address line 2 |  | profileInformation.email_1-default
+ADDRESS_HOME_CITY | profileInformation.customerContact.city | City or APO/FPO* |  | profileInformation.email_1-default
+ADDRESS_HOME_STATE | profileInformation.customerContact.stateOrProvince | State/Province* |  | profileInformation.email_1-default
+ADDRESS_HOME_ZIP | profileInformation.customerContact.zipOrPostalCode | Zip/Postal code |  | profileInformation.email_1-default
+ADDRESS_HOME_COUNTRY | profileInformation.customerContact.country | Country* | US | profileInformation.email_1-default
+PHONE_HOME_WHOLE_NUMBER | profileInformation.customerContact.primaryPhone | Phone number |  | profileInformation.email_1-default
+COMPANY_NAME | profileInformation.businessName | Company name |  | profileInformation.email_1-default
+UNKNOWN_TYPE | profileInformation.currency | Preferred currency | USD | profileInformation.email_1-default
+UNKNOWN_TYPE | profileInformation.customerContact.loyaltyAccountDesired | Sign me up to get 1 free night anywhere for every 10 nights I stay with Hotels.com. By enrolling, I agree to the full Terms and Conditions of the program. Learn more. | true | profileInformation.email_1-default
+UNKNOWN_TYPE | subscribeNewsletter | Email me exclusive coupons, deals and travel information from hotels.com | true | profileInformation.email_1-default
+UNKNOWN_TYPE | termsConditionsConfirm | I have read and accepted the Terms and Conditions and Privacy Policy for this website* | true | profileInformation.email_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/10_register_imdb.com.out b/chrome/test/data/autofill/heuristics/output/10_register_imdb.com.out
index abf0765..0bf5250 100644
--- a/chrome/test/data/autofill/heuristics/output/10_register_imdb.com.out
+++ b/chrome/test/data/autofill/heuristics/output/10_register_imdb.com.out
@@ -1,9 +1,9 @@
-EMAIL_ADDRESS | email1 | E-mail: | 
-EMAIL_ADDRESS | email2 | Confirm E-mail: | 
-UNKNOWN_TYPE | gender | Sex: | M
-UNKNOWN_TYPE | gender | Male | F
-UNKNOWN_TYPE | year | Year of Birth: | 
-ADDRESS_HOME_ZIP | postal | ZIP/Postal Code: | 
-ADDRESS_HOME_COUNTRY | country | Country: | US
-UNKNOWN_TYPE | pass1 | Select a password: | 
-UNKNOWN_TYPE | pass2 | Confirm password: | 
+EMAIL_ADDRESS | email1 | E-mail: |  | email1_1-default
+EMAIL_ADDRESS | email2 | Confirm E-mail: |  | email1_1-default
+UNKNOWN_TYPE | gender | Sex: | M | email1_1-default
+UNKNOWN_TYPE | gender | Male | F | email1_1-default
+UNKNOWN_TYPE | year | Year of Birth: |  | email1_1-default
+ADDRESS_HOME_ZIP | postal | ZIP/Postal Code: |  | email1_1-default
+ADDRESS_HOME_COUNTRY | country | Country: | US | email1_1-default
+UNKNOWN_TYPE | pass1 | Select a password: |  | email1_1-default
+UNKNOWN_TYPE | pass2 | Confirm password: |  | email1_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/10_register_jbox.com.out b/chrome/test/data/autofill/heuristics/output/10_register_jbox.com.out
index 3bf405c1..c65c9938 100644
--- a/chrome/test/data/autofill/heuristics/output/10_register_jbox.com.out
+++ b/chrome/test/data/autofill/heuristics/output/10_register_jbox.com.out
@@ -1,13 +1,13 @@
-NAME_FIRST | firstname | First Last | 
-NAME_LAST | lastname |  | 
-ADDRESS_HOME_LINE1 | address1 | Street Address | 
-ADDRESS_HOME_CITY | city | City | 
-ADDRESS_HOME_STATE | state | State / Province / Region | 
-ADDRESS_HOME_ZIP | zip | Postal / Zip Code | 
-ADDRESS_HOME_COUNTRY | country | Country | United States
-PHONE_HOME_WHOLE_NUMBER | phone |  | 
-EMAIL_ADDRESS | email |  | 
-UNKNOWN_TYPE | password | Enter a password | 
-UNKNOWN_TYPE | password_again | Retype your password | 
-UNKNOWN_TYPE | referred_by | Where did you hear about J-List/JBOX? | Don't Know!
-UNKNOWN_TYPE | referred_by_other | If other, please specify | 
+NAME_FIRST | firstname | First Last |  | firstname_1-default
+NAME_LAST | lastname |  |  | firstname_1-default
+ADDRESS_HOME_LINE1 | address1 | Street Address |  | firstname_1-default
+ADDRESS_HOME_CITY | city | City |  | firstname_1-default
+ADDRESS_HOME_STATE | state | State / Province / Region |  | firstname_1-default
+ADDRESS_HOME_ZIP | zip | Postal / Zip Code |  | firstname_1-default
+ADDRESS_HOME_COUNTRY | country | Country | United States | firstname_1-default
+PHONE_HOME_WHOLE_NUMBER | phone |  |  | firstname_1-default
+EMAIL_ADDRESS | email |  |  | firstname_1-default
+UNKNOWN_TYPE | password | Enter a password |  | firstname_1-default
+UNKNOWN_TYPE | password_again | Retype your password |  | firstname_1-default
+UNKNOWN_TYPE | referred_by | Where did you hear about J-List/JBOX? | Don't Know! | firstname_1-default
+UNKNOWN_TYPE | referred_by_other | If other, please specify |  | firstname_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/10_register_live.com.out b/chrome/test/data/autofill/heuristics/output/10_register_live.com.out
index 90ef072..80de5a81 100644
--- a/chrome/test/data/autofill/heuristics/output/10_register_live.com.out
+++ b/chrome/test/data/autofill/heuristics/output/10_register_live.com.out
@@ -1,17 +1,17 @@
-UNKNOWN_TYPE | imembernamelive | Windows Live ID: | 
-UNKNOWN_TYPE | idomain | Domains | hotmail.com
-UNKNOWN_TYPE | isug1 | Enter a word |  Enter a word
-UNKNOWN_TYPE | isug2 | Enter another word |  Enter another word
-UNKNOWN_TYPE | isug3 | Enter another word |  Enter another word
-EMAIL_ADDRESS | imembernameeasi | Use your email address: | Example: someone@example.com
-UNKNOWN_TYPE | iPwd | Create a password: | 
-UNKNOWN_TYPE | iRetypePwd | Retype password: | 
-EMAIL_ADDRESS | iAltEmail | Alternate email address: | 
-UNKNOWN_TYPE | iSQ | Question: | 0
-UNKNOWN_TYPE | iSA | Secret answer: | 
-NAME_FIRST | iFirstName | First name: | 
-NAME_LAST | iLastName | Last name: | 
-UNKNOWN_TYPE | profile_gender |  | m
-UNKNOWN_TYPE | profile_gender |  | f
-UNKNOWN_TYPE | iBirthYear | Birth year: | Example: 1990
-UNKNOWN_TYPE | iOptinEmail | Send me email with promotional offers and survey invitations from Windows Live, Bing, and MSN. (You can unsubscribe at any time.) | on
+UNKNOWN_TYPE | imembernamelive | Windows Live ID: |  | imembernamelive_1-default
+UNKNOWN_TYPE | idomain | Domains | hotmail.com | imembernamelive_1-default
+UNKNOWN_TYPE | isug1 | Enter a word |  Enter a word | imembernamelive_1-default
+UNKNOWN_TYPE | isug2 | Enter another word |  Enter another word | imembernamelive_1-default
+UNKNOWN_TYPE | isug3 | Enter another word |  Enter another word | imembernamelive_1-default
+EMAIL_ADDRESS | imembernameeasi | Use your email address: | Example: someone@example.com | imembernamelive_1-default
+UNKNOWN_TYPE | iPwd | Create a password: |  | imembernamelive_1-default
+UNKNOWN_TYPE | iRetypePwd | Retype password: |  | imembernamelive_1-default
+EMAIL_ADDRESS | iAltEmail | Alternate email address: |  | iAltEmail_1-default
+UNKNOWN_TYPE | iSQ | Question: | 0 | iAltEmail_1-default
+UNKNOWN_TYPE | iSA | Secret answer: |  | iAltEmail_1-default
+NAME_FIRST | iFirstName | First name: |  | iAltEmail_1-default
+NAME_LAST | iLastName | Last name: |  | iAltEmail_1-default
+UNKNOWN_TYPE | profile_gender |  | m | iAltEmail_1-default
+UNKNOWN_TYPE | profile_gender |  | f | iAltEmail_1-default
+UNKNOWN_TYPE | iBirthYear | Birth year: | Example: 1990 | iAltEmail_1-default
+UNKNOWN_TYPE | iOptinEmail | Send me email with promotional offers and survey invitations from Windows Live, Bing, and MSN. (You can unsubscribe at any time.) | on | iAltEmail_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/11_register_livejournal.com.out b/chrome/test/data/autofill/heuristics/output/11_register_livejournal.com.out
index ff81321..dae2427 100644
--- a/chrome/test/data/autofill/heuristics/output/11_register_livejournal.com.out
+++ b/chrome/test/data/autofill/heuristics/output/11_register_livejournal.com.out
@@ -1,9 +1,9 @@
-UNKNOWN_TYPE | Widget[CreateAccount]_user | Username: | 
-EMAIL_ADDRESS | Widget[CreateAccount]_email | Email Address: | 
-UNKNOWN_TYPE | Widget[CreateAccount]_password1 | Password: | 
-UNKNOWN_TYPE | Widget[CreateAccount]_password2 | Confirm Password: | 
-UNKNOWN_TYPE | Widget[CreateAccount]_gender | Gender: | 
-UNKNOWN_TYPE | Widget[CreateAccount]_bday_mm | Birthdate: | 1
-UNKNOWN_TYPE | Widget[CreateAccount]_bday_dd | Birthdate: | 
-UNKNOWN_TYPE | Widget[CreateAccount]_bday_yyyy | Birthdate: | 
-UNKNOWN_TYPE | Widget[CreateAccount]_news | Yes, send me LiveJournal announcements via email. | 1
+UNKNOWN_TYPE | Widget[CreateAccount]_user | Username: |  | Widget[CreateAccount]_user_1-default
+EMAIL_ADDRESS | Widget[CreateAccount]_email | Email Address: |  | Widget[CreateAccount]_user_1-default
+UNKNOWN_TYPE | Widget[CreateAccount]_password1 | Password: |  | Widget[CreateAccount]_user_1-default
+UNKNOWN_TYPE | Widget[CreateAccount]_password2 | Confirm Password: |  | Widget[CreateAccount]_user_1-default
+UNKNOWN_TYPE | Widget[CreateAccount]_gender | Gender: |  | Widget[CreateAccount]_user_1-default
+UNKNOWN_TYPE | Widget[CreateAccount]_bday_mm | Birthdate: | 1 | Widget[CreateAccount]_user_1-default
+UNKNOWN_TYPE | Widget[CreateAccount]_bday_dd | Birthdate: |  | Widget[CreateAccount]_user_1-default
+UNKNOWN_TYPE | Widget[CreateAccount]_bday_yyyy | Birthdate: |  | Widget[CreateAccount]_user_1-default
+UNKNOWN_TYPE | Widget[CreateAccount]_news | Yes, send me LiveJournal announcements via email. | 1 | Widget[CreateAccount]_user_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/11_register_macys.com.out b/chrome/test/data/autofill/heuristics/output/11_register_macys.com.out
index 7980741..a67d6be 100644
--- a/chrome/test/data/autofill/heuristics/output/11_register_macys.com.out
+++ b/chrome/test/data/autofill/heuristics/output/11_register_macys.com.out
@@ -1,24 +1,24 @@
-NAME_FIRST | FirstName | First Name | 
-NAME_LAST | LastName | Last Name | 
-ADDRESS_HOME_LINE1 | Address1 | Address | 
-ADDRESS_HOME_LINE2 | Address2 | P.O. Box/Apt # | 
-ADDRESS_HOME_ZIP | PostalCode | Zip Code | 
-EMAIL_ADDRESS | EmailAddress | Email | 
-EMAIL_ADDRESS | ConfirmEmailAddress | Verify Email | 
-UNKNOWN_TYPE | Password | Password | 
-UNKNOWN_TYPE | PasswordConfirm | Verify Password | 
-UNKNOWN_TYPE | BirthMonth | Birth date | NOSELECTION
-UNKNOWN_TYPE | BirthDay |  | NOSELECTION
-UNKNOWN_TYPE | BirthYear |  | NOSELECTION
-UNKNOWN_TYPE | Gender | Gender | NOSELECTION
-UNKNOWN_TYPE | NewsLetter | We'll let you know about exclusive sales and events,both online and in-store. | NewsLetter
-UNKNOWN_TYPE | MobileMarketing | Yes, please text me about exclusive sales and events, both online and in-store. We'll send your first text message within 48 hours. | MobileMarketing
-PHONE_HOME_CITY_CODE | MobilePhoneAreaCode |  | 
-PHONE_HOME_NUMBER | MobilePhoneExchangeNbr | - | 
-PHONE_HOME_NUMBER | MobilePhoneSubscriberNbr | - | 
-UNKNOWN_TYPE | addacard | Yes, I'd like to add my Macy's Card to my profile. | on
-UNKNOWN_TYPE | MaskedAccountNumber | Macy's Account Number: | 
-UNKNOWN_TYPE | SSN4 | Last 4 digits of SSN: | 
-UNKNOWN_TYPE | addToWallet | Save this store card in your macys.com wallet for faster checkout. | addToWallet
-UNKNOWN_TYPE | emailAlert | Receive email notification when statements are ready for review andwhen payments are due. | emailAlert
-UNKNOWN_TYPE | paperStatementDelivery | I want to turn off paper statement delivery and receive my statements online. | paperStatementDelivery
+NAME_FIRST | FirstName | First Name |  | FirstName_1-default
+NAME_LAST | LastName | Last Name |  | FirstName_1-default
+ADDRESS_HOME_LINE1 | Address1 | Address |  | FirstName_1-default
+ADDRESS_HOME_LINE2 | Address2 | P.O. Box/Apt # |  | FirstName_1-default
+ADDRESS_HOME_ZIP | PostalCode | Zip Code |  | FirstName_1-default
+EMAIL_ADDRESS | EmailAddress | Email |  | FirstName_1-default
+EMAIL_ADDRESS | ConfirmEmailAddress | Verify Email |  | FirstName_1-default
+UNKNOWN_TYPE | Password | Password |  | FirstName_1-default
+UNKNOWN_TYPE | PasswordConfirm | Verify Password |  | FirstName_1-default
+UNKNOWN_TYPE | BirthMonth | Birth date | NOSELECTION | FirstName_1-default
+UNKNOWN_TYPE | BirthDay |  | NOSELECTION | FirstName_1-default
+UNKNOWN_TYPE | BirthYear |  | NOSELECTION | FirstName_1-default
+UNKNOWN_TYPE | Gender | Gender | NOSELECTION | FirstName_1-default
+UNKNOWN_TYPE | NewsLetter | We'll let you know about exclusive sales and events,both online and in-store. | NewsLetter | FirstName_1-default
+UNKNOWN_TYPE | MobileMarketing | Yes, please text me about exclusive sales and events, both online and in-store. We'll send your first text message within 48 hours. | MobileMarketing | FirstName_1-default
+PHONE_HOME_CITY_CODE | MobilePhoneAreaCode |  |  | FirstName_1-default
+PHONE_HOME_NUMBER | MobilePhoneExchangeNbr | - |  | FirstName_1-default
+PHONE_HOME_NUMBER | MobilePhoneSubscriberNbr | - |  | FirstName_1-default
+UNKNOWN_TYPE | addacard | Yes, I'd like to add my Macy's Card to my profile. | on | FirstName_1-default
+UNKNOWN_TYPE | MaskedAccountNumber | Macy's Account Number: |  | FirstName_1-default
+UNKNOWN_TYPE | SSN4 | Last 4 digits of SSN: |  | FirstName_1-default
+UNKNOWN_TYPE | addToWallet | Save this store card in your macys.com wallet for faster checkout. | addToWallet | FirstName_1-default
+UNKNOWN_TYPE | emailAlert | Receive email notification when statements are ready for review andwhen payments are due. | emailAlert | FirstName_1-default
+UNKNOWN_TYPE | paperStatementDelivery | I want to turn off paper statement delivery and receive my statements online. | paperStatementDelivery | FirstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/11_register_mcphee.com.out b/chrome/test/data/autofill/heuristics/output/11_register_mcphee.com.out
index a34565cb..725c53f8 100644
--- a/chrome/test/data/autofill/heuristics/output/11_register_mcphee.com.out
+++ b/chrome/test/data/autofill/heuristics/output/11_register_mcphee.com.out
@@ -1,13 +1,13 @@
-EMAIL_ADDRESS | FormField[1][1] | * Email Address: | 
-UNKNOWN_TYPE | FormField[1][2] | * Password: | 
-UNKNOWN_TYPE | FormField[1][3] | * Confirm Password: | 
-NAME_FIRST | FormField[2][4] | * First Name: | 
-NAME_LAST | FormField[2][5] | * Last Name: | 
-COMPANY_NAME | FormField[2][6] | * Company Name: | 
-PHONE_HOME_WHOLE_NUMBER | FormField[2][7] | * Phone Number: | 
-ADDRESS_HOME_LINE1 | FormField[2][8] | * Address Line 1: | 
-ADDRESS_HOME_LINE2 | FormField[2][9] | * Address Line 2: | 
-ADDRESS_HOME_CITY | FormField[2][10] | * Suburb/City: | 
-ADDRESS_HOME_COUNTRY | FormField[2][11] | * Country: | United States
-ADDRESS_HOME_STATE | FormField[2][12] | * State/Province: | 
-ADDRESS_HOME_ZIP | FormField[2][13] | * Zip/Postcode: | 
+EMAIL_ADDRESS | FormField[1][1] | * Email Address: |  | FormField[1][1]_1-default
+UNKNOWN_TYPE | FormField[1][2] | * Password: |  | FormField[1][1]_1-default
+UNKNOWN_TYPE | FormField[1][3] | * Confirm Password: |  | FormField[1][1]_1-default
+NAME_FIRST | FormField[2][4] | * First Name: |  | FormField[1][1]_1-default
+NAME_LAST | FormField[2][5] | * Last Name: |  | FormField[1][1]_1-default
+COMPANY_NAME | FormField[2][6] | * Company Name: |  | FormField[1][1]_1-default
+PHONE_HOME_WHOLE_NUMBER | FormField[2][7] | * Phone Number: |  | FormField[1][1]_1-default
+ADDRESS_HOME_LINE1 | FormField[2][8] | * Address Line 1: |  | FormField[1][1]_1-default
+ADDRESS_HOME_LINE2 | FormField[2][9] | * Address Line 2: |  | FormField[1][1]_1-default
+ADDRESS_HOME_CITY | FormField[2][10] | * Suburb/City: |  | FormField[1][1]_1-default
+ADDRESS_HOME_COUNTRY | FormField[2][11] | * Country: | United States | FormField[1][1]_1-default
+ADDRESS_HOME_STATE | FormField[2][12] | * State/Province: |  | FormField[1][1]_1-default
+ADDRESS_HOME_ZIP | FormField[2][13] | * Zip/Postcode: |  | FormField[1][1]_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/11_register_myspace.com.out b/chrome/test/data/autofill/heuristics/output/11_register_myspace.com.out
index d14992a..69035c4 100644
--- a/chrome/test/data/autofill/heuristics/output/11_register_myspace.com.out
+++ b/chrome/test/data/autofill/heuristics/output/11_register_myspace.com.out
@@ -1,17 +1,17 @@
-UNKNOWN_TYPE | accountType | Account TypeWhat's this? | 2
-UNKNOWN_TYPE | accountType | Personal | 7
-UNKNOWN_TYPE | accountType | Musician | 15
-UNKNOWN_TYPE | accountType | Comedian | 9
-NAME_FIRST | tbxFirstName | First Name | 
-NAME_LAST | tbxLastName | Last Name | 
-UNKNOWN_TYPE | tbxMusicianName | Artist Name | 
-UNKNOWN_TYPE | ddlGenre | Genre | 
-UNKNOWN_TYPE | ddlLabel | Label Type | 
-EMAIL_ADDRESS | tbxEmail | Email | 
-UNKNOWN_TYPE | tbxPassword | Password | 
-UNKNOWN_TYPE | tbxPassword1 | Confirm Password | 
-UNKNOWN_TYPE | ddlMonth | Birthday | 
-UNKNOWN_TYPE | ddlDay |  | 
-UNKNOWN_TYPE | ddlYear |  | 
-UNKNOWN_TYPE | rblGender | Gender | M
-UNKNOWN_TYPE | rblGender | Male | F
+UNKNOWN_TYPE | accountType | Account TypeWhat's this? | 2 | accountType_1-default
+UNKNOWN_TYPE | accountType | Personal | 7 | accountType_1-default
+UNKNOWN_TYPE | accountType | Musician | 15 | accountType_1-default
+UNKNOWN_TYPE | accountType | Comedian | 9 | accountType_1-default
+NAME_FIRST | tbxFirstName | First Name |  | accountType_1-default
+NAME_LAST | tbxLastName | Last Name |  | accountType_1-default
+UNKNOWN_TYPE | tbxMusicianName | Artist Name |  | accountType_1-default
+UNKNOWN_TYPE | ddlGenre | Genre |  | accountType_1-default
+UNKNOWN_TYPE | ddlLabel | Label Type |  | accountType_1-default
+EMAIL_ADDRESS | tbxEmail | Email |  | accountType_1-default
+UNKNOWN_TYPE | tbxPassword | Password |  | accountType_1-default
+UNKNOWN_TYPE | tbxPassword1 | Confirm Password |  | accountType_1-default
+UNKNOWN_TYPE | ddlMonth | Birthday |  | accountType_1-default
+UNKNOWN_TYPE | ddlDay |  |  | accountType_1-default
+UNKNOWN_TYPE | ddlYear |  |  | accountType_1-default
+UNKNOWN_TYPE | rblGender | Gender | M | accountType_1-default
+UNKNOWN_TYPE | rblGender | Male | F | accountType_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/11_register_newegg.com.out b/chrome/test/data/autofill/heuristics/output/11_register_newegg.com.out
index 196998c..384da96 100644
--- a/chrome/test/data/autofill/heuristics/output/11_register_newegg.com.out
+++ b/chrome/test/data/autofill/heuristics/output/11_register_newegg.com.out
@@ -1,45 +1,45 @@
-EMAIL_ADDRESS | LoginName | Email Address* | 
-EMAIL_ADDRESS | LoginName1 | Confirm Email Address* | 
-UNKNOWN_TYPE | Password | Password* | 
-UNKNOWN_TYPE | Password1 | Confirm Password* | 
-NAME_FIRST | FirstName | First Name* | 
-NAME_MIDDLE_INITIAL | BMI | MI | 
-NAME_LAST | LastName | Last Name* | 
-COMPANY_NAME | BCompany | Company Name | 
-ADDRESS_HOME_LINE1 | BAddress1 | Address* | 
-ADDRESS_HOME_LINE2 | BAddress2 | Address 2 | 
-ADDRESS_HOME_CITY | BCity | City* | 
-ADDRESS_HOME_STATE | BState | State* | AK
-ADDRESS_HOME_ZIP | BZip | Zip Code* | 
-PHONE_HOME_CITY_CODE | BNightPhone_tel1 | Shipping Phone* | 
-PHONE_HOME_NUMBER | BNightPhone_tel2 | Exchange | 
-PHONE_HOME_NUMBER | BNightPhone_tel3 | Last four digits | 
-UNKNOWN_TYPE | BNightPhone_ext1 | Ext | 
-PHONE_HOME_CITY_CODE | BDayPhone_tel1 | Daytime Phone | 
-PHONE_HOME_NUMBER | BDayPhone_tel2 | Exchange | 
-PHONE_HOME_NUMBER | BDayPhone_tel3 | Last four digits | 
-UNKNOWN_TYPE | BDayPhone_ext1 | Ext | 
-UNKNOWN_TYPE | same | Is this your shipping address?* | 1
-UNKNOWN_TYPE | same | Yes No | 0
-NAME_FIRST | SFirstName | First Name* | 
-NAME_MIDDLE_INITIAL | SMI | MI | 
-NAME_LAST | SLastName | Last Name* | 
-COMPANY_NAME | SCompanyName | Company Name | 
-ADDRESS_HOME_LINE1 | SAddress1 | Address* | 
-ADDRESS_HOME_LINE2 | SAddress2 | Address 2 | 
-ADDRESS_HOME_CITY | SCity | City* | 
-ADDRESS_HOME_STATE | SState | State* | AK
-ADDRESS_HOME_ZIP | SZip | Zip Code* | 
-PHONE_HOME_CITY_CODE | ShippingPhone_tel1 | Shipping Phone* | 
-PHONE_HOME_NUMBER | ShippingPhone_tel2 | ) | 
-PHONE_HOME_NUMBER | ShippingPhone_tel3 | - | 
-UNKNOWN_TYPE | ShippingPhone_ext1 | Ext | 
-UNKNOWN_TYPE | custtype | Is this purchase for personal or business use? | 200
-UNKNOWN_TYPE | Age | Age | 
-UNKNOWN_TYPE | income | Income | 0
-UNKNOWN_TYPE | education | Education | 0
-UNKNOWN_TYPE | hob | Where did you hear about Newegg.com? | 0
-UNKNOWN_TYPE | FirstPurchase | Is this your first Newegg.com purchase? | 0
-UNKNOWN_TYPE | GameHours | How many hours per week do you play PC games? | 0
-UNKNOWN_TYPE | Spam | Sign me up for exclusive newsletter deals, sweepstakes, and 24-hour sales only available to subscribers | 1
-UNKNOWN_TYPE | SMS | I would like to receive SMS messages via my wireless device. | 1
+EMAIL_ADDRESS | LoginName | Email Address* |  | LoginName_1-default
+EMAIL_ADDRESS | LoginName1 | Confirm Email Address* |  | LoginName_1-default
+UNKNOWN_TYPE | Password | Password* |  | LoginName_1-default
+UNKNOWN_TYPE | Password1 | Confirm Password* |  | LoginName_1-default
+NAME_FIRST | FirstName | First Name* |  | LoginName_1-default
+NAME_MIDDLE_INITIAL | BMI | MI |  | LoginName_1-default
+NAME_LAST | LastName | Last Name* |  | LoginName_1-default
+COMPANY_NAME | BCompany | Company Name |  | LoginName_1-default
+ADDRESS_HOME_LINE1 | BAddress1 | Address* |  | LoginName_1-default
+ADDRESS_HOME_LINE2 | BAddress2 | Address 2 |  | LoginName_1-default
+ADDRESS_HOME_CITY | BCity | City* |  | LoginName_1-default
+ADDRESS_HOME_STATE | BState | State* | AK | LoginName_1-default
+ADDRESS_HOME_ZIP | BZip | Zip Code* |  | LoginName_1-default
+PHONE_HOME_CITY_CODE | BNightPhone_tel1 | Shipping Phone* |  | LoginName_1-default
+PHONE_HOME_NUMBER | BNightPhone_tel2 | Exchange |  | LoginName_1-default
+PHONE_HOME_NUMBER | BNightPhone_tel3 | Last four digits |  | LoginName_1-default
+UNKNOWN_TYPE | BNightPhone_ext1 | Ext |  | LoginName_1-default
+PHONE_HOME_CITY_CODE | BDayPhone_tel1 | Daytime Phone |  | LoginName_1-default
+PHONE_HOME_NUMBER | BDayPhone_tel2 | Exchange |  | LoginName_1-default
+PHONE_HOME_NUMBER | BDayPhone_tel3 | Last four digits |  | LoginName_1-default
+UNKNOWN_TYPE | BDayPhone_ext1 | Ext |  | LoginName_1-default
+UNKNOWN_TYPE | same | Is this your shipping address?* | 1 | LoginName_1-default
+UNKNOWN_TYPE | same | Yes No | 0 | LoginName_1-default
+NAME_FIRST | SFirstName | First Name* |  | SFirstName_1-default
+NAME_MIDDLE_INITIAL | SMI | MI |  | SFirstName_1-default
+NAME_LAST | SLastName | Last Name* |  | SFirstName_1-default
+COMPANY_NAME | SCompanyName | Company Name |  | SFirstName_1-default
+ADDRESS_HOME_LINE1 | SAddress1 | Address* |  | SFirstName_1-default
+ADDRESS_HOME_LINE2 | SAddress2 | Address 2 |  | SFirstName_1-default
+ADDRESS_HOME_CITY | SCity | City* |  | SFirstName_1-default
+ADDRESS_HOME_STATE | SState | State* | AK | SFirstName_1-default
+ADDRESS_HOME_ZIP | SZip | Zip Code* |  | SFirstName_1-default
+PHONE_HOME_CITY_CODE | ShippingPhone_tel1 | Shipping Phone* |  | SFirstName_1-default
+PHONE_HOME_NUMBER | ShippingPhone_tel2 | ) |  | SFirstName_1-default
+PHONE_HOME_NUMBER | ShippingPhone_tel3 | - |  | SFirstName_1-default
+UNKNOWN_TYPE | ShippingPhone_ext1 | Ext |  | SFirstName_1-default
+UNKNOWN_TYPE | custtype | Is this purchase for personal or business use? | 200 | SFirstName_1-default
+UNKNOWN_TYPE | Age | Age |  | SFirstName_1-default
+UNKNOWN_TYPE | income | Income | 0 | SFirstName_1-default
+UNKNOWN_TYPE | education | Education | 0 | SFirstName_1-default
+UNKNOWN_TYPE | hob | Where did you hear about Newegg.com? | 0 | SFirstName_1-default
+UNKNOWN_TYPE | FirstPurchase | Is this your first Newegg.com purchase? | 0 | SFirstName_1-default
+UNKNOWN_TYPE | GameHours | How many hours per week do you play PC games? | 0 | SFirstName_1-default
+UNKNOWN_TYPE | Spam | Sign me up for exclusive newsletter deals, sweepstakes, and 24-hour sales only available to subscribers | 1 | SFirstName_1-default
+UNKNOWN_TYPE | SMS | I would like to receive SMS messages via my wireless device. | 1 | SFirstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/12_register_officedepot.com.out b/chrome/test/data/autofill/heuristics/output/12_register_officedepot.com.out
index 00a5286..2d7a9c8 100644
--- a/chrome/test/data/autofill/heuristics/output/12_register_officedepot.com.out
+++ b/chrome/test/data/autofill/heuristics/output/12_register_officedepot.com.out
@@ -1,41 +1,41 @@
-NAME_FIRST | addrsForm[0].firstName | *First Name: | 
-NAME_MIDDLE_INITIAL | addrsForm[0].middleInitial | Middle Initial: | 
-NAME_LAST | addrsForm[0].lastName | *Last Name: | 
-COMPANY_NAME | addrsForm[0].shiptoName | Company Name | 
-ADDRESS_HOME_LINE1 | addrsForm[0].address1 | *Address | 
-ADDRESS_HOME_LINE2 | addrsForm[0].address2 | *First Name:Middle Initial:*Last Name:Company Name | 
-ADDRESS_HOME_CITY | addrsForm[0].city | *City | 
-ADDRESS_HOME_STATE | addrsForm[0].state | *State | {blank}
-ADDRESS_HOME_ZIP | addrsForm[0].postalCode1 | *Zip Code | 
-PHONE_HOME_CITY_CODE | addrsForm[0].phoneNumber1 | *Phone Number: | 
-PHONE_HOME_NUMBER | addrsForm[0].phoneNumber2 | - | 
-PHONE_HOME_NUMBER | addrsForm[0].phoneNumber3 | - | 
-UNKNOWN_TYPE | addrsForm[0].phoneNumber4 | ext. | 
-UNKNOWN_TYPE | addrsForm[0].faxNumber1 | Fax: | 
-UNKNOWN_TYPE | addrsForm[0].faxNumber2 | - | 
-UNKNOWN_TYPE | addrsForm[0].faxNumber3 | - | 
-EMAIL_ADDRESS | addrsForm[0].email | *Email Address: | 
-CREDIT_CARD_TYPE | paymentFormInfo.creditCardType | Credit Card Type: |  
-CREDIT_CARD_NUMBER | paymentFormInfo.creditCardNumber | Credit Card Number: | 
-CREDIT_CARD_EXP_MONTH | paymentFormInfo.creditCardExpMonth | Expiration Date: |  
-CREDIT_CARD_EXP_4_DIGIT_YEAR | paymentFormInfo.creditCardExpYear | / | -1
-CREDIT_CARD_VERIFICATION_CODE | paymentFormInfo.creditCardCvv | CID | 
-UNKNOWN_TYPE | sameAsBilling | Currently Office Depot is unable to process orders online for delivery to APO/FPO, PO Box, and export addresses. Please click here for additional ordering options * Indicates required field | on
-NAME_FIRST | addrsForm[2].firstName | *First Name: | 
-NAME_MIDDLE_INITIAL | addrsForm[2].middleInitial | Middle Initial: | 
-NAME_LAST | addrsForm[2].lastName | *Last Name: | 
-COMPANY_NAME | addrsForm[2].shiptoName | Company Name | 
-ADDRESS_HOME_LINE1 | addrsForm[2].address1 | *Address | 
-ADDRESS_HOME_LINE2 | addrsForm[2].address2 | * Indicates required field *First Name:Middle Initial:*Last Name:Company Name | 
-ADDRESS_HOME_CITY | addrsForm[2].city | *City | 
-ADDRESS_HOME_STATE | addrsForm[2].state | *State | {blank}
-ADDRESS_HOME_ZIP | addrsForm[2].postalCode1 | *Zip Code | 
-PHONE_HOME_CITY_CODE | addrsForm[2].phoneNumber1 | *Phone Number: | 
-PHONE_HOME_NUMBER | addrsForm[2].phoneNumber2 | - | 
-PHONE_HOME_NUMBER | addrsForm[2].phoneNumber3 | - | 
-UNKNOWN_TYPE | addrsForm[2].phoneNumber4 | ext. | 
-EMAIL_ADDRESS | addrsForm[2].email | *Email Address: | 
-UNKNOWN_TYPE | loginForm.loginName | *Login Name: | 
-UNKNOWN_TYPE | loginForm.password | *Password: | 
-UNKNOWN_TYPE | loginForm.passwordConfirm | *Password Confirm: | 
-UNKNOWN_TYPE | loginForm.autoLogin | *Password Confirm: | on
+NAME_FIRST | addrsForm[0].firstName | *First Name: |  | addrsForm[0].firstName_1-default
+NAME_MIDDLE_INITIAL | addrsForm[0].middleInitial | Middle Initial: |  | addrsForm[0].firstName_1-default
+NAME_LAST | addrsForm[0].lastName | *Last Name: |  | addrsForm[0].firstName_1-default
+COMPANY_NAME | addrsForm[0].shiptoName | Company Name |  | addrsForm[0].firstName_1-default
+ADDRESS_HOME_LINE1 | addrsForm[0].address1 | *Address |  | addrsForm[0].firstName_1-default
+ADDRESS_HOME_LINE2 | addrsForm[0].address2 | *First Name:Middle Initial:*Last Name:Company Name |  | addrsForm[0].firstName_1-default
+ADDRESS_HOME_CITY | addrsForm[0].city | *City |  | addrsForm[0].firstName_1-default
+ADDRESS_HOME_STATE | addrsForm[0].state | *State | {blank} | addrsForm[0].firstName_1-default
+ADDRESS_HOME_ZIP | addrsForm[0].postalCode1 | *Zip Code |  | addrsForm[0].firstName_1-default
+PHONE_HOME_CITY_CODE | addrsForm[0].phoneNumber1 | *Phone Number: |  | addrsForm[0].firstName_1-default
+PHONE_HOME_NUMBER | addrsForm[0].phoneNumber2 | - |  | addrsForm[0].firstName_1-default
+PHONE_HOME_NUMBER | addrsForm[0].phoneNumber3 | - |  | addrsForm[0].firstName_1-default
+UNKNOWN_TYPE | addrsForm[0].phoneNumber4 | ext. |  | addrsForm[0].firstName_1-default
+UNKNOWN_TYPE | addrsForm[0].faxNumber1 | Fax: |  | addrsForm[0].firstName_1-default
+UNKNOWN_TYPE | addrsForm[0].faxNumber2 | - |  | addrsForm[0].firstName_1-default
+UNKNOWN_TYPE | addrsForm[0].faxNumber3 | - |  | addrsForm[0].firstName_1-default
+EMAIL_ADDRESS | addrsForm[0].email | *Email Address: |  | addrsForm[0].firstName_1-default
+CREDIT_CARD_TYPE | paymentFormInfo.creditCardType | Credit Card Type: |   | addrsForm[0].firstName_1-cc
+CREDIT_CARD_NUMBER | paymentFormInfo.creditCardNumber | Credit Card Number: |  | addrsForm[0].firstName_1-cc
+CREDIT_CARD_EXP_MONTH | paymentFormInfo.creditCardExpMonth | Expiration Date: |   | addrsForm[0].firstName_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | paymentFormInfo.creditCardExpYear | / | -1 | addrsForm[0].firstName_1-cc
+CREDIT_CARD_VERIFICATION_CODE | paymentFormInfo.creditCardCvv | CID |  | addrsForm[0].firstName_1-cc
+UNKNOWN_TYPE | sameAsBilling | Currently Office Depot is unable to process orders online for delivery to APO/FPO, PO Box, and export addresses. Please click here for additional ordering options * Indicates required field | on | addrsForm[0].firstName_1-default
+NAME_FIRST | addrsForm[2].firstName | *First Name: |  | addrsForm[2].firstName_1-default
+NAME_MIDDLE_INITIAL | addrsForm[2].middleInitial | Middle Initial: |  | addrsForm[2].firstName_1-default
+NAME_LAST | addrsForm[2].lastName | *Last Name: |  | addrsForm[2].firstName_1-default
+COMPANY_NAME | addrsForm[2].shiptoName | Company Name |  | addrsForm[2].firstName_1-default
+ADDRESS_HOME_LINE1 | addrsForm[2].address1 | *Address |  | addrsForm[2].firstName_1-default
+ADDRESS_HOME_LINE2 | addrsForm[2].address2 | * Indicates required field *First Name:Middle Initial:*Last Name:Company Name |  | addrsForm[2].firstName_1-default
+ADDRESS_HOME_CITY | addrsForm[2].city | *City |  | addrsForm[2].firstName_1-default
+ADDRESS_HOME_STATE | addrsForm[2].state | *State | {blank} | addrsForm[2].firstName_1-default
+ADDRESS_HOME_ZIP | addrsForm[2].postalCode1 | *Zip Code |  | addrsForm[2].firstName_1-default
+PHONE_HOME_CITY_CODE | addrsForm[2].phoneNumber1 | *Phone Number: |  | addrsForm[2].firstName_1-default
+PHONE_HOME_NUMBER | addrsForm[2].phoneNumber2 | - |  | addrsForm[2].firstName_1-default
+PHONE_HOME_NUMBER | addrsForm[2].phoneNumber3 | - |  | addrsForm[2].firstName_1-default
+UNKNOWN_TYPE | addrsForm[2].phoneNumber4 | ext. |  | addrsForm[2].firstName_1-default
+EMAIL_ADDRESS | addrsForm[2].email | *Email Address: |  | addrsForm[2].firstName_1-default
+UNKNOWN_TYPE | loginForm.loginName | *Login Name: |  | addrsForm[2].firstName_1-default
+UNKNOWN_TYPE | loginForm.password | *Password: |  | addrsForm[2].firstName_1-default
+UNKNOWN_TYPE | loginForm.passwordConfirm | *Password Confirm: |  | addrsForm[2].firstName_1-default
+UNKNOWN_TYPE | loginForm.autoLogin | *Password Confirm: | on | addrsForm[2].firstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/12_register_officemax.com.out b/chrome/test/data/autofill/heuristics/output/12_register_officemax.com.out
index d62bb27..0630083 100644
--- a/chrome/test/data/autofill/heuristics/output/12_register_officemax.com.out
+++ b/chrome/test/data/autofill/heuristics/output/12_register_officemax.com.out
@@ -1,8 +1,8 @@
-UNKNOWN_TYPE | /atg/userprofiling/ProfileFormHandler.value.maxPerks | MaxPerks® ID No. | 
-NAME_FIRST | /atg/userprofiling/ProfileFormHandler.value.firstName | * First Name: | 
-NAME_LAST | /atg/userprofiling/ProfileFormHandler.value.lastName | * Last Name: | 
-EMAIL_ADDRESS | /atg/userprofiling/ProfileFormHandler.value.login | * Email Address: | 
-EMAIL_ADDRESS | /atg/userprofiling/ProfileFormHandler.confirmEmailAddress | * Confirm Email: | 
-ADDRESS_HOME_ZIP | /atg/userprofiling/ProfileFormHandler.value.zip | * Zip: | 
-UNKNOWN_TYPE | /atg/userprofiling/ProfileFormHandler.value.password | * Password: | 
-UNKNOWN_TYPE | /atg/userprofiling/ProfileFormHandler.value.confirmPassword | * Confirm Password: | 
+UNKNOWN_TYPE | /atg/userprofiling/ProfileFormHandler.value.maxPerks | MaxPerks® ID No. |  | /atg/userprofiling/ProfileFormHandler.value.maxPerks_1-default
+NAME_FIRST | /atg/userprofiling/ProfileFormHandler.value.firstName | * First Name: |  | /atg/userprofiling/ProfileFormHandler.value.maxPerks_1-default
+NAME_LAST | /atg/userprofiling/ProfileFormHandler.value.lastName | * Last Name: |  | /atg/userprofiling/ProfileFormHandler.value.maxPerks_1-default
+EMAIL_ADDRESS | /atg/userprofiling/ProfileFormHandler.value.login | * Email Address: |  | /atg/userprofiling/ProfileFormHandler.value.maxPerks_1-default
+EMAIL_ADDRESS | /atg/userprofiling/ProfileFormHandler.confirmEmailAddress | * Confirm Email: |  | /atg/userprofiling/ProfileFormHandler.value.maxPerks_1-default
+ADDRESS_HOME_ZIP | /atg/userprofiling/ProfileFormHandler.value.zip | * Zip: |  | /atg/userprofiling/ProfileFormHandler.value.maxPerks_1-default
+UNKNOWN_TYPE | /atg/userprofiling/ProfileFormHandler.value.password | * Password: |  | /atg/userprofiling/ProfileFormHandler.value.maxPerks_1-default
+UNKNOWN_TYPE | /atg/userprofiling/ProfileFormHandler.value.confirmPassword | * Confirm Password: |  | /atg/userprofiling/ProfileFormHandler.value.maxPerks_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/12_register_pyramidcollection.com.out b/chrome/test/data/autofill/heuristics/output/12_register_pyramidcollection.com.out
index 0539223..6acca3c 100644
--- a/chrome/test/data/autofill/heuristics/output/12_register_pyramidcollection.com.out
+++ b/chrome/test/data/autofill/heuristics/output/12_register_pyramidcollection.com.out
@@ -1,24 +1,24 @@
-EMAIL_ADDRESS | E1 | Email Address * | 
-NAME_FIRST | F1 | First Name * | 
-NAME_LAST | L1 | Last Name * | 
-ADDRESS_HOME_LINE1 | S1 | Address Line 1 * | 
-ADDRESS_HOME_LINE2 | R1 | Address Line 2 | 
-ADDRESS_HOME_CITY | C2 | City * | 
-ADDRESS_HOME_STATE | S2 | State * | 
-ADDRESS_HOME_COUNTRY | C3 | Country * | 0000
-ADDRESS_HOME_ZIP | Z1 | Zip Code * | 
-PHONE_HOME_WHOLE_NUMBER | P2 | Day Phone * | 
-PHONE_HOME_WHOLE_NUMBER | P3 | Evening Phone | 
-UNKNOWN_TYPE | P1 | Create Password * | 
-UNKNOWN_TYPE | PasswordConfirm | Confirm Password * | 
-NAME_FIRST | SF1 | First Name * | 
-NAME_LAST | SL1 | Last Name * | 
-ADDRESS_HOME_LINE1 | SS1 | Address Line 1 * | 
-ADDRESS_HOME_LINE2 | SR1 | Address Line 2 | 
-ADDRESS_HOME_CITY | SC2 | City * | 
-ADDRESS_HOME_STATE | SS2 | State * | 
-ADDRESS_HOME_COUNTRY | SC3 | Country * | 0000
-ADDRESS_HOME_ZIP | SZ1 | Zip Code * | 
-PHONE_HOME_WHOLE_NUMBER | SP2 | Day Phone * | 
-PHONE_HOME_WHOLE_NUMBER | SP3 | Evening Phone | 
-UNKNOWN_TYPE | sameAsBilling | Email Address * First Name * Last Name Address Line 1 First Name Last Name | on
+EMAIL_ADDRESS | E1 | Email Address * |  | E1_1-default
+NAME_FIRST | F1 | First Name * |  | E1_1-default
+NAME_LAST | L1 | Last Name * |  | E1_1-default
+ADDRESS_HOME_LINE1 | S1 | Address Line 1 * |  | E1_1-default
+ADDRESS_HOME_LINE2 | R1 | Address Line 2 |  | E1_1-default
+ADDRESS_HOME_CITY | C2 | City * |  | E1_1-default
+ADDRESS_HOME_STATE | S2 | State * |  | E1_1-default
+ADDRESS_HOME_COUNTRY | C3 | Country * | 0000 | E1_1-default
+ADDRESS_HOME_ZIP | Z1 | Zip Code * |  | E1_1-default
+PHONE_HOME_WHOLE_NUMBER | P2 | Day Phone * |  | E1_1-default
+PHONE_HOME_WHOLE_NUMBER | P3 | Evening Phone |  | E1_1-default
+UNKNOWN_TYPE | P1 | Create Password * |  | E1_1-default
+UNKNOWN_TYPE | PasswordConfirm | Confirm Password * |  | E1_1-default
+NAME_FIRST | SF1 | First Name * |  | SF1_1-default
+NAME_LAST | SL1 | Last Name * |  | SF1_1-default
+ADDRESS_HOME_LINE1 | SS1 | Address Line 1 * |  | SF1_1-default
+ADDRESS_HOME_LINE2 | SR1 | Address Line 2 |  | SF1_1-default
+ADDRESS_HOME_CITY | SC2 | City * |  | SF1_1-default
+ADDRESS_HOME_STATE | SS2 | State * |  | SF1_1-default
+ADDRESS_HOME_COUNTRY | SC3 | Country * | 0000 | SF1_1-default
+ADDRESS_HOME_ZIP | SZ1 | Zip Code * |  | SF1_1-default
+PHONE_HOME_WHOLE_NUMBER | SP2 | Day Phone * |  | SF1_1-default
+PHONE_HOME_WHOLE_NUMBER | SP3 | Evening Phone |  | SF1_1-default
+UNKNOWN_TYPE | sameAsBilling | Email Address * First Name * Last Name Address Line 1 First Name Last Name | on | SF1_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/12_register_rediff.com.out b/chrome/test/data/autofill/heuristics/output/12_register_rediff.com.out
index a3e1bc9..e398a19f 100644
--- a/chrome/test/data/autofill/heuristics/output/12_register_rediff.com.out
+++ b/chrome/test/data/autofill/heuristics/output/12_register_rediff.com.out
@@ -1,18 +1,18 @@
-NAME_FULL | name | : | 
-UNKNOWN_TYPE | login | : | 
-UNKNOWN_TYPE | passwd | : | 
-UNKNOWN_TYPE | confirm_passwd | : | 
-EMAIL_ADDRESS | altemail | : | 
-UNKNOWN_TYPE | chk_altemail |  | on
-UNKNOWN_TYPE | hintq | : | 
-UNKNOWN_TYPE | hinta | : | 
-UNKNOWN_TYPE | mothername | : | 
-UNKNOWN_TYPE | DOB_Day | : | 
-UNKNOWN_TYPE | DOB_Month | : | 
-UNKNOWN_TYPE | DOB_Year | : | 
-UNKNOWN_TYPE | gender | : | m
-UNKNOWN_TYPE | gender | Male | f
-ADDRESS_HOME_COUNTRY | country | : | 99
-ADDRESS_HOME_CITY | city | : | 
-UNKNOWN_TYPE | othercity | City : | 
-UNKNOWN_TYPE | 75cd7feb6ce926e1efbb8b96c0fb71c0 | : | 
+NAME_FULL | name | : |  | name_1-default
+UNKNOWN_TYPE | login | : |  | name_1-default
+UNKNOWN_TYPE | passwd | : |  | name_1-default
+UNKNOWN_TYPE | confirm_passwd | : |  | name_1-default
+EMAIL_ADDRESS | altemail | : |  | name_1-default
+UNKNOWN_TYPE | chk_altemail |  | on | name_1-default
+UNKNOWN_TYPE | hintq | : |  | name_1-default
+UNKNOWN_TYPE | hinta | : |  | name_1-default
+UNKNOWN_TYPE | mothername | : |  | name_1-default
+UNKNOWN_TYPE | DOB_Day | : |  | name_1-default
+UNKNOWN_TYPE | DOB_Month | : |  | name_1-default
+UNKNOWN_TYPE | DOB_Year | : |  | name_1-default
+UNKNOWN_TYPE | gender | : | m | name_1-default
+UNKNOWN_TYPE | gender | Male | f | name_1-default
+ADDRESS_HOME_COUNTRY | country | : | 99 | name_1-default
+ADDRESS_HOME_CITY | city | : |  | name_1-default
+UNKNOWN_TYPE | othercity | City : |  | name_1-default
+UNKNOWN_TYPE | 75cd7feb6ce926e1efbb8b96c0fb71c0 | : |  | name_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/12_register_rei.com.out b/chrome/test/data/autofill/heuristics/output/12_register_rei.com.out
index 141020e..11dbe7a 100644
--- a/chrome/test/data/autofill/heuristics/output/12_register_rei.com.out
+++ b/chrome/test/data/autofill/heuristics/output/12_register_rei.com.out
@@ -1,8 +1,8 @@
-NAME_FIRST | firstName | First Name:* | 
-NAME_MIDDLE_INITIAL | middleName | Middle Initial: | 
-NAME_LAST | lastName | Last Name:* | 
-UNKNOWN_TYPE | logonPassword | Password:* | 
-UNKNOWN_TYPE | logonPasswordVerify | Re-type Password:* | 
-ADDRESS_HOME_ZIP | zipCode | ZIP (Postal) Code:* | 
-EMAIL_ADDRESS | email1 | E-mail Address:* | 
-UNKNOWN_TYPE | gearmail |  | y
+NAME_FIRST | firstName | First Name:* |  | firstName_1-default
+NAME_MIDDLE_INITIAL | middleName | Middle Initial: |  | firstName_1-default
+NAME_LAST | lastName | Last Name:* |  | firstName_1-default
+UNKNOWN_TYPE | logonPassword | Password:* |  | firstName_1-default
+UNKNOWN_TYPE | logonPasswordVerify | Re-type Password:* |  | firstName_1-default
+ADDRESS_HOME_ZIP | zipCode | ZIP (Postal) Code:* |  | firstName_1-default
+EMAIL_ADDRESS | email1 | E-mail Address:* |  | firstName_1-default
+UNKNOWN_TYPE | gearmail |  | y | firstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/13_register_rocketlawyer.com.out b/chrome/test/data/autofill/heuristics/output/13_register_rocketlawyer.com.out
index fcc8ed4..10711d0 100644
--- a/chrome/test/data/autofill/heuristics/output/13_register_rocketlawyer.com.out
+++ b/chrome/test/data/autofill/heuristics/output/13_register_rocketlawyer.com.out
@@ -1,8 +1,8 @@
-UNKNOWN_TYPE | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery |  | 
-NAME_FIRST | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtFirstName | First Name * | 
-NAME_LAST | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtLastName | Last Name * | 
-EMAIL_ADDRESS | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtUserName | Email Address * | 
-EMAIL_ADDRESS | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtConfirmUserName | Confirm Email Address * | 
-UNKNOWN_TYPE | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtPassword | Password * | 
-UNKNOWN_TYPE | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtConfirmPassword | Confirm Password * | 
-UNKNOWN_TYPE | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$chkNewsletter | Yes, send me Rocket Lawyer partner offers, which are sent no more than twice per month and are from Rocket Lawyer's trusted business partners. | on
+UNKNOWN_TYPE | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery |  |  | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery_1-default
+NAME_FIRST | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtFirstName | First Name * |  | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery_1-default
+NAME_LAST | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtLastName | Last Name * |  | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery_1-default
+EMAIL_ADDRESS | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtUserName | Email Address * |  | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery_1-default
+EMAIL_ADDRESS | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtConfirmUserName | Confirm Email Address * |  | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery_1-default
+UNKNOWN_TYPE | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtPassword | Password * |  | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery_1-default
+UNKNOWN_TYPE | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$txtConfirmPassword | Confirm Password * |  | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery_1-default
+UNKNOWN_TYPE | ctl00$ctl00$ctl00$SiteMasterBody$ContentPlaceHolder1$ContentPlaceHolder1$chkNewsletter | Yes, send me Rocket Lawyer partner offers, which are sent no more than twice per month and are from Rocket Lawyer's trusted business partners. | on | ctl00$ctl00$ctl00$SiteMasterBody$NewNavigationTabs$txtQuery_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/13_register_signup.clicksor.com.out b/chrome/test/data/autofill/heuristics/output/13_register_signup.clicksor.com.out
index bb639e4..6d0914f 100644
--- a/chrome/test/data/autofill/heuristics/output/13_register_signup.clicksor.com.out
+++ b/chrome/test/data/autofill/heuristics/output/13_register_signup.clicksor.com.out
@@ -1,16 +1,16 @@
-EMAIL_ADDRESS | email1 | Email: | 
-EMAIL_ADDRESS | email2 | Confirm                           email: | 
-UNKNOWN_TYPE | website | Website: | 
-PHONE_HOME_WHOLE_NUMBER | phone | Phone: | 
-UNKNOWN_TYPE | timezone | Time Zone: | 1
-UNKNOWN_TYPE | password | Password: | 
-UNKNOWN_TYPE | RePassword | Confirm                           password: | 
-NAME_FULL | name | Name: | 
-COMPANY_NAME | company | Company: | 
-ADDRESS_HOME_LINE1 | address | Address: | 
-ADDRESS_HOME_CITY | city | City: | 
-ADDRESS_HOME_STATE | province | State: | 
-ADDRESS_HOME_ZIP | zipCode | Zip                           code: | 
-ADDRESS_HOME_COUNTRY | country | Country: | US
-UNKNOWN_TYPE | termcheck | Country: | ON
-UNKNOWN_TYPE | securityCode | Enter                           the security code shown below: | 
+EMAIL_ADDRESS | email1 | Email: |  | email1_1-default
+EMAIL_ADDRESS | email2 | Confirm                           email: |  | email1_1-default
+UNKNOWN_TYPE | website | Website: |  | email1_1-default
+PHONE_HOME_WHOLE_NUMBER | phone | Phone: |  | email1_1-default
+UNKNOWN_TYPE | timezone | Time Zone: | 1 | email1_1-default
+UNKNOWN_TYPE | password | Password: |  | email1_1-default
+UNKNOWN_TYPE | RePassword | Confirm                           password: |  | email1_1-default
+NAME_FULL | name | Name: |  | email1_1-default
+COMPANY_NAME | company | Company: |  | email1_1-default
+ADDRESS_HOME_LINE1 | address | Address: |  | email1_1-default
+ADDRESS_HOME_CITY | city | City: |  | email1_1-default
+ADDRESS_HOME_STATE | province | State: |  | email1_1-default
+ADDRESS_HOME_ZIP | zipCode | Zip                           code: |  | email1_1-default
+ADDRESS_HOME_COUNTRY | country | Country: | US | email1_1-default
+UNKNOWN_TYPE | termcheck | Country: | ON | email1_1-default
+UNKNOWN_TYPE | securityCode | Enter                           the security code shown below: |  | email1_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/13_register_signup.live.com.out b/chrome/test/data/autofill/heuristics/output/13_register_signup.live.com.out
index 90ef072..80de5a81 100644
--- a/chrome/test/data/autofill/heuristics/output/13_register_signup.live.com.out
+++ b/chrome/test/data/autofill/heuristics/output/13_register_signup.live.com.out
@@ -1,17 +1,17 @@
-UNKNOWN_TYPE | imembernamelive | Windows Live ID: | 
-UNKNOWN_TYPE | idomain | Domains | hotmail.com
-UNKNOWN_TYPE | isug1 | Enter a word |  Enter a word
-UNKNOWN_TYPE | isug2 | Enter another word |  Enter another word
-UNKNOWN_TYPE | isug3 | Enter another word |  Enter another word
-EMAIL_ADDRESS | imembernameeasi | Use your email address: | Example: someone@example.com
-UNKNOWN_TYPE | iPwd | Create a password: | 
-UNKNOWN_TYPE | iRetypePwd | Retype password: | 
-EMAIL_ADDRESS | iAltEmail | Alternate email address: | 
-UNKNOWN_TYPE | iSQ | Question: | 0
-UNKNOWN_TYPE | iSA | Secret answer: | 
-NAME_FIRST | iFirstName | First name: | 
-NAME_LAST | iLastName | Last name: | 
-UNKNOWN_TYPE | profile_gender |  | m
-UNKNOWN_TYPE | profile_gender |  | f
-UNKNOWN_TYPE | iBirthYear | Birth year: | Example: 1990
-UNKNOWN_TYPE | iOptinEmail | Send me email with promotional offers and survey invitations from Windows Live, Bing, and MSN. (You can unsubscribe at any time.) | on
+UNKNOWN_TYPE | imembernamelive | Windows Live ID: |  | imembernamelive_1-default
+UNKNOWN_TYPE | idomain | Domains | hotmail.com | imembernamelive_1-default
+UNKNOWN_TYPE | isug1 | Enter a word |  Enter a word | imembernamelive_1-default
+UNKNOWN_TYPE | isug2 | Enter another word |  Enter another word | imembernamelive_1-default
+UNKNOWN_TYPE | isug3 | Enter another word |  Enter another word | imembernamelive_1-default
+EMAIL_ADDRESS | imembernameeasi | Use your email address: | Example: someone@example.com | imembernamelive_1-default
+UNKNOWN_TYPE | iPwd | Create a password: |  | imembernamelive_1-default
+UNKNOWN_TYPE | iRetypePwd | Retype password: |  | imembernamelive_1-default
+EMAIL_ADDRESS | iAltEmail | Alternate email address: |  | iAltEmail_1-default
+UNKNOWN_TYPE | iSQ | Question: | 0 | iAltEmail_1-default
+UNKNOWN_TYPE | iSA | Secret answer: |  | iAltEmail_1-default
+NAME_FIRST | iFirstName | First name: |  | iAltEmail_1-default
+NAME_LAST | iLastName | Last name: |  | iAltEmail_1-default
+UNKNOWN_TYPE | profile_gender |  | m | iAltEmail_1-default
+UNKNOWN_TYPE | profile_gender |  | f | iAltEmail_1-default
+UNKNOWN_TYPE | iBirthYear | Birth year: | Example: 1990 | iAltEmail_1-default
+UNKNOWN_TYPE | iOptinEmail | Send me email with promotional offers and survey invitations from Windows Live, Bing, and MSN. (You can unsubscribe at any time.) | on | iAltEmail_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/13_register_sourceforge.net.out b/chrome/test/data/autofill/heuristics/output/13_register_sourceforge.net.out
index 589e7ad..8d38048 100644
--- a/chrome/test/data/autofill/heuristics/output/13_register_sourceforge.net.out
+++ b/chrome/test/data/autofill/heuristics/output/13_register_sourceforge.net.out
@@ -1,18 +1,18 @@
-NAME_FULL | X1mRVeMqejLnZpd1etxNGHllat2M | Name: | 
-EMAIL_ADDRESS | X129ZdMbfixhIflk8_zHDFWB72qk | Email: | 
-UNKNOWN_TYPE | X2n9HcN3dx1-mSbLywp_L-szMydw | Username: | 
-UNKNOWN_TYPE | X2npVZtzEyUCnSbLywp_L-szMydw | Password: | 
-UNKNOWN_TYPE | XwnpVZtzEyUCnO_sWtjjnr86sK5Q | Confirm Password: | 
-UNKNOWN_TYPE | X2mZVe8jGx1WmSbLywp_L-szMydw | Language: | 275
-ADDRESS_HOME_COUNTRY | X1WlbYMHH1EvuThNjGRupsu5JwuU | Country: | US
-UNKNOWN_TYPE | X2n5deMrJyVymSbLywp_L-szMydw | Time Zone: | America/New_York
-UNKNOWN_TYPE | Xw3lRdtrBz0a6O-kMvS36tMzvLDU | Security Question: | What was the name of your first pet?
-UNKNOWN_TYPE | X3WlBZtvcy22yEf0KrDfhs46rigU | Security Question: | 
-UNKNOWN_TYPE | X3XlRdtrBz0a6O_kXqynrr46rigU | Security Answer: | 
-UNKNOWN_TYPE | X0WBbd4KZLSgCIb8WlZZNJ3g3fVk | Job Title: | 
-UNKNOWN_TYPE | X229ZZcPc31emF7VTU0RPmITuTNc | Number of Employees: | 
-UNKNOWN_TYPE | X12VEYcbdixhIflk8_zHDFWB72qk |  | siteupdates
-UNKNOWN_TYPE | X12VEYcbdixhIflk8_zHDFWB72qk |  | research
-UNKNOWN_TYPE | X12VEYcbdixhIflk8_zHDFWB72qk |  | thirdparty
-UNKNOWN_TYPE | X1GJbe8rKlh_p74K4nXnhkGtC-8Q | You seem to have CSS turned off. Please don't fill out this field. | 
-UNKNOWN_TYPE | X1GJbe8rKlx_p74K4nXnhkGtC-8Q | You seem to have CSS turned off. Please don't fill out this field. | 
+NAME_FULL | X1mRVeMqejLnZpd1etxNGHllat2M | Name: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+EMAIL_ADDRESS | X129ZdMbfixhIflk8_zHDFWB72qk | Email: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X2n9HcN3dx1-mSbLywp_L-szMydw | Username: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X2npVZtzEyUCnSbLywp_L-szMydw | Password: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | XwnpVZtzEyUCnO_sWtjjnr86sK5Q | Confirm Password: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X2mZVe8jGx1WmSbLywp_L-szMydw | Language: | 275 | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+ADDRESS_HOME_COUNTRY | X1WlbYMHH1EvuThNjGRupsu5JwuU | Country: | US | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X2n5deMrJyVymSbLywp_L-szMydw | Time Zone: | America/New_York | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | Xw3lRdtrBz0a6O-kMvS36tMzvLDU | Security Question: | What was the name of your first pet? | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X3WlBZtvcy22yEf0KrDfhs46rigU | Security Question: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X3XlRdtrBz0a6O_kXqynrr46rigU | Security Answer: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X0WBbd4KZLSgCIb8WlZZNJ3g3fVk | Job Title: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X229ZZcPc31emF7VTU0RPmITuTNc | Number of Employees: |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X12VEYcbdixhIflk8_zHDFWB72qk |  | siteupdates | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X12VEYcbdixhIflk8_zHDFWB72qk |  | research | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X12VEYcbdixhIflk8_zHDFWB72qk |  | thirdparty | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X1GJbe8rKlh_p74K4nXnhkGtC-8Q | You seem to have CSS turned off. Please don't fill out this field. |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
+UNKNOWN_TYPE | X1GJbe8rKlx_p74K4nXnhkGtC-8Q | You seem to have CSS turned off. Please don't fill out this field. |  | X1mRVeMqejLnZpd1etxNGHllat2M_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/13_register_supershuttle.com.out b/chrome/test/data/autofill/heuristics/output/13_register_supershuttle.com.out
index 60f88ab..8b9d7a4 100644
--- a/chrome/test/data/autofill/heuristics/output/13_register_supershuttle.com.out
+++ b/chrome/test/data/autofill/heuristics/output/13_register_supershuttle.com.out
@@ -1,11 +1,11 @@
-EMAIL_ADDRESS | ctl00$cphLeft$InnerLogin1$txtEmailAddress | Email Address | 
-UNKNOWN_TYPE | ctl00$cphLeft$InnerLogin1$txtPassword | Password | 
-EMAIL_ADDRESS | ctl00$cphRight$Registration1$txtEmailAddress | Email Address | 
-NAME_FIRST | ctl00$cphRight$Registration1$txtFirstName | First Name | 
-NAME_LAST | ctl00$cphRight$Registration1$txtLastName | Last Name | 
-PHONE_HOME_WHOLE_NUMBER | ctl00$cphRight$Registration1$txtCellPhone | Contact or Cell Phone Number | 
-PHONE_HOME_COUNTRY_CODE | ctl00$cphRight$Registration1$txtCountryCode | If outside the US (Country Code/Phone Number) | 
-PHONE_HOME_CITY_AND_NUMBER | ctl00$cphRight$Registration1$txtIntPhoneNumber | Contact or Cell Phone Number | 
-UNKNOWN_TYPE | ctl00$cphRight$Registration1$txtPassword | Password | 
-UNKNOWN_TYPE | ctl00$cphRight$Registration1$txtConfirmPassword | Confirm Password | 
-UNKNOWN_TYPE | ctl00$cphRight$Registration1$chkAcceptSpecialOffers | Email me regarding SuperShuttle special offers and promotions | on
+EMAIL_ADDRESS | ctl00$cphLeft$InnerLogin1$txtEmailAddress | Email Address |  | ctl00$cphLeft$InnerLogin1$txtEmailAddress_1-default
+UNKNOWN_TYPE | ctl00$cphLeft$InnerLogin1$txtPassword | Password |  | ctl00$cphLeft$InnerLogin1$txtEmailAddress_1-default
+EMAIL_ADDRESS | ctl00$cphRight$Registration1$txtEmailAddress | Email Address |  | ctl00$cphRight$Registration1$txtEmailAddress_1-default
+NAME_FIRST | ctl00$cphRight$Registration1$txtFirstName | First Name |  | ctl00$cphRight$Registration1$txtEmailAddress_1-default
+NAME_LAST | ctl00$cphRight$Registration1$txtLastName | Last Name |  | ctl00$cphRight$Registration1$txtEmailAddress_1-default
+PHONE_HOME_WHOLE_NUMBER | ctl00$cphRight$Registration1$txtCellPhone | Contact or Cell Phone Number |  | ctl00$cphRight$Registration1$txtEmailAddress_1-default
+PHONE_HOME_COUNTRY_CODE | ctl00$cphRight$Registration1$txtCountryCode | If outside the US (Country Code/Phone Number) |  | ctl00$cphRight$Registration1$txtEmailAddress_1-default
+PHONE_HOME_CITY_AND_NUMBER | ctl00$cphRight$Registration1$txtIntPhoneNumber | Contact or Cell Phone Number |  | ctl00$cphRight$Registration1$txtEmailAddress_1-default
+UNKNOWN_TYPE | ctl00$cphRight$Registration1$txtPassword | Password |  | ctl00$cphRight$Registration1$txtEmailAddress_1-default
+UNKNOWN_TYPE | ctl00$cphRight$Registration1$txtConfirmPassword | Confirm Password |  | ctl00$cphRight$Registration1$txtEmailAddress_1-default
+UNKNOWN_TYPE | ctl00$cphRight$Registration1$chkAcceptSpecialOffers | Email me regarding SuperShuttle special offers and promotions | on | ctl00$cphRight$Registration1$txtEmailAddress_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/14_register_target.com.out b/chrome/test/data/autofill/heuristics/output/14_register_target.com.out
index 1067919..bd90100 100644
--- a/chrome/test/data/autofill/heuristics/output/14_register_target.com.out
+++ b/chrome/test/data/autofill/heuristics/output/14_register_target.com.out
@@ -1,8 +1,8 @@
-UNKNOWN_TYPE | userName | Your name:* | 
-EMAIL_ADDRESS | email | Your email address:* | 
-EMAIL_ADDRESS | emailCheck | Re-enter email address:* | 
-UNKNOWN_TYPE | password | Create a password:* | 
-UNKNOWN_TYPE | passwordCheck | Re-enter password:* | 
-UNKNOWN_TYPE | subscribeEmail | Yes, please send me e-mails about special offers, exclusives and promotions from Target. | 1
-UNKNOWN_TYPE | ageCheck |  | yes
-UNKNOWN_TYPE | ageCheck | Yes No | no
+UNKNOWN_TYPE | userName | Your name:* |  | userName_1-default
+EMAIL_ADDRESS | email | Your email address:* |  | userName_1-default
+EMAIL_ADDRESS | emailCheck | Re-enter email address:* |  | userName_1-default
+UNKNOWN_TYPE | password | Create a password:* |  | userName_1-default
+UNKNOWN_TYPE | passwordCheck | Re-enter password:* |  | userName_1-default
+UNKNOWN_TYPE | subscribeEmail | Yes, please send me e-mails about special offers, exclusives and promotions from Target. | 1 | userName_1-default
+UNKNOWN_TYPE | ageCheck |  | yes | userName_1-default
+UNKNOWN_TYPE | ageCheck | Yes No | no | userName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/14_register_threadless.com.out b/chrome/test/data/autofill/heuristics/output/14_register_threadless.com.out
index 6ba528d3..46aea7c 100644
--- a/chrome/test/data/autofill/heuristics/output/14_register_threadless.com.out
+++ b/chrome/test/data/autofill/heuristics/output/14_register_threadless.com.out
@@ -1,6 +1,6 @@
-UNKNOWN_TYPE | create_username | Desired username | 
-UNKNOWN_TYPE | create_password | Password | 
-UNKNOWN_TYPE | retype_password | Re-type password | 
-EMAIL_ADDRESS | email | Email | 
-UNKNOWN_TYPE | join_newsletter | Join our newsletter and be first to know about new tees and great deals! | on
-UNKNOWN_TYPE | recaptcha_response_field | Type the words above Type the numbers you hear | 
+UNKNOWN_TYPE | create_username | Desired username |  | create_username_1-default
+UNKNOWN_TYPE | create_password | Password |  | create_username_1-default
+UNKNOWN_TYPE | retype_password | Re-type password |  | create_username_1-default
+EMAIL_ADDRESS | email | Email |  | create_username_1-default
+UNKNOWN_TYPE | join_newsletter | Join our newsletter and be first to know about new tees and great deals! | on | create_username_1-default
+UNKNOWN_TYPE | recaptcha_response_field | Type the words above Type the numbers you hear |  | create_username_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/14_register_trueblue.jetblue.com.out b/chrome/test/data/autofill/heuristics/output/14_register_trueblue.jetblue.com.out
index 6283d54..75943bf 100644
--- a/chrome/test/data/autofill/heuristics/output/14_register_trueblue.jetblue.com.out
+++ b/chrome/test/data/autofill/heuristics/output/14_register_trueblue.jetblue.com.out
@@ -1,21 +1,21 @@
-UNKNOWN_TYPE | accountData.title | Title: | 
-NAME_FIRST | accountData.firstName | First name: | 
-NAME_MIDDLE | accountData.middleName | Middle name : | 
-NAME_LAST | accountData.lastName | Last name: | 
-UNKNOWN_TYPE | accountData.suffix | Suffix: | 
-ADDRESS_HOME_LINE1 | accountData.address | Street address 1: | 
-ADDRESS_HOME_LINE2 | accountData.address2 | Street address 2: | 
-ADDRESS_HOME_COUNTRY | accountData.country | Country: | USA
-ADDRESS_HOME_CITY | accountData.city | City: | 
-ADDRESS_HOME_STATE | accountData.state | State/Province: | 
-ADDRESS_HOME_ZIP | accountData.zip | Zip/Postal code: | 
-PHONE_HOME_WHOLE_NUMBER | accountData.phone | Phone number: | 
-UNKNOWN_TYPE | accountData.phoneType | Phone number: | M
-PHONE_HOME_WHOLE_NUMBER | accountData.alternatePhone | Alternate phone: | 
-UNKNOWN_TYPE | accountData.alternatePhoneType | Alternate phone: | 
-UNKNOWN_TYPE | accountData.fax | Fax: | 
-EMAIL_ADDRESS | accountData.email | Email address: | 
-EMAIL_ADDRESS | accountData.confirmEmail | Confirm email: | 
-UNKNOWN_TYPE | registrationPassword1 | Password: | 
-UNKNOWN_TYPE | registrationPassword2 | Confirm password: | 
-UNKNOWN_TYPE | accountData.entrollmentCode | Enrollment code: | 
+UNKNOWN_TYPE | accountData.title | Title: |  | accountData.title_1-default
+NAME_FIRST | accountData.firstName | First name: |  | accountData.title_1-default
+NAME_MIDDLE | accountData.middleName | Middle name : |  | accountData.title_1-default
+NAME_LAST | accountData.lastName | Last name: |  | accountData.title_1-default
+UNKNOWN_TYPE | accountData.suffix | Suffix: |  | accountData.title_1-default
+ADDRESS_HOME_LINE1 | accountData.address | Street address 1: |  | accountData.title_1-default
+ADDRESS_HOME_LINE2 | accountData.address2 | Street address 2: |  | accountData.title_1-default
+ADDRESS_HOME_COUNTRY | accountData.country | Country: | USA | accountData.title_1-default
+ADDRESS_HOME_CITY | accountData.city | City: |  | accountData.title_1-default
+ADDRESS_HOME_STATE | accountData.state | State/Province: |  | accountData.title_1-default
+ADDRESS_HOME_ZIP | accountData.zip | Zip/Postal code: |  | accountData.title_1-default
+PHONE_HOME_WHOLE_NUMBER | accountData.phone | Phone number: |  | accountData.title_1-default
+UNKNOWN_TYPE | accountData.phoneType | Phone number: | M | accountData.title_1-default
+PHONE_HOME_WHOLE_NUMBER | accountData.alternatePhone | Alternate phone: |  | accountData.title_1-default
+UNKNOWN_TYPE | accountData.alternatePhoneType | Alternate phone: |  | accountData.title_1-default
+UNKNOWN_TYPE | accountData.fax | Fax: |  | accountData.title_1-default
+EMAIL_ADDRESS | accountData.email | Email address: |  | accountData.title_1-default
+EMAIL_ADDRESS | accountData.confirmEmail | Confirm email: |  | accountData.title_1-default
+UNKNOWN_TYPE | registrationPassword1 | Password: |  | accountData.title_1-default
+UNKNOWN_TYPE | registrationPassword2 | Confirm password: |  | accountData.title_1-default
+UNKNOWN_TYPE | accountData.entrollmentCode | Enrollment code: |  | accountData.title_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/14_register_uhaul.com.out b/chrome/test/data/autofill/heuristics/output/14_register_uhaul.com.out
index 4a0be77..d00c155d9 100644
--- a/chrome/test/data/autofill/heuristics/output/14_register_uhaul.com.out
+++ b/chrome/test/data/autofill/heuristics/output/14_register_uhaul.com.out
@@ -1,10 +1,10 @@
-NAME_FULL | _ctl0:cphMainBody:txtName | Name | 
-COMPANY_NAME | _ctl0:cphMainBody:txtCompany | Company | 
-UNKNOWN_TYPE | _ctl0:cphMainBody:txtVendNo | Vendor Number | 
-UNKNOWN_TYPE | _ctl0:cphMainBody:txtEntity | U-Haul Shop Entity Number | 
-EMAIL_ADDRESS | _ctl0:cphMainBody:txtEmail | Email | 
-EMAIL_ADDRESS | _ctl0:cphMainBody:txtEmail0 | ReConfirm Email | 
-UNKNOWN_TYPE | _ctl0:cphMainBody:txtPassword | Password must be between 4 and 8 characters, contain at least one digit and one alphabetic character, and must not contain special characters. | 
-UNKNOWN_TYPE | _ctl0:cphMainBody:txtPassword0 | Password should be same as the above entered password | 
-PHONE_HOME_WHOLE_NUMBER | _ctl0:cphMainBody:txtPhone | Phone | 
-UNKNOWN_TYPE | _ctl0:cphMainBody:txtComments | Comments: | 
+NAME_FULL | _ctl0:cphMainBody:txtName | Name |  | _ctl0:cphMainBody:txtName_1-default
+COMPANY_NAME | _ctl0:cphMainBody:txtCompany | Company |  | _ctl0:cphMainBody:txtName_1-default
+UNKNOWN_TYPE | _ctl0:cphMainBody:txtVendNo | Vendor Number |  | _ctl0:cphMainBody:txtName_1-default
+UNKNOWN_TYPE | _ctl0:cphMainBody:txtEntity | U-Haul Shop Entity Number |  | _ctl0:cphMainBody:txtName_1-default
+EMAIL_ADDRESS | _ctl0:cphMainBody:txtEmail | Email |  | _ctl0:cphMainBody:txtName_1-default
+EMAIL_ADDRESS | _ctl0:cphMainBody:txtEmail0 | ReConfirm Email |  | _ctl0:cphMainBody:txtName_1-default
+UNKNOWN_TYPE | _ctl0:cphMainBody:txtPassword | Password must be between 4 and 8 characters, contain at least one digit and one alphabetic character, and must not contain special characters. |  | _ctl0:cphMainBody:txtName_1-default
+UNKNOWN_TYPE | _ctl0:cphMainBody:txtPassword0 | Password should be same as the above entered password |  | _ctl0:cphMainBody:txtName_1-default
+PHONE_HOME_WHOLE_NUMBER | _ctl0:cphMainBody:txtPhone | Phone |  | _ctl0:cphMainBody:txtName_1-default
+UNKNOWN_TYPE | _ctl0:cphMainBody:txtComments | Comments: |  | _ctl0:cphMainBody:txtName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/14_register_yahoo.com.out b/chrome/test/data/autofill/heuristics/output/14_register_yahoo.com.out
index 04f0aae..6b17176 100644
--- a/chrome/test/data/autofill/heuristics/output/14_register_yahoo.com.out
+++ b/chrome/test/data/autofill/heuristics/output/14_register_yahoo.com.out
@@ -1,20 +1,20 @@
-NAME_FIRST | firstname | Name | 
-NAME_LAST | secondname | Name | 
-UNKNOWN_TYPE | gender | Gender | 
-UNKNOWN_TYPE | mm | Birthday | 
-UNKNOWN_TYPE | dd | Birthday | 
-UNKNOWN_TYPE | yyyy | Birthday | 
-ADDRESS_HOME_COUNTRY | country | Country | us
-ADDRESS_HOME_ZIP | postalcode | Postal Code | 
-EMAIL_ADDRESS | yahooid | Yahoo! ID and Email | 
-UNKNOWN_TYPE | domain | @ | yahoo.com
-UNKNOWN_TYPE | password | Password | 
-UNKNOWN_TYPE | passwordconfirm | Re-type Password | 
-EMAIL_ADDRESS | altemail | Alternate Email (optional) | 
-UNKNOWN_TYPE | secquestion | Secret Question 1 | 
-UNKNOWN_TYPE | customsecquestion1 | Specify Your Question | 
-UNKNOWN_TYPE | secquestionanswer | Your Answer | 
-UNKNOWN_TYPE | secquestion2 | Secret Question 2 | 
-UNKNOWN_TYPE | customsecquestion2 | Specify Your Question | 
-UNKNOWN_TYPE | secquestionanswer2 | Your Answer | 
-UNKNOWN_TYPE | cword | Type the code shown | 
+NAME_FIRST | firstname | Name |  | firstname_1-default
+NAME_LAST | secondname | Name |  | firstname_1-default
+UNKNOWN_TYPE | gender | Gender |  | firstname_1-default
+UNKNOWN_TYPE | mm | Birthday |  | firstname_1-default
+UNKNOWN_TYPE | dd | Birthday |  | firstname_1-default
+UNKNOWN_TYPE | yyyy | Birthday |  | firstname_1-default
+ADDRESS_HOME_COUNTRY | country | Country | us | firstname_1-default
+ADDRESS_HOME_ZIP | postalcode | Postal Code |  | firstname_1-default
+EMAIL_ADDRESS | yahooid | Yahoo! ID and Email |  | firstname_1-default
+UNKNOWN_TYPE | domain | @ | yahoo.com | firstname_1-default
+UNKNOWN_TYPE | password | Password |  | firstname_1-default
+UNKNOWN_TYPE | passwordconfirm | Re-type Password |  | firstname_1-default
+EMAIL_ADDRESS | altemail | Alternate Email (optional) |  | altemail_1-default
+UNKNOWN_TYPE | secquestion | Secret Question 1 |  | altemail_1-default
+UNKNOWN_TYPE | customsecquestion1 | Specify Your Question |  | altemail_1-default
+UNKNOWN_TYPE | secquestionanswer | Your Answer |  | altemail_1-default
+UNKNOWN_TYPE | secquestion2 | Secret Question 2 |  | altemail_1-default
+UNKNOWN_TYPE | customsecquestion2 | Specify Your Question |  | altemail_1-default
+UNKNOWN_TYPE | secquestionanswer2 | Your Answer |  | altemail_1-default
+UNKNOWN_TYPE | cword | Type the code shown |  | altemail_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/15_crbug_40687.out b/chrome/test/data/autofill/heuristics/output/15_crbug_40687.out
index 7ab7f3fa3..7bc8ae8 100644
--- a/chrome/test/data/autofill/heuristics/output/15_crbug_40687.out
+++ b/chrome/test/data/autofill/heuristics/output/15_crbug_40687.out
@@ -1,15 +1,15 @@
-NAME_FIRST | user[billing][firstname] | First Name | 
-NAME_LAST | user[billing][lastname] | Last Name | 
-ADDRESS_HOME_LINE1 | user[billing][address_first] | Billing Address | 
-ADDRESS_HOME_LINE2 | user[billing][address_second] | Billing Suite/Apt # | 
-ADDRESS_HOME_CITY | user[billing][city] | Billing City | 
-ADDRESS_HOME_STATE | user[billing][state] | State/Province | CA
-ADDRESS_HOME_ZIP | user[billing][zip] | Billing Postal Code | 94043
-ADDRESS_HOME_COUNTRY | user[billing][country] | Billing Country | US
-PHONE_HOME_WHOLE_NUMBER | user[phone_first] | Phone Number | 
-EMAIL_ADDRESS | user[email] | Email Address | 
-EMAIL_ADDRESS | user[email_confirm] | Confirm Email Address | 
-CREDIT_CARD_NUMBER | payment[cc_number] | Credit Card Number | 
-CREDIT_CARD_EXP_MONTH | payment[cc_expmo] | Expiration Month | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | payment[cc_expyr] | Expiration Year | 
-CREDIT_CARD_VERIFICATION_CODE | payment[sigpanel] | CVV2/Panel Code | 
+NAME_FIRST | user[billing][firstname] | First Name |  | user[billing][firstname]_1-default
+NAME_LAST | user[billing][lastname] | Last Name |  | user[billing][firstname]_1-default
+ADDRESS_HOME_LINE1 | user[billing][address_first] | Billing Address |  | user[billing][firstname]_1-default
+ADDRESS_HOME_LINE2 | user[billing][address_second] | Billing Suite/Apt # |  | user[billing][firstname]_1-default
+ADDRESS_HOME_CITY | user[billing][city] | Billing City |  | user[billing][firstname]_1-default
+ADDRESS_HOME_STATE | user[billing][state] | State/Province | CA | user[billing][firstname]_1-default
+ADDRESS_HOME_ZIP | user[billing][zip] | Billing Postal Code | 94043 | user[billing][firstname]_1-default
+ADDRESS_HOME_COUNTRY | user[billing][country] | Billing Country | US | user[billing][firstname]_1-default
+PHONE_HOME_WHOLE_NUMBER | user[phone_first] | Phone Number |  | user[billing][firstname]_1-default
+EMAIL_ADDRESS | user[email] | Email Address |  | user[billing][firstname]_1-default
+EMAIL_ADDRESS | user[email_confirm] | Confirm Email Address |  | user[billing][firstname]_1-default
+CREDIT_CARD_NUMBER | payment[cc_number] | Credit Card Number |  | user[billing][firstname]_1-cc
+CREDIT_CARD_EXP_MONTH | payment[cc_expmo] | Expiration Month |  | user[billing][firstname]_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | payment[cc_expyr] | Expiration Year |  | user[billing][firstname]_1-cc
+CREDIT_CARD_VERIFICATION_CODE | payment[sigpanel] | CVV2/Panel Code |  | user[billing][firstname]_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/15_crbug_52198.out b/chrome/test/data/autofill/heuristics/output/15_crbug_52198.out
index 1de3682..c61e5ec73 100644
--- a/chrome/test/data/autofill/heuristics/output/15_crbug_52198.out
+++ b/chrome/test/data/autofill/heuristics/output/15_crbug_52198.out
@@ -1,18 +1,18 @@
-NAME_FIRST | firstName | *First (Given) Name: | 
-NAME_MIDDLE | middleName | Middle Name: | 
-NAME_LAST | lastName | *Last (Family) Name: | 
-UNKNOWN_TYPE | suffix | Generational Suffix: | 
-UNKNOWN_TYPE | otherFirstName | Other First Names: (For example, your nickname.) | 
-UNKNOWN_TYPE | otherLastName | Other Last Names: (For example, your maiden name.) | 
-UNKNOWN_TYPE | monthOfBirth | Month: | -
-UNKNOWN_TYPE | dayOfBirth | Day: | -
-UNKNOWN_TYPE | yearOfBirth | Year: | -
-ADDRESS_HOME_CITY | cityOrTownOfBirth | City or Town of Birth: | 
-ADDRESS_HOME_STATE | stateOrProvinceOfBirth | State or Province of Birth: (only if born in the US or Canada) | 
-ADDRESS_HOME_COUNTRY | countryOfBirth | Country of Birth: | 
-UNKNOWN_TYPE | studentSSNa | U.S. Social Security Number: (Why do we ask for your SSN?) | 
-UNKNOWN_TYPE | studentSSNb | - | 
-UNKNOWN_TYPE | studentSSNc | - | 
-UNKNOWN_TYPE | idCardNumber | UT Austin ID Card Number: | 
-EMAIL_ADDRESS | emailAddress | E-mail Address: | 
-EMAIL_ADDRESS | emailAddressVerify | Verify Your E-mail Address: | 
+NAME_FIRST | firstName | *First (Given) Name: |  | firstName_1-default
+NAME_MIDDLE | middleName | Middle Name: |  | firstName_1-default
+NAME_LAST | lastName | *Last (Family) Name: |  | firstName_1-default
+UNKNOWN_TYPE | suffix | Generational Suffix: |  | firstName_1-default
+UNKNOWN_TYPE | otherFirstName | Other First Names: (For example, your nickname.) |  | firstName_1-default
+UNKNOWN_TYPE | otherLastName | Other Last Names: (For example, your maiden name.) |  | firstName_1-default
+UNKNOWN_TYPE | monthOfBirth | Month: | - | firstName_1-default
+UNKNOWN_TYPE | dayOfBirth | Day: | - | firstName_1-default
+UNKNOWN_TYPE | yearOfBirth | Year: | - | firstName_1-default
+ADDRESS_HOME_CITY | cityOrTownOfBirth | City or Town of Birth: |  | firstName_1-default
+ADDRESS_HOME_STATE | stateOrProvinceOfBirth | State or Province of Birth: (only if born in the US or Canada) |  | firstName_1-default
+ADDRESS_HOME_COUNTRY | countryOfBirth | Country of Birth: |  | firstName_1-default
+UNKNOWN_TYPE | studentSSNa | U.S. Social Security Number: (Why do we ask for your SSN?) |  | firstName_1-default
+UNKNOWN_TYPE | studentSSNb | - |  | firstName_1-default
+UNKNOWN_TYPE | studentSSNc | - |  | firstName_1-default
+UNKNOWN_TYPE | idCardNumber | UT Austin ID Card Number: |  | firstName_1-default
+EMAIL_ADDRESS | emailAddress | E-mail Address: |  | firstName_1-default
+EMAIL_ADDRESS | emailAddressVerify | Verify Your E-mail Address: |  | firstName_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/15_crbug_53075.out b/chrome/test/data/autofill/heuristics/output/15_crbug_53075.out
index 3b6a857..8f8122a 100644
--- a/chrome/test/data/autofill/heuristics/output/15_crbug_53075.out
+++ b/chrome/test/data/autofill/heuristics/output/15_crbug_53075.out
@@ -1,27 +1,27 @@
-COMPANY_NAME | ecomms_company_name | Company Name: | 
-UNKNOWN_TYPE | ecomms_title | Title: | 
-NAME_FIRST | ecomms_first_name | First Name: | 
-NAME_LAST | ecomms_last_name | Last Name: | 
-PHONE_HOME_WHOLE_NUMBER | ecomms_telephone | Telephone: | 
-PHONE_HOME_WHOLE_NUMBER | ecomms_mobile | Mobile: | 
-EMAIL_ADDRESS | ecomms_email | Email Address: | x@foo.com
-UNKNOWN_TYPE | ecomms_password | Password: | abcdef
-UNKNOWN_TYPE | ecomms_password_confirm | Confirm password: | abcdef
-ADDRESS_HOME_LINE1 | ecomms_address1 | Address1: | 
-ADDRESS_HOME_LINE2 | ecomms_address2 | Address2: | 
-ADDRESS_HOME_CITY | ecomms_town | Town / City: | 
-ADDRESS_HOME_STATE | ecomms_county | County: | 
-ADDRESS_HOME_ZIP | ecomms_postcode | Postcode: | 
-ADDRESS_HOME_COUNTRY | ecomms_country | Country: | 224
-UNKNOWN_TYPE | delivery_address | Address Details Address1: Address2: Town / City: County: | 1
-UNKNOWN_TYPE | del_title | Title: | 
-NAME_FIRST | del_first_name | First Name: | 
-NAME_LAST | del_last_name | Last Name: | 
-PHONE_HOME_WHOLE_NUMBER | del_telephone | Telephone: | 
-PHONE_HOME_WHOLE_NUMBER | del_mobile | Mobile: | 
-ADDRESS_HOME_LINE1 | del_address1 | Address1: | 
-ADDRESS_HOME_LINE2 | del_address2 | Address2: | 
-ADDRESS_HOME_CITY | del_town | Town / City: | 
-ADDRESS_HOME_STATE | del_county | County: | 
-ADDRESS_HOME_ZIP | del_postcode | Postcode: | 
-ADDRESS_HOME_COUNTRY | ecomms_del_country | Country: | 224
+COMPANY_NAME | ecomms_company_name | Company Name: |  | ecomms_company_name_1-default
+UNKNOWN_TYPE | ecomms_title | Title: |  | ecomms_company_name_1-default
+NAME_FIRST | ecomms_first_name | First Name: |  | ecomms_company_name_1-default
+NAME_LAST | ecomms_last_name | Last Name: |  | ecomms_company_name_1-default
+PHONE_HOME_WHOLE_NUMBER | ecomms_telephone | Telephone: |  | ecomms_company_name_1-default
+PHONE_HOME_WHOLE_NUMBER | ecomms_mobile | Mobile: |  | ecomms_company_name_1-default
+EMAIL_ADDRESS | ecomms_email | Email Address: | x@foo.com | ecomms_company_name_1-default
+UNKNOWN_TYPE | ecomms_password | Password: | abcdef | ecomms_company_name_1-default
+UNKNOWN_TYPE | ecomms_password_confirm | Confirm password: | abcdef | ecomms_company_name_1-default
+ADDRESS_HOME_LINE1 | ecomms_address1 | Address1: |  | ecomms_company_name_1-default
+ADDRESS_HOME_LINE2 | ecomms_address2 | Address2: |  | ecomms_company_name_1-default
+ADDRESS_HOME_CITY | ecomms_town | Town / City: |  | ecomms_company_name_1-default
+ADDRESS_HOME_STATE | ecomms_county | County: |  | ecomms_company_name_1-default
+ADDRESS_HOME_ZIP | ecomms_postcode | Postcode: |  | ecomms_company_name_1-default
+ADDRESS_HOME_COUNTRY | ecomms_country | Country: | 224 | ecomms_company_name_1-default
+UNKNOWN_TYPE | delivery_address | Address Details Address1: Address2: Town / City: County: | 1 | ecomms_company_name_1-default
+UNKNOWN_TYPE | del_title | Title: |  | ecomms_company_name_1-default
+NAME_FIRST | del_first_name | First Name: |  | del_first_name_1-default
+NAME_LAST | del_last_name | Last Name: |  | del_first_name_1-default
+PHONE_HOME_WHOLE_NUMBER | del_telephone | Telephone: |  | del_first_name_1-default
+PHONE_HOME_WHOLE_NUMBER | del_mobile | Mobile: |  | del_first_name_1-default
+ADDRESS_HOME_LINE1 | del_address1 | Address1: |  | del_first_name_1-default
+ADDRESS_HOME_LINE2 | del_address2 | Address2: |  | del_first_name_1-default
+ADDRESS_HOME_CITY | del_town | Town / City: |  | del_first_name_1-default
+ADDRESS_HOME_STATE | del_county | County: |  | del_first_name_1-default
+ADDRESS_HOME_ZIP | del_postcode | Postcode: |  | del_first_name_1-default
+ADDRESS_HOME_COUNTRY | ecomms_del_country | Country: | 224 | del_first_name_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/15_crbug_64569.out b/chrome/test/data/autofill/heuristics/output/15_crbug_64569.out
index fc966fb..ef3dae3 100644
--- a/chrome/test/data/autofill/heuristics/output/15_crbug_64569.out
+++ b/chrome/test/data/autofill/heuristics/output/15_crbug_64569.out
@@ -1,15 +1,15 @@
-UNKNOWN_TYPE | payment_group | Payment Type We accept Visa, Mastercard, Discover, American Express, and PayPal. | cc
-UNKNOWN_TYPE | payment_group | Payment Type We accept Visa, Mastercard, Discover, American Express, and PayPal. | paypal
-CREDIT_CARD_NAME | ccFullName | (as it appears on the card) | 
-CREDIT_CARD_NUMBER | ccNumber | (no dashes or spaces) | 
-CREDIT_CARD_EXP_MONTH | ccExpMonth | Expiration date | 1
-CREDIT_CARD_EXP_4_DIGIT_YEAR | ccExpYear | Your name (as it appears on the card) Credit card number (no dashes or spaces) Expiration date | 2011
-CREDIT_CARD_VERIFICATION_CODE | ccSecurity | Security code | 
-UNKNOWN_TYPE | sameinfo | First name Last name | on
-NAME_FIRST | addrFirstName | First name | 
-NAME_LAST | addrLastName | Last name | 
-ADDRESS_HOME_LINE1 | addrStreet1 | (street address, PO box, company name) | 
-ADDRESS_HOME_LINE2 | addrStreet2 | (apt, suite, building, floor, etc) | 
-ADDRESS_HOME_CITY | addrCity | City | 
-ADDRESS_HOME_STATE | addrState | State |  
-ADDRESS_HOME_ZIP | addrZip | Postal code | 
+UNKNOWN_TYPE | payment_group | Payment Type We accept Visa, Mastercard, Discover, American Express, and PayPal. | cc | payment_group_1-default
+UNKNOWN_TYPE | payment_group | Payment Type We accept Visa, Mastercard, Discover, American Express, and PayPal. | paypal | payment_group_1-default
+CREDIT_CARD_NAME | ccFullName | (as it appears on the card) |  | payment_group_1-cc
+CREDIT_CARD_NUMBER | ccNumber | (no dashes or spaces) |  | payment_group_1-cc
+CREDIT_CARD_EXP_MONTH | ccExpMonth | Expiration date | 1 | payment_group_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | ccExpYear | Your name (as it appears on the card) Credit card number (no dashes or spaces) Expiration date | 2011 | payment_group_1-cc
+CREDIT_CARD_VERIFICATION_CODE | ccSecurity | Security code |  | payment_group_1-cc
+UNKNOWN_TYPE | sameinfo | First name Last name | on | payment_group_1-default
+NAME_FIRST | addrFirstName | First name |  | payment_group_1-default
+NAME_LAST | addrLastName | Last name |  | payment_group_1-default
+ADDRESS_HOME_LINE1 | addrStreet1 | (street address, PO box, company name) |  | payment_group_1-default
+ADDRESS_HOME_LINE2 | addrStreet2 | (apt, suite, building, floor, etc) |  | payment_group_1-default
+ADDRESS_HOME_CITY | addrCity | City |  | payment_group_1-default
+ADDRESS_HOME_STATE | addrState | State |   | payment_group_1-default
+ADDRESS_HOME_ZIP | addrZip | Postal code |  | payment_group_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/15_crbug_74918.out b/chrome/test/data/autofill/heuristics/output/15_crbug_74918.out
index e211c0e..3218a19 100644
--- a/chrome/test/data/autofill/heuristics/output/15_crbug_74918.out
+++ b/chrome/test/data/autofill/heuristics/output/15_crbug_74918.out
@@ -1,7 +1,7 @@
-UNKNOWN_TYPE | TopicList | Category | Topic10
-NAME_FULL | Name | From | 
-PHONE_HOME_WHOLE_NUMBER | DayPhone | Daytime Phone | 
-UNKNOWN_TYPE | Subject | Subject | 
-PHONE_HOME_WHOLE_NUMBER | EvePhone | Evening Phone | 
-UNKNOWN_TYPE | AccountList | Account | NO_SELECTION
-UNKNOWN_TYPE | BodyText |  | 
+UNKNOWN_TYPE | TopicList | Category | Topic10 | TopicList_1-default
+NAME_FULL | Name | From |  | TopicList_1-default
+PHONE_HOME_WHOLE_NUMBER | DayPhone | Daytime Phone |  | TopicList_1-default
+UNKNOWN_TYPE | Subject | Subject |  | TopicList_1-default
+PHONE_HOME_WHOLE_NUMBER | EvePhone | Evening Phone |  | TopicList_1-default
+UNKNOWN_TYPE | AccountList | Account | NO_SELECTION | TopicList_1-default
+UNKNOWN_TYPE | BodyText |  |  | TopicList_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/16_crbug_87517.out b/chrome/test/data/autofill/heuristics/output/16_crbug_87517.out
index 74a92c3..ed8eb48 100644
--- a/chrome/test/data/autofill/heuristics/output/16_crbug_87517.out
+++ b/chrome/test/data/autofill/heuristics/output/16_crbug_87517.out
@@ -1,44 +1,44 @@
-UNKNOWN_TYPE | f1 | MATHCOUNTS Foundation Online Donation Form | 
-NAME_FIRST | dnrfirst | Name * | 
-NAME_LAST | dnrlast | Name * | 
-COMPANY_NAME | company | Company | 
-ADDRESS_HOME_LINE1 | dadd1 | Address 1 * | 
-ADDRESS_HOME_LINE2 | dadd2 | Address 2 | 
-ADDRESS_HOME_CITY | dcity | City / State / Zip * | 
-ADDRESS_HOME_STATE | dstate | Name * | AL
-ADDRESS_HOME_ZIP | dzip | Name * | 
-ADDRESS_HOME_COUNTRY | CC_COUNTRY | Country | United States
-PHONE_HOME_WHOLE_NUMBER | dphone | Telephone | 
-EMAIL_ADDRESS | demail | Email * | 
-UNKNOWN_TYPE | amt | $ | 
-UNKNOWN_TYPE | tributeSelect | Name * | on
-UNKNOWN_TYPE | DonationType | Name * | OneTime
-UNKNOWN_TYPE | DonationType | This is a one time donation | Recurs
-UNKNOWN_TYPE | ccrecurring | I would like to make this a recurring donation deducted | Monthly
-UNKNOWN_TYPE | remLen | ( You may enter up to 500 characters. ) | 500
-UNKNOWN_TYPE | Comments | ( You may enter up to 500 characters. ) | 
-UNKNOWN_TYPE | tribute |  | IHO
-UNKNOWN_TYPE | tribute | In Honor Of | IMO
-NAME_FULL | Tribute_Name | Name: | 
-UNKNOWN_TYPE | Tribute_occasion | Occasion: | 
-UNKNOWN_TYPE | Tribute_Disclosure | Occasion: | on
-UNKNOWN_TYPE | Tribute_Notification | I wish to remain anonymous | on
-UNKNOWN_TYPE | Tribute_IncludeAmount |  | 1
-UNKNOWN_TYPE | Tribute_IncludeAmount | Include the amount | 0
-NAME_FULL | Tribute_NotifyName | Name: | 
-EMAIL_ADDRESS | Tribute_Email | Email: | 
-ADDRESS_HOME_LINE1 | Tribute_NotifyAddr | Street: | 
-ADDRESS_HOME_CITY | Tribute_NotifyCity | City / St. / Zip: | 
-ADDRESS_HOME_STATE | Tribute_NotifyState | City / St. / Zip: | 
-ADDRESS_HOME_ZIP | Tribute_NotifyZip | City / St. / Zip: | 
-CREDIT_CARD_TYPE | cctype | Credit Card Type * | Visa
-CREDIT_CARD_NUMBER | ccard | Credit Card Number * | 
-CREDIT_CARD_VERIFICATION_CODE | csc | CSC Number * What Is This? | 
-CREDIT_CARD_EXP_MONTH | ExpMon | Month | 1
-CREDIT_CARD_EXP_4_DIGIT_YEAR | ExpYear | Year | 11
-UNKNOWN_TYPE | SameAddress | Billing Address - | checkbox
-ADDRESS_HOME_LINE1 | CC_Addr | Address 1 * | 
-ADDRESS_HOME_LINE2 | CC_Addr2 | Address 2 | 
-ADDRESS_HOME_CITY | CC_City | City / State / Zip * | 
-ADDRESS_HOME_STATE | CC_State | Credit Card Information | 
-ADDRESS_HOME_ZIP | CC_Zip | Credit Card Information | 
+UNKNOWN_TYPE | f1 | MATHCOUNTS Foundation Online Donation Form |  | f1_1-default
+NAME_FIRST | dnrfirst | Name * |  | f1_1-default
+NAME_LAST | dnrlast | Name * |  | f1_1-default
+COMPANY_NAME | company | Company |  | f1_1-default
+ADDRESS_HOME_LINE1 | dadd1 | Address 1 * |  | f1_1-default
+ADDRESS_HOME_LINE2 | dadd2 | Address 2 |  | f1_1-default
+ADDRESS_HOME_CITY | dcity | City / State / Zip * |  | f1_1-default
+ADDRESS_HOME_STATE | dstate | Name * | AL | f1_1-default
+ADDRESS_HOME_ZIP | dzip | Name * |  | f1_1-default
+ADDRESS_HOME_COUNTRY | CC_COUNTRY | Country | United States | f1_1-default
+PHONE_HOME_WHOLE_NUMBER | dphone | Telephone |  | f1_1-default
+EMAIL_ADDRESS | demail | Email * |  | f1_1-default
+UNKNOWN_TYPE | amt | $ |  | f1_1-default
+UNKNOWN_TYPE | tributeSelect | Name * | on | f1_1-default
+UNKNOWN_TYPE | DonationType | Name * | OneTime | f1_1-default
+UNKNOWN_TYPE | DonationType | This is a one time donation | Recurs | f1_1-default
+UNKNOWN_TYPE | ccrecurring | I would like to make this a recurring donation deducted | Monthly | f1_1-default
+UNKNOWN_TYPE | remLen | ( You may enter up to 500 characters. ) | 500 | f1_1-default
+UNKNOWN_TYPE | Comments | ( You may enter up to 500 characters. ) |  | f1_1-default
+UNKNOWN_TYPE | tribute |  | IHO | f1_1-default
+UNKNOWN_TYPE | tribute | In Honor Of | IMO | f1_1-default
+NAME_FULL | Tribute_Name | Name: |  | f1_1-default
+UNKNOWN_TYPE | Tribute_occasion | Occasion: |  | f1_1-default
+UNKNOWN_TYPE | Tribute_Disclosure | Occasion: | on | f1_1-default
+UNKNOWN_TYPE | Tribute_Notification | I wish to remain anonymous | on | f1_1-default
+UNKNOWN_TYPE | Tribute_IncludeAmount |  | 1 | f1_1-default
+UNKNOWN_TYPE | Tribute_IncludeAmount | Include the amount | 0 | f1_1-default
+NAME_FULL | Tribute_NotifyName | Name: |  | Tribute_NotifyName_1-default
+EMAIL_ADDRESS | Tribute_Email | Email: |  | Tribute_NotifyName_1-default
+ADDRESS_HOME_LINE1 | Tribute_NotifyAddr | Street: |  | Tribute_NotifyName_1-default
+ADDRESS_HOME_CITY | Tribute_NotifyCity | City / St. / Zip: |  | Tribute_NotifyName_1-default
+ADDRESS_HOME_STATE | Tribute_NotifyState | City / St. / Zip: |  | Tribute_NotifyName_1-default
+ADDRESS_HOME_ZIP | Tribute_NotifyZip | City / St. / Zip: |  | Tribute_NotifyName_1-default
+CREDIT_CARD_TYPE | cctype | Credit Card Type * | Visa | Tribute_NotifyName_1-cc
+CREDIT_CARD_NUMBER | ccard | Credit Card Number * |  | Tribute_NotifyName_1-cc
+CREDIT_CARD_VERIFICATION_CODE | csc | CSC Number * What Is This? |  | Tribute_NotifyName_1-cc
+CREDIT_CARD_EXP_MONTH | ExpMon | Month | 1 | Tribute_NotifyName_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | ExpYear | Year | 11 | Tribute_NotifyName_1-cc
+UNKNOWN_TYPE | SameAddress | Billing Address - | checkbox | Tribute_NotifyName_1-default
+ADDRESS_HOME_LINE1 | CC_Addr | Address 1 * |  | CC_Addr_1-default
+ADDRESS_HOME_LINE2 | CC_Addr2 | Address 2 |  | CC_Addr_1-default
+ADDRESS_HOME_CITY | CC_City | City / State / Zip * |  | CC_Addr_1-default
+ADDRESS_HOME_STATE | CC_State | Credit Card Information |  | CC_Addr_1-default
+ADDRESS_HOME_ZIP | CC_Zip | Credit Card Information |  | CC_Addr_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/16_crbug_93595.out b/chrome/test/data/autofill/heuristics/output/16_crbug_93595.out
index 11523d6..790cd1e 100644
--- a/chrome/test/data/autofill/heuristics/output/16_crbug_93595.out
+++ b/chrome/test/data/autofill/heuristics/output/16_crbug_93595.out
@@ -1,8 +1,8 @@
-CREDIT_CARD_TYPE | payment_method |  | Visa
-CREDIT_CARD_NUMBER | cc_number |  | 
-CREDIT_CARD_NAME | cc_name |  | 
-CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR | cc_exp | Expiration date (MM/YY) | 
-CREDIT_CARD_VERIFICATION_CODE | cc_cvv2 | CVV2 / Security Code: | 
-UNKNOWN_TYPE | field_17 |  | Select an option...
-UNKNOWN_TYPE | age |  | 
-UNKNOWN_TYPE | comments |  | 
+CREDIT_CARD_TYPE | payment_method |  | Visa | payment_method_1-cc
+CREDIT_CARD_NUMBER | cc_number |  |  | payment_method_1-cc
+CREDIT_CARD_NAME | cc_name |  |  | payment_method_1-cc
+CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR | cc_exp | Expiration date (MM/YY) |  | payment_method_1-cc
+CREDIT_CARD_VERIFICATION_CODE | cc_cvv2 | CVV2 / Security Code: |  | payment_method_1-cc
+UNKNOWN_TYPE | field_17 |  | Select an option... | payment_method_1-default
+UNKNOWN_TYPE | age |  |  | payment_method_1-default
+UNKNOWN_TYPE | comments |  |  | payment_method_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/16_crbug_98152.out b/chrome/test/data/autofill/heuristics/output/16_crbug_98152.out
index 96a0bd8..af1fd636 100644
--- a/chrome/test/data/autofill/heuristics/output/16_crbug_98152.out
+++ b/chrome/test/data/autofill/heuristics/output/16_crbug_98152.out
@@ -1,14 +1,14 @@
-CREDIT_CARD_TYPE | CCForm.cardType | Type of Card | 
-CREDIT_CARD_NUMBER | CCForm.cardNumber | Card number | 
-CREDIT_CARD_EXP_MONTH | CCForm.expirationMonth | Expiration date | 9
-CREDIT_CARD_EXP_4_DIGIT_YEAR | CCForm.expirationYear | Expiration date | 2011
-CREDIT_CARD_NAME | CCForm.name | Name as it appears on card | 
-CREDIT_CARD_VERIFICATION_CODE | CCForm.cid |  | 
-UNKNOWN_TYPE | isBillingAddress | Make the most of your shopping experience with the Walmart Discover® or Walmart Credit Card®. Learn More or Apply Now. Debit cards (also called check cards, ATM cards or bank cards) are accepted if they have a Visa or MasterCard logo. | on
-COMPANY_NAME | CCForm.companyName | Company Name | 
-ADDRESS_HOME_LINE1 | addressForm.street1 | Address Line 1 | 
-ADDRESS_HOME_LINE2 | addressForm.street2 | Address Line 2 | 
-ADDRESS_HOME_CITY | addressForm.city | City | 
-ADDRESS_HOME_STATE | addressForm.state | State | 
-ADDRESS_HOME_ZIP | addressForm.zip | Zip Code | 
-PHONE_HOME_WHOLE_NUMBER | addressForm.phone | Phone Number | 
+CREDIT_CARD_TYPE | CCForm.cardType | Type of Card |  | CCForm.cardType_1-cc
+CREDIT_CARD_NUMBER | CCForm.cardNumber | Card number |  | CCForm.cardType_1-cc
+CREDIT_CARD_EXP_MONTH | CCForm.expirationMonth | Expiration date | 9 | CCForm.cardType_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | CCForm.expirationYear | Expiration date | 2011 | CCForm.cardType_1-cc
+CREDIT_CARD_NAME | CCForm.name | Name as it appears on card |  | CCForm.cardType_1-cc
+CREDIT_CARD_VERIFICATION_CODE | CCForm.cid |  |  | CCForm.cardType_1-cc
+UNKNOWN_TYPE | isBillingAddress | Make the most of your shopping experience with the Walmart Discover® or Walmart Credit Card®. Learn More or Apply Now. Debit cards (also called check cards, ATM cards or bank cards) are accepted if they have a Visa or MasterCard logo. | on | CCForm.cardType_1-default
+COMPANY_NAME | CCForm.companyName | Company Name |  | CCForm.cardType_1-default
+ADDRESS_HOME_LINE1 | addressForm.street1 | Address Line 1 |  | CCForm.cardType_1-default
+ADDRESS_HOME_LINE2 | addressForm.street2 | Address Line 2 |  | CCForm.cardType_1-default
+ADDRESS_HOME_CITY | addressForm.city | City |  | CCForm.cardType_1-default
+ADDRESS_HOME_STATE | addressForm.state | State |  | CCForm.cardType_1-default
+ADDRESS_HOME_ZIP | addressForm.zip | Zip Code |  | CCForm.cardType_1-default
+PHONE_HOME_WHOLE_NUMBER | addressForm.phone | Phone Number |  | CCForm.cardType_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/16_crbug_98269.out b/chrome/test/data/autofill/heuristics/output/16_crbug_98269.out
index 76277106..c6d3ba9 100644
--- a/chrome/test/data/autofill/heuristics/output/16_crbug_98269.out
+++ b/chrome/test/data/autofill/heuristics/output/16_crbug_98269.out
@@ -1,19 +1,19 @@
-UNKNOWN_TYPE | PaymentMethod |  | BL
-PHONE_HOME_CITY_CODE | txtHomePhone1 | * Home Phone: | 
-PHONE_HOME_NUMBER | txtHomePhone2 | * Home Phone: | 
-PHONE_HOME_NUMBER | txtHomePhone3 | * Home Phone: | 
-EMAIL_ADDRESS | txtEmail | * Email Address: | 
-UNKNOWN_TYPE | txtSSN | XXX-XX- | 
-UNKNOWN_TYPE | selBirthMonth | * Date of Birth: | Month
-UNKNOWN_TYPE | selBirthDate | * Date of Birth: | Date
-UNKNOWN_TYPE | selBirthYear | * Date of Birth: | Year
-UNKNOWN_TYPE | chkTAC | * | on
-UNKNOWN_TYPE | PaymentMethod |  | CK
-UNKNOWN_TYPE | PaymentMethod |  | AddNew
-CREDIT_CARD_TYPE | cardType | Type: | VI
-CREDIT_CARD_NUMBER | CreditCardNumber | Number: | 
-CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | CreditCardExpYYMM | Expiration: | 092011
-CREDIT_CARD_VERIFICATION_CODE | CVV | Security Code: | 
-UNKNOWN_TYPE | useGiftCard | QVC Gift Cards | on
-UNKNOWN_TYPE | GiftCardNum | Card Number: | 
-UNKNOWN_TYPE | GiftCardPIN | Security ID Number: | 
+UNKNOWN_TYPE | PaymentMethod |  | BL | PaymentMethod_1-default
+PHONE_HOME_CITY_CODE | txtHomePhone1 | * Home Phone: |  | PaymentMethod_1-default
+PHONE_HOME_NUMBER | txtHomePhone2 | * Home Phone: |  | PaymentMethod_1-default
+PHONE_HOME_NUMBER | txtHomePhone3 | * Home Phone: |  | PaymentMethod_1-default
+EMAIL_ADDRESS | txtEmail | * Email Address: |  | PaymentMethod_1-default
+UNKNOWN_TYPE | txtSSN | XXX-XX- |  | PaymentMethod_1-default
+UNKNOWN_TYPE | selBirthMonth | * Date of Birth: | Month | PaymentMethod_1-default
+UNKNOWN_TYPE | selBirthDate | * Date of Birth: | Date | PaymentMethod_1-default
+UNKNOWN_TYPE | selBirthYear | * Date of Birth: | Year | PaymentMethod_1-default
+UNKNOWN_TYPE | chkTAC | * | on | PaymentMethod_1-default
+UNKNOWN_TYPE | PaymentMethod |  | CK | PaymentMethod_1-default
+UNKNOWN_TYPE | PaymentMethod |  | AddNew | PaymentMethod_1-default
+CREDIT_CARD_TYPE | cardType | Type: | VI | PaymentMethod_1-cc
+CREDIT_CARD_NUMBER | CreditCardNumber | Number: |  | PaymentMethod_1-cc
+CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | CreditCardExpYYMM | Expiration: | 092011 | PaymentMethod_1-cc
+CREDIT_CARD_VERIFICATION_CODE | CVV | Security Code: |  | PaymentMethod_1-cc
+UNKNOWN_TYPE | useGiftCard | QVC Gift Cards | on | PaymentMethod_1-default
+UNKNOWN_TYPE | GiftCardNum | Card Number: |  | PaymentMethod_1-default
+UNKNOWN_TYPE | GiftCardPIN | Security ID Number: |  | PaymentMethod_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/16_crbug_98286.out b/chrome/test/data/autofill/heuristics/output/16_crbug_98286.out
index 65ec5606..1a4aa44 100644
--- a/chrome/test/data/autofill/heuristics/output/16_crbug_98286.out
+++ b/chrome/test/data/autofill/heuristics/output/16_crbug_98286.out
@@ -1,7 +1,7 @@
-CREDIT_CARD_TYPE | drpdwnCardTypes | *Card type: | JCP1
-CREDIT_CARD_NAME | txtNameOnCreditCard | *Name on the card: | 
-CREDIT_CARD_NUMBER | txtCreditCardNumber | *Card number: | 
-CREDIT_CARD_EXP_MONTH | drpdwnExpirationMonth | *Expiration date: | 00
-CREDIT_CARD_EXP_4_DIGIT_YEAR | drpdwnExpirationYear | *Expiration date: | 2011
-CREDIT_CARD_VERIFICATION_CODE | txtVisaVerificationNumber | VISA Card Verification # | 
-UNKNOWN_TYPE | chkUnreadable | I can't read the numbers | on
+CREDIT_CARD_TYPE | drpdwnCardTypes | *Card type: | JCP1 | drpdwnCardTypes_1-cc
+CREDIT_CARD_NAME | txtNameOnCreditCard | *Name on the card: |  | drpdwnCardTypes_1-cc
+CREDIT_CARD_NUMBER | txtCreditCardNumber | *Card number: |  | drpdwnCardTypes_1-cc
+CREDIT_CARD_EXP_MONTH | drpdwnExpirationMonth | *Expiration date: | 00 | drpdwnCardTypes_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | drpdwnExpirationYear | *Expiration date: | 2011 | drpdwnCardTypes_1-cc
+CREDIT_CARD_VERIFICATION_CODE | txtVisaVerificationNumber | VISA Card Verification # |  | drpdwnCardTypes_1-cc
+UNKNOWN_TYPE | chkUnreadable | I can't read the numbers | on | drpdwnCardTypes_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/17_crbug_224601.out b/chrome/test/data/autofill/heuristics/output/17_crbug_224601.out
index e9359b4..6feabf5 100644
--- a/chrome/test/data/autofill/heuristics/output/17_crbug_224601.out
+++ b/chrome/test/data/autofill/heuristics/output/17_crbug_224601.out
@@ -1,54 +1,54 @@
-UNKNOWN_TYPE | txtSearch | Buy tickets Live train information | Search
-UNKNOWN_TYPE | JP1$txtFrom | From * | 
-UNKNOWN_TYPE | JP1$txtTo | To * | 
-UNKNOWN_TYPE | JP1$txtDepartureDate | Out date | 18/04/2013
-UNKNOWN_TYPE | JP1$ddlDepartureHour | Hour | 15
-UNKNOWN_TYPE | JP1$ddlDepartureMin | Min | 00
-UNKNOWN_TYPE | JP1$chkReturn | Return ticket? | on
-UNKNOWN_TYPE | JP1$txtReturnDate | Return date | 18/04/2013
-UNKNOWN_TYPE | JP1$ddlReturnHour | Hour | 16
-UNKNOWN_TYPE | JP1$ddlReturnMin | Min | 00
-UNKNOWN_TYPE | JP1$ddlAdults | Adults | 1
-UNKNOWN_TYPE | JP1$ddlChildren | Children | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl00$Count | 16-25 Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl01$Count | Annual Gold Card | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl02$Count | Cambrian Lines Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl03$Count | Cotswold Line Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl04$Count | Devon & Cornwall Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl05$Count | Dales Railcards | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl06$Count | Disabled Adult Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl07$Count | Disabled Child Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl08$Count | Esk Valley Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl09$Count | Family & Friends Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl10$Count | Groupsave 3 | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl11$Count | Groupsave 4 | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl12$Count | Heart of Wales Line Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl13$Count | HM Forces Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl14$Count | Jobcentre Plus Discount Card | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl15$Count | Network Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl16$Count | Pembrokeshire Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl17$Count | Senior Railcard | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl18$Count | Scottish Youth | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl19$Count | Valleys senior | 0
-UNKNOWN_TYPE | JP1$rptCards$ctl20$Count | Valleys student | 0
-UNKNOWN_TYPE | JP1$ddlRailCard | Railcards and GroupSave | none
-UNKNOWN_TYPE | Register1$ddlTitle | Title: | MR
-NAME_FIRST | Register1$txtForenames | Forename(s): * | 
-NAME_LAST | Register1$txtSurname | Surname: * | 
-EMAIL_ADDRESS | Register1$txtEmail | Email: * | 
-EMAIL_ADDRESS | Register1$txtConfirmEmail | Confirm Email: * | 
-PHONE_HOME_WHOLE_NUMBER | Register1$txtDayPhone | Day time phone: | 
-PHONE_HOME_WHOLE_NUMBER | Register1$txtEveningPhone | Evening phone: | 
-PHONE_HOME_WHOLE_NUMBER | Register1$txtMobilePhone | Mobile phone: | 
-ADDRESS_HOME_LINE1 | Register1$txtAddress1 | Address Line 1: * | 
-ADDRESS_HOME_LINE2 | Register1$txtAddress2 | Address Line 2: * | 
-UNKNOWN_TYPE | Register1$txtAddress3 | Address Line 3: | 
-UNKNOWN_TYPE | Register1$txtAddress4 | Address Line 4: | 
-UNKNOWN_TYPE | Register1$txtAddress5 | Address Line 5: | 
-ADDRESS_HOME_ZIP | Register1$txtPostCode | Post Code: * | 
-ADDRESS_HOME_COUNTRY | Register1$ddlCountry | Country: * | Z0
-UNKNOWN_TYPE | Register1$termsandconditions$chkTerms | I agree to the terms and          conditions * | on
-UNKNOWN_TYPE | Register1$chkPrivacy1984 | Please tick here if you DO NOT wish to receive information and exclusive offers from South West Trains | on
-UNKNOWN_TYPE | Register1$chkPrivacy2003 | Please tick here if you DO wish to receive information and exclusive offers from our carefully selected partners | on
-UNKNOWN_TYPE | Register1$txtPassword | Password: * | 
-UNKNOWN_TYPE | Register1$txtConfirmPassword | Confirm Password: * | 
+UNKNOWN_TYPE | txtSearch | Buy tickets Live train information | Search | txtSearch_1-default
+UNKNOWN_TYPE | JP1$txtFrom | From * |  | txtSearch_1-default
+UNKNOWN_TYPE | JP1$txtTo | To * |  | txtSearch_1-default
+UNKNOWN_TYPE | JP1$txtDepartureDate | Out date | 18/04/2013 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$ddlDepartureHour | Hour | 15 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$ddlDepartureMin | Min | 00 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$chkReturn | Return ticket? | on | txtSearch_1-default
+UNKNOWN_TYPE | JP1$txtReturnDate | Return date | 18/04/2013 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$ddlReturnHour | Hour | 16 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$ddlReturnMin | Min | 00 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$ddlAdults | Adults | 1 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$ddlChildren | Children | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl00$Count | 16-25 Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl01$Count | Annual Gold Card | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl02$Count | Cambrian Lines Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl03$Count | Cotswold Line Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl04$Count | Devon & Cornwall Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl05$Count | Dales Railcards | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl06$Count | Disabled Adult Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl07$Count | Disabled Child Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl08$Count | Esk Valley Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl09$Count | Family & Friends Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl10$Count | Groupsave 3 | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl11$Count | Groupsave 4 | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl12$Count | Heart of Wales Line Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl13$Count | HM Forces Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl14$Count | Jobcentre Plus Discount Card | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl15$Count | Network Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl16$Count | Pembrokeshire Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl17$Count | Senior Railcard | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl18$Count | Scottish Youth | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl19$Count | Valleys senior | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$rptCards$ctl20$Count | Valleys student | 0 | txtSearch_1-default
+UNKNOWN_TYPE | JP1$ddlRailCard | Railcards and GroupSave | none | txtSearch_1-default
+UNKNOWN_TYPE | Register1$ddlTitle | Title: | MR | txtSearch_1-default
+NAME_FIRST | Register1$txtForenames | Forename(s): * |  | txtSearch_1-default
+NAME_LAST | Register1$txtSurname | Surname: * |  | txtSearch_1-default
+EMAIL_ADDRESS | Register1$txtEmail | Email: * |  | txtSearch_1-default
+EMAIL_ADDRESS | Register1$txtConfirmEmail | Confirm Email: * |  | txtSearch_1-default
+PHONE_HOME_WHOLE_NUMBER | Register1$txtDayPhone | Day time phone: |  | txtSearch_1-default
+PHONE_HOME_WHOLE_NUMBER | Register1$txtEveningPhone | Evening phone: |  | txtSearch_1-default
+PHONE_HOME_WHOLE_NUMBER | Register1$txtMobilePhone | Mobile phone: |  | txtSearch_1-default
+ADDRESS_HOME_LINE1 | Register1$txtAddress1 | Address Line 1: * |  | txtSearch_1-default
+ADDRESS_HOME_LINE2 | Register1$txtAddress2 | Address Line 2: * |  | txtSearch_1-default
+UNKNOWN_TYPE | Register1$txtAddress3 | Address Line 3: |  | txtSearch_1-default
+UNKNOWN_TYPE | Register1$txtAddress4 | Address Line 4: |  | txtSearch_1-default
+UNKNOWN_TYPE | Register1$txtAddress5 | Address Line 5: |  | txtSearch_1-default
+ADDRESS_HOME_ZIP | Register1$txtPostCode | Post Code: * |  | txtSearch_1-default
+ADDRESS_HOME_COUNTRY | Register1$ddlCountry | Country: * | Z0 | txtSearch_1-default
+UNKNOWN_TYPE | Register1$termsandconditions$chkTerms | I agree to the terms and          conditions * | on | txtSearch_1-default
+UNKNOWN_TYPE | Register1$chkPrivacy1984 | Please tick here if you DO NOT wish to receive information and exclusive offers from South West Trains | on | txtSearch_1-default
+UNKNOWN_TYPE | Register1$chkPrivacy2003 | Please tick here if you DO wish to receive information and exclusive offers from our carefully selected partners | on | txtSearch_1-default
+UNKNOWN_TYPE | Register1$txtPassword | Password: * |  | txtSearch_1-default
+UNKNOWN_TYPE | Register1$txtConfirmPassword | Confirm Password: * |  | txtSearch_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/17_crbug_308839.out b/chrome/test/data/autofill/heuristics/output/17_crbug_308839.out
index 3bde1a3..e93ab49 100644
--- a/chrome/test/data/autofill/heuristics/output/17_crbug_308839.out
+++ b/chrome/test/data/autofill/heuristics/output/17_crbug_308839.out
@@ -1,6 +1,6 @@
-NAME_FULL | name | Name* | 
-EMAIL_ADDRESS | email | Email Id* | 
-PHONE_HOME_WHOLE_NUMBER | mobile | Mobile* | 
-ADDRESS_HOME_STREET_ADDRESS | address | Full Address* | 
-ADDRESS_HOME_CITY | city | City | Select
-ADDRESS_HOME_ZIP | pincode | Pin Code* | 
+NAME_FULL | name | Name* |  | name_1-default
+EMAIL_ADDRESS | email | Email Id* |  | name_1-default
+PHONE_HOME_WHOLE_NUMBER | mobile | Mobile* |  | name_1-default
+ADDRESS_HOME_STREET_ADDRESS | address | Full Address* |  | name_1-default
+ADDRESS_HOME_CITY | city | City | Select | name_1-default
+ADDRESS_HOME_ZIP | pincode | Pin Code* |  | name_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/17_crbug_98338.out b/chrome/test/data/autofill/heuristics/output/17_crbug_98338.out
index f838e81..d82ed3f7 100644
--- a/chrome/test/data/autofill/heuristics/output/17_crbug_98338.out
+++ b/chrome/test/data/autofill/heuristics/output/17_crbug_98338.out
@@ -1,16 +1,16 @@
-UNKNOWN_TYPE | giftcardnumber_EGC | Gift Card Number Gift Card Number | 
-UNKNOWN_TYPE | pin_EGC | PIN PIN | 
-UNKNOWN_TYPE | giftCardNumber2 | Gift Card Number PIN | 
-UNKNOWN_TYPE | giftCardPin2 | Gift Card Number PIN | 
-UNKNOWN_TYPE | giftCardNumber3 | Gift Card Number PIN | 
-UNKNOWN_TYPE | giftCardPin3 | Gift Card Number PIN | 
-UNKNOWN_TYPE | giftcardnumber_GC | Gift Card Number PIN | 
-UNKNOWN_TYPE | pin_GC | Gift Card Number PIN | 
-UNKNOWN_TYPE | giftCardNumber2 | Gift Card Number PIN | 
-UNKNOWN_TYPE | giftCardPin2 | Gift Card Number PIN | 
-UNKNOWN_TYPE | giftCardNumber3 | Gift Card Number PIN | 
-UNKNOWN_TYPE | giftCardPin3 | Gift Card Number PIN | 
-CREDIT_CARD_TYPE | cardType | Card Number* Expiration Month* Expiration Year | 
-CREDIT_CARD_NUMBER | cardNumber | Card Number* Expiration Month* Expiration Year | 
-CREDIT_CARD_EXP_MONTH | cardMonth | Card Number* Expiration Month* Expiration Year | 
-CREDIT_CARD_EXP_4_DIGIT_YEAR | cardYear | Card Number* Expiration Month* Expiration Year | 
+UNKNOWN_TYPE | giftcardnumber_EGC | Gift Card Number Gift Card Number |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | pin_EGC | PIN PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftCardNumber2 | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftCardPin2 | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftCardNumber3 | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftCardPin3 | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftcardnumber_GC | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | pin_GC | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftCardNumber2 | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftCardPin2 | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftCardNumber3 | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+UNKNOWN_TYPE | giftCardPin3 | Gift Card Number PIN |  | giftcardnumber_EGC_1-default
+CREDIT_CARD_TYPE | cardType | Card Number* Expiration Month* Expiration Year |  | giftcardnumber_EGC_1-cc
+CREDIT_CARD_NUMBER | cardNumber | Card Number* Expiration Month* Expiration Year |  | giftcardnumber_EGC_1-cc
+CREDIT_CARD_EXP_MONTH | cardMonth | Card Number* Expiration Month* Expiration Year |  | giftcardnumber_EGC_1-cc
+CREDIT_CARD_EXP_4_DIGIT_YEAR | cardYear | Card Number* Expiration Month* Expiration Year |  | giftcardnumber_EGC_1-cc
diff --git a/chrome/test/data/autofill/heuristics/output/20_checkout_alaskaair.com.out b/chrome/test/data/autofill/heuristics/output/20_checkout_alaskaair.com.out
new file mode 100644
index 0000000..66e062b
--- /dev/null
+++ b/chrome/test/data/autofill/heuristics/output/20_checkout_alaskaair.com.out
@@ -0,0 +1,40 @@
+UNKNOWN_TYPE | UserId | User ID or MP # |  | UserId_1-default
+UNKNOWN_TYPE | Password | Password |  | UserId_1-default
+UNKNOWN_TYPE | JumpToSelection | Jump To Section | https://www.alaskaair.com/www2/ssl/myalaskaair/myalaskaair.aspx | UserId_1-default
+UNKNOWN_TYPE | RememberMe | Remember my User ID on this computer. | true | UserId_1-default
+UNKNOWN_TYPE | MyWalletInformation.UseMyWalletFunds | Use My Wallet Funds | true | MyWalletInformation.UseMyWalletFunds_1-default
+UNKNOWN_TYPE | GiftCardsAndCertificatesInformation.UseGiftCardsOrCertificates | Use Certificates or Gift Cards (not deposited in a My Wallet account) | true | MyWalletInformation.UseMyWalletFunds_1-default
+UNKNOWN_TYPE | CreditCardInformation.BillingCreditCardEntry.CardTypes_Selected | Card Type* | CreditCard | MyWalletInformation.UseMyWalletFunds_1-default
+UNKNOWN_TYPE | CreditCardInformation.BillingCreditCardEntry.CardTypes_Selected | Alaska Airlines Commercial Account | AS | MyWalletInformation.UseMyWalletFunds_1-default
+CREDIT_CARD_NUMBER | CreditCardInformation.BillingCreditCardEntry.CardNumber | Card Number |  | MyWalletInformation.UseMyWalletFunds_1-cc
+UNKNOWN_TYPE | CreditCardInformation.BillingCreditCardEntry.ExpirationMonths_Selected | Expiration* |  | MyWalletInformation.UseMyWalletFunds_1-default
+UNKNOWN_TYPE | CreditCardInformation.BillingCreditCardEntry.ExpirationYears_Selected | Expiration* |  | MyWalletInformation.UseMyWalletFunds_1-default
+CREDIT_CARD_NAME | CreditCardInformation.BillingCreditCardEntry.CardPersonName | Name on Card |  | MyWalletInformation.UseMyWalletFunds_1-cc
+ADDRESS_HOME_COUNTRY | CreditCardInformation.BillingAddressEntry.Countries_Selected | Country | US | MyWalletInformation.UseMyWalletFunds_1-default
+ADDRESS_HOME_LINE1 | CreditCardInformation.BillingAddressEntry.Address1 | Address |  | MyWalletInformation.UseMyWalletFunds_1-default
+ADDRESS_HOME_LINE2 | CreditCardInformation.BillingAddressEntry.Address2 | Address Line 2 |  | MyWalletInformation.UseMyWalletFunds_1-default
+ADDRESS_HOME_CITY | CreditCardInformation.BillingAddressEntry.City | City |  | MyWalletInformation.UseMyWalletFunds_1-default
+ADDRESS_HOME_STATE | CreditCardInformation.BillingAddressEntry.USStates_Selected | State/Province |  | MyWalletInformation.UseMyWalletFunds_1-default
+ADDRESS_HOME_STATE | CreditCardInformation.BillingAddressEntry.CAStates_Selected | State/Province |  | MyWalletInformation.UseMyWalletFunds_1-default
+ADDRESS_HOME_STATE | CreditCardInformation.BillingAddressEntry.MXStates_Selected | State/Province |  | MyWalletInformation.UseMyWalletFunds_1-default
+UNKNOWN_TYPE | CreditCardInformation.BillingAddressEntry.OtherStates_Selected | State/Province |  | MyWalletInformation.UseMyWalletFunds_1-default
+ADDRESS_HOME_ZIP | CreditCardInformation.BillingAddressEntry.PostalCode | Zip/Postal Code |  | MyWalletInformation.UseMyWalletFunds_1-default
+ADDRESS_HOME_COUNTRY | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected | Country Code | 1 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default
+PHONE_HOME_WHOLE_NUMBER | CreditCardInformation.BillingPhoneNumberEntry.Number | Phone (with area code) |  | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default
+UNKNOWN_TYPE | TripInsurance.QuoteID | Reimburses non-refundable, prepaid expenses up to the cost of your ticket(s) if you cancel your tripCovers emergency medical / dental and emergency medical transportation while travelingHelps with trip interruption, lost or damaged baggage, baggage delay, and additional travel delay costs Terms, conditions and exclusions apply, learn more. | 657566350481481886 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default
+UNKNOWN_TYPE | TripInsurance.QuoteID | Yes, add trip protection for a total of $21.00. No, I choose not to protect my purchase. | 657566350481481887 | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default
+CREDIT_CARD_NUMBER | AncillaryCreditCardInformation.BillingCreditCardEntry.CardNumber | Card Number |  | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-cc
+CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | AncillaryCreditCardInformation.BillingCreditCardEntry.ExpirationMonths_Selected | Expiration* |  | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-cc
+CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR | AncillaryCreditCardInformation.BillingCreditCardEntry.ExpirationYears_Selected | Expiration* |  | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-cc
+CREDIT_CARD_NAME | AncillaryCreditCardInformation.BillingCreditCardEntry.CardPersonName | Name on Card |  | CreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-cc
+ADDRESS_HOME_COUNTRY | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected | Country | US | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+ADDRESS_HOME_LINE1 | AncillaryCreditCardInformation.BillingAddressEntry.Address1 | Address |  | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+ADDRESS_HOME_LINE2 | AncillaryCreditCardInformation.BillingAddressEntry.Address2 | Address Line 2 |  | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+ADDRESS_HOME_CITY | AncillaryCreditCardInformation.BillingAddressEntry.City | City |  | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.USStates_Selected | State/Province |  | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.CAStates_Selected | State/Province |  | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+ADDRESS_HOME_STATE | AncillaryCreditCardInformation.BillingAddressEntry.MXStates_Selected | State/Province |  | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+UNKNOWN_TYPE | AncillaryCreditCardInformation.BillingAddressEntry.OtherStates_Selected | State/Province |  | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+ADDRESS_HOME_ZIP | AncillaryCreditCardInformation.BillingAddressEntry.PostalCode | Zip/Postal Code |  | AncillaryCreditCardInformation.BillingAddressEntry.Countries_Selected_1-default
+ADDRESS_HOME_COUNTRY | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected | Country Code | 1 | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default
+PHONE_HOME_WHOLE_NUMBER | AncillaryCreditCardInformation.BillingPhoneNumberEntry.Number | Phone (with area code) |  | AncillaryCreditCardInformation.BillingPhoneNumberEntry.CountryCode_Selected_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/20_register_alaskaair.com.out b/chrome/test/data/autofill/heuristics/output/20_register_alaskaair.com.out
index c4971e0..a7cc5b03 100644
--- a/chrome/test/data/autofill/heuristics/output/20_register_alaskaair.com.out
+++ b/chrome/test/data/autofill/heuristics/output/20_register_alaskaair.com.out
@@ -1,39 +1,39 @@
-UNKNOWN_TYPE | FormUserControl$_mileagePlanNumber$_mileagePlanChoice | Mileage Plan™ Number * | _needMileagePlanNbr
-UNKNOWN_TYPE | FormUserControl$_mileagePlanNumber$_mileagePlanChoice | I have an Alaska Airlines Mileage Plan Number | _haveMileagePlanNbr
-UNKNOWN_TYPE | FormUserControl$_mileagePlanNumber$_loyaltyNumber$_loyaltyNumber | Mileage Plan Number | 
-NAME_FIRST | FormUserControl$_personalIdentification$_firstName$_name | Legal First Name* | 
-UNKNOWN_TYPE | FormUserControl$_personalIdentification$_title$_title | Title | 
-NAME_MIDDLE | FormUserControl$_personalIdentification$_middleName$_middleName | Middle Name (if on ID) | 
-NAME_LAST | FormUserControl$_personalIdentification$_lastName$_name | Legal Last Name* | 
-UNKNOWN_TYPE | FormUserControl$_personalIdentification$_suffix$_suffix | Suffix | 
-UNKNOWN_TYPE | FormUserControl$_personalIdentification$_birthDate$_birthDate$_month | Month | 
-UNKNOWN_TYPE | FormUserControl$_personalIdentification$_birthDate$_birthDate$_day | Day | 
-UNKNOWN_TYPE | FormUserControl$_personalIdentification$_birthDate$_birthDate$_yearTextBox | Year | Year
-UNKNOWN_TYPE | FormUserControl$_personalIdentification$_gender$_gender | Gender* | 
-NAME_FIRST | FormUserControl$_guardianInformation$_firstName$_name | First Name* | 
-NAME_LAST | FormUserControl$_guardianInformation$_lastName$_name | Last Name* | 
-EMAIL_ADDRESS | FormUserControl$_guardianInformation$_email$_emailAddressTextBox | Email Address* | 
-ADDRESS_HOME_COUNTRY | FormUserControl$_mailingAddress$_country | Country* | US
-COMPANY_NAME | FormUserControl$_mailingAddress$_company | Company | 
-ADDRESS_HOME_LINE1 | FormUserControl$_mailingAddress$_addr1 | Address* | 
-ADDRESS_HOME_LINE2 | FormUserControl$_mailingAddress$_addr2 | Second Address Line | 
-ADDRESS_HOME_CITY | FormUserControl$_mailingAddress$_city | Zip/Postal Code | 
-ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateUS | State/Province* | 
-ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateCA | Canadian Provinces | 
-ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateMX | Mexican States | 
-ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateXX | State/Province Other | 
-ADDRESS_HOME_ZIP | FormUserControl$_mailingAddress$_zip | Zip/Postal Code* | 
-ADDRESS_HOME_COUNTRY | FormUserControl$_contactInformation$_phoneNumber$_countryCode | Country Code | 1
-PHONE_HOME_WHOLE_NUMBER | FormUserControl$_contactInformation$_phoneNumber$_phoneNumberTextBox | Country Code | 
-UNKNOWN_TYPE | FormUserControl$_contactInformation$_phoneNumber$_extensionTextBox | Ext. | 
-EMAIL_ADDRESS | FormUserControl$_contactInformation$_emailAddress$_emailAddressTextBox | Email Address* | 
-UNKNOWN_TYPE | FormUserControl$_userIdPassword$_userId$_userId | Create a User ID* | 
-UNKNOWN_TYPE | FormUserControl$_userIdPassword$_password$_password | Create a Password | 
-UNKNOWN_TYPE | FormUserControl$_userIdPassword$_reEnterPassword$_password | Re-enter Password | 
-UNKNOWN_TYPE | FormUserControl$_secretQuestion$_question | Secret Question* | 
-UNKNOWN_TYPE | FormUserControl$_secretQuestion$_answer | Please choose a secret question and provide the answer. You will need to answer the question again in case you forget your password. Make sure you choose a question and answer that are easy for you to remember, but difficult for other people to know.Secret Question* Answer* | 
-UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_insiderNewsletter$_subscriptionCheckBox | Insider NewsletterA weekly email personalized to provide you with an insider glimpse of the best deals we have to offer - across the board. | on
-ADDRESS_HOME_CITY | FormUserControl$_subscriptionsOffers$_primaryDepartureCity$_primaryDepartureCity$_city | Primary Departure City | 
-UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_eStatements$_subscriptionCheckBox | Mileage Plan E-Statements and Partner OffersA monthly recap of your Mileage Plan activity along with program news, exclusive partner offers, and countless ways to earn free travel faster. | on
-UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_asQXAnnouncements$_subscriptionCheckBox | Alaska AnnouncementsOccasional email that puts you "in the know" about sales, promotions, and other important travel information. | on
-UNKNOWN_TYPE | FormUserControl$_mpTermsAndConditions$_iAgree | Mileage Plan™ Terms & Conditions* I acknowledge that I have reviewed these Mileage Plan Terms and Conditions | on
+UNKNOWN_TYPE | FormUserControl$_mileagePlanNumber$_mileagePlanChoice | Mileage Plan™ Number * | _needMileagePlanNbr | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+UNKNOWN_TYPE | FormUserControl$_mileagePlanNumber$_mileagePlanChoice | I have an Alaska Airlines Mileage Plan Number | _haveMileagePlanNbr | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+UNKNOWN_TYPE | FormUserControl$_mileagePlanNumber$_loyaltyNumber$_loyaltyNumber | Mileage Plan Number |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+NAME_FIRST | FormUserControl$_personalIdentification$_firstName$_name | Legal First Name* |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+UNKNOWN_TYPE | FormUserControl$_personalIdentification$_title$_title | Title |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+NAME_MIDDLE | FormUserControl$_personalIdentification$_middleName$_middleName | Middle Name (if on ID) |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+NAME_LAST | FormUserControl$_personalIdentification$_lastName$_name | Legal Last Name* |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+UNKNOWN_TYPE | FormUserControl$_personalIdentification$_suffix$_suffix | Suffix |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+UNKNOWN_TYPE | FormUserControl$_personalIdentification$_birthDate$_birthDate$_month | Month |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+UNKNOWN_TYPE | FormUserControl$_personalIdentification$_birthDate$_birthDate$_day | Day |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+UNKNOWN_TYPE | FormUserControl$_personalIdentification$_birthDate$_birthDate$_yearTextBox | Year | Year | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+UNKNOWN_TYPE | FormUserControl$_personalIdentification$_gender$_gender | Gender* |  | FormUserControl$_mileagePlanNumber$_mileagePlanChoice_1-default
+NAME_FIRST | FormUserControl$_guardianInformation$_firstName$_name | First Name* |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+NAME_LAST | FormUserControl$_guardianInformation$_lastName$_name | Last Name* |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+EMAIL_ADDRESS | FormUserControl$_guardianInformation$_email$_emailAddressTextBox | Email Address* |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_COUNTRY | FormUserControl$_mailingAddress$_country | Country* | US | FormUserControl$_guardianInformation$_firstName$_name_1-default
+COMPANY_NAME | FormUserControl$_mailingAddress$_company | Company |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_LINE1 | FormUserControl$_mailingAddress$_addr1 | Address* |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_LINE2 | FormUserControl$_mailingAddress$_addr2 | Second Address Line |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_CITY | FormUserControl$_mailingAddress$_city | Zip/Postal Code |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateUS | State/Province* |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateCA | Canadian Provinces |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateMX | Mexican States |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_STATE | FormUserControl$_mailingAddress$_stateXX | State/Province Other |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_ZIP | FormUserControl$_mailingAddress$_zip | Zip/Postal Code* |  | FormUserControl$_guardianInformation$_firstName$_name_1-default
+ADDRESS_HOME_COUNTRY | FormUserControl$_contactInformation$_phoneNumber$_countryCode | Country Code | 1 | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+PHONE_HOME_WHOLE_NUMBER | FormUserControl$_contactInformation$_phoneNumber$_phoneNumberTextBox | Country Code |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_contactInformation$_phoneNumber$_extensionTextBox | Ext. |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+EMAIL_ADDRESS | FormUserControl$_contactInformation$_emailAddress$_emailAddressTextBox | Email Address* |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_userIdPassword$_userId$_userId | Create a User ID* |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_userIdPassword$_password$_password | Create a Password |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_userIdPassword$_reEnterPassword$_password | Re-enter Password |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_secretQuestion$_question | Secret Question* |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_secretQuestion$_answer | Please choose a secret question and provide the answer. You will need to answer the question again in case you forget your password. Make sure you choose a question and answer that are easy for you to remember, but difficult for other people to know.Secret Question* Answer* |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_insiderNewsletter$_subscriptionCheckBox | Insider NewsletterA weekly email personalized to provide you with an insider glimpse of the best deals we have to offer - across the board. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+ADDRESS_HOME_CITY | FormUserControl$_subscriptionsOffers$_primaryDepartureCity$_primaryDepartureCity$_city | Primary Departure City |  | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_eStatements$_subscriptionCheckBox | Mileage Plan E-Statements and Partner OffersA monthly recap of your Mileage Plan activity along with program news, exclusive partner offers, and countless ways to earn free travel faster. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_subscriptionsOffers$_asQXAnnouncements$_subscriptionCheckBox | Alaska AnnouncementsOccasional email that puts you "in the know" about sales, promotions, and other important travel information. | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
+UNKNOWN_TYPE | FormUserControl$_mpTermsAndConditions$_iAgree | Mileage Plan™ Terms & Conditions* I acknowledge that I have reviewed these Mileage Plan Terms and Conditions | on | FormUserControl$_contactInformation$_phoneNumber$_countryCode_1-default
diff --git a/chrome/test/data/autofill/heuristics/output/20_register_epson.com.mx.out b/chrome/test/data/autofill/heuristics/output/20_register_epson.com.mx.out
index 311cb46..3c6a52f 100644
--- a/chrome/test/data/autofill/heuristics/output/20_register_epson.com.mx.out
+++ b/chrome/test/data/autofill/heuristics/output/20_register_epson.com.mx.out
@@ -1,12 +1,12 @@
-UNKNOWN_TYPE | doAction |  | 
-ADDRESS_HOME_COUNTRY | idPaiseReg | n del producto *dd/mm/yyyySerial *Acerca del nro. de Serie | MX
-UNKNOWN_TYPE | fechaCompra | *dd/mm/yyyy | 
-UNKNOWN_TYPE | serialNumber | Serial * | 
-UNKNOWN_TYPE | idProducto | Serial * | 
-EMAIL_ADDRESS | emailLogin | Email * | 
-UNKNOWN_TYPE | passLogin | a * | 
-NAME_FIRST | nombre | Nombre * | 
-NAME_LAST | apellido | Apellido * | 
-EMAIL_ADDRESS | emailRegistro | Email * | 
-UNKNOWN_TYPE | passRegistro | a * | 
-UNKNOWN_TYPE | rePassRegistro | a * | 
+UNKNOWN_TYPE | doAction |  |  | doAction_1-default
+ADDRESS_HOME_COUNTRY | idPaiseReg | n del producto *dd/mm/yyyySerial *Acerca del nro. de Serie | MX | doAction_1-default
+UNKNOWN_TYPE | fechaCompra | *dd/mm/yyyy |  | doAction_1-default
+UNKNOWN_TYPE | serialNumber | Serial * |  | doAction_1-default
+UNKNOWN_TYPE | idProducto | Serial * |  | doAction_1-default
+EMAIL_ADDRESS | emailLogin | Email * |  | doAction_1-default
+UNKNOWN_TYPE | passLogin | a * |  | doAction_1-default
+NAME_FIRST | nombre | Nombre * |  | doAction_1-default
+NAME_LAST | apellido | Apellido * |  | doAction_1-default
+EMAIL_ADDRESS | emailRegistro | Email * |  | emailRegistro_1-default
+UNKNOWN_TYPE | passRegistro | a * |  | emailRegistro_1-default
+UNKNOWN_TYPE | rePassRegistro | a * |  | emailRegistro_1-default
diff --git a/chrome/test/data/chromedriver/anchor_download_test.png b/chrome/test/data/chromedriver/anchor_download_test.png
new file mode 100644
index 0000000..7a3361f
--- /dev/null
+++ b/chrome/test/data/chromedriver/anchor_download_test.png
Binary files differ
diff --git a/chrome/test/data/chromedriver/download.html b/chrome/test/data/chromedriver/download.html
new file mode 100644
index 0000000..e81b8e04
--- /dev/null
+++ b/chrome/test/data/chromedriver/download.html
@@ -0,0 +1,6 @@
+<html>
+<head><title>Test Page for ChromeDownloadDirTest</title></head>
+<body>
+<a id='red-dot' href="anchor_download_test.png" download='a_red_dot.png'>Download Red Dot!</a>
+</body>
+</html>
diff --git a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_iso-8859-1_saved_from_no_encoding_specified.html b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_iso-8859-1_saved_from_no_encoding_specified.html
index edae3cb..c647f3b 100644
--- a/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_iso-8859-1_saved_from_no_encoding_specified.html
+++ b/chrome/test/data/encoding_tests/auto_detect/expected_results/expected_iso-8859-1_saved_from_no_encoding_specified.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3c.o rg/TR/1999/REC-html401-19991224/loose.dtd">
 <!-- saved from url=(0086)http://mock.http/encoding_tests/auto_detect/iso-8859-1_with_no_encoding_specified.html -->
-<html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml"><head profile="http://www.w3.org/2000/08/w3c-synd/#"><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml"><head profile="http://www.w3.org/2000/08/w3c-synd/#"><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
 <title>iso-8859-1</title>
 </head>
 <body>
diff --git a/chrome/test/data/extensions/api_test/file_manager_browsertest/file_manager/copy_between_windows.js b/chrome/test/data/extensions/api_test/file_manager_browsertest/file_manager/copy_between_windows.js
index 2c4f34ef..4b72648 100644
--- a/chrome/test/data/extensions/api_test/file_manager_browsertest/file_manager/copy_between_windows.js
+++ b/chrome/test/data/extensions/api_test/file_manager_browsertest/file_manager/copy_between_windows.js
@@ -221,7 +221,6 @@
     },
     // Add a file to USB.
     function(result) {
-      chrome.test.assertTrue(JSON.parse(result));
       addEntries(['usb'], [ENTRIES.hello], this.next);
     },
     // Wait for the mount.
@@ -259,7 +258,6 @@
     },
     // Add a file to USB.
     function(result) {
-      chrome.test.assertTrue(JSON.parse(result));
       addEntries(['usb'], [ENTRIES.hello], this.next);
     },
     // Wait for the mount.
@@ -282,4 +280,3 @@
     }
   ]);
 };
-
diff --git a/chrome/test/data/extensions/api_test/file_manager_browsertest/file_manager/file_display.js b/chrome/test/data/extensions/api_test/file_manager_browsertest/file_manager/file_display.js
index c3b4c3b..e3d174ff 100644
--- a/chrome/test/data/extensions/api_test/file_manager_browsertest/file_manager/file_display.js
+++ b/chrome/test/data/extensions/api_test/file_manager_browsertest/file_manager/file_display.js
@@ -69,7 +69,6 @@
     },
     // Wait for the mount.
     function(result) {
-      chrome.test.assertTrue(JSON.parse(result));
       remoteCall.waitForElement(appId, MTP_VOLUME_QUERY).then(this.next);
     },
     // Click the MTP volume.
diff --git a/chrome/test/data/extensions/api_test/file_manager_browsertest/test_util.js b/chrome/test/data/extensions/api_test/file_manager_browsertest/test_util.js
index 2ca52c5..ea6da1f 100644
--- a/chrome/test/data/extensions/api_test/file_manager_browsertest/test_util.js
+++ b/chrome/test/data/extensions/api_test/file_manager_browsertest/test_util.js
@@ -109,9 +109,6 @@
       name: 'addEntries',
       volume: volume,
       entries: entries
-    }).then(function(result) {
-      if (result !== "onEntryAdded")
-        return Promise.reject('Failed to add entries to ' + volume + '.');
     });
   });
   var resultPromise = Promise.all(volumeResultPromises);
diff --git a/chrome/test/data/extensions/api_test/file_system_provider/write_file/test.js b/chrome/test/data/extensions/api_test/file_system_provider/write_file/test.js
index c51cfd1..0ec32ab7 100644
--- a/chrome/test/data/extensions/api_test/file_system_provider/write_file/test.js
+++ b/chrome/test/data/extensions/api_test/file_system_provider/write_file/test.js
@@ -49,15 +49,25 @@
 var TESTING_CHOCOLATE_FILE_NAME = 'chocolate.txt';
 
 /**
+ * List of callbacks to be called when a file write is requested.
+ * @type {Array.<function(string)>}
+ */
+var writeFileRequestedCallbacks = [];
+
+/**
  * Requests writing contents to a file, previously opened with <code>
  * openRequestId</code>.
  *
  * @param {ReadFileRequestedOptions} options Options.
- * @param {function(} onSuccess Success callback.
+ * @param {function()} onSuccess Success callback.
  * @param {function(string)} onError Error callback.
  */
 function onWriteFileRequested(options, onSuccess, onError) {
   var filePath = test_util.openedFiles[options.openRequestId];
+  writeFileRequestedCallbacks.forEach(function(callback) {
+    callback(filePath);
+  });
+
   if (options.fileSystemId != test_util.FILE_SYSTEM_ID || !filePath) {
     onError('SECURITY');  // enum ProviderError.
     return;
@@ -350,12 +360,14 @@
               fileWriter.onabort = function(e) {
                 hadAbort = true;
               };
+              writeFileRequestedCallbacks.push(
+                  function(filePath) {
+                    // Abort the operation after it's started.
+                    if (filePath == '/' + TESTING_CHOCOLATE_FILE_NAME)
+                      fileWriter.abort();
+                  });
               var blob = new Blob(['A lot of cherries.'], {type: 'text/plain'});
               fileWriter.write(blob);
-              setTimeout(function() {
-                // Abort the operation after it's started.
-                fileWriter.abort();
-              }, 0);
             },
             function(error) {
               chrome.test.fail();
diff --git a/chrome/test/data/extensions/api_test/webstore_private/bundle/app1.json b/chrome/test/data/extensions/api_test/webstore_private/bundle/app1.json
deleted file mode 100644
index cc6c678..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/bundle/app1.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "name": "app.1",
-  "version": "1",
-  "app": {
-    "urls": [ "http://www.testapp.com" ],
-    "launch": { "web_url": "http://www.testapp.com" }
-  },
-  "permissions": [ "clipboardRead" ]
-}
diff --git a/chrome/test/data/extensions/api_test/webstore_private/bundle/app2.json b/chrome/test/data/extensions/api_test/webstore_private/bundle/app2.json
deleted file mode 100644
index 4618194..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/bundle/app2.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "name": "app.2",
-  "version": "1",
-  "manifest_version": 2,
-  "app": {
-    "urls": [ "http://www.testapp2.com" ],
-    "launch": { "web_url": "http://www.testapp2.com" }
-  }
-}
diff --git a/chrome/test/data/extensions/api_test/webstore_private/bundle/begfmnajjkbjdgmffnjaojchoncnmngg.pem b/chrome/test/data/extensions/api_test/webstore_private/bundle/begfmnajjkbjdgmffnjaojchoncnmngg.pem
deleted file mode 100644
index 40fd445..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/bundle/begfmnajjkbjdgmffnjaojchoncnmngg.pem
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAK2fNXqRvU7cAJmPp
-XYmV0x96j9157th9YOPgP2qWtNEYp+e4pDgtr6FbmnrytDTbCCkyy2GgJmhX7I1x9
-FPZv7/kAYEH78IDNMHyEtbHJOkAhofZdVT7KdtDehhcZziKdBjtML/gY33ZGMBmDM
-PZsGJART/Zt9lj/5jexv80UiVAgMBAAECgYEAqe/VFl0jn9YyOBujZhttAw+Tgf3T
-jVL6TYTeSmq9b1/V8EpBlHB+LcjII6CI6RCnGuRxgePOZ5DN6848ACDpuzyA7m1/x
-ndm0KZnQN43EpMj8TLHcsnIZOiO2P/3Rc/srubwZR2oqgZicC8+mYNvwN1d+FHt6u
-2HzivMIcOJK0ECQQDWb0buj6XyV2dhdvhOwlONQYHPKWutNjPfDBf0o+rRGCW4SA9
-l9dozvkVnTuuGnv7PQBRDIae1zOKx8uHBz6zdAkEAz0a2S2hAxgeBSpt2UmixuYwA
-aLi3AX4tT6eAgAXGymVwtRXcBPUijB4itE3DHcFhyk4IzjBFFxdryMxAArkTGQJAL
-h/3gP8zMeKtISDnHoHcWQkbNAVz3OlI1RST3pKXwuxPyMjvTv5INlMaOLOYI/f1VX
-0yHpKRsaBlruNQvlC+nQJBAMxOcOUHD8GiKCi37/ruwy+W9dhDKe/IxTTcb+bAyt8
-4+c0kjMg+MB1YnvCGLaqosJFONZO3NIK8TTuRSA7nChECQQCNMCKYF/3NftJOFZKP
-eYGKagaFjwuPHj39qpGKJtCdwg5oIAtw/xlz7rSRfegQ/hGTAikXiPHt0ZIjU4Tps
-v+k
------END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/api_test/webstore_private/bundle/bmfoocgfinpmkmlbjhcbofejhkhlbchk.pem b/chrome/test/data/extensions/api_test/webstore_private/bundle/bmfoocgfinpmkmlbjhcbofejhkhlbchk.pem
deleted file mode 100644
index f69f4964..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/bundle/bmfoocgfinpmkmlbjhcbofejhkhlbchk.pem
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMRkvle1bZcmaeGv1
-/Ia8WRIosC5dr7E70gP3XOfwE+70EnC+Ytj3aU99VBbFow2tTgC2uAY+0P5HXvH9K
-woeJdPtOOPdRZ+VvE9JqwsEKps+C915YPb7iYIIoU3IXEe3O3ox8F4bPu1iiNabtr
-n6lopCH7E22QeSR5hPdVO8fq5AgMBAAECgYEAn0I23HdClHTRHfPzwN+6aqFAYdrE
-AXU/uQcshKvCTqY2BOq4ZCGqxmoU+YG0KiXfFLmz9lAryfZEw3Dl54m2J0oKHLgpX
-Fh2NsNPBAFTIgz8LLqXZxQ/30luxPLipTOX4mcN0ULX0MkQsxf/TgS0PrCPfgzFBU
-SKDETsBO7g/dUCQQDjE2zhcxMrmuqpF1Cy0G28+IzBjI0YooM2ZHiaSh/r/yO8ywN
-DLS3TTD0RggHJiqRCZnlrYgzDeqPW1aPv2tSXAkEA3WjRFEhAjtB5Ct4npVIyqGzW
-q+hQncG48T7PmOXdN+jL72XafEkKTJ0N0wghr9YwFda2EyBD0HD1FKnW+xIFLwJAW
-p3A4IMUjl0m8c1tFb6ZXETvnrlhAQixRf54JlIYRQwvDcMSDTe1RtHwuNDht7TM8f
-aE07ZwE34Ybb4ZyrjQBwJAfW7MRDlKmZ3xdP62ZypSGKjQVUOfqD//jmyPH4fZ87q
-nDlEdnhujAhRXqJ6KtxsY0sZ5EAzPXl8f+Tze1g43cQJAQa/Ycwm+IuaSkYeOM7oJ
-by7PRPZ7CqQknxBLfGgCnfmhEIcfNaa1+o+Fbf8GZNlQNzkxmq3zD9TDEn5zCdRa/
-w==
------END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/api_test/webstore_private/bundle/extension1.json b/chrome/test/data/extensions/api_test/webstore_private/bundle/extension1.json
deleted file mode 100644
index 25ff2c3..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/bundle/extension1.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "name": "__MSG__name",
-  "version": "1",
-  "manifest_version": 2,
-  "permissions": [ "tabs" ]
-}
diff --git a/chrome/test/data/extensions/api_test/webstore_private/bundle/extension2.json b/chrome/test/data/extensions/api_test/webstore_private/bundle/extension2.json
deleted file mode 100644
index 567fb13..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/bundle/extension2.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "name": "extension.2",
-  "version": "1",
-  "manifest_version": 2,
-  "permissions": ["management", "http://google.com" ]
-}
diff --git a/chrome/test/data/extensions/api_test/webstore_private/bundle/mpneghmdnmaolkljkipbhaienajcflfe.pem b/chrome/test/data/extensions/api_test/webstore_private/bundle/mpneghmdnmaolkljkipbhaienajcflfe.pem
deleted file mode 100644
index 045205b..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/bundle/mpneghmdnmaolkljkipbhaienajcflfe.pem
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOwcURDS6XmYMM8i0
-e46qYuH8OZImKV+FClIHYH6gVtsqRWGEFsGstkQa7PYP2eZRe1Y6C/bbrzAbPtNEZ
-8HDjtdDDLaO5buNyGHSP0xevj1QexwFYSuE0Skwatcz7vK32EkUzu1fuHeX3GuzOD
-tIk+drHNXcsIPggZ/U7X1DffrAgMBAAECgYEAqFGHePbiekyEfyXTgoFPXKkMkx4t
-s8ytksBWSNLMZOCRqUZpYnrkBNov7YW7rZ8Wup0m6PcFeomzJ3NJnJTrDwf8kDlRN
-GvVyfm2WYtuBfNEdielS1IGDdG5oXryFYkbQtstVvMEPRCmPylfaQEh7mA9EBoDJO
-KmHBC/vl4fzAECQQD/YF9SjhKTeP6t+eQ5nNhxKz4YlAo/ute6MoMAj335RjsLBAa
-S7QdAKoS30IRmJA2U9/q0grO9XOkL1hLEfD4lAkEA7K/m34Q8evMlN/372gSbbIkg
-xiv7h9mnWa99o673tUasHOchUcNjRUo7FPooGNF17GmCrg3exXXHlVrWOd9YzwJBA
-JmgXxepshEXS5Zbaukhqq9BxURB4nx+KQKxGk+/AphvoFs7G71Na/w018xAWzWa4L
-TKDP6EVh5Hg0aEjJu45iUCQDaJjZxBPyJhdlkBiA/DcgC/VDL1nX6/E0WiH0QhI+i
-8QRpj05SgffZQVW7O+YBGe3KfGUJ75bIAIp3ykVxCb5cCQHdBAeoCpV2SgRN3vwf7
-aJmjRmF1j3rBXIgpAZQ77XU30ZPwIy9DoaV1JPF/2fqmwjhBM8Ug8IlNusOkG31Op
-lw=
------END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/api_test/webstore_private/bundle/pkapffpjmiilhlhbibjhamlmdhfneidj.pem b/chrome/test/data/extensions/api_test/webstore_private/bundle/pkapffpjmiilhlhbibjhamlmdhfneidj.pem
deleted file mode 100644
index 9e0d783..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/bundle/pkapffpjmiilhlhbibjhamlmdhfneidj.pem
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANnVMj1o/ie45vXd3
-IhQEy+UNJ/CeZME9TJDMFPiOzrGqeMI6Ku9SdNo5EhS+EwA51/Zgfjt5lZl1BIa+B
-2wNammaJg2V2Yl9zfOj/ye5kyCr0z5QRcWwIG/YGhwVl9V+Hls+KHSV7ZP5ivhyGn
-Uts3ft/dL1YSF5pRgEK78YeBbAgMBAAECgYBxZ7vTGsEOXwXmxI1WbhG++HJ5Jd7z
-OmaIt1AGq8XYMKsrZmzzVAWGSZpnSMK5ltLeJLe0p+391t+UWXQIyL72UJ9Nm8e8h
-AFDwYC7Lyjlf2NDqi8/ylL0RfWM4y0EGzsVGprymWkQIdFZd932p0LnKNFPSsI1p4
-hqBpKyiiPd6QJBAPBfaOcJeeRwhWt5XN6mdl37K3BSdpXAG9ph1kwElTxN2QBk22a
-FxcaPlPJe0yKql5AUVDuNlXnwTSPanSFPQc8CQQDn/qYN1E1Vay1T82vtcp7SDPug
-J7BJRw7nVEfPaiCnngD8CX9706szZL7yqHf51WvF7EBrTjIgd7X/LsLGFVe1AkBTN
-NO9VhxppUGqCGLLd9f1hGJvCTyfbda2a7OgsN1v+Iqrhj4kaR4jM8SdeZGgqGi6qS
-7XRpV9ll89kAlgZG0lAkBxOx3rNArGvTfzeKTd0QrpdMK/qX9mVJNWnxEpkB/+D6V
-lXnFli6tMu0hjgYyFWQBwKt5KQXE/3Y3rzfPs4G/dAkAKjwU3x8/1MLD6mBZwp60s
-M3xunjgzglYKg55Grn3+C+S09TEr/OEMqIZPEQ5f4pAnIlWqOyQTDNBFutM3c6/j
------END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/api_test/webstore_private/install_bundle.html b/chrome/test/data/extensions/api_test/webstore_private/install_bundle.html
deleted file mode 100644
index d9859dd..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/install_bundle.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!--
- * Copyright (c) 2012 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.
--->
-<script src="common.js"></script>
-<script>
-
-var bundleItems = [
-  {
-    id: 'begfmnajjkbjdgmffnjaojchoncnmngg',
-    manifest: getManifest('bundle/app1.json'),
-    localizedName: 'app.1'
-  },
-  {
-    id: 'mpneghmdnmaolkljkipbhaienajcflfe',
-    manifest: getManifest('bundle/app2.json'),
-    localizedName: 'app.2'
-  },
-  {
-    id: 'bmfoocgfinpmkmlbjhcbofejhkhlbchk',
-    manifest: getManifest('bundle/extension1.json'),
-    localizedName: 'extension.1'
-  },
-  {
-    id: 'pkapffpjmiilhlhbibjhamlmdhfneidj',
-    manifest: getManifest('bundle/extension2.json'),
-    localizedName: 'extension.2'
-  }
-];
-
-runTests([
-  function successfulInstall() {
-    chrome.webstorePrivate.installBundle(
-        bundleItems, callbackPass(function() {
-      bundleItems.forEach(function(item) {
-        checkItemInstalled(
-            item.id,
-            callbackPass(function(result) { assertTrue(result); }));
-      });
-    }));
-  }
-]);
-
-</script>
diff --git a/chrome/test/data/extensions/api_test/webstore_private/install_bundle_cancel.html b/chrome/test/data/extensions/api_test/webstore_private/install_bundle_cancel.html
deleted file mode 100644
index 4453f92..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/install_bundle_cancel.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!--
- * Copyright (c) 2012 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.
--->
-<script src="common.js"></script>
-<script>
-
-var bundleItems = [
-  {
-    id: 'begfmnajjkbjdgmffnjaojchoncnmngg',
-    manifest: getManifest('bundle/app1.json'),
-    localizedName: 'app.1'
-  },
-  {
-    id: 'mpneghmdnmaolkljkipbhaienajcflfe',
-    manifest: getManifest('bundle/app2.json'),
-    localizedName: 'app.2'
-  },
-  {
-    id: 'bmfoocgfinpmkmlbjhcbofejhkhlbchk',
-    manifest: getManifest('bundle/extension1.json'),
-    localizedName: 'extension.1'
-  },
-  {
-    id: 'pkapffpjmiilhlhbibjhamlmdhfneidj',
-    manifest: getManifest('bundle/extension2.json'),
-    localizedName: 'extension.2'
-  }
-];
-
-runTests([
-  function installCanceled() {
-    chrome.webstorePrivate.installBundle(
-        bundleItems, callbackFail("user_canceled"));
-  }
-]);
-
-</script>
diff --git a/chrome/test/data/extensions/api_test/webstore_private/install_bundle_invalid.html b/chrome/test/data/extensions/api_test/webstore_private/install_bundle_invalid.html
deleted file mode 100644
index f27baea..0000000
--- a/chrome/test/data/extensions/api_test/webstore_private/install_bundle_invalid.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
- * Copyright (c) 2012 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.
--->
-<script src="common.js"></script>
-<script>
-
-var bundleItems = [
-  {
-    id: 'begfmnajjkbjdgmffnjaojchoncnmngg',
-    manifest: getManifest('bundle/app1.json'),
-    localizedName: 'app.1'
-  },
-  {
-    id: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',  // Invalid CRX.
-    manifest: getManifest('bundle/app2.json'),
-    localizedName: 'app.2'
-  },
-  {
-    id: 'bmfoocgfinpmkmlbjhcbofejhkhlbchk',  // Wrong manifest.
-    manifest: getManifest('bundle/extension2.json'),
-    localizedName: 'extension.1'
-  },
-  {
-    id: 'pkapffpjmiilhlhbibjhamlmdhfneidj',  // No CRX, 404.
-    manifest: getManifest('bundle/extension2.json'),
-    localizedName: 'extension.2'
-  }
-];
-
-var installed = [
-  'begfmnajjkbjdgmffnjaojchoncnmngg'
-];
-
-var failed = [
-  'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
-  'bmfoocgfinpmkmlbjhcbofejhkhlbchk',
-  'pkapffpjmiilhlhbibjhamlmdhfneidj'
-];
-
-runTests([
-  function successfulInstall() {
-    chrome.webstorePrivate.installBundle(
-        bundleItems, callbackPass(function() {
-      installed.forEach(function(id) {
-        checkItemInstalled(
-            id,
-            callbackPass(function(result) { assertTrue(result); }));
-      });
-      failed.forEach(function(id) {
-        checkItemInstalled(
-            id,
-            callbackPass(function(result) { assertFalse(result); }));
-      });
-    }));
-  },
-
-  function allItemsFail() {
-    chrome.webstorePrivate.installBundle(
-        [bundleItems[2]], callbackPass(function() {
-      checkItemInstalled(
-           bundleItems[2].id,
-           callbackPass(function(result) { assertFalse(result); }));
-    }));
-  },
-
-  function noItems() {
-    chrome.webstorePrivate.installBundle([], callbackFail("unknown_error"));
-  }
-]);
-
-</script>
diff --git a/chrome/test/data/extensions/policy_shared_module/importer.crx b/chrome/test/data/extensions/policy_shared_module/importer.crx
new file mode 100644
index 0000000..45485c2
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/importer.crx
Binary files differ
diff --git a/chrome/test/data/extensions/policy_shared_module/importer.pem b/chrome/test/data/extensions/policy_shared_module/importer.pem
new file mode 100644
index 0000000..eaafa40f
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/importer.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqQkAYUI9ul4Ge
+FYq50A7mkKrwrEFQHWx1P2j5yAoqcCginTSYW7FUkaI2oNIR1030dwKgx7O006oE
+gnuf6r/JzUmJtEdBW/BhFkJ955DenU0/DTVRGbkbq0QMkVePpDtjA3KtXytkZJds
+BEZMZ1DAvmNsSd9CGDUhrk3c4+6ErsJL6RWOhd8Kp84BN0RYluRr59A85P/d+rtB
+DV7Mgl63577khFpKivhO4I59Gjc4YuWWcOudbUu1YitP+rl6cxi8352Tdu7z8Q70
+ag5rX13Ph15Pj45UlsdhfrOM4dc+IEIUFl77SAFGbRehwUM6iTQFlAdnRPXbW8Kq
+isXLC3XjAgMBAAECggEAfukBQ96Q+7udV4vxK05mPQErGlkcGi7EkKUih8XPphCS
+KjMKaGM4zLP9uUCpNblKl2Y6pEQXtTttaQ0mP27JZRBLt4SU9KgmhwgDqjv5JacV
+VGFxE7Hb5D8Ga2PPY/fkeIqyaX8eJihBIrgQ+pSsge+oxqhN7cODn0aBLZ0NRwKR
+tWcr7mS/6DYqHO+AJxZmR4CViot1u55wmYOhrne611p9ffBHLiFn2JFsIW5+cCYq
+FYTZov4Y015B0jqGbMYMOaAmMkymjuSWlOEBN0lvh3eLuIDV7LOcHMz/DPhn6SH5
+bTV8PA8fghD6Ah0TVqi9aTUDz0A1+++mnccj7AlqYQKBgQDZ38dRaqy8GltFxMvF
+RkHP6d/+zr9KpTOw7/rAO42pouGf1vRB/ERZyb6Yfdogbca33KZ64t1XyakZuJU3
+RtcI9x63fyWM/vc4XEogWUcUkuaOH7N4HZNZAMebfYvAfr8z+G2VumGjCoOEQQbg
+VQjEQKiliC+mO14aSBN9qVvDMwKBgQDIDWwdlfx/Tn1vIkRYPgImAZf7YRKKzi0F
+54zh+oGhmQih3LqCpG+UGNPP4lyiYeyXequSzC6Y3we5/BLhIAYPSBYOfGYWm3VO
+MFMWJIb7BM0xgwm+jjS+me9RvHeQuIvUa6T2q196Ad3uWzxUrOTr34yP3YAiyCke
+cvwrh0aCkQKBgQDXOKJpP8pgilytP+jW+D8cxngZ+lumviig2X7HFE0tTJQ61Bk3
+cZ6HX64ibvfhXu+VQqdF7wMdrDyaBueH0jerSIoUU8phTKAkEa6749U+cprDvHcJ
+6ZVbr1R+ufcqcUopaXe/F31JlKI0LBRB2F4vl3vBARWozS55Icf3MyxNVwKBgBmB
+vJs5GGyS8WNOFzC5F0UJRvuCMP8JsqviDhByBD06aeNZZV5q4N8dG0SSNAVwPt5B
+gcbByd8r8KxB+5ZAowUnx8gpDEstnxNNDgrwtVUkE5WQg5mMQCVdMypUwVnubcWz
+w+C/kPjZbBaMA3E4aie45Q8iysekhbmgJ47VPKRBAoGAF7hIX+Enr9srmiydTab1
+p5PFnt5sHNlStFNHvUukO38TIshfOls6tyfv2OEqyZvLH4X8NWzWJLmdfOiz4zJf
+IJWovt7rhuliO3m0TiRHZTpmc7Syg3SNr4gdm5B6okRYCFwLaDr9u00z3v/ri5UD
+sldEo18tR5eZVdICX7mrGrk=
+-----END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/policy_shared_module/importer/main.html b/chrome/test/data/extensions/policy_shared_module/importer/main.html
new file mode 100644
index 0000000..528cf9c4
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/importer/main.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<script src="_modules/nfgclafboonjbiafbllihiailjlhelpm/pass.js"></script>
diff --git a/chrome/test/data/extensions/policy_shared_module/importer/manifest.json b/chrome/test/data/extensions/policy_shared_module/importer/manifest.json
new file mode 100644
index 0000000..378bbbf
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/importer/manifest.json
@@ -0,0 +1,14 @@
+{
+  "name": "Imports a Shared Module",
+  "manifest_version": 2,
+  "version": "1.0",
+  "app": {
+    "background": {
+      "page": "main.html"
+    }
+  },
+  "import": [{
+      "id": "nfgclafboonjbiafbllihiailjlhelpm"
+    }
+  ]
+}
diff --git a/chrome/test/data/extensions/policy_shared_module/shared_module.crx b/chrome/test/data/extensions/policy_shared_module/shared_module.crx
new file mode 100644
index 0000000..68a701ba
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/shared_module.crx
Binary files differ
diff --git a/chrome/test/data/extensions/policy_shared_module/shared_module.pem b/chrome/test/data/extensions/policy_shared_module/shared_module.pem
new file mode 100644
index 0000000..5e7066d
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/shared_module.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC9QW+Mz6lzWrbV
+3ujifeUh2teHWLc2zd8cAvKfSxw0YAB7C5ggHifk89tT6NBgqhcUms9jX1VD84XZ
+1FnNWEBvKo5XltIuHnPnf+NL2sWleXjhPXElgU6AyG3zFTk+k61oMnTiiG3m1rnm
+jhKLkxJE5uppEJaVsYvgpPlmQ3ImOsTEVT9kFfLQ3bIKU9f49VCFRN6b6HQr7Kfo
+HOtX8thcCkf1tTveZyrQWApGFyXFWQc/jQDro465R9ug5hhRinkxXgXzrS4Fm+ZU
+WhXSltLtE+FYXoUNCw6+X0btzu+cEUuLsV9L7i61eG/kyfVc8NzbM3E2x9J+sGzm
+nJQCFIDVAgMBAAECggEAVxkTTlmPoYABHwJcaUgJOIBvqmFgyD8My+ZrZHX7v/ri
+nb4jP7zBHXRA3ygJJkOBJcFtak1If2JGmo5I2eEgnkiWg6bsib8IFmVb5OAFD/eM
+cxSEyv7scwZK25FL7Amox4hZFJw3AAKYQYvm6wc/ZChlfv7cXn38YuFpye+GTCL6
+pJt3Xko3AaV0r29ND918kdi+DNdrIpknhzdRaRnzucR6TZOXAlLlUn+OIcVdTBrk
+mdKVnaa9VWR156VEy+PG5Dio0rILESGhErlG60JFhpwzWH6zOSEPyaUztuvkSmJJ
+wShzZMCY4wq8MMGvlUWRjHQOV6TPEeCWBMVfCqUwYQKBgQDslUpqzOw3v2LAuWix
+pMx734kBObv1EmRYOLcxMj0RFa4RRsQRq2g8nYROK33ikHZlIV2Y7lm/TZhhCLPW
+zs4RPE2lj5LhouncRNmnaIuSMuBJGmIcFfyJbFopphEER5SsXkBX8KYFNdoBPE7+
+wmg5GxTsnyq3bFAAXFNhbWQorQKBgQDMycYN3A/XKf0xfj5ROX6lnR/k6D4rEg+N
+9PS/2yROywxIl5WnMOZwDuqUG1DgzcHSbsrFdp4/L8fLOkCHUkQPRuYDfT6i98kz
+YnMmpT6fawV2xwMpAtXZO6v20jB+eM0VtKIXiFXJvg7m4iW54eXR7qtoiuxVSJ3T
+Uv5Csu/1yQKBgAygo0o0Cd+n3XN/8fCZZTivY7anCDs6chSrYkvD7LJ+v724UzrG
+NVgW6Drr41o2b7tSHpbNEgk98QYs2rx6aVFOMK7HjQVyFp1lJ2DiGaECCiqct+Pb
+4JDNMbrLXFkoIO1aUoDfHV1l1G8Acw7x/XIe2e0PSc5kf5ilVOX8Wr45AoGBAJqW
+titAM7T4vWjfI6us+y2JrsndhxB8UcGXaCpsArx4Co3B3/aVs15j5DBpbmRE7ksr
+12W4ZTzNlMSU9KEyOK5PltKLeP0Mj5V6e/JwSxWMdFN1Z61NtqCFqwpnILRX/Him
+IrYg9KGWFymzDUeEfzg6Mqp4NG8sofckb0tqSDoBAoGBALgA8EcJpRBcWgfzEoeL
+wwb5rYTdeu3Ta4UjI8XqOaVQ5d7GBCsgp1FGQTDZm4+swvi2dItxdiG/moijCCAw
+cES+VtK01APQoyUBpAb7nFOQRKM2rsX5uZvXWyO72Ejo4RRFTP5GVuykhTFAd3ga
+hZk8UU9YHOMrpyX2dC+XajnC
+-----END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/policy_shared_module/shared_module/manifest.json b/chrome/test/data/extensions/policy_shared_module/shared_module/manifest.json
new file mode 100644
index 0000000..80799d9
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/shared_module/manifest.json
@@ -0,0 +1,6 @@
+{
+  "name": "Shared Module",
+  "manifest_version": 2,
+  "version": "1.0",
+  "export": {}
+}
diff --git a/chrome/test/data/extensions/policy_shared_module/shared_module/pass.js b/chrome/test/data/extensions/policy_shared_module/shared_module/pass.js
new file mode 100644
index 0000000..2a344be5
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/shared_module/pass.js
@@ -0,0 +1,5 @@
+// Copyright (c) 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.
+
+var pass_exported = {};
diff --git a/chrome/test/data/extensions/policy_shared_module/update.xml b/chrome/test/data/extensions/policy_shared_module/update.xml
new file mode 100644
index 0000000..4200b23
--- /dev/null
+++ b/chrome/test/data/extensions/policy_shared_module/update.xml
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
+  <app appid='pchakhniekfaeoddkifplhnfbffomabh'>
+    <updatecheck codebase='http://mock.http/extensions/policy_shared_module/importer.crx' version='1.0.0.0' />
+   </app>
+  <app appid='nfgclafboonjbiafbllihiailjlhelpm'>
+    <updatecheck codebase='http://mock.http/extensions/policy_shared_module/shared_module.crx' version='1.0.0.0' />
+   </app>
+</gupdate>
diff --git a/chrome/test/data/password/password_xhr_submit.html b/chrome/test/data/password/password_xhr_submit.html
index bf337e1..67ec93e 100644
--- a/chrome/test/data/password/password_xhr_submit.html
+++ b/chrome/test/data/password/password_xhr_submit.html
@@ -23,5 +23,14 @@
   <input type="password" id="password_field" name="password_field">
   <input type="submit" id="submit_button" name="submit_button">
 </form>
+
+<form action="password_xhr_submit.html" id="signup_testform">
+  <input type="text" id="signup_username_field" name="signup_username_field">
+  <input type="password" id="signup_password_field"
+         name="signup_password_field" autocomplete="new-password">
+  <input type="password" id="confirmation_password_field"
+         name="confirmation_password_field" autocomplete="new-password">
+  <input type="submit" id="signup_submit_button" name="signup_submit_button">
+</form>
 </body>
 </html>
diff --git a/mojo/public/go/mojo/system/core.go b/chrome/test/data/push_messaging/service_worker.js
similarity index 62%
rename from mojo/public/go/mojo/system/core.go
rename to chrome/test/data/push_messaging/service_worker.js
index 8049d37b..116b3556 100644
--- a/mojo/public/go/mojo/system/core.go
+++ b/chrome/test/data/push_messaging/service_worker.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package system;
+// Empty service worker script.
 
-type Core interface {
-	GetTimeTicksNow() int64
-}
+// TODO(mvanouwerkerk): Add test coverage for push event delivery.
diff --git a/chrome/test/data/push_messaging/test.html b/chrome/test/data/push_messaging/test.html
new file mode 100644
index 0000000..4076956
--- /dev/null
+++ b/chrome/test/data/push_messaging/test.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+  <title>Push API Test</title>
+  <script>
+    function sendResultToTest(result) {
+      console.log(result);
+      if (window.domAutomationController) {
+        domAutomationController.send('' + result);
+      }
+    }
+
+    function sendErrorToTest(error) {
+      sendResultToTest(error.name + ' - ' + error.message);
+    }
+
+    function registerServiceWorker() {
+      navigator.serviceWorker.register('service_worker.js').then(function(swRegistration) {
+        console.log(swRegistration);
+        sendResultToTest('ok');
+      }, sendErrorToTest);
+    }
+
+    function registerPush(senderId) {
+      navigator.serviceWorker.ready.then(function() {
+        navigator.push.register(senderId).then(function(pushRegistration) {
+          sendResultToTest(pushRegistration.pushEndpoint + ' - ' + pushRegistration.pushRegistrationId);
+        }, sendErrorToTest);
+      }, sendErrorToTest);
+    }
+  </script>
+ </head>
+ <body>Push API Test</body>
+</html>
diff --git a/chrome/test/data/save_page/b.saved1.htm b/chrome/test/data/save_page/b.saved1.htm
index 6524f086..d14f2cd1 100644
--- a/chrome/test/data/save_page/b.saved1.htm
+++ b/chrome/test/data/save_page/b.saved1.htm
@@ -1,6 +1,6 @@
 
 <!-- saved from url=(0032)http://mock.http/save_page/b.htm -->
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
     <title>
       Test page for saving page feature
     </title>
diff --git a/chrome/test/data/save_page/b.saved2.htm b/chrome/test/data/save_page/b.saved2.htm
index 8f2e67e..e23a7d5f 100644
--- a/chrome/test/data/save_page/b.saved2.htm
+++ b/chrome/test/data/save_page/b.saved2.htm
@@ -1,6 +1,6 @@
 
 <!-- saved from url=(0032)http://mock.http/save_page/b.htm -->
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
     <title>
       Test page for saving page feature
     </title>
diff --git a/chrome/test/data/webui/history_browsertest.js b/chrome/test/data/webui/history_browsertest.js
index 938ee37..bcaf781 100644
--- a/chrome/test/data/webui/history_browsertest.js
+++ b/chrome/test/data/webui/history_browsertest.js
@@ -417,7 +417,7 @@
 
   // Check that there are 3 page navigation links and that only the "Older"
   // link is visible.
-  expectEquals(3, document.querySelectorAll('.link-button').length);
+  expectEquals(3, document.querySelectorAll('[is="action-link"]').length);
   expectTrue($('newest-button').hidden);
   expectTrue($('newer-button').hidden);
   expectFalse($('older-button').hidden);
@@ -442,7 +442,7 @@
 
     // Check that the "Newest" and "Newer" links are now visible, but the
     // "Older" link is hidden.
-    expectEquals(3, document.querySelectorAll('.link-button').length);
+    expectEquals(3, document.querySelectorAll('[is="action-link"]').length);
     expectFalse($('newest-button').hidden);
     expectFalse($('newer-button').hidden);
     expectTrue($('older-button').hidden);
@@ -784,7 +784,8 @@
 });
 
 TEST_F('HistoryWebUIRealBackendTest', 'atLeastOneFocusable', function() {
-  expectEquals(1, document.querySelectorAll('[tabindex="0"]').length);
+  var results = document.querySelectorAll('#results-display [tabindex="0"]');
+  expectEquals(1, results.length);
   testDone();
 });
 
@@ -944,7 +945,8 @@
 });
 
 TEST_F('HistoryWebUIDeleteProhibitedTest', 'atLeastOneFocusable', function() {
-  expectEquals(1, document.querySelectorAll('[tabindex="0"]').length);
+  var results = document.querySelectorAll('#results-display [tabindex="0"]');
+  expectEquals(1, results.length);
   testDone();
 });
 
diff --git a/chrome/test/nacl/nacl_browsertest.cc b/chrome/test/nacl/nacl_browsertest.cc
index de90c12..efd1a1a 100644
--- a/chrome/test/nacl/nacl_browsertest.cc
+++ b/chrome/test/nacl/nacl_browsertest.cc
@@ -107,6 +107,9 @@
 #if defined(OS_WIN)
 // crbug.com/98721
 #  define MAYBE_Crash DISABLED_Crash
+#elif defined(OS_MACOSX)
+// crbug.com/425570
+#  define MAYBE_Crash DISABLED_Crash
 #else
 #  define MAYBE_Crash Crash
 #endif
diff --git a/chrome/test/remoting/remote_desktop_browsertest.cc b/chrome/test/remoting/remote_desktop_browsertest.cc
index cf34624..b1d5717 100644
--- a/chrome/test/remoting/remote_desktop_browsertest.cc
+++ b/chrome/test/remoting/remote_desktop_browsertest.cc
@@ -821,11 +821,19 @@
 void RemoteDesktopBrowserTest::SetUserNameAndPassword(
     const base::FilePath &accounts_file_path, const std::string& account_type) {
 
-  // Read contents of accounts file.
-  std::string accounts_info;
-  ASSERT_TRUE(base::ReadFileToString(accounts_file_path, &accounts_info));
+  // ReadFileToString returns an error if the file-path is relative.
+  // Tests that run on the swarming slaves use relative paths, so we have to use
+  // ReadFile instead.
+  int64 accounts_file_size;
+  base::GetFileSize(accounts_file_path, &accounts_file_size);
+  // There is a compile error on Windows if you use a non-constant array size.
+  // For the test-accounts file, we'll assume a maximum file size of 10K.
+  char buf[10240];
+  ASSERT_FALSE(base::ReadFile(accounts_file_path, buf, accounts_file_size - 1)
+    == -1);
 
   // Get the root dictionary from the input json file contents.
+  std::string accounts_info(buf);
   scoped_ptr<base::Value> root(
       base::JSONReader::Read(accounts_info, base::JSON_ALLOW_TRAILING_COMMAS));
 
diff --git a/chrome/tools/mac_helpers/infoplist_strings_util.mm b/chrome/tools/mac_helpers/infoplist_strings_util.mm
index bd540efb..765969f 100644
--- a/chrome/tools/mac_helpers/infoplist_strings_util.mm
+++ b/chrome/tools/mac_helpers/infoplist_strings_util.mm
@@ -145,8 +145,8 @@
 }
 
 // The valid types for the -t arg
-const char* kAppType_Main = "main";  // Main app
-const char* kAppType_Helper = "helper";  // Helper app
+const char kAppType_Main[] = "main";  // Main app
+const char kAppType_Helper[] = "helper";  // Helper app
 
 }  // namespace
 
diff --git a/chrome/tools/profile_reset/jtl_compiler_unittest.cc b/chrome/tools/profile_reset/jtl_compiler_unittest.cc
index 986eed26..cb6fea2 100644
--- a/chrome/tools/profile_reset/jtl_compiler_unittest.cc
+++ b/chrome/tools/profile_reset/jtl_compiler_unittest.cc
@@ -120,7 +120,7 @@
 }
 
 TEST(JtlCompiler, InvalidArgumentsCount) {
-  const char* kSourceCodes[] = {
+  const char* const kSourceCodes[] = {
       "any().\nstore_bool(\"name\", true, \"superfluous argument\");\n",
       "any().\nstore_bool(\"name\");"};  // missing argument
 
diff --git a/chrome/utility/cloud_print/pwg_encoder.cc b/chrome/utility/cloud_print/pwg_encoder.cc
index 5246bd9..194ccdf 100644
--- a/chrome/utility/cloud_print/pwg_encoder.cc
+++ b/chrome/utility/cloud_print/pwg_encoder.cc
@@ -24,7 +24,7 @@
 const uint32 kBlueCoefficient = 721;
 const uint32 kColorCoefficientDenominator = 10000;
 
-const char* kPwgKeyword = "RaS2";
+const char kPwgKeyword[] = "RaS2";
 
 const uint32 kHeaderSize = 1796;
 const uint32 kHeaderCupsDuplex = 272;
diff --git a/chrome/utility/extensions/unpacker_unittest.cc b/chrome/utility/extensions/unpacker_unittest.cc
index abf6b75..99939f13 100644
--- a/chrome/utility/extensions/unpacker_unittest.cc
+++ b/chrome/utility/extensions/unpacker_unittest.cc
@@ -132,7 +132,7 @@
 }
 
 TEST_F(UnpackerTest, UnzipDirectoryError) {
-  const char* kExpected = "Could not create directory for unzipping: ";
+  const char kExpected[] = "Could not create directory for unzipping: ";
   SetupUnpacker("good_package.crx");
   base::FilePath path =
       temp_dir_.path().AppendASCII(kTempExtensionName);
@@ -146,14 +146,14 @@
 }
 
 TEST_F(UnpackerTest, UnzipError) {
-  const char* kExpected = "Could not unzip extension";
+  const char kExpected[] = "Could not unzip extension";
   SetupUnpacker("bad_zip.crx");
   EXPECT_FALSE(unpacker_->Run());
   EXPECT_EQ(ASCIIToUTF16(kExpected), unpacker_->error_message());
 }
 
 TEST_F(UnpackerTest, BadPathError) {
-  const char* kExpected = "Illegal path (absolute or relative with '..'): ";
+  const char kExpected[] = "Illegal path (absolute or relative with '..'): ";
   SetupUnpacker("bad_path.crx");
   EXPECT_FALSE(unpacker_->Run());
   EXPECT_TRUE(StartsWith(unpacker_->error_message(),
@@ -165,7 +165,7 @@
 
 
 TEST_F(UnpackerTest, ImageDecodingError) {
-  const char* kExpected = "Could not decode image: ";
+  const char kExpected[] = "Could not decode image: ";
   SetupUnpacker("bad_image.crx");
   EXPECT_FALSE(unpacker_->Run());
   EXPECT_TRUE(StartsWith(unpacker_->error_message(),
diff --git a/chrome/utility/importer/external_process_importer_bridge.cc b/chrome/utility/importer/external_process_importer_bridge.cc
index 56c82be..fcfc61f 100644
--- a/chrome/utility/importer/external_process_importer_bridge.cc
+++ b/chrome/utility/importer/external_process_importer_bridge.cc
@@ -5,6 +5,7 @@
 #include "chrome/utility/importer/external_process_importer_bridge.h"
 
 #include "base/bind.h"
+#include "base/debug/dump_without_crashing.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -26,7 +27,16 @@
 const int kNumHistoryRowsToSend = 100;
 const int kNumFaviconsToSend = 100;
 const int kNumAutofillFormDataToSend = 100;
+
+// http://crbug.com/404012. Let's see where the empty fields come from.
+void CheckForEmptyUsernameAndPassword(const autofill::PasswordForm& form) {
+  if (form.username_value.empty() &&
+      form.password_value.empty() &&
+      !form.blacklisted_by_user) {
+    base::debug::DumpWithoutCrashing();
+  }
 }
+} // namespace
 
 ExternalProcessImporterBridge::ExternalProcessImporterBridge(
     const base::DictionaryValue& localized_strings,
@@ -138,6 +148,7 @@
 
 void ExternalProcessImporterBridge::SetPasswordForm(
     const autofill::PasswordForm& form) {
+  CheckForEmptyUsernameAndPassword(form);
   Send(new ProfileImportProcessHostMsg_NotifyPasswordFormReady(form));
 }
 
diff --git a/chrome/utility/importer/firefox_importer.cc b/chrome/utility/importer/firefox_importer.cc
index e54032b7..fdb14cd 100644
--- a/chrome/utility/importer/firefox_importer.cc
+++ b/chrome/utility/importer/firefox_importer.cc
@@ -15,7 +15,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/common/importer/firefox_importer_utils.h"
-#include "chrome/common/importer/firefox_importer_utils.h"
 #include "chrome/common/importer/imported_bookmark_entry.h"
 #include "chrome/common/importer/imported_favicon_usage.h"
 #include "chrome/common/importer/importer_autofill_form_data_entry.h"
@@ -638,9 +637,9 @@
                                       int* toolbar_folder_id,
                                       int* menu_folder_id,
                                       int* unsorted_folder_id) {
-  static const char* kToolbarFolderName = "toolbar";
-  static const char* kMenuFolderName = "menu";
-  static const char* kUnsortedFolderName = "unfiled";
+  static const char kToolbarFolderName[] = "toolbar";
+  static const char kMenuFolderName[] = "menu";
+  static const char kUnsortedFolderName[] = "unfiled";
 
   const char query[] = "SELECT root_name, folder_id FROM moz_bookmarks_roots";
   sql::Statement s(db->GetUniqueStatement(query));
@@ -659,7 +658,7 @@
 
 void FirefoxImporter::LoadLivemarkIDs(sql::Connection* db,
                                        std::set<int>* livemark) {
-  static const char* kFeedAnnotation = "livemark/feedURI";
+  static const char kFeedAnnotation[] = "livemark/feedURI";
   livemark->clear();
 
   const char query[] =
diff --git a/chrome/utility/importer/nss_decryptor.cc b/chrome/utility/importer/nss_decryptor.cc
index 656b73f..8e9d85f 100644
--- a/chrome/utility/importer/nss_decryptor.cc
+++ b/chrome/utility/importer/nss_decryptor.cc
@@ -243,7 +243,7 @@
   if (!db.Open(sqlite_file))
     return false;
 
-  const char* query = "SELECT hostname FROM moz_disabledHosts";
+  const char query[] = "SELECT hostname FROM moz_disabledHosts";
   sql::Statement s(db.GetUniqueStatement(query));
   if (!s.is_valid())
     return false;
@@ -262,9 +262,9 @@
     forms->push_back(form);
   }
 
-  const char* query2 = "SELECT hostname, httpRealm, formSubmitURL, "
-                       "usernameField, passwordField, encryptedUsername, "
-                       "encryptedPassword FROM moz_logins";
+  const char query2[] = "SELECT hostname, httpRealm, formSubmitURL, "
+                        "usernameField, passwordField, encryptedUsername, "
+                        "encryptedPassword FROM moz_logins";
 
   sql::Statement s2(db.GetUniqueStatement(query2));
   if (!s2.is_valid())
diff --git a/chrome/utility/importer/safari_importer.mm b/chrome/utility/importer/safari_importer.mm
index 480eedd..e6fa2d73 100644
--- a/chrome/utility/importer/safari_importer.mm
+++ b/chrome/utility/importer/safari_importer.mm
@@ -120,7 +120,7 @@
 
 void SafariImporter::ImportFaviconURLs(sql::Connection* db,
                                        FaviconMap* favicon_map) {
-  const char* query = "SELECT iconID, url FROM PageURL;";
+  const char query[] = "SELECT iconID, url FROM PageURL;";
   sql::Statement s(db->GetUniqueStatement(query));
 
   while (s.Step() && !cancelled()) {
@@ -134,10 +134,10 @@
     sql::Connection* db,
     const FaviconMap& favicon_map,
     std::vector<ImportedFaviconUsage>* favicons) {
-  const char* query = "SELECT i.url, d.data "
-                      "FROM IconInfo i JOIN IconData d "
-                      "ON i.iconID = d.iconID "
-                      "WHERE i.iconID = ?;";
+  const char query[] = "SELECT i.url, d.data "
+                       "FROM IconInfo i JOIN IconData d "
+                       "ON i.iconID = d.iconID "
+                       "WHERE i.iconID = ?;";
   sql::Statement s(db->GetUniqueStatement(query));
 
   for (FaviconMap::const_iterator i = favicon_map.begin();
diff --git a/chrome/utility/web_resource_unpacker.cc b/chrome/utility/web_resource_unpacker.cc
index 3122200..648a5d14 100644
--- a/chrome/utility/web_resource_unpacker.cc
+++ b/chrome/utility/web_resource_unpacker.cc
@@ -7,10 +7,10 @@
 #include "base/json/json_reader.h"
 #include "base/values.h"
 
-const char* WebResourceUnpacker::kInvalidDataTypeError =
+const char WebResourceUnpacker::kInvalidDataTypeError[] =
     "Data from web resource server is missing or not valid JSON.";
 
-const char* WebResourceUnpacker::kUnexpectedJSONFormatError =
+const char WebResourceUnpacker::kUnexpectedJSONFormatError[] =
     "Data from web resource server does not have expected format.";
 
 WebResourceUnpacker::WebResourceUnpacker(const std::string &resource_data)
diff --git a/chrome/utility/web_resource_unpacker.h b/chrome/utility/web_resource_unpacker.h
index 18f045d..784ea00 100644
--- a/chrome/utility/web_resource_unpacker.h
+++ b/chrome/utility/web_resource_unpacker.h
@@ -23,8 +23,8 @@
 
 class WebResourceUnpacker {
  public:
-  static const char* kInvalidDataTypeError;
-  static const char* kUnexpectedJSONFormatError;
+  static const char kInvalidDataTypeError[];
+  static const char kUnexpectedJSONFormatError[];
 
   explicit WebResourceUnpacker(const std::string &resource_data);
   ~WebResourceUnpacker();
diff --git a/chrome_elf/blacklist/blacklist.cc b/chrome_elf/blacklist/blacklist.cc
index 24e5fe8b..6d78608 100644
--- a/chrome_elf/blacklist/blacklist.cc
+++ b/chrome_elf/blacklist/blacklist.cc
@@ -48,6 +48,7 @@
   L"libwinhook.dll",                    // V-Bates.
   L"lmrn.dll",                          // Unknown.
   L"minisp.dll",                        // Unknown (suspected malware).
+  L"safetynut.dll",                     // Unknown (suspected adware).
   L"systemk.dll",                       // Unknown (suspected adware).
   L"windowsapihookdll32.dll",           // Lenovo One Key Theater.
                                         // See crbug.com/379218.
diff --git a/chromecast/browser/android/apk/AndroidManifest.xml b/chromecast/browser/android/apk/AndroidManifest.xml
index 8084f8f..8dc8d97 100644
--- a/chromecast/browser/android/apk/AndroidManifest.xml
+++ b/chromecast/browser/android/apk/AndroidManifest.xml
@@ -97,37 +97,37 @@
                  android:exported="false" />
         <service android:name="org.chromium.content.app.SandboxedProcessService13"
                  android:process=":sandboxed_process13"
-                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:permission="org.chromium.chromecast.shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
         <service android:name="org.chromium.content.app.SandboxedProcessService14"
                  android:process=":sandboxed_process14"
-                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:permission="org.chromium.chromecast.shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
         <service android:name="org.chromium.content.app.SandboxedProcessService15"
                  android:process=":sandboxed_process15"
-                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:permission="org.chromium.chromecast.shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
         <service android:name="org.chromium.content.app.SandboxedProcessService16"
                  android:process=":sandboxed_process16"
-                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:permission="org.chromium.chromecast.shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
         <service android:name="org.chromium.content.app.SandboxedProcessService17"
                  android:process=":sandboxed_process17"
-                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:permission="org.chromium.chromecast.shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
         <service android:name="org.chromium.content.app.SandboxedProcessService18"
                  android:process=":sandboxed_process18"
-                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:permission="org.chromium.chromecast.shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
         <service android:name="org.chromium.content.app.SandboxedProcessService19"
                  android:process=":sandboxed_process19"
-                 android:permission="org.chromium.content_shell.permission.SANDBOX"
+                 android:permission="org.chromium.chromecast.shell.permission.SANDBOX"
                  android:isolatedProcess="true"
                  android:exported="false" />
     </application>
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
index 20fed19..ca25fb11 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
@@ -21,8 +21,8 @@
     @CalledByNative
     public static void uploadCurrentProcessDumpSync(String crashDumpPath, String logFilePath,
             boolean isDebugBuild) {
-        new CastCrashUploader(crashDumpPath, isDebugBuild).
-                uploadCurrentProcessDumpSync(logFilePath);
+        new CastCrashUploader(crashDumpPath, isDebugBuild)
+                .uploadCurrentProcessDumpSync(logFilePath);
     }
 
     @CalledByNative
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
index bc1631c..d8f50fc8 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
@@ -100,7 +100,7 @@
             public void run() {
                 // Multipart dump filename has format "[random string].dmp[pid]", e.g.
                 // 20597a65-b822-008e-31f8fc8e-02bb45c0.dmp18169
-                queueAllCrashDumpUpload(".*\\.dmp\\d+", null);
+                queueAllCrashDumpUpload(".*\\.dmp\\d*", null);
             }
         });
     }
@@ -183,6 +183,12 @@
                     int statusCode = response.getStatusLine().getStatusCode();
                     if (statusCode != HttpStatus.SC_OK) {
                         Log.e(TAG, "Failed response (" + statusCode + "): " + responseLine);
+
+                        // 400 Bad Request is returned if the dump file is malformed. Delete file
+                        // to prevent re-attempting later.
+                        if (statusCode == HttpStatus.SC_BAD_REQUEST) {
+                            dumpFile.delete();
+                        }
                         return;
                     }
 
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastShellActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastShellActivity.java
index 46152e7..344d9c1 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastShellActivity.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastShellActivity.java
@@ -31,11 +31,12 @@
  */
 public class CastShellActivity extends Activity {
     private static final String TAG = "CastShellActivity";
+    private static final boolean DEBUG = false;
 
     private static final String ACTIVE_SHELL_URL_KEY = "activeUrl";
     private static final int DEFAULT_HEIGHT_PIXELS = 720;
     public static final String ACTION_EXTRA_RESOLUTION_HEIGHT =
-        "org.chromium.chromecast.shell.intent.extra.RESOLUTION_HEIGHT";
+            "org.chromium.chromecast.shell.intent.extra.RESOLUTION_HEIGHT";
 
     private CastWindowManager mCastWindowManager;
     private AudioManager mAudioManager;
@@ -57,6 +58,7 @@
 
     @Override
     protected void onCreate(final Bundle savedInstanceState) {
+        if (DEBUG) Log.d(TAG, "onCreate");
         super.onCreate(savedInstanceState);
         exitIfUrlMissing();
 
@@ -115,7 +117,7 @@
 
     @Override
     protected void onDestroy() {
-        super.onDestroy();
+        if (DEBUG) Log.d(TAG, "onDestroy");
 
         unregisterBroadcastReceiver();
 
@@ -123,10 +125,13 @@
             mCastWindowManager.stopCastWindow(mNativeCastWindow, false /* gracefully */);
             mNativeCastWindow = 0;
         }
+
+        super.onDestroy();
     }
 
     @Override
     protected void onNewIntent(Intent intent) {
+        if (DEBUG) Log.d(TAG, "onNewIntent");
         // Only handle direct intents (e.g. "fling") if this activity is also managing
         // the browser process.
         if (!shouldLaunchBrowser()) return;
@@ -141,7 +146,23 @@
     }
 
     @Override
+    protected void onStart() {
+        if (DEBUG) Log.d(TAG, "onStart");
+        super.onStart();
+    }
+
+    @Override
+    protected void onStop() {
+        if (DEBUG) Log.d(TAG, "onStop");
+        // As soon as the cast app is no longer in the foreground, we ought to immediately tear
+        // everything down.
+        finishGracefully();
+        super.onStop();
+    }
+
+    @Override
     protected void onResume() {
+        if (DEBUG) Log.d(TAG, "onResume");
         super.onResume();
 
         // Inform ContentView that this activity is being shown.
@@ -158,9 +179,7 @@
 
     @Override
     protected void onPause() {
-        // As soon as the cast app is no longer in the foreground, we ought to immediately tear
-        // everything down. Apps should not continue running and playing sound in the background.
-        super.onPause();
+        if (DEBUG) Log.d(TAG, "onPause");
 
         // Release the audio focus. Note that releasing audio focus does not stop audio playback,
         // it just notifies the framework that this activity has stopped playing audio.
@@ -171,7 +190,7 @@
         ContentViewCore view = getActiveContentViewCore();
         if (view != null) view.onHide();
 
-        finishGracefully();
+        super.onPause();
     }
 
     protected void finishGracefully() {
@@ -229,7 +248,7 @@
         }
         // Log an exception so that the exit cause is obvious when reading the logs.
         Log.e(TAG, "Activity will not start",
-            new IllegalArgumentException("Intent did not contain a valid url"));
+                new IllegalArgumentException("Intent did not contain a valid url"));
         System.exit(-1);
     }
 
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index 0b2b803..fd1c3efe 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -45,6 +45,7 @@
   { switches::kEnableOverlayFullscreenVideo, ""},
   { switches::kDisableInfobarForProtectedMediaIdentifier, ""},
   { switches::kDisableGestureRequirementForMediaPlayback, ""},
+  { switches::kForceUseOverlayEmbeddedVideo, ""},
 #endif
   { switches::kDisableApplicationCache, "" },
   { switches::kDisablePlugins, "" },
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 392072b..397603d 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -98,10 +98,14 @@
 
   std::string process_type =
       command_line->GetSwitchValueNative(switches::kProcessType);
-  // Renderer process comamndline
+
+  // Renderer process command-line
   if (process_type == switches::kRendererProcess) {
     // Any browser command-line switches that should be propagated to
     // the renderer go here.
+#if defined(OS_ANDROID)
+    command_line->AppendSwitch(switches::kForceUseOverlayEmbeddedVideo);
+#endif  // defined(OS_ANDROID)
   }
 }
 
diff --git a/chromecast/browser/cast_http_user_agent_settings.cc b/chromecast/browser/cast_http_user_agent_settings.cc
index 1cbf1c6..9eb27058 100644
--- a/chromecast/browser/cast_http_user_agent_settings.cc
+++ b/chromecast/browser/cast_http_user_agent_settings.cc
@@ -12,7 +12,7 @@
 #include "ui/base/l10n/l10n_util.h"
 
 #if defined(OS_ANDROID)
-#include "ui/base/l10n/l10n_util_android.h"
+#include "base/android/locale_utils.h"
 #endif  // defined(OS_ANDROID)
 
 namespace chromecast {
@@ -31,7 +31,7 @@
   if (accept_language_.empty()) {
     accept_language_ = net::HttpUtil::GenerateAcceptLanguageHeader(
 #if defined(OS_ANDROID)
-        l10n_util::GetDefaultLocale()
+        base::android::GetDefaultLocale()
 #else
         l10n_util::GetStringUTF8(IDS_CHROMECAST_SETTINGS_ACCEPT_LANGUAGES)
 #endif  // defined(OS_ANDROID)
diff --git a/chromecast/browser/devtools/remote_debugging_server.cc b/chromecast/browser/devtools/remote_debugging_server.cc
index 2084b07..96b3ecc 100644
--- a/chromecast/browser/devtools/remote_debugging_server.cc
+++ b/chromecast/browser/devtools/remote_debugging_server.cc
@@ -76,7 +76,7 @@
 CreateSocketFactory(int port) {
 #if defined(OS_ANDROID)
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  std::string socket_name = "content_shell_devtools_remote";
+  std::string socket_name = "cast_shell_devtools_remote";
   if (command_line->HasSwitch(switches::kRemoteDebuggingSocketName)) {
     socket_name = command_line->GetSwitchValueASCII(
         switches::kRemoteDebuggingSocketName);
diff --git a/chromecast/browser/metrics/cast_metrics_service_client.cc b/chromecast/browser/metrics/cast_metrics_service_client.cc
index db12520..b6a6590 100644
--- a/chromecast/browser/metrics/cast_metrics_service_client.cc
+++ b/chromecast/browser/metrics/cast_metrics_service_client.cc
@@ -160,7 +160,7 @@
           new ::metrics::GPUMetricsProvider));
   metrics_service_->RegisterMetricsProvider(
       scoped_ptr< ::metrics::MetricsProvider>(
-          new NetworkMetricsProvider(io_task_runner)));
+          new ::metrics::NetworkMetricsProvider(io_task_runner)));
   metrics_service_->RegisterMetricsProvider(
       scoped_ptr< ::metrics::MetricsProvider>(
           new ::metrics::ProfilerMetricsProvider));
diff --git a/chromecast/browser/test/chromecast_browser_test.cc b/chromecast/browser/test/chromecast_browser_test.cc
index 01647742..2895a98 100644
--- a/chromecast/browser/test/chromecast_browser_test.cc
+++ b/chromecast/browser/test/chromecast_browser_test.cc
@@ -9,6 +9,7 @@
 #include "base/message_loop/message_loop.h"
 #include "chromecast/browser/cast_browser_context.h"
 #include "chromecast/browser/cast_browser_process.h"
+#include "chromecast/browser/cast_content_window.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
@@ -51,6 +52,7 @@
   }
 
   web_contents_.reset();
+  window_.reset();
 }
 
 void ChromecastBrowserTest::NavigateToURL(content::WebContents* window,
@@ -66,12 +68,10 @@
 }
 
 content::WebContents* ChromecastBrowserTest::CreateBrowser() {
-  content::WebContents::CreateParams create_params(
-      CastBrowserProcess::GetInstance()->browser_context(),
-      NULL);
-  create_params.routing_id = MSG_ROUTING_NONE;
-  create_params.initial_size = gfx::Size(1280, 720);
-  web_contents_.reset(content::WebContents::Create(create_params));
+  window_.reset(new CastContentWindow);
+  gfx::Size initial_size(1280, 720);
+  web_contents_ = window_->Create(
+      initial_size, CastBrowserProcess::GetInstance()->browser_context());
   return web_contents_.get();
 }
 
diff --git a/chromecast/browser/test/chromecast_browser_test.h b/chromecast/browser/test/chromecast_browser_test.h
index 76d8246..5d55f706 100644
--- a/chromecast/browser/test/chromecast_browser_test.h
+++ b/chromecast/browser/test/chromecast_browser_test.h
@@ -15,6 +15,8 @@
 }
 
 namespace chromecast {
+class CastContentWindow;
+
 namespace shell {
 
 // This test allows for running an entire browser-process lifecycle per unit
@@ -44,6 +46,7 @@
 
  private:
   scoped_ptr<content::WebContents> web_contents_;
+  scoped_ptr<CastContentWindow> window_;
 
   bool setup_called_;
 
diff --git a/chromecast/renderer/DEPS b/chromecast/renderer/DEPS
index 8632b540..790b870 100644
--- a/chromecast/renderer/DEPS
+++ b/chromecast/renderer/DEPS
@@ -2,6 +2,7 @@
   "+chromecast/media",
   "+components/cdm/renderer",
   "+content/public/renderer",
+  "+media/base",
   "+third_party/WebKit/public/platform",
   "+third_party/WebKit/public/web",
 ]
diff --git a/chromecast/renderer/key_systems_cast.cc b/chromecast/renderer/key_systems_cast.cc
index be25c64..a07e6ba 100644
--- a/chromecast/renderer/key_systems_cast.cc
+++ b/chromecast/renderer/key_systems_cast.cc
@@ -10,7 +10,7 @@
 #include "base/logging.h"
 #include "chromecast/media/base/key_systems_common.h"
 #include "components/cdm/renderer/widevine_key_systems.h"
-#include "content/public/common/eme_constants.h"
+#include "media/base/eme_constants.h"
 
 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
 
@@ -19,17 +19,17 @@
 
 void AddKeySystemWithCodecs(
     const std::string& key_system_name,
-    std::vector<content::KeySystemInfo>* concrete_key_systems) {
-  content::KeySystemInfo info(key_system_name);
-  info.supported_codecs = content::EME_CODEC_MP4_ALL;
+    std::vector<media::KeySystemInfo>* concrete_key_systems) {
+  media::KeySystemInfo info(key_system_name);
+  info.supported_codecs = media::EME_CODEC_MP4_ALL;
   concrete_key_systems->push_back(info);
 }
 
 void AddChromecastKeySystems(
-    std::vector<content::KeySystemInfo>* key_systems_info) {
+    std::vector<media::KeySystemInfo>* key_systems_info) {
 #if defined(WIDEVINE_CDM_AVAILABLE)
   AddWidevineWithCodecs(cdm::WIDEVINE,
-                        content::EME_CODEC_MP4_ALL,
+                        media::EME_CODEC_MP4_ALL,
                         key_systems_info);
 #endif
 
diff --git a/chromecast/renderer/key_systems_cast.h b/chromecast/renderer/key_systems_cast.h
index 5853c68..544876b 100644
--- a/chromecast/renderer/key_systems_cast.h
+++ b/chromecast/renderer/key_systems_cast.h
@@ -7,7 +7,7 @@
 
 #include <vector>
 
-#include "content/public/renderer/key_system_info.h"
+#include "media/base/key_system_info.h"
 
 namespace chromecast {
 namespace shell {
@@ -15,14 +15,14 @@
 // Adds a single key system by name.
 void AddKeySystemWithCodecs(
     const std::string& key_system_name,
-    std::vector<content::KeySystemInfo>* concrete_key_systems);
+    std::vector<media::KeySystemInfo>* concrete_key_systems);
 
 void AddChromecastKeySystems(
-    std::vector<content::KeySystemInfo>* key_systems_info);
+    std::vector<media::KeySystemInfo>* key_systems_info);
 
 // TODO(gunsch): Remove when prefixed EME is removed.
 void AddChromecastPlatformKeySystems(
-    std::vector<content::KeySystemInfo>* key_systems_info);
+    std::vector<media::KeySystemInfo>* key_systems_info);
 
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index 4fa9cd7..4fef2ba 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -100,8 +100,8 @@
     "network/mock_managed_network_configuration_handler.h",
     "network/onc/onc_test_utils.cc",
     "network/onc/onc_test_utils.h",
-    "system/mock_statistics_provider.cc",
-    "system/mock_statistics_provider.h",
+    "system/fake_statistics_provider.cc",
+    "system/fake_statistics_provider.h",
   ]
 }
 
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index b557019..6400d1c 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -254,6 +254,8 @@
       'login/auth/extended_authenticator_impl.h',
       'login/auth/key.cc',
       'login/auth/key.h',
+      'login/auth/login_performer.cc',
+      'login/auth/login_performer.h',
       'login/auth/online_attempt.cc',
       'login/auth/online_attempt.h',
       'login/auth/online_attempt_host.cc',
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index f608db2..76649858 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -78,14 +78,29 @@
 // Enables the next generation version of ChromeVox.
 const char kEnableChromeVoxNext[] = "enable-chromevox-next";
 
+// Enables cloud backup feature.
+const char kEnableCloudBackup[] = "enable-cloud-backup";
+
 // Enables consumer management, which allows user to enroll, remotely lock and
 // locate the device.
 const char kEnableConsumerManagement[] = "enable-consumer-management";
 
+// If this switch is set, the device cannot be remotely disabled by its owner.
+const char kDisableDeviceDisabling[] = "disable-device-disabling";
+
 // If this switch is set, Chrome OS login screen uses |EmbeddedSignin| endpoint
 // of GAIA.
 const char kEnableEmbeddedSignin[] = "enable-embedded-signin";
 
+// If this switch is set, the new Korean IME will be available in
+// chrome://settings/languages.
+const char kEnableNewKoreanIme[] = "enable-new-korean-ime";
+
+// If this switch is set, the US keyboard input method will provide suggestions
+// as typing on physical keyboard.
+const char kEnablePhysicalKeyboardAutocorrect[] =
+    "enable-physical-keyboard-autocorrect";
+
 // Enabled sharing assets for installed default apps.
 const char kEnableExtensionAssetsSharing[]  = "enable-extension-assets-sharing";
 
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 137e62b..da10ab9 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -42,12 +42,16 @@
 CHROMEOS_EXPORT extern const char kDisableVolumeAdjustSound[];
 CHROMEOS_EXPORT extern const char kEnableCarrierSwitching[];
 CHROMEOS_EXPORT extern const char kEnableChromeVoxNext[];
+CHROMEOS_EXPORT extern const char kEnableCloudBackup[];
 CHROMEOS_EXPORT extern const char kEnableConsumerManagement[];
+CHROMEOS_EXPORT extern const char kDisableDeviceDisabling[];
 CHROMEOS_EXPORT extern const char kEnableEmbeddedSignin[];
 CHROMEOS_EXPORT extern const char kEnableExtensionAssetsSharing[];
 CHROMEOS_EXPORT extern const char kEnableFirstRunUITransitions[];
 CHROMEOS_EXPORT extern const char kEnableKioskMode[];
 CHROMEOS_EXPORT extern const char kEnableNetworkPortalNotification[];
+CHROMEOS_EXPORT extern const char kEnableNewKoreanIme[];
+CHROMEOS_EXPORT extern const char kEnablePhysicalKeyboardAutocorrect[];
 CHROMEOS_EXPORT extern const char kEnableRequestTabletSite[];
 CHROMEOS_EXPORT extern const char kEnableTouchpadThreeFingerClick[];
 CHROMEOS_EXPORT extern const char kEnableVideoPlayerChromecastSupport[];
diff --git a/chromeos/ime/OWNERS b/chromeos/ime/OWNERS
index 631c968..a8edb11 100644
--- a/chromeos/ime/OWNERS
+++ b/chromeos/ime/OWNERS
@@ -1,7 +1,8 @@
 # primary reviewer
-yukishiino@chromium.org
+shuchen@chromium.org
 
 # backup reviewers
+yukishiino@chromium.org
 komatsu@chromium.org
 nona@chromium.org
 satorux@chromium.org
diff --git a/chromeos/ime/component_extension_ime_manager.cc b/chromeos/ime/component_extension_ime_manager.cc
index a83c6c4..9a8cce1 100644
--- a/chromeos/ime/component_extension_ime_manager.cc
+++ b/chromeos/ime/component_extension_ime_manager.cc
@@ -4,8 +4,10 @@
 
 #include "chromeos/ime/component_extension_ime_manager.h"
 
+#include "base/command_line.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
+#include "chromeos/chromeos_switches.h"
 #include "chromeos/ime/extension_ime_util.h"
 
 namespace chromeos {
@@ -141,6 +143,8 @@
 
 input_method::InputMethodDescriptors
     ComponentExtensionIMEManager::GetAllIMEAsInputMethodDescriptor() {
+  bool enable_new_korean_ime = CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableNewKoreanIme);
   input_method::InputMethodDescriptors result;
   for (std::map<std::string, ComponentExtensionIME>::const_iterator it =
           component_extension_imes_.begin();
@@ -148,6 +152,9 @@
     const ComponentExtensionIME& ext = it->second;
     for (size_t j = 0; j < ext.engines.size(); ++j) {
       const ComponentExtensionEngine& ime = ext.engines[j];
+      // Filter out new Korean IME if the experimental flag is OFF.
+      if (!enable_new_korean_ime && ime.engine_id == "ko-t-i0-und")
+        continue;
       const std::string input_method_id =
           extension_ime_util::GetComponentInputMethodID(
               ext.id, ime.engine_id);
diff --git a/chromeos/login/auth/authenticator.cc b/chromeos/login/auth/authenticator.cc
index fb642fa0..bf8d626 100644
--- a/chromeos/login/auth/authenticator.cc
+++ b/chromeos/login/auth/authenticator.cc
@@ -9,7 +9,7 @@
 class AuthStatusConsumer;
 
 Authenticator::Authenticator(AuthStatusConsumer* consumer)
-    : consumer_(consumer), authentication_profile_(NULL) {
+    : consumer_(consumer), authentication_context_(NULL) {
 }
 
 Authenticator::~Authenticator() {
diff --git a/chromeos/login/auth/authenticator.h b/chromeos/login/auth/authenticator.h
index d3fd584..7ae29b0 100644
--- a/chromeos/login/auth/authenticator.h
+++ b/chromeos/login/auth/authenticator.h
@@ -13,7 +13,9 @@
 #include "chromeos/login/auth/auth_status_consumer.h"
 #include "google_apis/gaia/gaia_auth_consumer.h"
 
-class Profile;
+namespace content {
+class BrowserContext;
+}
 
 namespace chromeos {
 
@@ -31,13 +33,13 @@
 
   // Given externally authenticated username and password (part of
   // |user_context|), this method attempts to complete authentication process.
-  virtual void CompleteLogin(Profile* profile,
+  virtual void CompleteLogin(content::BrowserContext* browser_context,
                              const UserContext& user_context) = 0;
 
   // Given a user credentials in |user_context|,
   // this method attempts to authenticate to login.
   // Must be called on the UI thread.
-  virtual void AuthenticateToLogin(Profile* profile,
+  virtual void AuthenticateToLogin(content::BrowserContext* browser_context,
                                    const UserContext& user_context) = 0;
 
   // Given a user credentials in |user_context|, this method attempts to
@@ -86,9 +88,11 @@
   // and create a new cryptohome.
   virtual void ResyncEncryptedData() = 0;
 
-  // Profile (usually off the record ) that was used to perform the last
+  // BrowserContext (usually off the record) that was used to perform the last
   // authentication process.
-  Profile* authentication_profile() { return authentication_profile_; }
+  content::BrowserContext* authentication_context() {
+    return authentication_context_;
+  }
 
   // Sets consumer explicitly.
   void SetConsumer(AuthStatusConsumer* consumer);
@@ -97,7 +101,7 @@
   virtual ~Authenticator();
 
   AuthStatusConsumer* consumer_;
-  Profile* authentication_profile_;
+  content::BrowserContext* authentication_context_;
 
  private:
   friend class base::RefCountedThreadSafe<Authenticator>;
diff --git a/chromeos/login/auth/cryptohome_authenticator.cc b/chromeos/login/auth/cryptohome_authenticator.cc
index 0c3c162..970f6f1d 100644
--- a/chromeos/login/auth/cryptohome_authenticator.cc
+++ b/chromeos/login/auth/cryptohome_authenticator.cc
@@ -384,9 +384,9 @@
 }
 
 void CryptohomeAuthenticator::AuthenticateToLogin(
-    Profile* profile,
+    content::BrowserContext* context,
     const UserContext& user_context) {
-  authentication_profile_ = profile;
+  authentication_context_ = context;
   current_state_.reset(new AuthAttemptState(user_context,
                                             user_manager::USER_TYPE_REGULAR,
                                             false,  // unlock
@@ -401,9 +401,9 @@
              false /* create_if_nonexistent */);
 }
 
-void CryptohomeAuthenticator::CompleteLogin(Profile* profile,
+void CryptohomeAuthenticator::CompleteLogin(content::BrowserContext* context,
                                             const UserContext& user_context) {
-  authentication_profile_ = profile;
+  authentication_context_ = context;
   current_state_.reset(new AuthAttemptState(user_context,
                                             user_manager::USER_TYPE_REGULAR,
                                             true,   // unlock
diff --git a/chromeos/login/auth/cryptohome_authenticator.h b/chromeos/login/auth/cryptohome_authenticator.h
index 980dc0f..fac0d068 100644
--- a/chromeos/login/auth/cryptohome_authenticator.h
+++ b/chromeos/login/auth/cryptohome_authenticator.h
@@ -21,7 +21,10 @@
 #include "google_apis/gaia/gaia_auth_consumer.h"
 
 class AuthFailure;
-class Profile;
+
+namespace content {
+class BrowserContext;
+}
 
 namespace chromeos {
 
@@ -93,7 +96,7 @@
                           AuthStatusConsumer* consumer);
 
   // Authenticator overrides.
-  virtual void CompleteLogin(Profile* profile,
+  virtual void CompleteLogin(content::BrowserContext* context,
                              const UserContext& user_context) override;
 
   // Given |user_context|, this method attempts to authenticate to your
@@ -103,8 +106,8 @@
   // Upon failure to login consumer_->OnAuthFailure() is called
   // with an error message.
   //
-  // Uses |profile| when doing URL fetches.
-  virtual void AuthenticateToLogin(Profile* profile,
+  // Uses |context| when doing URL fetches.
+  virtual void AuthenticateToLogin(content::BrowserContext* context,
                                    const UserContext& user_context) override;
 
   // Given |user_context|, this method attempts to authenticate to the cached
diff --git a/chromeos/login/auth/login_performer.cc b/chromeos/login/auth/login_performer.cc
new file mode 100644
index 0000000..960a69e
--- /dev/null
+++ b/chromeos/login/auth/login_performer.cc
@@ -0,0 +1,313 @@
+// 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 "chromeos/login/auth/login_performer.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/threading/thread_restrictions.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/session_manager_client.h"
+#include "chromeos/login/user_names.h"
+#include "chromeos/login_event_recorder.h"
+#include "chromeos/settings/cros_settings_names.h"
+#include "google_apis/gaia/gaia_auth_util.h"
+#include "net/cookies/cookie_monster.h"
+#include "net/cookies/cookie_store.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+
+using base::UserMetricsAction;
+
+namespace chromeos {
+
+LoginPerformer::LoginPerformer(scoped_refptr<base::TaskRunner> task_runner,
+                               Delegate* delegate)
+    : delegate_(delegate),
+      task_runner_(task_runner),
+      online_attempt_host_(this),
+      last_login_failure_(AuthFailure::AuthFailureNone()),
+      password_changed_(false),
+      password_changed_callback_count_(0),
+      auth_mode_(AUTH_MODE_INTERNAL),
+      weak_factory_(this) {
+}
+
+LoginPerformer::~LoginPerformer() {
+  DVLOG(1) << "Deleting LoginPerformer";
+  if (authenticator_.get())
+    authenticator_->SetConsumer(NULL);
+  if (extended_authenticator_.get())
+    extended_authenticator_->SetConsumer(NULL);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// LoginPerformer, AuthStatusConsumer implementation:
+
+void LoginPerformer::OnAuthFailure(const AuthFailure& failure) {
+  DCHECK(task_runner_->RunsTasksOnCurrentThread());
+  base::RecordAction(UserMetricsAction("Login_Failure"));
+
+  UMA_HISTOGRAM_ENUMERATION("Login.FailureReason",
+                            failure.reason(),
+                            AuthFailure::NUM_FAILURE_REASONS);
+
+  DVLOG(1) << "failure.reason " << failure.reason();
+  DVLOG(1) << "failure.error.state " << failure.error().state();
+
+  last_login_failure_ = failure;
+  if (delegate_) {
+    delegate_->OnAuthFailure(failure);
+    return;
+  } else {
+    // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
+    // happens during offline auth only.
+    NOTREACHED();
+  }
+}
+
+void LoginPerformer::OnRetailModeAuthSuccess(const UserContext& user_context) {
+  DCHECK(task_runner_->RunsTasksOnCurrentThread());
+  base::RecordAction(UserMetricsAction("Login_DemoUserLoginSuccess"));
+  AuthStatusConsumer::OnRetailModeAuthSuccess(user_context);
+}
+
+void LoginPerformer::OnAuthSuccess(const UserContext& user_context) {
+  DCHECK(task_runner_->RunsTasksOnCurrentThread());
+  base::RecordAction(UserMetricsAction("Login_Success"));
+  VLOG(1) << "LoginSuccess hash: " << user_context.GetUserIDHash();
+  DCHECK(delegate_);
+  // After delegate_->OnAuthSuccess(...) is called, delegate_ releases
+  // LoginPerformer ownership. LP now manages it's lifetime on its own.
+  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
+  delegate_->OnAuthSuccess(user_context);
+}
+
+void LoginPerformer::OnOffTheRecordAuthSuccess() {
+  DCHECK(task_runner_->RunsTasksOnCurrentThread());
+  base::RecordAction(UserMetricsAction("Login_GuestLoginSuccess"));
+
+  if (delegate_)
+    delegate_->OnOffTheRecordAuthSuccess();
+  else
+    NOTREACHED();
+}
+
+void LoginPerformer::OnPasswordChangeDetected() {
+  password_changed_ = true;
+  password_changed_callback_count_++;
+  if (delegate_) {
+    delegate_->OnPasswordChangeDetected();
+  } else {
+    NOTREACHED();
+  }
+}
+
+void LoginPerformer::OnChecked(const std::string& user_id, bool success) {
+  if (!delegate_) {
+    // Delegate is reset in case of successful offline login.
+    // See ExistingUserConstoller::OnAuthSuccess().
+    // Case when user has changed password and enters old password
+    // does not block user from sign in yet.
+    return;
+  }
+  delegate_->OnOnlineChecked(user_id, success);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// LoginPerformer, public:
+
+void LoginPerformer::NotifyWhitelistCheckFailure() {
+  if (delegate_)
+    delegate_->WhiteListCheckFailed(user_context_.GetUserID());
+  else
+    NOTREACHED();
+}
+
+void LoginPerformer::PerformLogin(const UserContext& user_context,
+                                  AuthorizationMode auth_mode) {
+  auth_mode_ = auth_mode;
+  user_context_ = user_context;
+
+  if (RunTrustedCheck(base::Bind(&LoginPerformer::DoPerformLogin,
+                                 weak_factory_.GetWeakPtr(),
+                                 user_context_,
+                                 auth_mode))) {
+    return;
+  }
+  DoPerformLogin(user_context, auth_mode);
+}
+
+void LoginPerformer::DoPerformLogin(const UserContext& user_context,
+                                    AuthorizationMode auth_mode) {
+  std::string email = gaia::CanonicalizeEmail(user_context.GetUserID());
+  bool wildcard_match = false;
+  if (!IsUserWhitelisted(email, &wildcard_match)) {
+    NotifyWhitelistCheckFailure();
+    return;
+  }
+
+  if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_EASY_UNLOCK)
+    SetupEasyUnlockUserFlow(user_context.GetUserID());
+
+  switch (auth_mode_) {
+    case AUTH_MODE_EXTENSION: {
+      RunOnlineWhitelistCheck(
+          email,
+          wildcard_match,
+          base::Bind(&LoginPerformer::StartLoginCompletion,
+                     weak_factory_.GetWeakPtr()),
+          base::Bind(&LoginPerformer::NotifyWhitelistCheckFailure,
+                     weak_factory_.GetWeakPtr()));
+      break;
+    }
+    case AUTH_MODE_INTERNAL:
+      StartAuthentication();
+      break;
+  }
+}
+
+void LoginPerformer::LoginAsSupervisedUser(const UserContext& user_context) {
+  DCHECK_EQ(chromeos::login::kSupervisedUserDomain,
+            gaia::ExtractDomainName(user_context.GetUserID()));
+
+  if (RunTrustedCheck(base::Bind(&LoginPerformer::LoginAsSupervisedUser,
+                                 weak_factory_.GetWeakPtr(),
+                                 user_context_))) {
+    return;
+  }
+
+  if (!AreSupervisedUsersAllowed()) {
+    LOG(ERROR) << "Login attempt of supervised user detected.";
+    delegate_->WhiteListCheckFailed(user_context.GetUserID());
+    return;
+  }
+
+  SetupSupervisedUserFlow(user_context.GetUserID());
+  UserContext user_context_copy = TransformSupervisedKey(user_context);
+
+  if (UseExtendedAuthenticatorForSupervisedUser(user_context)) {
+    EnsureExtendedAuthenticator();
+    // TODO(antrim) : Replace empty callback with explicit method.
+    // http://crbug.com/351268
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&ExtendedAuthenticator::AuthenticateToMount,
+                   extended_authenticator_.get(),
+                   user_context_copy,
+                   ExtendedAuthenticator::ResultCallback()));
+
+  } else {
+    EnsureAuthenticator();
+    task_runner_->PostTask(FROM_HERE,
+                           base::Bind(&Authenticator::LoginAsSupervisedUser,
+                                      authenticator_.get(),
+                                      user_context_copy));
+  }
+}
+
+void LoginPerformer::LoginAsPublicSession(const UserContext& user_context) {
+  if (!CheckPolicyForUser(user_context.GetUserID())) {
+    DCHECK(delegate_);
+    if (delegate_)
+      delegate_->PolicyLoadFailed();
+    return;
+  }
+
+  EnsureAuthenticator();
+  task_runner_->PostTask(FROM_HERE,
+                         base::Bind(&Authenticator::LoginAsPublicSession,
+                                    authenticator_.get(),
+                                    user_context));
+}
+
+void LoginPerformer::LoginRetailMode() {
+  EnsureAuthenticator();
+  task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&Authenticator::LoginRetailMode, authenticator_.get()));
+}
+
+void LoginPerformer::LoginOffTheRecord() {
+  EnsureAuthenticator();
+  task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get()));
+}
+
+void LoginPerformer::LoginAsKioskAccount(const std::string& app_user_id,
+                                         bool use_guest_mount) {
+  EnsureAuthenticator();
+  task_runner_->PostTask(FROM_HERE,
+                         base::Bind(&Authenticator::LoginAsKioskAccount,
+                                    authenticator_.get(),
+                                    app_user_id,
+                                    use_guest_mount));
+}
+
+void LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
+  task_runner_->PostTask(FROM_HERE,
+                         base::Bind(&Authenticator::RecoverEncryptedData,
+                                    authenticator_.get(),
+                                    old_password));
+}
+
+void LoginPerformer::ResyncEncryptedData() {
+  task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get()));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// LoginPerformer, private:
+
+void LoginPerformer::EnsureExtendedAuthenticator() {
+  if (extended_authenticator_.get())
+    extended_authenticator_->SetConsumer(NULL);
+  extended_authenticator_ = ExtendedAuthenticator::Create(this);
+}
+
+void LoginPerformer::StartLoginCompletion() {
+  DVLOG(1) << "Login completion started";
+  chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("AuthStarted", false);
+  content::BrowserContext* browser_context = GetSigninContext();
+  EnsureAuthenticator();
+  task_runner_->PostTask(FROM_HERE,
+                         base::Bind(&chromeos::Authenticator::CompleteLogin,
+                                    authenticator_.get(),
+                                    browser_context,
+                                    user_context_));
+  user_context_.ClearSecrets();
+}
+
+void LoginPerformer::StartAuthentication() {
+  DVLOG(1) << "Auth started";
+  chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("AuthStarted", false);
+  if (delegate_) {
+    EnsureAuthenticator();
+    content::BrowserContext* browser_context = GetSigninContext();
+    task_runner_->PostTask(FROM_HERE,
+                           base::Bind(&Authenticator::AuthenticateToLogin,
+                                      authenticator_.get(),
+                                      base::Unretained(browser_context),
+                                      user_context_));
+    // Make unobtrusive online check. It helps to determine password change
+    // state in the case when offline login fails.
+    online_attempt_host_.Check(GetSigninRequestContext(), user_context_);
+  } else {
+    NOTREACHED();
+  }
+  user_context_.ClearSecrets();
+}
+
+void LoginPerformer::EnsureAuthenticator() {
+  authenticator_ = CreateAuthenticator();
+}
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/auth/login_performer.h b/chromeos/login/auth/login_performer.h
similarity index 60%
rename from chrome/browser/chromeos/login/auth/login_performer.h
rename to chromeos/login/auth/login_performer.h
index 00d6ace8..e924a73 100644
--- a/chrome/browser/chromeos/login/auth/login_performer.h
+++ b/chromeos/login/auth/login_performer.h
@@ -2,28 +2,35 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_
-#define CHROME_BROWSER_CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_
+#ifndef CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_
+#define CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_
 
 #include <string>
 
 #include "base/basictypes.h"
+#include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/chromeos/policy/wildcard_login_checker.h"
+#include "chromeos/chromeos_export.h"
 #include "chromeos/login/auth/auth_status_consumer.h"
 #include "chromeos/login/auth/authenticator.h"
 #include "chromeos/login/auth/extended_authenticator.h"
 #include "chromeos/login/auth/online_attempt_host.h"
 #include "chromeos/login/auth/user_context.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "google_apis/gaia/google_service_auth_error.h"
 
+namespace net {
+class URLRequestContextGetter;
+}
+
 namespace policy {
 class WildcardLoginChecker;
 }
 
+namespace content {
+class BrowserContext;
+}
+
 namespace chromeos {
 
 // This class encapsulates sign in operations.
@@ -34,8 +41,8 @@
 // If auth is succeeded, cookie fetcher is executed, LP instance deletes itself.
 //
 // If |delegate_| is not NULL it will handle error messages, password input.
-class LoginPerformer : public AuthStatusConsumer,
-                       public OnlineAttemptHost::Delegate {
+class CHROMEOS_EXPORT LoginPerformer : public AuthStatusConsumer,
+                                       public OnlineAttemptHost::Delegate {
  public:
   typedef enum AuthorizationMode {
     // Authorization performed internally by Chrome.
@@ -53,17 +60,10 @@
     virtual void OnOnlineChecked(const std::string& email, bool success) = 0;
   };
 
-  explicit LoginPerformer(Delegate* delegate);
+  LoginPerformer(scoped_refptr<base::TaskRunner> task_runner,
+                 Delegate* delegate);
   virtual ~LoginPerformer();
 
-  // AuthStatusConsumer implementation:
-  virtual void OnAuthFailure(const AuthFailure& error) override;
-  virtual void OnRetailModeAuthSuccess(
-      const UserContext& user_context) override;
-  virtual void OnAuthSuccess(const UserContext& user_context) override;
-  virtual void OnOffTheRecordAuthSuccess() override;
-  virtual void OnPasswordChangeDetected() override;
-
   // Performs a login for |user_context|.
   // If auth_mode is AUTH_MODE_EXTENSION, there are no further auth checks,
   // AUTH_MODE_INTERNAL will perform auth checks.
@@ -86,6 +86,14 @@
   void LoginAsKioskAccount(const std::string& app_user_id,
                            bool use_guest_mount);
 
+  // AuthStatusConsumer implementation:
+  virtual void OnAuthFailure(const AuthFailure& error) override;
+  virtual void OnRetailModeAuthSuccess(
+      const UserContext& user_context) override;
+  virtual void OnAuthSuccess(const UserContext& user_context) override;
+  virtual void OnOffTheRecordAuthSuccess() override;
+  virtual void OnPasswordChangeDetected() override;
+
   // Migrates cryptohome using |old_password| specified.
   void RecoverEncryptedData(const std::string& old_password);
 
@@ -115,7 +123,65 @@
 
  protected:
   // Implements OnlineAttemptHost::Delegate.
-  virtual void OnChecked(const std::string& username, bool success) override;
+  virtual void OnChecked(const std::string& user_id, bool success) override;
+
+  // Platform-dependant methods to be implemented by concrete class.
+
+  // Run trusted check for a platform. If trusted check have to be performed
+  // asynchronously, |false| will be returned, and either delegate's
+  // PolicyLoadFailed() or |callback| will be called upon actual check.
+  virtual bool RunTrustedCheck(const base::Closure& callback) = 0;
+
+  // Check if user is allowed to sign in on device. |wildcard_match| will
+  // contain additional information whether this user is explicitly listed or
+  // not (may be relevant for extension-based sign-in).
+  virtual bool IsUserWhitelisted(const std::string& user_id,
+                                 bool* wildcard_match) = 0;
+
+  // This method should run addional online check if user can sign in on device.
+  // Either |success_callback| or |failure_callback| should be called upon this
+  // check.
+  virtual void RunOnlineWhitelistCheck(
+      const std::string& user_id,
+      bool wildcard_match,
+      const base::Closure& success_callback,
+      const base::Closure& failure_callback) = 0;
+
+  // Supervised users-related methods.
+
+  // Check if supervised users are allowed on this device.
+  virtual bool AreSupervisedUsersAllowed() = 0;
+
+  // Check which authenticator should be used for supervised user.
+  virtual bool UseExtendedAuthenticatorForSupervisedUser(
+      const UserContext& user_context) = 0;
+
+  // Probably transform supervised user's authentication key.
+  virtual UserContext TransformSupervisedKey(const UserContext& context) = 0;
+
+  // Set up sign-in flow for supervised user.
+  virtual void SetupSupervisedUserFlow(const std::string& user_id) = 0;
+
+  // Set up sign-in flow for Easy Unlock.
+  virtual void SetupEasyUnlockUserFlow(const std::string& user_id) = 0;
+
+  // Run policy check for |user_id|. If something is wrong, delegate's
+  // PolicyLoadFailed is called.
+  virtual bool CheckPolicyForUser(const std::string& user_id) = 0;
+
+  // Look up browser context to use during signin.
+  virtual content::BrowserContext* GetSigninContext() = 0;
+
+  // Get RequestContext used for sign in.
+  virtual net::URLRequestContextGetter* GetSigninRequestContext() = 0;
+
+  // Create authenticator implementation.
+  virtual scoped_refptr<Authenticator> CreateAuthenticator() = 0;
+
+  void set_authenticator(scoped_refptr<Authenticator> authenticator);
+
+  // Notifications receiver.
+  Delegate* delegate_;
 
  private:
   // Starts login completion of externally authenticated user.
@@ -123,15 +189,23 @@
 
   // Starts authentication.
   void StartAuthentication();
+  void NotifyWhitelistCheckFailure();
 
-  // Completion callback for the online wildcard login check for enterprise
-  // devices. Continues the login process or signals whitelist check failure
-  // depending on the value of |result|.
-  void OnlineWildcardLoginCheckCompleted(
-      policy::WildcardLoginChecker::Result result);
+  // Makes sure that authenticator is created.
+  void EnsureAuthenticator();
+  void EnsureExtendedAuthenticator();
+
+  // Actual implementantion of PeformLogin that is run after trusted values
+  // check.
+  void DoPerformLogin(const UserContext& user_context,
+                      AuthorizationMode auth_mode);
+
+  scoped_refptr<base::TaskRunner> task_runner_;
 
   // Used for logging in.
   scoped_refptr<Authenticator> authenticator_;
+
+  // Used for logging in.
   scoped_refptr<ExtendedAuthenticator> extended_authenticator_;
 
   // Used to make auxiliary online check.
@@ -144,9 +218,6 @@
   // User credentials for the current login attempt.
   UserContext user_context_;
 
-  // Notifications receiver.
-  Delegate* delegate_;
-
   // True if password change has been detected.
   // Once correct password is entered homedir migration is executed.
   bool password_changed_;
@@ -155,14 +226,10 @@
   // Authorization mode type.
   AuthorizationMode auth_mode_;
 
-  // Used to verify logins that matched wildcard on the login whitelist.
-  scoped_ptr<policy::WildcardLoginChecker> wildcard_login_checker_;
-
   base::WeakPtrFactory<LoginPerformer> weak_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(LoginPerformer);
 };
 
 }  // namespace chromeos
 
-#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_
+#endif  // CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_
diff --git a/chromeos/login/auth/mock_authenticator.cc b/chromeos/login/auth/mock_authenticator.cc
index e457f9f6..0665156f 100644
--- a/chromeos/login/auth/mock_authenticator.cc
+++ b/chromeos/login/auth/mock_authenticator.cc
@@ -17,14 +17,14 @@
       message_loop_(base::MessageLoopProxy::current()) {
 }
 
-void MockAuthenticator::CompleteLogin(Profile* profile,
+void MockAuthenticator::CompleteLogin(content::BrowserContext* ignored,
                                       const UserContext& user_context) {
   if (expected_user_context_ != user_context)
     NOTREACHED();
   OnAuthSuccess();
 }
 
-void MockAuthenticator::AuthenticateToLogin(Profile* profile,
+void MockAuthenticator::AuthenticateToLogin(content::BrowserContext* ignored,
                                             const UserContext& user_context) {
   if (user_context == expected_user_context_) {
     message_loop_->PostTask(
diff --git a/chromeos/login/auth/mock_authenticator.h b/chromeos/login/auth/mock_authenticator.h
index d887e59..d4c5e867 100644
--- a/chromeos/login/auth/mock_authenticator.h
+++ b/chromeos/login/auth/mock_authenticator.h
@@ -13,7 +13,9 @@
 #include "chromeos/login/auth/user_context.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-class Profile;
+namespace content {
+class BrowserContext;
+}
 
 namespace chromeos {
 
@@ -25,9 +27,9 @@
                     const UserContext& expected_user_context);
 
   // Authenticator:
-  virtual void CompleteLogin(Profile* profile,
+  virtual void CompleteLogin(content::BrowserContext* context,
                              const UserContext& user_context) override;
-  virtual void AuthenticateToLogin(Profile* profile,
+  virtual void AuthenticateToLogin(content::BrowserContext* context,
                                    const UserContext& user_context) override;
   virtual void AuthenticateToUnlock(const UserContext& user_context) override;
   virtual void LoginAsSupervisedUser(const UserContext& user_context) override;
diff --git a/chromeos/login/auth/user_context.cc b/chromeos/login/auth/user_context.cc
index 31113f1..edeb24e 100644
--- a/chromeos/login/auth/user_context.cc
+++ b/chromeos/login/auth/user_context.cc
@@ -15,6 +15,7 @@
 
 UserContext::UserContext(const UserContext& other)
     : user_id_(other.user_id_),
+      gaia_id_(other.gaia_id_),
       key_(other.key_),
       auth_code_(other.auth_code_),
       user_id_hash_(other.user_id_hash_),
@@ -48,6 +49,7 @@
 
 bool UserContext::operator==(const UserContext& context) const {
   return context.user_id_ == user_id_ &&
+         context.gaia_id_ == gaia_id_ &&
          context.key_ == key_ &&
          context.auth_code_ == auth_code_ &&
          context.user_id_hash_ == user_id_hash_ &&
@@ -66,6 +68,10 @@
   return user_id_;
 }
 
+const std::string& UserContext::GetGaiaID() const {
+  return gaia_id_;
+}
+
 const Key* UserContext::GetKey() const {
   return &key_;
 }
@@ -111,6 +117,10 @@
   user_id_ = login::CanonicalizeUserID(user_id);
 }
 
+void UserContext::SetGaiaID(const std::string& gaia_id) {
+  gaia_id_ = gaia_id;
+}
+
 void UserContext::SetKey(const Key& key) {
   key_ = key;
 }
diff --git a/chromeos/login/auth/user_context.h b/chromeos/login/auth/user_context.h
index ff28c96..879e59a 100644
--- a/chromeos/login/auth/user_context.h
+++ b/chromeos/login/auth/user_context.h
@@ -41,6 +41,7 @@
   bool operator!=(const UserContext& context) const;
 
   const std::string& GetUserID() const;
+  const std::string& GetGaiaID() const;
   const Key* GetKey() const;
   Key* GetKey();
   const std::string& GetAuthCode() const;
@@ -54,6 +55,7 @@
   bool HasCredentials() const;
 
   void SetUserID(const std::string& user_id);
+  void SetGaiaID(const std::string& gaia_id);
   void SetKey(const Key& key);
   void SetAuthCode(const std::string& auth_code);
   void SetUserIDHash(const std::string& user_id_hash);
@@ -67,6 +69,7 @@
 
  private:
   std::string user_id_;
+  std::string gaia_id_;
   Key key_;
   std::string auth_code_;
   std::string user_id_hash_;
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc
index a416061d..97a0cb0 100644
--- a/chromeos/network/client_cert_resolver.cc
+++ b/chromeos/network/client_cert_resolver.cc
@@ -16,7 +16,6 @@
 #include "base/stl_util.h"
 #include "base/task_runner.h"
 #include "base/threading/worker_pool.h"
-#include "base/time/time.h"
 #include "chromeos/cert_loader.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill_service_client.h"
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
index f637ae3f..68eca96 100644
--- a/chromeos/network/client_cert_resolver_unittest.cc
+++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -21,11 +21,9 @@
 #include "chromeos/network/network_configuration_handler.h"
 #include "chromeos/network/network_profile_handler.h"
 #include "chromeos/network/network_state_handler.h"
-#include "chromeos/tpm_token_loader.h"
 #include "components/onc/onc_constants.h"
 #include "crypto/nss_util_internal.h"
 #include "crypto/scoped_test_nss_chromeos_user.h"
-#include "net/base/crypto_module.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_data_directory.h"
 #include "net/cert/nss_cert_database_chromeos.h"
@@ -34,9 +32,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
-// http://crbug.com/418369
-#ifdef NDEBUG
-
 namespace chromeos {
 
 namespace {
@@ -77,12 +72,11 @@
         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
     profile_test_ =
         DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
+    profile_test_->AddProfile(kUserProfilePath, kUserHash);
     base::RunLoop().RunUntilIdle();
     service_test_->ClearServices();
     base::RunLoop().RunUntilIdle();
 
-    TPMTokenLoader::InitializeForTest();
-
     CertLoader::Initialize();
     cert_loader_ = CertLoader::Get();
     cert_loader_->force_hardware_backed_for_test();
@@ -95,9 +89,7 @@
     network_profile_handler_.reset();
     network_state_handler_.reset();
     CertLoader::Shutdown();
-    TPMTokenLoader::Shutdown();
     DBusThreadManager::Shutdown();
-    CleanupSlotContents();
   }
 
  protected:
@@ -118,7 +110,7 @@
     // Import a CA cert.
     net::CertificateList ca_cert_list =
         net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
-                                           "websocket_cacert.pem",
+                                           "client_1_ca.pem",
                                            net::X509Certificate::FORMAT_AUTO);
     ASSERT_TRUE(!ca_cert_list.empty());
     net::NSSCertDatabase::ImportCertFailureList failures;
@@ -131,22 +123,12 @@
     ASSERT_TRUE(!test_ca_cert_pem_.empty());
 
     // Import a client cert signed by that CA.
-    std::string pkcs12_data;
-    ASSERT_TRUE(base::ReadFileToString(
-        net::GetTestCertsDirectory().Append("websocket_client_cert.p12"),
-        &pkcs12_data));
-
-    net::CertificateList client_cert_list;
-    scoped_refptr<net::CryptoModule> module(
-        net::CryptoModule::CreateFromHandle(private_slot_.get()));
-    ASSERT_EQ(net::OK,
-              test_nssdb_->ImportFromPKCS12(module.get(),
-                                            pkcs12_data,
-                                            base::string16(),
-                                            false,
-                                            &client_cert_list));
-    ASSERT_TRUE(!client_cert_list.empty());
-    test_client_cert_ = client_cert_list[0];
+    test_client_cert_ =
+        net::ImportClientCertAndKeyFromFile(net::GetTestCertsDirectory(),
+                                            "client_1.pem",
+                                            "client_1.pk8",
+                                            private_slot_.get());
+    ASSERT_TRUE(test_client_cert_.get());
   }
 
   void SetupNetworkHandlers() {
@@ -162,12 +144,14 @@
                                   network_profile_handler_.get(),
                                   network_config_handler_.get(),
                                   NULL /* network_device_handler */);
+    // Run all notifications before starting the cert loader to reduce run time.
+    base::RunLoop().RunUntilIdle();
+
     client_cert_resolver_->Init(network_state_handler_.get(),
                                 managed_config_handler_.get());
     client_cert_resolver_->SetSlowTaskRunnerForTest(
         message_loop_.message_loop_proxy());
 
-    profile_test_->AddProfile(kUserProfilePath, kUserHash);
   }
 
   void SetupWifi() {
@@ -245,19 +229,6 @@
   base::MessageLoop message_loop_;
 
  private:
-  void CleanupSlotContents() {
-    CERTCertList* cert_list = PK11_ListCertsInSlot(private_slot_.get());
-    for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
-         !CERT_LIST_END(node, cert_list);
-         node = CERT_LIST_NEXT(node)) {
-      scoped_refptr<net::X509Certificate> cert(
-          net::X509Certificate::CreateFromHandle(
-              node->cert, net::X509Certificate::OSCertHandles()));
-      test_nssdb_->DeleteCertAndKey(cert.get());
-    }
-    CERT_DestroyCertList(cert_list);
-  }
-
   CertLoader* cert_loader_;
   scoped_refptr<net::X509Certificate> test_client_cert_;
   scoped_ptr<NetworkStateHandler> network_state_handler_;
@@ -273,9 +244,10 @@
 };
 
 TEST_F(ClientCertResolverTest, NoMatchingCertificates) {
-  SetupNetworkHandlers();
-  SetupWifi();
   StartCertLoader();
+  SetupWifi();
+  base::RunLoop().RunUntilIdle();
+  SetupNetworkHandlers();
   SetupPolicy();
   base::RunLoop().RunUntilIdle();
 
@@ -286,9 +258,11 @@
 }
 
 TEST_F(ClientCertResolverTest, ResolveOnCertificatesLoaded) {
-  SetupNetworkHandlers();
-  SetupWifi();
   SetupTestCerts();
+  SetupWifi();
+  base::RunLoop().RunUntilIdle();
+
+  SetupNetworkHandlers();
   SetupPolicy();
   base::RunLoop().RunUntilIdle();
 
@@ -304,9 +278,10 @@
 
 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) {
   SetupTestCerts();
+  SetupWifi();
+  base::RunLoop().RunUntilIdle();
   StartCertLoader();
   SetupNetworkHandlers();
-  SetupWifi();
   base::RunLoop().RunUntilIdle();
 
   // Policy application will trigger the ClientCertResolver.
@@ -321,5 +296,3 @@
 }
 
 }  // namespace chromeos
-
-#endif
diff --git a/chromeos/network/network_profile_handler.cc b/chromeos/network/network_profile_handler.cc
index c8353cc..002421a 100644
--- a/chromeos/network/network_profile_handler.cc
+++ b/chromeos/network/network_profile_handler.cc
@@ -111,17 +111,18 @@
     }
   }
 
-  for (std::vector<std::string>::const_iterator it =
-           removed_profile_paths.begin();
-       it != removed_profile_paths.end(); ++it) {
-    RemoveProfile(*it);
+  for (const std::string& profile_path : removed_profile_paths) {
+    RemoveProfile(profile_path);
+    // Also stop pending creations of this profile.
+    pending_profile_creations_.erase(profile_path);
   }
 
   for (std::vector<std::string>::const_iterator it = new_profile_paths.begin();
        it != new_profile_paths.end(); ++it) {
     // Skip known profiles. The associated userhash should never change.
-    if (GetProfileForPath(*it))
+    if (GetProfileForPath(*it) || pending_profile_creations_.count(*it) > 0)
       continue;
+    pending_profile_creations_.insert(*it);
 
     VLOG(2) << "Requesting properties of profile path " << *it << ".";
     DBusThreadManager::Get()->GetShillProfileClient()->GetProperties(
@@ -136,6 +137,14 @@
 void NetworkProfileHandler::GetProfilePropertiesCallback(
     const std::string& profile_path,
     const base::DictionaryValue& properties) {
+  if (pending_profile_creations_.erase(profile_path) == 0) {
+    VLOG(1) << "Ignore received properties, profile was removed.";
+    return;
+  }
+  if (GetProfileForPath(profile_path)) {
+    VLOG(1) << "Ignore received properties, profile is already created.";
+    return;
+  }
   std::string userhash;
   properties.GetStringWithoutPathExpansion(shill::kUserHashProperty, &userhash);
 
diff --git a/chromeos/network/network_profile_handler.h b/chromeos/network/network_profile_handler.h
index e71186c8..f3970ad 100644
--- a/chromeos/network/network_profile_handler.h
+++ b/chromeos/network/network_profile_handler.h
@@ -5,6 +5,7 @@
 #ifndef CHROMEOS_NETWORK_NETWORK_PROFILE_HANDLER_H_
 #define CHROMEOS_NETWORK_NETWORK_PROFILE_HANDLER_H_
 
+#include <set>
 #include <string>
 #include <vector>
 
@@ -73,6 +74,11 @@
 
  private:
   ProfileList profiles_;
+
+  // Contains the profile paths for which properties were requested. Once the
+  // properties are retrieved and the path is still in this set, a new profile
+  // object is created.
+  std::set<std::string> pending_profile_creations_;
   ObserverList<NetworkProfileObserver> observers_;
 
   // For Shill client callbacks
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 36b19c5..ad14d98 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -51,6 +51,7 @@
     "//components/keyed_service/content",
     "//components/language_usage_metrics",
     "//components/leveldb_proto",
+    "//components/login",
     "//components/metrics",
     "//components/navigation_interception",
     "//components/navigation_metrics",
@@ -81,7 +82,7 @@
     "//components/search",
     "//components/search_engines",
     "//components/search_provider_logos",
-    "//components/sessions",
+    "//components/sessions:sessions_content",
     "//components/signin/core/browser",
     "//components/startup_metric_utils",
     "//components/strings",
@@ -172,7 +173,7 @@
       "//components/renderer_context_menu",  # Blocked on content.
       "//components/search_engines",  # Should work, needs checking.
       "//components/search_provider_logos",  # Should work, needs checking.
-      "//components/sessions",  # Blocked on content.
+      "//components/sessions:sessions_content",  # Blocked on content.
       "//components/signin/core/browser",  # Should work, needs checking.
       "//components/translate/content/browser",  # Blocked on content.
       "//components/translate/content/common",  # Blocked on content.
@@ -226,9 +227,12 @@
     "//components/data_reduction_proxy/core/common:unit_tests",
     "//components/dom_distiller/core:unit_tests",
     "//components/domain_reliability:unit_tests",
+    "//components/login:unit_tests",
+    "//components/metrics:unit_tests",
     "//components/omnibox:unit_tests",
     "//components/ownership:unit_tests",
     "//components/proximity_auth:unit_tests",
+    "//components/variations:unit_tests",
   ]
 
   # TODO(GYP) need this target.
diff --git a/components/OWNERS b/components/OWNERS
index a507c2bd..5f683e77a 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -3,6 +3,8 @@
 erikwright@chromium.org
 jochen@chromium.org
 
+per-file app_modal_dialog*=avi@chromium.org
+
 # Can not match autofill* due to crbug.com/397984
 per-file autofill.gypi=estade@chromium.org
 per-file autofill.gypi=isherman@chromium.org
@@ -90,6 +92,10 @@
 per-file json_schema.gypi=kalman@chromium.org
 per-file json_schema.gypi=mpcomplete@chromium.org
 
+per-file keyed_service.gypi=erg@chromium.org
+per-file keyed_service.gypi=phajdan.jr@chromium.org
+per-file keyed_service.gypi=rlp@chromium.org
+
 per-file leveldb_proto*=cjhopman@chromium.org
 per-file leveldb_proto*=mathp@chromium.org
 
diff --git a/components/app_modal_dialogs.gypi b/components/app_modal_dialogs.gypi
new file mode 100644
index 0000000..df3c3ec7
--- /dev/null
+++ b/components/app_modal_dialogs.gypi
@@ -0,0 +1,36 @@
+# 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.
+{
+  'targets': [
+    {
+      'target_name': 'app_modal_dialogs',
+      'type': 'static_library',
+      'dependencies': [
+	'../skia/skia.gyp:skia',
+	'../content/content.gyp:content_browser',
+        'components_strings.gyp:components_strings',
+      ],
+      'include_dirs': [
+        '..',
+      ],
+      'sources': [
+        'app_modal_dialogs/app_modal_dialog.cc',
+        'app_modal_dialogs/app_modal_dialog.h',
+        'app_modal_dialogs/app_modal_dialog_test_util.h',
+        'app_modal_dialogs/app_modal_dialog_queue.cc',
+        'app_modal_dialogs/app_modal_dialog_queue.h',
+        'app_modal_dialogs/javascript_app_modal_dialog.cc',
+        'app_modal_dialogs/javascript_app_modal_dialog.h',
+        'app_modal_dialogs/native_app_modal_dialog.h'
+      ],
+      'conditions': [
+        ['use_aura==1',{
+          'dependencies': [
+            '../ui/aura/aura.gyp:aura',
+          ],
+        }]
+      ],
+    },
+  ],
+}
diff --git a/components/app_modal_dialogs/BUILD.gn b/components/app_modal_dialogs/BUILD.gn
new file mode 100644
index 0000000..34d10af3
--- /dev/null
+++ b/components/app_modal_dialogs/BUILD.gn
@@ -0,0 +1,28 @@
+# 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.
+
+import("//build/config/ui.gni")
+
+static_library("app_modal_dialogs") {
+  sources = [
+    "app_modal_dialog.cc",
+    "app_modal_dialog.h",
+    "app_modal_dialog_test_util.h",
+    "app_modal_dialog_queue.cc",
+    "app_modal_dialog_queue.h",
+    "javascript_app_modal_dialog.cc",
+    "javascript_app_modal_dialog.h",
+    "native_app_modal_dialog.h"
+  ]
+
+  deps = [
+    "//components/strings",
+    "//content/public/browser",
+    "//skia",
+  ]
+
+  if (use_aura) {
+    deps += [ "//ui/aura" ]
+  }
+}
diff --git a/components/app_modal_dialogs/DEPS b/components/app_modal_dialogs/DEPS
new file mode 100644
index 0000000..9faf2b46
--- /dev/null
+++ b/components/app_modal_dialogs/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+  "+content/public/browser",
+  "+grit/components_strings.h",
+  "+net/base",
+  "+ui/aura",
+  "+ui/gfx",
+]
diff --git a/components/app_modal_dialogs/OWNERS b/components/app_modal_dialogs/OWNERS
new file mode 100644
index 0000000..704db9f
--- /dev/null
+++ b/components/app_modal_dialogs/OWNERS
@@ -0,0 +1 @@
+avi@chromium.org
diff --git a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc b/components/app_modal_dialogs/app_modal_dialog.cc
similarity index 69%
rename from chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc
rename to components/app_modal_dialogs/app_modal_dialog.cc
index edd94572..7156520 100644
--- a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc
+++ b/components/app_modal_dialogs/app_modal_dialog.cc
@@ -2,18 +2,33 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
 
 #include "base/logging.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
-#include "content/public/browser/notification_service.h"
+#include "base/run_loop.h"
+#include "components/app_modal_dialogs/app_modal_dialog_queue.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_delegate.h"
 
 using content::WebContents;
 
+namespace {
+
+AppModalDialogObserver* app_modal_dialog_observer = NULL;
+
+}  // namespace
+
+AppModalDialogObserver::AppModalDialogObserver() {
+  DCHECK(!app_modal_dialog_observer);
+  app_modal_dialog_observer = this;
+}
+
+AppModalDialogObserver::~AppModalDialogObserver() {
+  DCHECK(app_modal_dialog_observer);
+  app_modal_dialog_observer = NULL;
+}
+
 AppModalDialog::AppModalDialog(WebContents* web_contents,
                                const base::string16& title)
     : title_(title),
@@ -30,11 +45,8 @@
 void AppModalDialog::ShowModalDialog() {
   web_contents_->GetDelegate()->ActivateContents(web_contents_);
   CreateAndShowDialog();
-
-  content::NotificationService::current()->Notify(
-      chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
-      content::Source<AppModalDialog>(this),
-      content::NotificationService::NoDetails());
+  if (app_modal_dialog_observer)
+    app_modal_dialog_observer->Notify(this);
 }
 
 void AppModalDialog::CreateAndShowDialog() {
diff --git a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h b/components/app_modal_dialogs/app_modal_dialog.h
similarity index 85%
rename from chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h
rename to components/app_modal_dialogs/app_modal_dialog.h
index 28cf584..12d7f5c 100644
--- a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h
+++ b/components/app_modal_dialogs/app_modal_dialog.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_H_
-#define CHROME_BROWSER_UI_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_H_
+#ifndef COMPONENTS_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_H_
+#define COMPONENTS_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_H_
 
 #include <string>
 
@@ -89,4 +89,17 @@
   DISALLOW_COPY_AND_ASSIGN(AppModalDialog);
 };
 
-#endif  // CHROME_BROWSER_UI_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_H_
+// An interface to observe that a modal dialog is shown.
+class AppModalDialogObserver {
+ public:
+  AppModalDialogObserver();
+  virtual ~AppModalDialogObserver();
+
+  // Called when the modal dialog is shown.
+  virtual void Notify(AppModalDialog* dialog) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AppModalDialogObserver);
+};
+
+#endif  // COMPONENTS_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_H_
diff --git a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc b/components/app_modal_dialogs/app_modal_dialog_queue.cc
similarity index 93%
rename from chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc
rename to components/app_modal_dialogs/app_modal_dialog_queue.cc
index 99af7ad..effacb9 100644
--- a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.cc
+++ b/components/app_modal_dialogs/app_modal_dialog_queue.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
+#include "components/app_modal_dialogs/app_modal_dialog_queue.h"
 
 #include "base/memory/singleton.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
 
 // static
 AppModalDialogQueue* AppModalDialogQueue::GetInstance() {
diff --git a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h b/components/app_modal_dialogs/app_modal_dialog_queue.h
similarity index 93%
rename from chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h
rename to components/app_modal_dialogs/app_modal_dialog_queue.h
index 5f4eb9a..aca8a23a 100644
--- a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h
+++ b/components/app_modal_dialogs/app_modal_dialog_queue.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_QUEUE_H_
-#define CHROME_BROWSER_UI_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_QUEUE_H_
+#ifndef COMPONENTS_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_QUEUE_H_
+#define COMPONENTS_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_QUEUE_H_
 
 #include <deque>
 
@@ -86,4 +86,4 @@
   DISALLOW_COPY_AND_ASSIGN(AppModalDialogQueue);
 };
 
-#endif  // CHROME_BROWSER_UI_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_QUEUE_H_
+#endif  // COMPONENTS_APP_MODAL_DIALOGS_APP_MODAL_DIALOG_QUEUE_H_
diff --git a/chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.cc b/components/app_modal_dialogs/javascript_app_modal_dialog.cc
similarity index 96%
rename from chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.cc
rename to components/app_modal_dialogs/javascript_app_modal_dialog.cc
index a0373764..99adc4b 100644
--- a/chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.cc
+++ b/components/app_modal_dialogs/javascript_app_modal_dialog.cc
@@ -2,10 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
+#include "components/app_modal_dialogs/javascript_app_modal_dialog.h"
 
-#include "chrome/browser/browser_shutdown.h"
-#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
+#include "components/app_modal_dialogs/native_app_modal_dialog.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/gfx/text_elider.h"
 
diff --git a/chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h b/components/app_modal_dialogs/javascript_app_modal_dialog.h
similarity index 92%
rename from chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h
rename to components/app_modal_dialogs/javascript_app_modal_dialog.h
index 87dd203..6fb07772 100644
--- a/chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h
+++ b/components/app_modal_dialogs/javascript_app_modal_dialog.h
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_APP_MODAL_DIALOGS_JAVASCRIPT_APP_MODAL_DIALOG_H_
-#define CHROME_BROWSER_UI_APP_MODAL_DIALOGS_JAVASCRIPT_APP_MODAL_DIALOG_H_
+#ifndef COMPONENTS_APP_MODAL_DIALOGS_JAVASCRIPT_APP_MODAL_DIALOG_H_
+#define COMPONENTS_APP_MODAL_DIALOGS_JAVASCRIPT_APP_MODAL_DIALOG_H_
 
 #include <map>
 
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/time/time.h"
-#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
+#include "components/app_modal_dialogs/app_modal_dialog.h"
 #include "content/public/browser/javascript_dialog_manager.h"
 
 // Extra data for JavaScript dialogs to add Chrome-only features.
@@ -98,4 +98,4 @@
   DISALLOW_COPY_AND_ASSIGN(JavaScriptAppModalDialog);
 };
 
-#endif  // CHROME_BROWSER_UI_APP_MODAL_DIALOGS_JAVASCRIPT_APP_MODAL_DIALOG_H_
+#endif  // COMPONENTS_APP_MODAL_DIALOGS_JAVASCRIPT_APP_MODAL_DIALOG_H_
diff --git a/chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h b/components/app_modal_dialogs/native_app_modal_dialog.h
similarity index 81%
rename from chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h
rename to components/app_modal_dialogs/native_app_modal_dialog.h
index 6fe82f8d..88db763 100644
--- a/chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h
+++ b/components/app_modal_dialogs/native_app_modal_dialog.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_APP_MODAL_DIALOGS_NATIVE_APP_MODAL_DIALOG_H_
-#define CHROME_BROWSER_UI_APP_MODAL_DIALOGS_NATIVE_APP_MODAL_DIALOG_H_
+#ifndef COMPONENTS_APP_MODAL_DIALOGS_NATIVE_APP_MODAL_DIALOG_H_
+#define COMPONENTS_APP_MODAL_DIALOGS_NATIVE_APP_MODAL_DIALOG_H_
 
 #include "ui/gfx/native_widget_types.h"
 
@@ -34,5 +34,4 @@
       gfx::NativeWindow parent_window);
 };
 
-#endif  // CHROME_BROWSER_UI_APP_MODAL_DIALOGS_NATIVE_APP_MODAL_DIALOG_H_
-
+#endif  // COMPONENTS_APP_MODAL_DIALOGS_NATIVE_APP_MODAL_DIALOG_H_
diff --git a/components/app_modal_dialogs_strings.grdp b/components/app_modal_dialogs_strings.grdp
new file mode 100644
index 0000000..f1e413c
--- /dev/null
+++ b/components/app_modal_dialogs_strings.grdp
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+
+  <!-- JavaScript Dialog Box strings -->
+  <message name="IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE" desc="Title for JavaScript alert originating from a webpage if there is no hostname to display">
+     JavaScript Alert
+   </message>
+  <message name="IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE" desc="Title for JavaScript prompt and confirm originating from a webpage if there is no hostname to display">
+    JavaScript
+  </message>
+  <message name="IDS_JAVASCRIPT_ALERT_TITLE" desc="Title for JavaScript alert originating from a webpage">
+    The page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says:
+  </message>
+  <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE" desc="Title for JavaScript prompt and confirm originating from a webpage">
+    The page at <ph name="SITE">$1<ex>http://www.google.com</ex></ph> says:
+  </message>
+  <message name="IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION" desc="Optional UI shown on the message box, in the form of a checkbox, allowing the user to suppress additional message boxes from the page.">
+    Prevent this page from creating additional dialogs.
+  </message>
+
+  <!-- "Before Unload" Dialog Box strings -->
+  <message name="IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE" desc="Title for the 'before unload' dialog.">
+    Confirm Navigation
+  </message>
+  <message name="IDS_BEFOREUNLOAD_MESSAGEBOX_FOOTER" desc="Text shown at the bottom of the dialog, after the message provided by the script.">
+    Are you sure you want to leave this page?
+  </message>
+  <message name="IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL" desc="The text on the button which navigates the user away from the page.">
+    Leave this Page
+  </message>
+  <message name="IDS_BEFOREUNLOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL" desc="The text on the button which cancels the navigation away from the page.">
+    Stay on this Page
+  </message>
+
+  <!-- "Before Reload" Dialog Box strings (same as "Before Unload" but when reloading rather than unloading the page -->
+  <message name="IDS_BEFORERELOAD_MESSAGEBOX_TITLE" desc="Title for the 'before reload' dialog.">
+    Confirm Reload
+  </message>
+  <message name="IDS_BEFORERELOAD_MESSAGEBOX_FOOTER" desc="Text shown at the bottom of the dialog, after the message provided by the script.">
+    Are you sure you want to reload this page?
+  </message>
+  <message name="IDS_BEFORERELOAD_MESSAGEBOX_OK_BUTTON_LABEL" desc="The text on the button which reloads the page.">
+    Reload this Page
+  </message>
+  <message name="IDS_BEFORERELOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL" desc="The text on the button which cancels the page reload.">
+    Don't Reload
+  </message>
+
+</grit-part>
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index e67f875..0a9b57f 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -632,9 +632,15 @@
   // warning.  Otherwise, we want to ignore fields that disable autocomplete, so
   // that the suggestions list does not include suggestions for these form
   // fields -- see comment 1 on http://crbug.com/69914
-  const RequirementsMask requirements =
+  RequirementsMask requirements =
       element.autoComplete() ? REQUIRE_AUTOCOMPLETE : REQUIRE_NONE;
 
+  // If we're ignoring autocomplete="off", always extract everything.
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kIgnoreAutocompleteOffForAutofill)) {
+    requirements = REQUIRE_NONE;
+  }
+
   FormData form;
   FormFieldData field;
   if (!FindFormAndFieldForFormControlElement(element, &form, &field,
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index c6175c9f..dde53799 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -56,15 +56,22 @@
 
 // A bit field mask for FillForm functions to not fill some fields.
 enum FieldFilterMask {
-  FILTER_NONE                       = 0,
-  FILTER_DISABLED_ELEMENTS          = 1 << 0,
-  FILTER_READONLY_ELEMENTS          = 1 << 1,
-  FILTER_NON_FOCUSABLE_ELEMENTS     = 1 << 2,
-  FILTER_ALL_NON_EDITIABLE_ELEMENTS = FILTER_DISABLED_ELEMENTS |
-                                      FILTER_READONLY_ELEMENTS |
-                                      FILTER_NON_FOCUSABLE_ELEMENTS,
+  FILTER_NONE                      = 0,
+  FILTER_DISABLED_ELEMENTS         = 1 << 0,
+  FILTER_READONLY_ELEMENTS         = 1 << 1,
+  FILTER_NON_FOCUSABLE_ELEMENTS    = 1 << 2,
+  FILTER_ALL_NON_EDITABLE_ELEMENTS = FILTER_DISABLED_ELEMENTS |
+                                     FILTER_READONLY_ELEMENTS |
+                                     FILTER_NON_FOCUSABLE_ELEMENTS,
 };
 
+RequirementsMask ExtractionRequirements() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+             switches::kIgnoreAutocompleteOffForAutofill)
+             ? REQUIRE_NONE
+             : REQUIRE_AUTOCOMPLETE;
+}
+
 bool IsOptionElement(const WebElement& element) {
   CR_DEFINE_STATIC_LOCAL(WebString, kOption, ("option"));
   return element.hasHTMLTagName(kOption);
@@ -480,8 +487,8 @@
                               bool force_override,
                               Callback callback) {
   std::vector<WebFormControlElement> control_elements;
-  ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE,
-                              &control_elements);
+  ExtractAutofillableElements(
+      form_element, ExtractionRequirements(), &control_elements);
 
   if (control_elements.size() != data.fields.size()) {
     // This case should be reachable only for pathological websites and tests,
@@ -1001,7 +1008,7 @@
   ForEachMatchingFormField(form_element,
                            element,
                            form,
-                           FILTER_ALL_NON_EDITIABLE_ELEMENTS,
+                           FILTER_ALL_NON_EDITABLE_ELEMENTS,
                            false, /* dont force override */
                            &FillFormField);
 }
@@ -1042,7 +1049,7 @@
   ForEachMatchingFormField(form_element,
                            element,
                            form,
-                           FILTER_ALL_NON_EDITIABLE_ELEMENTS,
+                           FILTER_ALL_NON_EDITABLE_ELEMENTS,
                            false, /* dont force override */
                            &PreviewFormField);
 }
@@ -1054,8 +1061,8 @@
     return false;
 
   std::vector<WebFormControlElement> control_elements;
-  ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE,
-                              &control_elements);
+  ExtractAutofillableElements(
+      form_element, ExtractionRequirements(), &control_elements);
   for (size_t i = 0; i < control_elements.size(); ++i) {
     // There might be unrelated elements in this form which have already been
     // auto-filled.  For example, the user might have already filled the address
@@ -1114,8 +1121,8 @@
     return false;
 
   std::vector<WebFormControlElement> control_elements;
-  ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE,
-                              &control_elements);
+  ExtractAutofillableElements(
+      form_element, ExtractionRequirements(), &control_elements);
   for (size_t i = 0; i < control_elements.size(); ++i) {
     WebInputElement* input_element = toWebInputElement(&control_elements[i]);
     if (!IsAutofillableInputElement(input_element))
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 17ef3d7..c5986925 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -196,22 +196,37 @@
 }
 
 // Returns true if the password specified in |form| is a default value.
-bool PasswordValueIsDefault(const PasswordForm& form,
+bool PasswordValueIsDefault(const base::string16& password_element,
+                            const base::string16& password_value,
                             blink::WebFormElement form_element) {
   blink::WebVector<blink::WebNode> temp_elements;
-  form_element.getNamedElements(form.password_element, temp_elements);
+  form_element.getNamedElements(password_element, temp_elements);
 
   // We are loose in our definition here and will return true if any of the
   // appropriately named elements match the element to be saved. Currently
   // we ignore filling passwords where naming is ambigious anyway.
   for (size_t i = 0; i < temp_elements.size(); ++i) {
     if (temp_elements[i].to<blink::WebElement>().getAttribute("value") ==
-        form.password_value)
+        password_value)
       return true;
   }
   return false;
 }
 
+// Return true if either password_value or new_password_value is not empty and
+// not default.
+bool FormContainsNonDefaultPasswordValue(const PasswordForm& password_form,
+                                         blink::WebFormElement form_element) {
+  return (!password_form.password_value.empty() &&
+          !PasswordValueIsDefault(password_form.password_element,
+                                  password_form.password_value,
+                                  form_element)) ||
+      (!password_form.new_password_value.empty() &&
+       !PasswordValueIsDefault(password_form.new_password_element,
+                               password_form.new_password_value,
+                               form_element));
+}
+
 // Log a message including the name, method and action of |form|.
 void LogHTMLForm(SavePasswordProgressLogger* logger,
                  SavePasswordProgressLogger::StringID message_id,
@@ -972,8 +987,8 @@
           scoped_ptr<PasswordForm> password_form(
               CreatePasswordForm(form_element));
           if (password_form.get() && !password_form->username_value.empty() &&
-              !password_form->password_value.empty() &&
-              !PasswordValueIsDefault(*password_form, form_element)) {
+              FormContainsNonDefaultPasswordValue(
+                  *password_form, form_element)) {
             password_forms_found = true;
             if (logger) {
               logger->LogPasswordForm(
diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc
index af8f16e..48acba0 100644
--- a/components/autofill/content/renderer/password_generation_agent.cc
+++ b/components/autofill/content/renderer/password_generation_agent.cc
@@ -92,6 +92,15 @@
   return false;
 }
 
+void CopyValueToAllInputElements(
+    const blink::WebString value,
+    std::vector<blink::WebInputElement>* elements) {
+  for (std::vector<blink::WebInputElement>::iterator it = elements->begin();
+       it != elements->end(); ++it) {
+    it->setValue(value);
+  }
+}
+
 }  // namespace
 
 PasswordGenerationAgent::PasswordGenerationAgent(
@@ -341,6 +350,7 @@
       // User generated a password and then deleted it.
       password_generation::LogPasswordGenerationEvent(
           password_generation::PASSWORD_DELETED);
+      CopyValueToAllInputElements(element.value(), &password_elements_);
     }
 
     // Do not treat the password as generated.
@@ -353,11 +363,7 @@
   } else if (password_is_generated_) {
     password_edited_ = true;
     // Mirror edits to any confirmation password fields.
-    for (std::vector<blink::WebInputElement>::iterator it =
-             password_elements_.begin();
-         it != password_elements_.end(); ++it) {
-      it->setValue(element.value());
-    }
+    CopyValueToAllInputElements(element.value(), &password_elements_);
   } else if (element.value().length() > kMaximumOfferSize) {
     // User has rejected the feature and has started typing a password.
     HidePopup();
diff --git a/components/autofill/core/browser/autocomplete_history_manager.cc b/components/autofill/core/browser/autocomplete_history_manager.cc
index d96249b4..5b8bbb4 100644
--- a/components/autofill/core/browser/autocomplete_history_manager.cc
+++ b/components/autofill/core/browser/autocomplete_history_manager.cc
@@ -87,7 +87,7 @@
     int query_id,
     const base::string16& name,
     const base::string16& prefix,
-    const std::string form_control_type,
+    const std::string& form_control_type,
     const std::vector<base::string16>& autofill_values,
     const std::vector<base::string16>& autofill_labels,
     const std::vector<base::string16>& autofill_icons,
diff --git a/components/autofill/core/browser/autocomplete_history_manager.h b/components/autofill/core/browser/autocomplete_history_manager.h
index 254676b..fb57474 100644
--- a/components/autofill/core/browser/autocomplete_history_manager.h
+++ b/components/autofill/core/browser/autocomplete_history_manager.h
@@ -26,19 +26,19 @@
  public:
   AutocompleteHistoryManager(AutofillDriver* driver,
                              AutofillClient* autofill_client);
-  ~AutocompleteHistoryManager() override;
+  virtual ~AutocompleteHistoryManager() override;
 
   // WebDataServiceConsumer implementation.
-  void OnWebDataServiceRequestDone(WebDataServiceBase::Handle h,
-                                   const WDTypedResult* result) override;
+  virtual void OnWebDataServiceRequestDone(
+      WebDataServiceBase::Handle h, const WDTypedResult* result) override;
 
   // Pass-through functions that are called by AutofillManager, after it has
   // dispatched a message.
-  void OnGetAutocompleteSuggestions(
+  virtual void OnGetAutocompleteSuggestions(
       int query_id,
       const base::string16& name,
       const base::string16& prefix,
-      const std::string form_control_type,
+      const std::string& form_control_type,
       const std::vector<base::string16>& autofill_values,
       const std::vector<base::string16>& autofill_labels,
       const std::vector<base::string16>& autofill_icons,
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index ff14515..7cc91394 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/autofill_external_delegate.h"
 
+#include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/sparse_histogram.h"
@@ -12,6 +13,7 @@
 #include "components/autofill/core/browser/autofill_driver.h"
 #include "components/autofill/core/browser/autofill_manager.h"
 #include "components/autofill/core/browser/popup_item_ids.h"
+#include "components/autofill/core/common/autofill_switches.h"
 #include "grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -42,6 +44,16 @@
 
 namespace autofill {
 
+namespace {
+
+bool ShouldAutofill(const FormFieldData& form_field) {
+  return form_field.should_autocomplete ||
+         base::CommandLine::ForCurrentProcess()->HasSwitch(
+             switches::kIgnoreAutocompleteOffForAutofill);
+}
+
+}  // namespace
+
 AutofillExternalDelegate::AutofillExternalDelegate(AutofillManager* manager,
                                                    AutofillDriver* driver)
     : manager_(manager),
@@ -307,7 +319,7 @@
     std::vector<base::string16>* labels,
     std::vector<base::string16>* icons,
     std::vector<int>* unique_ids) {
-  if (!query_field_.should_autocomplete) {
+  if (!ShouldAutofill(query_field_)) {
     // Autofill is disabled.  If there were some profile or credit card
     // suggestions to show, show a warning instead.  Otherwise, clear out the
     // list of suggestions.
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index 82e32b94c2..8d94045 100644
--- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -4,6 +4,7 @@
 
 #include <vector>
 
+#include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string16.h"
@@ -13,6 +14,7 @@
 #include "components/autofill/core/browser/test_autofill_client.h"
 #include "components/autofill/core/browser/test_autofill_driver.h"
 #include "components/autofill/core/browser/test_autofill_external_delegate.h"
+#include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "components/autofill/core/common/password_form_fill_data.h"
@@ -448,6 +450,34 @@
                                             autofill_ids);
 }
 
+TEST_F(AutofillExternalDelegateUnitTest, IgnoreAutocompleteOffForAutofill) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kIgnoreAutocompleteOffForAutofill);
+
+  const FormData form;
+  FormFieldData field;
+  field.is_focusable = true;
+  field.should_autocomplete = false;
+  const gfx::RectF element_bounds;
+
+  external_delegate_->OnQuery(kQueryId, form, field, element_bounds, false);
+
+  std::vector<base::string16> autofill_items;
+  autofill_items.push_back(base::string16());
+  std::vector<int> autofill_ids;
+  autofill_ids.push_back(POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY);
+
+  // Ensure the popup tries to show itself, despite autocomplete="off".
+  EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, _, _, _, _, _));
+  EXPECT_CALL(autofill_client_, HideAutofillPopup()).Times(0);
+
+  external_delegate_->OnSuggestionsReturned(kQueryId,
+                                            autofill_items,
+                                            autofill_items,
+                                            autofill_items,
+                                            autofill_ids);
+}
+
 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateFillFieldWithValue) {
   EXPECT_CALL(autofill_client_, HideAutofillPopup());
   base::string16 dummy_string(ASCIIToUTF16("baz foo"));
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 48cd597..d685ff79 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -493,8 +493,9 @@
       // provide credit card suggestions for non-HTTPS pages. However, provide a
       // warning to the user in these cases.
       int warning = 0;
-      if (is_filling_credit_card && !FormIsHTTPS(*form_structure))
+      if (is_filling_credit_card && !FormIsHTTPS(*form_structure)) {
         warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION;
+      }
       if (warning) {
         values.assign(1, l10n_util::GetStringUTF16(warning));
         labels.assign(1, base::string16());
@@ -530,12 +531,20 @@
     }
   }
 
-  // Add the results from AutoComplete.  They come back asynchronously, so we
-  // hand off what we generated and they will send the results back to the
-  // renderer.
-  autocomplete_history_manager_->OnGetAutocompleteSuggestions(
-      query_id, field.name, field.value, field.form_control_type, values,
-      labels, icons, unique_ids);
+  if (field.should_autocomplete) {
+    // Add the results from AutoComplete.  They come back asynchronously, so we
+    // hand off what we generated and they will send the results back to the
+    // renderer.
+    autocomplete_history_manager_->OnGetAutocompleteSuggestions(
+        query_id, field.name, field.value, field.form_control_type, values,
+        labels, icons, unique_ids);
+  } else {
+    // Autocomplete is disabled for this field; only pass back Autofill
+    // suggestions.
+    autocomplete_history_manager_->CancelPendingQuery();
+    external_delegate_->OnSuggestionsReturned(
+        query_id, values, labels, icons, unique_ids);
+  }
 }
 
 void AutofillManager::FillOrPreviewForm(
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index cdbb625..58058c7b 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -372,6 +372,10 @@
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, UserHappinessFormInteraction);
   FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
                            FormSubmittedAutocompleteEnabled);
+  FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
+                           AutocompleteOffRespected);
+  FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
+                           AutocompleteOffRespectedWithFlag);
   DISALLOW_COPY_AND_ASSIGN(AutofillManager);
 };
 
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index b027511..c556bf9 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -32,6 +32,7 @@
 #include "components/autofill/core/browser/test_autofill_external_delegate.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
+#include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "grit/components_strings.h"
@@ -358,6 +359,15 @@
   MockAutocompleteHistoryManager(AutofillDriver* driver, AutofillClient* client)
       : AutocompleteHistoryManager(driver, client) {}
 
+  MOCK_METHOD8(OnGetAutocompleteSuggestions, void(
+      int query_id,
+      const base::string16& name,
+      const base::string16& prefix,
+      const std::string& form_control_type,
+      const std::vector<base::string16>& autofill_values,
+      const std::vector<base::string16>& autofill_labels,
+      const std::vector<base::string16>& autofill_icons,
+      const std::vector<int>& autofill_unique_ids));
   MOCK_METHOD1(OnFormSubmitted, void(const FormData& form));
 
  private:
@@ -2392,6 +2402,66 @@
       expected_labels, expected_icons, expected_unique_ids);
 }
 
+TEST_F(AutofillManagerTest, AutocompleteOffRespected) {
+  TestAutofillClient client;
+  autofill_manager_.reset(
+      new TestAutofillManager(autofill_driver_.get(), &client, NULL));
+  autofill_manager_->set_autofill_enabled(false);
+  autofill_manager_->SetExternalDelegate(external_delegate_.get());
+
+  scoped_ptr<MockAutocompleteHistoryManager> autocomplete_history_manager;
+  autocomplete_history_manager.reset(
+      new MockAutocompleteHistoryManager(autofill_driver_.get(), &client));
+  autofill_manager_->autocomplete_history_manager_ =
+      autocomplete_history_manager.Pass();
+  MockAutocompleteHistoryManager* m = static_cast<
+      MockAutocompleteHistoryManager*>(
+          autofill_manager_->autocomplete_history_manager_.get());
+  EXPECT_CALL(*m,
+      OnGetAutocompleteSuggestions(_, _, _, _, _, _, _, _)).Times(0);
+
+  // Set up our form data.
+  FormData form;
+  test::CreateTestAddressFormData(&form);
+  std::vector<FormData> forms(1, form);
+  FormsSeen(forms);
+  FormFieldData* field = &form.fields[0];
+  field->should_autocomplete = false;
+  GetAutofillSuggestions(form, *field);
+}
+
+// Duplicate of the above test with the ignore-autocomplete-off-autofill switch.
+TEST_F(AutofillManagerTest, AutocompleteOffRespectedWithFlag) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kIgnoreAutocompleteOffForAutofill);
+
+  TestAutofillClient client;
+  autofill_manager_.reset(
+      new TestAutofillManager(autofill_driver_.get(), &client, NULL));
+  autofill_manager_->set_autofill_enabled(false);
+  autofill_manager_->SetExternalDelegate(external_delegate_.get());
+
+  scoped_ptr<MockAutocompleteHistoryManager> autocomplete_history_manager;
+  autocomplete_history_manager.reset(
+      new MockAutocompleteHistoryManager(autofill_driver_.get(), &client));
+  autofill_manager_->autocomplete_history_manager_ =
+      autocomplete_history_manager.Pass();
+  MockAutocompleteHistoryManager* m = static_cast<
+      MockAutocompleteHistoryManager*>(
+          autofill_manager_->autocomplete_history_manager_.get());
+  EXPECT_CALL(*m,
+      OnGetAutocompleteSuggestions(_, _, _, _, _, _, _, _)).Times(0);
+
+  // Set up our form data.
+  FormData form;
+  test::CreateTestAddressFormData(&form);
+  std::vector<FormData> forms(1, form);
+  FormsSeen(forms);
+  FormFieldData* field = &form.fields[0];
+  field->should_autocomplete = false;
+  GetAutofillSuggestions(form, *field);
+}
+
 // Test that we are able to save form data when forms are submitted and we only
 // have server data for the field types.
 TEST_F(AutofillManagerTest, FormSubmittedServerTypes) {
diff --git a/components/autofill/core/browser/credit_card_field.cc b/components/autofill/core/browser/credit_card_field.cc
index e13162ba..85b122f 100644
--- a/components/autofill/core/browser/credit_card_field.cc
+++ b/components/autofill/core/browser/credit_card_field.cc
@@ -29,7 +29,6 @@
 
   scoped_ptr<CreditCardField> credit_card_field(new CreditCardField);
   size_t saved_cursor = scanner->SaveCursor();
-  bool form_has_valid_card_number_fields = true;
 
   // Credit card fields can appear in many different orders.
   // We loop until no more credit card related fields are found, see |break| at
@@ -105,18 +104,13 @@
             credit_card_field->numbers_.back()->credit_card_number_offset() +
             credit_card_field->numbers_.back()->max_length;
 
-        // In some cases, HTML form may have credit card number split across
-        // multiple input fields and either one or cumulatively having
-        // |max_length| more than |kMaxValidCardNumberSize|, mark these input
-        // form fields as invalid and skip autofilling them.
-        if (last_number_field_size == 0U ||
-            last_number_field_size >= kMaxValidCardNumberSize) {
-          // Mark that the credit card number splits are invalid. But keep
-          // scanning HTML form so that cursor moves beyond related fields.
-          form_has_valid_card_number_fields = false;
-        }
-
-        start_index = last_number_field_size;
+        // Distinguish between
+        //   (a) one card split across multiple fields
+        //   (b) multiple fields for multiple cards
+        // Treat this field as a part of the same card as the last field, except
+        // when doing so would cause overflow.
+        if (last_number_field_size < kMaxValidCardNumberSize)
+          start_index = last_number_field_size;
       }
 
       current_number_field->set_credit_card_number_offset(start_index);
@@ -190,11 +184,6 @@
     break;
   }
 
-  // Cases where heuristic misinterprets input field as credit card number
-  // field, refuse to autofill credit card number fields.
-  if (!form_has_valid_card_number_fields)
-    credit_card_field->numbers_.clear();
-
   // Some pages have a billing address field after the cardholder name field.
   // For that case, allow only just the cardholder name field.  The remaining
   // CC fields will be picked up in a following CreditCardField.
@@ -209,8 +198,7 @@
   // the number and name were parsed in a separate part of the form.  So if
   // the cvc and date were found independently they are returned.
   if ((!credit_card_field->numbers_.empty() ||
-       credit_card_field->verification_ ||
-       !form_has_valid_card_number_fields) &&
+       credit_card_field->verification_) &&
       (credit_card_field->expiration_date_ ||
        (credit_card_field->expiration_month_ &&
         credit_card_field->expiration_year_))) {
diff --git a/components/autofill/core/browser/credit_card_field_unittest.cc b/components/autofill/core/browser/credit_card_field_unittest.cc
index fbf2f97..68719f2a 100644
--- a/components/autofill/core/browser/credit_card_field_unittest.cc
+++ b/components/autofill/core/browser/credit_card_field_unittest.cc
@@ -448,7 +448,7 @@
             field_type_map_[ASCIIToUTF16("year6")]);
 }
 
-TEST_F(CreditCardFieldTest, ParseCreditCardNumberWithInvalidSplit) {
+TEST_F(CreditCardFieldTest, ParseMultipleCreditCardNumbers) {
   FormFieldData field;
   field.form_control_type = "text";
 
@@ -460,8 +460,8 @@
   field.name = ASCIIToUTF16("card_number");
   list_.push_back(new AutofillField(field, ASCIIToUTF16("number2")));
 
-  field.label = ASCIIToUTF16("Not Card Number");
-  field.name = ASCIIToUTF16("not_card_number");
+  field.label = ASCIIToUTF16("Confirm Card Number");
+  field.name = ASCIIToUTF16("confirm_card_number");
   list_.push_back(new AutofillField(field, ASCIIToUTF16("number3")));
 
   field.label = ASCIIToUTF16("Exp Month");
@@ -479,10 +479,12 @@
   ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("name1")) !=
               field_type_map_.end());
   EXPECT_EQ(CREDIT_CARD_NAME, field_type_map_[ASCIIToUTF16("name1")]);
-  ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number2")) ==
+  ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number2")) !=
               field_type_map_.end());
-  ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number3")) ==
+  EXPECT_EQ(CREDIT_CARD_NUMBER, field_type_map_[ASCIIToUTF16("number2")]);
+  ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("number3")) !=
               field_type_map_.end());
+  EXPECT_EQ(CREDIT_CARD_NUMBER, field_type_map_[ASCIIToUTF16("number3")]);
   ASSERT_TRUE(field_type_map_.find(ASCIIToUTF16("month4")) !=
               field_type_map_.end());
   EXPECT_EQ(CREDIT_CARD_EXP_MONTH, field_type_map_[ASCIIToUTF16("month4")]);
diff --git a/components/autofill/core/common/autofill_switches.cc b/components/autofill/core/common/autofill_switches.cc
index ca73109d..36d0e3a 100644
--- a/components/autofill/core/common/autofill_switches.cc
+++ b/components/autofill/core/common/autofill_switches.cc
@@ -19,6 +19,10 @@
 // account creation.
 const char kEnablePasswordGeneration[]      = "enable-password-generation";
 
+// Ignores autocomplete="off" for Autofill data (profiles + credit cards).
+const char kIgnoreAutocompleteOffForAutofill[] =
+    "ignore-autocomplete-off-autofill";
+
 // Removes the requirement that we recieved a ping from the autofill servers
 // and that the user doesn't have the given form blacklisted. Used in testing.
 const char kLocalHeuristicsOnlyForPasswordGeneration[] =
diff --git a/components/autofill/core/common/autofill_switches.h b/components/autofill/core/common/autofill_switches.h
index 9cab817..f94a2df 100644
--- a/components/autofill/core/common/autofill_switches.h
+++ b/components/autofill/core/common/autofill_switches.h
@@ -13,6 +13,7 @@
 extern const char kDisableIgnoreAutocompleteOff[];
 extern const char kDisablePasswordGeneration[];
 extern const char kEnablePasswordGeneration[];
+extern const char kIgnoreAutocompleteOffForAutofill[];
 extern const char kLocalHeuristicsOnlyForPasswordGeneration[];
 extern const char kShowAutofillTypePredictions[];
 extern const char kWalletSecureServiceUrl[];
diff --git a/components/bookmarks.gypi b/components/bookmarks.gypi
index 6f6b770b..b9a72687 100644
--- a/components/bookmarks.gypi
+++ b/components/bookmarks.gypi
@@ -153,14 +153,10 @@
           # GN: //components/bookmarks/common/android:bookmarks_type_javagen
           'target_name': 'bookmark_type_java',
           'type': 'none',
-          'sources': [
-            'bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkType.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/components/bookmarks',
-            'template_deps': ['bookmarks/common/android/bookmark_type_list.h'],
+            'source_file': 'bookmarks/common/android/bookmark_type.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
       ],
     }]
diff --git a/components/bookmarks/browser/bookmark_node_data.cc b/components/bookmarks/browser/bookmark_node_data.cc
index 0753234..2d6e064 100644
--- a/components/bookmarks/browser/bookmark_node_data.cc
+++ b/components/bookmarks/browser/bookmark_node_data.cc
@@ -177,6 +177,22 @@
     // on Linux (on Windows and Mac, there is no difference between these
     // functions).
     scw.WriteText(base::UTF8ToUTF16(url));
+  } else {
+    // We have either more than one URL, a folder, or a combination of URLs
+    // and folders.
+    base::string16 text;
+    for (size_t i = 0; i < elements.size(); i++) {
+      text += i == 0 ? base::ASCIIToUTF16("") : base::ASCIIToUTF16("\n");
+      if (!elements[i].is_url) {
+        // Then it's a folder. Only copy the name of the folder.
+        const base::string16 title = elements[i].title;
+        text += title;
+      } else {
+        const base::string16 url = base::UTF8ToUTF16(elements[i].url.spec());
+        text += url;
+      }
+    }
+    scw.WriteText(text);
   }
 
   Pickle pickle;
diff --git a/components/bookmarks/browser/bookmark_node_data_unittest.cc b/components/bookmarks/browser/bookmark_node_data_unittest.cc
index d652595..0ff4493 100644
--- a/components/bookmarks/browser/bookmark_node_data_unittest.cc
+++ b/components/bookmarks/browser/bookmark_node_data_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/basictypes.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/bookmarks/browser/bookmark_model.h"
@@ -12,6 +13,7 @@
 #include "components/bookmarks/test/bookmark_test_helpers.h"
 #include "components/bookmarks/test/test_bookmark_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/clipboard/clipboard.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
 #include "ui/events/platform/platform_event_source.h"
 #include "url/gurl.h"
@@ -37,17 +39,22 @@
     event_source_.reset();
     bool success = profile_dir_.Delete();
     ASSERT_TRUE(success);
+    ui::Clipboard::DestroyClipboardForCurrentThread();
   }
 
   const base::FilePath& GetProfilePath() const { return profile_dir_.path(); }
 
   BookmarkModel* model() { return model_.get(); }
 
+ protected:
+  ui::Clipboard& clipboard() { return *ui::Clipboard::GetForCurrentThread(); }
+
  private:
   base::ScopedTempDir profile_dir_;
   TestBookmarkClient client_;
   scoped_ptr<BookmarkModel> model_;
   scoped_ptr<ui::PlatformEventSource> event_source_;
+  base::MessageLoopForUI loop_;
 
   DISALLOW_COPY_AND_ASSIGN(BookmarkNodeDataTest);
 };
@@ -269,6 +276,91 @@
   EXPECT_TRUE(read_data.GetFirstNode(model(), GetProfilePath()) == NULL);
 }
 
+TEST_F(BookmarkNodeDataTest, WriteToClipboardMultipleURLs) {
+  BookmarkNodeData data;
+  const BookmarkNode* root = model()->bookmark_bar_node();
+  GURL url(GURL("http://foo.com"));
+  const base::string16 title(ASCIIToUTF16("blah"));
+  GURL url2(GURL("http://bar.com"));
+  const base::string16 title2(ASCIIToUTF16("blah2"));
+  const BookmarkNode* url_node = model()->AddURL(root, 0, title, url);
+  const BookmarkNode* url_node2 = model()->AddURL(root, 1, title2, url2);
+  std::vector<const BookmarkNode*> nodes;
+  nodes.push_back(url_node);
+  nodes.push_back(url_node2);
+
+  data.ReadFromVector(nodes);
+  data.WriteToClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE);
+
+  // Now read the data back in.
+  base::string16 combined_text;
+  base::string16 new_line = base::ASCIIToUTF16("\n");
+  combined_text = base::UTF8ToUTF16(url.spec()) + new_line
+    + base::UTF8ToUTF16(url2.spec());
+  base::string16 clipboard_result;
+  clipboard().ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_result);
+  EXPECT_EQ(combined_text, clipboard_result);
+}
+
+TEST_F(BookmarkNodeDataTest, WriteToClipboardEmptyFolder) {
+  BookmarkNodeData data;
+  const BookmarkNode* root = model()->bookmark_bar_node();
+  const BookmarkNode* folder = model()->AddFolder(root, 0, ASCIIToUTF16("g1"));
+  std::vector<const BookmarkNode*> nodes;
+  nodes.push_back(folder);
+
+  data.ReadFromVector(nodes);
+  data.WriteToClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE);
+
+  // Now read the data back in.
+  base::string16 clipboard_result;
+  clipboard().ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_result);
+  EXPECT_EQ(base::ASCIIToUTF16("g1"), clipboard_result);
+}
+
+TEST_F(BookmarkNodeDataTest, WriteToClipboardFolderWithChildren) {
+  BookmarkNodeData data;
+  const BookmarkNode* root = model()->bookmark_bar_node();
+  const BookmarkNode* folder = model()->AddFolder(root, 0, ASCIIToUTF16("g1"));
+  GURL url(GURL("http://foo.com"));
+  const base::string16 title(ASCIIToUTF16("blah"));
+  model()->AddURL(folder, 0, title, url);
+  std::vector<const BookmarkNode*> nodes;
+  nodes.push_back(folder);
+
+  data.ReadFromVector(nodes);
+  data.WriteToClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE);
+
+  // Now read the data back in.
+  base::string16 clipboard_result;
+  clipboard().ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_result);
+  EXPECT_EQ(base::ASCIIToUTF16("g1"), clipboard_result);
+}
+
+TEST_F(BookmarkNodeDataTest, WriteToClipboardFolderAndURL) {
+  BookmarkNodeData data;
+  GURL url(GURL("http://foo.com"));
+  const base::string16 title(ASCIIToUTF16("blah"));
+  const BookmarkNode* root = model()->bookmark_bar_node();
+  const BookmarkNode* url_node = model()->AddURL(root, 0, title, url);
+  const BookmarkNode* folder = model()->AddFolder(root, 0, ASCIIToUTF16("g1"));
+  std::vector<const BookmarkNode*> nodes;
+  nodes.push_back(url_node);
+  nodes.push_back(folder);
+
+  data.ReadFromVector(nodes);
+  data.WriteToClipboard(ui::CLIPBOARD_TYPE_COPY_PASTE);
+
+  // Now read the data back in.
+  base::string16 combined_text;
+  base::string16 new_line = base::ASCIIToUTF16("\n");
+  base::string16 folder_title = ASCIIToUTF16("g1");
+  combined_text = base::ASCIIToUTF16(url.spec()) + new_line + folder_title;
+  base::string16 clipboard_result;
+  clipboard().ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &clipboard_result);
+  EXPECT_EQ(combined_text, clipboard_result);
+}
+
 // Tests reading/writing of meta info.
 TEST_F(BookmarkNodeDataTest, MetaInfo) {
   // Create a node containing meta info.
diff --git a/components/bookmarks/common/android/BUILD.gn b/components/bookmarks/common/android/BUILD.gn
index aa628827..bd8fee368 100644
--- a/components/bookmarks/common/android/BUILD.gn
+++ b/components/bookmarks/common/android/BUILD.gn
@@ -24,12 +24,11 @@
 }
 
 # GYP: //components/bookmarks.gyp:bookmarks_type_java
-java_cpp_template("bookmark_type_javagen") {
+java_cpp_enum("bookmark_type_javagen") {
   sources = [
-    "java/src/org/chromium/components/bookmarks/BookmarkType.template",
+    "bookmark_type.h",
   ]
-  package_name = "org/chromium/components/bookmarks"
-  inputs = [
-    "bookmark_type_list.h",
+  outputs = [
+    "org/chromium/components/bookmarks/BookmarkType.java",
   ]
 }
diff --git a/components/bookmarks/common/android/bookmark_type.h b/components/bookmarks/common/android/bookmark_type.h
index 0c4c3e2a..75d2138 100644
--- a/components/bookmarks/common/android/bookmark_type.h
+++ b/components/bookmarks/common/android/bookmark_type.h
@@ -7,10 +7,11 @@
 
 namespace bookmarks {
 
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.bookmarks
 enum BookmarkType {
-#define DEFINE_BOOKMARK_TYPE(name, value) name = value,
-#include "components/bookmarks/common/android/bookmark_type_list.h"
-#undef DEFINE_BOOKMARK_TYPE
+  BOOKMARK_TYPE_NORMAL,
+  BOOKMARK_TYPE_PARTNER,
 };
 
 }
diff --git a/components/bookmarks/common/android/bookmark_type_list.h b/components/bookmarks/common/android/bookmark_type_list.h
deleted file mode 100644
index e0a6594..0000000
--- a/components/bookmarks/common/android/bookmark_type_list.h
+++ /dev/null
@@ -1,13 +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.
-
-// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum values.
-
-#ifndef DEFINE_BOOKMARK_TYPE
-#error "DEFINE_BOOKMARK_TYPE should be defined before including this file"
-#endif
-
-DEFINE_BOOKMARK_TYPE(NORMAL, 0)
-DEFINE_BOOKMARK_TYPE(PARTNER, 1)
diff --git a/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkId.java b/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkId.java
index 88764fe..d8caa28 100644
--- a/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkId.java
+++ b/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkId.java
@@ -34,9 +34,9 @@
     private static int getBookmarkTypeFromChar(char c) {
         switch (c) {
             case TYPE_PARTNER:
-                return BookmarkType.BOOKMARK_TYPE_PARTNER;
+                return BookmarkType.PARTNER;
             default:
-                return BookmarkType.BOOKMARK_TYPE_NORMAL;
+                return BookmarkType.NORMAL;
         }
     }
 
@@ -55,7 +55,7 @@
      */
     public static BookmarkId getBookmarkIdFromString(String s) {
         long id = ROOT_FOLDER_ID;
-        int type = BookmarkType.BOOKMARK_TYPE_NORMAL;
+        int type = BookmarkType.NORMAL;
         if (TextUtils.isEmpty(s))
             return new BookmarkId(id, type);
         char folderTypeChar = s.charAt(0);
@@ -89,9 +89,9 @@
 
     private String getBookmarkTypeString() {
         switch (mType) {
-            case BookmarkType.BOOKMARK_TYPE_PARTNER:
+            case BookmarkType.PARTNER:
                 return String.valueOf(TYPE_PARTNER);
-            case BookmarkType.BOOKMARK_TYPE_NORMAL:
+            case BookmarkType.NORMAL:
             default:
                 return "";
         }
diff --git a/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkType.template b/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkType.template
deleted file mode 100644
index fd89154..0000000
--- a/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkType.template
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.components.bookmarks;
-
-public class BookmarkType {
-
-#define DEFINE_BOOKMARK_TYPE(name, value) public static final int BOOKMARK_TYPE_##name = value;
-#include "components/bookmarks/common/android/bookmark_type_list.h"
-#undef DEFINE_BOOKMARK_TYPE
-
-}
diff --git a/components/bookmarks/test/bookmark_test_helpers.cc b/components/bookmarks/test/bookmark_test_helpers.cc
index de4a899..a8c6d942 100644
--- a/components/bookmarks/test/bookmark_test_helpers.cc
+++ b/components/bookmarks/test/bookmark_test_helpers.cc
@@ -14,6 +14,9 @@
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "url/gurl.h"
 
+namespace bookmarks {
+namespace test {
+
 namespace {
 
 // BookmarkLoadObserver is used when blocking until the BookmarkModel finishes
@@ -92,8 +95,6 @@
 
 }  // namespace
 
-namespace test {
-
 void WaitForBookmarkModelToLoad(BookmarkModel* model) {
   if (model->loaded())
     return;
@@ -136,3 +137,4 @@
 }
 
 }  // namespace test
+}  // namespace bookmarks
diff --git a/components/bookmarks/test/bookmark_test_helpers.h b/components/bookmarks/test/bookmark_test_helpers.h
index cd107dd..a75609e5 100644
--- a/components/bookmarks/test/bookmark_test_helpers.h
+++ b/components/bookmarks/test/bookmark_test_helpers.h
@@ -10,6 +10,7 @@
 class BookmarkModel;
 class BookmarkNode;
 
+namespace bookmarks {
 namespace test {
 
 // Blocks until |model| finishes loading.
@@ -40,6 +41,8 @@
 void AddNodesFromModelString(BookmarkModel* model,
                              const BookmarkNode* node,
                              const std::string& model_string);
+
 }  // namespace test
+}  // namespace bookmarks
 
 #endif  // COMPONENTS_BOOKMARKS_TEST_BOOKMARK_TEST_HELPERS_H_
diff --git a/components/cdm.gypi b/components/cdm.gypi
index 618342c..d6f640a 100644
--- a/components/cdm.gypi
+++ b/components/cdm.gypi
@@ -26,7 +26,6 @@
       'dependencies': [
         'cdm_common',
         '../base/base.gyp:base',
-        '../content/content.gyp:content_common',
         '../content/content.gyp:content_renderer',
         '../third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h',
       ],
@@ -43,8 +42,8 @@
           'sources': [
             'cdm/renderer/android_key_systems.cc',
             'cdm/renderer/android_key_systems.h',
-	  ],
-	}],
+          ],
+        }],
       ],
     },
   ],
diff --git a/components/cdm/DEPS b/components/cdm/DEPS
index 1c40d98..5ca4943 100644
--- a/components/cdm/DEPS
+++ b/components/cdm/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   "+ipc",
+  "+media/base",
 ]
diff --git a/components/cdm/browser/cdm_message_filter_android.cc b/components/cdm/browser/cdm_message_filter_android.cc
index ccea5fe..a19a037 100644
--- a/components/cdm/browser/cdm_message_filter_android.cc
+++ b/components/cdm/browser/cdm_message_filter_android.cc
@@ -13,9 +13,9 @@
 #include "media/base/android/media_drm_bridge.h"
 
 using content::BrowserThread;
-using content::SupportedCodecs;
 using media::MediaCodecBridge;
 using media::MediaDrmBridge;
+using media::SupportedCodecs;
 
 namespace cdm {
 
@@ -34,12 +34,12 @@
 };
 
 const CodecInfo kCodecsToQuery[] = {
-  {content::EME_CODEC_WEBM_VORBIS, CODEC_AUDIO, "vorbis", "video/webm"},
-  {content::EME_CODEC_WEBM_VP8, CODEC_VIDEO, "vp8", "video/webm"},
-  {content::EME_CODEC_WEBM_VP9, CODEC_VIDEO, "vp9", "video/webm"},
+  {media::EME_CODEC_WEBM_VORBIS, CODEC_AUDIO, "vorbis", "video/webm"},
+  {media::EME_CODEC_WEBM_VP8, CODEC_VIDEO, "vp8", "video/webm"},
+  {media::EME_CODEC_WEBM_VP9, CODEC_VIDEO, "vp9", "video/webm"},
 #if defined(USE_PROPRIETARY_CODECS)
-  {content::EME_CODEC_MP4_AAC, CODEC_AUDIO, "mp4a", "video/mp4"},
-  {content::EME_CODEC_MP4_AVC1, CODEC_VIDEO, "avc1", "video/mp4"}
+  {media::EME_CODEC_MP4_AAC, CODEC_AUDIO, "mp4a", "video/mp4"},
+  {media::EME_CODEC_MP4_AVC1, CODEC_VIDEO, "avc1", "video/mp4"}
 #endif  // defined(USE_PROPRIETARY_CODECS)
 };
 
@@ -47,7 +47,7 @@
     const SupportedKeySystemRequest& request,
     bool video_must_be_compositable) {
   const std::string& key_system = request.key_system;
-  SupportedCodecs supported_codecs = content::EME_CODEC_NONE;
+  SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
 
   for (size_t i = 0; i < arraysize(kCodecsToQuery); ++i) {
     const CodecInfo& info = kCodecsToQuery[i];
@@ -106,7 +106,7 @@
   if (!MediaDrmBridge::IsKeySystemSupported(request.key_system))
     return;
 
-  DCHECK(request.codecs & content::EME_CODEC_ALL) << "unrecognized codec";
+  DCHECK(request.codecs & media::EME_CODEC_ALL) << "unrecognized codec";
   response->key_system = request.key_system;
   // TODO(qinmin): check composition is supported or not.
   response->compositing_codecs = GetSupportedCodecs(request, true);
diff --git a/components/cdm/common/cdm_messages_android.h b/components/cdm/common/cdm_messages_android.h
index 8e0ad1cb..028306a 100644
--- a/components/cdm/common/cdm_messages_android.h
+++ b/components/cdm/common/cdm_messages_android.h
@@ -7,24 +7,24 @@
 
 #include <vector>
 
-#include "content/public/common/eme_constants.h"
 #include "ipc/ipc_message_macros.h"
+#include "media/base/eme_constants.h"
 
 #define IPC_MESSAGE_START EncryptedMediaMsgStart
 
 IPC_STRUCT_BEGIN(SupportedKeySystemRequest)
   IPC_STRUCT_MEMBER(std::string, key_system)
-  IPC_STRUCT_MEMBER(content::SupportedCodecs, codecs, content::EME_CODEC_NONE)
+  IPC_STRUCT_MEMBER(media::SupportedCodecs, codecs, media::EME_CODEC_NONE)
 IPC_STRUCT_END()
 
 IPC_STRUCT_BEGIN(SupportedKeySystemResponse)
   IPC_STRUCT_MEMBER(std::string, key_system)
-  IPC_STRUCT_MEMBER(content::SupportedCodecs,
+  IPC_STRUCT_MEMBER(media::SupportedCodecs,
                     compositing_codecs,
-                    content::EME_CODEC_NONE)
-  IPC_STRUCT_MEMBER(content::SupportedCodecs,
+                    media::EME_CODEC_NONE)
+  IPC_STRUCT_MEMBER(media::SupportedCodecs,
                     non_compositing_codecs,
-                    content::EME_CODEC_NONE)
+                    media::EME_CODEC_NONE)
 IPC_STRUCT_END()
 
 // Messages sent from the renderer to the browser.
diff --git a/components/cdm/renderer/BUILD.gn b/components/cdm/renderer/BUILD.gn
index bc470b0..9652a6c 100644
--- a/components/cdm/renderer/BUILD.gn
+++ b/components/cdm/renderer/BUILD.gn
@@ -18,8 +18,8 @@
   deps = [
     "//base",
     "//components/cdm/common",
-    "//content/public/common",
     "//content/public/renderer",
+    "//media/base",
     "//third_party/widevine/cdm:version_h",
   ]
 }
diff --git a/components/cdm/renderer/DEPS b/components/cdm/renderer/DEPS
index dbd28cf..725e151 100644
--- a/components/cdm/renderer/DEPS
+++ b/components/cdm/renderer/DEPS
@@ -1,4 +1,3 @@
 include_rules = [
-  "+content/public/common",
   "+content/public/renderer",
 ]
diff --git a/components/cdm/renderer/android_key_systems.cc b/components/cdm/renderer/android_key_systems.cc
index c6adc80..83a0d04 100644
--- a/components/cdm/renderer/android_key_systems.cc
+++ b/components/cdm/renderer/android_key_systems.cc
@@ -10,13 +10,13 @@
 #include "base/logging.h"
 #include "components/cdm/common/cdm_messages_android.h"
 #include "components/cdm/renderer/widevine_key_systems.h"
-#include "content/public/common/eme_constants.h"
 #include "content/public/renderer/render_thread.h"
+#include "media/base/eme_constants.h"
 
 #include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
 
-using content::KeySystemInfo;
-using content::SupportedCodecs;
+using media::KeySystemInfo;
+using media::SupportedCodecs;
 
 namespace cdm {
 
@@ -26,12 +26,12 @@
   SupportedKeySystemResponse response;
 
   request.key_system = key_system;
-  request.codecs = content::EME_CODEC_ALL;
+  request.codecs = media::EME_CODEC_ALL;
   content::RenderThread::Get()->Send(
       new ChromeViewHostMsg_QueryKeySystemSupport(request, &response));
-  DCHECK(!(response.compositing_codecs & ~content::EME_CODEC_ALL))
+  DCHECK(!(response.compositing_codecs & ~media::EME_CODEC_ALL))
       << "unrecognized codec";
-  DCHECK(!(response.non_compositing_codecs & ~content::EME_CODEC_ALL))
+  DCHECK(!(response.non_compositing_codecs & ~media::EME_CODEC_ALL))
       << "unrecognized codec";
   return response;
 }
@@ -39,14 +39,14 @@
 void AddAndroidWidevine(std::vector<KeySystemInfo>* concrete_key_systems) {
   SupportedKeySystemResponse response = QueryKeySystemSupport(
       kWidevineKeySystem);
-  if (response.compositing_codecs != content::EME_CODEC_NONE) {
+  if (response.compositing_codecs != media::EME_CODEC_NONE) {
     AddWidevineWithCodecs(
         WIDEVINE,
         static_cast<SupportedCodecs>(response.compositing_codecs),
         concrete_key_systems);
   }
 
-  if (response.non_compositing_codecs != content::EME_CODEC_NONE) {
+  if (response.non_compositing_codecs != media::EME_CODEC_NONE) {
     AddWidevineWithCodecs(
         WIDEVINE_HR_NON_COMPOSITING,
         static_cast<SupportedCodecs>(response.non_compositing_codecs),
@@ -63,17 +63,17 @@
   for (std::vector<std::string>::const_iterator it = key_system_names.begin();
        it != key_system_names.end(); ++it) {
     SupportedKeySystemResponse response = QueryKeySystemSupport(*it);
-    if (response.compositing_codecs != content::EME_CODEC_NONE) {
+    if (response.compositing_codecs != media::EME_CODEC_NONE) {
       KeySystemInfo info(*it);
       info.supported_codecs = response.compositing_codecs;
       // Here we assume that support for a container implies support for the
       // associated initialization data type. KeySystems handles validating
       // |init_data_type| x |container| pairings.
-      if (response.compositing_codecs & content::EME_CODEC_WEBM_ALL)
-        info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_WEBM;
+      if (response.compositing_codecs & media::EME_CODEC_WEBM_ALL)
+        info.supported_init_data_types |= media::EME_INIT_DATA_TYPE_WEBM;
 #if defined(USE_PROPRIETARY_CODECS)
-      if (response.compositing_codecs & content::EME_CODEC_MP4_ALL)
-        info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_CENC;
+      if (response.compositing_codecs & media::EME_CODEC_MP4_ALL)
+        info.supported_init_data_types |= media::EME_INIT_DATA_TYPE_CENC;
 #endif  // defined(USE_PROPRIETARY_CODECS)
       concrete_key_systems->push_back(info);
     }
diff --git a/components/cdm/renderer/android_key_systems.h b/components/cdm/renderer/android_key_systems.h
index 36be6c9f5..fb962b15 100644
--- a/components/cdm/renderer/android_key_systems.h
+++ b/components/cdm/renderer/android_key_systems.h
@@ -7,17 +7,17 @@
 
 #include <vector>
 
-#include "content/public/renderer/key_system_info.h"
+#include "media/base/key_system_info.h"
 
 namespace cdm {
 
 void AddAndroidWidevine(
-    std::vector<content::KeySystemInfo>* concrete_key_systems);
+    std::vector<media::KeySystemInfo>* concrete_key_systems);
 
 // Add platform-supported key systems which are not explicitly handled
 // by Chrome.
 void AddAndroidPlatformKeySystems(
-    std::vector<content::KeySystemInfo>* concrete_key_systems);
+    std::vector<media::KeySystemInfo>* concrete_key_systems);
 
 }  // namespace cdm
 
diff --git a/components/cdm/renderer/widevine_key_systems.cc b/components/cdm/renderer/widevine_key_systems.cc
index d08b6ad9..f803e8e 100644
--- a/components/cdm/renderer/widevine_key_systems.cc
+++ b/components/cdm/renderer/widevine_key_systems.cc
@@ -8,14 +8,14 @@
 #include <vector>
 
 #include "base/logging.h"
-#include "content/public/common/eme_constants.h"
+#include "media/base/eme_constants.h"
 
 #include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
 
 #if defined(WIDEVINE_CDM_AVAILABLE)
 
-using content::KeySystemInfo;
-using content::SupportedCodecs;
+using media::KeySystemInfo;
+using media::SupportedCodecs;
 
 namespace cdm {
 
@@ -53,11 +53,11 @@
   // Here we assume that support for a container imples support for the
   // associated initialization data type. KeySystems handles validating
   // |init_data_type| x |container| pairings.
-  if (supported_codecs & content::EME_CODEC_WEBM_ALL)
-    info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_WEBM;
+  if (supported_codecs & media::EME_CODEC_WEBM_ALL)
+    info.supported_init_data_types |= media::EME_INIT_DATA_TYPE_WEBM;
 #if defined(USE_PROPRIETARY_CODECS)
-  if (supported_codecs & content::EME_CODEC_MP4_ALL)
-    info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_CENC;
+  if (supported_codecs & media::EME_CODEC_MP4_ALL)
+    info.supported_init_data_types |= media::EME_INIT_DATA_TYPE_CENC;
 #endif  // defined(USE_PROPRIETARY_CODECS)
 
 #if defined(ENABLE_PEPPER_CDMS)
diff --git a/components/cdm/renderer/widevine_key_systems.h b/components/cdm/renderer/widevine_key_systems.h
index ab1966f..1d42b3b 100644
--- a/components/cdm/renderer/widevine_key_systems.h
+++ b/components/cdm/renderer/widevine_key_systems.h
@@ -7,7 +7,8 @@
 
 #include <vector>
 
-#include "content/public/renderer/key_system_info.h"
+#include "build/build_config.h"
+#include "media/base/key_system_info.h"
 
 namespace cdm {
 
@@ -20,8 +21,8 @@
 
 void AddWidevineWithCodecs(
     WidevineCdmType widevine_cdm_type,
-    content::SupportedCodecs supported_codecs,
-    std::vector<content::KeySystemInfo>* concrete_key_systems);
+    media::SupportedCodecs supported_codecs,
+    std::vector<media::KeySystemInfo>* concrete_key_systems);
 
 }  // namespace cdm
 
diff --git a/components/components.gyp b/components/components.gyp
index 8f1dba5..8cb01a29 100644
--- a/components/components.gyp
+++ b/components/components.gyp
@@ -34,6 +34,7 @@
     'keyed_service.gypi',
     'language_usage_metrics.gypi',
     'leveldb_proto.gypi',
+    'login.gypi',
     'metrics.gypi',
     'navigation_metrics.gypi',
     'network_time.gypi',
@@ -62,6 +63,7 @@
   'conditions': [
     ['OS != "ios"', {
       'includes': [
+        'app_modal_dialogs.gypi',
         'cdm.gypi',
         'copresence_sockets.gypi',
         'navigation_interception.gypi',
diff --git a/components/components_strings.grd b/components/components_strings.grd
index 3c8437cb..7cc85831 100644
--- a/components/components_strings.grd
+++ b/components/components_strings.grd
@@ -167,6 +167,7 @@
   </translations>
   <release seq="1" allow_pseudo="false">
     <messages fallback_to_english="true">
+      <part file="app_modal_dialogs_strings.grdp" />
       <part file="autofill_strings.grdp" />
       <part file="bookmark_bar_strings.grdp" />
       <part file="dom_distiller_strings.grdp" />
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index a83440a..74c86a4 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -146,6 +146,7 @@
             'keyed_service/core/dependency_graph_unittest.cc',
             'language_usage_metrics/language_usage_metrics_unittest.cc',
             'leveldb_proto/proto_database_impl_unittest.cc',
+            'login/screens/screen_context_unittest.cc',
             'metrics/compression_utils_unittest.cc',
             'metrics/daily_event_unittest.cc',
             'metrics/machine_id_provider_win_unittest.cc',
@@ -204,6 +205,8 @@
             'search_engines/template_url_unittest.cc',
             'search_provider_logos/logo_cache_unittest.cc',
             'search_provider_logos/logo_tracker_unittest.cc',
+            'sessions/content/content_serialized_navigation_builder_unittest.cc',
+            'sessions/content/content_serialized_navigation_driver_unittest.cc',
             'sessions/serialized_navigation_entry_unittest.cc',
             'signin/core/browser/account_tracker_service_unittest.cc',
             'signin/core/browser/mutable_profile_oauth2_token_service_unittest.cc',
@@ -252,9 +255,9 @@
             'variations/caching_permuted_entropy_provider_unittest.cc',
             'variations/entropy_provider_unittest.cc',
             'variations/metrics_util_unittest.cc',
+            'variations/net/variations_http_header_provider_unittest.cc',
             'variations/study_filtering_unittest.cc',
             'variations/variations_associated_data_unittest.cc',
-            'variations/variations_http_header_provider_unittest.cc',
             'variations/variations_seed_processor_unittest.cc',
             'variations/variations_seed_simulator_unittest.cc',
             'visitedlink/test/visitedlink_unittest.cc',
@@ -375,6 +378,9 @@
             'components.gyp:leveldb_proto',
             'components.gyp:leveldb_proto_test_support',
 
+            # Dependencies of login
+            'components.gyp:login',
+
             # Dependencies of metrics
             'components.gyp:metrics',
             'components.gyp:metrics_gpu',
@@ -496,7 +502,7 @@
 
                 # Dependencies of sessions
                 '../third_party/protobuf/protobuf.gyp:protobuf_lite',
-                'components.gyp:sessions',
+                'components.gyp:sessions_content',
                 'components.gyp:sessions_test_support',
 
                 # Dependencies of storage monitor
@@ -667,6 +673,7 @@
               'sources': [
                 'copresence/handlers/audio/audio_directive_handler_unittest.cc',
                 'copresence/handlers/audio/audio_directive_list_unittest.cc',
+                'copresence/mediums/audio/audio_manager_unittest.cc',
                 'copresence/mediums/audio/audio_player_unittest.cc',
                 'copresence/mediums/audio/audio_recorder_unittest.cc',
                 'copresence/rpc/http_post_unittest.cc',
diff --git a/components/content_settings/core/browser/content_settings_client.h b/components/content_settings/core/browser/content_settings_client.h
index 0b89b169..e6f4a4e 100644
--- a/components/content_settings/core/browser/content_settings_client.h
+++ b/components/content_settings/core/browser/content_settings_client.h
@@ -21,9 +21,6 @@
 namespace content_settings {
 
 // An abstraction of operations that depend on the embedder (e.g. Chrome).
-// For mock / testing implementation in tests you can inherit from
-// StubContentSettingsClient instead to avoid the need to stub unneeded pure
-// virtual methods.
 class ContentSettingsClient {
  public:
   enum AccessType { BLOCKED, ALLOWED };
diff --git a/components/content_settings/core/browser/content_settings_observable_provider.cc b/components/content_settings/core/browser/content_settings_observable_provider.cc
index 9e82fbe..edda022 100644
--- a/components/content_settings/core/browser/content_settings_observable_provider.cc
+++ b/components/content_settings/core/browser/content_settings_observable_provider.cc
@@ -42,4 +42,8 @@
   observer_list_.Clear();
 }
 
+bool ObservableProvider::CalledOnValidThread() {
+  return thread_checker_.CalledOnValidThread();
+}
+
 }  // namespace content_settings
diff --git a/components/content_settings/core/browser/content_settings_observable_provider.h b/components/content_settings/core/browser/content_settings_observable_provider.h
index 6c011e0..cb6a01dd 100644
--- a/components/content_settings/core/browser/content_settings_observable_provider.h
+++ b/components/content_settings/core/browser/content_settings_observable_provider.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/observer_list.h"
+#include "base/threading/thread_checker.h"
 #include "components/content_settings/core/browser/content_settings_observer.h"
 #include "components/content_settings/core/browser/content_settings_provider.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
@@ -28,8 +29,10 @@
                        ContentSettingsType content_type,
                        const std::string& resource_identifier);
   void RemoveAllObservers();
+  bool CalledOnValidThread();
 
  private:
+  base::ThreadChecker thread_checker_;
   ObserverList<Observer, true> observer_list_;
 };
 
diff --git a/components/content_settings/core/common/content_settings.h b/components/content_settings/core/common/content_settings.h
index f35e9e1..7c91b0c 100644
--- a/components/content_settings/core/common/content_settings.h
+++ b/components/content_settings/core/common/content_settings.h
@@ -12,6 +12,8 @@
 
 // Different settings that can be assigned for a particular content type.  We
 // give the user the ability to set these on a global and per-origin basis.
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser
 enum ContentSetting {
   CONTENT_SETTING_DEFAULT = 0,
   CONTENT_SETTING_ALLOW,
diff --git a/components/content_settings/core/common/content_settings_types.h b/components/content_settings/core/common/content_settings_types.h
index cce4a77..7e83d4fd 100644
--- a/components/content_settings/core/common/content_settings_types.h
+++ b/components/content_settings/core/common/content_settings_types.h
@@ -9,6 +9,8 @@
 
 // A particular type of content to care about.  We give the user various types
 // of controls over each of these.
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser
 enum ContentSettingsType {
   // "DEFAULT" is only used as an argument to the Content Settings Window
   // opener; there it means "whatever was last shown".
diff --git a/components/copresence.gypi b/components/copresence.gypi
index 6ecd700..c095c2b3 100644
--- a/components/copresence.gypi
+++ b/components/copresence.gypi
@@ -31,10 +31,15 @@
         'copresence/handlers/audio/audio_directive_list.h',
         'copresence/handlers/directive_handler.cc',
         'copresence/handlers/directive_handler.h',
-        'copresence/mediums/audio/audio_player.cc',
+        'copresence/mediums/audio/audio_manager.h',
+        'copresence/mediums/audio/audio_manager_impl.cc',
+        'copresence/mediums/audio/audio_manager_impl.h',
         'copresence/mediums/audio/audio_player.h',
-        'copresence/mediums/audio/audio_recorder.cc',
+        'copresence/mediums/audio/audio_player_impl.cc',
+        'copresence/mediums/audio/audio_player_impl.h',
         'copresence/mediums/audio/audio_recorder.h',
+        'copresence/mediums/audio/audio_recorder_impl.cc',
+        'copresence/mediums/audio/audio_recorder_impl.h',
         'copresence/public/copresence_constants.h',
         'copresence/public/copresence_delegate.h',
         'copresence/public/copresence_manager.h',
diff --git a/components/copresence/BUILD.gn b/components/copresence/BUILD.gn
index d19aca1..e0130d0 100644
--- a/components/copresence/BUILD.gn
+++ b/components/copresence/BUILD.gn
@@ -15,10 +15,15 @@
     "handlers/audio/audio_directive_list.h",
     "handlers/directive_handler.cc",
     "handlers/directive_handler.h",
-    "mediums/audio/audio_player.cc",
+    "mediums/audio/audio_manager.h",
+    "mediums/audio/audio_manager_impl.cc",
+    "mediums/audio/audio_manager_impl.h",
     "mediums/audio/audio_player.h",
-    "mediums/audio/audio_recorder.cc",
+    "mediums/audio/audio_player_impl.cc",
+    "mediums/audio/audio_player_impl.h",
     "mediums/audio/audio_recorder.h",
+    "mediums/audio/audio_recorder_impl.cc",
+    "mediums/audio/audio_recorder_impl.h",
     "public/copresence_constants.h",
     "public/copresence_delegate.h",
     "public/copresence_manager.h",
diff --git a/components/copresence/handlers/audio/audio_directive_handler.cc b/components/copresence/handlers/audio/audio_directive_handler.cc
index 3d2e7c6..9a797380 100644
--- a/components/copresence/handlers/audio/audio_directive_handler.cc
+++ b/components/copresence/handlers/audio/audio_directive_handler.cc
@@ -7,67 +7,47 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/strings/string_util.h"
+#include "base/time/default_tick_clock.h"
 #include "base/time/time.h"
-#include "components/copresence/mediums/audio/audio_player.h"
-#include "components/copresence/mediums/audio/audio_recorder.h"
+#include "base/timer/timer.h"
+#include "components/copresence/mediums/audio/audio_manager_impl.h"
 #include "components/copresence/proto/data.pb.h"
+#include "components/copresence/public/copresence_constants.h"
 #include "media/base/audio_bus.h"
 
-namespace {
-
-// UrlSafe is defined as:
-// '/' represented by a '_' and '+' represented by a '-'
-// TODO(rkc): Move this processing to the whispernet wrapper.
-std::string FromUrlSafe(std::string token) {
-  base::ReplaceChars(token, "-", "+", &token);
-  base::ReplaceChars(token, "_", "/", &token);
-  return token;
-}
-
-const int kSampleExpiryTimeMs = 60 * 60 * 1000;  // 60 minutes.
-const int kMaxSamples = 10000;
-
-}  // namespace
-
 namespace copresence {
 
+namespace {
+
+base::TimeTicks GetEarliestEventTime(AudioDirectiveList* list,
+                                     base::TimeTicks event_time) {
+  if (!list->GetActiveDirective())
+    return event_time;
+
+  if (event_time.is_null())
+    return list->GetActiveDirective()->end_time;
+  else
+    return std::min(list->GetActiveDirective()->end_time, event_time);
+}
+
+}  // namespace
+
 // Public methods.
 
-AudioDirectiveHandler::AudioDirectiveHandler(
-    const AudioRecorder::DecodeSamplesCallback& decode_cb,
-    const AudioDirectiveHandler::EncodeTokenCallback& encode_cb)
-    : player_audible_(NULL),
-      player_inaudible_(NULL),
-      recorder_(NULL),
-      decode_cb_(decode_cb),
-      encode_cb_(encode_cb),
-      samples_cache_audible_(
-          base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs),
-          kMaxSamples),
-      samples_cache_inaudible_(
-          base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs),
-          kMaxSamples) {
+AudioDirectiveHandler::AudioDirectiveHandler()
+    : audio_event_timer_(new base::OneShotTimer<AudioDirectiveHandler>),
+      clock_(new base::DefaultTickClock) {
 }
 
 AudioDirectiveHandler::~AudioDirectiveHandler() {
-  if (player_audible_)
-    player_audible_->Finalize();
-  if (player_inaudible_)
-    player_inaudible_->Finalize();
-  if (recorder_)
-    recorder_->Finalize();
 }
 
-void AudioDirectiveHandler::Initialize() {
-  player_audible_ = new AudioPlayer();
-  player_audible_->Initialize();
-
-  player_inaudible_ = new AudioPlayer();
-  player_inaudible_->Initialize();
-
-  recorder_ = new AudioRecorder(decode_cb_);
-  recorder_->Initialize();
+void AudioDirectiveHandler::Initialize(
+    const AudioManager::DecodeSamplesCallback& decode_cb,
+    const AudioManager::EncodeTokenCallback& encode_cb) {
+  if (!audio_manager_)
+    audio_manager_.reset(new AudioManagerImpl());
+  audio_manager_->Initialize(decode_cb, encode_cb);
 }
 
 void AudioDirectiveHandler::AddInstruction(const TokenInstruction& instruction,
@@ -77,144 +57,105 @@
     case TRANSMIT:
       DVLOG(2) << "Audio Transmit Directive received. Token: "
                << instruction.token_id()
+               << " with medium=" << instruction.medium()
                << " with TTL=" << ttl.InMilliseconds();
       switch (instruction.medium()) {
         case AUDIO_ULTRASOUND_PASSBAND:
-          transmits_list_inaudible_.AddDirective(op_id, ttl);
-          PlayToken(instruction.token_id(), false);
+          transmits_list_[INAUDIBLE].AddDirective(op_id, ttl);
+          audio_manager_->SetToken(INAUDIBLE, instruction.token_id());
           break;
         case AUDIO_AUDIBLE_DTMF:
-          transmits_list_audible_.AddDirective(op_id, ttl);
-          PlayToken(instruction.token_id(), true);
+          transmits_list_[AUDIBLE].AddDirective(op_id, ttl);
+          audio_manager_->SetToken(AUDIBLE, instruction.token_id());
           break;
         default:
           NOTREACHED();
       }
       break;
     case RECEIVE:
-      DVLOG(2) << "Audio Receive Directive received. TTL="
-               << ttl.InMilliseconds();
-      receives_list_.AddDirective(op_id, ttl);
-      ProcessNextReceive();
+      DVLOG(2) << "Audio Receive Directive received."
+               << " with medium=" << instruction.medium()
+               << " with TTL=" << ttl.InMilliseconds();
+      switch (instruction.medium()) {
+        case AUDIO_ULTRASOUND_PASSBAND:
+          receives_list_[INAUDIBLE].AddDirective(op_id, ttl);
+          break;
+        case AUDIO_AUDIBLE_DTMF:
+          receives_list_[AUDIBLE].AddDirective(op_id, ttl);
+          break;
+        default:
+          NOTREACHED();
+      }
       break;
     case UNKNOWN_TOKEN_INSTRUCTION_TYPE:
     default:
-      LOG(WARNING) << "Unknown Audio Transmit Directive received.";
+      LOG(WARNING) << "Unknown Audio Transmit Directive received. type = "
+                   << instruction.token_instruction_type();
   }
+  ProcessNextInstruction();
 }
 
 void AudioDirectiveHandler::RemoveInstructions(const std::string& op_id) {
-  transmits_list_audible_.RemoveDirective(op_id);
-  transmits_list_inaudible_.RemoveDirective(op_id);
-  receives_list_.RemoveDirective(op_id);
+  transmits_list_[AUDIBLE].RemoveDirective(op_id);
+  transmits_list_[INAUDIBLE].RemoveDirective(op_id);
+  receives_list_[AUDIBLE].RemoveDirective(op_id);
+  receives_list_[INAUDIBLE].RemoveDirective(op_id);
 
-  ProcessNextTransmit();
-  ProcessNextReceive();
+  ProcessNextInstruction();
 }
 
+const std::string AudioDirectiveHandler::PlayingToken(AudioType type) const {
+  return audio_manager_->GetToken(type);
+}
 // Private methods.
 
-void AudioDirectiveHandler::ProcessNextTransmit() {
-  // If we have an active directive for audible or inaudible audio, ensure that
-  // we are playing our respective token; if we do not have a directive, then
-  // make sure we aren't playing. This is duplicate code, but for just two
-  // elements, it has hard to make a case for processing a loop instead.
+void AudioDirectiveHandler::ProcessNextInstruction() {
+  DCHECK(audio_event_timer_);
+  audio_event_timer_->Stop();
 
-  scoped_ptr<AudioDirective> audible_transmit(
-      transmits_list_audible_.GetActiveDirective());
-  if (audible_transmit && !player_audible_->IsPlaying() &&
-      samples_cache_audible_.HasKey(current_token_audible_)) {
-    DVLOG(3) << "Playing audible for op_id: " << audible_transmit->op_id;
-    player_audible_->Play(
-        samples_cache_audible_.GetValue(current_token_audible_));
-    stop_audible_playback_timer_.Start(
+  // Change |audio_manager_| state for audible transmits.
+  if (transmits_list_[AUDIBLE].GetActiveDirective())
+    audio_manager_->StartPlaying(AUDIBLE);
+  else
+    audio_manager_->StopPlaying(AUDIBLE);
+
+  // Change audio_manager_ state for inaudible transmits.
+  if (transmits_list_[INAUDIBLE].GetActiveDirective())
+    audio_manager_->StartPlaying(INAUDIBLE);
+  else
+    audio_manager_->StopPlaying(INAUDIBLE);
+
+  // Change audio_manager_ state for audible receives.
+  if (receives_list_[AUDIBLE].GetActiveDirective())
+    audio_manager_->StartRecording(AUDIBLE);
+  else
+    audio_manager_->StopRecording(AUDIBLE);
+
+  // Change audio_manager_ state for inaudible receives.
+  if (receives_list_[INAUDIBLE].GetActiveDirective())
+    audio_manager_->StartRecording(INAUDIBLE);
+  else
+    audio_manager_->StopRecording(INAUDIBLE);
+
+  base::TimeTicks next_event_time;
+  if (GetNextInstructionExpiry(&next_event_time)) {
+    audio_event_timer_->Start(
         FROM_HERE,
-        audible_transmit->end_time - base::Time::Now(),
-        this,
-        &AudioDirectiveHandler::ProcessNextTransmit);
-  } else if (!audible_transmit && player_audible_->IsPlaying()) {
-    DVLOG(3) << "Stopping audible playback.";
-    current_token_audible_.clear();
-    stop_audible_playback_timer_.Stop();
-    player_audible_->Stop();
-  }
-
-  scoped_ptr<AudioDirective> inaudible_transmit(
-      transmits_list_inaudible_.GetActiveDirective());
-  if (inaudible_transmit && !player_inaudible_->IsPlaying() &&
-      samples_cache_inaudible_.HasKey(current_token_inaudible_)) {
-    DVLOG(3) << "Playing inaudible for op_id: " << inaudible_transmit->op_id;
-    player_inaudible_->Play(
-        samples_cache_inaudible_.GetValue(current_token_inaudible_));
-    stop_inaudible_playback_timer_.Start(
-        FROM_HERE,
-        inaudible_transmit->end_time - base::Time::Now(),
-        this,
-        &AudioDirectiveHandler::ProcessNextTransmit);
-  } else if (!inaudible_transmit && player_inaudible_->IsPlaying()) {
-    DVLOG(3) << "Stopping inaudible playback.";
-    current_token_inaudible_.clear();
-    stop_inaudible_playback_timer_.Stop();
-    player_inaudible_->Stop();
+        next_event_time - clock_->NowTicks(),
+        base::Bind(&AudioDirectiveHandler::ProcessNextInstruction,
+                   base::Unretained(this)));
   }
 }
 
-void AudioDirectiveHandler::ProcessNextReceive() {
-  scoped_ptr<AudioDirective> receive(receives_list_.GetActiveDirective());
+bool AudioDirectiveHandler::GetNextInstructionExpiry(base::TimeTicks* expiry) {
+  DCHECK(expiry);
 
-  if (receive && !recorder_->IsRecording()) {
-    DVLOG(3) << "Recording for op_id: " << receive->op_id;
-    recorder_->Record();
-    stop_recording_timer_.Start(FROM_HERE,
-                                receive->end_time - base::Time::Now(),
-                                this,
-                                &AudioDirectiveHandler::ProcessNextReceive);
-  } else if (!receive && recorder_->IsRecording()) {
-    DVLOG(3) << "Stopping Recording";
-    stop_recording_timer_.Stop();
-    recorder_->Stop();
-  }
-}
+  *expiry = GetEarliestEventTime(&transmits_list_[AUDIBLE], base::TimeTicks());
+  *expiry = GetEarliestEventTime(&transmits_list_[INAUDIBLE], *expiry);
+  *expiry = GetEarliestEventTime(&receives_list_[AUDIBLE], *expiry);
+  *expiry = GetEarliestEventTime(&receives_list_[INAUDIBLE], *expiry);
 
-void AudioDirectiveHandler::PlayToken(const std::string token, bool audible) {
-  std::string valid_token = FromUrlSafe(token);
-
-  // If the token has been encoded already, use the cached samples.
-  if (audible && samples_cache_audible_.HasKey(valid_token)) {
-    current_token_audible_ = token;
-    ProcessNextTransmit();
-  } else if (!audible && samples_cache_inaudible_.HasKey(valid_token)) {
-    current_token_inaudible_ = token;
-    ProcessNextTransmit();
-  } else {
-    // Otherwise, encode the token and then play it.
-    encode_cb_.Run(valid_token,
-                   audible,
-                   base::Bind(&AudioDirectiveHandler::PlayEncodedToken,
-                              base::Unretained(this)));
-  }
-}
-
-void AudioDirectiveHandler::PlayEncodedToken(
-    const std::string& token,
-    bool audible,
-    const scoped_refptr<media::AudioBusRefCounted>& samples) {
-  DVLOG(3) << "Token " << token << "[audible:" << audible << "] encoded.";
-  if (audible) {
-    samples_cache_audible_.Add(token, samples);
-    current_token_audible_ = token;
-    // Force process transmits to pick up the new token.
-    if (player_audible_->IsPlaying())
-      player_audible_->Stop();
-  } else {
-    samples_cache_inaudible_.Add(token, samples);
-    current_token_inaudible_ = token;
-    // Force process transmits to pick up the new token.
-    if (player_inaudible_->IsPlaying())
-      player_inaudible_->Stop();
-  }
-
-  ProcessNextTransmit();
+  return !expiry->is_null();
 }
 
 }  // namespace copresence
diff --git a/components/copresence/handlers/audio/audio_directive_handler.h b/components/copresence/handlers/audio/audio_directive_handler.h
index 4b52707..54885b9 100644
--- a/components/copresence/handlers/audio/audio_directive_handler.h
+++ b/components/copresence/handlers/audio/audio_directive_handler.h
@@ -10,12 +10,16 @@
 #include "base/basictypes.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
-#include "base/timer/timer.h"
 #include "components/copresence/handlers/audio/audio_directive_list.h"
-#include "components/copresence/mediums/audio/audio_recorder.h"
+#include "components/copresence/mediums/audio/audio_manager.h"
 #include "components/copresence/proto/data.pb.h"
-#include "components/copresence/timed_map.h"
+
+namespace base {
+class TickClock;
+class Timer;
+}
 
 namespace media {
 class AudioBusRefCounted;
@@ -23,8 +27,6 @@
 
 namespace copresence {
 
-class AudioPlayer;
-
 // The AudioDirectiveHandler handles audio transmit and receive instructions.
 // TODO(rkc): Currently since WhispernetClient can only have one token encoded
 // callback at a time, we need to have both the audible and inaudible in this
@@ -32,22 +34,14 @@
 // out token encoding to a separate class, or allowing whispernet to have
 // multiple callbacks for encoded tokens being sent back and have two versions
 // of this class.
-class AudioDirectiveHandler {
+class AudioDirectiveHandler final {
  public:
-  typedef base::Callback<void(const std::string&,
-                              bool,
-                              const scoped_refptr<media::AudioBusRefCounted>&)>
-      SamplesCallback;
-  typedef base::Callback<void(const std::string&, bool, const SamplesCallback&)>
-      EncodeTokenCallback;
-
-  AudioDirectiveHandler(
-      const AudioRecorder::DecodeSamplesCallback& decode_cb,
-      const AudioDirectiveHandler::EncodeTokenCallback& encode_cb);
-  virtual ~AudioDirectiveHandler();
+  AudioDirectiveHandler();
+  ~AudioDirectiveHandler();
 
   // Do not use this class before calling this.
-  void Initialize();
+  void Initialize(const AudioManager::DecodeSamplesCallback& decode_cb,
+                  const AudioManager::EncodeTokenCallback& encode_cb);
 
   // Adds an instruction to our handler. The instruction will execute and be
   // removed after the ttl expires.
@@ -58,73 +52,35 @@
   // Removes all instructions associated with this operation id.
   void RemoveInstructions(const std::string& op_id);
 
-  // Returns the currently playing DTMF token.
-  const std::string& PlayingAudibleToken() const {
-    return current_token_audible_;
-  }
+  // Returns the currently playing token.
+  const std::string PlayingToken(AudioType type) const;
 
-  // Returns the currently playing DSSS token.
-  const std::string& PlayingInaudibleToken() const {
-    return current_token_inaudible_;
-  }
-
-  void set_player_audible_for_testing(AudioPlayer* player) {
-    player_audible_ = player;
-  }
-
-  void set_player_inaudible_for_testing(AudioPlayer* player) {
-    player_inaudible_ = player;
-  }
-
-  void set_recorder_for_testing(AudioRecorder* recorder) {
-    recorder_ = recorder;
+  // The manager being passed in needs to be uninitialized.
+  void set_audio_manager_for_testing(scoped_ptr<AudioManager> manager) {
+    audio_manager_ = manager.Pass();
   }
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(AudioDirectiveHandlerTest, Basic);
+  // Processes the next active instruction, updating our audio manager state
+  // accordingly.
+  void ProcessNextInstruction();
 
-  typedef TimedMap<std::string, scoped_refptr<media::AudioBusRefCounted>>
-      SamplesMap;
+  // Returns the time that an instruction expires at. This will always return
+  // the earliest expiry time among all the active receive and transmit
+  // instructions. In case we don't have any active instructions, this method
+  // returns false.
+  bool GetNextInstructionExpiry(base::TimeTicks* next_event);
 
-  // Processes the next active transmit instruction.
-  void ProcessNextTransmit();
-  // Processes the next active receive instruction.
-  void ProcessNextReceive();
+  scoped_ptr<AudioManager> audio_manager_;
 
-  void PlayToken(const std::string token, bool audible);
+  // Audible and inaudible lists.
+  // AUDIBLE = 0, INAUDIBLE = 1 (see copresence_constants.h).
+  AudioDirectiveList transmits_list_[2];
+  AudioDirectiveList receives_list_[2];
 
-  // This is the method that the whispernet client needs to call to return
-  // samples to us.
-  void PlayEncodedToken(
-      const std::string& token,
-      bool audible,
-      const scoped_refptr<media::AudioBusRefCounted>& samples);
+  scoped_ptr<base::Timer> audio_event_timer_;
 
-  AudioDirectiveList transmits_list_audible_;
-  AudioDirectiveList transmits_list_inaudible_;
-  AudioDirectiveList receives_list_;
-
-  // Currently playing tokens.
-  std::string current_token_audible_;
-  std::string current_token_inaudible_;
-
-  // AudioPlayer and AudioRecorder objects are self-deleting. When we call
-  // Finalize on them, they clean themselves up on the Audio thread.
-  AudioPlayer* player_audible_;
-  AudioPlayer* player_inaudible_;
-  AudioRecorder* recorder_;
-
-  AudioRecorder::DecodeSamplesCallback decode_cb_;
-  EncodeTokenCallback encode_cb_;
-
-  base::OneShotTimer<AudioDirectiveHandler> stop_audible_playback_timer_;
-  base::OneShotTimer<AudioDirectiveHandler> stop_inaudible_playback_timer_;
-  base::OneShotTimer<AudioDirectiveHandler> stop_recording_timer_;
-
-  // Cache that holds the encoded samples. After reaching its limit, the cache
-  // expires the oldest samples first.
-  SamplesMap samples_cache_audible_;
-  SamplesMap samples_cache_inaudible_;
+  scoped_ptr<base::TickClock> clock_;
 
   DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandler);
 };
diff --git a/components/copresence/handlers/audio/audio_directive_handler_unittest.cc b/components/copresence/handlers/audio/audio_directive_handler_unittest.cc
index 56dd49d..e5b1dc6 100644
--- a/components/copresence/handlers/audio/audio_directive_handler_unittest.cc
+++ b/components/copresence/handlers/audio/audio_directive_handler_unittest.cc
@@ -5,75 +5,66 @@
 #include "components/copresence/handlers/audio/audio_directive_handler.h"
 
 #include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
-#include "components/copresence/mediums/audio/audio_player.h"
-#include "components/copresence/mediums/audio/audio_recorder.h"
+#include "components/copresence/mediums/audio/audio_manager.h"
 #include "components/copresence/test/audio_test_support.h"
-#include "media/base/audio_bus.h"
-#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using ::testing::_;
-using ::testing::Le;
-
 namespace copresence {
 
-class TestAudioPlayer : public AudioPlayer {
- public:
-  TestAudioPlayer() {}
-  ~TestAudioPlayer() override {}
+namespace {
 
-  // AudioPlayer overrides:
-  void Initialize() override {}
-  void Play(
-      const scoped_refptr<media::AudioBusRefCounted>& /* samples */) override {
-    set_is_playing(true);
-  }
-  void Stop() override { set_is_playing(false); }
-  void Finalize() override { delete this; }
+// Callback stubs to pass into the directive handler.
+void DecodeSamples(AudioType, const std::string&) {
+}
+void EncodeToken(const std::string&,
+                 AudioType,
+                 const AudioManager::SamplesCallback&) {
+}
+
+}  // namespace
+
+class AudioManagerStub final : public AudioManager {
+ public:
+  AudioManagerStub() {}
+  virtual ~AudioManagerStub() {}
+
+  // AudioManager overrides:
+  void Initialize(const DecodeSamplesCallback& decode_cb,
+                  const EncodeTokenCallback& encode_cb) override {}
+  void StartPlaying(AudioType type) override { playing_[type] = true; }
+  void StopPlaying(AudioType type) override { playing_[type] = false; }
+  void StartRecording(AudioType type) override { recording_[type] = true; }
+  void StopRecording(AudioType type) override { recording_[type] = false; }
+  void SetToken(AudioType type, const std::string& url_unsafe_token) override {}
+  const std::string GetToken(AudioType type) override { return std::string(); }
+  bool IsRecording(AudioType type) override { return recording_[type]; }
+  bool IsPlaying(AudioType type) override { return playing_[type]; }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(TestAudioPlayer);
-};
+  // Indexed using enum AudioType.
+  bool playing_[2];
+  bool recording_[2];
 
-class TestAudioRecorder : public AudioRecorder {
- public:
-  TestAudioRecorder() : AudioRecorder(AudioRecorder::DecodeSamplesCallback()) {}
-  ~TestAudioRecorder() override {}
-
-  // AudioRecorder overrides:
-  void Initialize() override {}
-  void Record() override { set_is_recording(true); }
-  void Stop() override { set_is_recording(false); }
-  void Finalize() override { delete this; }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestAudioRecorder);
+  DISALLOW_COPY_AND_ASSIGN(AudioManagerStub);
 };
 
 class AudioDirectiveHandlerTest : public testing::Test {
  public:
   AudioDirectiveHandlerTest()
-      : directive_handler_(new AudioDirectiveHandler(
-            AudioRecorder::DecodeSamplesCallback(),
-            base::Bind(&AudioDirectiveHandlerTest::EncodeToken,
-                       base::Unretained(this)))) {
-    directive_handler_->set_player_audible_for_testing(new TestAudioPlayer());
-    directive_handler_->set_player_inaudible_for_testing(new TestAudioPlayer());
-    directive_handler_->set_recorder_for_testing(new TestAudioRecorder());
+      : directive_handler_(new AudioDirectiveHandler()) {
+    scoped_ptr<AudioManagerStub> manager(new AudioManagerStub);
+    manager_ptr_ = manager.get();
+    directive_handler_->set_audio_manager_for_testing(manager.Pass());
+    directive_handler_->Initialize(base::Bind(&DecodeSamples),
+                                   base::Bind(&EncodeToken));
   }
   virtual ~AudioDirectiveHandlerTest() {}
 
   void DirectiveAdded() {}
 
  protected:
-  void EncodeToken(const std::string& token,
-                   bool audible,
-                   const AudioDirectiveHandler::SamplesCallback& callback) {
-    callback.Run(
-        token, audible, CreateRandomAudioRefCounted(0x1337, 1, 0x7331));
-  }
-
   copresence::TokenInstruction CreateTransmitInstruction(
       const std::string& token,
       bool audible) {
@@ -85,17 +76,25 @@
     return instruction;
   }
 
-  copresence::TokenInstruction CreateReceiveInstruction() {
+  copresence::TokenInstruction CreateReceiveInstruction(bool audible) {
     copresence::TokenInstruction instruction;
     instruction.set_token_instruction_type(copresence::RECEIVE);
+    instruction.set_medium(audible ? AUDIO_AUDIBLE_DTMF
+                                   : AUDIO_ULTRASOUND_PASSBAND);
     return instruction;
   }
 
+  bool IsPlaying(AudioType type) { return manager_ptr_->IsPlaying(type); }
+
+  bool IsRecording(AudioType type) { return manager_ptr_->IsRecording(type); }
+
   // This order is important. We want the message loop to get created before
   // our the audio directive handler since the directive list ctor (invoked
   // from the directive handler ctor) will post tasks.
   base::MessageLoop message_loop_;
   scoped_ptr<AudioDirectiveHandler> directive_handler_;
+  // Unowned.
+  AudioManagerStub* manager_ptr_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandlerTest);
@@ -110,30 +109,34 @@
   directive_handler_->AddInstruction(
       CreateTransmitInstruction("token", false), "op_id2", kTtl);
   directive_handler_->AddInstruction(
-      CreateReceiveInstruction(), "op_id1", kTtl);
+      CreateReceiveInstruction(false), "op_id1", kTtl);
   directive_handler_->AddInstruction(
-      CreateReceiveInstruction(), "op_id2", kTtl);
+      CreateReceiveInstruction(true), "op_id2", kTtl);
   directive_handler_->AddInstruction(
-      CreateReceiveInstruction(), "op_id3", kTtl);
+      CreateReceiveInstruction(false), "op_id3", kTtl);
 
-  EXPECT_EQ(true, directive_handler_->player_audible_->IsPlaying());
-  EXPECT_EQ(true, directive_handler_->player_inaudible_->IsPlaying());
-  EXPECT_EQ(true, directive_handler_->recorder_->IsRecording());
+  EXPECT_TRUE(IsPlaying(AUDIBLE));
+  EXPECT_TRUE(IsPlaying(INAUDIBLE));
+  EXPECT_TRUE(IsRecording(AUDIBLE));
+  EXPECT_TRUE(IsRecording(INAUDIBLE));
 
   directive_handler_->RemoveInstructions("op_id1");
-  EXPECT_FALSE(directive_handler_->player_audible_->IsPlaying());
-  EXPECT_EQ(true, directive_handler_->player_inaudible_->IsPlaying());
-  EXPECT_EQ(true, directive_handler_->recorder_->IsRecording());
+  EXPECT_FALSE(IsPlaying(AUDIBLE));
+  EXPECT_TRUE(IsPlaying(INAUDIBLE));
+  EXPECT_TRUE(IsRecording(AUDIBLE));
+  EXPECT_TRUE(IsRecording(INAUDIBLE));
 
   directive_handler_->RemoveInstructions("op_id2");
-  EXPECT_FALSE(directive_handler_->player_inaudible_->IsPlaying());
-  EXPECT_EQ(true, directive_handler_->recorder_->IsRecording());
+  EXPECT_FALSE(IsPlaying(INAUDIBLE));
+  EXPECT_FALSE(IsRecording(AUDIBLE));
+  EXPECT_TRUE(IsRecording(INAUDIBLE));
 
   directive_handler_->RemoveInstructions("op_id3");
-  EXPECT_FALSE(directive_handler_->recorder_->IsRecording());
+  EXPECT_FALSE(IsRecording(INAUDIBLE));
 }
 
 // TODO(rkc): Write more tests that check more convoluted sequences of
 // transmits/receives.
+// TODO(rkc): Write tests to move time forward and test functionality.
 
 }  // namespace copresence
diff --git a/components/copresence/handlers/audio/audio_directive_list.cc b/components/copresence/handlers/audio/audio_directive_list.cc
index 2dc505b..8b9b76ec 100644
--- a/components/copresence/handlers/audio/audio_directive_list.cc
+++ b/components/copresence/handlers/audio/audio_directive_list.cc
@@ -7,6 +7,8 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/time/default_tick_clock.h"
+#include "base/time/tick_clock.h"
 #include "base/time/time.h"
 
 namespace copresence {
@@ -16,11 +18,12 @@
 AudioDirective::AudioDirective() {
 }
 
-AudioDirective::AudioDirective(const std::string& op_id, base::Time end_time)
+AudioDirective::AudioDirective(const std::string& op_id,
+                               base::TimeTicks end_time)
     : op_id(op_id), end_time(end_time) {
 }
 
-AudioDirectiveList::AudioDirectiveList() {
+AudioDirectiveList::AudioDirectiveList() : clock_(new base::DefaultTickClock) {
 }
 
 AudioDirectiveList::~AudioDirectiveList() {
@@ -28,7 +31,7 @@
 
 void AudioDirectiveList::AddDirective(const std::string& op_id,
                                       base::TimeDelta ttl) {
-  base::Time end_time = base::Time::Now() + ttl;
+  base::TimeTicks end_time = clock_->NowTicks() + ttl;
 
   // In case this op is already in the list, update it instead of adding
   // it again.
@@ -62,7 +65,7 @@
   // has passed, means all our previous instructions have expired too, hence
   // clear the list.
   if (!active_directives_.empty() &&
-      active_directives_.front().end_time < base::Time::Now()) {
+      active_directives_.front().end_time < clock_->NowTicks()) {
     active_directives_.clear();
   }
 
diff --git a/components/copresence/handlers/audio/audio_directive_list.h b/components/copresence/handlers/audio/audio_directive_list.h
index 9edd89f..e9d06342 100644
--- a/components/copresence/handlers/audio/audio_directive_list.h
+++ b/components/copresence/handlers/audio/audio_directive_list.h
@@ -13,19 +13,25 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
 
+namespace base {
+class TickClock;
+}
+
 namespace media {
 class AudioBusRefCounted;
 }
 
 namespace copresence {
 
-struct AudioDirective {
+struct AudioDirective final {
   // Default ctor, required by the priority queue.
   AudioDirective();
-  AudioDirective(const std::string& op_id, base::Time end_time);
+  AudioDirective(const std::string& op_id, base::TimeTicks end_time);
 
   std::string op_id;
-  base::Time end_time;
+  // We're currently using TimeTicks to track time. This may not work for cases
+  // where your machine suspends. See crbug.com/426136
+  base::TimeTicks end_time;
 };
 
 // This class maintains a list of active audio directives. It fetches the audio
@@ -37,7 +43,7 @@
 class AudioDirectiveList {
  public:
   AudioDirectiveList();
-  virtual ~AudioDirectiveList();
+  ~AudioDirectiveList();
 
   void AddDirective(const std::string& op_id, base::TimeDelta ttl);
   void RemoveDirective(const std::string& op_id);
@@ -62,6 +68,8 @@
   // element. Only currently active directives will exist in this list.
   std::vector<AudioDirective> active_directives_;
 
+  scoped_ptr<base::TickClock> clock_;
+
   DISALLOW_COPY_AND_ASSIGN(AudioDirectiveList);
 };
 
diff --git a/components/copresence/handlers/directive_handler.cc b/components/copresence/handlers/directive_handler.cc
index e76dde6..ae0bd30 100644
--- a/components/copresence/handlers/directive_handler.cc
+++ b/components/copresence/handlers/directive_handler.cc
@@ -4,6 +4,7 @@
 
 #include "components/copresence/handlers/directive_handler.h"
 
+#include "base/logging.h"
 #include "base/time/time.h"
 #include "components/copresence/handlers/audio/audio_directive_handler.h"
 #include "components/copresence/proto/data.pb.h"
@@ -13,10 +14,10 @@
 DirectiveHandler::DirectiveHandler() {}
 
 void DirectiveHandler::Initialize(
-    const AudioRecorder::DecodeSamplesCallback& decode_cb,
-    const AudioDirectiveHandler::EncodeTokenCallback& encode_cb) {
-  audio_handler_.reset(new AudioDirectiveHandler(decode_cb, encode_cb));
-  audio_handler_->Initialize();
+    const AudioManager::DecodeSamplesCallback& decode_cb,
+    const AudioManager::EncodeTokenCallback& encode_cb) {
+  audio_handler_.reset(new AudioDirectiveHandler());
+  audio_handler_->Initialize(decode_cb, encode_cb);
 }
 
 DirectiveHandler::~DirectiveHandler() {
@@ -53,12 +54,8 @@
   audio_handler_->RemoveInstructions(op_id);
 }
 
-const std::string& DirectiveHandler::CurrentAudibleToken() const {
-  return audio_handler_->PlayingAudibleToken();
-}
-
-const std::string& DirectiveHandler::CurrentInaudibleToken() const {
-  return audio_handler_->PlayingInaudibleToken();
+const std::string DirectiveHandler::GetCurrentAudioToken(AudioType type) const {
+  return audio_handler_->PlayingToken(type);
 }
 
 }  // namespace copresence
diff --git a/components/copresence/handlers/directive_handler.h b/components/copresence/handlers/directive_handler.h
index f36aa88..b9b1a88 100644
--- a/components/copresence/handlers/directive_handler.h
+++ b/components/copresence/handlers/directive_handler.h
@@ -11,7 +11,7 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "components/copresence/handlers/audio/audio_directive_handler.h"
-#include "components/copresence/mediums/audio/audio_recorder.h"
+#include "components/copresence/mediums/audio/audio_manager.h"
 
 namespace copresence {
 
@@ -28,17 +28,15 @@
   // This function must be called before any others.
   // TODO(ckehoe): Instead of this, use a static Create() method
   //               and make the constructor private.
-  virtual void Initialize(
-      const AudioRecorder::DecodeSamplesCallback& decode_cb,
-      const AudioDirectiveHandler::EncodeTokenCallback& encode_cb);
+  virtual void Initialize(const AudioManager::DecodeSamplesCallback& decode_cb,
+                          const AudioManager::EncodeTokenCallback& encode_cb);
 
   // Adds a directive to handle.
   virtual void AddDirective(const copresence::Directive& directive);
   // Removes any directives associated with the given operation id.
   virtual void RemoveDirectives(const std::string& op_id);
 
-  const std::string& CurrentAudibleToken() const;
-  const std::string& CurrentInaudibleToken() const;
+  const std::string GetCurrentAudioToken(AudioType type) const;
 
  private:
   scoped_ptr<AudioDirectiveHandler> audio_handler_;
diff --git a/components/copresence/mediums/audio/audio_manager.h b/components/copresence/mediums/audio/audio_manager.h
new file mode 100644
index 0000000..59ad3a3f
--- /dev/null
+++ b/components/copresence/mediums/audio/audio_manager.h
@@ -0,0 +1,54 @@
+// 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 COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_MANAGER_H_
+#define COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_MANAGER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "components/copresence/public/copresence_constants.h"
+
+namespace media {
+class AudioBusRefCounted;
+}
+
+namespace copresence {
+
+class AudioManager {
+ public:
+  typedef base::Callback<void(const std::string&,
+                              AudioType,
+                              const scoped_refptr<media::AudioBusRefCounted>&)>
+      SamplesCallback;
+  typedef base::Callback<void(const std::string&,
+                              AudioType,
+                              const SamplesCallback&)> EncodeTokenCallback;
+  typedef base::Callback<void(AudioType, const std::string&)>
+      DecodeSamplesCallback;
+
+  virtual ~AudioManager() {}
+
+  // Initializes the object. Do not use this object before calling this method.
+  virtual void Initialize(const DecodeSamplesCallback& decode_cb,
+                          const EncodeTokenCallback& encode_cb) = 0;
+
+  virtual void StartPlaying(AudioType type) = 0;
+  virtual void StopPlaying(AudioType type) = 0;
+
+  virtual void StartRecording(AudioType type) = 0;
+  virtual void StopRecording(AudioType type) = 0;
+
+  virtual void SetToken(AudioType type,
+                        const std::string& url_unsafe_token) = 0;
+
+  virtual const std::string GetToken(AudioType type) = 0;
+
+  virtual bool IsRecording(AudioType type) = 0;
+  virtual bool IsPlaying(AudioType type) = 0;
+};
+
+}  // namespace copresence
+
+#endif  // COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_MANAGER_H_
diff --git a/components/copresence/mediums/audio/audio_manager_impl.cc b/components/copresence/mediums/audio/audio_manager_impl.cc
new file mode 100644
index 0000000..7670d6e
--- /dev/null
+++ b/components/copresence/mediums/audio/audio_manager_impl.cc
@@ -0,0 +1,193 @@
+// 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 "components/copresence/mediums/audio/audio_manager_impl.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/run_loop.h"
+#include "base/strings/string_util.h"
+#include "components/copresence/mediums/audio/audio_player_impl.h"
+#include "components/copresence/mediums/audio/audio_recorder_impl.h"
+#include "components/copresence/public/copresence_constants.h"
+#include "content/public/browser/browser_thread.h"
+#include "media/audio/audio_manager.h"
+#include "media/audio/audio_manager_base.h"
+#include "media/base/audio_bus.h"
+
+namespace copresence {
+
+namespace {
+
+// UrlSafe is defined as:
+// '/' represented by a '_' and '+' represented by a '-'
+// TODO(rkc): Move this processing to the whispernet wrapper.
+std::string FromUrlSafe(std::string token) {
+  base::ReplaceChars(token, "-", "+", &token);
+  base::ReplaceChars(token, "_", "/", &token);
+  return token;
+}
+
+const int kSampleExpiryTimeMs = 60 * 60 * 1000;  // 60 minutes.
+const int kMaxSamples = 10000;
+
+}  // namespace
+
+// Public methods.
+
+AudioManagerImpl::AudioManagerImpl() : recorder_(NULL) {
+  // TODO(rkc): Move all of these into initializer lists once it is allowed.
+  playing_[AUDIBLE] = false;
+  playing_[INAUDIBLE] = false;
+  recording_[AUDIBLE] = false;
+  recording_[INAUDIBLE] = false;
+
+  player_[AUDIBLE] = NULL;
+  player_[INAUDIBLE] = NULL;
+}
+
+void AudioManagerImpl::Initialize(const DecodeSamplesCallback& decode_cb,
+                                  const EncodeTokenCallback& encode_cb) {
+  samples_cache_.resize(2);
+  samples_cache_[AUDIBLE] = new SamplesMap(
+      base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs), kMaxSamples);
+  samples_cache_[INAUDIBLE] = new SamplesMap(
+      base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs), kMaxSamples);
+
+  decode_cb_ = decode_cb;
+  encode_cb_ = encode_cb;
+
+  if (!player_[AUDIBLE])
+    player_[AUDIBLE] = new AudioPlayerImpl();
+  player_[AUDIBLE]->Initialize();
+
+  if (!player_[INAUDIBLE])
+    player_[INAUDIBLE] = new AudioPlayerImpl();
+  player_[INAUDIBLE]->Initialize();
+
+  decode_cancelable_cb_.Reset(base::Bind(
+      &AudioManagerImpl::DecodeSamplesConnector, base::Unretained(this)));
+  if (!recorder_)
+    recorder_ = new AudioRecorderImpl();
+  recorder_->Initialize(decode_cancelable_cb_.callback());
+}
+
+AudioManagerImpl::~AudioManagerImpl() {
+  if (player_[AUDIBLE])
+    player_[AUDIBLE]->Finalize();
+  if (player_[INAUDIBLE])
+    player_[INAUDIBLE]->Finalize();
+  if (recorder_)
+    recorder_->Finalize();
+}
+
+void AudioManagerImpl::StartPlaying(AudioType type) {
+  DCHECK(type == AUDIBLE || type == INAUDIBLE);
+  playing_[type] = true;
+  // If we don't have our token encoded yet, this check will be false, for now.
+  // Once our token is encoded, OnTokenEncoded will call UpdateToken, which
+  // will call this code again (if we're still supposed to be playing).
+  if (samples_cache_[type]->HasKey(token_[type]) &&
+      !player_[type]->IsPlaying()) {
+    DCHECK(!token_[type].empty());
+    player_[type]->Play(samples_cache_[type]->GetValue(token_[type]));
+  }
+}
+
+void AudioManagerImpl::StopPlaying(AudioType type) {
+  DCHECK(type == AUDIBLE || type == INAUDIBLE);
+  playing_[type] = false;
+  if (player_[type]->IsPlaying())
+    player_[type]->Stop();
+}
+
+void AudioManagerImpl::StartRecording(AudioType type) {
+  DCHECK(type == AUDIBLE || type == INAUDIBLE);
+  recording_[type] = true;
+  if (!recorder_->IsRecording())
+    recorder_->Record();
+}
+
+void AudioManagerImpl::StopRecording(AudioType type) {
+  DCHECK(type == AUDIBLE || type == INAUDIBLE);
+  recording_[type] = false;
+  if (recorder_->IsRecording())
+    recorder_->Stop();
+}
+
+void AudioManagerImpl::SetToken(AudioType type,
+                                const std::string& url_unsafe_token) {
+  DCHECK(type == AUDIBLE || type == INAUDIBLE);
+  std::string token = FromUrlSafe(url_unsafe_token);
+  if (!samples_cache_[type]->HasKey(token)) {
+    // We're destructed by the destruction chain of
+    // RpcHandler->DirectiveHandler->AudioDirectiveHandler. The RpcHandler
+    // unsets any callbacks that were set on the Whispernet client before it
+    // destructs, unsetting this callback too - making unretained safe to use.
+    encode_cb_.Run(
+        token,
+        type,
+        base::Bind(&AudioManagerImpl::OnTokenEncoded, base::Unretained(this)));
+  } else {
+    UpdateToken(type, token);
+  }
+}
+
+const std::string AudioManagerImpl::GetToken(AudioType type) {
+  return token_[type];
+}
+
+bool AudioManagerImpl::IsRecording(AudioType type) {
+  return recording_[type];
+}
+
+bool AudioManagerImpl::IsPlaying(AudioType type) {
+  return playing_[type];
+}
+
+// Private methods.
+
+void AudioManagerImpl::OnTokenEncoded(
+    const std::string& token,
+    AudioType type,
+    const scoped_refptr<media::AudioBusRefCounted>& samples) {
+  samples_cache_[type]->Add(token, samples);
+  UpdateToken(type, token);
+}
+
+void AudioManagerImpl::UpdateToken(AudioType type, const std::string& token) {
+  DCHECK(type == AUDIBLE || type == INAUDIBLE);
+  if (token_[type] == token)
+    return;
+
+  // Update token.
+  token_[type] = token;
+
+  // If we are supposed to be playing this token type at this moment, switch
+  // out playback with the new samples.
+  if (playing_[type]) {
+    if (player_[type]->IsPlaying())
+      player_[type]->Stop();
+    StartPlaying(type);
+  }
+}
+
+void AudioManagerImpl::DecodeSamplesConnector(const std::string& samples) {
+  AudioType decode_type = AUDIO_TYPE_UNKNOWN;
+
+  if (recording_[AUDIBLE] && recording_[INAUDIBLE])
+    decode_type = BOTH;
+  else if (recording_[AUDIBLE])
+    decode_type = AUDIBLE;
+  else if (recording_[INAUDIBLE])
+    decode_type = INAUDIBLE;
+
+  decode_cb_.Run(decode_type, samples);
+}
+
+}  // namespace copresence
diff --git a/components/copresence/mediums/audio/audio_manager_impl.h b/components/copresence/mediums/audio/audio_manager_impl.h
new file mode 100644
index 0000000..b1f40ae
--- /dev/null
+++ b/components/copresence/mediums/audio/audio_manager_impl.h
@@ -0,0 +1,107 @@
+// 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 COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_MANAGER_IMPL_H_
+#define COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_MANAGER_IMPL_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/cancelable_callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_vector.h"
+#include "components/copresence/mediums/audio/audio_manager.h"
+#include "components/copresence/public/copresence_constants.h"
+#include "components/copresence/timed_map.h"
+
+namespace copresence {
+
+class AudioPlayer;
+class AudioRecorder;
+
+// The AudioManagerImpl class manages the playback and recording of tokens. Once
+// playback or recording is started, it is up to the audio manager to handle
+// the specifics of how this is done. In the future, for example, this class
+// may pause recording and playback to implement carrier sense.
+class AudioManagerImpl final : public AudioManager {
+ public:
+  AudioManagerImpl();
+  ~AudioManagerImpl();
+
+  // AudioManager overrides:
+  void Initialize(const DecodeSamplesCallback& decode_cb,
+                  const EncodeTokenCallback& encode_cb) override;
+  void StartPlaying(AudioType type) override;
+  void StopPlaying(AudioType type) override;
+  void StartRecording(AudioType type) override;
+  void StopRecording(AudioType type) override;
+  void SetToken(AudioType type, const std::string& url_unsafe_token) override;
+  const std::string GetToken(AudioType type) override;
+  bool IsRecording(AudioType type) override;
+  bool IsPlaying(AudioType type) override;
+
+  void set_player_for_testing(AudioType type, AudioPlayer* player) {
+    player_[type] = player;
+  }
+  void set_recorder_for_testing(AudioRecorder* recorder) {
+    recorder_ = recorder;
+  }
+
+ private:
+  typedef TimedMap<std::string, scoped_refptr<media::AudioBusRefCounted>>
+      SamplesMap;
+
+  // This is the method that the whispernet client needs to call to return
+  // samples to us.
+  void OnTokenEncoded(const std::string& token,
+                      AudioType type,
+                      const scoped_refptr<media::AudioBusRefCounted>& samples);
+
+  // Update our currently playing token with the new token. Change the playing
+  // samples if needed. Prerequisite: Samples corresponding to this token
+  // should already be in the samples cache.
+  void UpdateToken(AudioType type, const std::string& token);
+
+  // Connector callback to forward the audio samples to Whispernet, based on
+  // the type of recording we've been instructed to do.
+  void DecodeSamplesConnector(const std::string& samples);
+
+  // Callbacks to speak with whispernet.
+  DecodeSamplesCallback decode_cb_;
+  EncodeTokenCallback encode_cb_;
+
+  // This cancelable callback is passed to the recorder. The recorder's
+  // destruction will happen on the audio thread, so it can outlive us.
+  base::CancelableCallback<void(const std::string&)> decode_cancelable_cb_;
+
+  // We use the AudioType enum to index into all our data structures that work
+  // on values for both audible and inaudible.
+  static_assert(AUDIBLE == 0, "AudioType::AUDIBLE should be 0.");
+  static_assert(INAUDIBLE == 1, "AudioType::INAUDIBLE should be 1.");
+
+  // Indexed using enum AudioType.
+  bool playing_[2];
+  bool recording_[2];
+
+  // AudioPlayer and AudioRecorder objects are self-deleting. When we call
+  // Finalize on them, they clean themselves up on the Audio thread.
+  // Indexed using enum AudioType.
+  AudioPlayer* player_[2];
+  AudioRecorder* recorder_;
+
+  // Indexed using enum AudioType.
+  std::string token_[2];
+
+  // Cache that holds the encoded samples. After reaching its limit, the cache
+  // expires the oldest samples first.
+  // Indexed using enum AudioType.
+  ScopedVector<SamplesMap> samples_cache_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioManagerImpl);
+};
+
+}  // namespace copresence
+
+#endif  // COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_MANAGER_IMPL_H_
diff --git a/components/copresence/mediums/audio/audio_manager_unittest.cc b/components/copresence/mediums/audio/audio_manager_unittest.cc
new file mode 100644
index 0000000..104b1fb
--- /dev/null
+++ b/components/copresence/mediums/audio/audio_manager_unittest.cc
@@ -0,0 +1,151 @@
+// 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 "components/copresence/mediums/audio/audio_manager.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "components/copresence/mediums/audio/audio_manager_impl.h"
+#include "components/copresence/mediums/audio/audio_player.h"
+#include "components/copresence/mediums/audio/audio_recorder.h"
+#include "components/copresence/test/audio_test_support.h"
+#include "media/base/audio_bus.h"
+//#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace copresence {
+
+class AudioPlayerStub final : public AudioPlayer {
+ public:
+  AudioPlayerStub() : is_playing_(false) {}
+  virtual ~AudioPlayerStub() {}
+
+  // AudioPlayer overrides:
+  void Initialize() override {}
+  void Play(const scoped_refptr<media::AudioBusRefCounted>&) override {
+    is_playing_ = true;
+  }
+  void Stop() override { is_playing_ = false; }
+  void Finalize() override { delete this; }
+  bool IsPlaying() override { return is_playing_; }
+
+ private:
+  bool is_playing_;
+  DISALLOW_COPY_AND_ASSIGN(AudioPlayerStub);
+};
+
+class AudioRecorderStub final : public AudioRecorder {
+ public:
+  AudioRecorderStub() : is_recording_(false) {}
+  virtual ~AudioRecorderStub() {}
+
+  // AudioRecorder overrides:
+  void Initialize(const RecordedSamplesCallback& cb) override { cb_ = cb; }
+  void Record() override { is_recording_ = true; }
+  void Stop() override { is_recording_ = false; }
+  void Finalize() override { delete this; }
+  bool IsRecording() override { return is_recording_; }
+
+  void TriggerDecodeRequest() {
+    if (!cb_.is_null())
+      cb_.Run(std::string(0x1337, 'a'));
+  }
+
+ private:
+  RecordedSamplesCallback cb_;
+  bool is_recording_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioRecorderStub);
+};
+
+class AudioManagerTest : public testing::Test {
+ public:
+  AudioManagerTest()
+      : audio_manager_(new AudioManagerImpl()),
+        audible_player_(new AudioPlayerStub),
+        inaudible_player_(new AudioPlayerStub),
+        recorder_(new AudioRecorderStub),
+        last_received_decode_type_(AUDIO_TYPE_UNKNOWN) {
+    audio_manager_->set_player_for_testing(AUDIBLE, audible_player_);
+    audio_manager_->set_player_for_testing(INAUDIBLE, inaudible_player_);
+    audio_manager_->set_recorder_for_testing(recorder_);
+    audio_manager_->Initialize(
+        base::Bind(&AudioManagerTest::DecodeSamples, base::Unretained(this)),
+        base::Bind(&AudioManagerTest::EncodeToken, base::Unretained(this)));
+  }
+  virtual ~AudioManagerTest() {}
+
+ protected:
+  void EncodeToken(const std::string& token,
+                   AudioType audible,
+                   const AudioManager::SamplesCallback& callback) {
+    callback.Run(
+        token, audible, CreateRandomAudioRefCounted(0x1337, 1, 0x7331));
+  }
+
+  void DecodeSamples(AudioType type, const std::string& /* samples */) {
+    last_received_decode_type_ = type;
+  }
+
+  base::MessageLoop message_loop_;
+  scoped_ptr<AudioManagerImpl> audio_manager_;
+
+  // These will be deleted by |audio_manager_|'s dtor calling finalize on them.
+  AudioPlayerStub* audible_player_;
+  AudioPlayerStub* inaudible_player_;
+  AudioRecorderStub* recorder_;
+
+  AudioType last_received_decode_type_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AudioManagerTest);
+};
+
+TEST_F(AudioManagerTest, Basic) {
+  audio_manager_->StartPlaying(AUDIBLE);
+  EXPECT_TRUE(audio_manager_->IsPlaying(AUDIBLE));
+  EXPECT_FALSE(audio_manager_->IsPlaying(INAUDIBLE));
+
+  audio_manager_->StopPlaying(AUDIBLE);
+  EXPECT_FALSE(audio_manager_->IsPlaying(AUDIBLE));
+
+  audio_manager_->StartRecording(INAUDIBLE);
+  EXPECT_TRUE(audio_manager_->IsRecording(INAUDIBLE));
+  EXPECT_FALSE(audio_manager_->IsRecording(AUDIBLE));
+
+  audio_manager_->StopRecording(INAUDIBLE);
+  EXPECT_FALSE(audio_manager_->IsRecording(INAUDIBLE));
+}
+
+TEST_F(AudioManagerTest, EncodeToken) {
+  audio_manager_->StartPlaying(AUDIBLE);
+  // No token yet, player shouldn't be playing.
+  EXPECT_FALSE(audible_player_->IsPlaying());
+
+  audio_manager_->SetToken(INAUDIBLE, "abcd");
+  // No *audible* token yet, so player still shouldn't be playing.
+  EXPECT_FALSE(audible_player_->IsPlaying());
+
+  audio_manager_->SetToken(AUDIBLE, "abcd");
+  EXPECT_TRUE(audible_player_->IsPlaying());
+}
+
+TEST_F(AudioManagerTest, Record) {
+  recorder_->TriggerDecodeRequest();
+  EXPECT_EQ(AUDIO_TYPE_UNKNOWN, last_received_decode_type_);
+
+  audio_manager_->StartRecording(AUDIBLE);
+  recorder_->TriggerDecodeRequest();
+  EXPECT_EQ(AUDIBLE, last_received_decode_type_);
+
+  audio_manager_->StartRecording(INAUDIBLE);
+  recorder_->TriggerDecodeRequest();
+  EXPECT_EQ(BOTH, last_received_decode_type_);
+
+  audio_manager_->StopRecording(AUDIBLE);
+  recorder_->TriggerDecodeRequest();
+  EXPECT_EQ(INAUDIBLE, last_received_decode_type_);
+}
+
+}  // namespace copresence
diff --git a/components/copresence/mediums/audio/audio_player.h b/components/copresence/mediums/audio/audio_player.h
index e2bb64d..3c92e5d 100644
--- a/components/copresence/mediums/audio/audio_player.h
+++ b/components/copresence/mediums/audio/audio_player.h
@@ -7,88 +7,36 @@
 
 #include <vector>
 
-#include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "media/audio/audio_io.h"
 
 namespace media {
-class AudioBus;
 class AudioBusRefCounted;
 }
 
 namespace copresence {
 
-// The AudioPlayer class will play a set of samples till it is told to stop.
-class AudioPlayer : public media::AudioOutputStream::AudioSourceCallback {
+// The AudioPlayerImpl class will play a set of samples till it is told to stop.
+class AudioPlayer {
  public:
-  AudioPlayer();
-
   // Initializes the object. Do not use this object before calling this method.
-  virtual void Initialize();
+  virtual void Initialize() = 0;
 
   // Play the given samples. These samples will keep on being played in a loop
   // till we explicitly tell the player to stop playing.
-  virtual void Play(const scoped_refptr<media::AudioBusRefCounted>& samples);
+  virtual void Play(
+      const scoped_refptr<media::AudioBusRefCounted>& samples) = 0;
 
   // Stop playing.
-  virtual void Stop();
+  virtual void Stop() = 0;
 
   // Cleans up and deletes this object. Do not use object after this call.
-  virtual void Finalize();
+  virtual void Finalize() = 0;
 
-  bool IsPlaying();
-
-  // Takes ownership of the stream.
-  void set_output_stream_for_testing(
-      media::AudioOutputStream* output_stream_for_testing) {
-    output_stream_for_testing_.reset(output_stream_for_testing);
-  }
+  virtual bool IsPlaying() = 0;
 
  protected:
-  ~AudioPlayer() override;
-  void set_is_playing(bool is_playing) { is_playing_ = is_playing; }
-
- private:
-  friend class AudioPlayerTest;
-  FRIEND_TEST_ALL_PREFIXES(AudioPlayerTest, BasicPlayAndStop);
-  FRIEND_TEST_ALL_PREFIXES(AudioPlayerTest, OutOfOrderPlayAndStopMultiple);
-
-  // Methods to do our various operations; all of these need to be run on the
-  // audio thread.
-  void InitializeOnAudioThread();
-  void PlayOnAudioThread(
-      const scoped_refptr<media::AudioBusRefCounted>& samples);
-  void StopOnAudioThread();
-  void StopAndCloseOnAudioThread();
-  void FinalizeOnAudioThread();
-
-  // AudioOutputStream::AudioSourceCallback overrides:
-  // Following methods could be called from *ANY* thread.
-  int OnMoreData(media::AudioBus* dest, uint32 total_bytes_delay) override;
-  void OnError(media::AudioOutputStream* stream) override;
-
-  // Flushes the audio loop, making sure that any queued operations are
-  // performed.
-  void FlushAudioLoopForTesting();
-
-  bool is_playing_;
-
-  // Self-deleting object.
-  media::AudioOutputStream* stream_;
-
-  scoped_ptr<media::AudioOutputStream> output_stream_for_testing_;
-
-  // All fields below here are protected by this lock.
-  base::Lock state_lock_;
-
-  scoped_refptr<media::AudioBusRefCounted> samples_;
-
-  // Index to the frame in the samples that we need to play next.
-  int frame_index_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioPlayer);
+  virtual ~AudioPlayer() {}
 };
 
 }  // namespace copresence
diff --git a/components/copresence/mediums/audio/audio_player.cc b/components/copresence/mediums/audio/audio_player_impl.cc
similarity index 76%
rename from components/copresence/mediums/audio/audio_player.cc
rename to components/copresence/mediums/audio/audio_player_impl.cc
index 25181b2..05c39063 100644
--- a/components/copresence/mediums/audio/audio_player.cc
+++ b/components/copresence/mediums/audio/audio_player_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/copresence/mediums/audio/audio_player.h"
+#include "components/copresence/mediums/audio/audio_player_impl.h"
 
 #include <algorithm>
 #include <string>
@@ -28,47 +28,49 @@
 
 // Public methods.
 
-AudioPlayer::AudioPlayer()
+AudioPlayerImpl::AudioPlayerImpl()
     : is_playing_(false), stream_(NULL), frame_index_(0) {
 }
 
-AudioPlayer::~AudioPlayer() {
+AudioPlayerImpl::~AudioPlayerImpl() {
 }
 
-void AudioPlayer::Initialize() {
+void AudioPlayerImpl::Initialize() {
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioPlayer::InitializeOnAudioThread,
+      base::Bind(&AudioPlayerImpl::InitializeOnAudioThread,
                  base::Unretained(this)));
 }
 
-void AudioPlayer::Play(
+void AudioPlayerImpl::Play(
     const scoped_refptr<media::AudioBusRefCounted>& samples) {
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(
-          &AudioPlayer::PlayOnAudioThread, base::Unretained(this), samples));
+      base::Bind(&AudioPlayerImpl::PlayOnAudioThread,
+                 base::Unretained(this),
+                 samples));
 }
 
-void AudioPlayer::Stop() {
+void AudioPlayerImpl::Stop() {
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioPlayer::StopOnAudioThread, base::Unretained(this)));
+      base::Bind(&AudioPlayerImpl::StopOnAudioThread, base::Unretained(this)));
 }
 
-bool AudioPlayer::IsPlaying() {
+bool AudioPlayerImpl::IsPlaying() {
   return is_playing_;
 }
 
-void AudioPlayer::Finalize() {
+void AudioPlayerImpl::Finalize() {
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioPlayer::FinalizeOnAudioThread, base::Unretained(this)));
+      base::Bind(&AudioPlayerImpl::FinalizeOnAudioThread,
+                 base::Unretained(this)));
 }
 
 // Private methods.
 
-void AudioPlayer::InitializeOnAudioThread() {
+void AudioPlayerImpl::InitializeOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   stream_ = output_stream_for_testing_
                 ? output_stream_for_testing_.get()
@@ -92,7 +94,7 @@
   stream_->SetVolume(kOutputVolumePercent);
 }
 
-void AudioPlayer::PlayOnAudioThread(
+void AudioPlayerImpl::PlayOnAudioThread(
     const scoped_refptr<media::AudioBusRefCounted>& samples) {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   if (!stream_)
@@ -112,7 +114,7 @@
   stream_->Start(this);
 }
 
-void AudioPlayer::StopOnAudioThread() {
+void AudioPlayerImpl::StopOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   if (!stream_)
     return;
@@ -121,7 +123,7 @@
   is_playing_ = false;
 }
 
-void AudioPlayer::StopAndCloseOnAudioThread() {
+void AudioPlayerImpl::StopAndCloseOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   if (!stream_)
     return;
@@ -134,14 +136,14 @@
   is_playing_ = false;
 }
 
-void AudioPlayer::FinalizeOnAudioThread() {
+void AudioPlayerImpl::FinalizeOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   StopAndCloseOnAudioThread();
   delete this;
 }
 
-int AudioPlayer::OnMoreData(media::AudioBus* dest,
-                            uint32 /* total_bytes_delay */) {
+int AudioPlayerImpl::OnMoreData(media::AudioBus* dest,
+                                uint32 /* total_bytes_delay */) {
   base::AutoLock al(state_lock_);
   // Continuously play our samples till explicitly told to stop.
   const int leftover_frames = samples_->frames() - frame_index_;
@@ -160,15 +162,15 @@
   return dest->frames();
 }
 
-void AudioPlayer::OnError(media::AudioOutputStream* /* stream */) {
+void AudioPlayerImpl::OnError(media::AudioOutputStream* /* stream */) {
   LOG(ERROR) << "Error during system sound reproduction.";
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioPlayer::StopAndCloseOnAudioThread,
+      base::Bind(&AudioPlayerImpl::StopAndCloseOnAudioThread,
                  base::Unretained(this)));
 }
 
-void AudioPlayer::FlushAudioLoopForTesting() {
+void AudioPlayerImpl::FlushAudioLoopForTesting() {
   if (media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread())
     return;
 
@@ -177,7 +179,7 @@
   base::RunLoop rl;
   media::AudioManager::Get()->GetTaskRunner()->PostTaskAndReply(
       FROM_HERE,
-      base::Bind(base::IgnoreResult(&AudioPlayer::FlushAudioLoopForTesting),
+      base::Bind(base::IgnoreResult(&AudioPlayerImpl::FlushAudioLoopForTesting),
                  base::Unretained(this)),
       rl.QuitClosure());
   rl.Run();
diff --git a/components/copresence/mediums/audio/audio_player_impl.h b/components/copresence/mediums/audio/audio_player_impl.h
new file mode 100644
index 0000000..84e0753
--- /dev/null
+++ b/components/copresence/mediums/audio/audio_player_impl.h
@@ -0,0 +1,89 @@
+// 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 COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_PLAYER_IMPL_H_
+#define COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_PLAYER_IMPL_H_
+
+#include <vector>
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "components/copresence/mediums/audio/audio_player.h"
+#include "media/audio/audio_io.h"
+
+namespace media {
+class AudioBus;
+class AudioBusRefCounted;
+}
+
+namespace copresence {
+
+// The AudioPlayerImpl class will play a set of samples till it is told to stop.
+class AudioPlayerImpl final
+    : public AudioPlayer,
+      public media::AudioOutputStream::AudioSourceCallback {
+ public:
+  AudioPlayerImpl();
+
+  // AudioPlayer overrides:
+  void Initialize() override;
+  void Play(const scoped_refptr<media::AudioBusRefCounted>& samples) override;
+  void Stop() override;
+  void Finalize() override;
+  bool IsPlaying() override;
+
+  // Takes ownership of the stream.
+  void set_output_stream_for_testing(
+      media::AudioOutputStream* output_stream_for_testing) {
+    output_stream_for_testing_.reset(output_stream_for_testing);
+  }
+
+ private:
+  friend class AudioPlayerTest;
+  FRIEND_TEST_ALL_PREFIXES(AudioPlayerTest, BasicPlayAndStop);
+  FRIEND_TEST_ALL_PREFIXES(AudioPlayerTest, OutOfOrderPlayAndStopMultiple);
+
+  virtual ~AudioPlayerImpl();
+
+  // Methods to do our various operations; all of these need to be run on the
+  // audio thread.
+  void InitializeOnAudioThread();
+  void PlayOnAudioThread(
+      const scoped_refptr<media::AudioBusRefCounted>& samples);
+  void StopOnAudioThread();
+  void StopAndCloseOnAudioThread();
+  void FinalizeOnAudioThread();
+
+  // AudioOutputStream::AudioSourceCallback overrides:
+  // Following methods could be called from *ANY* thread.
+  int OnMoreData(media::AudioBus* dest, uint32 total_bytes_delay) override;
+  void OnError(media::AudioOutputStream* stream) override;
+
+  // Flushes the audio loop, making sure that any queued operations are
+  // performed.
+  void FlushAudioLoopForTesting();
+
+  bool is_playing_;
+
+  // Self-deleting object.
+  media::AudioOutputStream* stream_;
+
+  scoped_ptr<media::AudioOutputStream> output_stream_for_testing_;
+
+  // All fields below here are protected by this lock.
+  base::Lock state_lock_;
+
+  scoped_refptr<media::AudioBusRefCounted> samples_;
+
+  // Index to the frame in the samples that we need to play next.
+  int frame_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioPlayerImpl);
+};
+
+}  // namespace copresence
+
+#endif  // COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_PLAYER_IMPL_H_
diff --git a/components/copresence/mediums/audio/audio_player_unittest.cc b/components/copresence/mediums/audio/audio_player_unittest.cc
index 97d58e5..06a095d 100644
--- a/components/copresence/mediums/audio/audio_player_unittest.cc
+++ b/components/copresence/mediums/audio/audio_player_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/memory/weak_ptr.h"
+#include "components/copresence/mediums/audio/audio_player_impl.h"
 #include "components/copresence/public/copresence_constants.h"
 #include "components/copresence/test/audio_test_support.h"
 #include "media/audio/audio_manager.h"
@@ -81,7 +82,7 @@
 
   void CreatePlayer() {
     DeletePlayer();
-    player_ = new AudioPlayer();
+    player_ = new AudioPlayerImpl();
     player_->set_output_stream_for_testing(new TestAudioOutputStream(
         kDefaultFrameCount,
         kMaxFrameCount,
@@ -129,7 +130,8 @@
   scoped_ptr<media::AudioBus> buffer_;
   int buffer_index_;
 
-  AudioPlayer* player_;
+  // Deleted by calling Finalize() on the object.
+  AudioPlayerImpl* player_;
   base::MessageLoop message_loop_;
 };
 
diff --git a/components/copresence/mediums/audio/audio_recorder.h b/components/copresence/mediums/audio/audio_recorder.h
index e554f01..4dfe0a1 100644
--- a/components/copresence/mediums/audio/audio_recorder.h
+++ b/components/copresence/mediums/audio/audio_recorder.h
@@ -14,101 +14,26 @@
 #include "media/audio/audio_parameters.h"
 #include "media/base/audio_converter.h"
 
-namespace base {
-class MessageLoop;
-}
-
-namespace media {
-class AudioBus;
-}
-
 namespace copresence {
 
 // The AudioRecorder class will record audio until told to stop.
-class AudioRecorder : public media::AudioInputStream::AudioInputCallback,
-                      public media::AudioConverter::InputCallback {
+class AudioRecorder {
  public:
-  typedef base::Callback<void(const std::string&)> DecodeSamplesCallback;
-
-  explicit AudioRecorder(const DecodeSamplesCallback& decode_callback);
+  typedef base::Callback<void(const std::string&)> RecordedSamplesCallback;
 
   // Initializes the object. Do not use this object before calling this method.
-  virtual void Initialize();
+  virtual void Initialize(const RecordedSamplesCallback& decode_callback) = 0;
 
-  virtual void Record();
-  virtual void Stop();
+  virtual void Record() = 0;
+  virtual void Stop() = 0;
 
   // Cleans up and deletes this object. Do not use object after this call.
-  virtual void Finalize();
+  virtual void Finalize() = 0;
 
-  bool IsRecording();
-
-  // Takes ownership of the stream.
-  void set_input_stream_for_testing(
-      media::AudioInputStream* input_stream_for_testing) {
-    input_stream_for_testing_.reset(input_stream_for_testing);
-  }
-
-  // Takes ownership of the params.
-  void set_params_for_testing(media::AudioParameters* params_for_testing) {
-    params_for_testing_.reset(params_for_testing);
-  }
+  virtual bool IsRecording() = 0;
 
  protected:
-  ~AudioRecorder() override;
-  void set_is_recording(bool is_recording) { is_recording_ = is_recording; }
-
- private:
-  friend class AudioRecorderTest;
-  FRIEND_TEST_ALL_PREFIXES(AudioRecorderTest, BasicRecordAndStop);
-  FRIEND_TEST_ALL_PREFIXES(AudioRecorderTest, OutOfOrderRecordAndStopMultiple);
-
-  // Methods to do our various operations; all of these need to be run on the
-  // audio thread.
-  void InitializeOnAudioThread();
-  void RecordOnAudioThread();
-  void StopOnAudioThread();
-  void StopAndCloseOnAudioThread();
-  void FinalizeOnAudioThread();
-
-  // AudioInputStream::AudioInputCallback overrides:
-  // Called by the audio recorder when a full packet of audio data is
-  // available. This is called from a special audio thread and the
-  // implementation should return as soon as possible.
-  void OnData(media::AudioInputStream* stream,
-              const media::AudioBus* source,
-              uint32 hardware_delay_bytes,
-              double volume) override;
-  void OnError(media::AudioInputStream* stream) override;
-
-  // AudioConverter::InputCallback overrides:
-  double ProvideInput(media::AudioBus* dest,
-                      base::TimeDelta buffer_delay) override;
-
-  // Flushes the audio loop, making sure that any queued operations are
-  // performed.
-  void FlushAudioLoopForTesting();
-
-  bool is_recording_;
-
-  media::AudioInputStream* stream_;
-  DecodeSamplesCallback decode_callback_;
-
-  // ProvideInput will use this buffer as its source.
-  const media::AudioBus* temp_conversion_buffer_;
-
-  // Outside of the ctor/Initialize method, only access the next variables on
-  // the recording thread.
-  scoped_ptr<media::AudioBus> buffer_;
-  int total_buffer_frames_;
-  int buffer_frame_index_;
-
-  scoped_ptr<media::AudioConverter> converter_;
-
-  scoped_ptr<media::AudioInputStream> input_stream_for_testing_;
-  scoped_ptr<media::AudioParameters> params_for_testing_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioRecorder);
+  virtual ~AudioRecorder() {};
 };
 
 }  // namespace copresence
diff --git a/components/copresence/mediums/audio/audio_recorder.cc b/components/copresence/mediums/audio/audio_recorder_impl.cc
similarity index 79%
rename from components/copresence/mediums/audio/audio_recorder.cc
rename to components/copresence/mediums/audio/audio_recorder_impl.cc
index 0946ba8..f919bccb9 100644
--- a/components/copresence/mediums/audio/audio_recorder.cc
+++ b/components/copresence/mediums/audio/audio_recorder_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/copresence/mediums/audio/audio_recorder.h"
+#include "components/copresence/mediums/audio/audio_recorder_impl.h"
 
 #include <algorithm>
 #include <vector>
@@ -38,8 +38,9 @@
 // Called every kProcessIntervalMs to process the recorded audio. This
 // converts our samples to the required sample rate, interleaves the samples
 // and sends them to the whispernet decoder to process.
-void ProcessSamples(scoped_ptr<media::AudioBus> bus,
-                    const AudioRecorder::DecodeSamplesCallback& callback) {
+void ProcessSamples(
+    scoped_ptr<media::AudioBus> bus,
+    const AudioRecorderImpl::RecordedSamplesCallback& callback) {
   std::string samples;
   AudioBusToString(bus.Pass(), &samples);
   content::BrowserThread::PostTask(
@@ -50,50 +51,54 @@
 
 // Public methods.
 
-AudioRecorder::AudioRecorder(const DecodeSamplesCallback& decode_callback)
+AudioRecorderImpl::AudioRecorderImpl()
     : is_recording_(false),
       stream_(NULL),
-      decode_callback_(decode_callback),
+      temp_conversion_buffer_(NULL),
       total_buffer_frames_(0),
       buffer_frame_index_(0) {
 }
 
-void AudioRecorder::Initialize() {
+void AudioRecorderImpl::Initialize(
+    const RecordedSamplesCallback& decode_callback) {
+  decode_callback_ = decode_callback;
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioRecorder::InitializeOnAudioThread,
+      base::Bind(&AudioRecorderImpl::InitializeOnAudioThread,
                  base::Unretained(this)));
 }
 
-AudioRecorder::~AudioRecorder() {
+AudioRecorderImpl::~AudioRecorderImpl() {
 }
 
-void AudioRecorder::Record() {
+void AudioRecorderImpl::Record() {
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioRecorder::RecordOnAudioThread, base::Unretained(this)));
+      base::Bind(&AudioRecorderImpl::RecordOnAudioThread,
+                 base::Unretained(this)));
 }
 
-void AudioRecorder::Stop() {
+void AudioRecorderImpl::Stop() {
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioRecorder::StopOnAudioThread, base::Unretained(this)));
+      base::Bind(&AudioRecorderImpl::StopOnAudioThread,
+                 base::Unretained(this)));
 }
 
-bool AudioRecorder::IsRecording() {
+bool AudioRecorderImpl::IsRecording() {
   return is_recording_;
 }
 
-void AudioRecorder::Finalize() {
+void AudioRecorderImpl::Finalize() {
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioRecorder::FinalizeOnAudioThread,
+      base::Bind(&AudioRecorderImpl::FinalizeOnAudioThread,
                  base::Unretained(this)));
 }
 
 // Private methods.
 
-void AudioRecorder::InitializeOnAudioThread() {
+void AudioRecorderImpl::InitializeOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
 
   media::AudioParameters params =
@@ -134,7 +139,7 @@
   stream_->SetVolume(stream_->GetMaxVolume());
 }
 
-void AudioRecorder::RecordOnAudioThread() {
+void AudioRecorderImpl::RecordOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   if (!stream_ || is_recording_)
     return;
@@ -144,7 +149,7 @@
   is_recording_ = true;
 }
 
-void AudioRecorder::StopOnAudioThread() {
+void AudioRecorderImpl::StopOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   if (!stream_ || !is_recording_)
     return;
@@ -153,7 +158,7 @@
   is_recording_ = false;
 }
 
-void AudioRecorder::StopAndCloseOnAudioThread() {
+void AudioRecorderImpl::StopAndCloseOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   if (!stream_)
     return;
@@ -163,16 +168,16 @@
   stream_ = NULL;
 }
 
-void AudioRecorder::FinalizeOnAudioThread() {
+void AudioRecorderImpl::FinalizeOnAudioThread() {
   DCHECK(media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
   StopAndCloseOnAudioThread();
   delete this;
 }
 
-void AudioRecorder::OnData(media::AudioInputStream* stream,
-                           const media::AudioBus* source,
-                           uint32 /* hardware_delay_bytes */,
-                           double /* volume */) {
+void AudioRecorderImpl::OnData(media::AudioInputStream* stream,
+                               const media::AudioBus* source,
+                               uint32 /* hardware_delay_bytes */,
+                               double /* volume */) {
   temp_conversion_buffer_ = source;
   while (temp_conversion_buffer_) {
     // source->frames() == source_params.frames_per_buffer(), so we only have
@@ -216,16 +221,16 @@
   }
 }
 
-void AudioRecorder::OnError(media::AudioInputStream* /* stream */) {
+void AudioRecorderImpl::OnError(media::AudioInputStream* /* stream */) {
   LOG(ERROR) << "Error during sound recording.";
   media::AudioManager::Get()->GetTaskRunner()->PostTask(
       FROM_HERE,
-      base::Bind(&AudioRecorder::StopAndCloseOnAudioThread,
+      base::Bind(&AudioRecorderImpl::StopAndCloseOnAudioThread,
                  base::Unretained(this)));
 }
 
-double AudioRecorder::ProvideInput(media::AudioBus* dest,
-                                   base::TimeDelta /* buffer_delay */) {
+double AudioRecorderImpl::ProvideInput(media::AudioBus* dest,
+                                       base::TimeDelta /* buffer_delay */) {
   DCHECK(temp_conversion_buffer_);
   DCHECK_LE(temp_conversion_buffer_->frames(), dest->frames());
   temp_conversion_buffer_->CopyTo(dest);
@@ -233,7 +238,7 @@
   return 1.0;
 }
 
-void AudioRecorder::FlushAudioLoopForTesting() {
+void AudioRecorderImpl::FlushAudioLoopForTesting() {
   if (media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread())
     return;
 
@@ -242,8 +247,9 @@
   base::RunLoop rl;
   media::AudioManager::Get()->GetTaskRunner()->PostTaskAndReply(
       FROM_HERE,
-      base::Bind(base::IgnoreResult(&AudioRecorder::FlushAudioLoopForTesting),
-                 base::Unretained(this)),
+      base::Bind(
+          base::IgnoreResult(&AudioRecorderImpl::FlushAudioLoopForTesting),
+          base::Unretained(this)),
       rl.QuitClosure());
   rl.Run();
 }
diff --git a/components/copresence/mediums/audio/audio_recorder_impl.h b/components/copresence/mediums/audio/audio_recorder_impl.h
new file mode 100644
index 0000000..7ef2790
--- /dev/null
+++ b/components/copresence/mediums/audio/audio_recorder_impl.h
@@ -0,0 +1,116 @@
+// 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 COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_RECORDER_IMPL_H_
+#define COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_RECORDER_IMPL_H_
+
+#include <string>
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/copresence/mediums/audio/audio_recorder.h"
+#include "media/audio/audio_io.h"
+#include "media/audio/audio_parameters.h"
+#include "media/base/audio_converter.h"
+
+namespace base {
+class MessageLoop;
+}
+
+namespace media {
+class AudioBus;
+}
+
+namespace copresence {
+
+// The AudioRecorder class will record audio until told to stop.
+class AudioRecorderImpl final
+    : public AudioRecorder,
+      public media::AudioInputStream::AudioInputCallback,
+      public media::AudioConverter::InputCallback {
+ public:
+  typedef base::Callback<void(const std::string&)> RecordedSamplesCallback;
+
+  AudioRecorderImpl();
+
+  // AudioRecorder overrides:
+  void Initialize(const RecordedSamplesCallback& decode_callback) override;
+  void Record() override;
+  void Stop() override;
+  void Finalize() override;
+  bool IsRecording() override;
+
+  // Takes ownership of the stream.
+  void set_input_stream_for_testing(
+      media::AudioInputStream* input_stream_for_testing) {
+    input_stream_for_testing_.reset(input_stream_for_testing);
+  }
+
+  // Takes ownership of the params.
+  void set_params_for_testing(media::AudioParameters* params_for_testing) {
+    params_for_testing_.reset(params_for_testing);
+  }
+
+ protected:
+  virtual ~AudioRecorderImpl();
+  void set_is_recording(bool is_recording) { is_recording_ = is_recording; }
+
+ private:
+  friend class AudioRecorderTest;
+  FRIEND_TEST_ALL_PREFIXES(AudioRecorderTest, BasicRecordAndStop);
+  FRIEND_TEST_ALL_PREFIXES(AudioRecorderTest, OutOfOrderRecordAndStopMultiple);
+
+  // Methods to do our various operations; all of these need to be run on the
+  // audio thread.
+  void InitializeOnAudioThread();
+  void RecordOnAudioThread();
+  void StopOnAudioThread();
+  void StopAndCloseOnAudioThread();
+  void FinalizeOnAudioThread();
+
+  // AudioInputStream::AudioInputCallback overrides:
+  // Called by the audio recorder when a full packet of audio data is
+  // available. This is called from a special audio thread and the
+  // implementation should return as soon as possible.
+  void OnData(media::AudioInputStream* stream,
+              const media::AudioBus* source,
+              uint32 hardware_delay_bytes,
+              double volume) override;
+  void OnError(media::AudioInputStream* stream) override;
+
+  // AudioConverter::InputCallback overrides:
+  double ProvideInput(media::AudioBus* dest,
+                      base::TimeDelta buffer_delay) override;
+
+  // Flushes the audio loop, making sure that any queued operations are
+  // performed.
+  void FlushAudioLoopForTesting();
+
+  bool is_recording_;
+
+  media::AudioInputStream* stream_;
+
+  RecordedSamplesCallback decode_callback_;
+
+  // ProvideInput will use this buffer as its source.
+  const media::AudioBus* temp_conversion_buffer_;
+
+  // Outside of the ctor/Initialize method, only access the next variables on
+  // the recording thread.
+  scoped_ptr<media::AudioBus> buffer_;
+  int total_buffer_frames_;
+  int buffer_frame_index_;
+
+  scoped_ptr<media::AudioConverter> converter_;
+
+  scoped_ptr<media::AudioInputStream> input_stream_for_testing_;
+  scoped_ptr<media::AudioParameters> params_for_testing_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioRecorderImpl);
+};
+
+}  // namespace copresence
+
+#endif  // COMPONENTS_COPRESENCE_MEDIUMS_AUDIO_AUDIO_RECORDER_IMPL_H_
diff --git a/components/copresence/mediums/audio/audio_recorder_unittest.cc b/components/copresence/mediums/audio/audio_recorder_unittest.cc
index 1e01c94..1d7c959 100644
--- a/components/copresence/mediums/audio/audio_recorder_unittest.cc
+++ b/components/copresence/mediums/audio/audio_recorder_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/memory/aligned_memory.h"
 #include "base/run_loop.h"
+#include "components/copresence/mediums/audio/audio_recorder_impl.h"
 #include "components/copresence/public/copresence_constants.h"
 #include "components/copresence/test/audio_test_support.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -85,9 +86,9 @@
 
   void CreateSimpleRecorder() {
     DeleteRecorder();
-    recorder_ = new AudioRecorder(
+    recorder_ = new AudioRecorderImpl();
+    recorder_->Initialize(
         base::Bind(&AudioRecorderTest::DecodeSamples, base::Unretained(this)));
-    recorder_->Initialize();
   }
 
   void CreateRecorder(size_t channels,
@@ -108,12 +109,12 @@
 
     total_samples_ = samples;
 
-    recorder_ = new AudioRecorder(
-        base::Bind(&AudioRecorderTest::DecodeSamples, base::Unretained(this)));
+    recorder_ = new AudioRecorderImpl();
     recorder_->set_input_stream_for_testing(
         new TestAudioInputStream(params_, channel_data_, samples));
     recorder_->set_params_for_testing(new media::AudioParameters(params_));
-    recorder_->Initialize();
+    recorder_->Initialize(
+        base::Bind(&AudioRecorderTest::DecodeSamples, base::Unretained(this)));
   }
 
   void DeleteRecorder() {
@@ -181,7 +182,8 @@
   media::AudioParameters params_;
   size_t total_samples_;
 
-  AudioRecorder* recorder_;
+  // Deleted by calling Finalize() on the object.
+  AudioRecorderImpl* recorder_;
 
   std::string received_samples_;
 
diff --git a/components/copresence/proto/enums.proto b/components/copresence/proto/enums.proto
index d44616d..e76eee1 100644
--- a/components/copresence/proto/enums.proto
+++ b/components/copresence/proto/enums.proto
@@ -81,7 +81,7 @@
 }
 enum AudioConfiguration {
   AUDIO_CONFIGURATION_UNKNOWN = 0;
-  AUDIBLE = 1;
+  AUDIO_CONFIGURATION_AUDIBLE = 1;
 }
 enum BroadcastScanConfiguration {
   BROADCAST_SCAN_CONFIGURATION_UNKNOWN = 0;
diff --git a/components/copresence/public/copresence_constants.h b/components/copresence/public/copresence_constants.h
index 1c2499d..07c38cf 100644
--- a/components/copresence/public/copresence_constants.h
+++ b/components/copresence/public/copresence_constants.h
@@ -27,6 +27,17 @@
 extern const int kDefaultChannels;
 extern const media::ChannelLayout kDefaultChannelLayout;
 
+// These constants are used from everywhere.
+// Particularly, these are used to index the directive lists in the
+// audio manager, so do not change these enums without changing
+// audio_directive_list.[h|cc].
+enum AudioType {
+  AUDIBLE = 0,
+  INAUDIBLE = 1,
+  BOTH = 2,
+  AUDIO_TYPE_UNKNOWN = 3,
+};
+
 }  // namespace copresence
 
 #endif  // COMPONENTS_COPRESENCE_PUBLIC_COPRESENCE_CONSTANTS_
diff --git a/components/copresence/public/copresence_delegate.h b/components/copresence/public/copresence_delegate.h
index 0b83087..f11b344e 100644
--- a/components/copresence/public/copresence_delegate.h
+++ b/components/copresence/public/copresence_delegate.h
@@ -27,6 +27,8 @@
 // A delegate interface for users of Copresence.
 class CopresenceDelegate {
  public:
+  virtual ~CopresenceDelegate() {}
+
   // This method will be called when we have subscribed messages that need to
   // be sent to their respective apps.
   virtual void HandleMessages(
diff --git a/components/copresence/public/whispernet_client.h b/components/copresence/public/whispernet_client.h
index a4e530c2..8dcb4a0 100644
--- a/components/copresence/public/whispernet_client.h
+++ b/components/copresence/public/whispernet_client.h
@@ -11,6 +11,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "components/copresence/public/copresence_constants.h"
 
 namespace media {
 class AudioBusRefCounted;
@@ -37,7 +38,7 @@
   typedef base::Callback<void(const std::vector<AudioToken>&)> TokensCallback;
   // Callback that returns encoded samples for a given token.
   typedef base::Callback<void(const std::string&,
-                              bool,
+                              AudioType,
                               const scoped_refptr<media::AudioBusRefCounted>&)>
       SamplesCallback;
 
@@ -48,9 +49,9 @@
   virtual void Shutdown() = 0;
 
   // Fires an event to request a token encode.
-  virtual void EncodeToken(const std::string& token, bool audible) = 0;
+  virtual void EncodeToken(const std::string& token, AudioType type) = 0;
   // Fires an event to request a decode for the given samples.
-  virtual void DecodeSamples(const std::string& samples) = 0;
+  virtual void DecodeSamples(AudioType type, const std::string& samples) = 0;
   // Fires an event to request detection of a whispernet broadcast.
   virtual void DetectBroadcast() = 0;
 
diff --git a/components/copresence/rpc/rpc_handler.cc b/components/copresence/rpc/rpc_handler.cc
index 7c4d121f..91a09f4 100644
--- a/components/copresence/rpc/rpc_handler.cc
+++ b/components/copresence/rpc/rpc_handler.cc
@@ -25,6 +25,7 @@
 #include "components/copresence/proto/codes.pb.h"
 #include "components/copresence/proto/data.pb.h"
 #include "components/copresence/proto/rpcs.pb.h"
+#include "components/copresence/public/copresence_constants.h"
 #include "components/copresence/public/copresence_delegate.h"
 #include "net/http/http_status_code.h"
 
@@ -166,6 +167,8 @@
   if (delegate_ && delegate_->GetWhispernetClient()) {
     delegate_->GetWhispernetClient()->RegisterTokensCallback(
         WhispernetClient::TokensCallback());
+    delegate_->GetWhispernetClient()->RegisterSamplesCallback(
+        WhispernetClient::SamplesCallback());
   }
 }
 
@@ -382,9 +385,10 @@
   if (!directive_handler_)
     return;
 
-  const std::string& audible_token = directive_handler_->CurrentAudibleToken();
+  const std::string& audible_token =
+      directive_handler_->GetCurrentAudioToken(AUDIBLE);
   const std::string& inaudible_token =
-      directive_handler_->CurrentInaudibleToken();
+      directive_handler_->GetCurrentAudioToken(INAUDIBLE);
 
   if (!audible_token.empty())
     AddTokenToRequest(request, AudioToken(audible_token, true));
@@ -477,12 +481,13 @@
 
 void RpcHandler::AudioDirectiveListToWhispernetConnector(
     const std::string& token,
-    bool audible,
+    AudioType type,
     const WhispernetClient::SamplesCallback& samples_callback) {
+  DCHECK(type == AUDIBLE || type == INAUDIBLE);
   WhispernetClient* whispernet_client = delegate_->GetWhispernetClient();
   if (whispernet_client) {
     whispernet_client->RegisterSamplesCallback(samples_callback);
-    whispernet_client->EncodeToken(token, audible);
+    whispernet_client->EncodeToken(token, type);
   }
 }
 
diff --git a/components/copresence/rpc/rpc_handler.h b/components/copresence/rpc/rpc_handler.h
index 34e6427..c431bd8 100644
--- a/components/copresence/rpc/rpc_handler.h
+++ b/components/copresence/rpc/rpc_handler.h
@@ -117,7 +117,7 @@
   // whispernet, setting the samples return callback to samples_callback.
   void AudioDirectiveListToWhispernetConnector(
       const std::string& token,
-      bool audible,
+      AudioType type,
       const WhispernetClient::SamplesCallback& samples_callback);
 
   CopresenceDelegate* delegate_;  // Belongs to the caller.
diff --git a/components/copresence/rpc/rpc_handler_unittest.cc b/components/copresence/rpc/rpc_handler_unittest.cc
index aad39e3..731bdab 100644
--- a/components/copresence/rpc/rpc_handler_unittest.cc
+++ b/components/copresence/rpc/rpc_handler_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/bind_helpers.h"
 #include "base/message_loop/message_loop.h"
 #include "components/copresence/handlers/directive_handler.h"
+#include "components/copresence/mediums/audio/audio_manager.h"
 #include "components/copresence/proto/data.pb.h"
 #include "components/copresence/proto/enums.pb.h"
 #include "components/copresence/proto/rpcs.pb.h"
@@ -46,9 +47,9 @@
     return added_directives_;
   }
 
-  void Initialize(
-      const AudioRecorder::DecodeSamplesCallback& decode_cb,
-      const AudioDirectiveHandler::EncodeTokenCallback& encode_cb) override {}
+  void Initialize(const AudioManager::DecodeSamplesCallback& decode_cb,
+                  const AudioManager::EncodeTokenCallback& encode_cb) override {
+  }
 
   void AddDirective(const Directive& directive) override {
     added_directives_.push_back(directive);
diff --git a/components/cronet.gypi b/components/cronet.gypi
index ecf374cd..a2a3409b 100644
--- a/components/cronet.gypi
+++ b/components/cronet.gypi
@@ -20,28 +20,12 @@
           'includes': [ '../build/jni_generator.gypi' ],
         },
         {
-          'target_name': 'cronet_url_request_error_list',
+          'target_name': 'cronet_url_request_java',
           'type': 'none',
-          'sources': [
-            'cronet/android/java/src/org/chromium/net/ChromiumUrlRequestError.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/cronet',
-            'template_deps': ['cronet/android/chromium_url_request_error_list.h'],
+            'source_file': 'cronet/android/chromium_url_request.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
-        },
-        {
-          'target_name': 'cronet_url_request_priority_list',
-          'type': 'none',
-          'sources': [
-            'cronet/android/java/src/org/chromium/net/ChromiumUrlRequestPriority.template',
-          ],
-          'variables': {
-            'package_name': 'org/chromium/cronet',
-            'template_deps': ['cronet/android/chromium_url_request_priority_list.h'],
-          },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
         {
           'target_name': 'cronet_url_request_context_config_list',
@@ -111,8 +95,7 @@
             '../third_party/icu/icu.gyp:icuuc',
             'cronet_jni_headers',
             'cronet_url_request_context_config_list',
-            'cronet_url_request_error_list',
-            'cronet_url_request_priority_list',
+            'cronet_url_request_java',
             'cronet_version',
             '../net/net.gyp:net',
           ],
@@ -210,8 +193,7 @@
           'dependencies': [
             '../base/base.gyp:base',
             'cronet_stub',
-            'cronet_url_request_error_list',
-            'cronet_url_request_priority_list',
+            'cronet_url_request_java',
             'libcronet',
           ],
           'variables': {
@@ -395,7 +377,6 @@
             'cronet',
             'cronet_sample_apk_java',
             'cronet_stub',
-            '../base/base.gyp:base_java',
             '../base/base.gyp:base_java_test_support',
           ],
           'variables': {
@@ -464,7 +445,7 @@
         {
           # cronet_test_apk creates a .jar as a side effect. Any java targets
           # that need that .jar in their classpath should depend on this target,
-          # cronet_sample_apk_java. Dependents of cronet_test_apk receive its
+          # cronet_test_apk_java. Dependents of cronet_test_apk receive its
           # jar path in the variable 'apk_output_jar_path'. This target should
           # only be used by targets which instrument cronet_test_apk.
           'target_name': 'cronet_test_apk_java',
@@ -479,8 +460,6 @@
           'type': 'none',
           'dependencies': [
             'cronet_test_apk_java',
-            '../base/base.gyp:base_java',
-            '../base/base.gyp:base_javatests',
             '../base/base.gyp:base_java_test_support',
           ],
           'variables': {
diff --git a/components/cronet/android/chromium_url_request.h b/components/cronet/android/chromium_url_request.h
index 4296738..b63f4f8f 100644
--- a/components/cronet/android/chromium_url_request.h
+++ b/components/cronet/android/chromium_url_request.h
@@ -11,18 +11,32 @@
 
 // Define request priority values like REQUEST_PRIORITY_IDLE in a
 // way that ensures they're always the same than their Java counterpart.
+//
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
+// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ChromiumUrlRequestPriority
+// GENERATED_JAVA_PREFIX_TO_STRIP: REQUEST_PRIORITY_
 enum UrlRequestPriority {
-#define DEFINE_REQUEST_PRIORITY(x, y) REQUEST_PRIORITY_##x = y,
-#include "components/cronet/android/chromium_url_request_priority_list.h"
-#undef DEFINE_REQUEST_PRIORITY
+  REQUEST_PRIORITY_IDLE = 0,
+  REQUEST_PRIORITY_LOWEST = 1,
+  REQUEST_PRIORITY_LOW = 2,
+  REQUEST_PRIORITY_MEDIUM = 3,
+  REQUEST_PRIORITY_HIGHEST = 4,
 };
 
 // Define request priority values like REQUEST_ERROR_SUCCESS in a
 // way that ensures they're always the same than their Java counterpart.
+//
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
+// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ChromiumUrlRequestError
+// GENERATED_JAVA_PREFIX_TO_STRIP: REQUEST_ERROR_
 enum UrlRequestError {
-#define DEFINE_REQUEST_ERROR(x, y) REQUEST_ERROR_##x = y,
-#include "components/cronet/android/chromium_url_request_error_list.h"
-#undef DEFINE_REQUEST_ERROR
+  REQUEST_ERROR_SUCCESS = 0,
+  REQUEST_ERROR_UNKNOWN = 1,
+  REQUEST_ERROR_MALFORMED_URL = 2,
+  REQUEST_ERROR_CONNECTION_TIMED_OUT = 3,
+  REQUEST_ERROR_UNKNOWN_HOST = 4,
 };
 
 bool ChromiumUrlRequestRegisterJni(JNIEnv* env);
diff --git a/components/cronet/android/chromium_url_request_error_list.h b/components/cronet/android/chromium_url_request_error_list.h
deleted file mode 100644
index 4f4cdb8..0000000
--- a/components/cronet/android/chromium_url_request_error_list.h
+++ /dev/null
@@ -1,14 +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.
-
-// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum values.
-#ifndef DEFINE_REQUEST_ERROR
-#error "DEFINE_REQUEST_ERROR should be defined before including this file"
-#endif
-DEFINE_REQUEST_ERROR(SUCCESS, 0)
-DEFINE_REQUEST_ERROR(UNKNOWN, 1)
-DEFINE_REQUEST_ERROR(MALFORMED_URL, 2)
-DEFINE_REQUEST_ERROR(CONNECTION_TIMED_OUT, 3)
-DEFINE_REQUEST_ERROR(UNKNOWN_HOST, 4)
diff --git a/components/cronet/android/chromium_url_request_priority_list.h b/components/cronet/android/chromium_url_request_priority_list.h
deleted file mode 100644
index 5f31095..0000000
--- a/components/cronet/android/chromium_url_request_priority_list.h
+++ /dev/null
@@ -1,14 +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.
-
-// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum values.
-#ifndef DEFINE_REQUEST_PRIORITY
-#error "DEFINE_REQUEST_PRIORITY should be defined before including this file"
-#endif
-DEFINE_REQUEST_PRIORITY(IDLE, 0)
-DEFINE_REQUEST_PRIORITY(LOWEST, 1)
-DEFINE_REQUEST_PRIORITY(LOW, 2)
-DEFINE_REQUEST_PRIORITY(MEDIUM, 3)
-DEFINE_REQUEST_PRIORITY(HIGHEST, 4)
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestError.template b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestError.template
deleted file mode 100644
index 24e51102..0000000
--- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestError.template
+++ /dev/null
@@ -1,14 +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.
-
-package org.chromium.net;
-
-// A simple auto-generated interface used to list request errors as used by
-// both org.chromium.net.ChromiumUrlRequest and
-// net/cronet/android/chromium_url_request_error_list.h
-public interface ChromiumUrlRequestError {
-#define DEFINE_REQUEST_ERROR(x,y) public static final int x = y;
-#include "components/cronet/android/chromium_url_request_error_list.h"
-#undef DEFINE_REQUEST_ERROR
-}
diff --git a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestPriority.template b/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestPriority.template
deleted file mode 100644
index 604849d..0000000
--- a/components/cronet/android/java/src/org/chromium/net/ChromiumUrlRequestPriority.template
+++ /dev/null
@@ -1,14 +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.
-
-package org.chromium.net;
-
-// A simple auto-generated interface used to list request priorities as used by
-// both org.chromium.net.ChromiumUrlRequest and
-// net/cronet/android/chromium_url_request_priority_list.h
-public interface ChromiumUrlRequestPriority {
-#define DEFINE_REQUEST_PRIORITY(x,y) public static final int x = y;
-#include "components/cronet/android/chromium_url_request_priority_list.h"
-#undef DEFINE_REQUEST_PRIORITY
-}
diff --git a/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactory.java b/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactory.java
index 55736c2e..50add44b 100644
--- a/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactory.java
+++ b/components/cronet/android/java/src/org/chromium/net/HttpUrlRequestFactory.java
@@ -78,9 +78,9 @@
         HttpUrlRequestFactory factory = null;
         try {
             Class<? extends HttpUrlRequestFactory> factoryClass =
-                    HttpUrlRequestFactory.class.getClassLoader().
-                            loadClass(CHROMIUM_URL_REQUEST_FACTORY).
-                            asSubclass(HttpUrlRequestFactory.class);
+                    HttpUrlRequestFactory.class.getClassLoader()
+                            .loadClass(CHROMIUM_URL_REQUEST_FACTORY)
+                            .asSubclass(HttpUrlRequestFactory.class);
             Constructor<? extends HttpUrlRequestFactory> constructor =
                     factoryClass.getConstructor(
                             Context.class, HttpUrlRequestFactoryConfig.class);
@@ -93,8 +93,7 @@
             // Leave as null
         } catch (Exception e) {
             throw new IllegalStateException(
-                    "Cannot instantiate: " +
-                    CHROMIUM_URL_REQUEST_FACTORY,
+                    "Cannot instantiate: " + CHROMIUM_URL_REQUEST_FACTORY,
                     e);
         }
         return factory;
diff --git a/components/cronet/android/sample/AndroidManifest.xml b/components/cronet/android/sample/AndroidManifest.xml
index b0137f8..4fc7724 100644
--- a/components/cronet/android/sample/AndroidManifest.xml
+++ b/components/cronet/android/sample/AndroidManifest.xml
@@ -23,7 +23,7 @@
         </activity>
     </application>
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 </manifest>
diff --git a/components/cronet/android/sample/javatests/AndroidManifest.xml b/components/cronet/android/sample/javatests/AndroidManifest.xml
index 1203694..3c2e38c 100644
--- a/components/cronet/android/sample/javatests/AndroidManifest.xml
+++ b/components/cronet/android/sample/javatests/AndroidManifest.xml
@@ -14,7 +14,7 @@
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
-    <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.cronet_sample_apk"
         android:label="Tests for org.chromium.cronet_sample_apk"/>
diff --git a/components/cronet/android/test/AndroidManifest.xml b/components/cronet/android/test/AndroidManifest.xml
index 5ab701d..fdb5125 100644
--- a/components/cronet/android/test/AndroidManifest.xml
+++ b/components/cronet/android/test/AndroidManifest.xml
@@ -23,7 +23,7 @@
         </activity>
     </application>
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 </manifest>
diff --git a/components/cronet/android/test/javatests/AndroidManifest.xml b/components/cronet/android/test/javatests/AndroidManifest.xml
index 47f17b63..d4e9a53 100644
--- a/components/cronet/android/test/javatests/AndroidManifest.xml
+++ b/components/cronet/android/test/javatests/AndroidManifest.xml
@@ -14,7 +14,7 @@
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
-    <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.cronet_test_apk"
         android:label="Tests for org.chromium.cronet_test_apk"/>
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.cc
index 967c897..b521281 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.cc
@@ -80,6 +80,16 @@
       GetDataReductionProxyBypassType(original_response_headers,
                                       &data_reduction_proxy_info);
 
+  // Requests with CORS headers do not support block-once, so emulate block-once
+  // with block=1. See crbug.com/418342.
+  // TODO(bengr): Remove this when block-once is supported for all requests.
+  if (bypass_type == BYPASS_EVENT_TYPE_CURRENT &&
+      request->extra_request_headers().HasHeader("origin")) {
+    bypass_type = BYPASS_EVENT_TYPE_SHORT;
+    data_reduction_proxy_info.mark_proxies_as_bad = true;
+    data_reduction_proxy_info.bypass_duration = base::TimeDelta::FromSeconds(1);
+  }
+
   if (bypass_type == BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER &&
       DataReductionProxyParams::
           IsIncludedInRemoveMissingViaHeaderOtherBypassFieldTrial()) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc
index 1ff38326..16d91f94 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc
@@ -117,6 +117,7 @@
   // if |expect_response_body|.
   void TestProxyFallback(const char* method,
                          const char* first_response,
+                         bool has_origin,
                          bool expected_retry,
                          bool expect_response_body) {
     std::string payload1 =
@@ -126,6 +127,8 @@
       MockRead(payload1.c_str()),
       MockRead(net::SYNCHRONOUS, net::OK),
     };
+    std::string origin = has_origin ? "Origin: foo.com\r\n" : "";
+
     std::string m(method);
     std::string trailer =
         (m == "HEAD" || m == "PUT" || m == "POST") ?
@@ -134,10 +137,10 @@
     std::string request1 =
         base::StringPrintf("%s http://www.google.com/ HTTP/1.1\r\n"
                            "Host: www.google.com\r\n"
-                           "Proxy-Connection: keep-alive\r\n%s"
+                           "Proxy-Connection: keep-alive\r\n%s%s"
                            "User-Agent:\r\n"
                            "Accept-Encoding: gzip, deflate\r\n\r\n",
-                           method, trailer.c_str());
+                           method, origin.c_str(), trailer.c_str());
     MockWrite data_writes[] = {
       MockWrite(request1.c_str()),
     };
@@ -154,10 +157,10 @@
       std::string request2 =
           base::StringPrintf("%s / HTTP/1.1\r\n"
                              "Host: www.google.com\r\n"
-                             "Connection: keep-alive\r\n%s"
+                             "Connection: keep-alive\r\n%s%s"
                              "User-Agent:\r\n"
                              "Accept-Encoding: gzip, deflate\r\n\r\n",
-                             method, trailer.c_str());
+                             method, origin.c_str(), trailer.c_str());
       MockWrite data_writes2[] = {
           MockWrite(request2.c_str()),
       };
@@ -174,6 +177,7 @@
         (expect_response_body ? "content" : ""),
         "server",
         (expected_retry == 0 ? "proxy" : "not-proxy"),
+        has_origin,
         expected_retry);
   }
 
@@ -185,6 +189,7 @@
                                                const std::string& content,
                                                const std::string& header,
                                                const std::string& value,
+                                               bool has_origin,
                                                bool expected_retry) {
     TestDelegate d;
     scoped_ptr<URLRequest> r(context_->CreateRequest(
@@ -194,6 +199,8 @@
         NULL));
     r->set_method(method);
     r->SetLoadFlags(net::LOAD_NORMAL);
+    if (has_origin)
+      r->SetExtraRequestHeaderByName("Origin", "foo.com", true);
 
     r->Start();
     base::RunLoop().Run();
@@ -407,6 +414,7 @@
   const struct {
     const char* method;
     const char* first_response;
+    bool has_origin;
     bool expected_retry;
     size_t expected_bad_proxy_count;
     bool expect_response_body;
@@ -419,6 +427,7 @@
       "Server: proxy\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
       false,
+      false,
       0u,
       true,
       -1,
@@ -431,6 +440,7 @@
       "Server: proxy\r\n"
       "Via: 1.1 Chrome Compression Proxy\r\n\r\n",
       false,
+      false,
       0u,
       true,
       -1,
@@ -443,6 +453,7 @@
       "Server: proxy\r\n"
       "Via: 1.1 Chrome-Compression-Proxy, 1.0 some-other-proxy\r\n\r\n",
       false,
+      false,
       0u,
       true,
       -1,
@@ -454,6 +465,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: bypass=0\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -466,6 +478,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: bypass=1\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -478,6 +491,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: bypass=0\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -490,6 +504,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: bypass=0\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       false,
@@ -502,6 +517,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: bypass=0\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -514,6 +530,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: bypass=0\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -526,6 +543,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: bypass=0\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -537,6 +555,7 @@
       "HTTP/1.1 500 Internal Server Error\r\n"
       "Server: proxy\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -548,6 +567,7 @@
       "HTTP/1.1 502 Internal Server Error\r\n"
       "Server: proxy\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -559,6 +579,7 @@
       "HTTP/1.1 503 Internal Server Error\r\n"
       "Server: proxy\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -569,6 +590,7 @@
     { "GET",
       "HTTP/1.1 404 Not Found\r\n"
       "Server: proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -579,6 +601,7 @@
     { "GET",
       "HTTP/1.1 200 OK\r\n"
       "Server: proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -590,6 +613,7 @@
       "HTTP/1.1 200 OK\r\n"
       "Server: proxy\r\n"
       "Via: 1.0 some-other-proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -601,6 +625,7 @@
       "HTTP/1.1 304 Not Modified\r\n"
       "Server: proxy\r\n\r\n",
       false,
+      false,
       0u,
       false,
       0,
@@ -614,6 +639,7 @@
       "Chrome-Proxy: bypass=0\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
       false,
+      false,
       1u,
       true,
       0,
@@ -626,6 +652,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: block=1\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       2u,
       true,
@@ -640,6 +667,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       0u,
       true,
@@ -652,6 +680,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       0u,
       true,
@@ -664,6 +693,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       0u,
       false,
@@ -676,6 +706,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       0u,
       true,
@@ -688,6 +719,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       0u,
       true,
@@ -700,6 +732,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       0u,
       true,
@@ -716,11 +749,28 @@
       "Chrome-Proxy: block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
       false,
+      false,
       0u,
       true,
       0,
       BYPASS_EVENT_TYPE_CURRENT
     },
+    // Requests with CORS headers do not support block-once, so they are
+    // emulated with block=1. The event type is recorded as SHORT, so note
+    // the type of bypass that was actually used, not sent.
+    // See: crbug.com/418342.
+    { "GET",
+      "HTTP/1.1 200 OK\r\n"
+      "Server: proxy\r\n"
+      "Chrome-Proxy: block-once\r\n"
+      "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      true,
+      true,
+      2u,
+      true,
+      1,
+      BYPASS_EVENT_TYPE_SHORT
+    },
     // Valid data reduction proxy response with block and block-once messages.
     // The block message will override the block-once message, so both proxies
     // should be on the retry list when it completes.
@@ -729,6 +779,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: block=1, block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       2u,
       true,
@@ -743,6 +794,7 @@
       "Server: proxy\r\n"
       "Chrome-Proxy: bypass=1, block-once\r\n"
       "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
+      false,
       true,
       1u,
       true,
@@ -761,6 +813,7 @@
         &bypass_type);
     TestProxyFallback(tests[i].method,
                       tests[i].first_response,
+                      tests[i].has_origin,
                       tests[i].expected_retry,
                       tests[i].expect_response_body);
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
index 955a581..16940b8 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -137,9 +137,6 @@
 
   AddDefaultProxyBypassRules();
   net::NetworkChangeNotifier::AddIPAddressObserver(this);
-
-  // We set or reset the proxy pref at startup.
-  MaybeActivateDataReductionProxy(true);
 }
 
 void DataReductionProxySettings::InitDataReductionProxySettings(
@@ -382,6 +379,11 @@
     bool at_startup) {
   DCHECK(thread_checker_.CalledOnValidThread());
   PrefService* prefs = GetOriginalProfilePrefs();
+  // Do nothing if prefs have not been initialized. This allows unit testing
+  // of profile related code without having to initialize data reduction proxy
+  // related prefs.
+  if (!prefs)
+    return;
   // TODO(marq): Consider moving this so stats are wiped the first time the
   // proxy settings are actually (not maybe) turned on.
   if (spdy_proxy_auth_enabled_.GetValue() &&
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
index 68f152e6..11dffb5 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
@@ -181,6 +181,11 @@
   // net::URLFetcherDelegate:
   void OnURLFetchComplete(const net::URLFetcher* source) override;
 
+  // Configures data reduction proxy and makes a request to the probe URL to
+  // determine server availability. |at_startup| is true when this method is
+  // called in response to creating or loading a new profile.
+  void MaybeActivateDataReductionProxy(bool at_startup);
+
  protected:
   void InitPrefMembers();
 
@@ -276,8 +281,6 @@
 
   void ResetDataReductionStatistics();
 
-  void MaybeActivateDataReductionProxy(bool at_startup);
-
   // Requests the proxy probe URL, if one is set.  If unable to do so, disables
   // the proxy, if enabled. Otherwise enables the proxy if disabled by a probe
   // failure.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
index 3e02cc8..26ec584 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -275,11 +275,6 @@
 void DataReductionProxySettingsTestBase::CheckInitDataReductionProxy(
     bool enabled_at_startup) {
   base::MessageLoopForUI loop;
-  SetProbeResult(kProbeURLWithOKResponse,
-                 "OK",
-                 FetchResult(enabled_at_startup, true),
-                 true,
-                 enabled_at_startup ? 1 : 0);
   scoped_ptr<DataReductionProxyConfigurator> configurator(
       new TestDataReductionProxyConfig());
   settings_->SetProxyConfigurator(configurator.get());
@@ -295,7 +290,6 @@
                  base::Unretained(this)));
 
   base::MessageLoop::current()->RunUntilIdle();
-  CheckProxyConfigs(enabled_at_startup, false, false);
   EXPECT_EQ(enabled_at_startup, proxy_enabled_);
 }
 
diff --git a/components/devtools_bridge/android/javatests/AndroidManifest.xml b/components/devtools_bridge/android/javatests/AndroidManifest.xml
index 0c0d729..b3d9d47 100644
--- a/components/devtools_bridge/android/javatests/AndroidManifest.xml
+++ b/components/devtools_bridge/android/javatests/AndroidManifest.xml
@@ -22,7 +22,7 @@
             </intent-filter>
         </activity>
     </application>
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.components.devtools_bridge.tests"
         android:label="Tests for org.chromium.components.devtools_bridge"/>
diff --git a/components/error_page/renderer/net_error_helper_core.cc b/components/error_page/renderer/net_error_helper_core.cc
index 93f943e..74cc14d3 100644
--- a/components/error_page/renderer/net_error_helper_core.cc
+++ b/components/error_page/renderer/net_error_helper_core.cc
@@ -430,6 +430,9 @@
     const NetErrorHelperCore::ErrorPageInfo& info) {
   return info.error.domain.utf8() == net::kErrorDomain &&
          info.error.reason != net::ERR_ABORTED &&
+         // For now, net::ERR_UNKNOWN_URL_SCHEME is only being displayed on
+         // Chrome for Android.
+         info.error.reason != net::ERR_UNKNOWN_URL_SCHEME &&
          !info.was_failed_post;
 }
 
diff --git a/components/error_page/renderer/net_error_helper_core_unittest.cc b/components/error_page/renderer/net_error_helper_core_unittest.cc
index 34a579e6..2402999 100644
--- a/components/error_page/renderer/net_error_helper_core_unittest.cc
+++ b/components/error_page/renderer/net_error_helper_core_unittest.cc
@@ -2171,7 +2171,19 @@
 TEST_F(NetErrorHelperCoreAutoReloadTest, ShouldSuppressNonReloadableErrorPage) {
   DoErrorLoad(net::ERR_ABORTED);
   EXPECT_FALSE(core()->ShouldSuppressErrorPage(NetErrorHelperCore::MAIN_FRAME,
-                                              GURL(kFailedUrl)));
+                                               GURL(kFailedUrl)));
+
+  DoErrorLoad(net::ERR_UNKNOWN_URL_SCHEME);
+  EXPECT_FALSE(core()->ShouldSuppressErrorPage(NetErrorHelperCore::MAIN_FRAME,
+                                               GURL(kFailedUrl)));
+}
+
+TEST_F(NetErrorHelperCoreAutoReloadTest, DoesNotReload) {
+  DoErrorLoad(net::ERR_ABORTED);
+  EXPECT_FALSE(timer()->IsRunning());
+
+  DoErrorLoad(net::ERR_UNKNOWN_URL_SCHEME);
+  EXPECT_FALSE(timer()->IsRunning());
 }
 
 TEST_F(NetErrorHelperCoreAutoReloadTest, ShouldSuppressErrorPage) {
diff --git a/components/keyed_service.gypi b/components/keyed_service.gypi
index 4a111140..b30e65da 100644
--- a/components/keyed_service.gypi
+++ b/components/keyed_service.gypi
@@ -22,9 +22,13 @@
       'sources': [
         'keyed_service/core/dependency_graph.cc',
         'keyed_service/core/dependency_graph.h',
+        'keyed_service/core/dependency_manager.cc',
+        'keyed_service/core/dependency_manager.h',
         'keyed_service/core/dependency_node.h',
         'keyed_service/core/keyed_service.cc',
         'keyed_service/core/keyed_service.h',
+        'keyed_service/core/keyed_service_base_factory.cc',
+        'keyed_service/core/keyed_service_base_factory.h',
         'keyed_service/core/keyed_service_export.h',
         'keyed_service/core/refcounted_keyed_service.cc',
         'keyed_service/core/refcounted_keyed_service.h',
diff --git a/components/keyed_service/content/browser_context_dependency_manager.cc b/components/keyed_service/content/browser_context_dependency_manager.cc
index ab460742f..3e7d2ce1 100644
--- a/components/keyed_service/content/browser_context_dependency_manager.cc
+++ b/components/keyed_service/content/browser_context_dependency_manager.cc
@@ -4,12 +4,9 @@
 
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
-#include <algorithm>
-#include <deque>
-#include <iterator>
-
 #include "base/bind.h"
 #include "base/debug/trace_event.h"
+#include "base/memory/singleton.h"
 #include "components/keyed_service/content/browser_context_keyed_base_factory.h"
 #include "content/public/browser/browser_context.h"
 
@@ -23,38 +20,10 @@
     "dump-browser-context-graph";
 #endif  // NDEBUG
 
-void BrowserContextDependencyManager::AddComponent(
-    BrowserContextKeyedBaseFactory* component) {
-  dependency_graph_.AddNode(component);
-}
-
-void BrowserContextDependencyManager::RemoveComponent(
-    BrowserContextKeyedBaseFactory* component) {
-  dependency_graph_.RemoveNode(component);
-}
-
-void BrowserContextDependencyManager::AddEdge(
-    BrowserContextKeyedBaseFactory* depended,
-    BrowserContextKeyedBaseFactory* dependee) {
-  dependency_graph_.AddEdge(depended, dependee);
-}
-
 void BrowserContextDependencyManager::RegisterProfilePrefsForServices(
     const content::BrowserContext* context,
     user_prefs::PrefRegistrySyncable* pref_registry) {
-  std::vector<DependencyNode*> construction_order;
-  if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
-    NOTREACHED();
-  }
-
-  for (std::vector<DependencyNode*>::const_iterator it =
-           construction_order.begin();
-       it != construction_order.end();
-       ++it) {
-    BrowserContextKeyedBaseFactory* factory =
-        static_cast<BrowserContextKeyedBaseFactory*>(*it);
-    factory->RegisterProfilePrefsIfNecessaryForContext(context, pref_registry);
-  }
+  RegisterPrefsForServices(context, pref_registry);
 }
 
 void BrowserContextDependencyManager::CreateBrowserContextServices(
@@ -73,61 +42,13 @@
   TRACE_EVENT0(
       "browser",
       "BrowserContextDependencyManager::DoCreateBrowserContextServices")
-#ifndef NDEBUG
-  MarkBrowserContextLiveForTesting(context);
-#endif
-
   will_create_browser_context_services_callbacks_.Notify(context);
-
-  std::vector<DependencyNode*> construction_order;
-  if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
-    NOTREACHED();
-  }
-
-#ifndef NDEBUG
-  DumpBrowserContextDependencies(context);
-#endif
-
-  for (size_t i = 0; i < construction_order.size(); i++) {
-    BrowserContextKeyedBaseFactory* factory =
-        static_cast<BrowserContextKeyedBaseFactory*>(construction_order[i]);
-    if (is_testing_context && factory->ServiceIsNULLWhileTesting() &&
-        !factory->HasTestingFactory(context)) {
-      factory->SetEmptyTestingFactory(context);
-    } else if (factory->ServiceIsCreatedWithBrowserContext()) {
-      // Create the service.
-      factory->CreateServiceNow(context);
-    }
-  }
+  DependencyManager::CreateContextServices(context, is_testing_context);
 }
 
 void BrowserContextDependencyManager::DestroyBrowserContextServices(
     content::BrowserContext* context) {
-  std::vector<DependencyNode*> destruction_order;
-  if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
-    NOTREACHED();
-  }
-
-#ifndef NDEBUG
-  DumpBrowserContextDependencies(context);
-#endif
-
-  for (size_t i = 0; i < destruction_order.size(); i++) {
-    BrowserContextKeyedBaseFactory* factory =
-        static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]);
-    factory->BrowserContextShutdown(context);
-  }
-
-#ifndef NDEBUG
-  // The context is now dead to the rest of the program.
-  dead_context_pointers_.insert(context);
-#endif
-
-  for (size_t i = 0; i < destruction_order.size(); i++) {
-    BrowserContextKeyedBaseFactory* factory =
-        static_cast<BrowserContextKeyedBaseFactory*>(destruction_order[i]);
-    factory->BrowserContextDestroyed(context);
-  }
+  DependencyManager::DestroyContextServices(context);
 }
 
 scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
@@ -140,20 +61,14 @@
 #ifndef NDEBUG
 void BrowserContextDependencyManager::AssertBrowserContextWasntDestroyed(
     content::BrowserContext* context) {
-  if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
-    NOTREACHED() << "Attempted to access a BrowserContext that was ShutDown(). "
-                 << "This is most likely a heap smasher in progress. After "
-                 << "KeyedService::Shutdown() completes, your "
-                 << "service MUST NOT refer to depended BrowserContext "
-                 << "services again.";
-  }
+  DependencyManager::AssertContextWasntDestroyed(context);
 }
 
 void BrowserContextDependencyManager::MarkBrowserContextLiveForTesting(
     content::BrowserContext* context) {
-  dead_context_pointers_.erase(context);
+  DependencyManager::MarkContextLiveForTesting(context);
 }
-#endif
+#endif  // NDEBUG
 
 // static
 BrowserContextDependencyManager*
@@ -166,26 +81,17 @@
 BrowserContextDependencyManager::~BrowserContextDependencyManager() {}
 
 #ifndef NDEBUG
-namespace {
-
-std::string BrowserContextKeyedBaseFactoryGetNodeName(DependencyNode* node) {
-  return static_cast<BrowserContextKeyedBaseFactory*>(node)->name();
-}
-
-}  // namespace
-
-void BrowserContextDependencyManager::DumpBrowserContextDependencies(
-    content::BrowserContext* context) {
+void BrowserContextDependencyManager::DumpContextDependencies(
+    const base::SupportsUserData* context) const {
   // Whenever we try to build a destruction ordering, we should also dump a
   // dependency graph to "/path/to/context/context-dependencies.dot".
   if (CommandLine::ForCurrentProcess()->HasSwitch(
           kDumpBrowserContextDependencyGraphFlag)) {
     base::FilePath dot_file =
-        context->GetPath().AppendASCII("browser-context-dependencies.dot");
-    std::string contents = dependency_graph_.DumpAsGraphviz(
-        "BrowserContext",
-        base::Bind(&BrowserContextKeyedBaseFactoryGetNodeName));
-    base::WriteFile(dot_file, contents.c_str(), contents.size());
+        static_cast<const content::BrowserContext*>(context)
+            ->GetPath()
+            .AppendASCII("browser-context-dependencies.dot");
+    DumpDependenciesAsGraphviz("BrowserContext", dot_file);
   }
 }
 #endif  // NDEBUG
diff --git a/components/keyed_service/content/browser_context_dependency_manager.h b/components/keyed_service/content/browser_context_dependency_manager.h
index f602ee4a..639b63d 100644
--- a/components/keyed_service/content/browser_context_dependency_manager.h
+++ b/components/keyed_service/content/browser_context_dependency_manager.h
@@ -7,15 +7,12 @@
 
 #include "base/callback_forward.h"
 #include "base/callback_list.h"
-#include "base/memory/singleton.h"
-#include "components/keyed_service/core/dependency_graph.h"
+#include "components/keyed_service/core/dependency_manager.h"
 #include "components/keyed_service/core/keyed_service_export.h"
 
-#ifndef NDEBUG
-#include <set>
-#endif
-
 class BrowserContextKeyedBaseFactory;
+template <typename T>
+struct DefaultSingletonTraits;
 
 namespace content {
 class BrowserContext;
@@ -28,17 +25,9 @@
 // A singleton that listens for context destruction notifications and
 // rebroadcasts them to each BrowserContextKeyedBaseFactory in a safe order
 // based on the stated dependencies by each service.
-class KEYED_SERVICE_EXPORT BrowserContextDependencyManager {
+class KEYED_SERVICE_EXPORT BrowserContextDependencyManager
+    : public DependencyManager {
  public:
-  // Adds/Removes a component from our list of live components. Removing will
-  // also remove live dependency links.
-  void AddComponent(BrowserContextKeyedBaseFactory* component);
-  void RemoveComponent(BrowserContextKeyedBaseFactory* component);
-
-  // Adds a dependency between two factories.
-  void AddEdge(BrowserContextKeyedBaseFactory* depended,
-               BrowserContextKeyedBaseFactory* dependee);
-
   // Registers profile-specific preferences for all services via |registry|.
   // |context| should be the BrowserContext containing |registry| and is used as
   // a key to prevent multiple registrations on the same BrowserContext in
@@ -85,7 +74,7 @@
   // (i.e., 0xWhatever might be created, be destroyed, and then a new
   // BrowserContext object might be created at 0xWhatever).
   void MarkBrowserContextLiveForTesting(content::BrowserContext* context);
-#endif
+#endif  // NDEBUG
 
   static BrowserContextDependencyManager* GetInstance();
 
@@ -101,23 +90,15 @@
   virtual ~BrowserContextDependencyManager();
 
 #ifndef NDEBUG
-  void DumpBrowserContextDependencies(content::BrowserContext* context);
-#endif
-
-  DependencyGraph dependency_graph_;
+  // DependencyManager:
+  virtual void DumpContextDependencies(
+      const base::SupportsUserData* context) const final;
+#endif  // NDEBUG
 
   // A list of callbacks to call just before executing
   // CreateBrowserContextServices() or CreateBrowserContextServicesForTest().
   base::CallbackList<void(content::BrowserContext*)>
       will_create_browser_context_services_callbacks_;
-
-#ifndef NDEBUG
-  // A list of context objects that have gone through the Shutdown()
-  // phase. These pointers are most likely invalid, but we keep track of their
-  // locations in memory so we can nicely assert if we're asked to do anything
-  // with them.
-  std::set<content::BrowserContext*> dead_context_pointers_;
-#endif
 };
 
 #endif  // COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_DEPENDENCY_MANAGER_H_
diff --git a/components/keyed_service/content/browser_context_keyed_base_factory.cc b/components/keyed_service/content/browser_context_keyed_base_factory.cc
index 622f1c8b..f2f09b4 100644
--- a/components/keyed_service/content/browser_context_keyed_base_factory.cc
+++ b/components/keyed_service/content/browser_context_keyed_base_factory.cc
@@ -13,33 +13,10 @@
 BrowserContextKeyedBaseFactory::BrowserContextKeyedBaseFactory(
     const char* name,
     BrowserContextDependencyManager* manager)
-    : dependency_manager_(manager)
-#ifndef NDEBUG
-      ,
-      service_name_(name)
-#endif
-{
-  dependency_manager_->AddComponent(this);
+    : KeyedServiceBaseFactory(name, manager) {
 }
 
 BrowserContextKeyedBaseFactory::~BrowserContextKeyedBaseFactory() {
-  dependency_manager_->RemoveComponent(this);
-}
-
-void BrowserContextKeyedBaseFactory::DependsOn(
-    BrowserContextKeyedBaseFactory* rhs) {
-  dependency_manager_->AddEdge(rhs, this);
-}
-
-void BrowserContextKeyedBaseFactory::RegisterProfilePrefsIfNecessaryForContext(
-    const content::BrowserContext* context,
-    user_prefs::PrefRegistrySyncable* registry) {
-  std::set<const content::BrowserContext*>::iterator it =
-      registered_preferences_.find(context);
-  if (it == registered_preferences_.end()) {
-    RegisterProfilePrefs(registry);
-    registered_preferences_.insert(context);
-  }
 }
 
 content::BrowserContext* BrowserContextKeyedBaseFactory::GetBrowserContextToUse(
@@ -47,7 +24,7 @@
   DCHECK(CalledOnValidThread());
 
 #ifndef NDEBUG
-  dependency_manager_->AssertBrowserContextWasntDestroyed(context);
+  AssertContextWasntDestroyed(context);
 #endif
 
   // Safe default for the Incognito mode: no service.
@@ -59,6 +36,26 @@
 
 void BrowserContextKeyedBaseFactory::RegisterUserPrefsOnBrowserContextForTest(
     content::BrowserContext* context) {
+  KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(context);
+}
+
+bool BrowserContextKeyedBaseFactory::ServiceIsCreatedWithBrowserContext()
+    const {
+  return KeyedServiceBaseFactory::ServiceIsCreatedWithContext();
+}
+
+bool BrowserContextKeyedBaseFactory::ServiceIsNULLWhileTesting() const {
+  return KeyedServiceBaseFactory::ServiceIsNULLWhileTesting();
+}
+
+void BrowserContextKeyedBaseFactory::BrowserContextDestroyed(
+    content::BrowserContext* context) {
+  KeyedServiceBaseFactory::ContextDestroyed(context);
+}
+
+user_prefs::PrefRegistrySyncable*
+BrowserContextKeyedBaseFactory::GetAssociatedPrefRegistry(
+    base::SupportsUserData* context) const {
   // Safe timing for pref registration is hard. Previously, we made
   // BrowserContext responsible for all pref registration on every service
   // that used BrowserContext. Now we don't and there are timing issues.
@@ -84,38 +81,49 @@
   // This is the purpose of RegisterProfilePrefsIfNecessary() which could be
   // replaced directly by RegisterProfilePrefs() if this method is ever phased
   // out.
-  PrefService* prefs = user_prefs::UserPrefs::Get(context);
+  PrefService* prefs = user_prefs::UserPrefs::Get(
+      static_cast<content::BrowserContext*>(context));
   user_prefs::PrefRegistrySyncable* registry =
       static_cast<user_prefs::PrefRegistrySyncable*>(
           prefs->DeprecatedGetPrefRegistry());
-  RegisterProfilePrefsIfNecessaryForContext(context, registry);
+  return registry;
 }
 
-bool BrowserContextKeyedBaseFactory::ServiceIsCreatedWithBrowserContext()
-    const {
-  return false;
+base::SupportsUserData* BrowserContextKeyedBaseFactory::GetContextToUse(
+    base::SupportsUserData* context) const {
+  return GetBrowserContextToUse(static_cast<content::BrowserContext*>(context));
 }
 
-bool BrowserContextKeyedBaseFactory::ServiceIsNULLWhileTesting() const {
-  return false;
+bool BrowserContextKeyedBaseFactory::ServiceIsCreatedWithContext() const {
+  return ServiceIsCreatedWithBrowserContext();
 }
 
-void BrowserContextKeyedBaseFactory::BrowserContextDestroyed(
-    content::BrowserContext* context) {
-  // While object destruction can be customized in ways where the object is
-  // only dereferenced, this still must run on the UI thread.
-  DCHECK(CalledOnValidThread());
-
-  registered_preferences_.erase(context);
+void BrowserContextKeyedBaseFactory::ContextShutdown(
+    base::SupportsUserData* context) {
+  BrowserContextShutdown(static_cast<content::BrowserContext*>(context));
 }
 
-bool BrowserContextKeyedBaseFactory::ArePreferencesSetOn(
-    content::BrowserContext* context) const {
-  return registered_preferences_.find(context) != registered_preferences_.end();
+void BrowserContextKeyedBaseFactory::ContextDestroyed(
+    base::SupportsUserData* context) {
+  BrowserContextDestroyed(static_cast<content::BrowserContext*>(context));
 }
 
-void BrowserContextKeyedBaseFactory::MarkPreferencesSetOn(
-    content::BrowserContext* context) {
-  DCHECK(!ArePreferencesSetOn(context));
-  registered_preferences_.insert(context);
+void BrowserContextKeyedBaseFactory::RegisterPrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  RegisterProfilePrefs(registry);
+}
+
+void BrowserContextKeyedBaseFactory::SetEmptyTestingFactory(
+    base::SupportsUserData* context) {
+  SetEmptyTestingFactory(static_cast<content::BrowserContext*>(context));
+}
+
+bool BrowserContextKeyedBaseFactory::HasTestingFactory(
+    base::SupportsUserData* context) {
+  return HasTestingFactory(static_cast<content::BrowserContext*>(context));
+}
+
+void BrowserContextKeyedBaseFactory::CreateServiceNow(
+    base::SupportsUserData* context) {
+  CreateServiceNow(static_cast<content::BrowserContext*>(context));
 }
diff --git a/components/keyed_service/content/browser_context_keyed_base_factory.h b/components/keyed_service/content/browser_context_keyed_base_factory.h
index 86e569d..c7603afd 100644
--- a/components/keyed_service/content/browser_context_keyed_base_factory.h
+++ b/components/keyed_service/content/browser_context_keyed_base_factory.h
@@ -5,10 +5,7 @@
 #ifndef COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_BASE_FACTORY_H_
 #define COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_BASE_FACTORY_H_
 
-#include <set>
-
-#include "base/threading/non_thread_safe.h"
-#include "components/keyed_service/core/dependency_node.h"
+#include "components/keyed_service/core/keyed_service_base_factory.h"
 #include "components/keyed_service/core/keyed_service_export.h"
 
 class BrowserContextDependencyManager;
@@ -31,8 +28,7 @@
 // dependency management between Factories; subclasses react to lifecycle
 // events and implement memory management.
 class KEYED_SERVICE_EXPORT BrowserContextKeyedBaseFactory
-    : public base::NonThreadSafe,
-      NON_EXPORTED_BASE(public DependencyNode) {
+    : public KeyedServiceBaseFactory {
  public:
   // Registers preferences used in this service on the pref service of
   // |context|. This is the public interface and is safe to be called multiple
@@ -44,28 +40,11 @@
   void RegisterUserPrefsOnBrowserContextForTest(
       content::BrowserContext* context);
 
-#ifndef NDEBUG
-  // Returns our name. We don't keep track of this in release mode.
-  const char* name() const { return service_name_; }
-#endif
-
  protected:
   BrowserContextKeyedBaseFactory(const char* name,
                                  BrowserContextDependencyManager* manager);
   virtual ~BrowserContextKeyedBaseFactory();
 
-  // The main public interface for declaring dependencies between services
-  // created by factories.
-  void DependsOn(BrowserContextKeyedBaseFactory* rhs);
-
-  // Calls RegisterProfilePrefs() after doing house keeping required to work
-  // alongside RegisterUserPrefsOnBrowserContextForTest().
-  // TODO(gab): This method can be replaced by RegisterProfilePrefs() directly
-  // once RegisterUserPrefsOnBrowserContextForTest() is phased out.
-  void RegisterProfilePrefsIfNecessaryForContext(
-      const content::BrowserContext* context,
-      user_prefs::PrefRegistrySyncable* registry);
-
   // Interface for people building a concrete FooServiceFactory: --------------
 
   // Finds which browser context (if any) to use.
@@ -82,7 +61,7 @@
   // TestingBrowserContext is NULL. (This is just a shortcut around
   // SetTestingFactory() to make sure our contexts don't directly refer to the
   // services they use.)
-  virtual bool ServiceIsNULLWhileTesting() const;
+  virtual bool ServiceIsNULLWhileTesting() const override;
 
   // Interface for people building a type of BrowserContextKeyedFactory: -------
 
@@ -104,31 +83,13 @@
   virtual void BrowserContextShutdown(content::BrowserContext* context) = 0;
   virtual void BrowserContextDestroyed(content::BrowserContext* context);
 
-  // Returns whether we've registered the preferences on this context.
-  bool ArePreferencesSetOn(content::BrowserContext* context) const;
-
-  // Mark context as Preferences set.
-  void MarkPreferencesSetOn(content::BrowserContext* context);
-
-  // Which BrowserContextDependencyManager we should communicate with.
-  // In real code, this will always be
-  // BrowserContextDependencyManager::GetInstance(), but unit tests will want
-  // to use their own copy.
-  BrowserContextDependencyManager* dependency_manager_;
-
  private:
-  friend class BrowserContextDependencyManager;
-  friend class BrowserContextDependencyManagerUnittests;
-
   // Registers any user preferences on this service. This is called by
   // RegisterProfilePrefsIfNecessary() and should be overriden by any service
   // that wants to register profile-specific preferences.
   virtual void RegisterProfilePrefs(
       user_prefs::PrefRegistrySyncable* registry) {}
 
-  // These two methods are for tight integration with the
-  // BrowserContextDependencyManager.
-
   // Because of ServiceIsNULLWhileTesting(), we need a way to tell different
   // subclasses that they should disable testing.
   virtual void SetEmptyTestingFactory(content::BrowserContext* context) = 0;
@@ -140,15 +101,18 @@
   // now for when we're creating the context.
   virtual void CreateServiceNow(content::BrowserContext* context) = 0;
 
-  // BrowserContexts that have this service's preferences registered on them.
-  std::set<const content::BrowserContext*> registered_preferences_;
-
-#if !defined(NDEBUG)
-  // A static string passed in to our constructor. Should be unique across all
-  // services. This is used only for debugging in debug mode. (We can print
-  // pretty graphs with GraphViz with this information.)
-  const char* service_name_;
-#endif
+  // KeyedServiceBaseFactory:
+  virtual user_prefs::PrefRegistrySyncable* GetAssociatedPrefRegistry(
+      base::SupportsUserData* context) const final;
+  virtual base::SupportsUserData* GetContextToUse(
+      base::SupportsUserData* context) const final;
+  virtual bool ServiceIsCreatedWithContext() const final;
+  virtual void ContextShutdown(base::SupportsUserData* context) final;
+  virtual void ContextDestroyed(base::SupportsUserData* context) final;
+  virtual void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) final;
+  virtual void SetEmptyTestingFactory(base::SupportsUserData* context) final;
+  virtual bool HasTestingFactory(base::SupportsUserData* context) final;
+  virtual void CreateServiceNow(base::SupportsUserData* context) final;
 };
 
 #endif  // COMPONENTS_KEYED_SERVICE_CONTENT_BROWSER_CONTEXT_KEYED_BASE_FACTORY_H_
diff --git a/components/keyed_service/content/browser_context_keyed_service_factory.cc b/components/keyed_service/content/browser_context_keyed_service_factory.cc
index 10be1bc9..a33ffed 100644
--- a/components/keyed_service/content/browser_context_keyed_service_factory.cc
+++ b/components/keyed_service/content/browser_context_keyed_service_factory.cc
@@ -26,7 +26,7 @@
   // instance that was destroyed in an earlier test) in order to avoid accesses
   // to |context| in |BrowserContextShutdown| from causing
   // |AssertBrowserContextWasntDestroyed| to raise an error.
-  dependency_manager_->MarkBrowserContextLiveForTesting(context);
+  MarkContextLiveForTesting(context);
 #endif
 
   // We have to go through the shutdown and destroy mechanisms because there
diff --git a/components/keyed_service/core/BUILD.gn b/components/keyed_service/core/BUILD.gn
index bc36aaa..36c842ee 100644
--- a/components/keyed_service/core/BUILD.gn
+++ b/components/keyed_service/core/BUILD.gn
@@ -7,9 +7,13 @@
   sources = [
     "dependency_graph.cc",
     "dependency_graph.h",
+    "dependency_manager.cc",
+    "dependency_manager.h",
     "dependency_node.h",
     "keyed_service.cc",
     "keyed_service.h",
+    "keyed_service_base_factory.cc",
+    "keyed_service_base_factory.h",
     "keyed_service_export.h",
     "refcounted_keyed_service.cc",
     "refcounted_keyed_service.h",
diff --git a/components/keyed_service/core/dependency_manager.cc b/components/keyed_service/core/dependency_manager.cc
new file mode 100644
index 0000000..7eea3cdc
--- /dev/null
+++ b/components/keyed_service/core/dependency_manager.cc
@@ -0,0 +1,139 @@
+// 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 "components/keyed_service/core/dependency_manager.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/supports_user_data.h"
+#include "components/keyed_service/core/keyed_service_base_factory.h"
+
+#ifndef NDEBUG
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#endif  // NDEBUG
+
+DependencyManager::DependencyManager() {
+}
+
+DependencyManager::~DependencyManager() {
+}
+
+void DependencyManager::AddComponent(KeyedServiceBaseFactory* component) {
+  dependency_graph_.AddNode(component);
+}
+
+void DependencyManager::RemoveComponent(KeyedServiceBaseFactory* component) {
+  dependency_graph_.RemoveNode(component);
+}
+
+void DependencyManager::AddEdge(KeyedServiceBaseFactory* depended,
+                                KeyedServiceBaseFactory* dependee) {
+  dependency_graph_.AddEdge(depended, dependee);
+}
+
+void DependencyManager::RegisterPrefsForServices(
+    const base::SupportsUserData* context,
+    user_prefs::PrefRegistrySyncable* pref_registry) {
+  std::vector<DependencyNode*> construction_order;
+  if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
+    NOTREACHED();
+  }
+
+  for (const auto& dependency_node : construction_order) {
+    KeyedServiceBaseFactory* factory =
+        static_cast<KeyedServiceBaseFactory*>(dependency_node);
+    factory->RegisterPrefsIfNecessaryForContext(context, pref_registry);
+  }
+}
+
+void DependencyManager::CreateContextServices(base::SupportsUserData* context,
+                                              bool is_testing_context) {
+#ifndef NDEBUG
+  MarkContextLiveForTesting(context);
+#endif
+
+  std::vector<DependencyNode*> construction_order;
+  if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
+    NOTREACHED();
+  }
+
+#ifndef NDEBUG
+  DumpContextDependencies(context);
+#endif
+
+  for (const auto& dependency_node : construction_order) {
+    KeyedServiceBaseFactory* factory =
+        static_cast<KeyedServiceBaseFactory*>(dependency_node);
+    if (is_testing_context && factory->ServiceIsNULLWhileTesting() &&
+        !factory->HasTestingFactory(context)) {
+      factory->SetEmptyTestingFactory(context);
+    } else if (factory->ServiceIsCreatedWithContext()) {
+      factory->CreateServiceNow(context);
+    }
+  }
+}
+
+void DependencyManager::DestroyContextServices(
+    base::SupportsUserData* context) {
+  std::vector<DependencyNode*> destruction_order;
+  if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
+    NOTREACHED();
+  }
+
+#ifndef NDEBUG
+  DumpContextDependencies(context);
+#endif
+
+  for (const auto& dependency_node : destruction_order) {
+    KeyedServiceBaseFactory* factory =
+        static_cast<KeyedServiceBaseFactory*>(dependency_node);
+    factory->ContextShutdown(context);
+  }
+
+#ifndef NDEBUG
+  // The context is now dead to the rest of the program.
+  dead_context_pointers_.insert(context);
+#endif
+
+  for (const auto& dependency_node : destruction_order) {
+    KeyedServiceBaseFactory* factory =
+        static_cast<KeyedServiceBaseFactory*>(dependency_node);
+    factory->ContextDestroyed(context);
+  }
+}
+
+#ifndef NDEBUG
+void DependencyManager::AssertContextWasntDestroyed(
+    const base::SupportsUserData* context) {
+  if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
+    NOTREACHED() << "Attempted to access a context that was ShutDown(). "
+                 << "This is most likely a heap smasher in progress. After "
+                 << "KeyedService::Shutdown() completes, your service MUST "
+                 << "NOT refer to depended services again.";
+  }
+}
+
+void DependencyManager::MarkContextLiveForTesting(
+    const base::SupportsUserData* context) {
+  dead_context_pointers_.erase(context);
+}
+
+namespace {
+
+std::string KeyedServiceBaseFactoryGetNodeName(DependencyNode* node) {
+  return static_cast<KeyedServiceBaseFactory*>(node)->name();
+}
+
+}  // namespace
+
+void DependencyManager::DumpDependenciesAsGraphviz(
+    const std::string& top_level_name,
+    const base::FilePath& dot_file) const {
+  DCHECK(!dot_file.empty());
+  std::string contents = dependency_graph_.DumpAsGraphviz(
+      top_level_name, base::Bind(&KeyedServiceBaseFactoryGetNodeName));
+  base::WriteFile(dot_file, contents.c_str(), contents.size());
+}
+#endif  // NDEBUG
diff --git a/components/keyed_service/core/dependency_manager.h b/components/keyed_service/core/dependency_manager.h
new file mode 100644
index 0000000..1cce3976
--- /dev/null
+++ b/components/keyed_service/core/dependency_manager.h
@@ -0,0 +1,106 @@
+// 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 COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
+
+#include <string>
+
+#include "components/keyed_service/core/dependency_graph.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+#ifndef NDEBUG
+#include <set>
+#endif
+
+class KeyedServiceBaseFactory;
+
+namespace base {
+class FilePath;
+class SupportsUserData;
+}
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+// DependencyManager manages dependency between KeyedServiceBaseFactory
+// broadcasting the context creation and destruction to each factory in
+// a safe order based on the stated dependencies.
+class KEYED_SERVICE_EXPORT DependencyManager {
+ protected:
+  DependencyManager();
+  virtual ~DependencyManager();
+
+  // Adds/Removes a component from our list of live components. Removing will
+  // also remove live dependency links.
+  void AddComponent(KeyedServiceBaseFactory* component);
+  void RemoveComponent(KeyedServiceBaseFactory* component);
+
+  // Adds a dependency between two factories.
+  void AddEdge(KeyedServiceBaseFactory* depended,
+               KeyedServiceBaseFactory* dependee);
+
+  // Registers preferences for all services via |registry| associated with
+  // |context| (the association is managed by the embedder). The |context|
+  // is used as a key to prevent multiple registration during tests.
+  void RegisterPrefsForServices(const base::SupportsUserData* context,
+                                user_prefs::PrefRegistrySyncable* registry);
+
+  // Called upon creation of |context| to create services that want to be
+  // started at the creation of a context and register service-related
+  // preferences.
+  //
+  // To have a KeyedService started when a context is created the method
+  // KeyedServiceBaseFactory::ServiceIsCreatedWithContext() must be overridden
+  // to return true.
+  //
+  // If |is_testing_context| then the service will not be started unless the
+  // method KeyedServiceBaseFactory::ServiceIsNULLWhileTesting() return false.
+  void CreateContextServices(base::SupportsUserData* context,
+                             bool is_testing_context);
+
+  // Called upon destruction of |context| to destroy all services associated
+  // with it.
+  void DestroyContextServices(base::SupportsUserData* context);
+
+#ifndef NDEBUG
+  // Debugging assertion called as part of GetServiceForContext() in debug
+  // mode. This will NOTREACHED() whenever the |context| is considered stale.
+  void AssertContextWasntDestroyed(const base::SupportsUserData* context);
+
+  // Marks |context| as live (i.e., not stale). This method can be called as a
+  // safeguard against |AssertContextWasntDestroyed()| checks going off due to
+  // |context| aliasing am instance from a prior test (i.e., 0xWhatever might
+  // be created, be destroyed, and then a new object might be created at
+  // 0xWhatever).
+  void MarkContextLiveForTesting(const base::SupportsUserData* context);
+
+  // Dumps service dependency graph as a Graphviz dot file |dot_file| with a
+  // title |top_level_name|. Helper for |DumpContextDependencies|.
+  void DumpDependenciesAsGraphviz(const std::string& top_level_name,
+                                  const base::FilePath& dot_file) const;
+#endif  // NDEBUG
+
+ private:
+  friend class KeyedServiceBaseFactory;
+
+#ifndef NDEBUG
+  // Hook for subclass to dump the dependency graph of service for |context|.
+  virtual void DumpContextDependencies(
+      const base::SupportsUserData* context) const = 0;
+#endif  // NDEBUG
+
+  DependencyGraph dependency_graph_;
+
+#ifndef NDEBUG
+  // A list of context objects that have gone through the Shutdown() phase.
+  // These pointers are most likely invalid, but we keep track of their
+  // locations in memory so we can nicely assert if we're asked to do anything
+  // with them.
+  std::set<const base::SupportsUserData*> dead_context_pointers_;
+#endif  // NDEBUG
+};
+
+#endif  // COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
diff --git a/components/keyed_service/core/keyed_service_base_factory.cc b/components/keyed_service/core/keyed_service_base_factory.cc
new file mode 100644
index 0000000..02e3fa81
--- /dev/null
+++ b/components/keyed_service/core/keyed_service_base_factory.cc
@@ -0,0 +1,111 @@
+// 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 "components/keyed_service/core/keyed_service_base_factory.h"
+
+#include "base/prefs/pref_service.h"
+#include "base/supports_user_data.h"
+#include "components/keyed_service/core/dependency_manager.h"
+// #include "components/pref_registry/pref_registry_syncable.h"
+// #include "components/user_prefs/user_prefs.h"
+// #include "content/public/browser/browser_context.h"
+
+void KeyedServiceBaseFactory::RegisterUserPrefsOnContextForTest(
+    base::SupportsUserData* context) {
+  // Safe timing for pref registration is hard. Previously, we made
+  // context responsible for all pref registration on every service
+  // that used contexts. Now we don't and there are timing issues.
+  //
+  // With normal contexts, prefs can simply be registered at
+  // DependencyManager::RegisterProfilePrefsForServices time.
+  // With incognito contexts, we just never register since incognito
+  // contexts share the same pref services with their parent contexts.
+  //
+  // Testing contexts throw a wrench into the mix, in that some tests will
+  // swap out the PrefService after we've registered user prefs on the original
+  // PrefService. Test code that does this is responsible for either manually
+  // invoking RegisterProfilePrefs() on the appropriate
+  // ContextKeyedServiceFactory associated with the prefs they need,
+  // or they can use SetTestingFactory() and create a service (since service
+  // creation with a factory method causes registration to happen at
+  // TestingProfile creation time).
+  //
+  // Now that services are responsible for declaring their preferences, we have
+  // to enforce a uniquenes check here because some tests create one context and
+  // multiple services of the same type attached to that context (serially, not
+  // parallel) and we don't want to register multiple times on the same context.
+  // This is the purpose of RegisterProfilePrefsIfNecessary() which could be
+  // replaced directly by RegisterProfilePrefs() if this method is ever phased
+  // out.
+  RegisterPrefsIfNecessaryForContext(context,
+                                     GetAssociatedPrefRegistry(context));
+}
+
+KeyedServiceBaseFactory::KeyedServiceBaseFactory(const char* service_name,
+                                                 DependencyManager* manager)
+    : dependency_manager_(manager) {
+#ifndef NDEBUG
+  service_name_ = service_name;
+#endif
+  dependency_manager_->AddComponent(this);
+}
+
+KeyedServiceBaseFactory::~KeyedServiceBaseFactory() {
+  dependency_manager_->RemoveComponent(this);
+}
+
+void KeyedServiceBaseFactory::DependsOn(KeyedServiceBaseFactory* rhs) {
+  dependency_manager_->AddEdge(rhs, this);
+}
+
+void KeyedServiceBaseFactory::RegisterPrefsIfNecessaryForContext(
+    const base::SupportsUserData* context,
+    user_prefs::PrefRegistrySyncable* registry) {
+  if (!ArePreferencesSetOn(context)) {
+    RegisterPrefs(registry);
+    MarkPreferencesSetOn(context);
+  }
+}
+
+#ifndef NDEBUG
+void KeyedServiceBaseFactory::AssertContextWasntDestroyed(
+    const base::SupportsUserData* context) const {
+  DCHECK(CalledOnValidThread());
+  dependency_manager_->AssertContextWasntDestroyed(context);
+}
+
+void KeyedServiceBaseFactory::MarkContextLiveForTesting(
+    const base::SupportsUserData* context) {
+  DCHECK(CalledOnValidThread());
+  dependency_manager_->MarkContextLiveForTesting(context);
+}
+#endif
+
+bool KeyedServiceBaseFactory::ServiceIsCreatedWithContext() const {
+  return false;
+}
+
+bool KeyedServiceBaseFactory::ServiceIsNULLWhileTesting() const {
+  return false;
+}
+
+void KeyedServiceBaseFactory::ContextDestroyed(
+    base::SupportsUserData* context) {
+  // While object destruction can be customized in ways where the object is
+  // only dereferenced, this still must run on the UI thread.
+  DCHECK(CalledOnValidThread());
+
+  registered_preferences_.erase(context);
+}
+
+bool KeyedServiceBaseFactory::ArePreferencesSetOn(
+    const base::SupportsUserData* context) const {
+  return registered_preferences_.find(context) != registered_preferences_.end();
+}
+
+void KeyedServiceBaseFactory::MarkPreferencesSetOn(
+    const base::SupportsUserData* context) {
+  DCHECK(!ArePreferencesSetOn(context));
+  registered_preferences_.insert(context);
+}
diff --git a/components/keyed_service/core/keyed_service_base_factory.h b/components/keyed_service/core/keyed_service_base_factory.h
new file mode 100644
index 0000000..89225ec
--- /dev/null
+++ b/components/keyed_service/core/keyed_service_base_factory.h
@@ -0,0 +1,148 @@
+// 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 COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_BASE_FACTORY_H_
+#define COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_BASE_FACTORY_H_
+
+#include <set>
+
+#include "base/threading/non_thread_safe.h"
+#include "components/keyed_service/core/dependency_node.h"
+#include "components/keyed_service/core/keyed_service_export.h"
+
+class DependencyManager;
+class PrefService;
+
+namespace base {
+class SupportsUserData;
+}
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+// Base class for factories that take a base::SupportsUserData and return some
+// service. Not for direct usage, instead use descendent classes that deal with
+// more specific context objects.
+//
+// This object describes general dependency management between factories while
+// direct subclasses react to lifecycle events and implement memory management.
+class KEYED_SERVICE_EXPORT KeyedServiceBaseFactory
+    : public base::NonThreadSafe,
+      NON_EXPORTED_BASE(public DependencyNode) {
+ public:
+#ifndef NDEBUG
+  // Returns our name. We don't keep track of this in release mode.
+  const char* name() const { return service_name_; }
+#endif
+
+ protected:
+  KeyedServiceBaseFactory(const char* service_name, DependencyManager* manager);
+  virtual ~KeyedServiceBaseFactory();
+
+  // Registers preferences used in this service on the pref service associated
+  // with |context|. This is safe to be called multiple times because testing
+  // code can have multiple services of the same type attached to a single
+  // |context|. Only test code is allowed to call this method.
+  //
+  // TODO(gab): This method can be removed entirely when
+  // PrefService::DeprecatedGetPrefRegistry() is phased out.
+  void RegisterUserPrefsOnContextForTest(base::SupportsUserData* context);
+
+  // The main public interface for declaring dependencies between services
+  // created by factories.
+  void DependsOn(KeyedServiceBaseFactory* rhs);
+
+#ifndef NDEBUG
+  // Debugging assertion that will NOTREACHED() is |context| is considered
+  // stale. Should be used by subclasses when accessing |context|.
+  void AssertContextWasntDestroyed(const base::SupportsUserData* context) const;
+
+  // Marks |context| as live (i.e., not stale). This method can be called as a
+  // safeguard against |AssertContextWasntDestroyed()| checks going off due to
+  // |context| aliasing am instance from a prior test (i.e., 0xWhatever might
+  // be created, be destroyed, and then a new object might be created at
+  // 0xWhatever).
+  void MarkContextLiveForTesting(const base::SupportsUserData* context);
+#endif
+
+  // Calls RegisterProfilePrefs() after doing house keeping required to work
+  // alongside RegisterUserPrefsOnContextForTest().
+  // TODO(gab): This method can be replaced by RegisterProfilePrefs() directly
+  // once RegisterUserPrefsOnContextForTest() is phased out.
+  void RegisterPrefsIfNecessaryForContext(
+      const base::SupportsUserData* context,
+      user_prefs::PrefRegistrySyncable* registry);
+
+  // Returns the |user_pref::PrefRegistrySyncable| associated with |context|.
+  // The way they are associated is controlled by the embedder.
+  virtual user_prefs::PrefRegistrySyncable* GetAssociatedPrefRegistry(
+      base::SupportsUserData* context) const = 0;
+
+  // Finds which context (if any) to use.
+  virtual base::SupportsUserData* GetContextToUse(
+      base::SupportsUserData* context) const = 0;
+
+  // By default, instance of a service are created lazily when GetForContext()
+  // is called by the subclass. Some services need to be created as soon as the
+  // context is created and should override this method to return true.
+  virtual bool ServiceIsCreatedWithContext() const;
+
+  // By default, testing contexts will be treated like normal contexts. If this
+  // method is overriden to return false, then the service associated with the
+  // testing context will be NULL.
+  virtual bool ServiceIsNULLWhileTesting() const;
+
+  // The service build by the factories goes through a two phase shutdown.
+  // It is up to the individual factory types to determine what this two pass
+  // shutdown means. The general framework guarantees the following:
+  //
+  // - Each ContextShutdown() is called in dependency order (and you may
+  //   reach out to other services during this phase).
+  //
+  // - Each ContextDestroyed() is called in dependency order. Accessing a
+  //   service with GetForContext() will NOTREACHED() and code should delete/
+  //   deref/do other final memory management during this phase. The base class
+  //   method *must* be called as the last thing.
+  virtual void ContextShutdown(base::SupportsUserData* context) = 0;
+  virtual void ContextDestroyed(base::SupportsUserData* context);
+
+  // Returns whether the preferences have been registered on this context.
+  bool ArePreferencesSetOn(const base::SupportsUserData* context) const;
+
+  // Mark context has having preferences registered.
+  void MarkPreferencesSetOn(const base::SupportsUserData* context);
+
+ private:
+  friend class DependencyManager;
+
+  // The DependencyManager used. In real code, this will be a singleton used
+  // by all the factories of a given type. Unit tests will use their own copy.
+  DependencyManager* dependency_manager_;
+
+  // Registers any preferences used by this service.
+  virtual void RegisterPrefs(user_prefs::PrefRegistrySyncable* registry) {}
+
+  // Used by DependencyManager to disable creation of the service when the
+  // method ServiceIsNULLWhileTesting() returns true.
+  virtual void SetEmptyTestingFactory(base::SupportsUserData* context) = 0;
+
+  // Returns true if a testing factory function has been set for |context|.
+  virtual bool HasTestingFactory(base::SupportsUserData* context) = 0;
+
+  // Create the service associated with |context|.
+  virtual void CreateServiceNow(base::SupportsUserData* context) = 0;
+
+  // Contexts that have this service's preferences registered on them.
+  std::set<const base::SupportsUserData*> registered_preferences_;
+
+#if !defined(NDEBUG)
+  // A static string passed in to the constructor. Should be unique across all
+  // services. This is used only for debugging in debug mode. (Used to print
+  // pretty graphs with GraphViz.)
+  const char* service_name_;
+#endif
+};
+
+#endif  // COMPONENTS_KEYED_SERVICE_CORE_KEYED_SERVICE_BASE_FACTORY_H_
diff --git a/components/login.gypi b/components/login.gypi
new file mode 100644
index 0000000..bc9f916
--- /dev/null
+++ b/components/login.gypi
@@ -0,0 +1,22 @@
+# 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.
+
+{
+  'targets': [{
+    'target_name': 'login',
+    'type': '<(component)',
+    'dependencies': [
+      '<(DEPTH)/base/base.gyp:base',
+    ],
+    'defines': [
+      'LOGIN_IMPLEMENTATION',
+    ],
+    'sources': [
+      'login/base_screen_handler_utils.cc',
+      'login/base_screen_handler_utils.h',
+      'login/screens/screen_context.cc',
+      'login/screens/screen_context.h',
+    ],
+  }],
+}
diff --git a/components/login/BUILD.gn b/components/login/BUILD.gn
new file mode 100644
index 0000000..12caf6a
--- /dev/null
+++ b/components/login/BUILD.gn
@@ -0,0 +1,30 @@
+# 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.
+
+component("login") {
+  sources = [
+    "base_screen_handler_utils.cc",
+    "base_screen_handler_utils.h",
+    "screens/screen_context.cc",
+    "screens/screen_context.h",
+  ]
+
+  defines = [
+    "LOGIN_IMPLEMENTATION"
+  ]
+
+  deps = [
+    "//base",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = ["screens/screen_context_unittest.cc"]
+
+  deps = [
+    ":login",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/login/OWNERS b/components/login/OWNERS
new file mode 100644
index 0000000..9ff5cc2
--- /dev/null
+++ b/components/login/OWNERS
@@ -0,0 +1,8 @@
+alemate@chromium.org
+antrim@chromium.org
+davemoore@chromium.org
+dpolukhin@chromium.org
+dzhioev@chromium.org
+nkostylev@chromium.org
+piman@chromium.org
+ygorshenin@chromium.org
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.cc b/components/login/base_screen_handler_utils.cc
similarity index 93%
rename from chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.cc
rename to components/login/base_screen_handler_utils.cc
index a0a9745..782c064 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.cc
+++ b/components/login/base_screen_handler_utils.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.h"
+#include "components/login/base_screen_handler_utils.h"
 
-namespace chromeos {
+namespace login {
 
 namespace {
 
@@ -83,4 +83,4 @@
   callback.Run();
 }
 
-}  // namespace chromeos
+}  // namespace login
diff --git a/components/login/base_screen_handler_utils.h b/components/login/base_screen_handler_utils.h
new file mode 100644
index 0000000..63e55129
--- /dev/null
+++ b/components/login/base_screen_handler_utils.h
@@ -0,0 +1,127 @@
+// Copyright (c) 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 COMPONENTS_LOGIN_BASE_SCREEN_HANDLER_UTILS_H_
+#define COMPONENTS_LOGIN_BASE_SCREEN_HANDLER_UTILS_H_
+
+#include <cstddef>
+#include <string>
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/strings/string16.h"
+#include "base/values.h"
+#include "components/login/login_export.h"
+
+namespace login {
+
+typedef std::vector<std::string> StringList;
+typedef std::vector<base::string16> String16List;
+
+template <typename T>
+struct LOGIN_EXPORT UnwrapConstRef {
+  typedef T Type;
+};
+
+template <typename T>
+struct LOGIN_EXPORT UnwrapConstRef<const T&> {
+  typedef T Type;
+};
+
+bool LOGIN_EXPORT ParseValue(const base::Value* value, bool* out_value);
+bool LOGIN_EXPORT ParseValue(const base::Value* value, int* out_value);
+bool LOGIN_EXPORT ParseValue(const base::Value* value, double* out_value);
+bool LOGIN_EXPORT ParseValue(const base::Value* value, std::string* out_value);
+bool LOGIN_EXPORT
+    ParseValue(const base::Value* value, base::string16* out_value);
+bool LOGIN_EXPORT ParseValue(const base::Value* value,
+                             const base::DictionaryValue** out_value);
+bool LOGIN_EXPORT ParseValue(const base::Value* value, StringList* out_value);
+bool LOGIN_EXPORT ParseValue(const base::Value* value, String16List* out_value);
+
+template <typename T>
+inline bool GetArg(const base::ListValue* args, size_t index, T* out_value) {
+  const base::Value* value;
+  if (!args->Get(index, &value))
+    return false;
+  return ParseValue(value, out_value);
+}
+
+base::FundamentalValue LOGIN_EXPORT MakeValue(bool v);
+base::FundamentalValue LOGIN_EXPORT MakeValue(int v);
+base::FundamentalValue LOGIN_EXPORT MakeValue(double v);
+base::StringValue LOGIN_EXPORT MakeValue(const std::string& v);
+base::StringValue LOGIN_EXPORT MakeValue(const base::string16& v);
+
+template <typename T>
+inline const T& MakeValue(const T& v) {
+  return v;
+}
+
+void LOGIN_EXPORT CallbackWrapper0(base::Callback<void()> callback,
+                                   const base::ListValue* args);
+
+template <typename A1>
+void CallbackWrapper1(base::Callback<void(A1)> callback,
+                      const base::ListValue* args) {
+  DCHECK(args);
+  DCHECK_EQ(1u, args->GetSize());
+  typename UnwrapConstRef<A1>::Type arg1;
+  if (!GetArg(args, 0, &arg1)) {
+    NOTREACHED();
+    return;
+  }
+  callback.Run(arg1);
+}
+
+template <typename A1, typename A2>
+void CallbackWrapper2(base::Callback<void(A1, A2)> callback,
+                      const base::ListValue* args) {
+  DCHECK(args);
+  DCHECK_EQ(2u, args->GetSize());
+  typename UnwrapConstRef<A1>::Type arg1;
+  typename UnwrapConstRef<A2>::Type arg2;
+  if (!GetArg(args, 0, &arg1) || !GetArg(args, 1, &arg2)) {
+    NOTREACHED();
+    return;
+  }
+  callback.Run(arg1, arg2);
+}
+
+template <typename A1, typename A2, typename A3>
+void CallbackWrapper3(base::Callback<void(A1, A2, A3)> callback,
+                      const base::ListValue* args) {
+  DCHECK(args);
+  DCHECK_EQ(3u, args->GetSize());
+  typename UnwrapConstRef<A1>::Type arg1;
+  typename UnwrapConstRef<A2>::Type arg2;
+  typename UnwrapConstRef<A3>::Type arg3;
+  if (!GetArg(args, 0, &arg1) || !GetArg(args, 1, &arg2) ||
+      !GetArg(args, 2, &arg3)) {
+    NOTREACHED();
+    return;
+  }
+  callback.Run(arg1, arg2, arg3);
+}
+
+template <typename A1, typename A2, typename A3, typename A4>
+void CallbackWrapper4(base::Callback<void(A1, A2, A3, A4)> callback,
+                      const base::ListValue* args) {
+  DCHECK(args);
+  DCHECK_EQ(4u, args->GetSize());
+  typename UnwrapConstRef<A1>::Type arg1;
+  typename UnwrapConstRef<A2>::Type arg2;
+  typename UnwrapConstRef<A3>::Type arg3;
+  typename UnwrapConstRef<A4>::Type arg4;
+  if (!GetArg(args, 0, &arg1) || !GetArg(args, 1, &arg2) ||
+      !GetArg(args, 2, &arg3) || !GetArg(args, 3, &arg4)) {
+    NOTREACHED();
+    return;
+  }
+  callback.Run(arg1, arg2, arg3, arg4);
+}
+
+}  // namespace login
+
+#endif  // COMPONENTS_LOGIN_BASE_SCREEN_HANDLER_UTILS_H_
diff --git a/components/login/login_export.h b/components/login/login_export.h
new file mode 100644
index 0000000..2ae7bef
--- /dev/null
+++ b/components/login/login_export.h
@@ -0,0 +1,34 @@
+// 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 COMPONENTS_LOGIN_LOGIN_EXPORT_H_
+#define COMPONENTS_LOGIN_LOGIN_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+
+#if defined(WIN32)
+
+#if defined(LOGIN_IMPLEMENTATION)
+#define LOGIN_EXPORT __declspec(dllexport)
+#else
+#define LOGIN_EXPORT __declspec(dllimport)
+#endif  // defined(LOGIN_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+
+#if defined(LOGIN_IMPLEMENTATION)
+#define LOGIN_EXPORT __attribute__((visibility("default")))
+#else
+#define LOGIN_EXPORT
+#endif  // defined(LOGIN_IMPLEMENTATION)
+
+#endif  // defined(WIN32)
+
+#else  // defined(COMPONENT_BUILD)
+
+#define LOGIN_EXPORT
+
+#endif
+
+#endif  // COMPONENTS_LOGIN_LOGIN_EXPORT_H_
diff --git a/chrome/browser/chromeos/login/screens/screen_context.cc b/components/login/screens/screen_context.cc
similarity index 97%
rename from chrome/browser/chromeos/login/screens/screen_context.cc
rename to components/login/screens/screen_context.cc
index e4fe850..5324164e 100644
--- a/chrome/browser/chromeos/login/screens/screen_context.cc
+++ b/components/login/screens/screen_context.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/chromeos/login/screens/screen_context.h"
+#include "components/login/screens/screen_context.h"
 
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 
-namespace chromeos {
+namespace login {
 
 namespace {
 
@@ -174,4 +174,4 @@
   return true;
 }
 
-}  // namespace chromeos
+}  // namespace login
diff --git a/chrome/browser/chromeos/login/screens/screen_context.h b/components/login/screens/screen_context.h
similarity index 91%
rename from chrome/browser/chromeos/login/screens/screen_context.h
rename to components/login/screens/screen_context.h
index 317d1737..6de612f 100644
--- a/chrome/browser/chromeos/login/screens/screen_context.h
+++ b/components/login/screens/screen_context.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_SCREEN_CONTEXT_H_
-#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_SCREEN_CONTEXT_H_
+#ifndef COMPONENTS_LOGIN_SCREENS_SCREEN_CONTEXT_H_
+#define COMPONENTS_LOGIN_SCREENS_SCREEN_CONTEXT_H_
 
 #include <string>
 #include <vector>
@@ -15,9 +15,10 @@
 #include "base/strings/string16.h"
 #include "base/threading/non_thread_safe.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler_utils.h"
+#include "components/login/base_screen_handler_utils.h"
+#include "components/login/login_export.h"
 
-namespace chromeos {
+namespace login {
 
 // ScreenContext is a key-value storage for values that are shared
 // between C++ and JS sides. Objects of this class should be used in
@@ -32,7 +33,7 @@
 // ScreenContext memorizes changed key-value pairs and returns them
 // via GetChangesAndReset() method. After call to this method an
 // internal buffer of changes will be cleared.
-class ScreenContext : public base::NonThreadSafe {
+class LOGIN_EXPORT ScreenContext : public base::NonThreadSafe {
  public:
   typedef std::string KeyType;
   typedef base::Value ValueType;
@@ -121,6 +122,6 @@
   DISALLOW_COPY_AND_ASSIGN(ScreenContext);
 };
 
-}  // namespace chromeos
+}  // namespace login
 
-#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_SCREEN_CONTEXT_H_
+#endif  // COMPONENTS_LOGIN_SCREENS_SCREEN_CONTEXT_H_
diff --git a/chrome/browser/chromeos/login/screens/screen_context_unittest.cc b/components/login/screens/screen_context_unittest.cc
similarity index 94%
rename from chrome/browser/chromeos/login/screens/screen_context_unittest.cc
rename to components/login/screens/screen_context_unittest.cc
index ca057c3..4deac92 100644
--- a/chrome/browser/chromeos/login/screens/screen_context_unittest.cc
+++ b/components/login/screens/screen_context_unittest.cc
@@ -6,22 +6,19 @@
 #include <vector>
 
 #include "base/memory/scoped_ptr.h"
-#include "chrome/browser/chromeos/login/screens/screen_context.h"
+#include "components/login/screens/screen_context.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace login {
 
 class ScreenContextTest : public testing::Test {
  public:
   ScreenContextTest() {}
   virtual ~ScreenContextTest() {}
 
-  virtual void SetUp() {
-    context_.reset(new ScreenContext());
-  }
+  virtual void SetUp() { context_.reset(new ScreenContext()); }
 
-  virtual void TearDown() {
-  }
+  virtual void TearDown() {}
 
  protected:
   ScreenContext& context() { return *context_.get(); }
@@ -154,4 +151,4 @@
   ASSERT_TRUE(context().GetBoolean("key2"));
 }
 
-}  // namespace chromeos
+}  // namespace login
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index 8bccd458..13c34a9 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -138,4 +138,27 @@
   }
 }
 
+source_set("unit_tests") {
+  testonly = true
+  sources = [
+    "compression_utils_unittest.cc",
+    "daily_event_unittest.cc",
+    "machine_id_provider_win_unittest.cc",
+    "metrics_hashes_unittest.cc",
+    "metrics_log_manager_unittest.cc",
+    "metrics_log_unittest.cc",
+    "metrics_reporting_scheduler_unittest.cc",
+    "metrics_service_unittest.cc",
+    "metrics_state_manager_unittest.cc",
+    "persisted_logs_unittest.cc",
+    "profiler/profiler_metrics_provider_unittest.cc",
+  ]
+
+  deps = [
+    ":metrics",
+    "//base/test:test_support",
+    "//testing/gtest",
+  ]
+}
+
 # TODO(GYP): metrics_chromeos
diff --git a/components/metrics/DEPS b/components/metrics/DEPS
index dfb4de1d..aa5bdc7 100644
--- a/components/metrics/DEPS
+++ b/components/metrics/DEPS
@@ -1,4 +1,8 @@
+# This component is shared with the Chrome OS build, so it's important to limit
+# dependencies to a minimal set.
 include_rules = [ 
+  "-components",
+  "+components/metrics",
   "+components/variations",
   "-net",
   "+third_party/zlib",
diff --git a/components/metrics/clean_exit_beacon.cc b/components/metrics/clean_exit_beacon.cc
index 595d05c0..422a1100 100644
--- a/components/metrics/clean_exit_beacon.cc
+++ b/components/metrics/clean_exit_beacon.cc
@@ -19,8 +19,7 @@
 CleanExitBeacon::CleanExitBeacon(const base::string16& backup_registry_key,
                                  PrefService* local_state)
     : local_state_(local_state),
-      initial_value_(
-          local_state->GetBoolean(metrics::prefs::kStabilityExitedCleanly)),
+      initial_value_(local_state->GetBoolean(prefs::kStabilityExitedCleanly)),
       backup_registry_key_(backup_registry_key) {
   DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING,
             local_state_->GetInitializationStatus());
@@ -44,8 +43,8 @@
                   backup_registry_key_.c_str(),
                   KEY_ALL_ACCESS) == ERROR_SUCCESS &&
       regkey.ReadValueDW(
-          base::ASCIIToUTF16(metrics::prefs::kStabilityExitedCleanly).c_str(),
-          &value) == ERROR_SUCCESS) {
+          base::ASCIIToUTF16(prefs::kStabilityExitedCleanly).c_str(), &value) ==
+          ERROR_SUCCESS) {
     if (value)
       consistency = initial_value_ ? CLEAN_CLEAN : CLEAN_DIRTY;
     else
@@ -63,7 +62,7 @@
 }
 
 void CleanExitBeacon::WriteBeaconValue(bool value) {
-  local_state_->SetBoolean(metrics::prefs::kStabilityExitedCleanly, value);
+  local_state_->SetBoolean(prefs::kStabilityExitedCleanly, value);
 
 #if defined(OS_WIN)
   base::win::RegKey regkey;
@@ -71,7 +70,7 @@
                     backup_registry_key_.c_str(),
                     KEY_ALL_ACCESS) == ERROR_SUCCESS) {
     regkey.WriteValue(
-        base::ASCIIToUTF16(metrics::prefs::kStabilityExitedCleanly).c_str(),
+        base::ASCIIToUTF16(prefs::kStabilityExitedCleanly).c_str(),
         value ? 1u : 0u);
   }
 #endif
diff --git a/components/metrics/cloned_install_detector.cc b/components/metrics/cloned_install_detector.cc
index b93e6e6..be89bb9 100644
--- a/components/metrics/cloned_install_detector.cc
+++ b/components/metrics/cloned_install_detector.cc
@@ -4,6 +4,8 @@
 
 #include "components/metrics/cloned_install_detector.h"
 
+#include <string>
+
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/metrics/histogram.h"
@@ -11,7 +13,6 @@
 #include "base/prefs/pref_service.h"
 #include "base/single_thread_task_runner.h"
 #include "base/task_runner_util.h"
-#include "components/metrics/cloned_install_detector.h"
 #include "components/metrics/machine_id_provider.h"
 #include "components/metrics/metrics_hashes.h"
 #include "components/metrics/metrics_pref_names.h"
@@ -21,7 +22,7 @@
 namespace {
 
 uint32 HashRawId(const std::string& value) {
-  uint64 hash = metrics::HashMetricName(value);
+  uint64 hash = HashMetricName(value);
 
   // Only use 24 bits from the 64-bit hash.
   return hash & ((1 << 24) - 1);
@@ -57,8 +58,8 @@
   base::PostTaskAndReplyWithResult(
       task_runner.get(),
       FROM_HERE,
-      base::Bind(&metrics::MachineIdProvider::GetMachineId, raw_id_provider_),
-      base::Bind(&metrics::ClonedInstallDetector::SaveMachineId,
+      base::Bind(&MachineIdProvider::GetMachineId, raw_id_provider_),
+      base::Bind(&ClonedInstallDetector::SaveMachineId,
                  weak_ptr_factory_.GetWeakPtr(),
                  local_state));
 }
diff --git a/components/metrics/daily_event_unittest.cc b/components/metrics/daily_event_unittest.cc
index d15def1..c600ee9 100644
--- a/components/metrics/daily_event_unittest.cc
+++ b/components/metrics/daily_event_unittest.cc
@@ -38,8 +38,7 @@
   DailyEventTest() : event_(&prefs_, kTestPrefName, kTestMetricName) {
     DailyEvent::RegisterPref(prefs_.registry(), kTestPrefName);
     observer_ = new TestDailyObserver();
-    scoped_ptr<metrics::DailyEvent::Observer> p(observer_);
-    event_.AddObserver(p.Pass());
+    event_.AddObserver(make_scoped_ptr(observer_));
   }
 
  protected:
diff --git a/components/metrics/gpu/gpu_metrics_provider_unittest.cc b/components/metrics/gpu/gpu_metrics_provider_unittest.cc
index 6624922..64f9579 100644
--- a/components/metrics/gpu/gpu_metrics_provider_unittest.cc
+++ b/components/metrics/gpu/gpu_metrics_provider_unittest.cc
@@ -50,12 +50,12 @@
 
 TEST_F(GPUMetricsProviderTest, ProvideSystemProfileMetrics) {
   TestGPUMetricsProvider provider;
-  metrics::ChromeUserMetricsExtension uma_proto;
+  ChromeUserMetricsExtension uma_proto;
 
   provider.ProvideSystemProfileMetrics(uma_proto.mutable_system_profile());
 
   // Check that the system profile has the correct values set.
-  const metrics::SystemProfileProto::Hardware& hardware =
+  const SystemProfileProto::Hardware& hardware =
       uma_proto.system_profile().hardware();
   EXPECT_EQ(kScreenWidth, hardware.primary_screen_width());
   EXPECT_EQ(kScreenHeight, hardware.primary_screen_height());
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc
index c8315f0c..4db3bb5e 100644
--- a/components/metrics/metrics_service.cc
+++ b/components/metrics/metrics_service.cc
@@ -262,7 +262,7 @@
 void MarkAppCleanShutdownAndCommit(CleanExitBeacon* clean_exit_beacon,
                                    PrefService* local_state) {
   clean_exit_beacon->WriteBeaconValue(true);
-  local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase,
+  local_state->SetInteger(prefs::kStabilityExecutionPhase,
                           MetricsService::SHUTDOWN_COMPLETE);
   // Start writing right away (write happens on a different thread).
   local_state->CommitPendingWrite();
@@ -289,32 +289,30 @@
 // static
 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) {
   DCHECK(IsSingleThreaded());
-  metrics::MetricsStateManager::RegisterPrefs(registry);
+  MetricsStateManager::RegisterPrefs(registry);
   MetricsLog::RegisterPrefs(registry);
 
-  registry->RegisterInt64Pref(metrics::prefs::kInstallDate, 0);
+  registry->RegisterInt64Pref(prefs::kInstallDate, 0);
 
-  registry->RegisterInt64Pref(metrics::prefs::kStabilityLaunchTimeSec, 0);
-  registry->RegisterInt64Pref(metrics::prefs::kStabilityLastTimestampSec, 0);
-  registry->RegisterStringPref(metrics::prefs::kStabilityStatsVersion,
-                               std::string());
-  registry->RegisterInt64Pref(metrics::prefs::kStabilityStatsBuildTime, 0);
-  registry->RegisterBooleanPref(metrics::prefs::kStabilityExitedCleanly, true);
-  registry->RegisterIntegerPref(metrics::prefs::kStabilityExecutionPhase,
+  registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0);
+  registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0);
+  registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string());
+  registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0);
+  registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true);
+  registry->RegisterIntegerPref(prefs::kStabilityExecutionPhase,
                                 UNINITIALIZED_PHASE);
-  registry->RegisterBooleanPref(metrics::prefs::kStabilitySessionEndCompleted,
-                                true);
-  registry->RegisterIntegerPref(metrics::prefs::kMetricsSessionID, -1);
+  registry->RegisterBooleanPref(prefs::kStabilitySessionEndCompleted, true);
+  registry->RegisterIntegerPref(prefs::kMetricsSessionID, -1);
 
-  registry->RegisterListPref(metrics::prefs::kMetricsInitialLogs);
-  registry->RegisterListPref(metrics::prefs::kMetricsOngoingLogs);
+  registry->RegisterListPref(prefs::kMetricsInitialLogs);
+  registry->RegisterListPref(prefs::kMetricsOngoingLogs);
 
-  registry->RegisterInt64Pref(metrics::prefs::kUninstallLaunchCount, 0);
-  registry->RegisterInt64Pref(metrics::prefs::kUninstallMetricsUptimeSec, 0);
+  registry->RegisterInt64Pref(prefs::kUninstallLaunchCount, 0);
+  registry->RegisterInt64Pref(prefs::kUninstallMetricsUptimeSec, 0);
 }
 
-MetricsService::MetricsService(metrics::MetricsStateManager* state_manager,
-                               metrics::MetricsServiceClient* client,
+MetricsService::MetricsService(MetricsStateManager* state_manager,
+                               MetricsServiceClient* client,
                                PrefService* local_state)
     : log_manager_(local_state, kUploadLogAvoidRetransmitSize),
       histogram_snapshot_manager_(this),
@@ -338,11 +336,9 @@
   DCHECK(local_state_);
 
   // Set the install date if this is our first run.
-  int64 install_date = local_state_->GetInt64(metrics::prefs::kInstallDate);
-  if (install_date == 0) {
-    local_state_->SetInt64(metrics::prefs::kInstallDate,
-                           base::Time::Now().ToTimeT());
-  }
+  int64 install_date = local_state_->GetInt64(prefs::kInstallDate);
+  if (install_date == 0)
+    local_state_->SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT());
 }
 
 MetricsService::~MetricsService() {
@@ -398,7 +394,7 @@
 }
 
 int64 MetricsService::GetInstallDate() {
-  return local_state_->GetInt64(metrics::prefs::kInstallDate);
+  return local_state_->GetInt64(prefs::kInstallDate);
 }
 
 scoped_ptr<const base::FieldTrial::EntropyProvider>
@@ -493,12 +489,12 @@
 
 void MetricsService::RecordStartOfSessionEnd() {
   LogCleanShutdown();
-  RecordBooleanPrefValue(metrics::prefs::kStabilitySessionEndCompleted, false);
+  RecordBooleanPrefValue(prefs::kStabilitySessionEndCompleted, false);
 }
 
 void MetricsService::RecordCompletedSessionEnd() {
   LogCleanShutdown();
-  RecordBooleanPrefValue(metrics::prefs::kStabilitySessionEndCompleted, true);
+  RecordBooleanPrefValue(prefs::kStabilitySessionEndCompleted, true);
 }
 
 #if defined(OS_ANDROID) || defined(OS_IOS)
@@ -536,22 +532,21 @@
 void MetricsService::SetExecutionPhase(ExecutionPhase execution_phase,
                                        PrefService* local_state) {
   execution_phase_ = execution_phase;
-  local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase,
-                          execution_phase_);
+  local_state->SetInteger(prefs::kStabilityExecutionPhase, execution_phase_);
 }
 
 void MetricsService::RecordBreakpadRegistration(bool success) {
   if (!success)
-    IncrementPrefValue(metrics::prefs::kStabilityBreakpadRegistrationFail);
+    IncrementPrefValue(prefs::kStabilityBreakpadRegistrationFail);
   else
-    IncrementPrefValue(metrics::prefs::kStabilityBreakpadRegistrationSuccess);
+    IncrementPrefValue(prefs::kStabilityBreakpadRegistrationSuccess);
 }
 
 void MetricsService::RecordBreakpadHasDebugger(bool has_debugger) {
   if (!has_debugger)
-    IncrementPrefValue(metrics::prefs::kStabilityDebuggerNotPresent);
+    IncrementPrefValue(prefs::kStabilityDebuggerNotPresent);
   else
-    IncrementPrefValue(metrics::prefs::kStabilityDebuggerPresent);
+    IncrementPrefValue(prefs::kStabilityDebuggerPresent);
 }
 
 //------------------------------------------------------------------------------
@@ -568,17 +563,17 @@
   bool version_changed = false;
   if (local_state_->GetInt64(prefs::kStabilityStatsBuildTime) != buildtime ||
       local_state_->GetString(prefs::kStabilityStatsVersion) != version) {
-    local_state_->SetString(metrics::prefs::kStabilityStatsVersion, version);
-    local_state_->SetInt64(metrics::prefs::kStabilityStatsBuildTime, buildtime);
+    local_state_->SetString(prefs::kStabilityStatsVersion, version);
+    local_state_->SetInt64(prefs::kStabilityStatsBuildTime, buildtime);
     version_changed = true;
   }
 
   log_manager_.LoadPersistedUnsentLogs();
 
-  session_id_ = local_state_->GetInteger(metrics::prefs::kMetricsSessionID);
+  session_id_ = local_state_->GetInteger(prefs::kMetricsSessionID);
 
   if (!clean_exit_beacon_.exited_cleanly()) {
-    IncrementPrefValue(metrics::prefs::kStabilityCrashCount);
+    IncrementPrefValue(prefs::kStabilityCrashCount);
     // Reset flag, and wait until we call LogNeedForCleanShutdown() before
     // monitoring.
     clean_exit_beacon_.WriteBeaconValue(true);
@@ -588,7 +583,7 @@
     // TODO(rtenneti): On windows, consider saving/getting execution_phase from
     // the registry.
     int execution_phase =
-        local_state_->GetInteger(metrics::prefs::kStabilityExecutionPhase);
+        local_state_->GetInteger(prefs::kStabilityExecutionPhase);
     UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase",
                                 execution_phase);
 
@@ -620,20 +615,18 @@
 
   // Update session ID.
   ++session_id_;
-  local_state_->SetInteger(metrics::prefs::kMetricsSessionID, session_id_);
+  local_state_->SetInteger(prefs::kMetricsSessionID, session_id_);
 
   // Stability bookkeeping
-  IncrementPrefValue(metrics::prefs::kStabilityLaunchCount);
+  IncrementPrefValue(prefs::kStabilityLaunchCount);
 
   DCHECK_EQ(UNINITIALIZED_PHASE, execution_phase_);
   SetExecutionPhase(START_METRICS_RECORDING, local_state_);
 
-  if (!local_state_->GetBoolean(
-          metrics::prefs::kStabilitySessionEndCompleted)) {
-    IncrementPrefValue(metrics::prefs::kStabilityIncompleteSessionEndCount);
+  if (!local_state_->GetBoolean(prefs::kStabilitySessionEndCompleted)) {
+    IncrementPrefValue(prefs::kStabilityIncompleteSessionEndCount);
     // This is marked false when we get a WM_ENDSESSION.
-    local_state_->SetBoolean(metrics::prefs::kStabilitySessionEndCompleted,
-                             true);
+    local_state_->SetBoolean(prefs::kStabilitySessionEndCompleted, true);
   }
 
   // Call GetUptimes() for the first time, thus allowing all later calls
@@ -643,13 +636,13 @@
   GetUptimes(local_state_, &startup_uptime, &ignored_uptime_parameter);
   DCHECK_EQ(0, startup_uptime.InMicroseconds());
   // For backwards compatibility, leave this intact in case Omaha is checking
-  // them.  metrics::prefs::kStabilityLastTimestampSec may also be useless now.
+  // them.  prefs::kStabilityLastTimestampSec may also be useless now.
   // TODO(jar): Delete these if they have no uses.
-  local_state_->SetInt64(metrics::prefs::kStabilityLaunchTimeSec,
+  local_state_->SetInt64(prefs::kStabilityLaunchTimeSec,
                          base::Time::Now().ToTimeT());
 
   // Bookkeeping for the uninstall metrics.
-  IncrementLongPrefsValue(metrics::prefs::kUninstallLaunchCount);
+  IncrementLongPrefsValue(prefs::kUninstallLaunchCount);
 
   // Kick off the process of saving the state (so the uptime numbers keep
   // getting updated) every n minutes.
@@ -693,10 +686,9 @@
 
   const int64 incremental_time_secs = incremental_uptime->InSeconds();
   if (incremental_time_secs > 0) {
-    int64 metrics_uptime =
-        pref->GetInt64(metrics::prefs::kUninstallMetricsUptimeSec);
+    int64 metrics_uptime = pref->GetInt64(prefs::kUninstallMetricsUptimeSec);
     metrics_uptime += incremental_time_secs;
-    pref->SetInt64(metrics::prefs::kUninstallMetricsUptimeSec, metrics_uptime);
+    pref->SetInt64(prefs::kUninstallMetricsUptimeSec, metrics_uptime);
   }
 }
 
@@ -1164,7 +1156,7 @@
 }
 
 void MetricsService::RegisterMetricsProvider(
-    scoped_ptr<metrics::MetricsProvider> provider) {
+    scoped_ptr<MetricsProvider> provider) {
   DCHECK_EQ(INITIALIZED, state_);
   metrics_providers_.push_back(provider.release());
 }
@@ -1224,7 +1216,7 @@
 
   clean_exit_beacon_.WriteBeaconValue(true);
   RecordCurrentState(local_state_);
-  local_state_->SetInteger(metrics::prefs::kStabilityExecutionPhase,
+  local_state_->SetInteger(prefs::kStabilityExecutionPhase,
                            MetricsService::SHUTDOWN_COMPLETE);
 }
 
@@ -1242,7 +1234,7 @@
 }
 
 void MetricsService::RecordCurrentState(PrefService* pref) {
-  pref->SetInt64(metrics::prefs::kStabilityLastTimestampSec,
+  pref->SetInt64(prefs::kStabilityLastTimestampSec,
                  base::Time::Now().ToTimeT());
 }
 
diff --git a/components/metrics/metrics_service_unittest.cc b/components/metrics/metrics_service_unittest.cc
index 2389060..0c5d6ea 100644
--- a/components/metrics/metrics_service_unittest.cc
+++ b/components/metrics/metrics_service_unittest.cc
@@ -31,7 +31,7 @@
   return scoped_ptr<ClientInfo>();
 }
 
-class TestMetricsProvider : public metrics::MetricsProvider {
+class TestMetricsProvider : public MetricsProvider {
  public:
   explicit TestMetricsProvider(bool has_stability_metrics) :
       has_stability_metrics_(has_stability_metrics),
@@ -164,8 +164,7 @@
       GetMetricsStateManager(), &client, GetLocalState());
 
   TestMetricsProvider* test_provider = new TestMetricsProvider(false);
-  service.RegisterMetricsProvider(
-      scoped_ptr<metrics::MetricsProvider>(test_provider));
+  service.RegisterMetricsProvider(scoped_ptr<MetricsProvider>(test_provider));
 
   service.InitializeMetricsRecordingState();
   // No initial stability log should be generated.
@@ -184,7 +183,7 @@
   // saved from a previous session.
   TestMetricsServiceClient client;
   TestMetricsLog log("client", 1, &client, GetLocalState());
-  log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
+  log.RecordEnvironment(std::vector<MetricsProvider*>(),
                         std::vector<variations::ActiveGroupId>(),
                         0);
 
@@ -278,10 +277,9 @@
   EXPECT_TRUE(log_manager->has_staged_log());
 
   std::string uncompressed_log;
-  EXPECT_TRUE(metrics::GzipUncompress(log_manager->staged_log(),
-                                      &uncompressed_log));
+  EXPECT_TRUE(GzipUncompress(log_manager->staged_log(), &uncompressed_log));
 
-  metrics::ChromeUserMetricsExtension uma_log;
+  ChromeUserMetricsExtension uma_log;
   EXPECT_TRUE(uma_log.ParseFromString(uncompressed_log));
 
   EXPECT_TRUE(uma_log.has_client_id());
@@ -297,16 +295,14 @@
 }
 
 TEST_F(MetricsServiceTest, RegisterSyntheticTrial) {
-  metrics::TestMetricsServiceClient client;
+  TestMetricsServiceClient client;
   MetricsService service(GetMetricsStateManager(), &client, GetLocalState());
 
   // Add two synthetic trials and confirm that they show up in the list.
-  SyntheticTrialGroup trial1(metrics::HashName("TestTrial1"),
-                             metrics::HashName("Group1"));
+  SyntheticTrialGroup trial1(HashName("TestTrial1"), HashName("Group1"));
   service.RegisterSyntheticFieldTrial(trial1);
 
-  SyntheticTrialGroup trial2(metrics::HashName("TestTrial2"),
-                             metrics::HashName("Group2"));
+  SyntheticTrialGroup trial2(HashName("TestTrial2"), HashName("Group2"));
   service.RegisterSyntheticFieldTrial(trial2);
   // Ensure that time has advanced by at least a tick before proceeding.
   WaitUntilTimeChanges(base::TimeTicks::Now());
@@ -332,16 +328,14 @@
   WaitUntilTimeChanges(begin_log_time);
 
   // Change the group for the first trial after the log started.
-  SyntheticTrialGroup trial3(metrics::HashName("TestTrial1"),
-                             metrics::HashName("Group2"));
+  SyntheticTrialGroup trial3(HashName("TestTrial1"), HashName("Group2"));
   service.RegisterSyntheticFieldTrial(trial3);
   service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
   EXPECT_EQ(1U, synthetic_trials.size());
   EXPECT_TRUE(HasSyntheticTrial(synthetic_trials, "TestTrial2", "Group2"));
 
   // Add a new trial after the log started and confirm that it doesn't show up.
-  SyntheticTrialGroup trial4(metrics::HashName("TestTrial3"),
-                             metrics::HashName("Group3"));
+  SyntheticTrialGroup trial4(HashName("TestTrial3"), HashName("Group3"));
   service.RegisterSyntheticFieldTrial(trial4);
   service.GetCurrentSyntheticFieldTrials(&synthetic_trials);
   EXPECT_EQ(1U, synthetic_trials.size());
diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc
index 7f7b8e5..ae158239 100644
--- a/components/metrics/metrics_state_manager.cc
+++ b/components/metrics/metrics_state_manager.cc
@@ -231,7 +231,7 @@
 }
 
 scoped_ptr<ClientInfo> MetricsStateManager::LoadClientInfoAndMaybeMigrate() {
-  scoped_ptr<metrics::ClientInfo> client_info = load_client_info_.Run();
+  scoped_ptr<ClientInfo> client_info = load_client_info_.Run();
 
   // Prior to 2014-07, the client ID was stripped of its dashes before being
   // saved. Migrate back to a proper GUID if this is the case. This migration
diff --git a/components/metrics/net/network_metrics_provider.cc b/components/metrics/net/network_metrics_provider.cc
index c0b38d7..e845cde5 100644
--- a/components/metrics/net/network_metrics_provider.cc
+++ b/components/metrics/net/network_metrics_provider.cc
@@ -15,9 +15,9 @@
 
 #if defined(OS_CHROMEOS)
 #include "components/metrics/net/wifi_access_point_info_provider_chromeos.h"
-#endif // OS_CHROMEOS
+#endif  // OS_CHROMEOS
 
-using metrics::SystemProfileProto;
+namespace metrics {
 
 NetworkMetricsProvider::NetworkMetricsProvider(
     base::TaskRunner* io_task_runner)
@@ -62,7 +62,7 @@
 #else
     wifi_access_point_info_provider_.reset(
         new WifiAccessPointInfoProvider());
-#endif // OS_CHROMEOS
+#endif  // OS_CHROMEOS
   }
 
   // Connected wifi access point information.
@@ -226,3 +226,5 @@
       NOTREACHED();
   }
 }
+
+}  // namespace metrics
diff --git a/components/metrics/net/network_metrics_provider.h b/components/metrics/net/network_metrics_provider.h
index 9ddb3f88..412ef67 100644
--- a/components/metrics/net/network_metrics_provider.h
+++ b/components/metrics/net/network_metrics_provider.h
@@ -14,10 +14,12 @@
 #include "net/base/net_util.h"
 #include "net/base/network_change_notifier.h"
 
+namespace metrics {
+
 // Registers as observer with net::NetworkChangeNotifier and keeps track of
 // the network environment.
 class NetworkMetricsProvider
-    : public metrics::MetricsProvider,
+    : public MetricsProvider,
       public net::NetworkChangeNotifier::ConnectionTypeObserver {
  public:
   // Creates a NetworkMetricsProvider, where |io_task_runner| is used to post
@@ -26,19 +28,17 @@
   ~NetworkMetricsProvider() override;
 
  private:
-  // metrics::MetricsProvider:
+  // MetricsProvider:
   void OnDidCreateMetricsLog() override;
-  void ProvideSystemProfileMetrics(
-      metrics::SystemProfileProto* system_profile) override;
+  void ProvideSystemProfileMetrics(SystemProfileProto* system_profile) override;
 
   // ConnectionTypeObserver:
   void OnConnectionTypeChanged(
       net::NetworkChangeNotifier::ConnectionType type) override;
 
-  metrics::SystemProfileProto::Network::ConnectionType
-  GetConnectionType() const;
-  metrics::SystemProfileProto::Network::WifiPHYLayerProtocol
-  GetWifiPHYLayerProtocol() const;
+  SystemProfileProto::Network::ConnectionType GetConnectionType() const;
+  SystemProfileProto::Network::WifiPHYLayerProtocol GetWifiPHYLayerProtocol()
+      const;
 
   // Posts a call to net::GetWifiPHYLayerProtocol on the blocking pool.
   void ProbeWifiPHYLayerProtocol();
@@ -50,7 +50,7 @@
   // connected to.
   void WriteWifiAccessPointProto(
       const WifiAccessPointInfoProvider::WifiAccessPointInfo& info,
-      metrics::SystemProfileProto::Network* network_proto);
+      SystemProfileProto::Network* network_proto);
 
   // Task runner used for blocking file I/O.
   base::TaskRunner* io_task_runner_;
@@ -74,4 +74,6 @@
   DISALLOW_COPY_AND_ASSIGN(NetworkMetricsProvider);
 };
 
+}  // namespace metrics
+
 #endif  // COMPONENTS_METRICS_NET_NETWORK_METRICS_PROVIDER_H_
diff --git a/components/metrics/net/wifi_access_point_info_provider.cc b/components/metrics/net/wifi_access_point_info_provider.cc
index c8f07a4..21e04b1 100644
--- a/components/metrics/net/wifi_access_point_info_provider.cc
+++ b/components/metrics/net/wifi_access_point_info_provider.cc
@@ -4,6 +4,8 @@
 
 #include "components/metrics/net/wifi_access_point_info_provider.h"
 
+namespace metrics {
+
 WifiAccessPointInfoProvider::WifiAccessPointInfo::WifiAccessPointInfo() {
 }
 
@@ -19,3 +21,5 @@
 bool WifiAccessPointInfoProvider::GetInfo(WifiAccessPointInfo *info) {
   return false;
 }
+
+}  // namespace metrics
diff --git a/components/metrics/net/wifi_access_point_info_provider.h b/components/metrics/net/wifi_access_point_info_provider.h
index 5d74c3c..349375695 100644
--- a/components/metrics/net/wifi_access_point_info_provider.h
+++ b/components/metrics/net/wifi_access_point_info_provider.h
@@ -8,6 +8,8 @@
 #include <string>
 #include "base/basictypes.h"
 
+namespace metrics {
+
 // Interface for accessing connected wireless access point information.
 class WifiAccessPointInfoProvider {
  public:
@@ -46,4 +48,6 @@
   DISALLOW_COPY_AND_ASSIGN(WifiAccessPointInfoProvider);
 };
 
+}  // namespace metrics
+
 #endif  // COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_H_
diff --git a/components/metrics/net/wifi_access_point_info_provider_chromeos.cc b/components/metrics/net/wifi_access_point_info_provider_chromeos.cc
index c05829b..314ddc5 100644
--- a/components/metrics/net/wifi_access_point_info_provider_chromeos.cc
+++ b/components/metrics/net/wifi_access_point_info_provider_chromeos.cc
@@ -16,6 +16,8 @@
 
 using chromeos::NetworkHandler;
 
+namespace metrics {
+
 WifiAccessPointInfoProviderChromeos::WifiAccessPointInfoProviderChromeos() {
   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
 
@@ -116,3 +118,5 @@
   vendor_dict->GetStringWithoutPathExpansion(shill::kVendorOUIListProperty,
                                              &wifi_access_point_info_.oui_list);
 }
+
+}  // namespace metrics
diff --git a/components/metrics/net/wifi_access_point_info_provider_chromeos.h b/components/metrics/net/wifi_access_point_info_provider_chromeos.h
index 520cedd..c6980ec 100644
--- a/components/metrics/net/wifi_access_point_info_provider_chromeos.h
+++ b/components/metrics/net/wifi_access_point_info_provider_chromeos.h
@@ -5,12 +5,16 @@
 #ifndef COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_CHROMEOS_H_
 #define COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_CHROMEOS_H_
 
+#include <string>
+
 #include "base/basictypes.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "chromeos/network/network_state_handler_observer.h"
 #include "components/metrics/net/wifi_access_point_info_provider.h"
 
+namespace metrics {
+
 // WifiAccessPointInfoProviderChromeos provides the connected wifi
 // acccess point information for chromeos.
 class WifiAccessPointInfoProviderChromeos
@@ -21,11 +25,11 @@
   WifiAccessPointInfoProviderChromeos();
   virtual ~WifiAccessPointInfoProviderChromeos();
 
-  // WifiAccessPointInfoProvider
-  virtual bool GetInfo(WifiAccessPointInfo* info) override;
+  // WifiAccessPointInfoProvider:
+  bool GetInfo(WifiAccessPointInfo* info) override;
 
-  // NetworkStateHandlerObserver overrides.
-  virtual void DefaultNetworkChanged(
+  // NetworkStateHandlerObserver:
+  void DefaultNetworkChanged(
       const chromeos::NetworkState* default_network) override;
 
  private:
@@ -39,4 +43,6 @@
   DISALLOW_COPY_AND_ASSIGN(WifiAccessPointInfoProviderChromeos);
 };
 
+}  // namespace metrics
+
 #endif  // COMPONENTS_METRICS_NET_WIFI_ACCESS_POINT_INFO_PROVIDER_CHROMEOS_H_
diff --git a/components/metrics/profiler/profiler_metrics_provider.cc b/components/metrics/profiler/profiler_metrics_provider.cc
index 245fc22..b87fa10e 100644
--- a/components/metrics/profiler/profiler_metrics_provider.cc
+++ b/components/metrics/profiler/profiler_metrics_provider.cc
@@ -11,6 +11,7 @@
 #include "base/tracked_objects.h"
 #include "components/metrics/metrics_log.h"
 #include "components/nacl/common/nacl_process_type.h"
+#include "components/variations/variations_associated_data.h"
 #include "content/public/common/process_type.h"
 
 using tracked_objects::ProcessDataSnapshot;
@@ -106,6 +107,13 @@
   }
 }
 
+bool SkipProfilerDataUpload() {
+  // If skip_profiler_data is set in experiment params then skip the uplaod.
+  std::string skip_profiler_data = variations::GetVariationParamValue(
+      "UMALogUploadInterval", "skip_profiler_data");
+  return skip_profiler_data == "true";
+}
+
 }  // namespace
 
 ProfilerMetricsProvider::ProfilerMetricsProvider() : has_profiler_data_(false) {
@@ -131,6 +139,9 @@
 void ProfilerMetricsProvider::RecordProfilerData(
     const tracked_objects::ProcessDataSnapshot& process_data,
     int process_type) {
+  if (SkipProfilerDataUpload())
+    return;
+
   if (tracked_objects::GetTimeSourceType() !=
       tracked_objects::TIME_SOURCE_TYPE_WALL_TIME) {
     // We currently only support the default time source, wall clock time.
diff --git a/components/metrics/profiler/tracking_synchronizer.cc b/components/metrics/profiler/tracking_synchronizer.cc
index a6ed609..0935f314 100644
--- a/components/metrics/profiler/tracking_synchronizer.cc
+++ b/components/metrics/profiler/tracking_synchronizer.cc
@@ -16,6 +16,8 @@
 using base::TimeTicks;
 using content::BrowserThread;
 
+namespace metrics {
+
 namespace {
 
 // Negative numbers are never used as sequence numbers.  We explicitly pick a
@@ -30,12 +32,9 @@
 // calls. This object is created on the UI thread, and it is destroyed after
 // all the other threads have gone away. As a result, it is ok to call it
 // from the UI thread, or for about:profiler.
-static metrics::TrackingSynchronizer* g_tracking_synchronizer =
-    NULL;
+static TrackingSynchronizer* g_tracking_synchronizer = NULL;
 
-}  // anonymous namespace
-
-namespace metrics {
+}  // namespace
 
 // The "RequestContext" structure describes an individual request received
 // from the UI. All methods are accessible on UI thread.
diff --git a/components/metrics/serialization/serialization_utils.cc b/components/metrics/serialization/serialization_utils.cc
index 30c2675..d57b51b 100644
--- a/components/metrics/serialization/serialization_utils.cc
+++ b/components/metrics/serialization/serialization_utils.cc
@@ -56,7 +56,7 @@
 
   // kMessageMaxLength applies to the entire message: the 4-byte
   // length field and the content.
-  if (message_size > metrics::SerializationUtils::kMessageMaxLength) {
+  if (message_size > SerializationUtils::kMessageMaxLength) {
     DLOG(ERROR) << "message too long : " << message_size;
     if (HANDLE_EINTR(lseek(fd, message_size - 4, SEEK_CUR)) == -1) {
       DLOG(ERROR) << "error while skipping message. abort";
@@ -69,7 +69,7 @@
   }
 
   message_size -= sizeof(message_size);  // The message size includes itself.
-  char buffer[metrics::SerializationUtils::kMessageMaxLength];
+  char buffer[SerializationUtils::kMessageMaxLength];
   if (!base::ReadFromFD(fd, buffer, message_size)) {
     DPLOG(ERROR) << "reading metrics message body";
     return false;
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc
index 1fdb09b32..afb430a 100644
--- a/components/nacl/browser/nacl_process_host.cc
+++ b/components/nacl/browser/nacl_process_host.cc
@@ -831,16 +831,12 @@
       return false;
     }
 
-    // Currently, everything uses the IRT except for the PNaCl Translators.
-    bool uses_irt = process_type_ != kPNaClTranslatorProcessType;
-    if (uses_irt) {
-      const base::File& irt_file = nacl_browser->IrtFile();
-      CHECK(irt_file.IsValid());
-      // Send over the IRT file handle.  We don't close our own copy!
-      if (!ShareHandleToSelLdr(data.handle, irt_file.GetPlatformFile(), false,
-                               &params.handles)) {
-        return false;
-      }
+    const base::File& irt_file = nacl_browser->IrtFile();
+    CHECK(irt_file.IsValid());
+    // Send over the IRT file handle.  We don't close our own copy!
+    if (!ShareHandleToSelLdr(data.handle, irt_file.GetPlatformFile(), false,
+                             &params.handles)) {
+      return false;
     }
 
 #if defined(OS_MACOSX)
diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc
index 8562a28..0733bf8 100644
--- a/components/nacl/loader/nacl_listener.cc
+++ b/components/nacl/loader/nacl_listener.cc
@@ -386,26 +386,20 @@
 #endif
 
   DCHECK(params.process_type != nacl::kUnknownNaClProcessType);
-  bool uses_irt = params.process_type != nacl::kPNaClTranslatorProcessType;
-  if (uses_irt) {
-    CHECK(handles.size() >= 1);
-    NaClHandle irt_handle = nacl::ToNativeHandle(handles[handles.size() - 1]);
-    handles.pop_back();
+  CHECK(handles.size() >= 1);
+  NaClHandle irt_handle = nacl::ToNativeHandle(handles[handles.size() - 1]);
+  handles.pop_back();
 
 #if defined(OS_WIN)
-    args->irt_fd = _open_osfhandle(reinterpret_cast<intptr_t>(irt_handle),
-                                   _O_RDONLY | _O_BINARY);
-    if (args->irt_fd < 0) {
-      LOG(ERROR) << "_open_osfhandle() failed";
-      return;
-    }
-#else
-    args->irt_fd = irt_handle;
-#endif
-  } else {
-    // Otherwise, the IRT handle is not even sent.
-    args->irt_fd = -1;
+  args->irt_fd = _open_osfhandle(reinterpret_cast<intptr_t>(irt_handle),
+                                 _O_RDONLY | _O_BINARY);
+  if (args->irt_fd < 0) {
+    LOG(ERROR) << "_open_osfhandle() failed";
+    return;
   }
+#else
+  args->irt_fd = irt_handle;
+#endif
 
   if (params.validation_cache_enabled) {
     // SHA256 block size.
@@ -439,6 +433,11 @@
     args->enable_dyncode_syscalls = 1;
     args->pnacl_mode = 0;
     args->initial_nexe_max_code_bytes = 0;
+  } else if (params.process_type == nacl::kPNaClTranslatorProcessType) {
+    // Transitioning the PNaCl translators to use the IRT again:
+    // https://code.google.com/p/nativeclient/issues/detail?id=3914.
+    // Once done, this can be removed.
+    args->irt_load_optional = 1;
   }
 
 #if defined(OS_LINUX) || defined(OS_MACOSX)
diff --git a/components/nacl_nonsfi.gyp b/components/nacl_nonsfi.gyp
index 60c09f41..1625451 100644
--- a/components/nacl_nonsfi.gyp
+++ b/components/nacl_nonsfi.gyp
@@ -13,6 +13,20 @@
     ['disable_nacl==0 and disable_nacl_untrusted==0', {
       'targets': [
         {
+          # nacl_helper_nonsfi is similar to nacl_helper (built in nacl.gyp)
+          # but for the NaCl plugin in Non-SFI mode.
+          # This binary is built using the PNaCl toolchain, but it is native
+          # linux binary and will run on Linux directly.
+          # Most library code can be shared with the one for untrusted build
+          # (i.e. the one for irt.nexe built by the NaCl/PNaCl toolchain), but
+          # as nacl_helper_nonsfi runs on Linux, there are some differences,
+          # such as MessageLoopForIO (which is based on libevent in Non-SFI
+          # mode) or ipc_channel implementation.
+          # Because of the toolchain, in both builds, OS_NACL macro (derived
+          # from __native_client__ macro) is defined. Code can test whether
+          # __native_client_nonsfi__ is #defined in order to determine
+          # whether it is being compiled for SFI mode or Non-SFI mode.
+          #
           # Currently, nacl_helper_nonsfi is under development and the binary
           # does nothing (i.e. it has only empty main(), now).
           # TODO(crbug.com/358465): Implement it then switch nacl_helper in
@@ -41,7 +55,14 @@
               ['target_arch=="ia32" or target_arch=="x64"', {
                 'extra_deps_newlib32_nonsfi': [
                   '>(tc_lib_dir_nonsfi_helper32)/libbase_nacl_nonsfi.a',
+                  '>(tc_lib_dir_nonsfi_helper32)/libcommand_buffer_client_nacl.a',
+                  '>(tc_lib_dir_nonsfi_helper32)/libcommand_buffer_common_nacl.a',
                   '>(tc_lib_dir_nonsfi_helper32)/libevent_nacl_nonsfi.a',
+                  '>(tc_lib_dir_nonsfi_helper32)/libgles2_cmd_helper_nacl.a',
+                  '>(tc_lib_dir_nonsfi_helper32)/libgles2_implementation_nacl.a',
+                  '>(tc_lib_dir_nonsfi_helper32)/libgles2_utils_nacl.a',
+                  '>(tc_lib_dir_nonsfi_helper32)/libgpu_ipc_nacl.a',
+                  '>(tc_lib_dir_nonsfi_helper32)/libipc_nacl_nonsfi.a',
                   '>(tc_lib_dir_nonsfi_helper32)/libshared_memory_support_nacl.a',
                 ],
               }],
@@ -49,6 +70,7 @@
           },
           'dependencies': [
             '../base/base_nacl.gyp:base_nacl_nonsfi',
+            '../ipc/ipc_nacl.gyp:ipc_nacl_nonsfi',
             '../native_client/src/nonsfi/irt/irt.gyp:nacl_sys_private',
             '../native_client/src/untrusted/nacl/nacl.gyp:nacl_lib_newlib',
             '../native_client/tools.gyp:prep_toolchain',
@@ -56,6 +78,12 @@
             # Temporarily depends on some libraries to make sure they can be
             # built properly. These are depended on by PPAPI library.
             # TODO(hidehiko): Remove them when PPAPI library is introduced.
+            '../gpu/command_buffer/command_buffer_nacl.gyp:gles2_utils_nacl',
+            '../gpu/gpu_nacl.gyp:command_buffer_client_nacl',
+            '../gpu/gpu_nacl.gyp:command_buffer_common_nacl',
+            '../gpu/gpu_nacl.gyp:gles2_cmd_helper_nacl',
+            '../gpu/gpu_nacl.gyp:gles2_implementation_nacl',
+            '../gpu/gpu_nacl.gyp:gpu_ipc_nacl',
             '../media/media_nacl.gyp:shared_memory_support_nacl',
           ],
         },
diff --git a/components/omnibox/BUILD.gn b/components/omnibox/BUILD.gn
index 259b2528d..1ba9aa1 100644
--- a/components/omnibox/BUILD.gn
+++ b/components/omnibox/BUILD.gn
@@ -45,6 +45,7 @@
     "//components/strings",
     "//components/url_fixer",
     "//components/variations",
+    "//components/variations/net",
     "//net",
     "//ui/base",
     "//url",
diff --git a/components/omnibox/omnibox_field_trial.cc b/components/omnibox/omnibox_field_trial.cc
index 96adb803..62cd8ec 100644
--- a/components/omnibox/omnibox_field_trial.cc
+++ b/components/omnibox/omnibox_field_trial.cc
@@ -175,11 +175,18 @@
 }
 
 bool OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial() {
-  return variations::GetVariationParamValue(
+  return InZeroSuggestMostVisitedWithoutSerpFieldTrial() ||
+      variations::GetVariationParamValue(
       kBundledExperimentFieldTrialName,
       kZeroSuggestVariantRule) == "MostVisited";
 }
 
+bool OmniboxFieldTrial::InZeroSuggestMostVisitedWithoutSerpFieldTrial() {
+  return variations::GetVariationParamValue(
+      kBundledExperimentFieldTrialName,
+      kZeroSuggestVariantRule) == "MostVisitedWithoutSERP";
+}
+
 bool OmniboxFieldTrial::InZeroSuggestAfterTypingFieldTrial() {
   return variations::GetVariationParamValue(
       kBundledExperimentFieldTrialName,
diff --git a/components/omnibox/omnibox_field_trial.h b/components/omnibox/omnibox_field_trial.h
index 07377bdc..c659b83 100644
--- a/components/omnibox/omnibox_field_trial.h
+++ b/components/omnibox/omnibox_field_trial.h
@@ -135,11 +135,16 @@
   // user clicks on the omnibox but has not typed anything yet.
   static bool InZeroSuggestFieldTrial();
 
-  // Returns whether the user is in a ZeroSuggest field trial, but should
-  // show most visited URL instead.  This is used to compare metrics of
-  // ZeroSuggest and most visited suggestions.
+  // Returns whether the user is in a ZeroSuggest field trial, which shows
+  // most visited URLs. This is true for both "MostVisited" and
+  // "MostVisitedWithoutSERP" trials.
   static bool InZeroSuggestMostVisitedFieldTrial();
 
+  // Returns whether the user is in ZeroSuggest field trial showing most
+  // visited URLs except it doesn't show suggestions on Google search result
+  // pages.
+  static bool InZeroSuggestMostVisitedWithoutSerpFieldTrial();
+
   // Returns whether the user is in a ZeroSuggest field trial and URL-based
   // suggestions can continue to appear after the user has started typing.
   static bool InZeroSuggestAfterTypingFieldTrial();
diff --git a/components/omnibox/search_provider.cc b/components/omnibox/search_provider.cc
index a9cd7b7..5cd42c6 100644
--- a/components/omnibox/search_provider.cc
+++ b/components/omnibox/search_provider.cc
@@ -29,7 +29,7 @@
 #include "components/search/search.h"
 #include "components/search_engines/template_url_prepopulate_data.h"
 #include "components/search_engines/template_url_service.h"
-#include "components/variations/variations_http_header_provider.h"
+#include "components/variations/net/variations_http_header_provider.h"
 #include "grit/components_strings.h"
 #include "net/base/escape.h"
 #include "net/base/load_flags.h"
diff --git a/components/ownership/BUILD.gn b/components/ownership/BUILD.gn
index ad11a79..9051ddb 100644
--- a/components/ownership/BUILD.gn
+++ b/components/ownership/BUILD.gn
@@ -30,7 +30,7 @@
 
 source_set("unit_tests") {
   testonly = true
-  sources = ["owner_key_util_unittest.cc"]
+  sources = ["owner_key_util_impl_unittest.cc"]
 
   deps = [
     ":ownership",
diff --git a/components/ownership/owner_settings_service.cc b/components/ownership/owner_settings_service.cc
index 56bcbe0b..204cdd1 100644
--- a/components/ownership/owner_settings_service.cc
+++ b/components/ownership/owner_settings_service.cc
@@ -12,6 +12,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/task_runner.h"
 #include "base/task_runner_util.h"
+#include "base/values.h"
 #include "components/ownership/owner_key_util.h"
 #include "crypto/signature_creator.h"
 
@@ -21,13 +22,15 @@
 
 namespace {
 
-std::string AssembleAndSignPolicy(scoped_ptr<em::PolicyData> policy,
-                                  crypto::RSAPrivateKey* private_key) {
+scoped_ptr<em::PolicyFetchResponse> AssembleAndSignPolicy(
+    scoped_ptr<em::PolicyData> policy,
+    crypto::RSAPrivateKey* private_key) {
   // Assemble the policy.
-  em::PolicyFetchResponse policy_response;
-  if (!policy->SerializeToString(policy_response.mutable_policy_data())) {
+  scoped_ptr<em::PolicyFetchResponse> policy_response(
+      new em::PolicyFetchResponse());
+  if (!policy->SerializeToString(policy_response->mutable_policy_data())) {
     LOG(ERROR) << "Failed to encode policy payload.";
-    return std::string();
+    return scoped_ptr<em::PolicyFetchResponse>(nullptr).Pass();
   }
 
   // Generate the signature.
@@ -35,19 +38,19 @@
       crypto::SignatureCreator::Create(private_key,
                                        crypto::SignatureCreator::SHA1));
   signature_creator->Update(
-      reinterpret_cast<const uint8*>(policy_response.policy_data().c_str()),
-      policy_response.policy_data().size());
+      reinterpret_cast<const uint8*>(policy_response->policy_data().c_str()),
+      policy_response->policy_data().size());
   std::vector<uint8> signature_bytes;
   std::string policy_blob;
   if (!signature_creator->Final(&signature_bytes)) {
     LOG(ERROR) << "Failed to create policy signature.";
-    return std::string();
+    return scoped_ptr<em::PolicyFetchResponse>(nullptr).Pass();
   }
 
-  policy_response.mutable_policy_data_signature()->assign(
+  policy_response->mutable_policy_data_signature()->assign(
       reinterpret_cast<const char*>(vector_as_array(&signature_bytes)),
       signature_bytes.size());
-  return policy_response.SerializeAsString();
+  return policy_response.Pass();
 }
 
 }  // namepace
@@ -61,6 +64,15 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 }
 
+void OwnerSettingsService::AddObserver(Observer* observer) {
+  if (observer && !observers_.HasObserver(observer))
+    observers_.AddObserver(observer);
+}
+
+void OwnerSettingsService::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 bool OwnerSettingsService::IsOwner() {
   DCHECK(thread_checker_.CalledOnValidThread());
   return private_key_.get() && private_key_->key();
@@ -91,6 +103,31 @@
       callback);
 }
 
+bool OwnerSettingsService::SetBoolean(const std::string& setting, bool value) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  base::FundamentalValue in_value(value);
+  return Set(setting, in_value);
+}
+
+bool OwnerSettingsService::SetInteger(const std::string& setting, int value) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  base::FundamentalValue in_value(value);
+  return Set(setting, in_value);
+}
+
+bool OwnerSettingsService::SetDouble(const std::string& setting, double value) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  base::FundamentalValue in_value(value);
+  return Set(setting, in_value);
+}
+
+bool OwnerSettingsService::SetString(const std::string& setting,
+                                     const std::string& value) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  base::StringValue in_value(value);
+  return Set(setting, in_value);
+}
+
 void OwnerSettingsService::ReloadKeypair() {
   ReloadKeypairImpl(
       base::Bind(&OwnerSettingsService::OnKeypairLoaded, as_weak_ptr()));
diff --git a/components/ownership/owner_settings_service.h b/components/ownership/owner_settings_service.h
index 1961975..db36595d 100644
--- a/components/ownership/owner_settings_service.h
+++ b/components/ownership/owner_settings_service.h
@@ -13,6 +13,7 @@
 #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/threading/thread_checker.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/ownership/ownership_export.h"
@@ -20,6 +21,7 @@
 
 namespace base {
 class TaskRunner;
+class Value;
 }
 
 namespace ownership {
@@ -31,19 +33,42 @@
 // which deal with ownership, keypairs and owner-related settings.
 class OWNERSHIP_EXPORT OwnerSettingsService : public KeyedService {
  public:
-  typedef base::Callback<void(std::string policy_blob)>
+  class Observer {
+   public:
+    virtual ~Observer() {}
+
+    // Called when signed policy was stored, or when an error happed during
+    // policy storage..
+    virtual void OnSignedPolicyStored(bool success) {}
+
+    // Called when tentative changes were made to policy, but the policy still
+    // not signed and stored.
+    //
+    // TODO (ygorshenin@, crbug.com/230018): get rid of the method
+    // since it creates DeviceSettingsService's dependency on
+    // OwnerSettingsService.
+    virtual void OnTentativeChangesInPolicy(
+        const enterprise_management::PolicyData& policy_data) {}
+  };
+
+  typedef base::Callback<void(
+      scoped_ptr<enterprise_management::PolicyFetchResponse> policy_response)>
       AssembleAndSignPolicyAsyncCallback;
 
   typedef base::Callback<void(bool is_owner)> IsOwnerCallback;
 
   explicit OwnerSettingsService(
       const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util);
-  ~OwnerSettingsService() override;
+  virtual ~OwnerSettingsService();
 
   base::WeakPtr<OwnerSettingsService> as_weak_ptr() {
     return weak_factory_.GetWeakPtr();
   }
 
+  void AddObserver(Observer* observer);
+
+  void RemoveObserver(Observer* observer);
+
   // Returns whether current user is owner or not. When this method
   // is called too early, incorrect result can be returned because
   // private key loading may be in progress.
@@ -60,12 +85,24 @@
       scoped_ptr<enterprise_management::PolicyData> policy,
       const AssembleAndSignPolicyAsyncCallback& callback);
 
-  // Signs |settings| with the private half of the owner key and sends
-  // the resulting policy blob for storage. The
-  // result of the operation is reported through |callback|.
-  virtual void SignAndStorePolicyAsync(
-      scoped_ptr<enterprise_management::PolicyData> policy,
-      const base::Closure& callback) = 0;
+  // Checks whether |setting| is handled by OwnerSettingsService.
+  virtual bool HandlesSetting(const std::string& setting) = 0;
+
+  // Sets |setting| value to |value|.
+  virtual bool Set(const std::string& setting, const base::Value& value) = 0;
+
+  // Sets a bunch of device settings accumulated before ownership gets
+  // established.
+  //
+  // TODO (ygorshenin@, crbug.com/230018): that this is a temporary
+  // solution and should be removed.
+  virtual bool CommitTentativeDeviceSettings(
+      scoped_ptr<enterprise_management::PolicyData> policy) = 0;
+
+  bool SetBoolean(const std::string& setting, bool value);
+  bool SetInteger(const std::string& setting, int value);
+  bool SetDouble(const std::string& setting, double value);
+  bool SetString(const std::string& setting, const std::string& value);
 
  protected:
   void ReloadKeypair();
@@ -89,6 +126,8 @@
 
   std::vector<IsOwnerCallback> pending_is_owner_callbacks_;
 
+  ObserverList<Observer> observers_;
+
   base::ThreadChecker thread_checker_;
 
  private:
diff --git a/components/pairing/bluetooth_controller_pairing_controller.cc b/components/pairing/bluetooth_controller_pairing_controller.cc
index 4e687adc..1d8e026 100644
--- a/components/pairing/bluetooth_controller_pairing_controller.cc
+++ b/components/pairing/bluetooth_controller_pairing_controller.cc
@@ -163,6 +163,7 @@
                  ptr_factory_.GetWeakPtr()),
       base::Bind(&BluetoothControllerPairingController::OnReceiveError,
                  ptr_factory_.GetWeakPtr()));
+  ChangeStage(STAGE_PAIRING_DONE);
 }
 
 void BluetoothControllerPairingController::OnSendComplete(int bytes_sent) {}
@@ -203,6 +204,9 @@
     // devices.  If the connection fails, it's not a problem as long as pairing
     // was successful.
     OnConnect();
+  } else {
+    // This can happen if the confirmation dialog times out.
+    ChangeStage(STAGE_ESTABLISHING_CONNECTION_ERROR);
   }
 }
 
@@ -314,6 +318,9 @@
     const std::string& timezone,
     bool send_reports,
     const std::string& keyboard_layout) {
+  VLOG(1) << "SetHostConfiguration lang=" << lang
+          << ", timezone=" << timezone
+          << ", keyboard_layout=" << keyboard_layout;
 
   pairing_api::ConfigureHost host_config;
   host_config.set_api_version(kPairingAPIVersion);
diff --git a/components/pairing/bluetooth_host_pairing_controller.cc b/components/pairing/bluetooth_host_pairing_controller.cc
index 4f19510..1d35628 100644
--- a/components/pairing/bluetooth_host_pairing_controller.cc
+++ b/components/pairing/bluetooth_host_pairing_controller.cc
@@ -243,8 +243,6 @@
                  ptr_factory_.GetWeakPtr()),
       base::Bind(&BluetoothHostPairingController::OnReceiveError,
                  ptr_factory_.GetWeakPtr()));
-
-  ChangeStage(STAGE_UPDATING);
 }
 
 void BluetoothHostPairingController::OnSetDiscoverable(bool change_stage) {
@@ -447,6 +445,11 @@
 void BluetoothHostPairingController::ConfirmPasskey(
     device::BluetoothDevice* device,
     uint32 passkey) {
+  // If a new connection is occurring, reset the stage.  This can occur if the
+  // pairing times out, or a new controller connects.
+  if (current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION)
+    ChangeStage(STAGE_WAITING_FOR_CONTROLLER);
+
   confirmation_code_ = base::StringPrintf("%06d", passkey);
   device->ConfirmPairing();
   ChangeStage(STAGE_WAITING_FOR_CODE_CONFIRMATION);
diff --git a/components/pairing/controller_pairing_controller.h b/components/pairing/controller_pairing_controller.h
index 6304c60..60b17a9 100644
--- a/components/pairing/controller_pairing_controller.h
+++ b/components/pairing/controller_pairing_controller.h
@@ -30,6 +30,7 @@
     STAGE_ESTABLISHING_CONNECTION,
     STAGE_ESTABLISHING_CONNECTION_ERROR,
     STAGE_WAITING_FOR_CODE_CONFIRMATION,
+    STAGE_PAIRING_DONE,
     STAGE_HOST_UPDATE_IN_PROGRESS,
     STAGE_HOST_CONNECTION_LOST,
     STAGE_WAITING_FOR_CREDENTIALS,
diff --git a/components/pairing/fake_host_pairing_controller.cc b/components/pairing/fake_host_pairing_controller.cc
index 9ebf1b6..12798e4 100644
--- a/components/pairing/fake_host_pairing_controller.cc
+++ b/components/pairing/fake_host_pairing_controller.cc
@@ -139,10 +139,6 @@
       break;
     }
     case STAGE_WAITING_FOR_CODE_CONFIRMATION: {
-      ChangeStageLater(STAGE_UPDATING);
-      break;
-    }
-    case STAGE_UPDATING: {
       ChangeStageLater(STAGE_WAITING_FOR_CONTROLLER_AFTER_UPDATE);
       break;
     }
diff --git a/components/pairing/host_pairing_controller.h b/components/pairing/host_pairing_controller.h
index 7be8f59..7d79c4f 100644
--- a/components/pairing/host_pairing_controller.h
+++ b/components/pairing/host_pairing_controller.h
@@ -18,7 +18,6 @@
     STAGE_INITIALIZATION_ERROR,
     STAGE_WAITING_FOR_CONTROLLER,
     STAGE_WAITING_FOR_CODE_CONFIRMATION,
-    STAGE_UPDATING,
     STAGE_WAITING_FOR_CONTROLLER_AFTER_UPDATE,
     STAGE_WAITING_FOR_CREDENTIALS,
     STAGE_ENROLLING,
@@ -84,7 +83,6 @@
   virtual std::string GetEnrollmentDomain() = 0;
 
   // Notify that the update status has changed.
-  // Can be called on stage |STAGE_UPDATING|.
   virtual void OnUpdateStatusChanged(UpdateStatus update_status) = 0;
 
   // Notify that enrollment status has changed.
diff --git a/components/policy/core/browser/managed_bookmarks_tracker_unittest.cc b/components/policy/core/browser/managed_bookmarks_tracker_unittest.cc
index 5903e05..295e8b5 100644
--- a/components/policy/core/browser/managed_bookmarks_tracker_unittest.cc
+++ b/components/policy/core/browser/managed_bookmarks_tracker_unittest.cc
@@ -66,7 +66,7 @@
                  base::FilePath(),
                  base::MessageLoopProxy::current(),
                  base::MessageLoopProxy::current());
-    test::WaitForBookmarkModelToLoad(model_.get());
+    bookmarks::test::WaitForBookmarkModelToLoad(model_.get());
     Mock::VerifyAndClearExpectations(&observer_);
 
     ASSERT_EQ(1u, client_.extra_nodes().size());
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index 0425d10..e3b6939 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -599,6 +599,11 @@
   repeated bytes server_backed_state_key = 1;
 }
 
+message DisabledState {
+  // A message to the finder/thief that should be shown on the screen.
+  optional string message = 1;
+}
+
 // Server to client message carrying the device state response. Because the
 // request is not authenticated, the only protection against state extraction
 // from server is the unpredictability of the server-backed state ID. Thus, the
@@ -620,6 +625,9 @@
 
   // Primary domain the device is associated with.
   optional string management_domain = 2;
+
+  // The device is disabled and no logins are possible when this is set.
+  optional DisabledState disabled_state = 3;
 }
 
 // Sent by the client to the server to pair the Host device with the Controller
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index be1e3ba5..f9c8c86 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -6897,7 +6897,7 @@
       'example_value': 'tls1',
       'id': 280,
       'caption': '''Minimum SSL version to fallback to''',
-      'desc': '''When an SSL/TLS handshake fails, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will retry the connection with a lesser version of SSL/TLS in order to work around bugs in HTTPS servers. This setting configures the version at which this fallback process will stop. If a server performs version negotiation correctly then this setting doesn't apply and SSLVersionMin controls.
+      'desc': '''When an SSL/TLS handshake fails, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will retry the connection with a lesser version of SSL/TLS in order to work around bugs in HTTPS servers. This setting configures the version at which this fallback process will stop. If a server performs version negotiation correctly (i.e. without breaking the connection) then this setting doesn't apply. Regardless, the resulting connection must still comply with SSLVersionMin.
 
       If this policy is not configured then <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use a default minimum version, which was SSLv3 in Chrome 38 but is TLS 1.0 in Chrome 39.
 
diff --git a/components/resources/components_scaled_resources.grd b/components/resources/components_scaled_resources.grd
index 4800748..ada8350 100644
--- a/components/resources/components_scaled_resources.grd
+++ b/components/resources/components_scaled_resources.grd
@@ -6,6 +6,7 @@
     </output>
     <output filename="components_resources_100_percent.pak" type="data_package" context="default_100_percent" />
     <output filename="components_resources_200_percent.pak" type="data_package" context="default_200_percent" />
+    <output filename="components_resources_300_percent.pak" type="data_package" context="default_300_percent" />
   </outputs>
   <release seq="1">
     <structures fallback_to_low_resolution="true">
diff --git a/mojo/examples/wm_flow/app/DEPS b/components/resources/default_300_percent/DELETE_ME
similarity index 100%
copy from mojo/examples/wm_flow/app/DEPS
copy to components/resources/default_300_percent/DELETE_ME
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index 0165af4..8d4d72a 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -892,18 +892,39 @@
             "422460 TemplateURLService::OnWebDataServiceRequestDone 4"));
 
     PatchMissingSyncGUIDs(&template_urls);
+
+    // TODO(vadimt): Remove ScopedProfile below once crbug.com/422460 is fixed.
+    tracked_objects::ScopedProfile tracking_profile41(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION(
+            "422460 TemplateURLService::OnWebDataServiceRequestDone 41"));
+
     SetTemplateURLs(&template_urls);
 
+    // TODO(vadimt): Remove ScopedProfile below once crbug.com/422460 is fixed.
+    tracked_objects::ScopedProfile tracking_profile42(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION(
+            "422460 TemplateURLService::OnWebDataServiceRequestDone 42"));
+
     // This initializes provider_map_ which should be done before
     // calling UpdateKeywordSearchTermsForURL.
     // This also calls NotifyObservers.
     ChangeToLoadedState();
 
+    // TODO(vadimt): Remove ScopedProfile below once crbug.com/422460 is fixed.
+    tracked_objects::ScopedProfile tracking_profile43(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION(
+            "422460 TemplateURLService::OnWebDataServiceRequestDone 43"));
+
     // Index any visits that occurred before we finished loading.
     for (size_t i = 0; i < visits_to_add_.size(); ++i)
       UpdateKeywordSearchTermsForURL(visits_to_add_[i]);
     visits_to_add_.clear();
 
+    // TODO(vadimt): Remove ScopedProfile below once crbug.com/422460 is fixed.
+    tracked_objects::ScopedProfile tracking_profile44(
+        FROM_HERE_WITH_EXPLICIT_FUNCTION(
+            "422460 TemplateURLService::OnWebDataServiceRequestDone 44"));
+
     if (new_resource_keyword_version)
       web_data_service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
   }
diff --git a/components/sessions.gypi b/components/sessions.gypi
index 2da33d78..390fb4d 100644
--- a/components/sessions.gypi
+++ b/components/sessions.gypi
@@ -3,13 +3,32 @@
 # found in the LICENSE file.
 
 {
+  'variables': {
+    # Core sources shared by sessions_content and sessions_ios.
+    #
+    # TODO(rohitrao): We are including these sources directly into each
+    # individual target in order to avoid the complications associated with
+    # making a separate sessions_core target.  The files in sessions/core
+    # declare a static function that they do not define, which means that a
+    # sessions_core target would not link as a shared_library.  It would also be
+    # unsuitable as a static_library because it would be linked into multiple
+    # shared libraries.  Revisit this setup if necessary.
+    'sessions_core_sources': [
+      'sessions/core/serialized_navigation_driver.h',
+      'sessions/serialized_navigation_entry.cc',
+      'sessions/serialized_navigation_entry.h',
+      'sessions/session_id.cc',
+      'sessions/session_id.h',
+    ],
+  },
   'targets': [
     {
-      # GN version: //components/sessions
-      'target_name': 'sessions',
+      # GN version: //components/sessions:sessions_content
+      'target_name': 'sessions_content',
       'type': '<(component)',
       'dependencies': [
         '../base/base.gyp:base',
+        '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
         '../content/content.gyp:content_browser',
         '../skia/skia.gyp:skia',
         '../third_party/protobuf/protobuf.gyp:protobuf_lite',
@@ -24,10 +43,12 @@
       ],
       'sources': [
         # Note: sources list duplicated in GN build.
-        'sessions/serialized_navigation_entry.cc',
-        'sessions/serialized_navigation_entry.h',
-        'sessions/session_id.cc',
-        'sessions/session_id.h',
+        '<@(sessions_core_sources)',
+
+        'sessions/content/content_serialized_navigation_builder.cc',
+        'sessions/content/content_serialized_navigation_builder.h',
+        'sessions/content/content_serialized_navigation_driver.cc',
+        'sessions/content/content_serialized_navigation_driver.h',
       ],
       'conditions': [
         ['android_webview_build == 0', {
diff --git a/components/sessions/BUILD.gn b/components/sessions/BUILD.gn
index 79a0d4b..1b75012a 100644
--- a/components/sessions/BUILD.gn
+++ b/components/sessions/BUILD.gn
@@ -6,8 +6,13 @@
   import("//build/config/android/config.gni")
 }
 
-component("sessions") {
+# TODO(rohitrao): sessions_core is defined as a source_set because it declares a
+# static function that it does not define.  This prevents it from linking as a
+# shared_library.  It also cannot be a static_library because it will be linked
+# into multiple shared libraries.  Revisit this setup if necessary.
+source_set("sessions_core") {
   sources = [
+    "core/serialized_navigation_driver.h",
     "serialized_navigation_entry.cc",
     "serialized_navigation_entry.h",
     "session_id.cc",
@@ -18,7 +23,6 @@
 
   deps = [
     "//base",
-    "//content/public/browser",
     "//skia",
     "//ui/base",
     "//url",
@@ -29,6 +33,26 @@
   }
 }
 
+component("sessions_content") {
+  sources = [
+    "content/content_serialized_navigation_builder.cc",
+    "content/content_serialized_navigation_builder.h",
+    "content/content_serialized_navigation_driver.cc",
+    "content/content_serialized_navigation_driver.h",
+  ]
+
+  defines = [ "SESSIONS_IMPLEMENTATION" ]
+
+  deps = [
+    ":sessions_core",
+    "//base",
+    "//base/third_party/dynamic_annotations",
+    "//content/public/browser",
+    "//ui/base",
+    "//url",
+  ]
+}
+
 static_library("test_support") {
   testonly = true
   sources = [
diff --git a/components/sessions/content/content_serialized_navigation_builder.cc b/components/sessions/content/content_serialized_navigation_builder.cc
new file mode 100644
index 0000000..a9bd244
--- /dev/null
+++ b/components/sessions/content/content_serialized_navigation_builder.cc
@@ -0,0 +1,106 @@
+// 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 "components/sessions/content/content_serialized_navigation_builder.h"
+
+#include "components/sessions/serialized_navigation_entry.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/common/page_state.h"
+#include "content/public/common/referrer.h"
+
+namespace sessions {
+
+// static
+SerializedNavigationEntry
+ContentSerializedNavigationBuilder::FromNavigationEntry(
+    int index,
+    const content::NavigationEntry& entry) {
+  SerializedNavigationEntry navigation;
+  navigation.index_ = index;
+  navigation.unique_id_ = entry.GetUniqueID();
+  navigation.referrer_url_ = entry.GetReferrer().url;
+  navigation.referrer_policy_ = entry.GetReferrer().policy;
+  navigation.virtual_url_ = entry.GetVirtualURL();
+  navigation.title_ = entry.GetTitle();
+  navigation.encoded_page_state_ = entry.GetPageState().ToEncodedData();
+  navigation.transition_type_ = entry.GetTransitionType();
+  navigation.has_post_data_ = entry.GetHasPostData();
+  navigation.post_id_ = entry.GetPostID();
+  navigation.original_request_url_ = entry.GetOriginalRequestURL();
+  navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent();
+  navigation.timestamp_ = entry.GetTimestamp();
+  navigation.is_restored_ = entry.IsRestored();
+  // If you want to navigate a named frame in Chrome, you will first need to
+  // add support for persisting it. It is currently only used for layout tests.
+  CHECK(entry.GetFrameToNavigate().empty());
+  entry.GetExtraData(kSearchTermsKey, &navigation.search_terms_);
+  if (entry.GetFavicon().valid)
+    navigation.favicon_url_ = entry.GetFavicon().url;
+  navigation.http_status_code_ = entry.GetHttpStatusCode();
+  navigation.redirect_chain_ = entry.GetRedirectChain();
+
+  return navigation;
+}
+
+// static
+scoped_ptr<content::NavigationEntry>
+ContentSerializedNavigationBuilder::ToNavigationEntry(
+    const SerializedNavigationEntry* navigation,
+    int page_id,
+    content::BrowserContext* browser_context) {
+  blink::WebReferrerPolicy policy =
+      static_cast<blink::WebReferrerPolicy>(navigation->referrer_policy_);
+  scoped_ptr<content::NavigationEntry> entry(
+      content::NavigationController::CreateNavigationEntry(
+          navigation->virtual_url_,
+          content::Referrer(navigation->referrer_url_, policy),
+          // Use a transition type of reload so that we don't incorrectly
+          // increase the typed count.
+          ui::PAGE_TRANSITION_RELOAD,
+          false,
+          // The extra headers are not sync'ed across sessions.
+          std::string(),
+          browser_context));
+
+  entry->SetTitle(navigation->title_);
+  entry->SetPageState(content::PageState::CreateFromEncodedData(
+      navigation->encoded_page_state_));
+  entry->SetPageID(page_id);
+  entry->SetHasPostData(navigation->has_post_data_);
+  entry->SetPostID(navigation->post_id_);
+  entry->SetOriginalRequestURL(navigation->original_request_url_);
+  entry->SetIsOverridingUserAgent(navigation->is_overriding_user_agent_);
+  entry->SetTimestamp(navigation->timestamp_);
+  entry->SetExtraData(kSearchTermsKey, navigation->search_terms_);
+  entry->SetHttpStatusCode(navigation->http_status_code_);
+  entry->SetRedirectChain(navigation->redirect_chain_);
+
+  // These fields should have default values.
+  DCHECK_EQ(SerializedNavigationEntry::STATE_INVALID,
+            navigation->blocked_state_);
+  DCHECK_EQ(0u, navigation->content_pack_categories_.size());
+
+  return entry.Pass();
+}
+
+// static
+ScopedVector<content::NavigationEntry>
+ContentSerializedNavigationBuilder::ToNavigationEntries(
+    const std::vector<SerializedNavigationEntry>& navigations,
+    content::BrowserContext* browser_context) {
+  int page_id = 0;
+  ScopedVector<content::NavigationEntry> entries;
+  for (std::vector<SerializedNavigationEntry>::const_iterator
+       it = navigations.begin(); it != navigations.end(); ++it) {
+    entries.push_back(
+        ToNavigationEntry(&(*it), page_id, browser_context).release());
+    ++page_id;
+  }
+  return entries.Pass();
+}
+
+}  // namespace sessions
diff --git a/components/sessions/content/content_serialized_navigation_builder.h b/components/sessions/content/content_serialized_navigation_builder.h
new file mode 100644
index 0000000..b02117a
--- /dev/null
+++ b/components/sessions/content/content_serialized_navigation_builder.h
@@ -0,0 +1,49 @@
+// 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 COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_BUILDER_H_
+#define COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_BUILDER_H_
+
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "components/sessions/sessions_export.h"
+
+namespace content {
+class BrowserContext;
+class NavigationEntry;
+}
+
+namespace sessions {
+class SerializedNavigationEntry;
+
+// Provides methods to convert between SerializedNavigationEntry and content
+// classes.
+class SESSIONS_EXPORT ContentSerializedNavigationBuilder {
+ public:
+  // Construct a SerializedNavigationEntry for a particular index from the given
+  // NavigationEntry.
+  static SerializedNavigationEntry FromNavigationEntry(
+      int index,
+      const content::NavigationEntry& entry);
+
+  // Convert the given SerializedNavigationEntry into a NavigationEntry with the
+  // given page ID and context.  The NavigationEntry will have a transition type
+  // of PAGE_TRANSITION_RELOAD and a new unique ID.
+  static scoped_ptr<content::NavigationEntry> ToNavigationEntry(
+      const SerializedNavigationEntry* navigation,
+      int page_id,
+      content::BrowserContext* browser_context);
+
+  // Converts a set of SerializedNavigationEntrys into a list of
+  // NavigationEntrys with sequential page IDs and the given context.
+  static ScopedVector<content::NavigationEntry> ToNavigationEntries(
+      const std::vector<SerializedNavigationEntry>& navigations,
+      content::BrowserContext* browser_context);
+};
+
+}  // namespace sessions
+
+#endif  // COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_BUILDER_H_
diff --git a/components/sessions/content/content_serialized_navigation_builder_unittest.cc b/components/sessions/content/content_serialized_navigation_builder_unittest.cc
new file mode 100644
index 0000000..ee0d7c9
--- /dev/null
+++ b/components/sessions/content/content_serialized_navigation_builder_unittest.cc
@@ -0,0 +1,131 @@
+// 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 "components/sessions/content/content_serialized_navigation_builder.h"
+
+#include "components/sessions/serialized_navigation_entry.h"
+#include "components/sessions/serialized_navigation_entry_test_helper.h"
+#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/common/page_state.h"
+#include "content/public/common/referrer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace sessions {
+
+namespace {
+// Create a NavigationEntry from the test_data constants in
+// serialized_navigation_entry_test_helper.h.
+scoped_ptr<content::NavigationEntry> MakeNavigationEntryForTest() {
+  scoped_ptr<content::NavigationEntry> navigation_entry(
+      content::NavigationEntry::Create());
+  navigation_entry->SetReferrer(content::Referrer(
+      test_data::kReferrerURL,
+      static_cast<blink::WebReferrerPolicy>(test_data::kReferrerPolicy)));
+  navigation_entry->SetVirtualURL(test_data::kVirtualURL);
+  navigation_entry->SetTitle(test_data::kTitle);
+  navigation_entry->SetPageState(
+      content::PageState::CreateFromEncodedData(test_data::kEncodedPageState));
+  navigation_entry->SetTransitionType(test_data::kTransitionType);
+  navigation_entry->SetHasPostData(test_data::kHasPostData);
+  navigation_entry->SetPostID(test_data::kPostID);
+  navigation_entry->SetOriginalRequestURL(test_data::kOriginalRequestURL);
+  navigation_entry->SetIsOverridingUserAgent(test_data::kIsOverridingUserAgent);
+  navigation_entry->SetTimestamp(test_data::kTimestamp);
+  navigation_entry->SetExtraData(kSearchTermsKey,
+                                 test_data::kSearchTerms);
+  navigation_entry->GetFavicon().valid = true;
+  navigation_entry->GetFavicon().url = test_data::kFaviconURL;
+  navigation_entry->SetHttpStatusCode(test_data::kHttpStatusCode);
+  std::vector<GURL> redirect_chain;
+  redirect_chain.push_back(test_data::kRedirectURL0);
+  redirect_chain.push_back(test_data::kRedirectURL1);
+  redirect_chain.push_back(test_data::kVirtualURL);
+  navigation_entry->SetRedirectChain(redirect_chain);
+  return navigation_entry.Pass();
+}
+
+}  // namespace
+
+
+// Create a SerializedNavigationEntry from a NavigationEntry.  All its fields
+// should match the NavigationEntry's.
+TEST(ContentSerializedNavigationBuilderTest, FromNavigationEntry) {
+  const scoped_ptr<content::NavigationEntry> navigation_entry(
+      MakeNavigationEntryForTest());
+
+  const SerializedNavigationEntry& navigation =
+      ContentSerializedNavigationBuilder::FromNavigationEntry(
+          test_data::kIndex, *navigation_entry);
+
+  EXPECT_EQ(test_data::kIndex, navigation.index());
+
+  EXPECT_EQ(navigation_entry->GetUniqueID(), navigation.unique_id());
+  EXPECT_EQ(test_data::kReferrerURL, navigation.referrer_url());
+  EXPECT_EQ(test_data::kReferrerPolicy, navigation.referrer_policy());
+  EXPECT_EQ(test_data::kVirtualURL, navigation.virtual_url());
+  EXPECT_EQ(test_data::kTitle, navigation.title());
+  EXPECT_EQ(test_data::kEncodedPageState, navigation.encoded_page_state());
+  EXPECT_EQ(test_data::kTransitionType, navigation.transition_type());
+  EXPECT_EQ(test_data::kHasPostData, navigation.has_post_data());
+  EXPECT_EQ(test_data::kPostID, navigation.post_id());
+  EXPECT_EQ(test_data::kOriginalRequestURL, navigation.original_request_url());
+  EXPECT_EQ(test_data::kIsOverridingUserAgent,
+            navigation.is_overriding_user_agent());
+  EXPECT_EQ(test_data::kTimestamp, navigation.timestamp());
+  EXPECT_EQ(test_data::kFaviconURL, navigation.favicon_url());
+  EXPECT_EQ(test_data::kHttpStatusCode, navigation.http_status_code());
+  ASSERT_EQ(3U, navigation.redirect_chain().size());
+  EXPECT_EQ(test_data::kRedirectURL0, navigation.redirect_chain()[0]);
+  EXPECT_EQ(test_data::kRedirectURL1, navigation.redirect_chain()[1]);
+  EXPECT_EQ(test_data::kVirtualURL, navigation.redirect_chain()[2]);
+}
+
+// Create a NavigationEntry, then create another one by converting to
+// a SerializedNavigationEntry and back.  The new one should match the old one
+// except for fields that aren't preserved, which should be set to
+// expected values.
+TEST(ContentSerializedNavigationBuilderTest, ToNavigationEntry) {
+  const scoped_ptr<content::NavigationEntry> old_navigation_entry(
+      MakeNavigationEntryForTest());
+
+  const SerializedNavigationEntry& navigation =
+      ContentSerializedNavigationBuilder::FromNavigationEntry(
+          test_data::kIndex, *old_navigation_entry);
+
+  const scoped_ptr<content::NavigationEntry> new_navigation_entry(
+      ContentSerializedNavigationBuilder::ToNavigationEntry(
+          &navigation, test_data::kPageID, NULL));
+
+  EXPECT_EQ(test_data::kReferrerURL, new_navigation_entry->GetReferrer().url);
+  EXPECT_EQ(test_data::kReferrerPolicy,
+            new_navigation_entry->GetReferrer().policy);
+  EXPECT_EQ(test_data::kVirtualURL, new_navigation_entry->GetVirtualURL());
+  EXPECT_EQ(test_data::kTitle, new_navigation_entry->GetTitle());
+  EXPECT_EQ(test_data::kEncodedPageState,
+            new_navigation_entry->GetPageState().ToEncodedData());
+  EXPECT_EQ(test_data::kPageID, new_navigation_entry->GetPageID());
+  EXPECT_EQ(ui::PAGE_TRANSITION_RELOAD,
+            new_navigation_entry->GetTransitionType());
+  EXPECT_EQ(test_data::kHasPostData, new_navigation_entry->GetHasPostData());
+  EXPECT_EQ(test_data::kPostID, new_navigation_entry->GetPostID());
+  EXPECT_EQ(test_data::kOriginalRequestURL,
+            new_navigation_entry->GetOriginalRequestURL());
+  EXPECT_EQ(test_data::kIsOverridingUserAgent,
+            new_navigation_entry->GetIsOverridingUserAgent());
+  base::string16 search_terms;
+  new_navigation_entry->GetExtraData(kSearchTermsKey, &search_terms);
+  EXPECT_EQ(test_data::kSearchTerms, search_terms);
+  EXPECT_EQ(test_data::kHttpStatusCode,
+            new_navigation_entry->GetHttpStatusCode());
+  ASSERT_EQ(3U, new_navigation_entry->GetRedirectChain().size());
+  EXPECT_EQ(test_data::kRedirectURL0,
+            new_navigation_entry->GetRedirectChain()[0]);
+  EXPECT_EQ(test_data::kRedirectURL1,
+            new_navigation_entry->GetRedirectChain()[1]);
+  EXPECT_EQ(test_data::kVirtualURL,
+            new_navigation_entry->GetRedirectChain()[2]);
+}
+
+}  // namespace sessions
diff --git a/components/sessions/content/content_serialized_navigation_driver.cc b/components/sessions/content/content_serialized_navigation_driver.cc
new file mode 100644
index 0000000..4dd6bd0
--- /dev/null
+++ b/components/sessions/content/content_serialized_navigation_driver.cc
@@ -0,0 +1,71 @@
+// 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 "components/sessions/content/content_serialized_navigation_driver.h"
+
+#include "base/memory/singleton.h"
+#include "components/sessions/serialized_navigation_entry.h"
+#include "content/public/common/page_state.h"
+#include "content/public/common/referrer.h"
+
+namespace sessions {
+
+// static
+SerializedNavigationDriver* SerializedNavigationDriver::Get() {
+  return ContentSerializedNavigationDriver::GetInstance();
+}
+
+// static
+ContentSerializedNavigationDriver*
+ContentSerializedNavigationDriver::GetInstance() {
+  return Singleton<ContentSerializedNavigationDriver,
+      LeakySingletonTraits<ContentSerializedNavigationDriver>>::get();
+}
+
+ContentSerializedNavigationDriver::ContentSerializedNavigationDriver() {
+}
+
+ContentSerializedNavigationDriver::~ContentSerializedNavigationDriver() {
+}
+
+int ContentSerializedNavigationDriver::GetDefaultReferrerPolicy() const {
+  return blink::WebReferrerPolicyDefault;
+}
+
+std::string
+ContentSerializedNavigationDriver::GetSanitizedPageStateForPickle(
+    const SerializedNavigationEntry* navigation) const {
+  if (!navigation->has_post_data_) {
+    return navigation->encoded_page_state_;
+  }
+  content::PageState page_state =
+      content::PageState::CreateFromEncodedData(
+          navigation->encoded_page_state_);
+  return page_state.RemovePasswordData().ToEncodedData();
+}
+
+void ContentSerializedNavigationDriver::Sanitize(
+    SerializedNavigationEntry* navigation) const {
+  content::Referrer old_referrer(
+      navigation->referrer_url_,
+      static_cast<blink::WebReferrerPolicy>(navigation->referrer_policy_));
+  content::Referrer new_referrer =
+      content::Referrer::SanitizeForRequest(navigation->virtual_url_,
+                                            old_referrer);
+
+  // No need to compare the policy, as it doesn't change during
+  // sanitization. If there has been a change, the referrer needs to be
+  // stripped from the page state as well.
+  if (navigation->referrer_url_ != new_referrer.url) {
+    navigation->referrer_url_ = GURL();
+    navigation->referrer_policy_ = GetDefaultReferrerPolicy();
+    navigation->encoded_page_state_ =
+        content::PageState::CreateFromEncodedData(
+            navigation->encoded_page_state_)
+            .RemoveReferrer()
+            .ToEncodedData();
+  }
+}
+
+}  // namespace sessions
diff --git a/components/sessions/content/content_serialized_navigation_driver.h b/components/sessions/content/content_serialized_navigation_driver.h
new file mode 100644
index 0000000..499d258
--- /dev/null
+++ b/components/sessions/content/content_serialized_navigation_driver.h
@@ -0,0 +1,40 @@
+// 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 COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_DRIVER_H_
+#define COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_DRIVER_H_
+
+#include "components/sessions/core/serialized_navigation_driver.h"
+
+#include "components/sessions/sessions_export.h"
+
+template <typename T> struct DefaultSingletonTraits;
+
+namespace sessions {
+
+// Provides an implementation of SerializedNavigationDriver that is backed by
+// content classes.
+class SESSIONS_EXPORT_PRIVATE ContentSerializedNavigationDriver
+    : public SerializedNavigationDriver {
+ public:
+  virtual ~ContentSerializedNavigationDriver();
+
+  // Returns the singleton ContentSerializedNavigationDriver.  Almost all
+  // callers should use SerializedNavigationDriver::Get() instead.
+  static ContentSerializedNavigationDriver* GetInstance();
+
+  // SerializedNavigationDriver implementation.
+  virtual int GetDefaultReferrerPolicy() const override;
+  virtual std::string GetSanitizedPageStateForPickle(
+      const SerializedNavigationEntry* navigation) const override;
+  virtual void Sanitize(SerializedNavigationEntry* navigation) const override;
+
+ private:
+  ContentSerializedNavigationDriver();
+  friend struct DefaultSingletonTraits<ContentSerializedNavigationDriver>;
+};
+
+}  // namespace sessions
+
+#endif  // COMPONENTS_SESSIONS_CONTENT_CONTENT_SERIALIZED_NAVIGATION_DRIVER_H_
diff --git a/components/sessions/content/content_serialized_navigation_driver_unittest.cc b/components/sessions/content/content_serialized_navigation_driver_unittest.cc
new file mode 100644
index 0000000..9a3525c
--- /dev/null
+++ b/components/sessions/content/content_serialized_navigation_driver_unittest.cc
@@ -0,0 +1,117 @@
+// 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 "components/sessions/content/content_serialized_navigation_driver.h"
+
+#include "components/sessions/serialized_navigation_entry.h"
+#include "components/sessions/serialized_navigation_entry_test_helper.h"
+#include "content/public/common/page_state.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
+
+namespace sessions {
+
+// Tests that PageState data is properly sanitized when post data is present.
+TEST(ContentSerializedNavigationDriverTest, PickleSanitizationWithPostData) {
+  ContentSerializedNavigationDriver* driver =
+      ContentSerializedNavigationDriver::GetInstance();
+  SerializedNavigationEntry navigation =
+      SerializedNavigationEntryTestHelper::CreateNavigationForTest();
+  ASSERT_TRUE(navigation.has_post_data());
+
+  // When post data is present, the page state should be sanitized.
+  std::string sanitized_page_state =
+      driver->GetSanitizedPageStateForPickle(&navigation);
+  EXPECT_EQ(std::string(), sanitized_page_state);
+}
+
+// Tests that PageState data is left unsanitized when post data is absent.
+TEST(ContentSerializedNavigationDriverTest, PickleSanitizationNoPostData) {
+  ContentSerializedNavigationDriver* driver =
+      ContentSerializedNavigationDriver::GetInstance();
+  SerializedNavigationEntry navigation =
+      SerializedNavigationEntryTestHelper::CreateNavigationForTest();
+  SerializedNavigationEntryTestHelper::SetHasPostData(false, &navigation);
+  ASSERT_FALSE(navigation.has_post_data());
+
+  std::string sanitized_page_state =
+      driver->GetSanitizedPageStateForPickle(&navigation);
+  EXPECT_EQ(test_data::kEncodedPageState, sanitized_page_state);
+}
+
+// Tests that the input data is left unsanitized when the referrer policy is
+// Always.
+TEST(ContentSerializedNavigationDriverTest, SanitizeWithReferrerPolicyAlways) {
+  ContentSerializedNavigationDriver* driver =
+      ContentSerializedNavigationDriver::GetInstance();
+  SerializedNavigationEntry navigation =
+      SerializedNavigationEntryTestHelper::CreateNavigationForTest();
+  SerializedNavigationEntryTestHelper::SetReferrerPolicy(
+      blink::WebReferrerPolicyAlways, &navigation);
+
+  content::PageState page_state =
+      content::PageState::CreateFromURL(test_data::kVirtualURL);
+  SerializedNavigationEntryTestHelper::SetEncodedPageState(
+      page_state.ToEncodedData(), &navigation);
+
+  driver->Sanitize(&navigation);
+  EXPECT_EQ(test_data::kIndex, navigation.index());
+  EXPECT_EQ(test_data::kUniqueID, navigation.unique_id());
+  EXPECT_EQ(test_data::kReferrerURL, navigation.referrer_url());
+  EXPECT_EQ(blink::WebReferrerPolicyAlways, navigation.referrer_policy());
+  EXPECT_EQ(test_data::kVirtualURL, navigation.virtual_url());
+  EXPECT_EQ(test_data::kTitle, navigation.title());
+  EXPECT_EQ(page_state.ToEncodedData(), navigation.encoded_page_state());
+  EXPECT_EQ(test_data::kTransitionType, navigation.transition_type());
+  EXPECT_EQ(test_data::kHasPostData, navigation.has_post_data());
+  EXPECT_EQ(test_data::kPostID, navigation.post_id());
+  EXPECT_EQ(test_data::kOriginalRequestURL, navigation.original_request_url());
+  EXPECT_EQ(test_data::kIsOverridingUserAgent,
+            navigation.is_overriding_user_agent());
+  EXPECT_EQ(test_data::kTimestamp, navigation.timestamp());
+  EXPECT_EQ(test_data::kSearchTerms, navigation.search_terms());
+  EXPECT_EQ(test_data::kFaviconURL, navigation.favicon_url());
+  EXPECT_EQ(test_data::kHttpStatusCode, navigation.http_status_code());
+}
+
+// Tests that the input data is properly sanitized when the referrer policy is
+// Never.
+TEST(ContentSerializedNavigationDriverTest, SanitizeWithReferrerPolicyNever) {
+  ContentSerializedNavigationDriver* driver =
+      ContentSerializedNavigationDriver::GetInstance();
+  SerializedNavigationEntry navigation =
+      SerializedNavigationEntryTestHelper::CreateNavigationForTest();
+  SerializedNavigationEntryTestHelper::SetReferrerPolicy(
+      blink::WebReferrerPolicyNever, &navigation);
+
+  content::PageState page_state =
+      content::PageState::CreateFromURL(test_data::kVirtualURL);
+  SerializedNavigationEntryTestHelper::SetEncodedPageState(
+      page_state.ToEncodedData(), &navigation);
+
+  driver->Sanitize(&navigation);
+
+  // Fields that should remain untouched.
+  EXPECT_EQ(test_data::kIndex, navigation.index());
+  EXPECT_EQ(test_data::kUniqueID, navigation.unique_id());
+  EXPECT_EQ(test_data::kVirtualURL, navigation.virtual_url());
+  EXPECT_EQ(test_data::kTitle, navigation.title());
+  EXPECT_EQ(test_data::kTransitionType, navigation.transition_type());
+  EXPECT_EQ(test_data::kHasPostData, navigation.has_post_data());
+  EXPECT_EQ(test_data::kPostID, navigation.post_id());
+  EXPECT_EQ(test_data::kOriginalRequestURL, navigation.original_request_url());
+  EXPECT_EQ(test_data::kIsOverridingUserAgent,
+            navigation.is_overriding_user_agent());
+  EXPECT_EQ(test_data::kTimestamp, navigation.timestamp());
+  EXPECT_EQ(test_data::kSearchTerms, navigation.search_terms());
+  EXPECT_EQ(test_data::kFaviconURL, navigation.favicon_url());
+  EXPECT_EQ(test_data::kHttpStatusCode, navigation.http_status_code());
+
+  // Fields that were sanitized.
+  EXPECT_EQ(GURL(), navigation.referrer_url());
+  EXPECT_EQ(blink::WebReferrerPolicyDefault, navigation.referrer_policy());
+  EXPECT_EQ(page_state.ToEncodedData(), navigation.encoded_page_state());
+}
+
+}  // namespace sessions
diff --git a/components/sessions/core/serialized_navigation_driver.h b/components/sessions/core/serialized_navigation_driver.h
new file mode 100644
index 0000000..fafaa27d
--- /dev/null
+++ b/components/sessions/core/serialized_navigation_driver.h
@@ -0,0 +1,40 @@
+// 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 COMPONENTS_SESSIONS_CORE_SERIALIZED_NAVIGATION_DRIVER_H_
+#define COMPONENTS_SESSIONS_CORE_SERIALIZED_NAVIGATION_DRIVER_H_
+
+#include <string>
+
+#include "components/sessions/sessions_export.h"
+
+namespace sessions {
+class SerializedNavigationEntry;
+
+// The SerializedNavigationDriver interface allows SerializedNavigationEntry to
+// obtain information from a singleton driver object. A concrete implementation
+// must be provided by the driver on each platform.
+class SESSIONS_EXPORT_PRIVATE SerializedNavigationDriver {
+ public:
+  virtual ~SerializedNavigationDriver() {}
+
+  // Returns the singleton SerializedNavigationDriver.
+  static SerializedNavigationDriver* Get();
+
+  // Returns the default referrer policy.
+  virtual int GetDefaultReferrerPolicy() const = 0;
+
+  // Returns a sanitized version of the given |navigation|'s encoded_page_state
+  // suitable for writing to disk.
+  virtual std::string GetSanitizedPageStateForPickle(
+      const SerializedNavigationEntry* navigation) const = 0;
+
+  // Sanitizes the data in the given |navigation| to be more robust against
+  // faulty data written by older versions.
+  virtual void Sanitize(SerializedNavigationEntry* navigation) const = 0;
+};
+
+}  // namespace sessions
+
+#endif  // COMPONENTS_SESSIONS_CORE_SERIALIZED_NAVIGATION_DRIVER_H_
diff --git a/components/sessions/serialized_navigation_entry.cc b/components/sessions/serialized_navigation_entry.cc
index facd7e4..5135223 100644
--- a/components/sessions/serialized_navigation_entry.cc
+++ b/components/sessions/serialized_navigation_entry.cc
@@ -6,17 +6,11 @@
 
 #include "base/pickle.h"
 #include "base/strings/utf_string_conversions.h"
-#include "content/public/browser/favicon_status.h"
-#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/navigation_entry.h"
-#include "content/public/common/page_state.h"
-#include "content/public/common/referrer.h"
+#include "components/sessions/core/serialized_navigation_driver.h"
 #include "sync/protocol/session_specifics.pb.h"
 #include "sync/util/time.h"
 #include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
 
-using content::NavigationEntry;
-
 namespace sessions {
 
 const char kSearchTermsKey[] = "search_terms";
@@ -31,42 +25,12 @@
       http_status_code_(0),
       is_restored_(false),
       blocked_state_(STATE_INVALID) {
-  referrer_policy_ = GetDefaultReferrerPolicy();
+  referrer_policy_ =
+      SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy();
 }
 
 SerializedNavigationEntry::~SerializedNavigationEntry() {}
 
-// static
-SerializedNavigationEntry SerializedNavigationEntry::FromNavigationEntry(
-    int index,
-    const NavigationEntry& entry) {
-  SerializedNavigationEntry navigation;
-  navigation.index_ = index;
-  navigation.unique_id_ = entry.GetUniqueID();
-  navigation.referrer_url_ = entry.GetReferrer().url;
-  navigation.referrer_policy_ = entry.GetReferrer().policy;
-  navigation.virtual_url_ = entry.GetVirtualURL();
-  navigation.title_ = entry.GetTitle();
-  navigation.encoded_page_state_ = entry.GetPageState().ToEncodedData();
-  navigation.transition_type_ = entry.GetTransitionType();
-  navigation.has_post_data_ = entry.GetHasPostData();
-  navigation.post_id_ = entry.GetPostID();
-  navigation.original_request_url_ = entry.GetOriginalRequestURL();
-  navigation.is_overriding_user_agent_ = entry.GetIsOverridingUserAgent();
-  navigation.timestamp_ = entry.GetTimestamp();
-  navigation.is_restored_ = entry.IsRestored();
-  // If you want to navigate a named frame in Chrome, you will first need to
-  // add support for persisting it. It is currently only used for layout tests.
-  CHECK(entry.GetFrameToNavigate().empty());
-  entry.GetExtraData(kSearchTermsKey, &navigation.search_terms_);
-  if (entry.GetFavicon().valid)
-    navigation.favicon_url_ = entry.GetFavicon().url;
-  navigation.http_status_code_ = entry.GetHttpStatusCode();
-  navigation.redirect_chain_ = entry.GetRedirectChain();
-
-  return navigation;
-}
-
 SerializedNavigationEntry SerializedNavigationEntry::FromSyncData(
     int index,
     const sync_pb::TabNavigation& sync_data) {
@@ -151,7 +115,7 @@
 
   navigation.http_status_code_ = sync_data.http_status_code();
 
-  navigation.Sanitize();
+  SerializedNavigationDriver::Get()->Sanitize(&navigation);
 
   navigation.is_restored_ = true;
 
@@ -238,7 +202,8 @@
 
   WriteString16ToPickle(pickle, &bytes_written, max_size, title_);
 
-  const std::string encoded_page_state = GetSanitizedPageStateForPickle();
+  const std::string encoded_page_state =
+      SerializedNavigationDriver::Get()->GetSanitizedPageStateForPickle(this);
   WriteStringToPickle(pickle, &bytes_written, max_size, encoded_page_state);
 
   pickle->WriteInt(transition_type_);
@@ -295,7 +260,8 @@
     // The "referrer policy" property was added even later, so we fall back to
     // the default policy if the property is not present.
     if (!iterator->ReadInt(&referrer_policy_))
-      referrer_policy_ = GetDefaultReferrerPolicy();
+      referrer_policy_ =
+          SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy();
 
     // If the original URL can't be found, leave it empty.
     std::string original_request_url_spec;
@@ -322,50 +288,13 @@
       http_status_code_ = 0;
   }
 
-  Sanitize();
+  SerializedNavigationDriver::Get()->Sanitize(this);
 
   is_restored_ = true;
 
   return true;
 }
 
-scoped_ptr<NavigationEntry> SerializedNavigationEntry::ToNavigationEntry(
-    int page_id,
-    content::BrowserContext* browser_context) const {
-  scoped_ptr<NavigationEntry> entry(
-      content::NavigationController::CreateNavigationEntry(
-          virtual_url_,
-          content::Referrer(
-              referrer_url_,
-              static_cast<blink::WebReferrerPolicy>(referrer_policy_)),
-          // Use a transition type of reload so that we don't incorrectly
-          // increase the typed count.
-          ui::PAGE_TRANSITION_RELOAD,
-          false,
-          // The extra headers are not sync'ed across sessions.
-          std::string(),
-          browser_context));
-
-  entry->SetTitle(title_);
-  entry->SetPageState(
-      content::PageState::CreateFromEncodedData(encoded_page_state_));
-  entry->SetPageID(page_id);
-  entry->SetHasPostData(has_post_data_);
-  entry->SetPostID(post_id_);
-  entry->SetOriginalRequestURL(original_request_url_);
-  entry->SetIsOverridingUserAgent(is_overriding_user_agent_);
-  entry->SetTimestamp(timestamp_);
-  entry->SetExtraData(kSearchTermsKey, search_terms_);
-  entry->SetHttpStatusCode(http_status_code_);
-  entry->SetRedirectChain(redirect_chain_);
-
-  // These fields should have default values.
-  DCHECK_EQ(STATE_INVALID, blocked_state_);
-  DCHECK_EQ(0u, content_pack_categories_.size());
-
-  return entry.Pass();
-}
-
 // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well?
 // See http://crbug.com/67068.
 sync_pb::TabNavigation SerializedNavigationEntry::ToSyncData() const {
@@ -493,58 +422,4 @@
   return sync_data;
 }
 
-// static
-std::vector<NavigationEntry*> SerializedNavigationEntry::ToNavigationEntries(
-    const std::vector<SerializedNavigationEntry>& navigations,
-    content::BrowserContext* browser_context) {
-  int page_id = 0;
-  std::vector<NavigationEntry*> entries;
-  for (std::vector<SerializedNavigationEntry>::const_iterator
-       it = navigations.begin(); it != navigations.end(); ++it) {
-    entries.push_back(
-        it->ToNavigationEntry(page_id, browser_context).release());
-    ++page_id;
-  }
-  return entries;
-}
-
-// TODO(rohitrao): Move this content-specific code into a
-// SerializedNavigationEntryHelper class.
-int SerializedNavigationEntry::GetDefaultReferrerPolicy() const {
-  return blink::WebReferrerPolicyDefault;
-}
-
-// TODO(rohitrao): Move this content-specific code into a
-// SerializedNavigationEntryHelper class.
-std::string SerializedNavigationEntry::GetSanitizedPageStateForPickle() const {
-  content::PageState page_state =
-      content::PageState::CreateFromEncodedData(encoded_page_state_);
-  if (has_post_data_)
-    page_state = page_state.RemovePasswordData();
-
-  return page_state.ToEncodedData();
-}
-
-// TODO(rohitrao): Move this content-specific code into a
-// SerializedNavigationEntryHelper class.
-void SerializedNavigationEntry::Sanitize() {
-  content::Referrer old_referrer(
-      referrer_url_,
-      static_cast<blink::WebReferrerPolicy>(referrer_policy_));
-  content::Referrer new_referrer =
-      content::Referrer::SanitizeForRequest(virtual_url_, old_referrer);
-
-  // No need to compare the policy, as it doesn't change during
-  // sanitization. If there has been a change, the referrer needs to be
-  // stripped from the page state as well.
-  if (referrer_url_ != new_referrer.url) {
-    referrer_url_ = GURL();
-    referrer_policy_ = GetDefaultReferrerPolicy();
-    encoded_page_state_ =
-        content::PageState::CreateFromEncodedData(encoded_page_state_)
-            .RemoveReferrer()
-            .ToEncodedData();
-  }
-}
-
 }  // namespace sessions
diff --git a/components/sessions/serialized_navigation_entry.h b/components/sessions/serialized_navigation_entry.h
index bbc3d7a..7db46c0 100644
--- a/components/sessions/serialized_navigation_entry.h
+++ b/components/sessions/serialized_navigation_entry.h
@@ -20,11 +20,6 @@
 class Pickle;
 class PickleIterator;
 
-namespace content {
-class BrowserContext;
-class NavigationEntry;
-}
-
 namespace sync_pb {
 class TabNavigation;
 }
@@ -54,12 +49,6 @@
   SerializedNavigationEntry();
   ~SerializedNavigationEntry();
 
-  // Construct a SerializedNavigationEntry for a particular index from the given
-  // NavigationEntry.
-  static SerializedNavigationEntry FromNavigationEntry(
-      int index,
-      const content::NavigationEntry& entry);
-
   // Construct a SerializedNavigationEntry for a particular index from a sync
   // protocol buffer.  Note that the sync protocol buffer doesn't contain all
   // SerializedNavigationEntry fields.  Also, the timestamp of the returned
@@ -74,13 +63,6 @@
   void WriteToPickle(int max_size, Pickle* pickle) const;
   bool ReadFromPickle(PickleIterator* iterator);
 
-  // Convert this SerializedNavigationEntry into a NavigationEntry with the
-  // given page ID and context.  The NavigationEntry will have a transition type
-  // of PAGE_TRANSITION_RELOAD and a new unique ID.
-  scoped_ptr<content::NavigationEntry> ToNavigationEntry(
-      int page_id,
-      content::BrowserContext* browser_context) const;
-
   // Convert this navigation into its sync protocol buffer equivalent.  Note
   // that the protocol buffer doesn't contain all SerializedNavigationEntry
   // fields.
@@ -123,27 +105,11 @@
   }
   const std::vector<GURL>& redirect_chain() const { return redirect_chain_; }
 
-  // Converts a set of SerializedNavigationEntrys into a list of
-  // NavigationEntrys with sequential page IDs and the given context. The caller
-  // owns the returned NavigationEntrys.
-  static std::vector<content::NavigationEntry*> ToNavigationEntries(
-      const std::vector<SerializedNavigationEntry>& navigations,
-      content::BrowserContext* browser_context);
-
  private:
+  friend class ContentSerializedNavigationBuilder;
+  friend class ContentSerializedNavigationDriver;
   friend class SerializedNavigationEntryTestHelper;
 
-  // Returns the default referrer policy.
-  int GetDefaultReferrerPolicy() const;
-
-  // Returns a sanitized version of |encoded_page_state_| suitable for writing
-  // to disk.
-  std::string GetSanitizedPageStateForPickle() const;
-
-  // Sanitizes the data in this class to be more robust against faulty data
-  // written by older versions.
-  void Sanitize();
-
   // Index in the NavigationController.
   int index_;
 
diff --git a/components/sessions/serialized_navigation_entry_test_helper.cc b/components/sessions/serialized_navigation_entry_test_helper.cc
index 030db0b..708346b 100644
--- a/components/sessions/serialized_navigation_entry_test_helper.cc
+++ b/components/sessions/serialized_navigation_entry_test_helper.cc
@@ -7,13 +7,41 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 #include "components/sessions/serialized_navigation_entry.h"
-#include "content/public/common/page_state.h"
+#include "sync/util/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
 #include "url/gurl.h"
 
 namespace sessions {
 
+namespace test_data {
+
+const int kIndex = 3;
+const int kUniqueID = 50;
+const GURL kReferrerURL = GURL("http://www.referrer.com");
+const int kReferrerPolicy = 0;
+const GURL kVirtualURL= GURL("http://www.virtual-url.com");
+const base::string16 kTitle = base::ASCIIToUTF16("title");
+const std::string kEncodedPageState = "page state";
+const ui::PageTransition kTransitionType =
+    ui::PageTransitionFromInt(
+        ui::PAGE_TRANSITION_AUTO_SUBFRAME |
+        ui::PAGE_TRANSITION_HOME_PAGE |
+        ui::PAGE_TRANSITION_CLIENT_REDIRECT);
+const bool kHasPostData = true;
+const int64 kPostID = 100;
+const GURL kOriginalRequestURL = GURL("http://www.original-request.com");
+const bool kIsOverridingUserAgent = true;
+const base::Time kTimestamp = syncer::ProtoTimeToTime(100);
+const base::string16 kSearchTerms = base::ASCIIToUTF16("my search terms");
+const GURL kFaviconURL = GURL("http://virtual-url.com/favicon.ico");
+const int kHttpStatusCode = 404;
+const GURL kRedirectURL0 = GURL("http://go/redirect0");
+const GURL kRedirectURL1 = GURL("http://go/redirect1");
+const GURL kOtherURL = GURL("http://other.com");
+const int kPageID = 10;
+
+}  // namespace test_data
+
 // static
 void SerializedNavigationEntryTestHelper::ExpectNavigationEquals(
     const SerializedNavigationEntry& expected,
@@ -37,7 +65,6 @@
   SerializedNavigationEntry navigation;
   navigation.index_ = 0;
   navigation.referrer_url_ = GURL("http://www.referrer.com");
-  navigation.referrer_policy_ = blink::WebReferrerPolicyDefault;
   navigation.virtual_url_ = GURL(virtual_url);
   navigation.title_ = base::UTF8ToUTF16(title);
   navigation.encoded_page_state_ = "fake state";
@@ -47,10 +74,58 @@
 }
 
 // static
-void SerializedNavigationEntryTestHelper::SetPageState(
-    const content::PageState& page_state,
+SerializedNavigationEntry
+SerializedNavigationEntryTestHelper::CreateNavigationForTest() {
+  SerializedNavigationEntry navigation;
+  navigation.index_ = test_data::kIndex;
+  navigation.unique_id_ = test_data::kUniqueID;
+  navigation.referrer_url_ = test_data::kReferrerURL;
+  navigation.referrer_policy_ = test_data::kReferrerPolicy;
+  navigation.virtual_url_ = test_data::kVirtualURL;
+  navigation.title_ = test_data::kTitle;
+  navigation.encoded_page_state_ = test_data::kEncodedPageState;
+  navigation.transition_type_ = test_data::kTransitionType;
+  navigation.has_post_data_ = test_data::kHasPostData;
+  navigation.post_id_ = test_data::kPostID;
+  navigation.original_request_url_ = test_data::kOriginalRequestURL;
+  navigation.is_overriding_user_agent_ = test_data::kIsOverridingUserAgent;
+  navigation.timestamp_ = test_data::kTimestamp;
+  navigation.search_terms_ = test_data::kSearchTerms;
+  navigation.favicon_url_ = test_data::kFaviconURL;
+  navigation.http_status_code_ = test_data::kHttpStatusCode;
+
+  navigation.redirect_chain_.push_back(test_data::kRedirectURL0);
+  navigation.redirect_chain_.push_back(test_data::kRedirectURL1);
+  navigation.redirect_chain_.push_back(test_data::kVirtualURL);
+  return navigation;
+}
+
+// static
+void SerializedNavigationEntryTestHelper::SetReferrerPolicy(
+    int policy,
     SerializedNavigationEntry* navigation) {
-  navigation->encoded_page_state_ = page_state.ToEncodedData();
+  navigation->referrer_policy_ = policy;
+}
+
+// static
+void SerializedNavigationEntryTestHelper::SetVirtualURL(
+    const GURL& virtual_url,
+    SerializedNavigationEntry* navigation) {
+  navigation->virtual_url_ = virtual_url;
+}
+
+// static
+void SerializedNavigationEntryTestHelper::SetEncodedPageState(
+    const std::string& encoded_page_state,
+    SerializedNavigationEntry* navigation) {
+  navigation->encoded_page_state_ = encoded_page_state;
+}
+
+// static
+void SerializedNavigationEntryTestHelper::SetTransitionType(
+    ui::PageTransition transition_type,
+    SerializedNavigationEntry* navigation) {
+  navigation->transition_type_ = transition_type;
 }
 
 // static
diff --git a/components/sessions/serialized_navigation_entry_test_helper.h b/components/sessions/serialized_navigation_entry_test_helper.h
index 1044b0c..54f070f 100644
--- a/components/sessions/serialized_navigation_entry_test_helper.h
+++ b/components/sessions/serialized_navigation_entry_test_helper.h
@@ -8,6 +8,9 @@
 #include <string>
 
 #include "base/basictypes.h"
+#include "base/strings/string16.h"
+#include "base/time/time.h"
+#include "ui/base/page_transition_types.h"
 
 class GURL;
 
@@ -15,15 +18,35 @@
 class Time;
 }
 
-namespace content {
-class PageState;
-struct Referrer;
-}
-
 namespace sessions {
 
 class SerializedNavigationEntry;
 
+namespace test_data {
+
+extern const int kIndex;
+extern const int kUniqueID;
+extern const GURL kReferrerURL;
+extern const int kReferrerPolicy;
+extern const GURL kVirtualURL;
+extern const base::string16 kTitle;
+extern const std::string kEncodedPageState;
+extern const ui::PageTransition kTransitionType;
+extern const bool kHasPostData;
+extern const int64 kPostID;
+extern const GURL kOriginalRequestURL;
+extern const bool kIsOverridingUserAgent;
+extern const base::Time kTimestamp;
+extern const base::string16 kSearchTerms;
+extern const GURL kFaviconURL;
+extern const int kHttpStatusCode;
+extern const GURL kRedirectURL0;
+extern const GURL kRedirectURL1;
+extern const GURL kOtherURL;
+extern const int kPageID;
+
+}  // namespace test_data
+
 // Set of test functions to manipulate a SerializedNavigationEntry.
 class SerializedNavigationEntryTestHelper {
  public:
@@ -32,14 +55,26 @@
   static void ExpectNavigationEquals(const SerializedNavigationEntry& expected,
                                      const SerializedNavigationEntry& actual);
 
-  // Create a SerializedNavigationEntry with the given URL and title and some
+  // Creates a SerializedNavigationEntry with the given URL and title and some
   // common values for the other fields.
   static SerializedNavigationEntry CreateNavigation(
       const std::string& virtual_url,
       const std::string& title);
 
-  static void SetPageState(const content::PageState& page_state,
-                           SerializedNavigationEntry* navigation);
+  // Creates a SerializedNavigationEntry using the |test_data| constants above.
+  static SerializedNavigationEntry CreateNavigationForTest();
+
+  static void SetReferrerPolicy(int policy,
+                                SerializedNavigationEntry* navigation);
+
+  static void SetVirtualURL(const GURL& virtual_url,
+                            SerializedNavigationEntry* navigation);
+
+  static void SetEncodedPageState(const std::string& encoded_page_state,
+                                  SerializedNavigationEntry* navigation);
+
+  static void SetTransitionType(ui::PageTransition transition_type,
+                                SerializedNavigationEntry* navigation);
 
   static void SetHasPostData(bool has_post_data,
                              SerializedNavigationEntry* navigation);
diff --git a/components/sessions/serialized_navigation_entry_unittest.cc b/components/sessions/serialized_navigation_entry_unittest.cc
index f14321a..70a3086 100644
--- a/components/sessions/serialized_navigation_entry_unittest.cc
+++ b/components/sessions/serialized_navigation_entry_unittest.cc
@@ -14,92 +14,34 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
-#include "content/public/browser/favicon_status.h"
-#include "content/public/browser/navigation_entry.h"
-#include "content/public/common/page_state.h"
-#include "content/public/common/referrer.h"
+#include "components/sessions/core/serialized_navigation_driver.h"
+#include "components/sessions/serialized_navigation_entry_test_helper.h"
 #include "sync/protocol/session_specifics.pb.h"
 #include "sync/util/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
 #include "ui/base/page_transition_types.h"
 #include "url/gurl.h"
 
 namespace sessions {
 namespace {
 
-const int kIndex = 3;
-const int kUniqueID = 50;
-const GURL kReferrerURL = GURL("http://www.referrer.com");
-const int kReferrerPolicy = blink::WebReferrerPolicyAlways;
-const GURL kVirtualURL("http://www.virtual-url.com");
-const base::string16 kTitle = base::ASCIIToUTF16("title");
-const std::string kEncodedPageState = "page state";
-const ui::PageTransition kTransitionType =
-    ui::PageTransitionFromInt(
-        ui::PAGE_TRANSITION_AUTO_SUBFRAME |
-        ui::PAGE_TRANSITION_HOME_PAGE |
-        ui::PAGE_TRANSITION_CLIENT_REDIRECT);
-const bool kHasPostData = true;
-const int64 kPostID = 100;
-const GURL kOriginalRequestURL("http://www.original-request.com");
-const bool kIsOverridingUserAgent = true;
-const base::Time kTimestamp = syncer::ProtoTimeToTime(100);
-const base::string16 kSearchTerms = base::ASCIIToUTF16("my search terms");
-const GURL kFaviconURL("http://virtual-url.com/favicon.ico");
-const int kHttpStatusCode = 404;
-const GURL kRedirectURL0("http://go/redirect0");
-const GURL kRedirectURL1("http://go/redirect1");
-const GURL kOtherURL("http://other.com");
-
-const int kPageID = 10;
-
-// Create a NavigationEntry from the constants above.
-scoped_ptr<content::NavigationEntry> MakeNavigationEntryForTest() {
-  scoped_ptr<content::NavigationEntry> navigation_entry(
-      content::NavigationEntry::Create());
-  navigation_entry->SetReferrer(content::Referrer(
-      kReferrerURL,
-      static_cast<blink::WebReferrerPolicy>(kReferrerPolicy)));
-  navigation_entry->SetVirtualURL(kVirtualURL);
-  navigation_entry->SetTitle(kTitle);
-  navigation_entry->SetPageState(
-      content::PageState::CreateFromEncodedData(kEncodedPageState));
-  navigation_entry->SetTransitionType(kTransitionType);
-  navigation_entry->SetHasPostData(kHasPostData);
-  navigation_entry->SetPostID(kPostID);
-  navigation_entry->SetOriginalRequestURL(kOriginalRequestURL);
-  navigation_entry->SetIsOverridingUserAgent(kIsOverridingUserAgent);
-  navigation_entry->SetTimestamp(kTimestamp);
-  navigation_entry->SetExtraData(kSearchTermsKey, kSearchTerms);
-  navigation_entry->GetFavicon().valid = true;
-  navigation_entry->GetFavicon().url = kFaviconURL;
-  navigation_entry->SetHttpStatusCode(kHttpStatusCode);
-  std::vector<GURL> redirect_chain;
-  redirect_chain.push_back(kRedirectURL0);
-  redirect_chain.push_back(kRedirectURL1);
-  redirect_chain.push_back(kVirtualURL);
-  navigation_entry->SetRedirectChain(redirect_chain);
-  return navigation_entry.Pass();
-}
-
 // Create a sync_pb::TabNavigation from the constants above.
 sync_pb::TabNavigation MakeSyncDataForTest() {
   sync_pb::TabNavigation sync_data;
-  sync_data.set_virtual_url(kVirtualURL.spec());
-  sync_data.set_referrer(kReferrerURL.spec());
-  sync_data.set_referrer_policy(blink::WebReferrerPolicyOrigin);
-  sync_data.set_title(base::UTF16ToUTF8(kTitle));
-  sync_data.set_state(kEncodedPageState);
+  sync_data.set_virtual_url(test_data::kVirtualURL.spec());
+  sync_data.set_referrer(test_data::kReferrerURL.spec());
+  sync_data.set_referrer_policy(test_data::kReferrerPolicy);
+  sync_data.set_title(base::UTF16ToUTF8(test_data::kTitle));
+  sync_data.set_state(test_data::kEncodedPageState);
   sync_data.set_page_transition(
       sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME);
-  sync_data.set_unique_id(kUniqueID);
-  sync_data.set_timestamp_msec(syncer::TimeToProtoTime(kTimestamp));
+  sync_data.set_unique_id(test_data::kUniqueID);
+  sync_data.set_timestamp_msec(syncer::TimeToProtoTime(test_data::kTimestamp));
   sync_data.set_redirect_type(sync_pb::SyncEnums::CLIENT_REDIRECT);
   sync_data.set_navigation_home_page(true);
-  sync_data.set_search_terms(base::UTF16ToUTF8(kSearchTerms));
-  sync_data.set_favicon_url(kFaviconURL.spec());
-  sync_data.set_http_status_code(kHttpStatusCode);
+  sync_data.set_search_terms(base::UTF16ToUTF8(test_data::kSearchTerms));
+  sync_data.set_favicon_url(test_data::kFaviconURL.spec());
+  sync_data.set_http_status_code(test_data::kHttpStatusCode);
   // The redirect chain only syncs one way.
   return sync_data;
 }
@@ -111,7 +53,9 @@
   EXPECT_EQ(-1, navigation.index());
   EXPECT_EQ(0, navigation.unique_id());
   EXPECT_EQ(GURL(), navigation.referrer_url());
-  EXPECT_EQ(blink::WebReferrerPolicyDefault, navigation.referrer_policy());
+  EXPECT_EQ(
+      SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy(),
+      navigation.referrer_policy());
   EXPECT_EQ(GURL(), navigation.virtual_url());
   EXPECT_TRUE(navigation.title().empty());
   EXPECT_EQ(std::string(), navigation.encoded_page_state());
@@ -127,37 +71,6 @@
   EXPECT_EQ(0U, navigation.redirect_chain().size());
 }
 
-// Create a SerializedNavigationEntry from a NavigationEntry.  All its fields
-// should match the NavigationEntry's.
-TEST(SerializedNavigationEntryTest, FromNavigationEntry) {
-  const scoped_ptr<content::NavigationEntry> navigation_entry(
-      MakeNavigationEntryForTest());
-
-  const SerializedNavigationEntry& navigation =
-      SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry);
-
-  EXPECT_EQ(kIndex, navigation.index());
-
-  EXPECT_EQ(navigation_entry->GetUniqueID(), navigation.unique_id());
-  EXPECT_EQ(kReferrerURL, navigation.referrer_url());
-  EXPECT_EQ(kReferrerPolicy, navigation.referrer_policy());
-  EXPECT_EQ(kVirtualURL, navigation.virtual_url());
-  EXPECT_EQ(kTitle, navigation.title());
-  EXPECT_EQ(kEncodedPageState, navigation.encoded_page_state());
-  EXPECT_EQ(kTransitionType, navigation.transition_type());
-  EXPECT_EQ(kHasPostData, navigation.has_post_data());
-  EXPECT_EQ(kPostID, navigation.post_id());
-  EXPECT_EQ(kOriginalRequestURL, navigation.original_request_url());
-  EXPECT_EQ(kIsOverridingUserAgent, navigation.is_overriding_user_agent());
-  EXPECT_EQ(kTimestamp, navigation.timestamp());
-  EXPECT_EQ(kFaviconURL, navigation.favicon_url());
-  EXPECT_EQ(kHttpStatusCode, navigation.http_status_code());
-  ASSERT_EQ(3U, navigation.redirect_chain().size());
-  EXPECT_EQ(kRedirectURL0, navigation.redirect_chain()[0]);
-  EXPECT_EQ(kRedirectURL1, navigation.redirect_chain()[1]);
-  EXPECT_EQ(kVirtualURL, navigation.redirect_chain()[2]);
-}
-
 // Create a SerializedNavigationEntry from a sync_pb::TabNavigation.  All its
 // fields should match the protocol buffer's if it exists there, and
 // sbould be set to the default value otherwise.
@@ -165,24 +78,24 @@
   const sync_pb::TabNavigation sync_data = MakeSyncDataForTest();
 
   const SerializedNavigationEntry& navigation =
-      SerializedNavigationEntry::FromSyncData(kIndex, sync_data);
+      SerializedNavigationEntry::FromSyncData(test_data::kIndex, sync_data);
 
-  EXPECT_EQ(kIndex, navigation.index());
-  EXPECT_EQ(kUniqueID, navigation.unique_id());
-  EXPECT_EQ(kReferrerURL, navigation.referrer_url());
-  EXPECT_EQ(blink::WebReferrerPolicyOrigin, navigation.referrer_policy());
-  EXPECT_EQ(kVirtualURL, navigation.virtual_url());
-  EXPECT_EQ(kTitle, navigation.title());
-  EXPECT_EQ(kEncodedPageState, navigation.encoded_page_state());
-  EXPECT_EQ(kTransitionType, navigation.transition_type());
+  EXPECT_EQ(test_data::kIndex, navigation.index());
+  EXPECT_EQ(test_data::kUniqueID, navigation.unique_id());
+  EXPECT_EQ(test_data::kReferrerURL, navigation.referrer_url());
+  EXPECT_EQ(test_data::kReferrerPolicy, navigation.referrer_policy());
+  EXPECT_EQ(test_data::kVirtualURL, navigation.virtual_url());
+  EXPECT_EQ(test_data::kTitle, navigation.title());
+  EXPECT_EQ(test_data::kEncodedPageState, navigation.encoded_page_state());
+  EXPECT_EQ(test_data::kTransitionType, navigation.transition_type());
   EXPECT_FALSE(navigation.has_post_data());
   EXPECT_EQ(-1, navigation.post_id());
   EXPECT_EQ(GURL(), navigation.original_request_url());
   EXPECT_FALSE(navigation.is_overriding_user_agent());
   EXPECT_TRUE(navigation.timestamp().is_null());
-  EXPECT_EQ(kSearchTerms, navigation.search_terms());
-  EXPECT_EQ(kFaviconURL, navigation.favicon_url());
-  EXPECT_EQ(kHttpStatusCode, navigation.http_status_code());
+  EXPECT_EQ(test_data::kSearchTerms, navigation.search_terms());
+  EXPECT_EQ(test_data::kFaviconURL, navigation.favicon_url());
+  EXPECT_EQ(test_data::kHttpStatusCode, navigation.http_status_code());
   // The redirect chain only syncs one way.
 }
 
@@ -190,9 +103,8 @@
 // unpickling.  The new one should match the old one except for fields
 // that aren't pickled, which should be set to default values.
 TEST(SerializedNavigationEntryTest, Pickle) {
-  const SerializedNavigationEntry& old_navigation =
-      SerializedNavigationEntry::FromNavigationEntry(
-          kIndex, *MakeNavigationEntryForTest());
+  const SerializedNavigationEntry old_navigation =
+      SerializedNavigationEntryTestHelper::CreateNavigationForTest();
 
   Pickle pickle;
   old_navigation.WriteToPickle(30000, &pickle);
@@ -201,131 +113,89 @@
   PickleIterator pickle_iterator(pickle);
   EXPECT_TRUE(new_navigation.ReadFromPickle(&pickle_iterator));
 
-  EXPECT_EQ(kIndex, new_navigation.index());
+  // Fields that are written to the pickle.
+  EXPECT_EQ(test_data::kIndex, new_navigation.index());
+  EXPECT_EQ(test_data::kReferrerURL, new_navigation.referrer_url());
+  EXPECT_EQ(test_data::kReferrerPolicy, new_navigation.referrer_policy());
+  EXPECT_EQ(test_data::kVirtualURL, new_navigation.virtual_url());
+  EXPECT_EQ(test_data::kTitle, new_navigation.title());
+  EXPECT_EQ(test_data::kTransitionType, new_navigation.transition_type());
+  EXPECT_EQ(test_data::kHasPostData, new_navigation.has_post_data());
+  EXPECT_EQ(test_data::kOriginalRequestURL,
+            new_navigation.original_request_url());
+  EXPECT_EQ(test_data::kIsOverridingUserAgent,
+            new_navigation.is_overriding_user_agent());
+  EXPECT_EQ(test_data::kTimestamp, new_navigation.timestamp());
+  EXPECT_EQ(test_data::kSearchTerms, new_navigation.search_terms());
+  EXPECT_EQ(test_data::kHttpStatusCode, new_navigation.http_status_code());
 
+  // Fields that are not written to the pickle.
   EXPECT_EQ(0, new_navigation.unique_id());
-  EXPECT_EQ(kReferrerURL, new_navigation.referrer_url());
-  EXPECT_EQ(kReferrerPolicy, new_navigation.referrer_policy());
-  EXPECT_EQ(kVirtualURL, new_navigation.virtual_url());
-  EXPECT_EQ(kTitle, new_navigation.title());
   EXPECT_EQ(std::string(), new_navigation.encoded_page_state());
-  EXPECT_EQ(kTransitionType, new_navigation.transition_type());
-  EXPECT_EQ(kHasPostData, new_navigation.has_post_data());
   EXPECT_EQ(-1, new_navigation.post_id());
-  EXPECT_EQ(kOriginalRequestURL, new_navigation.original_request_url());
-  EXPECT_EQ(kIsOverridingUserAgent, new_navigation.is_overriding_user_agent());
-  EXPECT_EQ(kTimestamp, new_navigation.timestamp());
-  EXPECT_EQ(kSearchTerms, new_navigation.search_terms());
-  EXPECT_EQ(kHttpStatusCode, new_navigation.http_status_code());
   EXPECT_EQ(0U, new_navigation.redirect_chain().size());
 }
 
-// Create a NavigationEntry, then create another one by converting to
-// a SerializedNavigationEntry and back.  The new one should match the old one
-// except for fields that aren't preserved, which should be set to
-// expected values.
-TEST(SerializedNavigationEntryTest, ToNavigationEntry) {
-  const scoped_ptr<content::NavigationEntry> old_navigation_entry(
-      MakeNavigationEntryForTest());
-
-  const SerializedNavigationEntry& navigation =
-      SerializedNavigationEntry::FromNavigationEntry(kIndex,
-                                                     *old_navigation_entry);
-
-  const scoped_ptr<content::NavigationEntry> new_navigation_entry(
-      navigation.ToNavigationEntry(kPageID, NULL));
-
-  EXPECT_EQ(kReferrerURL, new_navigation_entry->GetReferrer().url);
-  EXPECT_EQ(kReferrerPolicy, new_navigation_entry->GetReferrer().policy);
-  EXPECT_EQ(kVirtualURL, new_navigation_entry->GetVirtualURL());
-  EXPECT_EQ(kTitle, new_navigation_entry->GetTitle());
-  EXPECT_EQ(kEncodedPageState,
-            new_navigation_entry->GetPageState().ToEncodedData());
-  EXPECT_EQ(kPageID, new_navigation_entry->GetPageID());
-  EXPECT_EQ(ui::PAGE_TRANSITION_RELOAD,
-            new_navigation_entry->GetTransitionType());
-  EXPECT_EQ(kHasPostData, new_navigation_entry->GetHasPostData());
-  EXPECT_EQ(kPostID, new_navigation_entry->GetPostID());
-  EXPECT_EQ(kOriginalRequestURL,
-            new_navigation_entry->GetOriginalRequestURL());
-  EXPECT_EQ(kIsOverridingUserAgent,
-            new_navigation_entry->GetIsOverridingUserAgent());
-  base::string16 search_terms;
-  new_navigation_entry->GetExtraData(kSearchTermsKey, &search_terms);
-  EXPECT_EQ(kSearchTerms, search_terms);
-  EXPECT_EQ(kHttpStatusCode, new_navigation_entry->GetHttpStatusCode());
-  ASSERT_EQ(3U, new_navigation_entry->GetRedirectChain().size());
-  EXPECT_EQ(kRedirectURL0, new_navigation_entry->GetRedirectChain()[0]);
-  EXPECT_EQ(kRedirectURL1, new_navigation_entry->GetRedirectChain()[1]);
-  EXPECT_EQ(kVirtualURL, new_navigation_entry->GetRedirectChain()[2]);
-}
-
-// Create a NavigationEntry, convert it to a SerializedNavigationEntry, then
-// create a sync protocol buffer from it.  The protocol buffer should
-// have matching fields to the NavigationEntry (when applicable).
+// Create a SerializedNavigationEntry, then create a sync protocol buffer from
+// it.  The protocol buffer should have matching fields to the
+// SerializedNavigationEntry (when applicable).
 TEST(SerializedNavigationEntryTest, ToSyncData) {
-  const scoped_ptr<content::NavigationEntry> navigation_entry(
-      MakeNavigationEntryForTest());
-
-  const SerializedNavigationEntry& navigation =
-      SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry);
-
+  const SerializedNavigationEntry navigation =
+      SerializedNavigationEntryTestHelper::CreateNavigationForTest();
   const sync_pb::TabNavigation sync_data = navigation.ToSyncData();
 
-  EXPECT_EQ(kVirtualURL.spec(), sync_data.virtual_url());
-  EXPECT_EQ(kReferrerURL.spec(), sync_data.referrer());
-  EXPECT_EQ(kTitle, base::ASCIIToUTF16(sync_data.title()));
+  EXPECT_EQ(test_data::kVirtualURL.spec(), sync_data.virtual_url());
+  EXPECT_EQ(test_data::kReferrerURL.spec(), sync_data.referrer());
+  EXPECT_EQ(test_data::kTitle, base::ASCIIToUTF16(sync_data.title()));
   EXPECT_TRUE(sync_data.state().empty());
   EXPECT_EQ(sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME,
             sync_data.page_transition());
   EXPECT_TRUE(sync_data.has_redirect_type());
-  EXPECT_EQ(navigation_entry->GetUniqueID(), sync_data.unique_id());
-  EXPECT_EQ(syncer::TimeToProtoTime(kTimestamp), sync_data.timestamp_msec());
-  EXPECT_EQ(kTimestamp.ToInternalValue(), sync_data.global_id());
-  EXPECT_EQ(kFaviconURL.spec(), sync_data.favicon_url());
-  EXPECT_EQ(kHttpStatusCode, sync_data.http_status_code());
+  EXPECT_EQ(test_data::kUniqueID, sync_data.unique_id());
+  EXPECT_EQ(syncer::TimeToProtoTime(test_data::kTimestamp),
+            sync_data.timestamp_msec());
+  EXPECT_EQ(test_data::kTimestamp.ToInternalValue(), sync_data.global_id());
+  EXPECT_EQ(test_data::kFaviconURL.spec(), sync_data.favicon_url());
+  EXPECT_EQ(test_data::kHttpStatusCode, sync_data.http_status_code());
   // The proto navigation redirects don't include the final chain entry
   // (because it didn't redirect) so the lengths should differ by 1.
   ASSERT_EQ(3, sync_data.navigation_redirect_size() + 1);
-  EXPECT_EQ(navigation_entry->GetRedirectChain()[0].spec(),
+  EXPECT_EQ(test_data::kRedirectURL0.spec(),
             sync_data.navigation_redirect(0).url());
-  EXPECT_EQ(navigation_entry->GetRedirectChain()[1].spec(),
+  EXPECT_EQ(test_data::kRedirectURL1.spec(),
             sync_data.navigation_redirect(1).url());
   EXPECT_FALSE(sync_data.has_last_navigation_redirect_url());
 }
 
-// Test that the last_navigation_redirect_url is set when needed.
-// This test is just like the above, but with a different virtual_url.
-// Create a NavigationEntry, convert it to a SerializedNavigationEntry, then
-// create a sync protocol buffer from it.  The protocol buffer should
-// have a last_navigation_redirect_url.
+// Test that the last_navigation_redirect_url is set when needed.  This test is
+// just like the above, but with a different virtual_url.  Create a
+// SerializedNavigationEntry, then create a sync protocol buffer from it.  The
+// protocol buffer should have a last_navigation_redirect_url.
 TEST(SerializedNavigationEntryTest, LastNavigationRedirectUrl) {
-  const scoped_ptr<content::NavigationEntry> navigation_entry(
-      MakeNavigationEntryForTest());
-
-  navigation_entry->SetVirtualURL(kOtherURL);
-
-  const SerializedNavigationEntry& navigation =
-      SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry);
+  SerializedNavigationEntry navigation =
+      SerializedNavigationEntryTestHelper::CreateNavigationForTest();
+  SerializedNavigationEntryTestHelper::SetVirtualURL(
+      test_data::kOtherURL, &navigation);
 
   const sync_pb::TabNavigation sync_data = navigation.ToSyncData();
-
   EXPECT_TRUE(sync_data.has_last_navigation_redirect_url());
-  EXPECT_EQ(kVirtualURL.spec(), sync_data.last_navigation_redirect_url());
+  EXPECT_EQ(test_data::kVirtualURL.spec(),
+            sync_data.last_navigation_redirect_url());
 
   // The redirect chain should be the same as in the above test.
   ASSERT_EQ(3, sync_data.navigation_redirect_size() + 1);
-  EXPECT_EQ(navigation_entry->GetRedirectChain()[0].spec(),
+  EXPECT_EQ(test_data::kRedirectURL0.spec(),
             sync_data.navigation_redirect(0).url());
-  EXPECT_EQ(navigation_entry->GetRedirectChain()[1].spec(),
+  EXPECT_EQ(test_data::kRedirectURL1.spec(),
             sync_data.navigation_redirect(1).url());
 }
 
 // Ensure all transition types and qualifiers are converted to/from the sync
 // SerializedNavigationEntry representation properly.
 TEST(SerializedNavigationEntryTest, TransitionTypes) {
-  scoped_ptr<content::NavigationEntry> navigation_entry(
-      MakeNavigationEntryForTest());
+  SerializedNavigationEntry navigation =
+      SerializedNavigationEntryTestHelper::CreateNavigationForTest();
+
   for (uint32 core_type = ui::PAGE_TRANSITION_LINK;
        core_type != ui::PAGE_TRANSITION_LAST_CORE; ++core_type) {
     // Because qualifier is a uint32, left shifting will eventually overflow
@@ -338,14 +208,12 @@
         continue;  // 0x08000000 is not a valid qualifier.
       ui::PageTransition transition =
           ui::PageTransitionFromInt(core_type | qualifier);
+      SerializedNavigationEntryTestHelper::SetTransitionType(
+          transition, &navigation);
 
-      navigation_entry->SetTransitionType(transition);
-      const SerializedNavigationEntry& navigation =
-          SerializedNavigationEntry::FromNavigationEntry(kIndex,
-                                                         *navigation_entry);
       const sync_pb::TabNavigation& sync_data = navigation.ToSyncData();
       const SerializedNavigationEntry& constructed_nav =
-          SerializedNavigationEntry::FromSyncData(kIndex, sync_data);
+          SerializedNavigationEntry::FromSyncData(test_data::kIndex, sync_data);
       const ui::PageTransition constructed_transition =
           constructed_nav.transition_type();
 
@@ -354,39 +222,5 @@
   }
 }
 
-// Tests that the input data is sanitized when a SerializedNavigationEntry
-// is created from a pickle format.
-TEST(SerializedNavigationEntryTest, Sanitize) {
-  sync_pb::TabNavigation sync_data = MakeSyncDataForTest();
-
-  sync_data.set_referrer_policy(blink::WebReferrerPolicyNever);
-  content::PageState page_state =
-      content::PageState::CreateFromURL(kVirtualURL);
-  sync_data.set_state(page_state.ToEncodedData());
-
-  const SerializedNavigationEntry& navigation =
-      SerializedNavigationEntry::FromSyncData(kIndex, sync_data);
-
-  EXPECT_EQ(kIndex, navigation.index());
-  EXPECT_EQ(kUniqueID, navigation.unique_id());
-  EXPECT_EQ(GURL(), navigation.referrer_url());
-  EXPECT_EQ(blink::WebReferrerPolicyDefault, navigation.referrer_policy());
-  EXPECT_EQ(kVirtualURL, navigation.virtual_url());
-  EXPECT_EQ(kTitle, navigation.title());
-  EXPECT_EQ(page_state.ToEncodedData(), navigation.encoded_page_state());
-  EXPECT_EQ(kTransitionType, navigation.transition_type());
-  EXPECT_FALSE(navigation.has_post_data());
-  EXPECT_EQ(-1, navigation.post_id());
-  EXPECT_EQ(GURL(), navigation.original_request_url());
-  EXPECT_FALSE(navigation.is_overriding_user_agent());
-  EXPECT_TRUE(navigation.timestamp().is_null());
-  EXPECT_EQ(kSearchTerms, navigation.search_terms());
-  EXPECT_EQ(kFaviconURL, navigation.favicon_url());
-  EXPECT_EQ(kHttpStatusCode, navigation.http_status_code());
-
-  content::PageState empty_state;
-  EXPECT_TRUE(empty_state.Equals(empty_state.RemoveReferrer()));
-}
-
 }  // namespace
 }  // namespace sessions
diff --git a/components/sessions/sessions_export.h b/components/sessions/sessions_export.h
index 66ac822..f307101 100644
--- a/components/sessions/sessions_export.h
+++ b/components/sessions/sessions_export.h
@@ -10,20 +10,25 @@
 
 #if defined(SESSIONS_IMPLEMENTATION)
 #define SESSIONS_EXPORT __declspec(dllexport)
+#define SESSIONS_EXPORT_PRIVATE __declspec(dllexport)
 #else
 #define SESSIONS_EXPORT __declspec(dllimport)
-#endif  // defined(BASE_PREFS_IMPLEMENTATION)
+#define SESSIONS_EXPORT_PRIVATE __declspec(dllimport)
+#endif  // defined(SESSIONS_IMPLEMENTATION)
 
 #else  // defined(WIN32)
 #if defined(SESSIONS_IMPLEMENTATION)
 #define SESSIONS_EXPORT __attribute__((visibility("default")))
+#define SESSIONS_EXPORT_PRIVATE __attribute__((visibility("default")))
 #else
 #define SESSIONS_EXPORT
+#define SESSIONS_EXPORT_PRIVATE
 #endif
 #endif
 
 #else  // defined(COMPONENT_BUILD)
 #define SESSIONS_EXPORT
+#define SESSIONS_EXPORT_PRIVATE
 #endif
 
 #endif  // COMPONENTS_SESSIONS_SESSIONS_EXPORT_H_
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc
index 74b664c..982e0e2 100644
--- a/components/signin/core/browser/about_signin_internals.cc
+++ b/components/signin/core/browser/about_signin_internals.cc
@@ -443,6 +443,8 @@
   AddSectionEntry(basic_info, "Signin Status", signin_status_string);
   AddSectionEntry(basic_info, "Web Based Signin Enabled?",
       switches::IsEnableWebBasedSignin() == true ? "True" : "False");
+  AddSectionEntry(basic_info, "Webview Based Signin Enabled?",
+      switches::IsEnableWebviewBasedSignin() == true ? "True" : "False");
   AddSectionEntry(basic_info, "New Avatar Menu Enabled?",
       switches::IsNewAvatarMenu() == true ? "True" : "False");
   AddSectionEntry(basic_info, "New Profile Management Enabled?",
diff --git a/components/signin/core/browser/account_tracker_service.cc b/components/signin/core/browser/account_tracker_service.cc
index 714c452..0b13386d 100644
--- a/components/signin/core/browser/account_tracker_service.cc
+++ b/components/signin/core/browser/account_tracker_service.cc
@@ -5,6 +5,7 @@
 #include "components/signin/core/browser/account_tracker_service.h"
 
 #include "base/debug/trace_event.h"
+#include "base/logging.h"
 #include "base/prefs/pref_service.h"
 #include "base/prefs/scoped_user_pref_update.h"
 #include "base/profiler/scoped_profile.h"
@@ -448,3 +449,42 @@
     OnRefreshTokenAvailable(*it);
   }
 }
+
+std::string AccountTrackerService::PickAccountIdForAccount(
+    const std::string& gaia,
+    const std::string& email) {
+  return PickAccountIdForAccount(pref_service_, gaia, email);
+}
+
+// static
+std::string AccountTrackerService::PickAccountIdForAccount(
+    PrefService* pref_service,
+    const std::string& gaia,
+    const std::string& email) {
+  DCHECK(!gaia.empty());
+  DCHECK(!email.empty());
+  switch(GetMigrationState(pref_service)) {
+    case MIGRATION_NOT_STARTED:
+    case MIGRATION_IN_PROGRESS:
+      return gaia::CanonicalizeEmail(gaia::SanitizeEmail(email));
+    case MIGRATION_DONE:
+      return gaia;
+    default:
+      NOTREACHED();
+      return email;
+  }
+}
+
+void AccountTrackerService::SeedAccountInfo(const std::string& gaia,
+                                            const std::string& email) {
+  DCHECK(!gaia.empty());
+  DCHECK(!email.empty());
+  const std::string account_id = PickAccountIdForAccount(gaia, email);
+  const bool already_exists = ContainsKey(accounts_, account_id);
+  StartTrackingAccount(account_id);
+  AccountState& state = accounts_[account_id];
+  DCHECK(!already_exists || state.info.gaia == gaia);
+  state.info.gaia = gaia;
+  state.info.email = email;
+  SaveToPrefs(state);
+}
diff --git a/components/signin/core/browser/account_tracker_service.h b/components/signin/core/browser/account_tracker_service.h
index a6f403e..c65ed010 100644
--- a/components/signin/core/browser/account_tracker_service.h
+++ b/components/signin/core/browser/account_tracker_service.h
@@ -79,6 +79,18 @@
   // there are still unfininshed fetchers.
   virtual bool IsAllUserInfoFetched() const;
 
+  // Picks the correct account_id for the specified account depending on the
+  // migration state.
+  std::string PickAccountIdForAccount(const std::string& gaia,
+                                      const std::string& email);
+  static std::string PickAccountIdForAccount(PrefService* pref_service,
+                                             const std::string& gaia,
+                                             const std::string& email);
+
+  // Seeds the account whose account_id is given by PickAccountIdForAccount()
+  // with its corresponding gaia id and email address.
+  void SeedAccountInfo(const std::string& gaia, const std::string& email);
+
   AccountIdMigrationState GetMigrationState();
   static AccountIdMigrationState GetMigrationState(PrefService* pref_service);
 
diff --git a/components/signin/core/browser/account_tracker_service_unittest.cc b/components/signin/core/browser/account_tracker_service_unittest.cc
index 64b83b0d..7a4d327 100644
--- a/components/signin/core/browser/account_tracker_service_unittest.cc
+++ b/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/prefs/testing_pref_service.h"
 #include "base/strings/stringprintf.h"
 #include "components/signin/core/browser/account_tracker_service.h"
+#include "components/signin/core/common/signin_pref_names.h"
 #include "google_apis/gaia/fake_oauth2_token_service.h"
 #include "google_apis/gaia/gaia_oauth_client.h"
 #include "net/http/http_status_code.h"
@@ -198,6 +199,9 @@
 
     pref_service_.registry()->RegisterListPref(
         AccountTrackerService::kAccountInfoPref);
+    pref_service_.registry()->RegisterIntegerPref(
+        prefs::kAccountIdMigrationState,
+        AccountTrackerService::MIGRATION_NOT_STARTED);
 
     account_tracker_.reset(new AccountTrackerService());
     account_tracker_->Initialize(fake_oauth2_token_service_.get(),
@@ -505,3 +509,21 @@
     tracker.Shutdown();
   }
 }
+
+TEST_F(AccountTrackerServiceTest, SeedAccountInfo) {
+  std::vector<AccountTrackerService::AccountInfo> infos =
+      account_tracker()->GetAccounts();
+  EXPECT_EQ(0u, infos.size());
+
+  const std::string gaia_id = AccountIdToGaiaId("alpha");
+  const std::string email = AccountIdToEmail("alpha");
+  const std::string account_id =
+      account_tracker()->PickAccountIdForAccount(gaia_id, email);
+  account_tracker()->SeedAccountInfo(gaia_id, email);
+
+  infos = account_tracker()->GetAccounts();
+  EXPECT_EQ(1u, infos.size());
+  EXPECT_EQ(account_id, infos[0].account_id);
+  EXPECT_EQ(gaia_id, infos[0].gaia);
+  EXPECT_EQ(email, infos[0].email);
+}
diff --git a/components/signin/core/common/profile_management_switches.cc b/components/signin/core/common/profile_management_switches.cc
index 2785cf4e..f1a720330 100644
--- a/components/signin/core/common/profile_management_switches.cc
+++ b/components/signin/core/common/profile_management_switches.cc
@@ -126,7 +126,13 @@
 
 bool IsEnableWebBasedSignin() {
   return CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kEnableWebBasedSignin) && !IsNewProfileManagement();
+      switches::kEnableWebBasedSignin) && !IsNewProfileManagement() &&
+      !IsEnableWebviewBasedSignin();
+}
+
+bool IsEnableWebviewBasedSignin() {
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableWebviewBasedSignin);
 }
 
 bool IsExtensionsMultiAccount() {
diff --git a/components/signin/core/common/profile_management_switches.h b/components/signin/core/common/profile_management_switches.h
index 1304295..63557d6 100644
--- a/components/signin/core/common/profile_management_switches.h
+++ b/components/signin/core/common/profile_management_switches.h
@@ -19,9 +19,12 @@
 // management UI is available in the avatar bubble.
 bool IsEnableAccountConsistency();
 
-// Enables the web-based sign in flow on Chrome desktop.
+// Checks whether the web-based sign in flow is enabled on Chrome desktop.
 bool IsEnableWebBasedSignin();
 
+// Checks whether the webview-based sign in flow is enabled on Chrome desktop.
+bool IsEnableWebviewBasedSignin();
+
 // Whether the chrome.identity API should be multi-account.
 bool IsExtensionsMultiAccount();
 
diff --git a/components/signin/core/common/signin_switches.cc b/components/signin/core/common/signin_switches.cc
index aa9bab1a..c6e914e 100644
--- a/components/signin/core/common/signin_switches.cc
+++ b/components/signin/core/common/signin_switches.cc
@@ -35,6 +35,9 @@
 // settings page.
 const char kEnableWebBasedSignin[] = "enable-web-based-signin";
 
+// Enables the webview-based flow for sign in.
+const char kEnableWebviewBasedSignin[] = "enable-webview-based-signin";
+
 // Enables multiple account versions of chrome.identity APIs.
 const char kExtensionsMultiAccount[] = "extensions-multi-account";
 
diff --git a/components/signin/core/common/signin_switches.h b/components/signin/core/common/signin_switches.h
index 3d39438..84aa1d65 100644
--- a/components/signin/core/common/signin_switches.h
+++ b/components/signin/core/common/signin_switches.h
@@ -22,6 +22,7 @@
 extern const char kEnableNewAvatarMenu[];
 extern const char kEnableNewProfileManagement[];
 extern const char kEnableWebBasedSignin[];
+extern const char kEnableWebviewBasedSignin[];
 extern const char kExtensionsMultiAccount[];
 extern const char kFastUserSwitching[];
 extern const char kGoogleProfileInfo[];
diff --git a/components/storage_monitor/storage_monitor_linux.cc b/components/storage_monitor/storage_monitor_linux.cc
index 254fd5d..6b57f5cd 100644
--- a/components/storage_monitor/storage_monitor_linux.cc
+++ b/components/storage_monitor/storage_monitor_linux.cc
@@ -26,7 +26,7 @@
 #include "components/storage_monitor/storage_info.h"
 #include "components/storage_monitor/udev_util_linux.h"
 #include "device/media_transfer_protocol/media_transfer_protocol_manager.h"
-#include "device/udev_linux/udev.h"
+#include "device/udev_linux/scoped_udev.h"
 
 using content::BrowserThread;
 
diff --git a/components/storage_monitor/udev_util_linux.cc b/components/storage_monitor/udev_util_linux.cc
index 5a3a117..154f11c 100644
--- a/components/storage_monitor/udev_util_linux.cc
+++ b/components/storage_monitor/udev_util_linux.cc
@@ -5,11 +5,11 @@
 #include "components/storage_monitor/udev_util_linux.h"
 
 #include "base/files/file_path.h"
-#include "device/udev_linux/udev.h"
+#include "device/udev_linux/scoped_udev.h"
 
 namespace storage_monitor {
 
-std::string GetUdevDevicePropertyValue(struct udev_device* udev_device,
+std::string GetUdevDevicePropertyValue(udev_device* udev_device,
                                        const char* key) {
   const char* value = udev_device_get_property_value(udev_device, key);
   return value ? value : std::string();
diff --git a/components/storage_monitor/udev_util_linux.h b/components/storage_monitor/udev_util_linux.h
index f00048b..76b59ad 100644
--- a/components/storage_monitor/udev_util_linux.h
+++ b/components/storage_monitor/udev_util_linux.h
@@ -5,12 +5,12 @@
 #ifndef COMPONENTS_STORAGE_MONITOR_UDEV_UTIL_LINUX_H_
 #define COMPONENTS_STORAGE_MONITOR_UDEV_UTIL_LINUX_H_
 
-#include <libudev.h>
-
 #include <string>
 
 #include "base/memory/scoped_ptr.h"
 
+struct udev_device;
+
 namespace base {
 class FilePath;
 }
@@ -19,7 +19,7 @@
 
 // Wrapper function for udev_device_get_property_value() that also checks for
 // valid but empty values.
-std::string GetUdevDevicePropertyValue(struct udev_device* udev_device,
+std::string GetUdevDevicePropertyValue(udev_device* udev_device,
                                        const char* key);
 
 // Helper for udev_device_new_from_syspath()/udev_device_get_property_value()
diff --git a/components/suggestions/BUILD.gn b/components/suggestions/BUILD.gn
index 2af25a3..e2bb9070 100644
--- a/components/suggestions/BUILD.gn
+++ b/components/suggestions/BUILD.gn
@@ -27,6 +27,7 @@
     "//components/pref_registry",
     "//components/suggestions/proto",
     "//components/variations",
+    "//components/variations/net",
     "//net",
     "//ui/gfx",
     "//url",
diff --git a/components/suggestions/suggestions_service.cc b/components/suggestions/suggestions_service.cc
index e7b0397..ce7eabd3 100644
--- a/components/suggestions/suggestions_service.cc
+++ b/components/suggestions/suggestions_service.cc
@@ -17,8 +17,8 @@
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/suggestions/blacklist_store.h"
 #include "components/suggestions/suggestions_store.h"
+#include "components/variations/net/variations_http_header_provider.h"
 #include "components/variations/variations_associated_data.h"
-#include "components/variations/variations_http_header_provider.h"
 #include "net/base/escape.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
diff --git a/components/sync_driver/device_info_data_type_controller.cc b/components/sync_driver/device_info_data_type_controller.cc
index 592633d..f1e7499b 100644
--- a/components/sync_driver/device_info_data_type_controller.cc
+++ b/components/sync_driver/device_info_data_type_controller.cc
@@ -37,6 +37,10 @@
   return false;
 }
 
+void DeviceInfoDataTypeController::StopModels() {
+  subscription_.reset();
+}
+
 void DeviceInfoDataTypeController::OnLocalDeviceInfoLoaded() {
   DCHECK_EQ(state_, MODEL_STARTING);
   DCHECK(local_device_info_provider_->GetLocalDeviceInfo());
diff --git a/components/sync_driver/device_info_data_type_controller.h b/components/sync_driver/device_info_data_type_controller.h
index fa6b8f1..d20d0374 100644
--- a/components/sync_driver/device_info_data_type_controller.h
+++ b/components/sync_driver/device_info_data_type_controller.h
@@ -25,6 +25,7 @@
 
   // UIDataTypeController implementations.
   bool StartModels() override;
+  void StopModels() override;
 
   // Called by LocalDeviceInfoProvider when the local device into becomes
   // available.
diff --git a/components/sync_driver/device_info_data_type_controller_unittest.cc b/components/sync_driver/device_info_data_type_controller_unittest.cc
index 137ed253..c6535cb 100644
--- a/components/sync_driver/device_info_data_type_controller_unittest.cc
+++ b/components/sync_driver/device_info_data_type_controller_unittest.cc
@@ -127,6 +127,19 @@
   EXPECT_TRUE(LoadResult());
 }
 
+// Tests that DeviceInfoDataTypeControllerTest handles the situation
+// when everything stops before the start gets a chance to finish.
+TEST_F(DeviceInfoDataTypeControllerTest, DestructionWithDelayedStart) {
+  local_device_->SetInitialized(false);
+  Start();
+
+  controller_->Stop();
+  // Destroy |local_device_| and |controller_| out of order
+  // to verify that the controller doesn't crash in the destructor.
+  local_device_.reset();
+  controller_ = NULL;
+}
+
 }  // namespace
 
 }  // namespace sync_driver
diff --git a/components/sync_driver/shared_change_processor.cc b/components/sync_driver/shared_change_processor.cc
index c1cf407..ce49430 100644
--- a/components/sync_driver/shared_change_processor.cc
+++ b/components/sync_driver/shared_change_processor.cc
@@ -24,21 +24,20 @@
 
 SharedChangeProcessor::~SharedChangeProcessor() {
   // We can either be deleted when the DTC is destroyed (on UI
-  // thread), or when the syncer::SyncableService stop's syncing (datatype
+  // thread), or when the syncer::SyncableService stops syncing (datatype
   // thread).  |generic_change_processor_|, if non-NULL, must be
   // deleted on |backend_loop_|.
-  if (frontend_loop_->BelongsToCurrentThread()) {
-    if (backend_loop_.get()) {
+  if (backend_loop_.get()) {
+    if (backend_loop_->BelongsToCurrentThread()) {
+      delete generic_change_processor_;
+    } else {
+      DCHECK(frontend_loop_->BelongsToCurrentThread());
       if (!backend_loop_->DeleteSoon(FROM_HERE, generic_change_processor_)) {
         NOTREACHED();
       }
-    } else {
-      DCHECK(!generic_change_processor_);
     }
   } else {
-    DCHECK(backend_loop_.get());
-    DCHECK(backend_loop_->BelongsToCurrentThread());
-    delete generic_change_processor_;
+    DCHECK(!generic_change_processor_);
   }
 }
 
diff --git a/components/translate/core/browser/translate_language_list.cc b/components/translate/core/browser/translate_language_list.cc
index 6a9b8c25..5db1a1c 100644
--- a/components/translate/core/browser/translate_language_list.cc
+++ b/components/translate/core/browser/translate_language_list.cc
@@ -256,12 +256,22 @@
 }
 
 void TranslateLanguageList::NotifyEvent(int line, const std::string& message) {
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/422577 is fixed.
+  tracked_objects::ScopedProfile tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422577 TranslateLanguageList::NotifyEvent"));
+
   TranslateEventDetails details(__FILE__, line, message);
   callback_list_.Notify(details);
 }
 
 void TranslateLanguageList::SetSupportedLanguages(
     const std::string& language_list) {
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/422577 is fixed.
+  tracked_objects::ScopedProfile tracking_profile1(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422577 TranslateLanguageList::SetSupportedLanguages 1"));
+
   // The format is:
   // sl({
   //   "sl": {"XX": "LanguageName", ...},
@@ -284,8 +294,20 @@
   std::string languages_json = language_list.substr(
       kLanguageListCallbackNameLength,
       language_list.size() - kLanguageListCallbackNameLength - 1);
+
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/422577 is fixed.
+  tracked_objects::ScopedProfile tracking_profile2(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422577 TranslateLanguageList::SetSupportedLanguages 2"));
+
   scoped_ptr<base::Value> json_value(
       base::JSONReader::Read(languages_json, base::JSON_ALLOW_TRAILING_COMMAS));
+
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/422577 is fixed.
+  tracked_objects::ScopedProfile tracking_profile3(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "422577 TranslateLanguageList::SetSupportedLanguages 3"));
+
   if (json_value == NULL || !json_value->IsType(base::Value::TYPE_DICTIONARY)) {
     NOTREACHED();
     return;
diff --git a/components/url_matcher/url_matcher.cc b/components/url_matcher/url_matcher.cc
index 13a4896e..3798f7eb 100644
--- a/components/url_matcher/url_matcher.cc
+++ b/components/url_matcher/url_matcher.cc
@@ -8,7 +8,6 @@
 #include <iterator>
 
 #include "base/logging.h"
-#include "base/profiler/scoped_profile.h"
 #include "url/gurl.h"
 #include "url/url_canon.h"
 
@@ -1082,10 +1081,6 @@
 }
 
 void URLMatcher::UpdateInternalDatastructures() {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "URLMatcher_UpdateInternalDatastructures"));
   UpdateSubstringSetMatcher(false);
   UpdateSubstringSetMatcher(true);
   UpdateRegexSetMatcher();
diff --git a/components/variations.gypi b/components/variations.gypi
index a3fc300c..ee3a4129 100644
--- a/components/variations.gypi
+++ b/components/variations.gypi
@@ -62,7 +62,7 @@
       ],
     },
     {
-      # GN version: //components/variations_http_provider
+      # GN version: //components/variations/net/variations_http_provider
       'target_name': 'variations_http_provider',
       'type': 'static_library',
       'include_dirs': [
@@ -74,8 +74,8 @@
         'variations',
       ],
       'sources': [
-        'variations/variations_http_header_provider.cc',
-        'variations/variations_http_header_provider.h',
+        'variations/net/variations_http_header_provider.cc',
+        'variations/net/variations_http_header_provider.h',
       ],
     },
   ],
diff --git a/components/variations/BUILD.gn b/components/variations/BUILD.gn
index 07b17e7..5bf88ee 100644
--- a/components/variations/BUILD.gn
+++ b/components/variations/BUILD.gn
@@ -6,7 +6,7 @@
   import("//build/config/android/rules.gni")
 }
 
-static_library("variations") {
+source_set("variations") {
   sources = [
     "active_field_trials.cc",
     "active_field_trials.h",
@@ -32,8 +32,6 @@
     "study_filtering.h",
     "variations_associated_data.cc",
     "variations_associated_data.h",
-    "variations_http_header_provider.cc",
-    "variations_http_header_provider.h",
     "variations_seed_processor.cc",
     "variations_seed_processor.h",
     "variations_seed_simulator.cc",
@@ -41,8 +39,8 @@
   ]
 
   deps = [
+    "proto",
     "//base",
-    "//components/variations/proto",
     "//third_party/mt19937ar",
   ]
 
@@ -60,3 +58,26 @@
     jni_package = "variations"
   }
 }
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [
+    "active_field_trials_unittest.cc",
+    "caching_permuted_entropy_provider_unittest.cc",
+    "entropy_provider_unittest.cc",
+    "metrics_util_unittest.cc",
+    "net/variations_http_header_provider_unittest.cc",
+    "study_filtering_unittest.cc",
+    "variations_associated_data_unittest.cc",
+    "variations_seed_processor_unittest.cc",
+    "variations_seed_simulator_unittest.cc",
+  ]
+
+  deps = [
+    ":variations",
+    "net",
+    "proto",
+    "//base/test:test_support",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/variations/DEPS b/components/variations/DEPS
index 1a790cd..3d6cf278 100644
--- a/components/variations/DEPS
+++ b/components/variations/DEPS
@@ -1,5 +1,8 @@
+# This component is shared with the Chrome OS build, so it's important to limit
+# dependencies to a minimal set.
 include_rules = [
-  "+components/google",
-  "+net",
+  "-components",
+  "+components/variations",
+  "-net",
   "+third_party/mt19937ar",
 ]
diff --git a/components/variations/net/BUILD.gn b/components/variations/net/BUILD.gn
new file mode 100644
index 0000000..e35f5a84
--- /dev/null
+++ b/components/variations/net/BUILD.gn
@@ -0,0 +1,18 @@
+# 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.
+
+source_set("net") {
+  sources = [
+    "variations_http_header_provider.cc",
+    "variations_http_header_provider.h",
+  ]
+
+  public_deps = [ "//components/variations" ]
+  deps = [
+    "//base",
+    "//components/google/core/browser",
+    "//components/variations/proto",
+    "//net",
+  ]
+}
diff --git a/components/variations/net/DEPS b/components/variations/net/DEPS
new file mode 100644
index 0000000..f4a5acd
--- /dev/null
+++ b/components/variations/net/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "+components/google",
+  "+net",
+]
diff --git a/components/variations/variations_http_header_provider.cc b/components/variations/net/variations_http_header_provider.cc
similarity index 98%
rename from components/variations/variations_http_header_provider.cc
rename to components/variations/net/variations_http_header_provider.cc
index 12d9c9f4..1220fae 100644
--- a/components/variations/variations_http_header_provider.cc
+++ b/components/variations/net/variations_http_header_provider.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/variations/variations_http_header_provider.h"
+#include "components/variations/net/variations_http_header_provider.h"
 
 #include <vector>
 
diff --git a/components/variations/variations_http_header_provider.h b/components/variations/net/variations_http_header_provider.h
similarity index 94%
rename from components/variations/variations_http_header_provider.h
rename to components/variations/net/variations_http_header_provider.h
index 4bb79769..a0e3046 100644
--- a/components/variations/variations_http_header_provider.h
+++ b/components/variations/net/variations_http_header_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_VARIATIONS_VARIATIONS_HTTP_HEADER_PROVIDER_H_
-#define COMPONENTS_VARIATIONS_VARIATIONS_HTTP_HEADER_PROVIDER_H_
+#ifndef COMPONENTS_VARIATIONS_NET_VARIATIONS_HTTP_HEADER_PROVIDER_H_
+#define COMPONENTS_VARIATIONS_NET_VARIATIONS_HTTP_HEADER_PROVIDER_H_
 
 #include <set>
 #include <string>
@@ -109,4 +109,4 @@
 
 }  // namespace variations
 
-#endif  // COMPONENTS_VARIATIONS_VARIATIONS_HTTP_HEADER_PROVIDER_H_
+#endif  // COMPONENTS_VARIATIONS_NET_VARIATIONS_HTTP_HEADER_PROVIDER_H_
diff --git a/components/variations/variations_http_header_provider_unittest.cc b/components/variations/net/variations_http_header_provider_unittest.cc
similarity index 98%
rename from components/variations/variations_http_header_provider_unittest.cc
rename to components/variations/net/variations_http_header_provider_unittest.cc
index ca8a560a..6ed2ff4 100644
--- a/components/variations/variations_http_header_provider_unittest.cc
+++ b/components/variations/net/variations_http_header_provider_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/variations/variations_http_header_provider.h"
+#include "components/variations/net/variations_http_header_provider.h"
 
 #include <string>
 
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index 8ebce62..9031eef 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -78,7 +78,6 @@
 
 #include "base/strings/string_number_conversions.h"
 #include "ui/base/win/atl_module.h"
-#include "ui/base/win/dpi_setup.h"
 #include "ui/gfx/win/dpi.h"
 #elif defined(OS_MACOSX)
 #include "base/mac/scoped_nsautorelease_pool.h"
@@ -634,7 +633,7 @@
       }
     }
     if (init_device_scale_factor)
-      ui::win::InitDeviceScaleFactor();
+      gfx::InitDeviceScaleFactor(gfx::GetDPIScale());
 #endif
 
     if (!GetContentClient())
diff --git a/content/app/strings/content_strings.grd b/content/app/strings/content_strings.grd
index 9f9fca6..0b95a51 100644
--- a/content/app/strings/content_strings.grd
+++ b/content/app/strings/content_strings.grd
@@ -353,6 +353,9 @@
       <message name="IDS_AX_ROLE_HEADING" desc="accessibility role description for headings">
         heading
       </message>
+      <message name="IDS_AX_ROLE_REGION" desc="accessibility role description for region">
+        region
+      </message>
       <if expr="is_macosx">
         <message name="IDS_AX_ROLE_FOOTER" desc="accessibility role description for footers">
           footer
diff --git a/content/browser/DEPS b/content/browser/DEPS
index 715e0d38..742d204 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -15,6 +15,10 @@
   # above.
   "+components/tracing",
 
+  # In general, //content shouldn't depend on //device.
+  # This is the an exception.
+  "+device/udev_linux",  # For udev utility and wrapper library.
+
   # Other libraries.
   "+third_party/iaccessible2",
   "+third_party/isimpledom",
diff --git a/content/browser/accessibility/accessibility_ipc_error_browsertest.cc b/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
new file mode 100644
index 0000000..5702a33
--- /dev/null
+++ b/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 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 "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/accessibility_messages.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/accessibility_browser_test_utils.h"
+#include "ui/accessibility/ax_node.h"
+#include "ui/accessibility/ax_tree.h"
+
+namespace content {
+
+class AccessibilityIpcErrorBrowserTest : public ContentBrowserTest {
+ public:
+  AccessibilityIpcErrorBrowserTest() {}
+
+ protected:
+  // Convenience method to get the value of a particular AXNode
+  // attribute as a UTF-8 string.
+  std::string GetAttr(const ui::AXNode* node,
+                      const ui::AXStringAttribute attr) {
+    const ui::AXNodeData& data = node->data();
+    for (size_t i = 0; i < data.string_attributes.size(); ++i) {
+      if (data.string_attributes[i].first == attr)
+        return data.string_attributes[i].second;
+    }
+    return std::string();
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(AccessibilityIpcErrorBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(AccessibilityIpcErrorBrowserTest,
+                       ResetBrowserAccessibilityManager) {
+  // Create a data url and load it.
+  const char url_str[] =
+      "data:text/html,"
+      "<div aria-live='polite'>"
+      "  <p id='p1'>Paragraph One</p>"
+      "  <p id='p2'>Paragraph Two</p>"
+      "</div>"
+      "<button id='button'>Button</button>";
+  GURL url(url_str);
+  NavigateToURL(shell(), url);
+
+  // Simulate a condition where the RFH can't create a
+  // BrowserAccessibilityManager - like if there's no view.
+  RenderFrameHostImpl* frame = static_cast<RenderFrameHostImpl*>(
+      shell()->web_contents()->GetMainFrame());
+  frame->set_no_create_browser_accessibility_manager_for_testing(true);
+  ASSERT_EQ(nullptr, frame->GetOrCreateBrowserAccessibilityManager());
+
+  {
+    // Enable accessibility (passing AccessibilityModeComplete to
+    // AccessibilityNotificationWaiter does this automatically) and wait for
+    // the first event.
+    AccessibilityNotificationWaiter waiter(
+        shell(), AccessibilityModeComplete, ui::AX_EVENT_LAYOUT_COMPLETE);
+    waiter.WaitForNotification();
+  }
+
+  // Make sure we still didn't create a BrowserAccessibilityManager.
+  // This means that at least one accessibility IPC was lost.
+  ASSERT_EQ(nullptr, frame->GetOrCreateBrowserAccessibilityManager());
+
+  // Now create a BrowserAccessibilityManager, simulating what would happen
+  // if the RFH's view is created now - but then disallow recreating the
+  // BrowserAccessibilityManager so that we can test that this one gets
+  // destroyed.
+  frame->set_no_create_browser_accessibility_manager_for_testing(false);
+  ASSERT_TRUE(frame->GetOrCreateBrowserAccessibilityManager() != nullptr);
+  frame->set_no_create_browser_accessibility_manager_for_testing(true);
+
+  {
+    // Hide one of the elements on the page, and wait for an accessibility
+    // notification triggered by the hide.
+    AccessibilityNotificationWaiter waiter(
+        shell(), AccessibilityModeComplete, ui::AX_EVENT_LIVE_REGION_CHANGED);
+    ASSERT_TRUE(ExecuteScript(
+        shell()->web_contents(),
+        "document.getElementById('p1').style.display = 'none';"));
+    waiter.WaitForNotification();
+  }
+
+  // Show that accessibility was reset because the frame doesn't have a
+  // BrowserAccessibilityManager anymore.
+  ASSERT_EQ(nullptr, frame->browser_accessibility_manager());
+
+  // Finally, allow creating a new accessibility manager and
+  // ensure that we didn't kill the renderer; we can still send it messages.
+  frame->set_no_create_browser_accessibility_manager_for_testing(false);
+  const ui::AXTree* tree = nullptr;
+  {
+    AccessibilityNotificationWaiter waiter(
+        shell(), AccessibilityModeComplete, ui::AX_EVENT_FOCUS);
+    ASSERT_TRUE(ExecuteScript(
+        shell()->web_contents(),
+        "document.getElementById('button').focus();"));
+    waiter.WaitForNotification();
+    tree = &waiter.GetAXTree();
+  }
+
+  // Get the accessibility tree, ensure it reflects the final state of the
+  // document.
+  const ui::AXNode* root = tree->GetRoot();
+
+  // Use this for debugging if the test fails.
+  VLOG(1) << tree->ToString();
+
+  EXPECT_EQ(ui::AX_ROLE_ROOT_WEB_AREA, root->data().role);
+  ASSERT_EQ(2, root->child_count());
+
+  const ui::AXNode* live_region = root->ChildAtIndex(0);
+  ASSERT_EQ(1, live_region->child_count());
+  EXPECT_EQ(ui::AX_ROLE_DIV, live_region->data().role);
+
+  const ui::AXNode* para = live_region->ChildAtIndex(0);
+  EXPECT_EQ(ui::AX_ROLE_PARAGRAPH, para->data().role);
+
+  const ui::AXNode* button_container = root->ChildAtIndex(1);
+  EXPECT_EQ(ui::AX_ROLE_GROUP, button_container->data().role);
+  ASSERT_EQ(1, button_container->child_count());
+
+  const ui::AXNode* button = button_container->ChildAtIndex(0);
+  EXPECT_EQ(ui::AX_ROLE_BUTTON, button->data().role);
+  EXPECT_TRUE(button->data().state >> ui::AX_STATE_FOCUSED & 1);
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityIpcErrorBrowserTest,
+                       MultipleBadAccessibilityIPCsKillsRenderer) {
+  // Create a data url and load it.
+  const char url_str[] =
+      "data:text/html,"
+      "<button id='button'>Button</button>";
+  GURL url(url_str);
+  NavigateToURL(shell(), url);
+  RenderFrameHostImpl* frame = static_cast<RenderFrameHostImpl*>(
+      shell()->web_contents()->GetMainFrame());
+
+  {
+    // Enable accessibility (passing AccessibilityModeComplete to
+    // AccessibilityNotificationWaiter does this automatically) and wait for
+    // the first event.
+    AccessibilityNotificationWaiter waiter(
+        shell(), AccessibilityModeComplete, ui::AX_EVENT_LAYOUT_COMPLETE);
+    waiter.WaitForNotification();
+  }
+
+  // Construct a bad accessibility message that BrowserAccessibilityManager
+  // will reject.
+  std::vector<AccessibilityHostMsg_EventParams> bad_accessibility_event_list;
+  bad_accessibility_event_list.push_back(AccessibilityHostMsg_EventParams());
+  bad_accessibility_event_list[0].update.node_id_to_clear = -2;
+
+  // We should be able to reset accessibility |max_iterations-1| times
+  // (see render_frame_host_impl.cc - kMaxAccessibilityResets),
+  // but the subsequent time the renderer should be killed.
+  int max_iterations = RenderFrameHostImpl::kMaxAccessibilityResets;
+
+  for (int iteration = 0; iteration < max_iterations; iteration++) {
+    // Send the browser accessibility the bad message.
+    BrowserAccessibilityManager* manager =
+        frame->GetOrCreateBrowserAccessibilityManager();
+    manager->OnAccessibilityEvents(bad_accessibility_event_list);
+
+    // Now the frame should have deleted the BrowserAccessibilityManager.
+    ASSERT_EQ(nullptr, frame->browser_accessibility_manager());
+
+    if (iteration == max_iterations - 1)
+      break;
+
+    AccessibilityNotificationWaiter waiter(
+        shell(), AccessibilityModeComplete, ui::AX_EVENT_LAYOUT_COMPLETE);
+    waiter.WaitForNotification();
+  }
+
+  // Wait for the renderer to be killed.
+  if (frame->IsRenderFrameLive()) {
+    RenderProcessHostWatcher render_process_watcher(
+        frame->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+    render_process_watcher.Wait();
+  }
+  ASSERT_FALSE(frame->IsRenderFrameLive());
+}
+
+}  // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index a0a5baf..61ecb22 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -307,6 +307,8 @@
   // Blink, making the platform-specific mapping to accessible text simpler.
   base::string16 description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION);
   base::string16 help = GetString16Attribute(ui::AX_ATTR_HELP);
+  base::string16 placeholder;
+  GetHtmlAttribute("placeholder", &placeholder);
   int title_elem_id = GetIntAttribute(
       ui::AX_ATTR_TITLE_UI_ELEMENT);
   base::string16 text;
@@ -318,6 +320,8 @@
     text = help;
   else if (!name().empty())
     text = base::UTF8ToUTF16(name());
+  else if (GetRole() == ui::AX_ROLE_TEXT_FIELD && !placeholder.empty())
+    text = placeholder;
   else if (!value().empty())
     text = base::UTF8ToUTF16(value());
 
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 1172e34..aa11b5f 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -582,6 +582,9 @@
   case ui::AX_ROLE_FOOTER:
     return base::SysUTF16ToNSString(content_client->GetLocalizedString(
         IDS_AX_ROLE_FOOTER));
+  case ui::AX_ROLE_REGION:
+    return base::SysUTF16ToNSString(content_client->GetLocalizedString(
+        IDS_AX_ROLE_REGION));
   case ui::AX_ROLE_SPIN_BUTTON:
     // This control is similar to what VoiceOver calls a "stepper".
     return base::SysUTF16ToNSString(content_client->GetLocalizedString(
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index f8aadbc..acfc35c1 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -3690,9 +3690,12 @@
       ia2_role_ = IA2_ROLE_SECTION;
       break;
     case ui::AX_ROLE_REGION:
-      ia_role_ = ROLE_SYSTEM_GROUPING;
-      ia2_role_ = IA2_ROLE_SECTION;
-      ia_state_ |= STATE_SYSTEM_READONLY;
+      if (html_tag == L"section") {
+        ia_role_ = ROLE_SYSTEM_GROUPING;
+        ia2_role_ = IA2_ROLE_SECTION;
+      } else {
+        ia_role_ = ROLE_SYSTEM_PANE;
+      }
       break;
     case ui::AX_ROLE_ROW:
       ia_role_ = ROLE_SYSTEM_ROW;
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index d475159..9e66af6 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -340,6 +340,10 @@
   RunTest(FILE_PATH_LITERAL("aria-checkbox.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaChecked) {
+  RunTest(FILE_PATH_LITERAL("aria-checked.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                        AccessibilityAriaColumnHeader) {
   RunTest(FILE_PATH_LITERAL("aria-columnheader.html"));
@@ -362,6 +366,10 @@
   RunTest(FILE_PATH_LITERAL("aria-contentinfo.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaDefinition) {
+  RunTest(FILE_PATH_LITERAL("aria-definition.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaHasPopup) {
   RunTest(FILE_PATH_LITERAL("aria-haspopup.html"));
 }
@@ -396,6 +404,10 @@
   RunTest(FILE_PATH_LITERAL("aria-list.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaListBox) {
+  RunTest(FILE_PATH_LITERAL("aria-listbox.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                        AccessibilityAriaListBoxActiveDescendant) {
   RunTest(FILE_PATH_LITERAL("aria-listbox-activedescendant.html"));
@@ -423,6 +435,10 @@
   RunTest(FILE_PATH_LITERAL("aria-menu.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaMenuBar) {
+  RunTest(FILE_PATH_LITERAL("aria-menubar.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                        AccessibilityAriaMenuItemCheckBox) {
   RunTest(FILE_PATH_LITERAL("aria-menuitemcheckbox.html"));
@@ -460,6 +476,10 @@
   RunTest(FILE_PATH_LITERAL("aria-relevant.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaRequired) {
+  RunTest(FILE_PATH_LITERAL("aria-required.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaRow) {
   RunTest(FILE_PATH_LITERAL("aria-row.html"));
 }
@@ -469,6 +489,14 @@
   RunTest(FILE_PATH_LITERAL("aria-readonly.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaRegion) {
+  RunTest(FILE_PATH_LITERAL("aria-region.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaSeparator) {
+  RunTest(FILE_PATH_LITERAL("aria-separator.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaSort) {
   RunTest(FILE_PATH_LITERAL("aria-sort.html"));
 }
@@ -492,6 +520,10 @@
   RunTest(FILE_PATH_LITERAL("aria-toolbar.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaTree) {
+  RunTest(FILE_PATH_LITERAL("aria-tree.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
                        AccessibilityAriaValueMin) {
   RunTest(FILE_PATH_LITERAL("aria-valuemin.html"));
@@ -608,6 +640,10 @@
   RunTest(FILE_PATH_LITERAL("frameset.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityHead) {
+  RunTest(FILE_PATH_LITERAL("head.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityHeader) {
   RunTest(FILE_PATH_LITERAL("header.html"));
 }
@@ -697,6 +733,14 @@
   RunTest(FILE_PATH_LITERAL("input-search.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputSubmit) {
+  RunTest(FILE_PATH_LITERAL("input-submit.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputTel) {
+  RunTest(FILE_PATH_LITERAL("input-tel.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityInputText) {
   RunTest(FILE_PATH_LITERAL("input-text.html"));
 }
@@ -799,6 +843,10 @@
   RunTest(FILE_PATH_LITERAL("navigation.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityNoscript) {
+  RunTest(FILE_PATH_LITERAL("noscript.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityOl) {
   RunTest(FILE_PATH_LITERAL("ol.html"));
 }
@@ -824,8 +872,8 @@
   RunTest(FILE_PATH_LITERAL("q.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityRegion) {
-  RunTest(FILE_PATH_LITERAL("region.html"));
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilitySection) {
+  RunTest(FILE_PATH_LITERAL("section.html"));
 }
 
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilitySelect) {
@@ -870,6 +918,14 @@
   RunTest(FILE_PATH_LITERAL("table-spans.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityTextArea) {
+  RunTest(FILE_PATH_LITERAL("textarea.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityTitle) {
+  RunTest(FILE_PATH_LITERAL("title.html"));
+}
+
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityTransition) {
   RunTest(FILE_PATH_LITERAL("transition.html"));
 }
diff --git a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
index 556acf0..12cdc89 100644
--- a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
+++ b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
@@ -22,7 +22,6 @@
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
-#include "content/public/test/routing_id_mangling_disabler.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "content/test/accessibility_browser_test_utils.h"
@@ -36,11 +35,6 @@
     : public SitePerProcessBrowserTest {
  public:
   SitePerProcessAccessibilityBrowserTest() {}
-
-  // TODO(morrita): This is fishy. This test shouldn't rely on the
-  // abasence of routing_id mangling. Something seems wrong.
-  // See http://crbug.com/422136 for more updates.
-  content::RoutingIDManglingDisabler mangling_disabler_;
 };
 
 // TODO(nasko): try enabling this test on more platforms once
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 54bb4fc..cdc2146 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -866,6 +866,20 @@
   if (!rwhv)
     return false;
 
+  MotionEventAndroid::Pointer pointer0(pointer_id_0,
+                                       pos_x_0,
+                                       pos_y_0,
+                                       touch_major_0,
+                                       touch_minor_0,
+                                       orientation_0,
+                                       android_tool_type_0);
+  MotionEventAndroid::Pointer pointer1(pointer_id_1,
+                                       pos_x_1,
+                                       pos_y_1,
+                                       touch_major_1,
+                                       touch_minor_1,
+                                       orientation_1,
+                                       android_tool_type_1);
   MotionEventAndroid event(1.f / dpi_scale(),
                            env,
                            motion_event,
@@ -874,24 +888,12 @@
                            pointer_count,
                            history_size,
                            action_index,
-                           pos_x_0,
-                           pos_y_0,
-                           pos_x_1,
-                           pos_y_1,
-                           pointer_id_0,
-                           pointer_id_1,
-                           touch_major_0,
-                           touch_major_1,
-                           touch_minor_0,
-                           touch_minor_1,
-                           orientation_0,
-                           orientation_1,
-                           raw_pos_x,
-                           raw_pos_y,
-                           android_tool_type_0,
-                           android_tool_type_1,
                            android_button_state,
-                           android_meta_state);
+                           android_meta_state,
+                           raw_pos_x - pos_x_0,
+                           raw_pos_y - pos_y_0,
+                           pointer0,
+                           pointer1);
 
   return is_touch_handle_event ? rwhv->OnTouchHandleEvent(event)
                                : rwhv->OnTouchEvent(event);
@@ -1145,25 +1147,6 @@
   return rwhva->GetNativeImeAdapter();
 }
 
-// TODO(sgurun) add support for posting a frame whose name is known (only
-//               main frame is supported at this time, see crbug.com/389721)
-// TODO(sgurun) add support for passing message ports
-void ContentViewCoreImpl::PostMessageToFrame(JNIEnv* env, jobject obj,
-    jstring frame_name, jstring message, jstring source_origin,
-    jstring target_origin) {
-
-  RenderViewHost* host = web_contents_->GetRenderViewHost();
-  if (!host)
-      return;
-  ViewMsg_PostMessage_Params params;
-  params.source_origin = ConvertJavaStringToUTF16(env, source_origin);
-  params.target_origin = ConvertJavaStringToUTF16(env, target_origin);
-  params.data = ConvertJavaStringToUTF16(env, message);
-  params.is_data_raw_string = true;
-  params.source_routing_id = MSG_ROUTING_NONE;
-  host->Send(new ViewMsg_PostMessageEvent(host->GetRoutingID(), params));
-}
-
 void ContentViewCoreImpl::UpdateImeAdapter(long native_ime_adapter,
                                            int text_input_type,
                                            int text_input_flags,
@@ -1261,8 +1244,12 @@
 
 void ContentViewCoreImpl::SetBackgroundOpaque(JNIEnv* env, jobject jobj,
     jboolean opaque) {
-  if (GetRenderWidgetHostViewAndroid())
-    GetRenderWidgetHostViewAndroid()->SetBackgroundOpaque(opaque);
+  if (GetRenderWidgetHostViewAndroid()) {
+    if (opaque)
+      GetRenderWidgetHostViewAndroid()->SetBackgroundColorToDefault();
+    else
+      GetRenderWidgetHostViewAndroid()->SetBackgroundColor(SK_ColorTRANSPARENT);
+  }
 }
 
 void ContentViewCoreImpl::RequestTextSurroundingSelection(
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index cee7a1d5..8304df0e 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -151,8 +151,6 @@
                                        jobject obj,
                                        jboolean enabled);
 
-  void PostMessageToFrame(JNIEnv* env, jobject obj, jstring frame_id,
-      jstring message, jstring source_origin, jstring target_origin);
   long GetNativeImeAdapter(JNIEnv* env, jobject obj);
   void SetFocus(JNIEnv* env, jobject obj, jboolean focused);
 
diff --git a/content/browser/android/system_ui_resource_manager_impl.cc b/content/browser/android/system_ui_resource_manager_impl.cc
index 2862857..57ef6f205 100644
--- a/content/browser/android/system_ui_resource_manager_impl.cc
+++ b/content/browser/android/system_ui_resource_manager_impl.cc
@@ -16,7 +16,6 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPaint.h"
-#include "third_party/skia/include/effects/SkPorterDuff.h"
 #include "ui/gfx/android/java_bitmap.h"
 #include "ui/gfx/screen.h"
 
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index f2f2827..7c47194 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -265,6 +265,11 @@
 
 void BrowserChildProcessHostImpl::OnChildDisconnected() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+#if defined(OS_WIN)
+  // OnChildDisconnected may be called without OnChannelConnected, so stop the
+  // early exit watcher so GetTerminationStatus can close the process handle.
+  early_exit_watcher_.StopWatching();
+#endif
   if (child_process_.get() || data_.handle) {
     DCHECK(data_.handle != base::kNullProcessHandle);
     int exit_code;
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
index 68876eae..ea6a573 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -86,6 +86,7 @@
       is_in_destruction_(false),
       last_text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
       last_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
+      last_input_flags_(0),
       last_can_compose_inline_(true),
       guest_proxy_routing_id_(MSG_ROUTING_NONE),
       delegate_(delegate),
@@ -121,7 +122,7 @@
       rwh->GetView());
   if (rwhv) {
     rwhv->TextInputTypeChanged(last_text_input_type_, last_input_mode_,
-                               last_can_compose_inline_);
+                               last_can_compose_inline_, last_input_flags_);
   }
 }
 
@@ -800,15 +801,17 @@
 
 void BrowserPluginGuest::OnTextInputTypeChanged(ui::TextInputType type,
                                                 ui::TextInputMode input_mode,
-                                                bool can_compose_inline) {
+                                                bool can_compose_inline,
+                                                int flags) {
   // Save the state of text input so we can restore it on focus.
   last_text_input_type_ = type;
   last_input_mode_ = input_mode;
+  last_input_flags_ = flags;
   last_can_compose_inline_ = can_compose_inline;
 
   static_cast<RenderWidgetHostViewBase*>(
       web_contents()->GetRenderWidgetHostView())->TextInputTypeChanged(
-          type, input_mode, can_compose_inline);
+          type, input_mode, can_compose_inline, flags);
 }
 
 void BrowserPluginGuest::OnImeCancelComposition() {
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h
index be25d09..1cc9e02a 100644
--- a/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -290,7 +290,8 @@
 
   void OnTextInputTypeChanged(ui::TextInputType type,
                               ui::TextInputMode input_mode,
-                              bool can_compose_inline);
+                              bool can_compose_inline,
+                              int flags);
   void OnImeSetComposition(
       int instance_id,
       const std::string& text,
@@ -371,6 +372,7 @@
   // Text input type states.
   ui::TextInputType last_text_input_type_;
   ui::TextInputMode last_input_mode_;
+  int last_input_flags_;
   bool last_can_compose_inline_;
 
   // The is the routing ID for a swapped out RenderView for the guest
diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc
index 7f3961b..ccf962a 100644
--- a/content/browser/compositor/delegated_frame_host.cc
+++ b/content/browser/compositor/delegated_frame_host.cc
@@ -349,6 +349,10 @@
     // the DelegatedRendererLayer.
     EvictDelegatedFrame();
 
+    surface_factory_.reset();
+    if (!surface_returned_resources_.empty())
+      SendReturnedDelegatedResources(last_output_surface_id_);
+
     // Drop the cc::DelegatedFrameResourceCollection so that we will not return
     // any resources from the old output surface with the new output surface id.
     if (resource_collection_.get()) {
diff --git a/content/browser/device_sensors/sensor_manager_android.cc b/content/browser/device_sensors/sensor_manager_android.cc
index abc3792..11de85a 100644
--- a/content/browser/device_sensors/sensor_manager_android.cc
+++ b/content/browser/device_sensors/sensor_manager_android.cc
@@ -31,7 +31,8 @@
       device_orientation_buffer_(NULL),
       is_light_buffer_ready_(false),
       is_motion_buffer_ready_(false),
-      is_orientation_buffer_ready_(false) {
+      is_orientation_buffer_ready_(false),
+      is_using_backup_sensors_for_orientation_(false) {
   memset(received_motion_data_, 0, sizeof(received_motion_data_));
   device_sensors_.Reset(Java_DeviceSensors_getInstance(
       AttachCurrentThread(), base::android::GetApplicationContext()));
@@ -67,7 +68,7 @@
 
   if (!is_orientation_buffer_ready_) {
     SetOrientationBufferReadyStatus(true);
-    updateRotationVectorHistogram(true);
+    updateRotationVectorHistogram(!is_using_backup_sensors_for_orientation_);
   }
 }
 
@@ -173,6 +174,11 @@
       AttachCurrentThread(), device_sensors_.obj());
 }
 
+bool SensorManagerAndroid::isUsingBackupSensorsForOrientation() {
+  DCHECK(!device_sensors_.is_null());
+  return Java_DeviceSensors_isUsingBackupSensorsForOrientation(
+      AttachCurrentThread(), device_sensors_.obj());
+}
 
 // ----- Shared memory API methods
 
@@ -308,6 +314,9 @@
 
   if (!success)
     updateRotationVectorHistogram(false);
+  else
+    is_using_backup_sensors_for_orientation_ =
+        isUsingBackupSensorsForOrientation();
 
   return success;
 }
diff --git a/content/browser/device_sensors/sensor_manager_android.h b/content/browser/device_sensors/sensor_manager_android.h
index b8e90d86..714b8ec 100644
--- a/content/browser/device_sensors/sensor_manager_android.h
+++ b/content/browser/device_sensors/sensor_manager_android.h
@@ -86,6 +86,7 @@
   void ClearInternalMotionBuffers();
 
   void SetOrientationBufferReadyStatus(bool ready);
+  bool isUsingBackupSensorsForOrientation();
 
   // The Java provider of sensors info.
   base::android::ScopedJavaGlobalRef<jobject> device_sensors_;
@@ -102,6 +103,8 @@
   base::Lock motion_buffer_lock_;
   base::Lock orientation_buffer_lock_;
 
+  bool is_using_backup_sensors_for_orientation_;
+
   DISALLOW_COPY_AND_ASSIGN(SensorManagerAndroid);
 };
 
diff --git a/content/browser/devtools/devtools_http_handler_impl.cc b/content/browser/devtools/devtools_http_handler_impl.cc
index 11f1fb1..014032de 100644
--- a/content/browser/devtools/devtools_http_handler_impl.cc
+++ b/content/browser/devtools/devtools_http_handler_impl.cc
@@ -21,7 +21,8 @@
 #include "content/browser/devtools/devtools_protocol.h"
 #include "content/browser/devtools/devtools_protocol_constants.h"
 #include "content/browser/devtools/devtools_system_info_handler.h"
-#include "content/browser/devtools/devtools_tracing_handler.h"
+#include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h"
+#include "content/browser/devtools/protocol/tracing_handler.h"
 #include "content/browser/devtools/tethering_handler.h"
 #include "content/common/devtools_messages.h"
 #include "content/public/browser/browser_thread.h"
@@ -158,7 +159,13 @@
                 int connection_id)
       : message_loop_(message_loop),
         server_(server),
-        connection_id_(connection_id) {
+        connection_id_(connection_id),
+        tracing_handler_(new devtools::tracing::TracingHandler(
+            devtools::tracing::TracingHandler::Browser)),
+        protocol_handler_(new DevToolsProtocolHandlerImpl()) {
+    protocol_handler_->SetNotifier(
+        base::Bind(&BrowserTarget::Respond, base::Unretained(this)));
+    protocol_handler_->SetTracingHandler(tracing_handler_.get());
   }
 
   ~BrowserTarget() {
@@ -183,17 +190,20 @@
       return;
     }
 
+    scoped_refptr<DevToolsProtocol::Response> response =
+        protocol_handler_->HandleCommand(command);
     for (const auto& handler : handlers_) {
-      scoped_refptr<DevToolsProtocol::Response> response =
-              handler->HandleCommand(command);
-      if (response.get()) {
-        if (!response->is_async_promise())
-          Respond(response->Serialize());
-        return;
-      }
+      if (response.get())
+        break;
+      response = handler->HandleCommand(command);
     }
 
-    Respond(command->NoSuchMethodErrorResponse()->Serialize());
+    if (response.get()) {
+      if (!response->is_async_promise())
+        Respond(response->Serialize());
+    } else {
+      Respond(command->NoSuchMethodErrorResponse()->Serialize());
+    }
   }
 
   void Respond(const std::string& message) {
@@ -210,6 +220,8 @@
   base::MessageLoop* const message_loop_;
   net::HttpServer* const server_;
   const int connection_id_;
+  scoped_ptr<devtools::tracing::TracingHandler> tracing_handler_;
+  scoped_ptr<DevToolsProtocolHandlerImpl> protocol_handler_;
   std::vector<DevToolsProtocol::Handler*> handlers_;
 };
 
@@ -691,8 +703,6 @@
     BrowserTarget* browser_target = new BrowserTarget(
         thread_->message_loop(), server_.get(), connection_id);
     browser_target->RegisterHandler(
-        new DevToolsTracingHandler(DevToolsTracingHandler::Browser));
-    browser_target->RegisterHandler(
         new TetheringHandler(delegate_.get(), thread_->message_loop_proxy()));
     browser_target->RegisterHandler(
         new DevToolsSystemInfoHandler());
diff --git a/content/browser/devtools/devtools_protocol.h b/content/browser/devtools/devtools_protocol.h
index 512bfb7b..50dc8a6 100644
--- a/content/browser/devtools/devtools_protocol.h
+++ b/content/browser/devtools/devtools_protocol.h
@@ -113,6 +113,7 @@
 
    private:
     friend class DevToolsProtocol;
+    friend class DevToolsProtocolClient;
     ~Notification() override;
 
     // Takes ownership of |params|.
diff --git a/content/browser/devtools/devtools_tracing_handler.cc b/content/browser/devtools/devtools_tracing_handler.cc
deleted file mode 100644
index f8539da4..0000000
--- a/content/browser/devtools/devtools_tracing_handler.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/devtools/devtools_tracing_handler.h"
-
-#include <cmath>
-
-#include "base/bind.h"
-#include "base/debug/trace_event_impl.h"
-#include "base/strings/string_split.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "base/values.h"
-#include "content/browser/devtools/devtools_http_handler_impl.h"
-#include "content/browser/devtools/devtools_protocol_constants.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/tracing_controller.h"
-
-namespace content {
-
-namespace {
-
-const char kRecordUntilFull[]   = "record-until-full";
-const char kRecordContinuously[] = "record-continuously";
-const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible";
-const char kEnableSampling[] = "enable-sampling";
-
-class DevToolsTraceSinkProxy : public TracingController::TraceDataSink {
- public:
-  explicit DevToolsTraceSinkProxy(base::WeakPtr<DevToolsTracingHandler> handler)
-      : tracing_handler_(handler) {}
-
-  void AddTraceChunk(const std::string& chunk) override {
-    if (DevToolsTracingHandler* h = tracing_handler_.get())
-      h->OnTraceDataCollected(chunk);
-  }
-  void Close() override {
-    if (DevToolsTracingHandler* h = tracing_handler_.get())
-      h->OnTraceComplete();
-  }
-
- private:
-  ~DevToolsTraceSinkProxy() override {}
-
-  base::WeakPtr<DevToolsTracingHandler> tracing_handler_;
-};
-
-}  // namespace
-
-const char* DevToolsTracingHandler::kDefaultCategories =
-    "-*,disabled-by-default-devtools.timeline*";
-const double DevToolsTracingHandler::kDefaultReportingInterval = 1000.0;
-const double DevToolsTracingHandler::kMinimumReportingInterval = 250.0;
-
-DevToolsTracingHandler::DevToolsTracingHandler(
-    DevToolsTracingHandler::Target target)
-    : target_(target), is_recording_(false), weak_factory_(this) {
-  RegisterCommandHandler(devtools::Tracing::start::kName,
-                         base::Bind(&DevToolsTracingHandler::OnStart,
-                                    base::Unretained(this)));
-  RegisterCommandHandler(devtools::Tracing::end::kName,
-                         base::Bind(&DevToolsTracingHandler::OnEnd,
-                                    base::Unretained(this)));
-  RegisterCommandHandler(devtools::Tracing::getCategories::kName,
-                         base::Bind(&DevToolsTracingHandler::OnGetCategories,
-                                    base::Unretained(this)));
-}
-
-DevToolsTracingHandler::~DevToolsTracingHandler() {
-}
-
-void DevToolsTracingHandler::OnTraceDataCollected(
-    const std::string& trace_fragment) {
-  // Hand-craft protocol notification message so we can substitute JSON
-  // that we already got as string as a bare object, not a quoted string.
-  std::string message =
-      base::StringPrintf("{ \"method\": \"%s\", \"params\": { \"%s\": [",
-                         devtools::Tracing::dataCollected::kName,
-                         devtools::Tracing::dataCollected::kParamValue);
-  const size_t messageSuffixSize = 10;
-  message.reserve(message.size() + trace_fragment.size() + messageSuffixSize);
-  message += trace_fragment;
-  message += "] } }", SendRawMessage(message);
-}
-
-void DevToolsTracingHandler::OnTraceComplete() {
-  SendNotification(devtools::Tracing::tracingComplete::kName, NULL);
-}
-
-base::debug::TraceOptions DevToolsTracingHandler::TraceOptionsFromString(
-    const std::string& options) {
-  std::vector<std::string> split;
-  std::vector<std::string>::iterator iter;
-  base::debug::TraceOptions ret;
-
-  base::SplitString(options, ',', &split);
-  for (iter = split.begin(); iter != split.end(); ++iter) {
-    if (*iter == kRecordUntilFull) {
-      ret.record_mode = base::debug::RECORD_UNTIL_FULL;
-    } else if (*iter == kRecordContinuously) {
-      ret.record_mode = base::debug::RECORD_CONTINUOUSLY;
-    } else if (*iter == kRecordAsMuchAsPossible) {
-      ret.record_mode = base::debug::RECORD_AS_MUCH_AS_POSSIBLE;
-    } else if (*iter == kEnableSampling) {
-      ret.enable_sampling = true;
-    }
-  }
-  return ret;
-}
-
-scoped_refptr<DevToolsProtocol::Response>
-DevToolsTracingHandler::OnStart(
-    scoped_refptr<DevToolsProtocol::Command> command) {
-  if (is_recording_) {
-    return command->InternalErrorResponse("Tracing is already started");
-  }
-  is_recording_ = true;
-
-  std::string categories;
-  base::debug::TraceOptions options;
-  double usage_reporting_interval = 0.0;
-
-  base::DictionaryValue* params = command->params();
-  if (params) {
-    params->GetString(devtools::Tracing::start::kParamCategories, &categories);
-    std::string options_param;
-    if (params->GetString(devtools::Tracing::start::kParamOptions,
-                          &options_param)) {
-      options = TraceOptionsFromString(options_param);
-    }
-    params->GetDouble(
-        devtools::Tracing::start::kParamBufferUsageReportingInterval,
-        &usage_reporting_interval);
-  }
-
-  SetupTimer(usage_reporting_interval);
-
-  // If inspected target is a render process Tracing.start will be handled by
-  // tracing agent in the renderer.
-  if (target_ == Renderer) {
-    TracingController::GetInstance()->EnableRecording(
-        base::debug::CategoryFilter(categories),
-        options,
-        TracingController::EnableRecordingDoneCallback());
-    return NULL;
-  }
-
-  TracingController::GetInstance()->EnableRecording(
-      base::debug::CategoryFilter(categories),
-      options,
-      base::Bind(&DevToolsTracingHandler::OnRecordingEnabled,
-                 weak_factory_.GetWeakPtr(),
-                 command));
-  return command->AsyncResponsePromise();
-}
-
-void DevToolsTracingHandler::SetupTimer(double usage_reporting_interval) {
-  if (usage_reporting_interval == 0) return;
-
-  if (usage_reporting_interval < kMinimumReportingInterval)
-      usage_reporting_interval = kMinimumReportingInterval;
-
-  base::TimeDelta interval = base::TimeDelta::FromMilliseconds(
-      std::ceil(usage_reporting_interval));
-  buffer_usage_poll_timer_.reset(new base::Timer(
-      FROM_HERE,
-      interval,
-      base::Bind(
-          base::IgnoreResult(&TracingController::GetTraceBufferPercentFull),
-          base::Unretained(TracingController::GetInstance()),
-          base::Bind(&DevToolsTracingHandler::OnBufferUsage,
-                     weak_factory_.GetWeakPtr())),
-      true));
-  buffer_usage_poll_timer_->Reset();
-}
-
-void DevToolsTracingHandler::OnRecordingEnabled(
-    scoped_refptr<DevToolsProtocol::Command> command) {
-  SendAsyncResponse(command->SuccessResponse(NULL));
-}
-
-void DevToolsTracingHandler::OnBufferUsage(float usage) {
-  base::DictionaryValue* params = new base::DictionaryValue();
-  params->SetDouble(devtools::Tracing::bufferUsage::kParamValue, usage);
-  SendNotification(devtools::Tracing::bufferUsage::kName, params);
-}
-
-scoped_refptr<DevToolsProtocol::Response>
-DevToolsTracingHandler::OnEnd(
-    scoped_refptr<DevToolsProtocol::Command> command) {
-  if (!is_recording_) {
-    return command->InternalErrorResponse("Tracing is not started");
-  }
-  DisableRecording(false);
-  // If inspected target is a render process Tracing.end will be handled by
-  // tracing agent in the renderer.
-  if (target_ == Renderer)
-    return NULL;
-  return command->SuccessResponse(NULL);
-}
-
-void DevToolsTracingHandler::DisableRecording(bool abort) {
-  is_recording_ = false;
-  buffer_usage_poll_timer_.reset();
-  TracingController::GetInstance()->DisableRecording(
-      abort ? NULL : new DevToolsTraceSinkProxy(weak_factory_.GetWeakPtr()));
-}
-
-void DevToolsTracingHandler::OnClientDetached() {
-  if (is_recording_)
-    DisableRecording(true);
-}
-
-scoped_refptr<DevToolsProtocol::Response>
-DevToolsTracingHandler::OnGetCategories(
-    scoped_refptr<DevToolsProtocol::Command> command) {
-  TracingController::GetInstance()->GetCategories(
-      base::Bind(&DevToolsTracingHandler::OnCategoriesReceived,
-                 weak_factory_.GetWeakPtr(),
-                 command));
-  return command->AsyncResponsePromise();
-}
-
-void DevToolsTracingHandler::OnCategoriesReceived(
-    scoped_refptr<DevToolsProtocol::Command> command,
-    const std::set<std::string>& category_set) {
-  base::DictionaryValue* response = new base::DictionaryValue;
-  base::ListValue* category_list = new base::ListValue;
-  for (std::set<std::string>::const_iterator it = category_set.begin();
-       it != category_set.end(); ++it) {
-    category_list->AppendString(*it);
-  }
-
-  response->Set(devtools::Tracing::getCategories::kResponseCategories,
-                category_list);
-  SendAsyncResponse(command->SuccessResponse(response));
-}
-
-}  // namespace content
diff --git a/content/browser/devtools/devtools_tracing_handler.h b/content/browser/devtools/devtools_tracing_handler.h
deleted file mode 100644
index 6b1a93f9..0000000
--- a/content/browser/devtools/devtools_tracing_handler.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
-#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
-
-#include <set>
-#include <string>
-
-#include "base/debug/trace_event.h"
-#include "base/memory/weak_ptr.h"
-#include "content/browser/devtools/devtools_protocol.h"
-#include "content/public/browser/tracing_controller.h"
-
-namespace base {
-class RefCountedString;
-class Timer;
-}
-
-namespace content {
-
-// This class bridges DevTools remote debugging server with the trace
-// infrastructure.
-class DevToolsTracingHandler : public DevToolsProtocol::Handler {
- public:
-  enum Target { Browser, Renderer };
-  explicit DevToolsTracingHandler(Target target);
-  ~DevToolsTracingHandler() override;
-
-  void OnClientDetached();
-
-  void OnTraceDataCollected(const std::string& trace_fragment);
-  void OnTraceComplete();
-
- private:
-  void OnRecordingEnabled(scoped_refptr<DevToolsProtocol::Command> command);
-  void OnBufferUsage(float usage);
-
-  scoped_refptr<DevToolsProtocol::Response> OnStart(
-      scoped_refptr<DevToolsProtocol::Command> command);
-  scoped_refptr<DevToolsProtocol::Response> OnEnd(
-      scoped_refptr<DevToolsProtocol::Command> command);
-
-  scoped_refptr<DevToolsProtocol::Response> OnGetCategories(
-      scoped_refptr<DevToolsProtocol::Command> command);
-
-  void OnCategoriesReceived(scoped_refptr<DevToolsProtocol::Command> command,
-                            const std::set<std::string>& category_set);
-
-  base::debug::TraceOptions TraceOptionsFromString(const std::string& options);
-
-  void SetupTimer(double usage_reporting_interval);
-
-  void DisableRecording(bool abort);
-
-  scoped_ptr<base::Timer> buffer_usage_poll_timer_;
-  Target target_;
-  bool is_recording_;
-
-  static const char* kDefaultCategories;
-  static const double kDefaultReportingInterval;
-  static const double kMinimumReportingInterval;
-
-  base::WeakPtrFactory<DevToolsTracingHandler> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(DevToolsTracingHandler);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
diff --git a/content/browser/devtools/protocol/devtools_protocol_client.cc b/content/browser/devtools/protocol/devtools_protocol_client.cc
index a0d9547..a34189e0 100644
--- a/content/browser/devtools/protocol/devtools_protocol_client.cc
+++ b/content/browser/devtools/protocol/devtools_protocol_client.cc
@@ -7,10 +7,8 @@
 namespace content {
 
 DevToolsProtocolClient::DevToolsProtocolClient(
-    const EventCallback& event_callback,
-    const ResponseCallback& response_callback)
-    : event_callback_(event_callback),
-      response_callback_(response_callback) {
+    const RawMessageCallback& raw_message_callback)
+    : raw_message_callback_(raw_message_callback) {
 }
 
 DevToolsProtocolClient::~DevToolsProtocolClient() {
@@ -18,12 +16,18 @@
 
 void DevToolsProtocolClient::SendNotification(const std::string& method,
                                               base::DictionaryValue* params) {
-  event_callback_.Run(method, params);
+  scoped_refptr<DevToolsProtocol::Notification> notification =
+      new DevToolsProtocol::Notification(method, params);
+  SendRawMessage(notification->Serialize());
 }
 
 void DevToolsProtocolClient::SendAsyncResponse(
     scoped_refptr<DevToolsProtocol::Response> response) {
-  response_callback_.Run(response);
+  SendRawMessage(response->Serialize());
+}
+
+void DevToolsProtocolClient::SendRawMessage(const std::string& message) {
+  raw_message_callback_.Run(message);
 }
 
 void DevToolsProtocolClient::SendInvalidParamsResponse(
diff --git a/content/browser/devtools/protocol/devtools_protocol_client.h b/content/browser/devtools/protocol/devtools_protocol_client.h
index b2f95b71..620a7c1 100644
--- a/content/browser/devtools/protocol/devtools_protocol_client.h
+++ b/content/browser/devtools/protocol/devtools_protocol_client.h
@@ -11,11 +11,8 @@
 
 class DevToolsProtocolClient {
  public:
-  typedef base::Callback<void(const std::string& event,
-                              base::DictionaryValue* params)> EventCallback;
-
-  typedef base::Callback<void(scoped_refptr<DevToolsProtocol::Response>)>
-      ResponseCallback;
+  typedef base::Callback<void(const std::string& message)>
+      RawMessageCallback;
 
   enum ResponseStatus {
     RESPONSE_STATUS_FALLTHROUGH,
@@ -53,9 +50,12 @@
       scoped_refptr<DevToolsProtocol::Command> command,
       const std::string& message);
 
+  // Sends message to client, the caller is presumed to properly
+  // format the message. Do not use unless you must.
+  void SendRawMessage(const std::string& message);
+
  protected:
-  DevToolsProtocolClient(const EventCallback& event_callback,
-                         const ResponseCallback& response_callback);
+  DevToolsProtocolClient(const RawMessageCallback& raw_message_callback);
 
   virtual ~DevToolsProtocolClient();
 
@@ -65,8 +65,7 @@
   void SendAsyncResponse(scoped_refptr<DevToolsProtocol::Response> response);
 
  private:
-  EventCallback event_callback_;
-  ResponseCallback response_callback_;
+  RawMessageCallback raw_message_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(DevToolsProtocolClient);
 };
diff --git a/content/browser/devtools/protocol/devtools_protocol_handler_generator.py b/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
index 6aa39f8d..dd165fa 100755
--- a/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
+++ b/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
@@ -120,8 +120,7 @@
 namespace ${domain} {
 class Client : public DevToolsProtocolClient {
  public:
-  Client(const EventCallback& event_callback,
-         const ResponseCallback& response_callback);
+  Client(const RawMessageCallback& raw_message_callback);
   virtual ~Client();
 
 ${methods}\
@@ -246,9 +245,7 @@
 tmpl_init_client = string.Template("""\
   ${domain}_handler_->SetClient(make_scoped_ptr(
       new devtools::${domain}::Client(
-          base::Bind(&DevToolsProtocolHandlerImpl::SendNotification,
-                     base::Unretained(this)),
-          base::Bind(&DevToolsProtocolHandlerImpl::SendAsyncResponse,
+          base::Bind(&DevToolsProtocolHandlerImpl::SendRawMessage,
                      base::Unretained(this)))));
 """)
 
@@ -358,9 +355,8 @@
 tmpl_client_impl = string.Template("""\
 namespace ${domain} {
 
-Client::Client(const EventCallback& event_callback,
-               const ResponseCallback& response_callback)
-    : DevToolsProtocolClient(event_callback, response_callback) {
+Client::Client(const RawMessageCallback& raw_message_callback)
+    : DevToolsProtocolClient(raw_message_callback) {
 }
 
 Client::~Client() {
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc
index f4ce95b8..3db5629 100644
--- a/content/browser/devtools/protocol/tracing_handler.cc
+++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -4,13 +4,55 @@
 
 #include "content/browser/devtools/protocol/tracing_handler.h"
 
+#include <cmath>
+
+#include "base/bind.h"
+#include "base/debug/trace_event_impl.h"
+#include "base/strings/string_split.h"
+#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+
 namespace content {
 namespace devtools {
 namespace tracing {
 
 typedef DevToolsProtocolClient::Response Response;
 
-TracingHandler::TracingHandler() {
+namespace {
+
+const char kRecordUntilFull[]   = "record-until-full";
+const char kRecordContinuously[] = "record-continuously";
+const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible";
+const char kEnableSampling[] = "enable-sampling";
+const double kMinimumReportingInterval = 250.0;
+
+class DevToolsTraceSinkProxy : public TracingController::TraceDataSink {
+ public:
+  explicit DevToolsTraceSinkProxy(base::WeakPtr<TracingHandler> handler)
+      : tracing_handler_(handler) {}
+
+  virtual void AddTraceChunk(const std::string& chunk) override {
+    if (TracingHandler* h = tracing_handler_.get())
+      h->OnTraceDataCollected(chunk);
+  }
+  virtual void Close() override {
+    if (TracingHandler* h = tracing_handler_.get())
+      h->OnTraceComplete();
+  }
+
+ private:
+  virtual ~DevToolsTraceSinkProxy() {}
+
+  base::WeakPtr<TracingHandler> tracing_handler_;
+};
+
+}  // namespace
+
+TracingHandler::TracingHandler(TracingHandler::Target target)
+    : target_(target),
+      is_recording_(false),
+      weak_factory_(this) {
 }
 
 TracingHandler::~TracingHandler() {
@@ -20,30 +62,152 @@
   client_.swap(client);
 }
 
-scoped_refptr<DevToolsProtocol::Response> TracingHandler::Start(
-    const std::string& categories,
-    const std::string& options,
-    const double* buffer_usage_reporting_interval,
-    scoped_refptr<DevToolsProtocol::Command> command) {
-  return NULL;
+void TracingHandler::Detached() {
+  if (is_recording_)
+    DisableRecording(true);
+}
+
+void TracingHandler::OnTraceDataCollected(const std::string& trace_fragment) {
+  // Hand-craft protocol notification message so we can substitute JSON
+  // that we already got as string as a bare object, not a quoted string.
+  std::string message(
+      "{ \"method\": \"Tracing.dataCollected\", \"params\": { \"value\": [");
+  const size_t messageSuffixSize = 10;
+  message.reserve(message.size() + trace_fragment.size() + messageSuffixSize);
+  message += trace_fragment;
+  message += "] } }";
+  client_->SendRawMessage(message);
+}
+
+void TracingHandler::OnTraceComplete() {
+  TracingCompleteParams params;
+  client_->TracingComplete(params);
 }
 
 scoped_refptr<DevToolsProtocol::Response> TracingHandler::Start(
     const std::string* categories,
-    const std::string* options,
+    const std::string* options_str,
     const double* buffer_usage_reporting_interval,
     scoped_refptr<DevToolsProtocol::Command> command) {
-  return NULL;
+  if (is_recording_)
+    return command->InternalErrorResponse("Tracing is already started");
+  is_recording_ = true;
+
+  base::debug::TraceOptions options = TraceOptionsFromString(options_str);
+  base::debug::CategoryFilter filter(categories ? *categories : std::string());
+  if (buffer_usage_reporting_interval)
+    SetupTimer(*buffer_usage_reporting_interval);
+
+  // If inspected target is a render process Tracing.start will be handled by
+  // tracing agent in the renderer.
+  if (target_ == Renderer) {
+    TracingController::GetInstance()->EnableRecording(
+        filter,
+        options,
+        TracingController::EnableRecordingDoneCallback());
+    return nullptr;
+  }
+
+  TracingController::GetInstance()->EnableRecording(
+      filter,
+      options,
+      base::Bind(&TracingHandler::OnRecordingEnabled,
+                 weak_factory_.GetWeakPtr(),
+                 command));
+  return command->AsyncResponsePromise();
 }
 
 scoped_refptr<DevToolsProtocol::Response> TracingHandler::End(
     scoped_refptr<DevToolsProtocol::Command> command) {
-  return NULL;
+  if (!is_recording_)
+    return command->InternalErrorResponse("Tracing is not started");
+  DisableRecording(false);
+  // If inspected target is a render process Tracing.end will be handled by
+  // tracing agent in the renderer.
+  if (target_ == Renderer)
+    return nullptr;
+  return command->SuccessResponse(nullptr);
 }
 
 scoped_refptr<DevToolsProtocol::Response> TracingHandler::GetCategories(
     scoped_refptr<DevToolsProtocol::Command> command) {
-  return NULL;
+  TracingController::GetInstance()->GetCategories(
+      base::Bind(&TracingHandler::OnCategoriesReceived,
+                 weak_factory_.GetWeakPtr(),
+                 command));
+  return command->AsyncResponsePromise();
+}
+
+void TracingHandler::OnRecordingEnabled(
+    scoped_refptr<DevToolsProtocol::Command> command) {
+  StartResponse response;
+  client_->SendStartResponse(command, response);
+}
+
+void TracingHandler::OnBufferUsage(float usage) {
+  BufferUsageParams params;
+  params.set_value(usage);
+  client_->BufferUsage(params);
+}
+
+void TracingHandler::OnCategoriesReceived(
+    scoped_refptr<DevToolsProtocol::Command> command,
+    const std::set<std::string>& category_set) {
+  std::vector<std::string> categories(category_set.begin(), category_set.end());
+  GetCategoriesResponse response;
+  response.set_categories(categories);
+  client_->SendGetCategoriesResponse(command, response);
+}
+
+base::debug::TraceOptions TracingHandler::TraceOptionsFromString(
+    const std::string* options) {
+  base::debug::TraceOptions ret;
+  if (!options)
+    return ret;
+
+  std::vector<std::string> split;
+  std::vector<std::string>::iterator iter;
+
+  base::SplitString(*options, ',', &split);
+  for (iter = split.begin(); iter != split.end(); ++iter) {
+    if (*iter == kRecordUntilFull) {
+      ret.record_mode = base::debug::RECORD_UNTIL_FULL;
+    } else if (*iter == kRecordContinuously) {
+      ret.record_mode = base::debug::RECORD_CONTINUOUSLY;
+    } else if (*iter == kRecordAsMuchAsPossible) {
+      ret.record_mode = base::debug::RECORD_AS_MUCH_AS_POSSIBLE;
+    } else if (*iter == kEnableSampling) {
+      ret.enable_sampling = true;
+    }
+  }
+  return ret;
+}
+
+void TracingHandler::SetupTimer(double usage_reporting_interval) {
+  if (usage_reporting_interval == 0) return;
+
+  if (usage_reporting_interval < kMinimumReportingInterval)
+      usage_reporting_interval = kMinimumReportingInterval;
+
+  base::TimeDelta interval = base::TimeDelta::FromMilliseconds(
+      std::ceil(usage_reporting_interval));
+  buffer_usage_poll_timer_.reset(new base::Timer(
+      FROM_HERE,
+      interval,
+      base::Bind(
+          base::IgnoreResult(&TracingController::GetTraceBufferPercentFull),
+          base::Unretained(TracingController::GetInstance()),
+          base::Bind(&TracingHandler::OnBufferUsage,
+                     weak_factory_.GetWeakPtr())),
+      true));
+  buffer_usage_poll_timer_->Reset();
+}
+
+void TracingHandler::DisableRecording(bool abort) {
+  is_recording_ = false;
+  buffer_usage_poll_timer_.reset();
+  TracingController::GetInstance()->DisableRecording(
+      abort ? nullptr : new DevToolsTraceSinkProxy(weak_factory_.GetWeakPtr()));
 }
 
 }  // namespace tracing
diff --git a/content/browser/devtools/protocol/tracing_handler.h b/content/browser/devtools/protocol/tracing_handler.h
index c629188..b20e585 100644
--- a/content/browser/devtools/protocol/tracing_handler.h
+++ b/content/browser/devtools/protocol/tracing_handler.h
@@ -5,7 +5,18 @@
 #ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TRACING_HANDLER_H_
 #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TRACING_HANDLER_H_
 
+#include <set>
+#include <string>
+
+#include "base/debug/trace_event.h"
+#include "base/memory/weak_ptr.h"
 #include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h"
+#include "content/public/browser/tracing_controller.h"
+
+namespace base {
+class RefCountedString;
+class Timer;
+}
 
 namespace content {
 namespace devtools {
@@ -15,16 +26,16 @@
  public:
   typedef DevToolsProtocolClient::Response Response;
 
-  TracingHandler();
+  enum Target { Browser, Renderer };
+  explicit TracingHandler(Target target);
   virtual ~TracingHandler();
 
   void SetClient(scoped_ptr<Client> client);
+  void Detached();
 
-  scoped_refptr<DevToolsProtocol::Response> Start(
-      const std::string& categories,
-      const std::string& options,
-      const double* buffer_usage_reporting_interval,
-      scoped_refptr<DevToolsProtocol::Command> command);
+  void OnTraceDataCollected(const std::string& trace_fragment);
+  void OnTraceComplete();
+
   scoped_refptr<DevToolsProtocol::Response> Start(
       const std::string* categories,
       const std::string* options,
@@ -33,12 +44,28 @@
 
   scoped_refptr<DevToolsProtocol::Response> End(
       scoped_refptr<DevToolsProtocol::Command> command);
-
   scoped_refptr<DevToolsProtocol::Response> GetCategories(
       scoped_refptr<DevToolsProtocol::Command> command);
 
  private:
+  void OnRecordingEnabled(scoped_refptr<DevToolsProtocol::Command> command);
+  void OnBufferUsage(float usage);
+
+  void OnCategoriesReceived(scoped_refptr<DevToolsProtocol::Command> command,
+                            const std::set<std::string>& category_set);
+
+  base::debug::TraceOptions TraceOptionsFromString(const std::string* options);
+
+  void SetupTimer(double usage_reporting_interval);
+
+  void DisableRecording(bool abort);
+
+  scoped_ptr<base::Timer> buffer_usage_poll_timer_;
+  Target target_;
+  bool is_recording_;
+
   scoped_ptr<Client> client_;
+  base::WeakPtrFactory<TracingHandler> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(TracingHandler);
 };
diff --git a/content/browser/devtools/render_view_devtools_agent_host.cc b/content/browser/devtools/render_view_devtools_agent_host.cc
index 2aafc38..5115ba21 100644
--- a/content/browser/devtools/render_view_devtools_agent_host.cc
+++ b/content/browser/devtools/render_view_devtools_agent_host.cc
@@ -11,8 +11,13 @@
 #include "content/browser/devtools/devtools_manager.h"
 #include "content/browser/devtools/devtools_protocol.h"
 #include "content/browser/devtools/devtools_protocol_constants.h"
-#include "content/browser/devtools/devtools_tracing_handler.h"
 #include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h"
+#include "content/browser/devtools/protocol/dom_handler.h"
+#include "content/browser/devtools/protocol/input_handler.h"
+#include "content/browser/devtools/protocol/network_handler.h"
+#include "content/browser/devtools/protocol/page_handler.h"
+#include "content/browser/devtools/protocol/power_handler.h"
+#include "content/browser/devtools/protocol/tracing_handler.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/site_instance_impl.h"
@@ -113,21 +118,21 @@
       network_handler_(new devtools::network::NetworkHandler()),
       page_handler_(new devtools::page::PageHandler()),
       power_handler_(new devtools::power::PowerHandler()),
+      tracing_handler_(new devtools::tracing::TracingHandler(
+          devtools::tracing::TracingHandler::Renderer)),
       handler_impl_(new DevToolsProtocolHandlerImpl()),
-      tracing_handler_(
-          new DevToolsTracingHandler(DevToolsTracingHandler::Renderer)),
       reattaching_(false) {
   handler_impl_->SetDOMHandler(dom_handler_.get());
   handler_impl_->SetInputHandler(input_handler_.get());
   handler_impl_->SetNetworkHandler(network_handler_.get());
   handler_impl_->SetPageHandler(page_handler_.get());
   handler_impl_->SetPowerHandler(power_handler_.get());
+  handler_impl_->SetTracingHandler(tracing_handler_.get());
   SetRenderViewHost(rvh);
   DevToolsProtocol::Notifier notifier(base::Bind(
       &RenderViewDevToolsAgentHost::DispatchOnInspectorFrontend,
       base::Unretained(this)));
   handler_impl_->SetNotifier(notifier);
-  tracing_handler_->SetNotifier(notifier);
   g_instances.Get().push_back(this);
   AddRef();  // Balanced in RenderViewHostDestroyed.
   DevToolsManager::GetInstance()->AgentHostChanged(this);
@@ -159,8 +164,6 @@
             overridden_response_value.get());
     }
     if (!overridden_response.get())
-      overridden_response = tracing_handler_->HandleCommand(command);
-    if (!overridden_response.get())
       overridden_response = handler_impl_->HandleCommand(command);
     if (overridden_response.get()) {
       if (!overridden_response->is_async_promise())
@@ -212,9 +215,9 @@
 #if defined(OS_ANDROID)
   power_save_blocker_.reset();
 #endif
-  tracing_handler_->OnClientDetached();
   page_handler_->Detached();
   power_handler_->Detached();
+  tracing_handler_->Detached();
   ClientDetachedFromRenderer();
 
   // TODO(kaznacheev): Move this call back to DevToolsManager when
diff --git a/content/browser/devtools/render_view_devtools_agent_host.h b/content/browser/devtools/render_view_devtools_agent_host.h
index 0f4208f..204d87e8 100644
--- a/content/browser/devtools/render_view_devtools_agent_host.h
+++ b/content/browser/devtools/render_view_devtools_agent_host.h
@@ -11,11 +11,6 @@
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "content/browser/devtools/ipc_devtools_agent_host.h"
-#include "content/browser/devtools/protocol/dom_handler.h"
-#include "content/browser/devtools/protocol/input_handler.h"
-#include "content/browser/devtools/protocol/network_handler.h"
-#include "content/browser/devtools/protocol/page_handler.h"
-#include "content/browser/devtools/protocol/power_handler.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -28,7 +23,6 @@
 namespace content {
 
 class DevToolsProtocolHandlerImpl;
-class DevToolsTracingHandler;
 class RenderViewHost;
 class RenderViewHostImpl;
 
@@ -36,6 +30,15 @@
 class PowerSaveBlockerImpl;
 #endif
 
+namespace devtools {
+namespace dom { class DOMHandler; }
+namespace input { class InputHandler; }
+namespace network { class NetworkHandler; }
+namespace page { class PageHandler; }
+namespace power { class PowerHandler; }
+namespace tracing { class TracingHandler; }
+}
+
 class CONTENT_EXPORT RenderViewDevToolsAgentHost
     : public IPCDevToolsAgentHost,
       private WebContentsObserver,
@@ -118,8 +121,8 @@
   scoped_ptr<devtools::network::NetworkHandler> network_handler_;
   scoped_ptr<devtools::page::PageHandler> page_handler_;
   scoped_ptr<devtools::power::PowerHandler> power_handler_;
+  scoped_ptr<devtools::tracing::TracingHandler> tracing_handler_;
   scoped_ptr<DevToolsProtocolHandlerImpl> handler_impl_;
-  scoped_ptr<DevToolsTracingHandler> tracing_handler_;
 #if defined(OS_ANDROID)
   scoped_ptr<PowerSaveBlockerImpl> power_save_blocker_;
 #endif
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc
index 90c1f8d..27ed57f 100644
--- a/content/browser/frame_host/frame_tree.cc
+++ b/content/browser/frame_host/frame_tree.cc
@@ -54,7 +54,12 @@
 
 bool CreateProxyForSiteInstance(const scoped_refptr<SiteInstance>& instance,
                                 FrameTreeNode* node) {
-  node->render_manager()->CreateRenderFrameProxy(instance.get());
+  // If a new frame is created in the current SiteInstance, other frames in
+  // that SiteInstance don't need a proxy for the new frame.
+  SiteInstance* current_instance =
+      node->render_manager()->current_frame_host()->GetSiteInstance();
+  if (current_instance != instance.get())
+    node->render_manager()->CreateRenderFrameProxy(instance.get());
   return true;
 }
 
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 584f950b..c5b67b4 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -887,7 +887,6 @@
                                     navigation_data_->start_time_ -
                                     navigation_data_->before_unload_delay_;
   if (navigation_data_->is_restoring_from_last_session_) {
-    DCHECK(!navigation_data_->before_unload_delay_.InMicroseconds());
     UMA_HISTOGRAM_TIMES(
         "Navigation.TimeToCommit_SessionRestored",
         time_to_commit);
@@ -897,10 +896,9 @@
     navigation_data_.reset();
     return;
   }
-  RenderProcessHostImpl* process_host =
-      static_cast<RenderProcessHostImpl*>(site_instance->GetProcess());
   bool navigation_created_new_renderer_process =
-      process_host->init_time() > navigation_data_->start_time_;
+      site_instance->GetProcess()->GetInitTimeForNavigationMetrics() >
+      navigation_data_->start_time_;
   if (navigation_created_new_renderer_process) {
     UMA_HISTOGRAM_TIMES(
         "Navigation.TimeToCommit_NewRenderer_BeforeUnloadDiscounted",
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index bd837fa..1f22880 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -70,6 +70,9 @@
 
 namespace {
 
+// The next value to use for the accessibility reset token.
+int g_next_accessibility_reset_token = 1;
+
 // The (process id, routing id) pair that identifies one RenderFrame.
 typedef std::pair<int32, int32> RenderFrameHostID;
 typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*>
@@ -189,6 +192,9 @@
       navigations_suspended_(false),
       is_waiting_for_beforeunload_ack_(false),
       unload_ack_is_for_cross_site_transition_(false),
+      accessibility_reset_token_(0),
+      accessibility_reset_count_(0),
+      no_create_browser_accessibility_manager_for_testing_(false),
       weak_ptr_factory_(this) {
   frame_tree_->RegisterRenderFrameHost(this);
   GetProcess()->AddRoute(routing_id_, this);
@@ -479,8 +485,18 @@
 }
 
 void RenderFrameHostImpl::AccessibilityFatalError() {
-  Send(new AccessibilityMsg_FatalError(routing_id_));
   browser_accessibility_manager_.reset(NULL);
+  if (accessibility_reset_token_)
+    return;
+
+  accessibility_reset_count_++;
+  if (accessibility_reset_count_ >= kMaxAccessibilityResets) {
+    Send(new AccessibilityMsg_FatalError(routing_id_));
+  } else {
+    accessibility_reset_token_ = g_next_accessibility_reset_token++;
+    UMA_HISTOGRAM_COUNTS("Accessibility.FrameResetCount", 1);
+    Send(new AccessibilityMsg_Reset(routing_id_, accessibility_reset_token_));
+  }
 }
 
 gfx::AcceleratedWidget
@@ -707,8 +723,8 @@
   if (is_waiting_for_beforeunload_ack_ &&
       unload_ack_is_for_cross_site_transition_ &&
       ui::PageTransitionIsMainFrame(validated_params.transition)) {
-    OnBeforeUnloadACK(true, send_before_unload_start_time_,
-                      base::TimeTicks::Now());
+    base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_;
+    OnBeforeUnloadACK(true, approx_renderer_start_time, base::TimeTicks::Now());
     return;
   }
 
@@ -756,6 +772,7 @@
     return;
   }
 
+  accessibility_reset_count_ = 0;
   frame_tree_node()->navigator()->DidNavigate(this, validated_params);
 }
 
@@ -830,16 +847,7 @@
     const base::TimeTicks& renderer_before_unload_end_time) {
   TRACE_EVENT_ASYNC_END0(
       "navigation", "RenderFrameHostImpl::BeforeUnload", this);
-  // TODO(creis): Support beforeunload on subframes.  For now just pretend that
-  // the handler ran and allowed the navigation to proceed.
-  if (GetParent()) {
-    is_waiting_for_beforeunload_ack_ = false;
-    frame_tree_node_->render_manager()->OnBeforeUnloadACK(
-        unload_ack_is_for_cross_site_transition_, proceed,
-        renderer_before_unload_end_time);
-    return;
-  }
-
+  DCHECK(!GetParent());
   render_view_host_->decrement_in_flight_event_count();
   render_view_host_->StopHangMonitorTimeout();
   // If this renderer navigated while the beforeunload request was in flight, we
@@ -853,20 +861,21 @@
   if (!is_waiting_for_beforeunload_ack_) {
     return;
   }
+  DCHECK(!send_before_unload_start_time_.is_null());
 
-  is_waiting_for_beforeunload_ack_ = false;
-
-  base::TimeTicks before_unload_end_time;
-  if (!send_before_unload_start_time_.is_null() &&
-      !renderer_before_unload_start_time.is_null() &&
+  // Sets a default value for before_unload_end_time so that the browser
+  // survives a hacked renderer.
+  base::TimeTicks before_unload_end_time = renderer_before_unload_end_time;
+  if (!renderer_before_unload_start_time.is_null() &&
       !renderer_before_unload_end_time.is_null()) {
     // When passing TimeTicks across process boundaries, we need to compensate
     // for any skew between the processes. Here we are converting the
     // renderer's notion of before_unload_end_time to TimeTicks in the browser
     // process. See comments in inter_process_time_ticks_converter.h for more.
+    base::TimeTicks receive_before_unload_ack_time = base::TimeTicks::Now();
     InterProcessTimeTicksConverter converter(
         LocalTimeTicks::FromTimeTicks(send_before_unload_start_time_),
-        LocalTimeTicks::FromTimeTicks(base::TimeTicks::Now()),
+        LocalTimeTicks::FromTimeTicks(receive_before_unload_ack_time),
         RemoteTimeTicks::FromTimeTicks(renderer_before_unload_start_time),
         RemoteTimeTicks::FromTimeTicks(renderer_before_unload_end_time));
     LocalTimeTicks browser_before_unload_end_time =
@@ -891,9 +900,19 @@
         "InterProcessTimeTicks.IsSkewAdditive_RendererToBrowser",
         is_skew_additive);
 
+    base::TimeDelta on_before_unload_overhead_time =
+        (receive_before_unload_ack_time - send_before_unload_start_time_) -
+        (renderer_before_unload_end_time - renderer_before_unload_start_time);
+    UMA_HISTOGRAM_TIMES("Navigation.OnBeforeUnloadOverheadTime",
+                        on_before_unload_overhead_time);
+
     frame_tree_node_->navigator()->LogBeforeUnloadTime(
         renderer_before_unload_start_time, renderer_before_unload_end_time);
   }
+  // Resets beforeunload waiting state.
+  is_waiting_for_beforeunload_ack_ = false;
+  send_before_unload_start_time_ = base::TimeTicks();
+
   frame_tree_node_->render_manager()->OnBeforeUnloadACK(
       unload_ack_is_for_cross_site_transition_, proceed,
       before_unload_end_time);
@@ -1051,7 +1070,6 @@
     int32 page_id,
     const base::string16& title,
     blink::WebTextDirection title_direction) {
-  CHECK_EQ(render_view_host_->page_id_, page_id);
   // This message is only sent for top-level frames. TODO(avi): when frame tree
   // mirroring works correctly, add a check here to enforce it.
   if (title.length() > kMaxTitleChars) {
@@ -1080,7 +1098,17 @@
 }
 
 void RenderFrameHostImpl::OnAccessibilityEvents(
-    const std::vector<AccessibilityHostMsg_EventParams>& params) {
+    const std::vector<AccessibilityHostMsg_EventParams>& params,
+    int reset_token) {
+  // Don't process this IPC if either we're waiting on a reset and this
+  // IPC doesn't have the matching token ID, or if we're not waiting on a
+  // reset but this message includes a reset token.
+  if (accessibility_reset_token_ != reset_token) {
+    Send(new AccessibilityMsg_Events_ACK(routing_id_));
+    return;
+  }
+  accessibility_reset_token_ = 0;
+
   RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
       render_view_host_->GetView());
 
@@ -1155,17 +1183,18 @@
 
 void RenderFrameHostImpl::OnAccessibilityLocationChanges(
     const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) {
+  if (accessibility_reset_token_)
+    return;
+
   RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
       render_view_host_->GetView());
   if (view && RenderFrameHostImpl::IsRFHStateActive(rfh_state())) {
     AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode();
     if (accessibility_mode & AccessibilityModeFlagPlatform) {
-      if (!browser_accessibility_manager_) {
-        browser_accessibility_manager_.reset(
-            view->CreateBrowserAccessibilityManager(this));
-      }
-      if (browser_accessibility_manager_)
-        browser_accessibility_manager_->OnLocationChanges(params);
+      BrowserAccessibilityManager* manager =
+          GetOrCreateBrowserAccessibilityManager();
+      if (manager)
+        manager->OnLocationChanges(params);
     }
     // TODO(aboxhall): send location change events to web contents observers too
   }
@@ -1225,6 +1254,7 @@
       rfh_state_ == STATE_DEFAULT ||
       rfh_state_ == STATE_SWAPPED_OUT) {
     is_waiting_for_beforeunload_ack_ = false;
+    send_before_unload_start_time_ = base::TimeTicks();
     render_view_host_->is_waiting_for_close_ack_ = false;
   }
   rfh_state_ = rfh_state;
@@ -1309,17 +1339,16 @@
 }
 
 void RenderFrameHostImpl::DispatchBeforeUnload(bool for_cross_site_transition) {
-  TRACE_EVENT_ASYNC_BEGIN0(
-      "navigation", "RenderFrameHostImpl::BeforeUnload", this);
-  // TODO(creis): Support subframes.
+  // TODO(creis): Support beforeunload on subframes.  For now just pretend that
+  // the handler ran and allowed the navigation to proceed.
   if (GetParent() || !IsRenderFrameLive()) {
     // We don't have a live renderer, so just skip running beforeunload.
-    is_waiting_for_beforeunload_ack_ = true;
-    unload_ack_is_for_cross_site_transition_ = for_cross_site_transition;
-    base::TimeTicks now = base::TimeTicks::Now();
-    OnBeforeUnloadACK(true, now, now);
+    frame_tree_node_->render_manager()->OnBeforeUnloadACK(
+        for_cross_site_transition, true, base::TimeTicks::Now());
     return;
   }
+  TRACE_EVENT_ASYNC_BEGIN0(
+      "navigation", "RenderFrameHostImpl::BeforeUnload", this);
 
   // This may be called more than once (if the user clicks the tab close button
   // several times, or if she clicks the tab close button then the browser close
@@ -1473,9 +1502,14 @@
   RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
       render_view_host_->GetView());
   if (view &&
-      !browser_accessibility_manager_) {
+      !browser_accessibility_manager_ &&
+      !no_create_browser_accessibility_manager_for_testing_) {
     browser_accessibility_manager_.reset(
         view->CreateBrowserAccessibilityManager(this));
+    if (browser_accessibility_manager_)
+      UMA_HISTOGRAM_COUNTS("Accessibility.FrameEnabledCount", 1);
+    else
+      UMA_HISTOGRAM_COUNTS("Accessibility.FrameDidNotEnableCount", 1);
   }
   return browser_accessibility_manager_.get();
 }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 3fcb8e2f..ea159cb 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -93,6 +93,11 @@
   // number of active frames of a SiteInstance or not.
   static bool IsRFHStateActive(RenderFrameHostImplState rfh_state);
 
+  // An accessibility reset is only allowed to prevent very rare corner cases
+  // or race conditions where the browser and renderer get out of sync. If
+  // this happens more than this many times, kill the renderer.
+  static const int kMaxAccessibilityResets = 5;
+
   static RenderFrameHostImpl* FromID(int process_id, int routing_id);
 
   ~RenderFrameHostImpl() override;
@@ -334,6 +339,10 @@
   // NULL.
   BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager();
 
+  void set_no_create_browser_accessibility_manager_for_testing(bool flag) {
+    no_create_browser_accessibility_manager_for_testing_ = flag;
+  }
+
 #if defined(OS_WIN)
   void SetParentNativeViewAccessible(
       gfx::NativeViewAccessible accessible_parent);
@@ -426,7 +435,8 @@
   void OnBeginNavigation(const FrameHostMsg_BeginNavigation_Params& params,
                          const CommonNavigationParams& common_params);
   void OnAccessibilityEvents(
-      const std::vector<AccessibilityHostMsg_EventParams>& params);
+      const std::vector<AccessibilityHostMsg_EventParams>& params,
+      int reset_token);
   void OnAccessibilityLocationChanges(
       const std::vector<AccessibilityHostMsg_LocationChangeParams>& params);
 
@@ -554,12 +564,25 @@
   scoped_ptr<ServiceRegistryAndroid> service_registry_android_;
 #endif
 
+  // The object managing the accessibility tree for this frame.
   scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_;
 
+  // This is nonzero if we sent an accessibility reset to the renderer and
+  // we're waiting for an IPC containing this reset token (sequentially
+  // assigned) and a complete replacement accessibility tree.
+  int accessibility_reset_token_;
+
+  // A count of the number of times we needed to reset accessibility, so
+  // we don't keep trying to reset forever.
+  int accessibility_reset_count_;
+
   // Callback when an event is received, for testing.
   base::Callback<void(ui::AXEvent, int)> accessibility_testing_callback_;
   // The most recently received accessibility tree - for testing only.
   scoped_ptr<ui::AXTree> ax_tree_for_testing_;
+  // Flag to not create a BrowserAccessibilityManager, for testing. If one
+  // already exists it will still be used.
+  bool no_create_browser_accessibility_manager_for_testing_;
 
   // PlzNavigate: Owns the stream used in navigations to store the body of the
   // response once it has started.
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index 37997ac2..39799b9c 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -690,7 +690,9 @@
 
   // For security, we should transition between processes when one is a Web UI
   // page and one isn't.
-  if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
+  if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+          render_frame_host_->GetProcess()->GetID()) ||
+      WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
           browser_context, current_effective_url)) {
     // If so, force a swap if destination is not an acceptable URL for Web UI.
     // Here, data URLs are never allowed.
@@ -747,7 +749,8 @@
   SiteInstance* new_instance = current_instance;
 
   // We do not currently swap processes for navigations in webview tag guests.
-  bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme);
+  if (current_instance->GetSiteURL().SchemeIs(kGuestScheme))
+    return current_instance;
 
   // Determine if we need a new BrowsingInstance for this entry.  If true, this
   // implies that it will get a new SiteInstance (and likely process), and that
@@ -765,14 +768,13 @@
       render_frame_host_->GetSiteInstance()->GetSiteURL();
   bool current_is_view_source_mode = current_entry ?
       current_entry->IsViewSourceMode() : dest_is_view_source_mode;
-  bool force_swap = !is_guest_scheme &&
-      ShouldSwapBrowsingInstancesForNavigation(
-          current_effective_url,
-          current_is_view_source_mode,
-          dest_instance,
-          SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url),
-          dest_is_view_source_mode);
-  if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) {
+  bool force_swap = ShouldSwapBrowsingInstancesForNavigation(
+      current_effective_url,
+      current_is_view_source_mode,
+      dest_instance,
+      SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url),
+      dest_is_view_source_mode);
+  if (ShouldTransitionCrossSite() || force_swap) {
     new_instance = GetSiteInstanceForURL(
         dest_url,
         dest_instance,
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
index 38eef8ce..9ae4cb3 100644
--- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -1473,4 +1473,27 @@
       new_web_contents->GetRenderViewHost()->GetEnabledBindings());
 }
 
+// crbug.com/424526
+// The test loads a WebUI page in rocess-per-tab mode, then navigates to a blank
+// page and then to a regular page. The bug reproduces if blank page is visited
+// in between WebUI and regular page.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+                       ForceSwapAfterWebUIBindings) {
+  CommandLine::ForCurrentProcess()->AppendSwitch(switches::kProcessPerTab);
+  ASSERT_TRUE(test_server()->Start());
+
+  const GURL web_ui_url(std::string(kChromeUIScheme) + "://" +
+                        std::string(kChromeUIGpuHost));
+  NavigateToURL(shell(), web_ui_url);
+  EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+      shell()->web_contents()->GetRenderProcessHost()->GetID()));
+
+  NavigateToURL(shell(), GURL(url::kAboutBlankURL));
+
+  GURL regular_page_url(test_server()->GetURL("files/title2.html"));
+  NavigateToURL(shell(), regular_page_url);
+  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+      shell()->web_contents()->GetRenderProcessHost()->GetID()));
+}
+
 }  // namespace content
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc
index ba0c94a0..42e20de 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -91,7 +91,7 @@
   return NULL;
 }
 
-void RenderWidgetHostViewChildFrame::SetBackgroundOpaque(bool opaque) {
+void RenderWidgetHostViewChildFrame::SetBackgroundColor(SkColor color) {
 }
 
 gfx::Size RenderWidgetHostViewChildFrame::GetPhysicalBackingSize() const {
@@ -153,7 +153,8 @@
 void RenderWidgetHostViewChildFrame::TextInputTypeChanged(
     ui::TextInputType type,
     ui::TextInputMode input_mode,
-    bool can_compose_inline) {
+    bool can_compose_inline,
+    int flags) {
   NOTREACHED();
 }
 
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h
index 4774d55..b61982e 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.h
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -51,7 +51,7 @@
   gfx::NativeView GetNativeView() const override;
   gfx::NativeViewId GetNativeViewId() const override;
   gfx::NativeViewAccessible GetNativeViewAccessible() override;
-  void SetBackgroundOpaque(bool opaque) override;
+  void SetBackgroundColor(SkColor color) override;
   gfx::Size GetPhysicalBackingSize() const override;
 
   // RenderWidgetHostViewBase implementation.
@@ -66,7 +66,8 @@
   void SetIsLoading(bool is_loading) override;
   void TextInputTypeChanged(ui::TextInputType type,
                             ui::TextInputMode input_mode,
-                            bool can_compose_inline) override;
+                            bool can_compose_inline,
+                            int flags) override;
   void ImeCancelComposition() override;
 #if defined(OS_MACOSX) || defined(USE_AURA)
   void ImeCompositionRangeChanged(
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc
index 20782e8..4804315 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.cc
+++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -284,7 +284,8 @@
 void RenderWidgetHostViewGuest::TextInputTypeChanged(
     ui::TextInputType type,
     ui::TextInputMode input_mode,
-    bool can_compose_inline) {
+    bool can_compose_inline,
+    int flags) {
   if (!guest_)
     return;
 
@@ -292,7 +293,7 @@
   if (!rwhv)
     return;
   // Forward the information to embedding RWHV.
-  rwhv->TextInputTypeChanged(type, input_mode, can_compose_inline);
+  rwhv->TextInputTypeChanged(type, input_mode, can_compose_inline, flags);
 }
 
 void RenderWidgetHostViewGuest::ImeCancelComposition() {
@@ -358,14 +359,15 @@
   guest_->CopyFromCompositingSurface(src_subrect, dst_size, callback);
 }
 
-void RenderWidgetHostViewGuest::SetBackgroundOpaque(bool opaque) {
+void RenderWidgetHostViewGuest::SetBackgroundColor(SkColor color) {
   // Content embedders can toggle opaque backgrounds through this API.
   // We plumb the value here so that BrowserPlugin updates its compositing
   // state in response to this change. We also want to preserve this flag
   // after recovering from a crash so we let BrowserPluginGuest store it.
   if (!guest_)
     return;
-  RenderWidgetHostViewBase::SetBackgroundOpaque(opaque);
+  RenderWidgetHostViewBase::SetBackgroundColor(color);
+  bool opaque = GetBackgroundOpaque();
   host_->SetBackgroundOpaque(opaque);
   guest_->SetContentsOpaque(opaque);
 }
diff --git a/content/browser/frame_host/render_widget_host_view_guest.h b/content/browser/frame_host/render_widget_host_view_guest.h
index 2d6a880..ba18f7c5 100644
--- a/content/browser/frame_host/render_widget_host_view_guest.h
+++ b/content/browser/frame_host/render_widget_host_view_guest.h
@@ -59,7 +59,7 @@
   gfx::NativeViewId GetNativeViewId() const override;
   gfx::NativeViewAccessible GetNativeViewAccessible() override;
   gfx::Rect GetViewBounds() const override;
-  void SetBackgroundOpaque(bool opaque) override;
+  void SetBackgroundColor(SkColor color) override;
   gfx::Size GetPhysicalBackingSize() const override;
   base::string16 GetSelectedText() const override;
 
@@ -74,7 +74,8 @@
   void SetIsLoading(bool is_loading) override;
   void TextInputTypeChanged(ui::TextInputType type,
                             ui::TextInputMode input_mode,
-                            bool can_compose_inline) override;
+                            bool can_compose_inline,
+                            int flags) override;
   void ImeCancelComposition() override;
 #if defined(OS_MACOSX) || defined(USE_AURA)
   void ImeCompositionRangeChanged(
diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
index a211bb67..e99a5e15 100644
--- a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
+++ b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc
@@ -20,6 +20,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/browser/udev_linux.h"
+#include "device/udev_linux/scoped_udev.h"
 
 namespace {
 
@@ -126,9 +127,7 @@
     // hardware, get the parent device that is also in the "input" subsystem.
     // This function should just walk up the tree one level.
     dev = udev_device_get_parent_with_subsystem_devtype(
-        dev,
-        kInputSubsystem,
-        NULL);
+        dev, kInputSubsystem, NULL);
     if (!dev) {
       // Unable to get device information, don't use this device.
       device_fd = -1;
@@ -156,10 +155,8 @@
     // as good as the information that the device bus has, walk up further
     // to the subsystem/device type "usb"/"usb_device" and if this device
     // has the same vendor/product id, prefer the description from that.
-    struct udev_device *usb_dev = udev_device_get_parent_with_subsystem_devtype(
-        dev,
-        kUsbSubsystem,
-        kUsbDeviceType);
+    struct udev_device* usb_dev = udev_device_get_parent_with_subsystem_devtype(
+        dev, kUsbSubsystem, kUsbDeviceType);
     if (usb_dev) {
       const char* usb_vendor_id =
           udev_device_get_sysattr_value(usb_dev, "idVendor");
@@ -181,11 +178,11 @@
 
     // Append the vendor and product information then convert the utf-8
     // id string to WebUChar.
-    std::string id = name_string + base::StringPrintf(
-        " (%sVendor: %s Product: %s)",
-        mapper ? "STANDARD GAMEPAD " : "",
-        vendor_id,
-        product_id);
+    std::string id =
+        name_string + base::StringPrintf(" (%sVendor: %s Product: %s)",
+                                         mapper ? "STANDARD GAMEPAD " : "",
+                                         vendor_id,
+                                         product_id);
     base::TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id);
     base::string16 tmp16 = base::UTF8ToUTF16(id);
     memset(pad.id, 0, sizeof(pad.id));
@@ -193,8 +190,8 @@
 
     if (mapper) {
       std::string mapping = "standard";
-      base::TruncateUTF8ToByteSize(mapping, WebGamepad::mappingLengthCap - 1,
-          &mapping);
+      base::TruncateUTF8ToByteSize(
+          mapping, WebGamepad::mappingLengthCap - 1, &mapping);
       tmp16 = base::UTF8ToUTF16(mapping);
       memset(pad.mapping, 0, sizeof(pad.mapping));
       tmp16.copy(pad.mapping, arraysize(pad.mapping) - 1);
@@ -207,31 +204,30 @@
 }
 
 void GamepadPlatformDataFetcherLinux::EnumerateDevices() {
-  udev_enumerate* enumerate = udev_enumerate_new(udev_->udev_handle());
+  device::ScopedUdevEnumeratePtr enumerate(
+      udev_enumerate_new(udev_->udev_handle()));
   if (!enumerate)
     return;
-  int ret = udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem);
+  int ret =
+      udev_enumerate_add_match_subsystem(enumerate.get(), kInputSubsystem);
   if (ret != 0)
     return;
-  ret = udev_enumerate_scan_devices(enumerate);
+  ret = udev_enumerate_scan_devices(enumerate.get());
   if (ret != 0)
     return;
 
-  udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate);
-  for (udev_list_entry* dev_list_entry = devices;
-       dev_list_entry != NULL;
+  udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate.get());
+  for (udev_list_entry* dev_list_entry = devices; dev_list_entry != NULL;
        dev_list_entry = udev_list_entry_get_next(dev_list_entry)) {
     // Get the filename of the /sys entry for the device and create a
     // udev_device object (dev) representing it
     const char* path = udev_list_entry_get_name(dev_list_entry);
-    udev_device* dev = udev_device_new_from_syspath(udev_->udev_handle(), path);
+    device::ScopedUdevDevicePtr dev(
+        udev_device_new_from_syspath(udev_->udev_handle(), path));
     if (!dev)
       continue;
-    RefreshDevice(dev);
-    udev_device_unref(dev);
+    RefreshDevice(dev.get());
   }
-  // Free the enumerator object
-  udev_enumerate_unref(enumerate);
 }
 
 void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) {
diff --git a/content/browser/geofencing/geofencing_dispatcher_host.cc b/content/browser/geofencing/geofencing_dispatcher_host.cc
index 077485b..5cae113 100644
--- a/content/browser/geofencing/geofencing_dispatcher_host.cc
+++ b/content/browser/geofencing/geofencing_dispatcher_host.cc
@@ -5,18 +5,20 @@
 #include "content/browser/geofencing/geofencing_dispatcher_host.h"
 
 #include "content/browser/geofencing/geofencing_manager.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_registration.h"
 #include "content/common/geofencing_messages.h"
 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
-#include "url/gurl.h"
 
 namespace content {
 
 static const int kMaxRegionIdLength = 200;
 
 GeofencingDispatcherHost::GeofencingDispatcherHost(
-    BrowserContext* browser_context)
+    GeofencingManager* geofencing_manager)
     : BrowserMessageFilter(GeofencingMsgStart),
-      browser_context_(browser_context),
+      manager_(geofencing_manager),
       weak_factory_(this) {
 }
 
@@ -39,18 +41,17 @@
     int thread_id,
     int request_id,
     const std::string& region_id,
-    const blink::WebCircularGeofencingRegion& region) {
+    const blink::WebCircularGeofencingRegion& region,
+    int64 service_worker_registration_id) {
   // Sanity check on region_id
   if (region_id.length() > kMaxRegionIdLength) {
     Send(new GeofencingMsg_RegisterRegionComplete(
         thread_id, request_id, GeofencingStatus::GEOFENCING_STATUS_ERROR));
     return;
   }
-  // TODO(mek): Actually pass service worker information to manager.
-  GeofencingManager::GetInstance()->RegisterRegion(
-      browser_context_,
-      0,      /* service_worker_registration_id */
-      GURL(), /* service_worker_origin */
+
+  manager_->RegisterRegion(
+      service_worker_registration_id,
       region_id,
       region,
       base::Bind(&GeofencingDispatcherHost::RegisterRegionCompleted,
@@ -62,18 +63,17 @@
 void GeofencingDispatcherHost::OnUnregisterRegion(
     int thread_id,
     int request_id,
-    const std::string& region_id) {
+    const std::string& region_id,
+    int64 service_worker_registration_id) {
   // Sanity check on region_id
   if (region_id.length() > kMaxRegionIdLength) {
     Send(new GeofencingMsg_UnregisterRegionComplete(
         thread_id, request_id, GeofencingStatus::GEOFENCING_STATUS_ERROR));
     return;
   }
-  // TODO(mek): Actually pass service worker information to manager.
-  GeofencingManager::GetInstance()->UnregisterRegion(
-      browser_context_,
-      0,      /* service_worker_registration_id */
-      GURL(), /* service_worker_origin */
+
+  manager_->UnregisterRegion(
+      service_worker_registration_id,
       region_id,
       base::Bind(&GeofencingDispatcherHost::UnregisterRegionCompleted,
                  weak_factory_.GetWeakPtr(),
@@ -81,16 +81,14 @@
                  request_id));
 }
 
-void GeofencingDispatcherHost::OnGetRegisteredRegions(int thread_id,
-                                                      int request_id) {
+void GeofencingDispatcherHost::OnGetRegisteredRegions(
+    int thread_id,
+    int request_id,
+    int64 service_worker_registration_id) {
   GeofencingRegistrations result;
-  // TODO(mek): Actually pass service worker information to manager.
+
   GeofencingStatus status =
-      GeofencingManager::GetInstance()->GetRegisteredRegions(
-          browser_context_,
-          0,      /* service_worker_registration_id */
-          GURL(), /* service_worker_origin */
-          &result);
+      manager_->GetRegisteredRegions(service_worker_registration_id, &result);
   Send(new GeofencingMsg_GetRegisteredRegionsComplete(
       thread_id, request_id, status, result));
 }
diff --git a/content/browser/geofencing/geofencing_dispatcher_host.h b/content/browser/geofencing/geofencing_dispatcher_host.h
index 86858b8..40ed3a848 100644
--- a/content/browser/geofencing/geofencing_dispatcher_host.h
+++ b/content/browser/geofencing/geofencing_dispatcher_host.h
@@ -14,11 +14,12 @@
 
 namespace content {
 
-class BrowserContext;
+class GeofencingManager;
+class ServiceWorkerContextWrapper;
 
 class GeofencingDispatcherHost : public BrowserMessageFilter {
  public:
-  explicit GeofencingDispatcherHost(BrowserContext* browser_context);
+  explicit GeofencingDispatcherHost(GeofencingManager* geofencing_manager);
 
  private:
   ~GeofencingDispatcherHost() override;
@@ -29,11 +30,15 @@
   void OnRegisterRegion(int thread_id,
                         int request_id,
                         const std::string& region_id,
-                        const blink::WebCircularGeofencingRegion& region);
+                        const blink::WebCircularGeofencingRegion& region,
+                        int64 service_worker_registration_id);
   void OnUnregisterRegion(int thread_id,
                           int request_id,
-                          const std::string& region_id);
-  void OnGetRegisteredRegions(int thread_id, int request_id);
+                          const std::string& region_id,
+                          int64 service_worker_registration_id);
+  void OnGetRegisteredRegions(int thread_id,
+                              int request_id,
+                              int64 service_worker_registration_id);
 
   void RegisterRegionCompleted(int thread_id,
                                int request_id,
@@ -42,7 +47,7 @@
                                  int request_id,
                                  GeofencingStatus result);
 
-  BrowserContext* browser_context_;
+  scoped_refptr<GeofencingManager> manager_;
   base::WeakPtrFactory<GeofencingDispatcherHost> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(GeofencingDispatcherHost);
diff --git a/content/browser/geofencing/geofencing_manager.cc b/content/browser/geofencing/geofencing_manager.cc
index 94b0f25..1147d7d 100644
--- a/content/browser/geofencing/geofencing_manager.cc
+++ b/content/browser/geofencing/geofencing_manager.cc
@@ -7,97 +7,93 @@
 #include <algorithm>
 
 #include "base/callback.h"
-#include "base/memory/singleton.h"
-#include "content/browser/geofencing/geofencing_provider.h"
+#include "content/browser/geofencing/geofencing_service.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/public/browser/browser_thread.h"
 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
-#include "url/gurl.h"
 
 namespace content {
 
-struct GeofencingManager::RegistrationKey {
-  RegistrationKey(BrowserContext* browser_context,
-                  int64 service_worker_registration_id,
-                  const GURL& service_worker_origin,
-                  const std::string& region_id);
-
-  BrowserContext* browser_context;
+struct GeofencingManager::Registration {
+  Registration(int64 service_worker_registration_id,
+               const GURL& service_worker_origin,
+               const std::string& region_id,
+               const blink::WebCircularGeofencingRegion& region,
+               const StatusCallback& callback,
+               int64 geofencing_registration_id);
 
   int64 service_worker_registration_id;
   GURL service_worker_origin;
-
   std::string region_id;
-};
-
-GeofencingManager::RegistrationKey::RegistrationKey(
-    BrowserContext* browser_context,
-    int64 service_worker_registration_id,
-    const GURL& service_worker_origin,
-    const std::string& region_id)
-    : browser_context(browser_context),
-      service_worker_registration_id(service_worker_registration_id),
-      service_worker_origin(service_worker_origin),
-      region_id(region_id) {
-}
-
-struct GeofencingManager::Registration {
-  Registration();
-  Registration(const RegistrationKey& key,
-               const blink::WebCircularGeofencingRegion& region);
-
-  RegistrationKey key;
   blink::WebCircularGeofencingRegion region;
 
-  // Registration id as returned by the GeofencingProvider, set to -1 if not
-  // currently registered with the provider.
-  int registration_id;
+  // Registration ID as returned by the |GeofencingService|.
+  int64 geofencing_registration_id;
 
-  // Flag to indicate if this registration has completed, and thus should be
+  // Callback to call when registration is completed. This field is reset when
+  // registration is complete.
+  StatusCallback registration_callback;
+
+  // Returns true if registration has been completed, and thus should be
   // included in calls to GetRegisteredRegions.
-  bool is_active;
+  bool is_active() const { return registration_callback.is_null(); }
 };
 
-GeofencingManager::Registration::Registration() : key(nullptr, -1, GURL(), "") {
-}
-
 GeofencingManager::Registration::Registration(
-    const RegistrationKey& key,
-    const blink::WebCircularGeofencingRegion& region)
-    : key(key), region(region), registration_id(-1), is_active(false) {
+    int64 service_worker_registration_id,
+    const GURL& service_worker_origin,
+    const std::string& region_id,
+    const blink::WebCircularGeofencingRegion& region,
+    const GeofencingManager::StatusCallback& callback,
+    int64 geofencing_registration_id)
+    : service_worker_registration_id(service_worker_registration_id),
+      region_id(region_id),
+      region(region),
+      geofencing_registration_id(geofencing_registration_id),
+      registration_callback(callback) {
 }
 
-class GeofencingManager::RegistrationMatches {
- public:
-  RegistrationMatches(const RegistrationKey& key) : key_(key) {}
-
-  bool operator()(const Registration& registration) {
-    return registration.key.browser_context == key_.browser_context &&
-           registration.key.service_worker_registration_id ==
-               key_.service_worker_registration_id &&
-           registration.key.service_worker_origin ==
-               key_.service_worker_origin &&
-           registration.key.region_id == key_.region_id;
-  }
-
- private:
-  const RegistrationKey& key_;
-};
-
-GeofencingManager::GeofencingManager() {
+GeofencingManager::GeofencingManager(
+    const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
+    : service_(nullptr), service_worker_context_(service_worker_context) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
 GeofencingManager::~GeofencingManager() {
 }
 
-GeofencingManager* GeofencingManager::GetInstance() {
+void GeofencingManager::Init() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  BrowserThread::PostTask(BrowserThread::IO,
+                          FROM_HERE,
+                          base::Bind(&GeofencingManager::InitOnIO, this));
+}
+
+void GeofencingManager::Shutdown() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  BrowserThread::PostTask(BrowserThread::IO,
+                          FROM_HERE,
+                          base::Bind(&GeofencingManager::ShutdownOnIO, this));
+}
+
+void GeofencingManager::InitOnIO() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  return Singleton<GeofencingManager>::get();
+  service_ = GeofencingServiceImpl::GetInstance();
+}
+
+void GeofencingManager::ShutdownOnIO() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  // Clean up all registrations with the |GeofencingService|.
+  // TODO(mek): This will need to change to support geofence registrations that
+  //     outlive the browser, although removing the references to this
+  //     |GeofencingManager| from the |GeofencingService| will still be needed.
+  for (const auto& registration : registrations_by_id_) {
+    service_->UnregisterRegion(registration.first);
+  }
 }
 
 void GeofencingManager::RegisterRegion(
-    BrowserContext* browser_context,
     int64 service_worker_registration_id,
-    const GURL& service_worker_origin,
     const std::string& region_id,
     const blink::WebCircularGeofencingRegion& region,
     const StatusCallback& callback) {
@@ -105,148 +101,189 @@
 
   // TODO(mek): Validate region_id and region.
 
-  if (!provider_.get()) {
-    callback.Run(GeofencingStatus::
-                     GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE);
+  // Look up service worker. In unit tests |service_worker_context_| might not
+  // be set.
+  GURL service_worker_origin;
+  if (service_worker_context_.get()) {
+    ServiceWorkerRegistration* service_worker_registration =
+        service_worker_context_->context()->GetLiveRegistration(
+            service_worker_registration_id);
+    if (!service_worker_registration) {
+      callback.Run(GEOFENCING_STATUS_OPERATION_FAILED_NO_SERVICE_WORKER);
+      return;
+    }
+
+    service_worker_origin = service_worker_registration->pattern().GetOrigin();
+  }
+
+  if (!service_->IsServiceAvailable()) {
+    callback.Run(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE);
     return;
   }
 
-  RegistrationKey key(browser_context,
-                      service_worker_registration_id,
-                      service_worker_origin,
-                      region_id);
-  if (FindRegistration(key)) {
+  if (FindRegistration(service_worker_registration_id, region_id)) {
     // Already registered, return an error.
-    callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR);
+    // TODO(mek): Use a more specific error code.
+    callback.Run(GEOFENCING_STATUS_ERROR);
     return;
   }
 
-  // Add registration, but don't mark it as active yet. This prevents duplicate
-  // registrations.
-  AddRegistration(key, region);
-
-  // Register with provider.
-  provider_->RegisterRegion(
-      region,
-      base::Bind(&GeofencingManager::RegisterRegionCompleted,
-                 base::Unretained(this),
-                 callback,
-                 key));
+  AddRegistration(service_worker_registration_id,
+                  service_worker_origin,
+                  region_id,
+                  region,
+                  callback,
+                  service_->RegisterRegion(region, this));
 }
 
-void GeofencingManager::UnregisterRegion(BrowserContext* browser_context,
-                                         int64 service_worker_registration_id,
-                                         const GURL& service_worker_origin,
+void GeofencingManager::UnregisterRegion(int64 service_worker_registration_id,
                                          const std::string& region_id,
                                          const StatusCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   // TODO(mek): Validate region_id.
 
-  if (!provider_.get()) {
-    callback.Run(GeofencingStatus::
-                     GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE);
+  // Look up service worker. In unit tests |service_worker_context_| might not
+  // be set.
+  if (service_worker_context_.get()) {
+    ServiceWorkerRegistration* service_worker_registration =
+        service_worker_context_->context()->GetLiveRegistration(
+            service_worker_registration_id);
+    if (!service_worker_registration) {
+      callback.Run(GEOFENCING_STATUS_OPERATION_FAILED_NO_SERVICE_WORKER);
+      return;
+    }
+  }
+
+  if (!service_->IsServiceAvailable()) {
+    callback.Run(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE);
     return;
   }
 
-  RegistrationKey key(browser_context,
-                      service_worker_registration_id,
-                      service_worker_origin,
-                      region_id);
-  Registration* registration = FindRegistration(key);
+  Registration* registration =
+      FindRegistration(service_worker_registration_id, region_id);
   if (!registration) {
-    // Not registered, return an error/
-    callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR);
+    // Not registered, return an error.
+    callback.Run(GEOFENCING_STATUS_UNREGISTRATION_FAILED_NOT_REGISTERED);
     return;
   }
 
-  if (!registration->is_active) {
+  if (!registration->is_active()) {
     // Started registration, but not completed yet, error.
-    callback.Run(GeofencingStatus::GEOFENCING_STATUS_ERROR);
+    callback.Run(GEOFENCING_STATUS_UNREGISTRATION_FAILED_NOT_REGISTERED);
     return;
   }
 
-  if (registration->registration_id != -1) {
-    provider_->UnregisterRegion(registration->registration_id);
-  }
-  ClearRegistration(key);
-  callback.Run(GeofencingStatus::GEOFENCING_STATUS_OK);
+  service_->UnregisterRegion(registration->geofencing_registration_id);
+  ClearRegistration(registration);
+  callback.Run(GEOFENCING_STATUS_OK);
 }
 
 GeofencingStatus GeofencingManager::GetRegisteredRegions(
-    BrowserContext* browser_context,
     int64 service_worker_registration_id,
-    const GURL& service_worker_origin,
     std::map<std::string, blink::WebCircularGeofencingRegion>* result) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   CHECK(result);
 
-  if (!provider_.get()) {
-    return GeofencingStatus::
-        GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE;
+  // Look up service worker. In unit tests |service_worker_context_| might not
+  // be set.
+  if (service_worker_context_.get()) {
+    ServiceWorkerRegistration* service_worker_registration =
+        service_worker_context_->context()->GetLiveRegistration(
+            service_worker_registration_id);
+    if (!service_worker_registration) {
+      return GEOFENCING_STATUS_OPERATION_FAILED_NO_SERVICE_WORKER;
+    }
+  }
+
+  if (!service_->IsServiceAvailable()) {
+    return GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE;
   }
 
   // Populate result, filtering out inactive registrations.
   result->clear();
-  for (const auto& registration : registrations_) {
-    if (registration.key.browser_context == browser_context &&
-        registration.key.service_worker_registration_id ==
-            service_worker_registration_id &&
-        registration.key.service_worker_origin == service_worker_origin &&
-        registration.is_active) {
-      (*result)[registration.key.region_id] = registration.region;
-    }
+  ServiceWorkerRegistrationsMap::iterator registrations =
+      registrations_.find(service_worker_registration_id);
+  if (registrations == registrations_.end())
+    return GEOFENCING_STATUS_OK;
+  for (const auto& registration : registrations->second) {
+    if (registration.second.is_active())
+      (*result)[registration.first] = registration.second.region;
   }
-  return GeofencingStatus::GEOFENCING_STATUS_OK;
+  return GEOFENCING_STATUS_OK;
 }
 
-void GeofencingManager::RegisterRegionCompleted(const StatusCallback& callback,
-                                                const RegistrationKey& key,
-                                                GeofencingStatus status,
-                                                int registration_id) {
+void GeofencingManager::RegistrationFinished(int64 geofencing_registration_id,
+                                             GeofencingStatus status) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (status != GEOFENCING_STATUS_OK) {
-    ClearRegistration(key);
-    callback.Run(status);
-    return;
-  }
-
-  Registration* registration = FindRegistration(key);
+  Registration* registration = FindRegistrationById(geofencing_registration_id);
   DCHECK(registration);
-  registration->registration_id = registration_id;
-  registration->is_active = true;
-  callback.Run(GeofencingStatus::GEOFENCING_STATUS_OK);
-}
+  DCHECK(!registration->is_active());
+  registration->registration_callback.Run(status);
+  registration->registration_callback.Reset();
 
-void GeofencingManager::SetProviderForTests(
-    scoped_ptr<GeofencingProvider> provider) {
-  DCHECK(!provider_.get());
-  provider_ = provider.Pass();
+  // If the registration wasn't succesful, remove it from our storage.
+  if (status != GEOFENCING_STATUS_OK)
+    ClearRegistration(registration);
 }
 
 GeofencingManager::Registration* GeofencingManager::FindRegistration(
-    const RegistrationKey& key) {
-  std::vector<Registration>::iterator it = std::find_if(
-      registrations_.begin(), registrations_.end(), RegistrationMatches(key));
-  if (it == registrations_.end())
+    int64 service_worker_registration_id,
+    const std::string& region_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  ServiceWorkerRegistrationsMap::iterator registrations_iterator =
+      registrations_.find(service_worker_registration_id);
+  if (registrations_iterator == registrations_.end())
     return nullptr;
-  return &*it;
+  RegionIdRegistrationMap::iterator registration =
+      registrations_iterator->second.find(region_id);
+  if (registration == registrations_iterator->second.end())
+    return nullptr;
+  return &registration->second;
+}
+
+GeofencingManager::Registration* GeofencingManager::FindRegistrationById(
+    int64 geofencing_registration_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  RegistrationIdRegistrationMap::iterator registration_iterator =
+      registrations_by_id_.find(geofencing_registration_id);
+  if (registration_iterator == registrations_by_id_.end())
+    return nullptr;
+  return &registration_iterator->second->second;
 }
 
 GeofencingManager::Registration& GeofencingManager::AddRegistration(
-    const RegistrationKey& key,
-    const blink::WebCircularGeofencingRegion& region) {
-  DCHECK(!FindRegistration(key));
-  registrations_.push_back(Registration(key, region));
-  return registrations_.back();
+    int64 service_worker_registration_id,
+    const GURL& service_worker_origin,
+    const std::string& region_id,
+    const blink::WebCircularGeofencingRegion& region,
+    const StatusCallback& callback,
+    int64 geofencing_registration_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(!FindRegistration(service_worker_registration_id, region_id));
+  RegionIdRegistrationMap::iterator registration =
+      registrations_[service_worker_registration_id]
+          .insert(std::make_pair(region_id,
+                                 Registration(service_worker_registration_id,
+                                              service_worker_origin,
+                                              region_id,
+                                              region,
+                                              callback,
+                                              geofencing_registration_id)))
+          .first;
+  registrations_by_id_[geofencing_registration_id] = registration;
+  return registration->second;
 }
 
-void GeofencingManager::ClearRegistration(const RegistrationKey& key) {
-  std::vector<Registration>::iterator it = std::find_if(
-      registrations_.begin(), registrations_.end(), RegistrationMatches(key));
-  if (it == registrations_.end())
-    return;
-  registrations_.erase(it);
+void GeofencingManager::ClearRegistration(Registration* registration) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  registrations_by_id_.erase(registration->geofencing_registration_id);
+  ServiceWorkerRegistrationsMap::iterator registrations_iterator =
+      registrations_.find(registration->service_worker_registration_id);
+  DCHECK(registrations_iterator != registrations_.end());
+  registrations_iterator->second.erase(registration->region_id);
+  if (registrations_iterator->second.empty())
+    registrations_.erase(registrations_iterator);
 }
 
 }  // namespace content
diff --git a/content/browser/geofencing/geofencing_manager.h b/content/browser/geofencing/geofencing_manager.h
index cae5edd..7cd7b17 100644
--- a/content/browser/geofencing/geofencing_manager.h
+++ b/content/browser/geofencing/geofencing_manager.h
@@ -11,7 +11,9 @@
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "content/browser/geofencing/geofencing_registration_delegate.h"
 #include "content/common/content_export.h"
 #include "content/common/geofencing_status.h"
 
@@ -25,34 +27,30 @@
 
 namespace content {
 
-class BrowserContext;
-class GeofencingProvider;
+class GeofencingService;
+class ServiceWorkerContextWrapper;
 
-// This is the main API to the geofencing subsystem. The application will hold
-// a single instance of this class.
+// This is the main API to the geofencing subsystem. There is one instance of
+// this class per storage partition.
 // This class is responsible for keeping track of which geofences are currently
 // registered by websites/workers, persisting this list of registrations and
-// registering a subset of these active registrations with the underlying
-// platform specific |GeofencingProvider| instance.
-// This class lives on the IO thread, and all public methods of it should only
-// ever be called from that same thread.
-// FIXME: Does it make more sense for this to live on the UI thread instead of
-//     the IO thread?
+// registering them with the global |GeofencingService|.
+// This class is created on the UI thread, but all its methods should only be
+// called from the IO thread.
 // TODO(mek): Implement some kind of persistence of registrations.
-// TODO(mek): Limit the number of geofences that are registered with the
-//    underlying GeofencingProvider.
-class CONTENT_EXPORT GeofencingManager {
+class CONTENT_EXPORT GeofencingManager
+    : NON_EXPORTED_BASE(public GeofencingRegistrationDelegate),
+      public base::RefCountedThreadSafe<GeofencingManager> {
  public:
   typedef base::Callback<void(GeofencingStatus)> StatusCallback;
-  typedef base::Callback<void(
-      GeofencingStatus,
-      const std::map<std::string, blink::WebCircularGeofencingRegion>&)>
-      RegistrationsCallback;
 
-  // Gets a pointer to the singleton instance of the geofencing manager. This
-  // must only be called on the IO thread so that the GeofencingManager is
-  // always instantiated on the same thread. Ownership is NOT returned.
-  static GeofencingManager* GetInstance();
+  explicit GeofencingManager(
+      const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context);
+
+  // Init and Shutdown are for use on the UI thread when the storagepartition is
+  // being setup and torn down.
+  void Init();
+  void Shutdown();
 
   // Initiates registration of a new geofence. StatusCallback is called when
   // registration has completed or failed (which could possibly be before
@@ -61,9 +59,7 @@
   // (or in progress of being registered) region will fail.
   // TODO(mek): Behavior when using an already used ID might need to be revised
   //     depending on what the actual spec ends up saying about this.
-  void RegisterRegion(BrowserContext* browser_context,
-                      int64 service_worker_registration_id,
-                      const GURL& service_worker_origin,
+  void RegisterRegion(int64 service_worker_registration_id,
                       const std::string& region_id,
                       const blink::WebCircularGeofencingRegion& region,
                       const StatusCallback& callback);
@@ -74,9 +70,7 @@
   // (RegisterRegion hasn't called its callback yet) will fail.
   // TODO(mek): Maybe better behavior would be to allow unregistering still
   //     in-progress registrations.
-  void UnregisterRegion(BrowserContext* browser_context,
-                        int64 service_worker_registration_id,
-                        const GURL& service_worker_origin,
+  void UnregisterRegion(int64 service_worker_registration_id,
                         const std::string& region_id,
                         const StatusCallback& callback);
 
@@ -87,51 +81,65 @@
   // has been called already (so it doesn't include still in progress
   // registrations).
   GeofencingStatus GetRegisteredRegions(
-      BrowserContext* browser_context,
       int64 service_worker_registration_id,
-      const GURL& service_worker_origin,
-      std::map<std::string, blink::WebCircularGeofencingRegion>* regions);
+      std::map<std::string, blink::WebCircularGeofencingRegion>* result);
 
-  void SetProviderForTests(scoped_ptr<GeofencingProvider> provider);
+  void SetServiceForTesting(GeofencingService* service) {
+    service_ = service;
+  }
 
  protected:
-  friend struct DefaultSingletonTraits<GeofencingManager>;
-  friend class GeofencingManagerTest;
-  GeofencingManager();
-  virtual ~GeofencingManager();
+  friend class base::RefCountedThreadSafe<GeofencingManager>;
+  ~GeofencingManager() override;
 
  private:
   // Internal bookkeeping associated with each registered geofence.
-  struct RegistrationKey;
   struct Registration;
-  class RegistrationMatches;
 
-  // Called by GeofencingProvider when the platform specific provider completes
-  // registration of a geofence.
-  void RegisterRegionCompleted(const StatusCallback& callback,
-                               const RegistrationKey& key,
-                               GeofencingStatus status,
-                               int registration_id);
+  void InitOnIO();
+  void ShutdownOnIO();
+
+  // GeofencingRegistrationDelegate implementation.
+  void RegistrationFinished(int64 geofencing_registration_id,
+                            GeofencingStatus status) override;
 
   // Looks up a particular geofence registration. Returns nullptr if no
   // registration with the given IDs exists.
-  Registration* FindRegistration(const RegistrationKey& key);
+  Registration* FindRegistration(int64 service_worker_registration_id,
+                                 const std::string& region_id);
+
+  // Looks up a particular geofence registration. Returns nullptr if no
+  // registration with the given ID exists.
+  Registration* FindRegistrationById(int64 geofencing_registration_id);
 
   // Registers a new registration, returning a reference to the newly inserted
   // object. Assumes no registration with the same IDs currently exists.
   Registration& AddRegistration(
-      const RegistrationKey& key,
-      const blink::WebCircularGeofencingRegion& region);
+      int64 service_worker_registration_id,
+      const GURL& service_worker_origin,
+      const std::string& region_id,
+      const blink::WebCircularGeofencingRegion& region,
+      const StatusCallback& callback,
+      int64 geofencing_registration_id);
 
   // Clears a registration.
-  void ClearRegistration(const RegistrationKey& key);
+  void ClearRegistration(Registration* registration);
 
-  // List of all currently registered geofences.
-  // TODO(mek): Better way of storing these that allows more efficient lookup
-  //     and deletion.
-  std::vector<Registration> registrations_;
+  // Map of all registered regions for a particular service worker registration.
+  typedef std::map<std::string, Registration> RegionIdRegistrationMap;
+  // Map of service worker registration id to the regions registered by that
+  // service worker.
+  typedef std::map<int64, RegionIdRegistrationMap>
+      ServiceWorkerRegistrationsMap;
+  ServiceWorkerRegistrationsMap registrations_;
 
-  scoped_ptr<GeofencingProvider> provider_;
+  // Map of all registered regions by geofencing_registration_id.
+  typedef std::map<int64, RegionIdRegistrationMap::iterator>
+      RegistrationIdRegistrationMap;
+  RegistrationIdRegistrationMap registrations_by_id_;
+
+  GeofencingService* service_;
+  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
 
   DISALLOW_COPY_AND_ASSIGN(GeofencingManager);
 };
diff --git a/content/browser/geofencing/geofencing_manager_unittest.cc b/content/browser/geofencing/geofencing_manager_unittest.cc
index 78828ac..6970b71 100644
--- a/content/browser/geofencing/geofencing_manager_unittest.cc
+++ b/content/browser/geofencing/geofencing_manager_unittest.cc
@@ -5,14 +5,13 @@
 #include "base/callback.h"
 #include "base/message_loop/message_loop.h"
 #include "content/browser/geofencing/geofencing_manager.h"
-#include "content/browser/geofencing/geofencing_provider.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/test/test_browser_thread.h"
+#include "content/browser/geofencing/geofencing_service.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
-#include "url/gurl.h"
 
 using blink::WebCircularGeofencingRegion;
 typedef std::map<std::string, WebCircularGeofencingRegion> RegionMap;
@@ -22,6 +21,8 @@
 static const char* kTestRegionId = "region-id";
 static const int64 kTestServiceWorkerRegistrationId = 123;
 static const int64 kTestServiceWorkerRegistrationId2 = 456;
+static const int64 kTestGeofencingRegistrationId = 42;
+static const int64 kTestGeofencingRegistrationId2 = 43;
 
 bool RegionsMatch(const WebCircularGeofencingRegion& expected,
                   const WebCircularGeofencingRegion& arg) {
@@ -33,20 +34,21 @@
 
 namespace content {
 
-class TestGeofencingProvider : public GeofencingProvider {
+class TestGeofencingService : public GeofencingService {
  public:
+  MOCK_METHOD0(IsServiceAvailable, bool());
   MOCK_METHOD2(RegisterRegion,
-               void(const WebCircularGeofencingRegion& region,
-                    const RegisterCallback& callback));
-  MOCK_METHOD1(UnregisterRegion, void(int registration_id));
+               int64(const WebCircularGeofencingRegion& region,
+                     GeofencingRegistrationDelegate* delegate));
+  MOCK_METHOD1(UnregisterRegion, void(int64 geofencing_registration_id));
 };
 
-ACTION_P2(CallRegisterCallback, status, id) {
-  arg1.Run(status, id);
+ACTION_P(SaveDelegate, delegate) {
+  *delegate = arg1;
 }
 
-ACTION_P(SaveRegisterCallback, callback) {
-  *callback = arg1;
+ACTION_P(QuitRunner, runner) {
+  runner->Quit();
 }
 
 MATCHER_P(WebCircularGeofencingRegionEq, expected, "") {
@@ -78,25 +80,30 @@
 
 class GeofencingManagerTest : public testing::Test {
  public:
-  GeofencingManagerTest()
-      : message_loop_(),
-        io_thread_(BrowserThread::IO, &message_loop_),
-        provider_(0),
-        manager_(0),
-        test_origin_("https://example.com/") {
+  GeofencingManagerTest() : service_(nullptr) {
     test_region_.latitude = 37.421999;
     test_region_.longitude = -122.084015;
     test_region_.radius = 100;
     expected_regions_[kTestRegionId] = test_region_;
   }
 
-  virtual void SetUp() { manager_ = new GeofencingManager(); }
+  virtual void SetUp() {
+    service_ = new TestGeofencingService();
+    ON_CALL(*service_, IsServiceAvailable())
+        .WillByDefault(testing::Return(false));
+    manager_ = new GeofencingManager(nullptr /* ServiceWorkerContextWrapper */);
+    manager_->SetServiceForTesting(service_);
+  }
 
-  virtual void TearDown() { delete manager_; }
+  virtual void TearDown() {
+    manager_ = nullptr;
+    delete service_;
+    service_ = nullptr;
+  }
 
-  void SetProviderForTests() {
-    provider_ = new TestGeofencingProvider();
-    manager_->SetProviderForTests(scoped_ptr<GeofencingProvider>(provider_));
+  void SetHasProviderForTests() {
+    ON_CALL(*service_, IsServiceAvailable())
+        .WillByDefault(testing::Return(true));
   }
 
   GeofencingStatus RegisterRegionSync(
@@ -105,48 +112,46 @@
       const WebCircularGeofencingRegion& region) {
     StatusCatcher result;
     manager_->RegisterRegion(
-        nullptr, /* browser_context */
         service_worker_registration_id,
-        test_origin_,
         id,
         region,
         base::Bind(&StatusCatcher::Done, base::Unretained(&result)));
     return result.Wait();
   }
 
-  GeofencingStatus RegisterRegionSyncWithProviderResult(
+  GeofencingStatus RegisterRegionSyncWithServiceResult(
       int64 service_worker_registration_id,
       const std::string& id,
       const WebCircularGeofencingRegion& region,
-      GeofencingStatus provider_status,
-      int provider_result) {
+      GeofencingStatus service_status,
+      int64 geofencing_registration_id) {
     StatusCatcher result;
+    GeofencingRegistrationDelegate* delegate = 0;
     EXPECT_CALL(
-        *provider_,
+        *service_,
         RegisterRegion(WebCircularGeofencingRegionEq(region), testing::_))
-        .WillOnce(CallRegisterCallback(provider_status, provider_result));
+        .WillOnce(testing::DoAll(SaveDelegate(&delegate),
+                                 testing::Return(geofencing_registration_id)));
     manager_->RegisterRegion(
-        nullptr, /* browser_context */
         service_worker_registration_id,
-        test_origin_,
         id,
         region,
         base::Bind(&StatusCatcher::Done, base::Unretained(&result)));
+    CHECK(delegate);
+    delegate->RegistrationFinished(geofencing_registration_id, service_status);
     return result.Wait();
   }
 
   GeofencingStatus UnregisterRegionSync(int64 service_worker_registration_id,
                                         const std::string& id,
-                                        bool should_call_provider,
-                                        int provider_id = 0) {
+                                        bool should_call_service,
+                                        int64 geofencing_registration_id = 0) {
     StatusCatcher result;
-    if (should_call_provider) {
-      EXPECT_CALL(*provider_, UnregisterRegion(provider_id));
+    if (should_call_service) {
+      EXPECT_CALL(*service_, UnregisterRegion(geofencing_registration_id));
     }
     manager_->UnregisterRegion(
-        nullptr, /* browser_context */
         service_worker_registration_id,
-        test_origin_,
         id,
         base::Bind(&StatusCatcher::Done, base::Unretained(&result)));
     return result.Wait();
@@ -155,10 +160,8 @@
   void VerifyRegions(int64 service_worker_registration_id,
                      const RegionMap& expected_regions) {
     RegionMap regions;
-    EXPECT_EQ(GeofencingStatus::GEOFENCING_STATUS_OK,
-              manager_->GetRegisteredRegions(nullptr, /* browser_context */
-                                             service_worker_registration_id,
-                                             test_origin_,
+    EXPECT_EQ(GEOFENCING_STATUS_OK,
+              manager_->GetRegisteredRegions(service_worker_registration_id,
                                              &regions));
     EXPECT_EQ(expected_regions.size(), regions.size());
     for (RegionMap::const_iterator it = expected_regions.begin();
@@ -170,236 +173,242 @@
   }
 
  protected:
-  base::MessageLoop message_loop_;
-  TestBrowserThread io_thread_;
-  TestGeofencingProvider* provider_;
-  GeofencingManager* manager_;
+  TestBrowserThreadBundle threads_;
+  TestGeofencingService* service_;
+  scoped_refptr<GeofencingManager> manager_;
 
   WebCircularGeofencingRegion test_region_;
   RegionMap expected_regions_;
-  GURL test_origin_;
 };
 
-TEST_F(GeofencingManagerTest, RegisterRegion_NoProvider) {
-  EXPECT_EQ(GeofencingStatus::
-                GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE,
+TEST_F(GeofencingManagerTest, RegisterRegion_NoService) {
+  EXPECT_EQ(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE,
             RegisterRegionSync(
                 kTestServiceWorkerRegistrationId, kTestRegionId, test_region_));
 }
 
-TEST_F(GeofencingManagerTest, UnregisterRegion_NoProvider) {
-  EXPECT_EQ(GeofencingStatus::
-                GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE,
+TEST_F(GeofencingManagerTest, UnregisterRegion_NoService) {
+  EXPECT_EQ(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE,
             UnregisterRegionSync(
                 kTestServiceWorkerRegistrationId, kTestRegionId, false));
 }
 
-TEST_F(GeofencingManagerTest, GetRegisteredRegions_NoProvider) {
+TEST_F(GeofencingManagerTest, GetRegisteredRegions_NoService) {
   RegionMap regions;
-  EXPECT_EQ(GeofencingStatus::
-                GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE,
-            manager_->GetRegisteredRegions(nullptr, /* browser_context */
-                                           kTestServiceWorkerRegistrationId,
-                                           test_origin_,
+  EXPECT_EQ(GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE,
+            manager_->GetRegisteredRegions(kTestServiceWorkerRegistrationId,
                                            &regions));
   EXPECT_TRUE(regions.empty());
 }
 
-TEST_F(GeofencingManagerTest, RegisterRegion_FailsInProvider) {
-  SetProviderForTests();
+TEST_F(GeofencingManagerTest, RegisterRegion_FailsInService) {
+  SetHasProviderForTests();
   EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_ERROR,
-      RegisterRegionSyncWithProviderResult(kTestServiceWorkerRegistrationId,
-                                           kTestRegionId,
-                                           test_region_,
-                                           GEOFENCING_STATUS_ERROR,
-                                           -1));
+      GEOFENCING_STATUS_ERROR,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_ERROR,
+                                          -1));
 }
 
-TEST_F(GeofencingManagerTest, RegisterRegion_SucceedsInProvider) {
-  SetProviderForTests();
+TEST_F(GeofencingManagerTest, RegisterRegion_SucceedsInService) {
+  SetHasProviderForTests();
   EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      RegisterRegionSyncWithProviderResult(kTestServiceWorkerRegistrationId,
-                                           kTestRegionId,
-                                           test_region_,
-                                           GEOFENCING_STATUS_OK,
-                                           0));
+      GEOFENCING_STATUS_OK,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_OK,
+                                          kTestGeofencingRegistrationId));
   VerifyRegions(kTestServiceWorkerRegistrationId, expected_regions_);
 }
 
 TEST_F(GeofencingManagerTest, RegisterRegion_AlreadyRegistered) {
-  SetProviderForTests();
+  SetHasProviderForTests();
   EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      RegisterRegionSyncWithProviderResult(kTestServiceWorkerRegistrationId,
-                                           kTestRegionId,
-                                           test_region_,
-                                           GEOFENCING_STATUS_OK,
-                                           0));
+      GEOFENCING_STATUS_OK,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_OK,
+                                          kTestGeofencingRegistrationId));
   VerifyRegions(kTestServiceWorkerRegistrationId, expected_regions_);
 
   WebCircularGeofencingRegion region2;
   region2.latitude = 43.2;
   region2.longitude = 1.45;
   region2.radius = 8.5;
-  EXPECT_EQ(GeofencingStatus::GEOFENCING_STATUS_ERROR,
+  EXPECT_EQ(GEOFENCING_STATUS_ERROR,
             RegisterRegionSync(
                 kTestServiceWorkerRegistrationId, kTestRegionId, region2));
   VerifyRegions(kTestServiceWorkerRegistrationId, expected_regions_);
 }
 
 TEST_F(GeofencingManagerTest, UnregisterRegion_NotRegistered) {
-  SetProviderForTests();
-  EXPECT_EQ(GeofencingStatus::GEOFENCING_STATUS_ERROR,
+  SetHasProviderForTests();
+  EXPECT_EQ(GEOFENCING_STATUS_UNREGISTRATION_FAILED_NOT_REGISTERED,
             UnregisterRegionSync(
                 kTestServiceWorkerRegistrationId, kTestRegionId, false));
 }
 
 TEST_F(GeofencingManagerTest, UnregisterRegion_Success) {
-  SetProviderForTests();
-  int provider_id = 123;
+  SetHasProviderForTests();
 
   EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      RegisterRegionSyncWithProviderResult(kTestServiceWorkerRegistrationId,
-                                           kTestRegionId,
-                                           test_region_,
-                                           GEOFENCING_STATUS_OK,
-                                           provider_id));
+      GEOFENCING_STATUS_OK,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_OK,
+                                          kTestGeofencingRegistrationId));
 
-  EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      UnregisterRegionSync(
-          kTestServiceWorkerRegistrationId, kTestRegionId, true, provider_id));
+  EXPECT_EQ(GEOFENCING_STATUS_OK,
+            UnregisterRegionSync(kTestServiceWorkerRegistrationId,
+                                 kTestRegionId,
+                                 true,
+                                 kTestGeofencingRegistrationId));
   VerifyRegions(kTestServiceWorkerRegistrationId, RegionMap());
 }
 
 TEST_F(GeofencingManagerTest, GetRegisteredRegions_RegistrationInProgress) {
-  SetProviderForTests();
+  SetHasProviderForTests();
   StatusCatcher result;
-  GeofencingProvider::RegisterCallback callback;
+  GeofencingRegistrationDelegate* delegate = nullptr;
 
   EXPECT_CALL(
-      *provider_,
+      *service_,
       RegisterRegion(WebCircularGeofencingRegionEq(test_region_), testing::_))
-      .WillOnce(SaveRegisterCallback(&callback));
+      .WillOnce(testing::DoAll(SaveDelegate(&delegate),
+                               testing::Return(kTestGeofencingRegistrationId)));
   manager_->RegisterRegion(
-      nullptr, /* browser_context */
       kTestServiceWorkerRegistrationId,
-      test_origin_,
       kTestRegionId,
       test_region_,
       base::Bind(&StatusCatcher::Done, base::Unretained(&result)));
 
   // At this point the manager should have tried registering the region with
-  // the provider, resulting in |callback| being set. Until the callback is
+  // the service, resulting in |delegate| being set. Until the callback is
   // called the registration is not complete though.
-  EXPECT_FALSE(callback.is_null());
+  EXPECT_NE(delegate, nullptr);
   VerifyRegions(kTestServiceWorkerRegistrationId, RegionMap());
 
   // Now call the callback, and verify the registration completed succesfully.
-  callback.Run(GEOFENCING_STATUS_OK, 123);
-  EXPECT_EQ(GeofencingStatus::GEOFENCING_STATUS_OK, result.Wait());
+  delegate->RegistrationFinished(kTestGeofencingRegistrationId,
+                                 GEOFENCING_STATUS_OK);
+  EXPECT_EQ(GEOFENCING_STATUS_OK, result.Wait());
   VerifyRegions(kTestServiceWorkerRegistrationId, expected_regions_);
 }
 
 TEST_F(GeofencingManagerTest, UnregisterRegion_RegistrationInProgress) {
-  SetProviderForTests();
+  SetHasProviderForTests();
   StatusCatcher result;
-  GeofencingProvider::RegisterCallback callback;
+  GeofencingRegistrationDelegate* delegate = nullptr;
 
   EXPECT_CALL(
-      *provider_,
+      *service_,
       RegisterRegion(WebCircularGeofencingRegionEq(test_region_), testing::_))
-      .WillOnce(SaveRegisterCallback(&callback));
+      .WillOnce(testing::DoAll(SaveDelegate(&delegate),
+                               testing::Return(kTestGeofencingRegistrationId)));
   manager_->RegisterRegion(
-      nullptr, /* browser_context */
       kTestServiceWorkerRegistrationId,
-      test_origin_,
       kTestRegionId,
       test_region_,
       base::Bind(&StatusCatcher::Done, base::Unretained(&result)));
 
   // At this point the manager should have tried registering the region with
-  // the provider, resulting in |callback| being set. Until the callback is
+  // the service, resulting in |delegate| being set. Until the callback is
   // called the registration is not complete though.
-  EXPECT_FALSE(callback.is_null());
+  EXPECT_NE(delegate, nullptr);
 
-  EXPECT_EQ(GeofencingStatus::GEOFENCING_STATUS_ERROR,
+  EXPECT_EQ(GEOFENCING_STATUS_UNREGISTRATION_FAILED_NOT_REGISTERED,
             UnregisterRegionSync(
                 kTestServiceWorkerRegistrationId, kTestRegionId, false));
 }
 
 TEST_F(GeofencingManagerTest, GetRegisteredRegions_NoRegions) {
-  SetProviderForTests();
+  SetHasProviderForTests();
   VerifyRegions(kTestServiceWorkerRegistrationId, RegionMap());
 }
 
 TEST_F(GeofencingManagerTest, RegisterRegion_SeparateServiceWorkers) {
-  SetProviderForTests();
-  int provider_id1 = 12;
-  int provider_id2 = 34;
+  SetHasProviderForTests();
 
   EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      RegisterRegionSyncWithProviderResult(kTestServiceWorkerRegistrationId,
-                                           kTestRegionId,
-                                           test_region_,
-                                           GEOFENCING_STATUS_OK,
-                                           provider_id1));
+      GEOFENCING_STATUS_OK,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_OK,
+                                          kTestGeofencingRegistrationId));
 
   VerifyRegions(kTestServiceWorkerRegistrationId, expected_regions_);
   VerifyRegions(kTestServiceWorkerRegistrationId2, RegionMap());
 
   EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      RegisterRegionSyncWithProviderResult(kTestServiceWorkerRegistrationId2,
-                                           kTestRegionId,
-                                           test_region_,
-                                           GEOFENCING_STATUS_OK,
-                                           provider_id2));
+      GEOFENCING_STATUS_OK,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId2,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_OK,
+                                          kTestGeofencingRegistrationId2));
 
   VerifyRegions(kTestServiceWorkerRegistrationId, expected_regions_);
   VerifyRegions(kTestServiceWorkerRegistrationId2, expected_regions_);
 }
 
 TEST_F(GeofencingManagerTest, UnregisterRegion_SeparateServiceWorkers) {
-  SetProviderForTests();
-  int provider_id1 = 12;
-  int provider_id2 = 34;
+  SetHasProviderForTests();
 
   EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      RegisterRegionSyncWithProviderResult(kTestServiceWorkerRegistrationId,
-                                           kTestRegionId,
-                                           test_region_,
-                                           GEOFENCING_STATUS_OK,
-                                           provider_id1));
+      GEOFENCING_STATUS_OK,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_OK,
+                                          kTestGeofencingRegistrationId));
   EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      RegisterRegionSyncWithProviderResult(kTestServiceWorkerRegistrationId2,
-                                           kTestRegionId,
-                                           test_region_,
-                                           GEOFENCING_STATUS_OK,
-                                           provider_id2));
+      GEOFENCING_STATUS_OK,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId2,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_OK,
+                                          kTestGeofencingRegistrationId2));
 
-  EXPECT_EQ(
-      GeofencingStatus::GEOFENCING_STATUS_OK,
-      UnregisterRegionSync(
-          kTestServiceWorkerRegistrationId, kTestRegionId, true, provider_id1));
+  EXPECT_EQ(GEOFENCING_STATUS_OK,
+            UnregisterRegionSync(kTestServiceWorkerRegistrationId,
+                                 kTestRegionId,
+                                 true,
+                                 kTestGeofencingRegistrationId));
 
   VerifyRegions(kTestServiceWorkerRegistrationId, RegionMap());
   VerifyRegions(kTestServiceWorkerRegistrationId2, expected_regions_);
 
-  EXPECT_EQ(GeofencingStatus::GEOFENCING_STATUS_OK,
+  EXPECT_EQ(GEOFENCING_STATUS_OK,
             UnregisterRegionSync(kTestServiceWorkerRegistrationId2,
                                  kTestRegionId,
                                  true,
-                                 provider_id2));
+                                 kTestGeofencingRegistrationId2));
 
   VerifyRegions(kTestServiceWorkerRegistrationId, RegionMap());
   VerifyRegions(kTestServiceWorkerRegistrationId2, RegionMap());
 }
 
+TEST_F(GeofencingManagerTest, ShutdownCleansRegistrations) {
+  SetHasProviderForTests();
+  scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner());
+  EXPECT_EQ(
+      GEOFENCING_STATUS_OK,
+      RegisterRegionSyncWithServiceResult(kTestServiceWorkerRegistrationId,
+                                          kTestRegionId,
+                                          test_region_,
+                                          GEOFENCING_STATUS_OK,
+                                          kTestGeofencingRegistrationId));
+
+  EXPECT_CALL(*service_, UnregisterRegion(kTestGeofencingRegistrationId))
+      .WillOnce(QuitRunner(runner));
+  manager_->Shutdown();
+  runner->Run();
+}
+
 }  // namespace content
diff --git a/content/browser/geofencing/geofencing_provider.h b/content/browser/geofencing/geofencing_provider.h
index ab5faa0..dec96b52 100644
--- a/content/browser/geofencing/geofencing_provider.h
+++ b/content/browser/geofencing/geofencing_provider.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_GEOFENCING_GEOFENCING_PROVIDER_H_
 #define CONTENT_BROWSER_GEOFENCING_GEOFENCING_PROVIDER_H_
 
+#include "base/basictypes.h"
 #include "base/callback_forward.h"
 #include "content/common/geofencing_status.h"
 
@@ -16,28 +17,26 @@
 
 class GeofencingProvider {
  public:
-  // Callback that gets called on completion of registering a new region. The
-  // status indicates success or failure, and in case of success, an id to use
-  // to later unregister the region is passed as |registration_id|. If
-  // registration failed, providers should set |registration_id| to -1.
-  typedef base::Callback<void(GeofencingStatus, int registration_id)>
-      RegisterCallback;
+  typedef base::Callback<void(GeofencingStatus)> StatusCallback;
 
   virtual ~GeofencingProvider() {}
 
-  // Called by |GeofencingManager| to register a new fence. GeofencingManager is
+  // Called by |GeofencingService| to register a new fence. GeofencingService is
   // responsible for handling things like duplicate regions, so platform
   // specific implementations shouldn't have to worry about things like that.
-  // Also GeofencingManager should be making sure the total number of geofences
+  // Also GeofencingService should be making sure the total number of geofences
   // that is registered with the platform specific provider does not exceed the
   // number of regions supported by the platform, although that isn't
   // implemented yet.
-  virtual void RegisterRegion(const blink::WebCircularGeofencingRegion& region,
-                              const RegisterCallback& callback) = 0;
+  // Implementations of RegisterRegion must asynchronously call the |callback|
+  // to indicate success or failure.
+  virtual void RegisterRegion(int64 geofencing_registration_id,
+                              const blink::WebCircularGeofencingRegion& region,
+                              const StatusCallback& callback) = 0;
 
-  // Called by |GeofencingManager| to unregister an existing registration. Will
+  // Called by |GeofencingService| to unregister an existing registration. Will
   // only be called once for each registration.
-  virtual void UnregisterRegion(int registration_id) = 0;
+  virtual void UnregisterRegion(int64 geofencing_registration_id) = 0;
 };
 
 }  // namespace content
diff --git a/content/browser/geofencing/geofencing_registration_delegate.h b/content/browser/geofencing/geofencing_registration_delegate.h
new file mode 100644
index 0000000..ba7836c
--- /dev/null
+++ b/content/browser/geofencing/geofencing_registration_delegate.h
@@ -0,0 +1,29 @@
+// 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 CONTENT_BROWSER_GEOFENCING_GEOFENCING_REGISTRATION_DELEGATE_H_
+#define CONTENT_BROWSER_GEOFENCING_GEOFENCING_REGISTRATION_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "content/common/geofencing_status.h"
+
+namespace content {
+
+// |GeofencingService| has an instance of this class associated with each
+// geofence registration, and uses it to inform about events related to the
+// registration, such as the geofence finishing being registered.
+// These methods will always be called on the IO thread.
+// TODO(mek): Add methods for geofence enter/leave events.
+class GeofencingRegistrationDelegate {
+ public:
+  virtual void RegistrationFinished(int64 geofencing_registration_id,
+                                    GeofencingStatus status) = 0;
+
+ protected:
+  virtual ~GeofencingRegistrationDelegate() {}
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_GEOFENCING_GEOFENCING_REGISTRATION_DELEGATE_H_
diff --git a/content/browser/geofencing/geofencing_service.cc b/content/browser/geofencing/geofencing_service.cc
new file mode 100644
index 0000000..11df952
--- /dev/null
+++ b/content/browser/geofencing/geofencing_service.cc
@@ -0,0 +1,199 @@
+// 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 "content/browser/geofencing/geofencing_service.h"
+
+#include "base/memory/singleton.h"
+#include "base/message_loop/message_loop.h"
+#include "content/browser/geofencing/geofencing_provider.h"
+#include "content/browser/geofencing/geofencing_registration_delegate.h"
+#include "content/public/browser/browser_thread.h"
+#include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
+
+namespace content {
+
+namespace {
+
+void RunSoon(const base::Closure& callback) {
+  if (!callback.is_null())
+    base::MessageLoop::current()->PostTask(FROM_HERE, callback);
+}
+
+}  // namespace
+
+struct GeofencingServiceImpl::Registration {
+  Registration();
+  Registration(const blink::WebCircularGeofencingRegion& region,
+               int64 geofencing_registration_id,
+               GeofencingRegistrationDelegate* delegate);
+
+  blink::WebCircularGeofencingRegion region;
+  int64 geofencing_registration_id;
+  GeofencingRegistrationDelegate* delegate;
+
+  enum RegistrationState {
+    // In progress of being registered with provider.
+    STATE_REGISTERING,
+    // Currently registered with provider.
+    STATE_REGISTERED,
+    // In progress of being registered with provider, but should be unregistered
+    // and deleted.
+    STATE_SHOULD_UNREGISTER_AND_DELETE,
+    // Not currently registered with provider, but still an active registration.
+    STATE_UNREGISTERED
+  };
+  RegistrationState state;
+};
+
+GeofencingServiceImpl::Registration::Registration()
+    : geofencing_registration_id(-1),
+      delegate(nullptr),
+      state(STATE_UNREGISTERED) {
+}
+
+GeofencingServiceImpl::Registration::Registration(
+    const blink::WebCircularGeofencingRegion& region,
+    int64 geofencing_registration_id,
+    GeofencingRegistrationDelegate* delegate)
+    : region(region),
+      geofencing_registration_id(geofencing_registration_id),
+      delegate(delegate),
+      state(STATE_REGISTERING) {
+}
+
+GeofencingServiceImpl::GeofencingServiceImpl() : next_registration_id_(0) {
+}
+
+GeofencingServiceImpl::~GeofencingServiceImpl() {
+}
+
+GeofencingServiceImpl* GeofencingServiceImpl::GetInstance() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  return Singleton<GeofencingServiceImpl>::get();
+}
+
+bool GeofencingServiceImpl::IsServiceAvailable() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  return EnsureProvider();
+}
+
+int64 GeofencingServiceImpl::RegisterRegion(
+    const blink::WebCircularGeofencingRegion& region,
+    GeofencingRegistrationDelegate* delegate) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  int64 geofencing_registration_id = GetNextId();
+  registrations_[geofencing_registration_id] =
+      Registration(region, geofencing_registration_id, delegate);
+
+  if (!EnsureProvider()) {
+    RunSoon(
+        base::Bind(&GeofencingServiceImpl::NotifyRegistrationFinished,
+                   base::Unretained(this),
+                   geofencing_registration_id,
+                   GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE));
+    return geofencing_registration_id;
+  }
+
+  provider_->RegisterRegion(
+      geofencing_registration_id,
+      region,
+      base::Bind(&GeofencingServiceImpl::NotifyRegistrationFinished,
+                 base::Unretained(this),
+                 geofencing_registration_id));
+  return geofencing_registration_id;
+}
+
+void GeofencingServiceImpl::UnregisterRegion(int64 geofencing_registration_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  RegistrationsMap::iterator registration_iterator =
+      registrations_.find(geofencing_registration_id);
+  DCHECK(registration_iterator != registrations_.end());
+
+  if (!EnsureProvider())
+    return;
+
+  switch (registration_iterator->second.state) {
+    case Registration::STATE_REGISTERED:
+      provider_->UnregisterRegion(geofencing_registration_id);
+    // fallthru
+    case Registration::STATE_UNREGISTERED:
+      registrations_.erase(registration_iterator);
+      break;
+    case Registration::STATE_REGISTERING:
+      // Update state, NotifyRegistrationFinished will take care of actually
+      // unregistering.
+      registration_iterator->second.state =
+          Registration::STATE_SHOULD_UNREGISTER_AND_DELETE;
+      break;
+    case Registration::STATE_SHOULD_UNREGISTER_AND_DELETE:
+      // Should not happen.
+      NOTREACHED();
+      break;
+  }
+}
+
+void GeofencingServiceImpl::SetProviderForTesting(
+    scoped_ptr<GeofencingProvider> provider) {
+  DCHECK(!provider_.get());
+  provider_ = provider.Pass();
+}
+
+int GeofencingServiceImpl::RegistrationCountForTesting() {
+  return registrations_.size();
+}
+
+bool GeofencingServiceImpl::EnsureProvider() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  if (!provider_) {
+    // TODO(mek): Create platform specific provider.
+    return false;
+  }
+  return true;
+}
+
+int64 GeofencingServiceImpl::GetNextId() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  return next_registration_id_++;
+}
+
+void GeofencingServiceImpl::NotifyRegistrationFinished(
+    int64 geofencing_registration_id,
+    GeofencingStatus status) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  RegistrationsMap::iterator registration_iterator =
+      registrations_.find(geofencing_registration_id);
+  DCHECK(registration_iterator != registrations_.end());
+  DCHECK(registration_iterator->second.state ==
+             Registration::STATE_REGISTERING ||
+         registration_iterator->second.state ==
+             Registration::STATE_SHOULD_UNREGISTER_AND_DELETE);
+
+  if (registration_iterator->second.state ==
+      Registration::STATE_SHOULD_UNREGISTER_AND_DELETE) {
+    // Don't call delegate, but unregister with provider if registration was
+    // succesfull.
+    if (status == GEOFENCING_STATUS_OK) {
+      provider_->UnregisterRegion(geofencing_registration_id);
+    }
+    registrations_.erase(registration_iterator);
+    return;
+  }
+
+  // Normal case, mark as registered and call delegate.
+  registration_iterator->second.state = Registration::STATE_REGISTERED;
+  registration_iterator->second.delegate->RegistrationFinished(
+      geofencing_registration_id, status);
+
+  if (status != GEOFENCING_STATUS_OK) {
+    // Registration failed, remove from our book-keeping.
+    registrations_.erase(registration_iterator);
+  }
+}
+
+}  // namespace content
diff --git a/content/browser/geofencing/geofencing_service.h b/content/browser/geofencing/geofencing_service.h
new file mode 100644
index 0000000..dc3d832
--- /dev/null
+++ b/content/browser/geofencing/geofencing_service.h
@@ -0,0 +1,105 @@
+// 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 CONTENT_BROWSER_GEOFENCING_GEOFENCING_SERVICE_H_
+#define CONTENT_BROWSER_GEOFENCING_GEOFENCING_SERVICE_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/common/content_export.h"
+#include "content/common/geofencing_status.h"
+
+template <typename T>
+struct DefaultSingletonTraits;
+
+namespace blink {
+struct WebCircularGeofencingRegion;
+};
+
+namespace content {
+
+class GeofencingProvider;
+class GeofencingRegistrationDelegate;
+
+// This interface exists primarily to facilitate testing of classes that depend
+// on GeofencingService. It defines the interface exposed by
+// |GeofencingService|.
+class GeofencingService {
+ public:
+  virtual ~GeofencingService() {}
+
+  // Returns if a geofencing service is available.
+  virtual bool IsServiceAvailable() = 0;
+
+  // Register a region. This returns a unique registration ID, and
+  // asynchronously calls the |delegate|s RegistrationFinished method to
+  // inform the delegate of the result of the attempt to register the region.
+  // This does not transfer ownership of the |delegate|. Callers have to ensure
+  // that the delegate remains valid as long as the region is registered.
+  virtual int64 RegisterRegion(const blink::WebCircularGeofencingRegion& region,
+                               GeofencingRegistrationDelegate* delegate) = 0;
+
+  // Unregister a region. This is assumed to always succeed. It is safe to call
+  // this even if a registration is still in progress.
+  virtual void UnregisterRegion(int64 geofencing_registration_id) = 0;
+};
+
+// This class combines all the geofence registrations from the various per
+// storage partition |GeofencingManager| instances, and registers a subset
+// of those fences with an underlying platform specific |GeofencingProvider|.
+// TODO(mek): Limit the number of geofences that are registered with the
+// underlying GeofencingProvider.
+class CONTENT_EXPORT GeofencingServiceImpl
+    : NON_EXPORTED_BASE(public GeofencingService) {
+ public:
+  // Gets a pointer to the singleton instance of the geofencing service. This
+  // must only be called on the IO thread so that the GeofencingService is
+  // always instantiated on the same thread. Ownership is NOT returned.
+  static GeofencingServiceImpl* GetInstance();
+
+  // GeofencingServiceInterface implementation.
+  bool IsServiceAvailable() override;
+  int64 RegisterRegion(
+      const blink::WebCircularGeofencingRegion& region,
+      GeofencingRegistrationDelegate* delegate) override;
+  void UnregisterRegion(int64 geofencing_registration_id) override;
+
+ protected:
+  friend class GeofencingServiceTest;
+  friend struct DefaultSingletonTraits<GeofencingServiceImpl>;
+  GeofencingServiceImpl();
+  ~GeofencingServiceImpl() override;
+
+  void SetProviderForTesting(scoped_ptr<GeofencingProvider> provider);
+  int RegistrationCountForTesting();
+
+ private:
+  struct Registration;
+  typedef std::map<int64, Registration> RegistrationsMap;
+
+  // This method checks if a |GeofencingProvider| exists, creates a new one if
+  // not, and finally returns false if it can't create a provider for the
+  // current platform.
+  bool EnsureProvider();
+
+  // Returns a new unique ID to use for the next geofence registration.
+  int64 GetNextId();
+
+  // Notifies the correct delegate that registration has completed for a
+  // specific geofence registration.
+  void NotifyRegistrationFinished(int64 geofencing_registration_id,
+                                  GeofencingStatus status);
+
+  int64 next_registration_id_;
+  RegistrationsMap registrations_;
+  scoped_ptr<GeofencingProvider> provider_;
+
+  DISALLOW_COPY_AND_ASSIGN(GeofencingServiceImpl);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_GEOFENCING_GEOFENCING_SERVICE_H_
diff --git a/content/browser/geofencing/geofencing_service_unittest.cc b/content/browser/geofencing/geofencing_service_unittest.cc
new file mode 100644
index 0000000..329fcaf7
--- /dev/null
+++ b/content/browser/geofencing/geofencing_service_unittest.cc
@@ -0,0 +1,191 @@
+// 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 "content/browser/geofencing/geofencing_provider.h"
+#include "content/browser/geofencing/geofencing_registration_delegate.h"
+#include "content/browser/geofencing/geofencing_service.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
+
+using blink::WebCircularGeofencingRegion;
+
+namespace {
+
+bool RegionsMatch(const WebCircularGeofencingRegion& expected,
+                  const WebCircularGeofencingRegion& arg) {
+  return testing::Matches(expected.latitude)(arg.latitude) &&
+         testing::Matches(expected.longitude)(arg.longitude) &&
+         testing::Matches(expected.radius)(arg.radius);
+}
+
+}  // namespace
+
+namespace content {
+
+class MockGeofencingRegistrationDelegate
+    : public GeofencingRegistrationDelegate {
+ public:
+  MOCK_METHOD2(RegistrationFinished,
+               void(int64 geofencing_registration_id, GeofencingStatus status));
+};
+
+class MockGeofencingProvider : public GeofencingProvider {
+ public:
+  MOCK_METHOD3(RegisterRegion,
+               void(int64 geofencing_registration_id,
+                    const blink::WebCircularGeofencingRegion& region,
+                    const StatusCallback& callback));
+  MOCK_METHOD1(UnregisterRegion, void(int64 geofencing_registration_id));
+};
+
+ACTION_P(QuitRunner, runner) {
+  runner->Quit();
+}
+
+ACTION_P(SaveRegistrationId, geofencing_registration_id) {
+  *geofencing_registration_id = arg0;
+}
+
+ACTION_P(SaveStatusCallback, callback) {
+  *callback = arg2;
+}
+
+MATCHER_P(WebCircularGeofencingRegionEq, expected, "") {
+  return RegionsMatch(expected, arg);
+}
+
+class GeofencingServiceTest : public testing::Test {
+ public:
+  GeofencingServiceTest() : service_(nullptr) {
+    test_region_.latitude = 37.421999;
+    test_region_.longitude = -122.084015;
+    test_region_.radius = 100;
+  }
+
+  virtual void SetUp() { service_ = new GeofencingServiceImpl(); }
+
+  virtual void TearDown() { delete service_; }
+
+  void SetProviderForTests() {
+    provider_ = new MockGeofencingProvider();
+    service_->SetProviderForTesting(make_scoped_ptr(provider_));
+  }
+
+  int RegistrationCount() { return service_->RegistrationCountForTesting(); }
+
+  int64 RegisterRegionSync(const WebCircularGeofencingRegion& region,
+                           GeofencingStatus provider_status) {
+    scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner());
+
+    // The registration ID that is passed to the provider.
+    int64 provider_registration_id = -1;
+    // The callback that is passed to the provider.
+    GeofencingProvider::StatusCallback callback;
+
+    EXPECT_CALL(
+        *provider_,
+        RegisterRegion(
+            testing::_, WebCircularGeofencingRegionEq(region), testing::_))
+        .WillOnce(testing::DoAll(SaveRegistrationId(&provider_registration_id),
+                                 SaveStatusCallback(&callback)));
+
+    int64 geofencing_registration_id =
+        service_->RegisterRegion(region, &delegate_);
+
+    // Service should have synchronously called the provider.
+    CHECK(!callback.is_null());
+    CHECK(provider_registration_id == geofencing_registration_id);
+
+    // Finish up registration by calling the callback and waiting for the
+    // delegate to be called.
+    EXPECT_CALL(
+        delegate_,
+        RegistrationFinished(geofencing_registration_id, provider_status))
+        .WillOnce(QuitRunner(runner));
+    callback.Run(provider_status);
+    runner->Run();
+    return geofencing_registration_id;
+  }
+
+ protected:
+  TestBrowserThreadBundle threads_;
+  GeofencingServiceImpl* service_;
+  MockGeofencingProvider* provider_;
+  MockGeofencingRegistrationDelegate delegate_;
+
+  WebCircularGeofencingRegion test_region_;
+};
+
+TEST_F(GeofencingServiceTest, RegisterRegion_NoProvider) {
+  scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner());
+  int64 geofencing_registration_id =
+      service_->RegisterRegion(test_region_, &delegate_);
+  EXPECT_CALL(delegate_,
+              RegistrationFinished(
+                  geofencing_registration_id,
+                  GEOFENCING_STATUS_OPERATION_FAILED_SERVICE_NOT_AVAILABLE))
+      .WillOnce(QuitRunner(runner));
+  runner->Run();
+  EXPECT_EQ(0, RegistrationCount());
+}
+
+TEST_F(GeofencingServiceTest, RegisterRegion_FailsInProvider) {
+  SetProviderForTests();
+  RegisterRegionSync(test_region_, GEOFENCING_STATUS_ERROR);
+  EXPECT_EQ(0, RegistrationCount());
+}
+
+TEST_F(GeofencingServiceTest, RegisterRegion_SucceedsInProvider) {
+  SetProviderForTests();
+  RegisterRegionSync(test_region_, GEOFENCING_STATUS_OK);
+  EXPECT_EQ(1, RegistrationCount());
+}
+
+TEST_F(GeofencingServiceTest, UnregisterRegion_AfterRegistration) {
+  SetProviderForTests();
+  int geofencing_registration_id =
+      RegisterRegionSync(test_region_, GEOFENCING_STATUS_OK);
+  EXPECT_EQ(1, RegistrationCount());
+
+  EXPECT_CALL(*provider_, UnregisterRegion(geofencing_registration_id));
+  service_->UnregisterRegion(geofencing_registration_id);
+  EXPECT_EQ(0, RegistrationCount());
+}
+
+TEST_F(GeofencingServiceTest, UnregisterRegion_DuringSuccesfullRegistration) {
+  SetProviderForTests();
+  scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner());
+
+  // The callback that is passed to the provider.
+  GeofencingProvider::StatusCallback callback;
+
+  EXPECT_CALL(
+      *provider_,
+      RegisterRegion(
+          testing::_, WebCircularGeofencingRegionEq(test_region_), testing::_))
+      .WillOnce(SaveStatusCallback(&callback));
+
+  int64 geofencing_registration_id =
+      service_->RegisterRegion(test_region_, &delegate_);
+
+  // Service should have synchronously called the provider.
+  CHECK(!callback.is_null());
+
+  // Call unregister before registration is finished.
+  service_->UnregisterRegion(geofencing_registration_id);
+
+  // Finish up registration by calling the callback and waiting for the
+  // provider to be called. The delegate should not be called in this case.
+  EXPECT_CALL(delegate_, RegistrationFinished(testing::_, testing::_)).Times(0);
+  EXPECT_CALL(*provider_, UnregisterRegion(geofencing_registration_id))
+      .WillOnce(QuitRunner(runner));
+  callback.Run(GEOFENCING_STATUS_OK);
+  runner->Run();
+  EXPECT_EQ(0, RegistrationCount());
+}
+
+}  // namespace content
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc
index 1fcc0a5..4ecf628 100644
--- a/content/browser/gpu/compositor_util.cc
+++ b/content/browser/gpu/compositor_util.cc
@@ -200,13 +200,10 @@
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
 
-  if (command_line.HasSwitch(switches::kDisableImplSidePainting))
+  if (command_line.HasSwitch(switches::kEnableImplSidePainting))
+    return true;
+  else if (command_line.HasSwitch(switches::kDisableImplSidePainting))
     return false;
-  else if (command_line.HasSwitch(switches::kEnableImplSidePainting))
-    return true;
-  else if (command_line.HasSwitch(
-      switches::kEnableBleedingEdgeRenderingFastPaths))
-    return true;
 
   return true;
 }
diff --git a/content/browser/manifest/manifest_manager_host.cc b/content/browser/manifest/manifest_manager_host.cc
index 962189ff..50b3ecad 100644
--- a/content/browser/manifest/manifest_manager_host.cc
+++ b/content/browser/manifest/manifest_manager_host.cc
@@ -44,11 +44,14 @@
     return;
 
   // Before deleting the callbacks, make sure they are called with a failure
-  // state.
-  CallbackMap::const_iterator it(callbacks);
-  for (; !it.IsAtEnd(); it.Advance())
-    it.GetCurrentValue()->Run(Manifest());
+  // state. Do this in a block so the iterator is destroyed before |callbacks|.
+  {
+    CallbackMap::const_iterator it(callbacks);
+    for (; !it.IsAtEnd(); it.Advance())
+      it.GetCurrentValue()->Run(Manifest());
+  }
 
+  delete callbacks;
   pending_callbacks_.erase(render_frame_host);
 }
 
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc
index 2a10c94..4a931fc5 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -667,15 +667,13 @@
   if (rwhv) {
     const gfx::NativeView view = rwhv->GetNativeView();
     gfx::Screen* const screen = gfx::Screen::GetScreenFor(view);
-    if (screen->IsDIPEnabled()) {
-      const gfx::Display display = screen->GetDisplayNearestWindow(view);
-      const float scale = display.device_scale_factor();
-      if (scale > 1.0f) {
-        const gfx::Size shrunk_size(
-            gfx::ToFlooredSize(gfx::ScaleSize(optimal_size, 1.0f / scale)));
-        if (shrunk_size.width() > 0 && shrunk_size.height() > 0)
-          optimal_size = shrunk_size;
-      }
+    const gfx::Display display = screen->GetDisplayNearestWindow(view);
+    const float scale = display.device_scale_factor();
+    if (scale > 1.0f) {
+      const gfx::Size shrunk_size(
+          gfx::ToFlooredSize(gfx::ScaleSize(optimal_size, 1.0f / scale)));
+      if (shrunk_size.width() > 0 && shrunk_size.height() > 0)
+        optimal_size = shrunk_size;
     }
   }
 
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
index e9fa2a2..96fe4ba 100644
--- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -472,7 +472,6 @@
   ~FakeScreen() override {}
 
   // gfx::Screen implementation (only what's needed for testing).
-  bool IsDIPEnabled() override { return true; }
   gfx::Point GetCursorScreenPoint() override { return gfx::Point(); }
   gfx::NativeWindow GetWindowUnderCursor() override { return NULL; }
   gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override {
diff --git a/content/browser/media/encrypted_media_browsertest.cc b/content/browser/media/encrypted_media_browsertest.cc
index 8448851..3d56142 100644
--- a/content/browser/media/encrypted_media_browsertest.cc
+++ b/content/browser/media/encrypted_media_browsertest.cc
@@ -83,6 +83,7 @@
     base::StringPairs query_params;
     query_params.push_back(std::make_pair("keySystem", CurrentKeySystem()));
     query_params.push_back(std::make_pair("runEncrypted", "1"));
+    query_params.push_back(std::make_pair("usePrefixedEME", "1"));
     RunMediaTestPage("mse_config_change.html", query_params, kEnded, true);
   }
 
@@ -92,10 +93,6 @@
                              const std::string& key_system,
                              SrcType src_type,
                              const std::string& expectation) {
-#if defined(OS_ANDROID) && defined(__aarch64__)
-    // Disable EME tests on arm64 due to timeouts: http://crbug.com/418039
-    return;
-#endif
     if (src_type == MSE && !IsMSESupported()) {
       VLOG(0) << "Skipping test - MSE not supported.";
       return;
@@ -107,6 +104,7 @@
     query_params.push_back(std::make_pair("keySystem", key_system));
     if (src_type == MSE)
       query_params.push_back(std::make_pair("useMSE", "1"));
+    query_params.push_back(std::make_pair("usePrefixedEME", "1"));
     RunMediaTestPage(html_page, query_params, expectation, true);
   }
 
diff --git a/content/browser/media/media_internals.cc b/content/browser/media/media_internals.cc
index bdc47d0..4d60085 100644
--- a/content/browser/media/media_internals.cc
+++ b/content/browser/media/media_internals.cc
@@ -246,9 +246,9 @@
         "name", video_capture_device_info.name.GetNameAndModel());
     device_dict->Set("formats", format_list);
 #if defined(OS_WIN) || defined(OS_MACOSX)
-    device_dict->SetInteger(
+    device_dict->SetString(
         "captureApi",
-        video_capture_device_info.name.capture_api_type());
+        video_capture_device_info.name.GetCaptureApiTypeString());
 #endif
     video_capture_capabilities_cached_data_.Append(device_dict);
   }
diff --git a/content/browser/media/media_internals_unittest.cc b/content/browser/media/media_internals_unittest.cc
index aa344a0..6bec01f 100644
--- a/content/browser/media/media_internals_unittest.cc
+++ b/content/browser/media/media_internals_unittest.cc
@@ -8,11 +8,13 @@
 #include "base/bind_helpers.h"
 #include "base/json/json_reader.h"
 #include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "media/audio/audio_parameters.h"
 #include "media/base/channel_layout.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace {
 const int kTestComponentID = 0;
@@ -107,6 +109,52 @@
   MediaInternals::UpdateCallback update_cb_;
 };
 
+#if defined(OS_WIN) || defined(OS_MACOSX)
+TEST_F(MediaInternalsVideoCaptureDeviceTest,
+       AllCaptureApiTypesHaveProperStringRepresentation) {
+  typedef media::VideoCaptureDevice::Name VideoCaptureDeviceName;
+  typedef std::map<VideoCaptureDeviceName::CaptureApiType, std::string>
+      CaptureApiTypeStringMap;
+  CaptureApiTypeStringMap m;
+#if defined(OS_WIN)
+  m[VideoCaptureDeviceName::MEDIA_FOUNDATION] = "Media Foundation";
+  m[VideoCaptureDeviceName::DIRECT_SHOW] = "Direct Show";
+  m[VideoCaptureDeviceName::DIRECT_SHOW_WDM_CROSSBAR] =
+      "Direct Show WDM Crossbar";
+#elif defined(OS_MACOSX)
+  m[VideoCaptureDeviceName::AVFOUNDATION] = "AV Foundation";
+  m[VideoCaptureDeviceName::QTKIT] = "QTKit";
+  m[VideoCaptureDeviceName::DECKLINK] = "DeckLink";
+#endif
+  EXPECT_EQ(media::VideoCaptureDevice::Name::API_TYPE_UNKNOWN, m.size());
+  for (CaptureApiTypeStringMap::iterator it = m.begin(); it != m.end(); ++it) {
+    const VideoCaptureDeviceName device_name("dummy", "dummy", it->first);
+    EXPECT_EQ(it->second, device_name.GetCaptureApiTypeString());
+  }
+}
+#endif
+
+TEST_F(MediaInternalsVideoCaptureDeviceTest,
+       VideoCaptureFormatStringIsInExpectedFormat) {
+  // Since media internals will send video capture capabilities to JavaScript in
+  // an expected format and there are no public methods for accessing the
+  // resolutions, frame rates or pixel formats, this test checks that the format
+  // has not changed. If the test fails because of the changed format, it should
+  // be updated at the same time as the media internals JS files.
+  const float kFrameRate = 30.0f;
+  const gfx::Size kFrameSize(1280, 720);
+  const media::VideoPixelFormat kPixelFormat = media::PIXEL_FORMAT_I420;
+  const media::VideoCaptureFormat capture_format(
+      kFrameSize, kFrameRate, kPixelFormat);
+  const std::string expected_string =
+      base::StringPrintf("resolution: %s, fps: %f, pixel format: %s",
+                         kFrameSize.ToString().c_str(),
+                         kFrameRate,
+                         media::VideoCaptureFormat::PixelFormatToString(
+                              kPixelFormat).c_str());
+  EXPECT_EQ(expected_string, capture_format.ToString());
+}
+
 TEST_F(MediaInternalsVideoCaptureDeviceTest,
        NotifyVideoCaptureDeviceCapabilitiesEnumerated) {
   const int kWidth = 1280;
@@ -149,9 +197,9 @@
   expected_list.AppendString(format_hd.ToString());
   ExpectListOfStrings("formats", expected_list);
 #if defined(OS_MACOSX)
-  ExpectInt("captureApi", media::VideoCaptureDevice::Name::QTKIT);
+  ExpectString("captureApi", "QTKit");
 #elif defined(OS_WIN)
-  ExpectInt("captureApi", media::VideoCaptureDevice::Name::DIRECT_SHOW);
+  ExpectString("captureApi", "Direct Show");
 #endif
 }
 
diff --git a/content/browser/media/media_source_browsertest.cc b/content/browser/media/media_source_browsertest.cc
index 6283682..684b37d6 100644
--- a/content/browser/media/media_source_browsertest.cc
+++ b/content/browser/media/media_source_browsertest.cc
@@ -43,6 +43,7 @@
     base::StringPairs query_params;
     query_params.push_back(std::make_pair("mediaFile", media_file));
     query_params.push_back(std::make_pair("mediaType", media_type));
+    query_params.push_back(std::make_pair("usePrefixedEME", "1"));
     RunMediaTestPage("media_source_player.html", query_params, expectation,
                      true);
   }
@@ -85,10 +86,9 @@
     VLOG(0) << "Skipping test - MSE not supported.";
     return;
   }
-  RunMediaTestPage("mse_config_change.html",
-                   base::StringPairs(),
-                   kEnded,
-                   true);
+  base::StringPairs query_params;
+  query_params.push_back(std::make_pair("usePrefixedEME", "1"));
+  RunMediaTestPage("mse_config_change.html", query_params, kEnded, true);
 }
 
 }  // namespace content
diff --git a/content/browser/media/midi_host.cc b/content/browser/media/midi_host.cc
index 950cf48..2fc0147 100644
--- a/content/browser/media/midi_host.cc
+++ b/content/browser/media/midi_host.cc
@@ -52,13 +52,16 @@
     : BrowserMessageFilter(MidiMsgStart),
       renderer_process_id_(renderer_process_id),
       has_sys_ex_permission_(false),
+      is_session_requested_(false),
       midi_manager_(midi_manager),
       sent_bytes_in_flight_(0),
       bytes_sent_since_last_acknowledgement_(0) {
+  CHECK(midi_manager_);
 }
 
 MidiHost::~MidiHost() {
-  if (midi_manager_)
+  // Close an open session, or abort opening a session.
+  if (is_session_requested_)
     midi_manager_->EndSession(this);
 }
 
@@ -72,23 +75,21 @@
   IPC_BEGIN_MESSAGE_MAP(MidiHost, message)
     IPC_MESSAGE_HANDLER(MidiHostMsg_StartSession, OnStartSession)
     IPC_MESSAGE_HANDLER(MidiHostMsg_SendData, OnSendData)
+    IPC_MESSAGE_HANDLER(MidiHostMsg_EndSession, OnEndSession)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
   return handled;
 }
 
-void MidiHost::OnStartSession(int client_id) {
-  if (midi_manager_)
-    midi_manager_->StartSession(this, client_id);
+void MidiHost::OnStartSession() {
+  is_session_requested_ = true;
+  midi_manager_->StartSession(this);
 }
 
 void MidiHost::OnSendData(uint32 port,
                           const std::vector<uint8>& data,
                           double timestamp) {
-  if (!midi_manager_)
-    return;
-
   if (data.empty())
     return;
 
@@ -117,25 +118,31 @@
   midi_manager_->DispatchSendMidiData(this, port, data, timestamp);
 }
 
-void MidiHost::CompleteStartSession(int client_id, media::MidiResult result) {
-  MidiPortInfoList input_ports;
-  MidiPortInfoList output_ports;
+void MidiHost::OnEndSession() {
+  is_session_requested_ = false;
+  midi_manager_->EndSession(this);
+}
 
+void MidiHost::CompleteStartSession(media::MidiResult result) {
+  DCHECK(is_session_requested_);
   if (result == media::MIDI_OK) {
-    input_ports = midi_manager_->input_ports();
-    output_ports = midi_manager_->output_ports();
-    received_messages_queues_.clear();
-    received_messages_queues_.resize(input_ports.size());
     // ChildSecurityPolicy is set just before OnStartSession by
     // MidiDispatcherHost. So we can safely cache the policy.
     has_sys_ex_permission_ = ChildProcessSecurityPolicyImpl::GetInstance()->
         CanSendMidiSysExMessage(renderer_process_id_);
   }
+  Send(new MidiMsg_SessionStarted(result));
+}
 
-  Send(new MidiMsg_SessionStarted(client_id,
-                                  result,
-                                  input_ports,
-                                  output_ports));
+void MidiHost::AddInputPort(const media::MidiPortInfo& info) {
+  base::AutoLock auto_lock(messages_queues_lock_);
+  // MidiMessageQueue is created later in ReceiveMidiData().
+  received_messages_queues_.push_back(nullptr);
+  Send(new MidiMsg_AddInputPort(info));
+}
+
+void MidiHost::AddOutputPort(const media::MidiPortInfo& info) {
+  Send(new MidiMsg_AddOutputPort(info));
 }
 
 void MidiHost::ReceiveMidiData(
@@ -145,11 +152,12 @@
     double timestamp) {
   TRACE_EVENT0("midi", "MidiHost::ReceiveMidiData");
 
+  base::AutoLock auto_lock(messages_queues_lock_);
   if (received_messages_queues_.size() <= port)
     return;
 
   // Lazy initialization
-  if (received_messages_queues_[port] == NULL)
+  if (received_messages_queues_[port] == nullptr)
     received_messages_queues_[port] = new media::MidiMessageQueue(true);
 
   received_messages_queues_[port]->Add(data, length);
diff --git a/content/browser/media/midi_host.h b/content/browser/media/midi_host.h
index 87be305..3a469bf93b 100644
--- a/content/browser/media/midi_host.h
+++ b/content/browser/media/midi_host.h
@@ -11,6 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
+#include "base/synchronization/lock.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/browser/browser_thread.h"
@@ -35,7 +36,9 @@
   bool OnMessageReceived(const IPC::Message& message) override;
 
   // MidiManagerClient implementation.
-  void CompleteStartSession(int client_id, media::MidiResult result) override;
+  void CompleteStartSession(media::MidiResult result) override;
+  void AddInputPort(const media::MidiPortInfo& info) override;
+  void AddOutputPort(const media::MidiPortInfo& info) override;
   void ReceiveMidiData(uint32 port,
                        const uint8* data,
                        size_t length,
@@ -43,13 +46,15 @@
   void AccumulateMidiBytesSent(size_t n) override;
 
   // Start session to access MIDI hardware.
-  void OnStartSession(int client_id);
+  void OnStartSession();
 
   // Data to be sent to a MIDI output port.
   void OnSendData(uint32 port,
                   const std::vector<uint8>& data,
                   double timestamp);
 
+  void OnEndSession();
+
  private:
   FRIEND_TEST_ALL_PREFIXES(MidiHostTest, IsValidWebMIDIData);
   friend class base::DeleteHelper<MidiHost>;
@@ -70,6 +75,9 @@
   // messages.
   bool has_sys_ex_permission_;
 
+  // Represents if a session is requested to start.
+  bool is_session_requested_;
+
   // |midi_manager_| talks to the platform-specific MIDI APIs.
   // It can be NULL if the platform (or our current implementation)
   // does not support MIDI.  If not supported then a call to
@@ -80,6 +88,9 @@
   // Buffers where data sent from each MIDI input port is stored.
   ScopedVector<media::MidiMessageQueue> received_messages_queues_;
 
+  // Protects access to |received_messages_queues_|;
+  base::Lock messages_queues_lock_;
+
   // The number of bytes sent to the platform-specific MIDI sending
   // system, but not yet completed.
   size_t sent_bytes_in_flight_;
diff --git a/content/browser/media/webrtc_internals_browsertest.cc b/content/browser/media/webrtc_internals_browsertest.cc
index e9b8b98..7c304f0 100644
--- a/content/browser/media/webrtc_internals_browsertest.cc
+++ b/content/browser/media/webrtc_internals_browsertest.cc
@@ -152,12 +152,11 @@
   virtual ~MAYBE_WebRtcInternalsBrowserTest() {}
 
   void SetUpOnMainThread() override {
-    // We need fake devices in this test since we want to run on naked VMs. We
-    // assume these switches are set by default in content_browsertests.
-    ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
-        switches::kUseFakeDeviceForMediaStream));
+    // Assume this is set by the content test launcher.
     ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
         switches::kUseFakeUIForMediaStream));
+    ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
+        switches::kUseFakeDeviceForMediaStream));
   }
 
  protected:
diff --git a/content/browser/media/webrtc_webcam_browsertest.cc b/content/browser/media/webrtc_webcam_browsertest.cc
new file mode 100644
index 0000000..1be6ee51
--- /dev/null
+++ b/content/browser/media/webrtc_webcam_browsertest.cc
@@ -0,0 +1,102 @@
+// 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 "base/command_line.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "media/base/media_switches.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace {
+
+const base::CommandLine::StringType FAKE_DEVICE_FLAG =
+#if defined(OS_WIN)
+    base::ASCIIToUTF16(switches::kUseFakeDeviceForMediaStream);
+#else
+    switches::kUseFakeDeviceForMediaStream;
+#endif
+
+bool IsUseFakeDeviceForMediaStream(const base::CommandLine::StringType& arg) {
+  return arg.find(FAKE_DEVICE_FLAG) != std::string::npos;
+}
+
+void RemoveFakeDeviceFromCommandLine(base::CommandLine* command_line) {
+  CommandLine::StringVector argv = command_line->argv();
+  argv.erase(std::remove_if(argv.begin(), argv.end(),
+                            IsUseFakeDeviceForMediaStream),
+             argv.end());
+  command_line->InitFromArgv(argv);
+}
+
+}  // namespace
+
+namespace content {
+
+// This class doesn't inherit from WebRtcContentBrowserTestBase like the others
+// since we want it to actually acquire the real webcam on the system (if there
+// is one).
+class WebRtcWebcamBrowserTest: public ContentBrowserTest {
+ public:
+  ~WebRtcWebcamBrowserTest() override {}
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    ASSERT_TRUE(command_line->HasSwitch(switches::kUseFakeUIForMediaStream));
+
+    // The content_browsertests run with this flag by default, and this test is
+    // the only current exception to that rule, so just remove the flag
+    // --use-fake-device-for-media-stream here. We could also have all tests
+    // involving media streams add this flag explicitly, but it will be really
+    // unintuitive for developers to write tests involving media stream and have
+    // them fail on what looks like random bots, so running with fake devices
+    // is really a reasonable default.
+    RemoveFakeDeviceFromCommandLine(command_line);
+  }
+
+  void SetUp() override {
+    EnablePixelOutput();
+    ContentBrowserTest::SetUp();
+  }
+};
+
+// The test is tagged as MANUAL since the webcam is a system-level resource; we
+// only want it to run on bots where we can ensure sequential execution. The
+// Android bots will run the test since they ignore MANUAL, but that's what we
+// want here since the bot runs tests sequentially on the device.
+IN_PROC_BROWSER_TEST_F(WebRtcWebcamBrowserTest,
+                       MANUAL_CanAcquireVgaOnRealWebcam) {
+  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+  GURL url(embedded_test_server()->GetURL(
+      "/media/getusermedia-real-webcam.html"));
+  NavigateToURL(shell(), url);
+
+  std::string result;
+  ASSERT_TRUE(ExecuteScriptAndExtractString(shell()->web_contents(),
+                                            "hasVideoInputDeviceOnSystem()",
+                                            &result));
+  if (result != "has-video-input-device") {
+    VLOG(0) << "No video device; skipping test...";
+    return;
+  }
+
+  // GetUserMedia should acquire VGA by default.
+  ASSERT_TRUE(ExecuteScriptAndExtractString(
+      shell()->web_contents(),
+      "getUserMediaAndReturnVideoDimensions({video: true})",
+      &result));
+
+  if (result == "640x480" || result == "480x640") {
+    // Don't care if the device happens to be in landscape or portrait mode
+    // since we don't know how it is oriented in the lab :)
+    return;
+  }
+  FAIL() << "Expected resolution to be 640x480 or 480x640, got" << result;
+}
+
+}  // namespace content
diff --git a/content/browser/push_messaging_message_filter.cc b/content/browser/push_messaging_message_filter.cc
index f0c3a11d..b681ce7 100644
--- a/content/browser/push_messaging_message_filter.cc
+++ b/content/browser/push_messaging_message_filter.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/bind.h"
+#include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -16,6 +17,15 @@
 #include "content/public/browser/push_messaging_service.h"
 
 namespace content {
+namespace {
+
+void RecordRegistrationStatus(PushRegistrationStatus status) {
+  UMA_HISTOGRAM_ENUMERATION("PushMessaging.RegistrationStatus",
+                            status,
+                            PUSH_REGISTRATION_STATUS_LAST + 1);
+}
+
+}  // namespace
 
 PushMessagingMessageFilter::PushMessagingMessageFilter(
     int render_process_id,
@@ -50,10 +60,13 @@
       service_worker_context_->context()->GetProviderHost(
           render_process_id_, service_worker_provider_id);
   if (!service_worker_host || !service_worker_host->active_version()) {
+    PushRegistrationStatus status =
+        PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER;
     Send(new PushMessagingMsg_RegisterError(
         render_frame_id,
         callbacks_id,
-        PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER));
+        status));
+    RecordRegistrationStatus(status);
     return;
   }
   BrowserThread::PostTask(
@@ -78,10 +91,13 @@
     int64 service_worker_registration_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (!service()) {
+    PushRegistrationStatus status =
+        PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE;
     Send(new PushMessagingMsg_RegisterError(
         render_frame_id,
         callbacks_id,
-        PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE));
+        status));
+    RecordRegistrationStatus(status);
     return;
   }
   service()->Register(origin,
@@ -110,6 +126,7 @@
     Send(new PushMessagingMsg_RegisterError(
         render_frame_id, callbacks_id, status));
   }
+  RecordRegistrationStatus(status);
 }
 
 PushMessagingService* PushMessagingMessageFilter::service() {
diff --git a/content/browser/renderer_host/input/gesture_text_selector_unittest.cc b/content/browser/renderer_host/input/gesture_text_selector_unittest.cc
index 3070586..75de21c4c 100644
--- a/content/browser/renderer_host/input/gesture_text_selector_unittest.cc
+++ b/content/browser/renderer_host/input/gesture_text_selector_unittest.cc
@@ -11,7 +11,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/gesture_detection/motion_event.h"
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
 #include "ui/gfx/geometry/rect_f.h"
 
 using ui::MotionEvent;
diff --git a/content/browser/renderer_host/input/motion_event_android.cc b/content/browser/renderer_host/input/motion_event_android.cc
index 35cce4b..fa21047 100644
--- a/content/browser/renderer_host/input/motion_event_android.cc
+++ b/content/browser/renderer_host/input/motion_event_android.cc
@@ -17,26 +17,6 @@
 namespace content {
 namespace {
 
-int ToAndroidAction(MotionEventAndroid::Action action) {
-  switch (action) {
-    case MotionEventAndroid::ACTION_DOWN:
-      return ACTION_DOWN;
-    case MotionEventAndroid::ACTION_UP:
-      return ACTION_UP;
-    case MotionEventAndroid::ACTION_MOVE:
-      return ACTION_MOVE;
-    case MotionEventAndroid::ACTION_CANCEL:
-      return ACTION_CANCEL;
-    case MotionEventAndroid::ACTION_POINTER_DOWN:
-      return ACTION_POINTER_DOWN;
-    case MotionEventAndroid::ACTION_POINTER_UP:
-      return ACTION_POINTER_UP;
-  };
-  NOTREACHED() << "Invalid Android MotionEvent type for gesture detection: "
-               << action;
-  return ACTION_CANCEL;
-}
-
 MotionEventAndroid::Action FromAndroidAction(int android_action) {
   switch (android_action) {
     case ACTION_DOWN:
@@ -107,10 +87,6 @@
   return flags;
 }
 
-int64 ToAndroidTime(base::TimeTicks time) {
-  return (time - base::TimeTicks()).InMilliseconds();
-}
-
 base::TimeTicks FromAndroidTime(int64 time_ms) {
   return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms);
 }
@@ -130,6 +106,30 @@
 
 }  // namespace
 
+MotionEventAndroid::Pointer::Pointer(jint id,
+                                     jfloat pos_x_pixels,
+                                     jfloat pos_y_pixels,
+                                     jfloat touch_major_pixels,
+                                     jfloat touch_minor_pixels,
+                                     jfloat orientation_rad,
+                                     jint tool_type)
+    : id(id),
+      pos_x_pixels(pos_x_pixels),
+      pos_y_pixels(pos_y_pixels),
+      touch_major_pixels(touch_major_pixels),
+      touch_minor_pixels(touch_minor_pixels),
+      orientation_rad(orientation_rad),
+      tool_type(tool_type) {
+}
+
+MotionEventAndroid::CachedPointer::CachedPointer()
+    : id(0),
+      touch_major(0),
+      touch_minor(0),
+      orientation(0),
+      tool_type(TOOL_TYPE_UNKNOWN) {
+}
+
 MotionEventAndroid::MotionEventAndroid(float pix_to_dip,
                                        JNIEnv* env,
                                        jobject event,
@@ -138,129 +138,34 @@
                                        jint pointer_count,
                                        jint history_size,
                                        jint action_index,
-                                       jfloat pos_x_0_pixels,
-                                       jfloat pos_y_0_pixels,
-                                       jfloat pos_x_1_pixels,
-                                       jfloat pos_y_1_pixels,
-                                       jint pointer_id_0,
-                                       jint pointer_id_1,
-                                       jfloat touch_major_0_pixels,
-                                       jfloat touch_major_1_pixels,
-                                       jfloat touch_minor_0_pixels,
-                                       jfloat touch_minor_1_pixels,
-                                       jfloat orientation_0_rad,
-                                       jfloat orientation_1_rad,
-                                       jfloat raw_pos_x_pixels,
-                                       jfloat raw_pos_y_pixels,
-                                       jint android_tool_type_0,
-                                       jint android_tool_type_1,
                                        jint android_button_state,
-                                       jint meta_state)
-    : cached_time_(FromAndroidTime(time_ms)),
+                                       jint meta_state,
+                                       jfloat raw_offset_x_pixels,
+                                       jfloat raw_offset_y_pixels,
+                                       const Pointer& pointer0,
+                                       const Pointer& pointer1)
+    : pix_to_dip_(pix_to_dip),
+      cached_time_(FromAndroidTime(time_ms)),
       cached_action_(FromAndroidAction(android_action)),
       cached_pointer_count_(pointer_count),
       cached_history_size_(history_size),
       cached_action_index_(action_index),
       cached_button_state_(FromAndroidButtonState(android_button_state)),
       cached_flags_(FromAndroidMetaState(meta_state)),
-      pix_to_dip_(pix_to_dip),
-      should_recycle_(false) {
+      cached_raw_position_offset_(ToDips(raw_offset_x_pixels),
+                                  ToDips(raw_offset_y_pixels)) {
   DCHECK_GT(pointer_count, 0);
   DCHECK_GE(history_size, 0);
 
   event_.Reset(env, event);
-  DCHECK(event_.obj());
+  if (cached_pointer_count_ > MAX_POINTERS_TO_CACHE || history_size > 0)
+    DCHECK(event_.obj());
 
-  cached_positions_[0] = ToDips(gfx::PointF(pos_x_0_pixels, pos_y_0_pixels));
-  cached_positions_[1] = ToDips(gfx::PointF(pos_x_1_pixels, pos_y_1_pixels));
-  cached_pointer_ids_[0] = pointer_id_0;
-  cached_pointer_ids_[1] = pointer_id_1;
-  cached_touch_majors_[0] = ToDips(touch_major_0_pixels);
-  cached_touch_majors_[1] = ToDips(touch_major_1_pixels);
-  cached_touch_minors_[0] = ToDips(touch_minor_0_pixels);
-  cached_touch_minors_[1] = ToDips(touch_minor_1_pixels);
-  cached_orientations_[0] = ToValidFloat(orientation_0_rad);
-  cached_orientations_[1] = ToValidFloat(orientation_1_rad);
-  cached_raw_position_offset_ =
-      ToDips(gfx::PointF(raw_pos_x_pixels, raw_pos_y_pixels)) -
-      cached_positions_[0];
-  cached_tool_types_[0] = FromAndroidToolType(android_tool_type_0);
-  cached_tool_types_[1] = FromAndroidToolType(android_tool_type_1);
-}
-
-MotionEventAndroid::MotionEventAndroid(float pix_to_dip,
-                                       JNIEnv* env,
-                                       jobject event)
-    : cached_time_(FromAndroidTime(Java_MotionEvent_getEventTime(env, event))),
-      cached_action_(
-          FromAndroidAction(Java_MotionEvent_getActionMasked(env, event))),
-      cached_pointer_count_(Java_MotionEvent_getPointerCount(env, event)),
-      cached_history_size_(Java_MotionEvent_getHistorySize(env, event)),
-      cached_action_index_(Java_MotionEvent_getActionIndex(env, event)),
-      cached_button_state_(
-          FromAndroidButtonState(Java_MotionEvent_getButtonState(env, event))),
-      cached_flags_(
-          FromAndroidMetaState(Java_MotionEvent_getMetaState(env, event))),
-      pix_to_dip_(pix_to_dip),
-      should_recycle_(true) {
-  event_.Reset(env, event);
-  DCHECK(event_.obj());
-
-  for (size_t i = 0; i < MAX_POINTERS_TO_CACHE; ++i) {
-    if (i < cached_pointer_count_) {
-      cached_positions_[i] =
-          ToDips(gfx::PointF(Java_MotionEvent_getXF_I(env, event, i),
-                             Java_MotionEvent_getYF_I(env, event, i)));
-      cached_pointer_ids_[i] = Java_MotionEvent_getPointerId(env, event, i);
-      cached_touch_majors_[i] =
-          ToDips(Java_MotionEvent_getTouchMajorF_I(env, event, i));
-      cached_touch_minors_[i] =
-          ToDips(Java_MotionEvent_getTouchMinorF_I(env, event, i));
-      cached_orientations_[i] =
-          ToValidFloat(Java_MotionEvent_getOrientationF_I(env, event, i));
-      cached_tool_types_[i] =
-          FromAndroidToolType(Java_MotionEvent_getToolType(env, event, i));
-    } else {
-      cached_pointer_ids_[i] = 0;
-      cached_touch_majors_[i] = 0.f;
-      cached_touch_minors_[i] = 0.f;
-      cached_orientations_[i] = 0.f;
-      cached_tool_types_[i] = MotionEvent::TOOL_TYPE_UNKNOWN;
-    }
-  }
-
-  cached_raw_position_offset_ =
-      ToDips(gfx::PointF(Java_MotionEvent_getRawX(env, event),
-                         Java_MotionEvent_getRawY(env, event))) -
-      cached_positions_[0];
-}
-
-MotionEventAndroid::MotionEventAndroid(const MotionEventAndroid& other)
-    : event_(Obtain(other)),
-      cached_time_(other.cached_time_),
-      cached_action_(other.cached_action_),
-      cached_pointer_count_(other.cached_pointer_count_),
-      cached_history_size_(other.cached_history_size_),
-      cached_action_index_(other.cached_action_index_),
-      cached_raw_position_offset_(other.cached_raw_position_offset_),
-      cached_button_state_(other.cached_button_state_),
-      cached_flags_(other.cached_flags_),
-      pix_to_dip_(other.pix_to_dip_),
-      should_recycle_(true) {
-  DCHECK(event_.obj());
-  for (size_t i = 0; i < MAX_POINTERS_TO_CACHE; ++i) {
-    cached_positions_[i] = other.cached_positions_[i];
-    cached_pointer_ids_[i] = other.cached_pointer_ids_[i];
-    cached_touch_majors_[i] = other.cached_touch_majors_[i];
-    cached_touch_minors_[i] = other.cached_touch_minors_[i];
-    cached_orientations_[i] = other.cached_orientations_[i];
-    cached_tool_types_[i] = other.cached_tool_types_[i];
-  }
+  cached_pointers_[0] = FromAndroidPointer(pointer0);
+  cached_pointers_[1] = FromAndroidPointer(pointer1);
 }
 
 MotionEventAndroid::~MotionEventAndroid() {
-  if (should_recycle_)
-    Java_MotionEvent_recycle(AttachCurrentThread(), event_.obj());
 }
 
 int MotionEventAndroid::GetId() const {
@@ -282,7 +187,7 @@
 int MotionEventAndroid::GetPointerId(size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
   if (pointer_index < MAX_POINTERS_TO_CACHE)
-    return cached_pointer_ids_[pointer_index];
+    return cached_pointers_[pointer_index].id;
   return Java_MotionEvent_getPointerId(
       AttachCurrentThread(), event_.obj(), pointer_index);
 }
@@ -290,7 +195,7 @@
 float MotionEventAndroid::GetX(size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
   if (pointer_index < MAX_POINTERS_TO_CACHE)
-    return cached_positions_[pointer_index].x();
+    return cached_pointers_[pointer_index].position.x();
   return ToDips(Java_MotionEvent_getXF_I(
       AttachCurrentThread(), event_.obj(), pointer_index));
 }
@@ -298,7 +203,7 @@
 float MotionEventAndroid::GetY(size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
   if (pointer_index < MAX_POINTERS_TO_CACHE)
-    return cached_positions_[pointer_index].y();
+    return cached_pointers_[pointer_index].position.y();
   return ToDips(Java_MotionEvent_getYF_I(
       AttachCurrentThread(), event_.obj(), pointer_index));
 }
@@ -314,7 +219,7 @@
 float MotionEventAndroid::GetTouchMajor(size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
   if (pointer_index < MAX_POINTERS_TO_CACHE)
-    return cached_touch_majors_[pointer_index];
+    return cached_pointers_[pointer_index].touch_major;
   return ToDips(Java_MotionEvent_getTouchMajorF_I(
       AttachCurrentThread(), event_.obj(), pointer_index));
 }
@@ -322,21 +227,26 @@
 float MotionEventAndroid::GetTouchMinor(size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
   if (pointer_index < MAX_POINTERS_TO_CACHE)
-    return cached_touch_minors_[pointer_index];
-  return ToDips(Java_MotionEvent_getTouchMinorF_I(AttachCurrentThread(),
-    event_.obj(), pointer_index));
+    return cached_pointers_[pointer_index].touch_minor;
+  return ToDips(Java_MotionEvent_getTouchMinorF_I(
+      AttachCurrentThread(), event_.obj(), pointer_index));
 }
 
 float MotionEventAndroid::GetOrientation(size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
   if (pointer_index < MAX_POINTERS_TO_CACHE)
-    return cached_orientations_[pointer_index];
+    return cached_pointers_[pointer_index].orientation;
   return ToValidFloat(Java_MotionEvent_getOrientationF_I(
       AttachCurrentThread(), event_.obj(), pointer_index));
 }
 
 float MotionEventAndroid::GetPressure(size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
+  // Note that this early return is a special case exercised only in testing, as
+  // caching the pressure values is not a worthwhile optimization (they're
+  // accessed at most once per event instance).
+  if (!event_.obj())
+    return 0.f;
   return Java_MotionEvent_getPressureF_I(
       AttachCurrentThread(), event_.obj(), pointer_index);
 }
@@ -378,7 +288,7 @@
     size_t pointer_index) const {
   DCHECK_LT(pointer_index, cached_pointer_count_);
   if (pointer_index < MAX_POINTERS_TO_CACHE)
-    return cached_tool_types_[pointer_index];
+    return cached_pointers_[pointer_index].tool_type;
   return FromAndroidToolType(Java_MotionEvent_getToolType(
       AttachCurrentThread(), event_.obj(), pointer_index));
 }
@@ -391,36 +301,21 @@
   return cached_flags_;
 }
 
-scoped_ptr<ui::MotionEvent> MotionEventAndroid::Clone() const {
-  return scoped_ptr<MotionEvent>(new MotionEventAndroid(*this));
-}
-
-scoped_ptr<ui::MotionEvent> MotionEventAndroid::Cancel() const {
-  // The input coordinates to |MotionEventAndroid| are always in device pixels,
-  // but the cached coordinates are in DIPs.
-  const gfx::PointF position_pixels =
-      gfx::ScalePoint(cached_positions_[0], 1.f / pix_to_dip_);
-  return scoped_ptr<MotionEvent>(
-      new MotionEventAndroid(pix_to_dip_,
-                             AttachCurrentThread(),
-                             Obtain(GetDownTime(),
-                                    GetEventTime(),
-                                    MotionEventAndroid::ACTION_CANCEL,
-                                    position_pixels.x(),
-                                    position_pixels.y()).obj()));
-}
-
-base::TimeTicks MotionEventAndroid::GetDownTime() const {
-  return FromAndroidTime(
-      Java_MotionEvent_getDownTime(AttachCurrentThread(), event_.obj()));
-}
-
 float MotionEventAndroid::ToDips(float pixels) const {
   return pixels * pix_to_dip_;
 }
 
-gfx::PointF MotionEventAndroid::ToDips(const gfx::PointF& point_pixels) const {
-  return gfx::ScalePoint(point_pixels, pix_to_dip_);
+MotionEventAndroid::CachedPointer MotionEventAndroid::FromAndroidPointer(
+    const Pointer& pointer) const {
+  CachedPointer result;
+  result.id = pointer.id;
+  result.position =
+      gfx::PointF(ToDips(pointer.pos_x_pixels), ToDips(pointer.pos_y_pixels));
+  result.touch_major = ToDips(pointer.touch_major_pixels);
+  result.touch_minor = ToDips(pointer.touch_minor_pixels);
+  result.orientation = ToValidFloat(pointer.orientation_rad);
+  result.tool_type = FromAndroidToolType(pointer.tool_type);
+  return result;
 }
 
 // static
@@ -428,27 +323,4 @@
   return JNI_MotionEvent::RegisterNativesImpl(env);
 }
 
-// static
-base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain(
-    const MotionEventAndroid& event) {
-  return Java_MotionEvent_obtainAVME_AVME(AttachCurrentThread(),
-                                          event.event_.obj());
-}
-
-// static
-base::android::ScopedJavaLocalRef<jobject> MotionEventAndroid::Obtain(
-    base::TimeTicks down_time,
-    base::TimeTicks event_time,
-    Action action,
-    float x_pixels,
-    float y_pixels) {
-  return Java_MotionEvent_obtainAVME_J_J_I_F_F_I(AttachCurrentThread(),
-                                                 ToAndroidTime(down_time),
-                                                 ToAndroidTime(event_time),
-                                                 ToAndroidAction(action),
-                                                 x_pixels,
-                                                 y_pixels,
-                                                 0);
-}
-
 }  // namespace content
diff --git a/content/browser/renderer_host/input/motion_event_android.h b/content/browser/renderer_host/input/motion_event_android.h
index 95224dc..4af9f72 100644
--- a/content/browser/renderer_host/input/motion_event_android.h
+++ b/content/browser/renderer_host/input/motion_event_android.h
@@ -1,3 +1,4 @@
+
 // 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.
@@ -21,6 +22,23 @@
 // while all *output* coordinates are in DIPs (as with WebTouchEvent).
 class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
  public:
+  struct Pointer {
+    Pointer(jint id,
+            jfloat pos_x_pixels,
+            jfloat pos_y_pixels,
+            jfloat touch_major_pixels,
+            jfloat touch_minor_pixels,
+            jfloat orientation_rad,
+            jint tool_type);
+    jint id;
+    jfloat pos_x_pixels;
+    jfloat pos_y_pixels;
+    jfloat touch_major_pixels;
+    jfloat touch_minor_pixels;
+    jfloat orientation_rad;
+    jint tool_type;
+  };
+
   // Forcing the caller to provide all cached values upon construction
   // eliminates the need to perform a JNI call to retrieve values individually.
   MotionEventAndroid(float pix_to_dip,
@@ -31,24 +49,12 @@
                      jint pointer_count,
                      jint history_size,
                      jint action_index,
-                     jfloat pos_x_0_pixels,
-                     jfloat pos_y_0_pixels,
-                     jfloat pos_x_1_pixels,
-                     jfloat pos_y_1_pixels,
-                     jint pointer_id_0,
-                     jint pointer_id_1,
-                     jfloat touch_major_0_pixels,
-                     jfloat touch_major_1_pixels,
-                     jfloat touch_minor_0_pixels,
-                     jfloat touch_minor_1_pixels,
-                     jfloat orientation_0_rad,
-                     jfloat orientation_1_rad,
-                     jfloat raw_pos_x_pixels,
-                     jfloat raw_pos_y_pixels,
-                     jint android_tool_type_0,
-                     jint android_tool_type_1,
                      jint android_button_state,
-                     jint meta_state);
+                     jint meta_state,
+                     jfloat raw_offset_x_pixels,
+                     jfloat raw_offset_y_pixels,
+                     const Pointer& pointer0,
+                     const Pointer& pointer1);
   virtual ~MotionEventAndroid();
 
   // ui::MotionEvent methods.
@@ -78,31 +84,14 @@
   virtual ToolType GetToolType(size_t pointer_index) const override;
   virtual int GetButtonState() const override;
   virtual int GetFlags() const override;
-  virtual scoped_ptr<MotionEvent> Clone() const override;
-  virtual scoped_ptr<MotionEvent> Cancel() const override;
-
-  // Additional Android MotionEvent methods.
-  base::TimeTicks GetDownTime() const;
 
   static bool RegisterMotionEventAndroid(JNIEnv* env);
 
-  static base::android::ScopedJavaLocalRef<jobject> Obtain(
-      const MotionEventAndroid& event);
-  static base::android::ScopedJavaLocalRef<jobject> Obtain(
-      base::TimeTicks down_time,
-      base::TimeTicks event_time,
-      Action action,
-      float x_pixels,
-      float y_pixels);
-
  private:
-  MotionEventAndroid();
-  MotionEventAndroid(float pix_to_dip, JNIEnv* env, jobject event);
-  MotionEventAndroid(const MotionEventAndroid&);
-  MotionEventAndroid& operator=(const MotionEventAndroid&);
+  struct CachedPointer;
 
   float ToDips(float pixels) const;
-  gfx::PointF ToDips(const gfx::PointF& pixels) const;
+  CachedPointer FromAndroidPointer(const Pointer& pointer) const;
 
   // Cache pointer coords, id's and major lengths for the most common
   // touch-related scenarios, i.e., scrolling and pinching.  This prevents
@@ -112,28 +101,29 @@
   // The Java reference to the underlying MotionEvent.
   base::android::ScopedJavaGlobalRef<jobject> event_;
 
-  base::TimeTicks cached_time_;
-  Action cached_action_;
-  size_t cached_pointer_count_;
-  size_t cached_history_size_;
-  int cached_action_index_;
-  gfx::PointF cached_positions_[MAX_POINTERS_TO_CACHE];
-  int cached_pointer_ids_[MAX_POINTERS_TO_CACHE];
-  float cached_touch_majors_[MAX_POINTERS_TO_CACHE];
-  float cached_touch_minors_[MAX_POINTERS_TO_CACHE];
-  float cached_orientations_[MAX_POINTERS_TO_CACHE];
-  gfx::Vector2dF cached_raw_position_offset_;
-  ToolType cached_tool_types_[MAX_POINTERS_TO_CACHE];
-  int cached_button_state_;
-  int cached_flags_;
-
   // Used to convert pixel coordinates from the Java-backed MotionEvent to
   // DIP coordinates cached/returned by the MotionEventAndroid.
   const float pix_to_dip_;
 
-  // Whether |event_| should be recycled on destruction. This will only be true
-  // for those events generated via |Obtain(...)|.
-  bool should_recycle_;
+  const base::TimeTicks cached_time_;
+  const Action cached_action_;
+  const size_t cached_pointer_count_;
+  const size_t cached_history_size_;
+  const int cached_action_index_;
+  const int cached_button_state_;
+  const int cached_flags_;
+  const gfx::Vector2dF cached_raw_position_offset_;
+  struct CachedPointer {
+    CachedPointer();
+    int id;
+    gfx::PointF position;
+    float touch_major;
+    float touch_minor;
+    float orientation;
+    ToolType tool_type;
+  } cached_pointers_[MAX_POINTERS_TO_CACHE];
+
+  DISALLOW_COPY_AND_ASSIGN(MotionEventAndroid);
 };
 
 }  // namespace content
diff --git a/content/browser/renderer_host/input/motion_event_android_unittest.cc b/content/browser/renderer_host/input/motion_event_android_unittest.cc
index ced6c1a..d7482d9a 100644
--- a/content/browser/renderer_host/input/motion_event_android_unittest.cc
+++ b/content/browser/renderer_host/input/motion_event_android_unittest.cc
@@ -9,6 +9,7 @@
 #include "content/browser/renderer_host/input/motion_event_android.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event_constants.h"
+#include "ui/events/test/motion_event_test_utils.h"
 
 using ui::MotionEvent;
 
@@ -31,76 +32,54 @@
 
 }  // namespace
 
+// Note that these tests avoid creating a Java instance of the MotionEvent, as
+// we're primarily testing caching behavior, and the code necessary to
+// construct a Java-backed MotionEvent itself adds unnecessary complexity.
 TEST(MotionEventAndroidTest, Constructor) {
   int event_time_ms = 5;
   base::TimeTicks event_time =
       base::TimeTicks() + base::TimeDelta::FromMilliseconds(event_time_ms);
-  float x0 = 13.7f;
-  float y0 = -7.13f;
-  float x1 = -13.7f;
-  float y1 = 7.13f;
-  float raw_offset = 10.1f;
-  float touch_major0 = 5.3f;
-  float touch_major1 = 3.5f;
-  float touch_minor0 = 1.2f;
-  float touch_minor1 = 2.1f;
-  float orientation0 = 0.1f;
-  float orientation1 = -0.1f;
-  int p0 = 1;
-  int p1 = 2;
+  MotionEventAndroid::Pointer p0(
+      1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
+  MotionEventAndroid::Pointer p1(
+      2, -13.7f, 7.13f, 3.5f, 12.1f, -0.1f, kAndroidToolTypeFinger);
+  float raw_offset = -3.f;
   int pointer_count = 2;
   int history_size = 0;
   int action_index = -1;
-  base::android::ScopedJavaLocalRef<jobject> base_event_obj =
-      MotionEventAndroid::Obtain(
-          event_time, event_time, MotionEvent::ACTION_DOWN, x0, y0);
-  ASSERT_TRUE(base_event_obj.obj());
-
   MotionEventAndroid event(kPixToDip,
                            base::android::AttachCurrentThread(),
-                           base_event_obj.obj(),
+                           nullptr,
                            event_time_ms,
                            kAndroidActionDown,
                            pointer_count,
                            history_size,
                            action_index,
-                           x0,
-                           y0,
-                           x1,
-                           y1,
-                           p0,
-                           p1,
-                           touch_major0,
-                           touch_major1,
-                           touch_minor0,
-                           touch_minor1,
-                           orientation0,
-                           orientation1,
-                           x0 + raw_offset,
-                           y0 - raw_offset,
-                           kAndroidToolTypeFinger,
-                           kAndroidToolTypeFinger,
                            kAndroidButtonPrimary,
-                           kAndroidAltKeyDown);
+                           kAndroidAltKeyDown,
+                           raw_offset,
+                           -raw_offset,
+                           p0,
+                           p1);
 
   EXPECT_EQ(MotionEvent::ACTION_DOWN, event.GetAction());
   EXPECT_EQ(event_time, event.GetEventTime());
-  EXPECT_EQ(x0 * kPixToDip, event.GetX(0));
-  EXPECT_EQ(y0 * kPixToDip, event.GetY(0));
-  EXPECT_EQ(x1 * kPixToDip, event.GetX(1));
-  EXPECT_EQ(y1 * kPixToDip, event.GetY(1));
-  EXPECT_FLOAT_EQ((x0 + raw_offset) * kPixToDip, event.GetRawX(0));
-  EXPECT_FLOAT_EQ((y0 - raw_offset) * kPixToDip, event.GetRawY(0));
-  EXPECT_FLOAT_EQ((x1 + raw_offset) * kPixToDip, event.GetRawX(1));
-  EXPECT_FLOAT_EQ((y1 - raw_offset) * kPixToDip, event.GetRawY(1));
-  EXPECT_EQ(touch_major0 * kPixToDip, event.GetTouchMajor(0));
-  EXPECT_EQ(touch_major1 * kPixToDip, event.GetTouchMajor(1));
-  EXPECT_EQ(touch_minor0 * kPixToDip, event.GetTouchMinor(0));
-  EXPECT_EQ(touch_minor1 * kPixToDip, event.GetTouchMinor(1));
-  EXPECT_EQ(orientation0, event.GetOrientation(0));
-  EXPECT_EQ(orientation1, event.GetOrientation(1));
-  EXPECT_EQ(p0, event.GetPointerId(0));
-  EXPECT_EQ(p1, event.GetPointerId(1));
+  EXPECT_EQ(p0.pos_x_pixels * kPixToDip, event.GetX(0));
+  EXPECT_EQ(p0.pos_y_pixels * kPixToDip, event.GetY(0));
+  EXPECT_EQ(p1.pos_x_pixels * kPixToDip, event.GetX(1));
+  EXPECT_EQ(p1.pos_y_pixels * kPixToDip, event.GetY(1));
+  EXPECT_FLOAT_EQ((p0.pos_x_pixels + raw_offset) * kPixToDip, event.GetRawX(0));
+  EXPECT_FLOAT_EQ((p0.pos_y_pixels - raw_offset) * kPixToDip, event.GetRawY(0));
+  EXPECT_FLOAT_EQ((p1.pos_x_pixels + raw_offset) * kPixToDip, event.GetRawX(1));
+  EXPECT_FLOAT_EQ((p1.pos_y_pixels - raw_offset) * kPixToDip, event.GetRawY(1));
+  EXPECT_EQ(p0.touch_major_pixels * kPixToDip, event.GetTouchMajor(0));
+  EXPECT_EQ(p1.touch_major_pixels * kPixToDip, event.GetTouchMajor(1));
+  EXPECT_EQ(p0.touch_minor_pixels * kPixToDip, event.GetTouchMinor(0));
+  EXPECT_EQ(p1.touch_minor_pixels * kPixToDip, event.GetTouchMinor(1));
+  EXPECT_EQ(p0.orientation_rad, event.GetOrientation(0));
+  EXPECT_EQ(p1.orientation_rad, event.GetOrientation(1));
+  EXPECT_EQ(p0.id, event.GetPointerId(0));
+  EXPECT_EQ(p1.id, event.GetPointerId(1));
   EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(0));
   EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(1));
   EXPECT_EQ(MotionEvent::BUTTON_PRIMARY, event.GetButtonState());
@@ -111,114 +90,71 @@
 }
 
 TEST(MotionEventAndroidTest, Clone) {
-  int event_time_ms = 5;
-  base::TimeTicks event_time =
-      base::TimeTicks() + base::TimeDelta::FromMilliseconds(event_time_ms);
-  float x = 13.7f;
-  float y = -7.13f;
-  float touch_major = 5.3f;
-  float touch_minor = 3.5f;
-  float orientation = 0.2f;
-  int pointer_count = 1;
-  int pointer_id = 1;
-  base::android::ScopedJavaLocalRef<jobject> event_obj =
-      MotionEventAndroid::Obtain(
-          event_time, event_time, MotionEvent::ACTION_DOWN, x, y);
-  ASSERT_TRUE(event_obj.obj());
-
+  const int pointer_count = 1;
+  MotionEventAndroid::Pointer p0(
+      1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
+  MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0);
   MotionEventAndroid event(kPixToDip,
                            base::android::AttachCurrentThread(),
-                           event_obj.obj(),
-                           event_time_ms,
+                           nullptr,
+                           0,
                            kAndroidActionDown,
                            pointer_count,
                            0,
                            0,
-                           x,
-                           y,
-                           0,
-                           0,
-                           pointer_id,
-                           0,
-                           touch_major,
-                           0.f,
-                           touch_minor,
-                           0.f,
-                           orientation,
-                           0.f,
-                           x,
-                           y,
                            0,
                            0,
                            0,
-                           0);
+                           0,
+                           p0,
+                           p1);
 
   scoped_ptr<MotionEvent> clone = event.Clone();
-  EXPECT_EQ(event, *clone);
+  EXPECT_EQ(ui::test::ToString(event), ui::test::ToString(*clone));
 }
 
 TEST(MotionEventAndroidTest, Cancel) {
-  int event_time_ms = 5;
-  base::TimeTicks event_time =
-      base::TimeTicks() + base::TimeDelta::FromMilliseconds(event_time_ms);
-  int pointer_count = 1;
-  float x = 13.7f;
-  float y = -7.13f;
-  base::android::ScopedJavaLocalRef<jobject> event_obj =
-      MotionEventAndroid::Obtain(
-          event_time, event_time, MotionEvent::ACTION_DOWN, x, y);
-  ASSERT_TRUE(event_obj.obj());
-
+  const int event_time_ms = 5;
+  const int pointer_count = 1;
+  MotionEventAndroid::Pointer p0(
+      1, 13.7f, -7.13f, 5.3f, 1.2f, 0.1f, kAndroidToolTypeFinger);
+  MotionEventAndroid::Pointer p1(0, 0, 0, 0, 0, 0, 0);
   MotionEventAndroid event(kPixToDip,
                            base::android::AttachCurrentThread(),
-                           event_obj.obj(),
+                           nullptr,
                            event_time_ms,
                            kAndroidActionDown,
                            pointer_count,
                            0,
                            0,
-                           x,
-                           y,
                            0,
                            0,
                            0,
                            0,
-                           0.f,
-                           0.f,
-                           0.f,
-                           0.f,
-                           0.f,
-                           0.f,
-                           x,
-                           y,
-                           0,
-                           0,
-                           0,
-                           0);
+                           p0,
+                           p1);
 
   scoped_ptr<MotionEvent> cancel_event = event.Cancel();
   EXPECT_EQ(MotionEvent::ACTION_CANCEL, cancel_event->GetAction());
-  EXPECT_EQ(event_time, cancel_event->GetEventTime());
-  EXPECT_EQ(x * kPixToDip, cancel_event->GetX(0));
-  EXPECT_EQ(y * kPixToDip, cancel_event->GetY(0));
+  EXPECT_EQ(
+      base::TimeTicks() + base::TimeDelta::FromMilliseconds(event_time_ms),
+      cancel_event->GetEventTime());
+  EXPECT_EQ(p0.pos_x_pixels * kPixToDip, cancel_event->GetX(0));
+  EXPECT_EQ(p0.pos_y_pixels * kPixToDip, cancel_event->GetY(0));
   EXPECT_EQ(static_cast<size_t>(pointer_count),
             cancel_event->GetPointerCount());
   EXPECT_EQ(0U, cancel_event->GetHistorySize());
 }
 
 TEST(MotionEventAndroidTest, InvalidOrientationsSanitized) {
-  base::TimeTicks event_time;
   int pointer_count = 2;
   float orientation0 = 1e10f;
   float orientation1 = std::numeric_limits<float>::quiet_NaN();
-  base::android::ScopedJavaLocalRef<jobject> base_event_obj =
-      MotionEventAndroid::Obtain(
-          event_time, event_time, MotionEvent::ACTION_DOWN, 0, 0);
-  ASSERT_TRUE(base_event_obj.obj());
-
+  MotionEventAndroid::Pointer p0(0, 0, 0, 0, 0, orientation0, 0);
+  MotionEventAndroid::Pointer p1(1, 0, 0, 0, 0, orientation1, 0);
   MotionEventAndroid event(kPixToDip,
                            base::android::AttachCurrentThread(),
-                           base_event_obj.obj(),
+                           nullptr,
                            0,
                            kAndroidActionDown,
                            pointer_count,
@@ -228,20 +164,8 @@
                            0,
                            0,
                            0,
-                           0,
-                           0,
-                           0,
-                           0,
-                           0,
-                           0,
-                           orientation0,
-                           orientation1,
-                           0,
-                           0,
-                           0,
-                           0,
-                           0,
-                           0);
+                           p0,
+                           p1);
 
   EXPECT_EQ(0.f, event.GetOrientation(0));
   EXPECT_EQ(0.f, event.GetOrientation(1));
diff --git a/content/browser/renderer_host/input/motion_event_web.cc b/content/browser/renderer_host/input/motion_event_web.cc
index bff4535..77a40a4 100644
--- a/content/browser/renderer_host/input/motion_event_web.cc
+++ b/content/browser/renderer_host/input/motion_event_web.cc
@@ -155,7 +155,6 @@
 }
 
 int MotionEventWeb::GetButtonState() const {
-  NOTIMPLEMENTED();
   return 0;
 }
 
@@ -163,18 +162,4 @@
   return WebEventModifiersToEventFlags(event_.modifiers);
 }
 
-scoped_ptr<ui::MotionEvent> MotionEventWeb::Clone() const {
-  return scoped_ptr<MotionEvent>(new MotionEventWeb(event_));
-}
-
-scoped_ptr<ui::MotionEvent> MotionEventWeb::Cancel() const {
-  WebTouchEvent cancel_event(event_);
-  WebTouchEventTraits::ResetTypeAndTouchStates(
-      blink::WebInputEvent::TouchCancel,
-      // TODO(rbyers): Shouldn't we use a fresh timestamp?
-      event_.timeStampSeconds,
-      &cancel_event);
-  return scoped_ptr<MotionEvent>(new MotionEventWeb(cancel_event));
-}
-
 }  // namespace content
diff --git a/content/browser/renderer_host/input/motion_event_web.h b/content/browser/renderer_host/input/motion_event_web.h
index 8177a9f..f3d85abf 100644
--- a/content/browser/renderer_host/input/motion_event_web.h
+++ b/content/browser/renderer_host/input/motion_event_web.h
@@ -34,8 +34,6 @@
   ToolType GetToolType(size_t pointer_index) const override;
   int GetButtonState() const override;
   int GetFlags() const override;
-  scoped_ptr<MotionEvent> Clone() const override;
-  scoped_ptr<MotionEvent> Cancel() const override;
 
  private:
   blink::WebTouchEvent event_;
diff --git a/content/browser/renderer_host/input/touch_handle_unittest.cc b/content/browser/renderer_host/input/touch_handle_unittest.cc
index 28ba7a5..94f92a5e 100644
--- a/content/browser/renderer_host/input/touch_handle_unittest.cc
+++ b/content/browser/renderer_host/input/touch_handle_unittest.cc
@@ -5,7 +5,7 @@
 #include "content/browser/renderer_host/input/touch_handle.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
 #include "ui/gfx/geometry/rect_f.h"
 
 using ui::test::MockMotionEvent;
diff --git a/content/browser/renderer_host/input/touch_selection_controller_unittest.cc b/content/browser/renderer_host/input/touch_selection_controller_unittest.cc
index 1b3451ee..3b20b02 100644
--- a/content/browser/renderer_host/input/touch_selection_controller_unittest.cc
+++ b/content/browser/renderer_host/input/touch_selection_controller_unittest.cc
@@ -5,7 +5,7 @@
 #include "content/browser/renderer_host/input/touch_selection_controller.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
 
 using ui::test::MockMotionEvent;
 
diff --git a/content/browser/renderer_host/input/web_input_event_util_unittest.cc b/content/browser/renderer_host/input/web_input_event_util_unittest.cc
index 1c1c7be..1d29a07 100644
--- a/content/browser/renderer_host/input/web_input_event_util_unittest.cc
+++ b/content/browser/renderer_host/input/web_input_event_util_unittest.cc
@@ -24,13 +24,12 @@
 namespace content {
 
 TEST(WebInputEventUtilTest, MotionEventConversion) {
-  ui::PointerProperties pointer(5, 10);
+  ui::PointerProperties pointer(5, 10, 40);
   pointer.id = 15;
   pointer.raw_x = 20;
   pointer.raw_y = 25;
   pointer.pressure = 30;
   pointer.touch_minor = 35;
-  pointer.touch_major = 40;
   pointer.orientation = static_cast<float>(-M_PI / 2);
   MotionEventGeneric event(
       MotionEvent::ACTION_DOWN, base::TimeTicks::Now(), pointer);
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc
index 83aa43c..7b421ba 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -389,16 +389,17 @@
         entry->writer.get(),
         user_input_monitor_);
   } else {
-    // TODO(henrika): replace CreateLowLatency() with Create() as soon
-    // as satish has ensured that Speech Input also uses the default low-
-    // latency path. See crbug.com/112472 for details.
-    entry->controller =
-        media::AudioInputController::CreateLowLatency(audio_manager_,
-                                                      this,
-                                                      audio_params,
-                                                      device_id,
-                                                      entry->writer.get(),
-                                                      user_input_monitor_);
+    DCHECK_EQ(config.params.format(),
+              media::AudioParameters::AUDIO_PCM_LOW_LATENCY);
+    entry->controller = media::AudioInputController::CreateLowLatency(
+        audio_manager_,
+        this,
+        audio_params,
+        device_id,
+        entry->writer.get(),
+        user_input_monitor_,
+        config.automatic_gain_control);
+    oss << ", AGC=" << config.automatic_gain_control;
   }
 
   if (!entry->controller.get()) {
@@ -407,13 +408,6 @@
     return;
   }
 
-  // Set the initial AGC state for the audio input stream. Note that, the AGC
-  // is only supported in AUDIO_PCM_LOW_LATENCY mode.
-  if (config.params.format() == media::AudioParameters::AUDIO_PCM_LOW_LATENCY) {
-    entry->controller->SetAutomaticGainControl(config.automatic_gain_control);
-    oss << ", AGC=" << config.automatic_gain_control;
-  }
-
 #if defined(OS_CHROMEOS)
   if (config.params.channel_layout() ==
           media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) {
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index fa0a4065..aa38131 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -92,7 +92,6 @@
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/browser/renderer_host/render_widget_helper.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/browser/renderer_host/socket_stream_dispatcher_host.h"
 #include "content/browser/renderer_host/text_input_client_message_filter.h"
 #include "content/browser/renderer_host/websocket_dispatcher_host.h"
 #include "content/browser/resolve_proxy_msg_helper.h"
@@ -799,16 +798,6 @@
   AddFilter(browser_cdm_manager_.get());
 #endif
 
-  SocketStreamDispatcherHost::GetRequestContextCallback
-      request_context_callback(
-          base::Bind(&GetRequestContext, request_context,
-                     media_request_context));
-
-  SocketStreamDispatcherHost* socket_stream_dispatcher_host =
-      new SocketStreamDispatcherHost(
-          GetID(), request_context_callback, resource_context);
-  AddFilter(socket_stream_dispatcher_host);
-
   WebSocketDispatcherHost::GetRequestContextCallback
       websocket_request_context_callback(
           base::Bind(&GetRequestContext, request_context,
@@ -875,7 +864,8 @@
 #if defined(OS_ANDROID)
   AddFilter(new ScreenOrientationMessageFilterAndroid());
 #endif
-  AddFilter(new GeofencingDispatcherHost(browser_context_));
+  AddFilter(new GeofencingDispatcherHost(
+      storage_partition_impl_->GetGeofencingManager()));
 }
 
 int RenderProcessHostImpl::GetNextRoutingID() {
@@ -902,11 +892,14 @@
   return mojo_application_host_->service_registry();
 }
 
+const base::TimeTicks& RenderProcessHostImpl::GetInitTimeForNavigationMetrics()
+    const {
+  return init_time_;
+}
+
 void RenderProcessHostImpl::AddRoute(
     int32 routing_id,
     IPC::Listener* listener) {
-  CHECK(widget_helper_->IsRoutingIDProbablyValid(routing_id))
-      << "Found Invalid Routing ID: " << routing_id;
   CHECK(!listeners_.Lookup(routing_id))
       << "Found Routing ID Conflict: " << routing_id;
   listeners_.AddWithID(listener, routing_id);
@@ -1242,6 +1235,7 @@
 #endif
 #if defined(OS_WIN)
     switches::kDisableDirectWrite,
+    switches::kEnableWin32kRendererLockDown,
 #endif
 #if defined(OS_CHROMEOS)
     switches::kDisableVaapiAcceleratedVideoEncode,
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 7ab0dc2..76d6d35 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -137,6 +137,7 @@
   void ResumeDeferredNavigation(const GlobalRequestID& request_id) override;
   void NotifyTimezoneChange() override;
   ServiceRegistry* GetServiceRegistry() override;
+  const base::TimeTicks& GetInitTimeForNavigationMetrics() const override;
 
   // IPC::Sender via RenderProcessHost.
   bool Send(IPC::Message* msg) override;
@@ -254,13 +255,6 @@
   // immediately after receiving response headers.
   void ResumeResponseDeferredAtStart(const GlobalRequestID& request_id);
 
-  // PlzNavigate
-  // Returns the time the first call to Init completed successfully (after a new
-  // renderer process was created); further calls to Init won't change this
-  // value.
-  // Note: Will disappear after PlzNavitate is completed.
-  const base::TimeTicks& init_time() const { return init_time_; }
-
  protected:
   // A proxy for our IPC::Channel that lives on the IO thread (see
   // browser_process.h)
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h
index 2e467bc..b7074f5 100644
--- a/content/browser/renderer_host/render_view_host_delegate.h
+++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -106,7 +106,6 @@
 
   // The state for the page changed and should be updated.
   virtual void UpdateState(RenderViewHost* render_view_host,
-                           int32 rvh_page_id,  // http://crbug.com/407376
                            int32 page_id,
                            const PageState& state) {}
 
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index cb050e4..ad6908c3 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -1028,7 +1028,7 @@
     return;
   }
 
-  delegate_->UpdateState(this, page_id_, page_id, state);
+  delegate_->UpdateState(this, page_id, state);
 }
 
 void RenderViewHostImpl::OnUpdateTargetURL(const GURL& url) {
diff --git a/content/browser/renderer_host/render_widget_helper.cc b/content/browser/renderer_host/render_widget_helper.cc
index b5bb50f..9261de92 100644
--- a/content/browser/renderer_host/render_widget_helper.cc
+++ b/content/browser/renderer_host/render_widget_helper.cc
@@ -16,7 +16,6 @@
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/renderer_host/routing_id_issuer.h"
 #include "content/common/view_messages.h"
 
 namespace content {
@@ -38,7 +37,6 @@
 
 RenderWidgetHelper::RenderWidgetHelper()
     : render_process_id_(-1),
-      routing_id_issuer_(RoutingIDIssuer::Create()),
       resource_dispatcher_host_(NULL) {
 }
 
@@ -69,11 +67,7 @@
 }
 
 int RenderWidgetHelper::GetNextRoutingID() {
-  return routing_id_issuer_->IssueNext();
-}
-
-bool RenderWidgetHelper::IsRoutingIDProbablyValid(int routing_id) const {
-  return routing_id_issuer_->IsProbablyValid(routing_id);
+  return next_routing_id_.GetNext() + 1;
 }
 
 // static
diff --git a/content/browser/renderer_host/render_widget_helper.h b/content/browser/renderer_host/render_widget_helper.h
index 4e09bdf..98b3ca6 100644
--- a/content/browser/renderer_host/render_widget_helper.h
+++ b/content/browser/renderer_host/render_widget_helper.h
@@ -7,9 +7,9 @@
 
 #include <map>
 
+#include "base/atomic_sequence_num.h"
 #include "base/containers/hash_tables.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/process/process.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
@@ -33,7 +33,6 @@
 namespace content {
 class GpuProcessHost;
 class ResourceDispatcherHostImpl;
-class RoutingIDIssuer;
 class SessionStorageNamespace;
 
 // Instantiated per RenderProcessHost to provide various optimizations on
@@ -81,9 +80,6 @@
 
   // Gets the next available routing id.  This is thread safe.
   int GetNextRoutingID();
-  // Probablistically verify if the ID is issued by this helper.
-  // Thread safe.
-  bool IsRoutingIDProbablyValid(int routing_id) const;
 
   // IO THREAD ONLY -----------------------------------------------------------
 
@@ -179,7 +175,8 @@
 
   int render_process_id_;
 
-  scoped_ptr<RoutingIDIssuer> routing_id_issuer_;
+  // The next routing id to use.
+  base::AtomicSequenceNumber next_routing_id_;
 
   ResourceDispatcherHostImpl* resource_dispatcher_host_;
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 47cfba2..8d0d24c 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -65,9 +65,9 @@
 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
 #include "ui/events/event.h"
 #include "ui/events/keycodes/keyboard_codes.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 #include "ui/gfx/size_conversions.h"
 #include "ui/gfx/skbitmap_operations.h"
-#include "ui/gfx/vector2d_conversions.h"
 #include "ui/snapshot/snapshot.h"
 
 #if defined(OS_WIN)
@@ -1680,9 +1680,10 @@
 void RenderWidgetHostImpl::OnTextInputTypeChanged(
     ui::TextInputType type,
     ui::TextInputMode input_mode,
-    bool can_compose_inline) {
+    bool can_compose_inline,
+    int flags) {
   if (view_)
-    view_->TextInputTypeChanged(type, input_mode, can_compose_inline);
+    view_->TextInputTypeChanged(type, input_mode, can_compose_inline, flags);
 }
 
 #if defined(OS_MACOSX) || defined(USE_AURA)
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index de95733..8423beb 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -598,7 +598,8 @@
   void OnSetCursor(const WebCursor& cursor);
   void OnTextInputTypeChanged(ui::TextInputType type,
                               ui::TextInputMode input_mode,
-                              bool can_compose_inline);
+                              bool can_compose_inline,
+                              int flags);
 
 #if defined(OS_MACOSX) || defined(USE_AURA)
   void OnImeCompositionRangeChanged(
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 5d610ae8c..de30353 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -760,7 +760,7 @@
   host_->SetView(view.get());
 
   EXPECT_TRUE(view->GetBackgroundOpaque());
-  view->SetBackgroundOpaque(false);
+  view->SetBackgroundColor(SK_ColorTRANSPARENT);
   EXPECT_FALSE(view->GetBackgroundOpaque());
 
   const IPC::Message* set_background =
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 1c97a71..af88a1b 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -625,7 +625,8 @@
 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
     ui::TextInputType type,
     ui::TextInputMode input_mode,
-    bool can_compose_inline) {
+    bool can_compose_inline,
+    int flags) {
   // Unused on Android, which uses OnTextInputChanged instead.
 }
 
@@ -820,9 +821,10 @@
   NOTREACHED() << "Selection bounds should be routed through the compositor.";
 }
 
-void RenderWidgetHostViewAndroid::SetBackgroundOpaque(bool opaque) {
-  RenderWidgetHostViewBase::SetBackgroundOpaque(opaque);
-  host_->SetBackgroundOpaque(opaque);
+void RenderWidgetHostViewAndroid::SetBackgroundColor(SkColor color) {
+  RenderWidgetHostViewBase::SetBackgroundColor(color);
+  host_->SetBackgroundOpaque(GetBackgroundOpaque());
+  OnDidChangeBodyBackgroundColor(color);
 }
 
 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index e99bda74..8433a96 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -127,7 +127,8 @@
   virtual void SetIsLoading(bool is_loading) override;
   virtual void TextInputTypeChanged(ui::TextInputType type,
                                     ui::TextInputMode input_mode,
-                                    bool can_compose_inline) override;
+                                    bool can_compose_inline,
+                                    int flags) override;
   virtual void ImeCancelComposition() override;
   virtual void FocusedNodeChanged(bool is_editable_node) override;
   virtual void RenderProcessGone(base::TerminationStatus status,
@@ -141,7 +142,7 @@
       const ViewHostMsg_SelectionBounds_Params& params) override;
   virtual void AcceleratedSurfaceInitialized(int route_id) override;
   virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) override;
-  virtual void SetBackgroundOpaque(bool transparent) override;
+  virtual void SetBackgroundColor(SkColor color) override;
   virtual void CopyFromCompositingSurface(
       const gfx::Rect& src_subrect,
       const gfx::Size& dst_size,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index a7eb8d6..a735aff 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -441,6 +441,7 @@
       is_loading_(false),
       text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
       text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
+      text_input_flags_(0),
       can_compose_inline_(true),
       has_composition_text_(false),
       accept_return_character_(false),
@@ -494,7 +495,7 @@
   window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
   window_->Init(aura::WINDOW_LAYER_SOLID_COLOR);
   window_->SetName("RenderWidgetHostViewAura");
-  window_->layer()->SetColor(SK_ColorWHITE);
+  window_->layer()->SetColor(background_color_);
 }
 
 void RenderWidgetHostViewAura::InitAsPopup(
@@ -523,7 +524,7 @@
   window_->SetType(ui::wm::WINDOW_TYPE_MENU);
   window_->Init(aura::WINDOW_LAYER_SOLID_COLOR);
   window_->SetName("RenderWidgetHostViewAura");
-  window_->layer()->SetColor(SK_ColorWHITE);
+  window_->layer()->SetColor(background_color_);
 
   // Setting the transient child allows for the popup to get mouse events when
   // in a system modal dialog. Do this before calling ParentWindowWithContext
@@ -552,7 +553,7 @@
   window_->Init(aura::WINDOW_LAYER_SOLID_COLOR);
   window_->SetName("RenderWidgetHostViewAura");
   window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
-  window_->layer()->SetColor(SK_ColorWHITE);
+  window_->layer()->SetColor(background_color_);
 
   aura::Window* parent = NULL;
   gfx::Rect bounds;
@@ -823,12 +824,12 @@
   return window_->GetBoundsInScreen();
 }
 
-void RenderWidgetHostViewAura::SetBackgroundOpaque(bool opaque) {
-  RenderWidgetHostViewBase::SetBackgroundOpaque(opaque);
+void RenderWidgetHostViewAura::SetBackgroundColor(SkColor color) {
+  RenderWidgetHostViewBase::SetBackgroundColor(color);
+  bool opaque = GetBackgroundOpaque();
   host_->SetBackgroundOpaque(opaque);
   window_->layer()->SetFillsBoundsOpaquely(opaque);
-  SkColor background_color = opaque ? SK_ColorWHITE : SK_ColorTRANSPARENT;
-  window_->layer()->SetColor(background_color);
+  window_->layer()->SetColor(color);
 }
 
 gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() const {
@@ -860,13 +861,16 @@
 void RenderWidgetHostViewAura::TextInputTypeChanged(
     ui::TextInputType type,
     ui::TextInputMode input_mode,
-    bool can_compose_inline) {
+    bool can_compose_inline,
+    int flags) {
   if (text_input_type_ != type ||
       text_input_mode_ != input_mode ||
-      can_compose_inline_ != can_compose_inline) {
+      can_compose_inline_ != can_compose_inline ||
+      text_input_flags_ != flags) {
     text_input_type_ = type;
     text_input_mode_ = input_mode;
     can_compose_inline_ = can_compose_inline;
+    text_input_flags_ = flags;
     if (GetInputMethod())
       GetInputMethod()->OnTextInputTypeChanged(this);
     if (touch_editing_client_)
@@ -876,6 +880,7 @@
 
 void RenderWidgetHostViewAura::OnTextInputStateChanged(
     const ViewHostMsg_TextInputState_Params& params) {
+  text_input_flags_ = params.flags;
   if (params.show_ime_if_needed && params.type != ui::TEXT_INPUT_TYPE_NONE) {
     if (GetInputMethod())
       GetInputMethod()->ShowImeIfNeeded();
@@ -1461,6 +1466,10 @@
   return text_input_mode_;
 }
 
+int RenderWidgetHostViewAura::GetTextInputFlags() const {
+  return text_input_flags_;
+}
+
 bool RenderWidgetHostViewAura::CanComposeInline() const {
   return can_compose_inline_;
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 0a6ba5f..c814c97 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -154,7 +154,7 @@
   virtual void Hide() override;
   virtual bool IsShowing() override;
   virtual gfx::Rect GetViewBounds() const override;
-  virtual void SetBackgroundOpaque(bool opaque) override;
+  virtual void SetBackgroundColor(SkColor color) override;
   virtual gfx::Size GetVisibleViewportSize() const override;
   virtual void SetInsets(const gfx::Insets& insets) override;
 
@@ -173,7 +173,8 @@
   virtual void SetIsLoading(bool is_loading) override;
   virtual void TextInputTypeChanged(ui::TextInputType type,
                                     ui::TextInputMode input_mode,
-                                    bool can_compose_inline) override;
+                                    bool can_compose_inline,
+                                    int flags) override;
   virtual void ImeCancelComposition() override;
   virtual void ImeCompositionRangeChanged(
       const gfx::Range& range,
@@ -247,6 +248,7 @@
   virtual gfx::NativeWindow GetAttachedWindow() const override;
   virtual ui::TextInputType GetTextInputType() const override;
   virtual ui::TextInputMode GetTextInputMode() const override;
+  virtual int GetTextInputFlags() const override;
   virtual bool CanComposeInline() const override;
   virtual gfx::Rect GetCaretBounds() const override;
   virtual bool GetCompositionCharacterBounds(uint32 index,
@@ -527,6 +529,8 @@
   ui::TextInputType text_input_type_;
   // The current text input mode corresponding to HTML5 inputmode attribute.
   ui::TextInputMode text_input_mode_;
+  // The current text input flags.
+  int text_input_flags_;
   bool can_compose_inline_;
 
   // Rectangles for the selection anchor and focus.
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index fcd41f0..b11990a 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -366,7 +366,7 @@
 
 RenderWidgetHostViewBase::RenderWidgetHostViewBase()
     : popup_type_(blink::WebPopupTypeNone),
-      background_opaque_(true),
+      background_color_(SK_ColorWHITE),
       mouse_locked_(false),
       showing_context_menu_(false),
       selection_text_offset_(0),
@@ -386,12 +386,16 @@
   return false;
 }
 
-void RenderWidgetHostViewBase::SetBackgroundOpaque(bool opaque) {
-  background_opaque_ = opaque;
+void RenderWidgetHostViewBase::SetBackgroundColor(SkColor color) {
+  background_color_ = color;
+}
+
+void RenderWidgetHostViewBase::SetBackgroundColorToDefault() {
+  SetBackgroundColor(SK_ColorWHITE);
 }
 
 bool RenderWidgetHostViewBase::GetBackgroundOpaque() {
-  return background_opaque_;
+  return SkColorGetA(background_color_) == SK_AlphaOPAQUE;
 }
 
 gfx::Size RenderWidgetHostViewBase::GetPhysicalBackingSize() const {
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index d30bc5d6..b7e24b5 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -69,7 +69,8 @@
   ~RenderWidgetHostViewBase() override;
 
   // RenderWidgetHostView implementation.
-  void SetBackgroundOpaque(bool opaque) override;
+  void SetBackgroundColor(SkColor color) override;
+  void SetBackgroundColorToDefault() final override;
   bool GetBackgroundOpaque() override;
   ui::TextInputClient* GetTextInputClient() override;
   bool IsShowingContextMenu() const override;
@@ -222,7 +223,8 @@
   // Updates the type of the input method attached to the view.
   virtual void TextInputTypeChanged(ui::TextInputType type,
                                     ui::TextInputMode mode,
-                                    bool can_compose_inline) = 0;
+                                    bool can_compose_inline,
+                                    int flags) = 0;
 
   // Cancel the ongoing composition of the input method attached to the view.
   virtual void ImeCancelComposition() = 0;
@@ -379,8 +381,8 @@
   // autofill...).
   blink::WebPopupType popup_type_;
 
-  // When false, the background of the web content is not fully opaque.
-  bool background_opaque_;
+  // The background color of the web content.
+  SkColor background_color_;
 
   // While the mouse is locked, the cursor is hidden from the user. Mouse events
   // are still generated. However, the position they report is the last known
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h
index acab4f07e..f8d3522 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -253,7 +253,7 @@
   void SpeakSelection() override;
   bool IsSpeaking() const override;
   void StopSpeaking() override;
-  void SetBackgroundOpaque(bool opaque) override;
+  void SetBackgroundColor(SkColor color) override;
 
   // Implementation of RenderWidgetHostViewBase.
   void InitAsPopup(RenderWidgetHostView* parent_host_view,
@@ -268,7 +268,8 @@
   void SetIsLoading(bool is_loading) override;
   void TextInputTypeChanged(ui::TextInputType type,
                             ui::TextInputMode input_mode,
-                            bool can_compose_inline) override;
+                            bool can_compose_inline,
+                            int flags) override;
   void ImeCancelComposition() override;
   void ImeCompositionRangeChanged(
       const gfx::Range& range,
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 324599f7..e828190 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -58,6 +58,7 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "skia/ext/platform_canvas.h"
+#include "skia/ext/skia_utils_mac.h"
 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "third_party/WebKit/public/web/mac/WebInputEventFactory.h"
@@ -531,11 +532,11 @@
   cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc]
                   initWithRenderWidgetHostViewMac:this] autorelease];
 
-  // Make this view host a solid white layer when there is no content ready to
-  // draw.
+  // Paint this view host with |background_color_| when there is no content
+  // ready to draw.
   background_layer_.reset([[CALayer alloc] init]);
   [background_layer_
-      setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
+      setBackgroundColor:gfx::CGColorCreateFromSkColor(background_color_)];
   [cocoa_view_ setLayer:background_layer_];
   [cocoa_view_ setWantsLayer:YES];
 
@@ -944,7 +945,8 @@
 void RenderWidgetHostViewMac::TextInputTypeChanged(
     ui::TextInputType type,
     ui::TextInputMode input_mode,
-    bool can_compose_inline) {
+    bool can_compose_inline,
+    int flags) {
   if (text_input_type_ != type
       || can_compose_inline_ != can_compose_inline) {
     text_input_type_ = type;
@@ -1531,10 +1533,15 @@
   helper.ShowDefinitionForSelection();
 }
 
-void RenderWidgetHostViewMac::SetBackgroundOpaque(bool opaque) {
-  RenderWidgetHostViewBase::SetBackgroundOpaque(opaque);
+void RenderWidgetHostViewMac::SetBackgroundColor(SkColor color) {
+  RenderWidgetHostViewBase::SetBackgroundColor(color);
   if (render_widget_host_)
-    render_widget_host_->SetBackgroundOpaque(opaque);
+    render_widget_host_->SetBackgroundOpaque(GetBackgroundOpaque());
+
+  if (background_layer_) {
+    [background_layer_
+        setBackgroundColor:gfx::CGColorCreateFromSkColor(background_color_)];
+  }
 }
 
 BrowserAccessibilityManager*
diff --git a/content/browser/renderer_host/routing_id_issuer.cc b/content/browser/renderer_host/routing_id_issuer.cc
deleted file mode 100644
index 1e6fd7ff..0000000
--- a/content/browser/renderer_host/routing_id_issuer.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/routing_id_issuer.h"
-
-namespace content {
-
-namespace {
-
-const int kManglerBits = 3;
-const int kIDBits = 31 - kManglerBits;
-const int kManglerWrap = 1 << kManglerBits;
-const int kIDWrap = 1 << kIDBits;
-const int kIDMask = kIDWrap - 1;
-
-static base::StaticAtomicSequenceNumber g_manglerSequence;
-static int g_disablingIDManglingCount = 0;
-
-int GetNextMangler() {
-  // Does +1 to always gives some mangler.
-  return (g_manglerSequence.GetNext() % (kManglerWrap - 1)) + 1;
-}
-
-}  // namespace
-
-scoped_ptr<RoutingIDIssuer> RoutingIDIssuer::Create() {
-  if (0 < g_disablingIDManglingCount)
-    return make_scoped_ptr(new RoutingIDIssuer(0));
-
-  DCHECK(0 == g_disablingIDManglingCount);
-  return make_scoped_ptr(new RoutingIDIssuer(GetNextMangler()));
-}
-
-scoped_ptr<RoutingIDIssuer> RoutingIDIssuer::CreateWithMangler(int mangler) {
-  return make_scoped_ptr(new RoutingIDIssuer(mangler));
-}
-
-RoutingIDIssuer::RoutingIDIssuer(int mangler) : mangler_(mangler) {
-  DCHECK(0 <= mangler_ && mangler_ < kManglerWrap) << mangler_
-                                                   << ">=" << kManglerWrap;
-}
-
-int RoutingIDIssuer::IssueNext() {
-  return (mangler_ << kIDBits) | ((next_.GetNext() + 1) & kIDMask);
-}
-
-bool RoutingIDIssuer::IsProbablyValid(int issued_id) const {
-  return (mangler_ << kIDBits) == (issued_id & ~kIDMask);
-}
-
-void RoutingIDIssuer::DisableIDMangling() {
-  g_disablingIDManglingCount++;
-}
-
-void RoutingIDIssuer::EnableIDMangling() {
-  g_disablingIDManglingCount--;
-  DCHECK(0 <= g_disablingIDManglingCount);
-}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/routing_id_issuer.h b/content/browser/renderer_host/routing_id_issuer.h
deleted file mode 100644
index 36fc452..0000000
--- a/content/browser/renderer_host/routing_id_issuer.h
+++ /dev/null
@@ -1,44 +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 CONTENT_BROWSER_RENDERER_HOST_ROUTING_ID_ISSUER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_ROUTING_ID_ISSUER_H_
-
-#include "base/atomic_sequence_num.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "ipc/ipc_message.h"
-
-namespace content {
-
-// A debug facility for tightening the routing ID usage across multiple
-// RenderProcessHost. The tracked ID is used by RenderProcessHost
-// to verify if the given ID is correct.
-class CONTENT_EXPORT RoutingIDIssuer {
- public:
-  static scoped_ptr<RoutingIDIssuer> Create();
-  static scoped_ptr<RoutingIDIssuer> CreateWithMangler(int mangler);
-
-  int IssueNext();
-  bool IsProbablyValid(int issued_id) const;
-
- private:
-  friend class RoutingIDManglingDisabler;
-
-  static void DisableIDMangling();
-  static void EnableIDMangling();
-
-  explicit RoutingIDIssuer(int mangler);
-
-  base::AtomicSequenceNumber next_;
-  const int mangler_;
-
-  DISALLOW_COPY_AND_ASSIGN(RoutingIDIssuer);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_RENDERER_HOST_ROUTING_ID_ISSUER_H_
diff --git a/content/browser/renderer_host/routing_id_issuer_unittest.cc b/content/browser/renderer_host/routing_id_issuer_unittest.cc
deleted file mode 100644
index da1e528..0000000
--- a/content/browser/renderer_host/routing_id_issuer_unittest.cc
+++ /dev/null
@@ -1,41 +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 "content/browser/renderer_host/routing_id_issuer.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-namespace {
-
-const int kMangler = 5;
-
-class RoutingIDIssuerTest : public testing::Test {};
-
-TEST_F(RoutingIDIssuerTest, IssueNext) {
-  scoped_ptr<RoutingIDIssuer> target =
-      RoutingIDIssuer::CreateWithMangler(kMangler);
-  int id0 = target->IssueNext();
-  int id1 = target->IssueNext();
-  EXPECT_EQ(id0 + 1, id1);
-}
-
-TEST_F(RoutingIDIssuerTest, IsProbablyValid) {
-  scoped_ptr<RoutingIDIssuer> proper =
-      RoutingIDIssuer::CreateWithMangler(kMangler);
-  scoped_ptr<RoutingIDIssuer> foreign =
-      RoutingIDIssuer::CreateWithMangler(kMangler + 1);
-
-  EXPECT_FALSE(proper->IsProbablyValid(kMangler));
-
-  int proper_id = proper->IssueNext();
-  int foreign_id = foreign->IssueNext();
-  EXPECT_TRUE(proper->IsProbablyValid(proper_id));
-  EXPECT_TRUE(foreign->IsProbablyValid(foreign_id));
-  EXPECT_FALSE(proper->IsProbablyValid(foreign_id));
-  EXPECT_FALSE(foreign->IsProbablyValid(proper_id));
-}
-
-}  // namespace
-}  // namespace contnet
diff --git a/content/browser/renderer_host/socket_stream_dispatcher_host.cc b/content/browser/renderer_host/socket_stream_dispatcher_host.cc
deleted file mode 100644
index 3b8876f1..0000000
--- a/content/browser/renderer_host/socket_stream_dispatcher_host.cc
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/socket_stream_dispatcher_host.h"
-
-#include <string>
-
-#include "base/logging.h"
-#include "content/browser/renderer_host/socket_stream_host.h"
-#include "content/browser/ssl/ssl_manager.h"
-#include "content/common/resource_messages.h"
-#include "content/common/socket_stream.h"
-#include "content/common/socket_stream_messages.h"
-#include "content/public/browser/content_browser_client.h"
-#include "net/base/net_errors.h"
-#include "net/cookies/canonical_cookie.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "net/websockets/websocket_job.h"
-#include "net/websockets/websocket_throttle.h"
-
-namespace content {
-
-namespace {
-
-const size_t kMaxSocketStreamHosts = 16 * 1024;
-
-}  // namespace
-
-SocketStreamDispatcherHost::SocketStreamDispatcherHost(
-    int render_process_id,
-    const GetRequestContextCallback& request_context_callback,
-    ResourceContext* resource_context)
-    : BrowserMessageFilter(SocketStreamMsgStart),
-      render_process_id_(render_process_id),
-      request_context_callback_(request_context_callback),
-      resource_context_(resource_context),
-      on_shutdown_(false) {
-  net::WebSocketJob::EnsureInit();
-}
-
-bool SocketStreamDispatcherHost::OnMessageReceived(
-    const IPC::Message& message) {
-  if (on_shutdown_)
-    return false;
-
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(SocketStreamDispatcherHost, message)
-    IPC_MESSAGE_HANDLER(SocketStreamHostMsg_Connect, OnConnect)
-    IPC_MESSAGE_HANDLER(SocketStreamHostMsg_SendData, OnSendData)
-    IPC_MESSAGE_HANDLER(SocketStreamHostMsg_Close, OnCloseReq)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-// SocketStream::Delegate methods implementations.
-void SocketStreamDispatcherHost::OnConnected(net::SocketStream* socket,
-                                             int max_pending_send_allowed) {
-  int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
-  DVLOG(2) << "SocketStreamDispatcherHost::OnConnected socket_id=" << socket_id
-           << " max_pending_send_allowed=" << max_pending_send_allowed;
-  if (socket_id == kNoSocketId) {
-    DVLOG(1) << "NoSocketId in OnConnected";
-    return;
-  }
-  if (!Send(new SocketStreamMsg_Connected(
-          socket_id, max_pending_send_allowed))) {
-    DVLOG(1) << "SocketStreamMsg_Connected failed.";
-    DeleteSocketStreamHost(socket_id);
-  }
-}
-
-void SocketStreamDispatcherHost::OnSentData(net::SocketStream* socket,
-                                            int amount_sent) {
-  int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
-  DVLOG(2) << "SocketStreamDispatcherHost::OnSentData socket_id=" << socket_id
-           << " amount_sent=" << amount_sent;
-  if (socket_id == kNoSocketId) {
-    DVLOG(1) << "NoSocketId in OnSentData";
-    return;
-  }
-  if (!Send(new SocketStreamMsg_SentData(socket_id, amount_sent))) {
-    DVLOG(1) << "SocketStreamMsg_SentData failed.";
-    DeleteSocketStreamHost(socket_id);
-  }
-}
-
-void SocketStreamDispatcherHost::OnReceivedData(
-    net::SocketStream* socket, const char* data, int len) {
-  int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
-  DVLOG(2) << "SocketStreamDispatcherHost::OnReceiveData socket_id="
-           << socket_id;
-  if (socket_id == kNoSocketId) {
-    DVLOG(1) << "NoSocketId in OnReceivedData";
-    return;
-  }
-  if (!Send(new SocketStreamMsg_ReceivedData(
-          socket_id, std::vector<char>(data, data + len)))) {
-    DVLOG(1) << "SocketStreamMsg_ReceivedData failed.";
-    DeleteSocketStreamHost(socket_id);
-  }
-}
-
-void SocketStreamDispatcherHost::OnClose(net::SocketStream* socket) {
-  int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
-  DVLOG(2) << "SocketStreamDispatcherHost::OnClosed socket_id=" << socket_id;
-  if (socket_id == kNoSocketId) {
-    DVLOG(1) << "NoSocketId in OnClose";
-    return;
-  }
-  DeleteSocketStreamHost(socket_id);
-}
-
-void SocketStreamDispatcherHost::OnError(const net::SocketStream* socket,
-                                         int error) {
-  int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
-  DVLOG(2) << "SocketStreamDispatcherHost::OnError socket_id=" << socket_id;
-  if (socket_id == content::kNoSocketId) {
-    DVLOG(1) << "NoSocketId in OnError";
-    return;
-  }
-  // SocketStream::Delegate::OnError() events are handled as WebSocket error
-  // event when user agent was required to fail WebSocket connection or the
-  // WebSocket connection is closed with prejudice.
-  if (!Send(new SocketStreamMsg_Failed(socket_id, error))) {
-    DVLOG(1) << "SocketStreamMsg_Failed failed.";
-    DeleteSocketStreamHost(socket_id);
-  }
-}
-
-void SocketStreamDispatcherHost::OnSSLCertificateError(
-    net::SocketStream* socket, const net::SSLInfo& ssl_info, bool fatal) {
-  int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
-  DVLOG(2) << "SocketStreamDispatcherHost::OnSSLCertificateError socket_id="
-           << socket_id;
-  if (socket_id == kNoSocketId) {
-    DVLOG(1) << "NoSocketId in OnSSLCertificateError";
-    return;
-  }
-  SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
-  DCHECK(socket_stream_host);
-  SSLManager::OnSSLCertificateError(
-      socket_stream_host->AsSSLErrorHandlerDelegate(),
-      RESOURCE_TYPE_SUB_RESOURCE,
-      socket->url(), render_process_id_, socket_stream_host->render_frame_id(),
-      ssl_info, fatal);
-}
-
-bool SocketStreamDispatcherHost::CanGetCookies(net::SocketStream* socket,
-                                               const GURL& url) {
-  int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
-  if (socket_id == kNoSocketId) {
-    return false;
-  }
-  SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
-  DCHECK(socket_stream_host);
-  return GetContentClient()->browser()->AllowGetCookie(
-      url,
-      url,
-      net::CookieList(),
-      resource_context_,
-      render_process_id_,
-      socket_stream_host->render_frame_id());
-}
-
-bool SocketStreamDispatcherHost::CanSetCookie(net::SocketStream* request,
-                                              const GURL& url,
-                                              const std::string& cookie_line,
-                                              net::CookieOptions* options) {
-  int socket_id = SocketStreamHost::SocketIdFromSocketStream(request);
-  if (socket_id == kNoSocketId) {
-    return false;
-  }
-  SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
-  DCHECK(socket_stream_host);
-  return GetContentClient()->browser()->AllowSetCookie(
-      url,
-      url,
-      cookie_line,
-      resource_context_,
-      render_process_id_,
-      socket_stream_host->render_frame_id(),
-      options);
-}
-
-SocketStreamDispatcherHost::~SocketStreamDispatcherHost() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  Shutdown();
-}
-
-// Message handlers called by OnMessageReceived.
-void SocketStreamDispatcherHost::OnConnect(int render_frame_id,
-                                           const GURL& url,
-                                           int socket_id) {
-  DVLOG(2) << "SocketStreamDispatcherHost::OnConnect"
-           << " render_frame_id=" << render_frame_id
-           << " url=" << url
-           << " socket_id=" << socket_id;
-  DCHECK_NE(kNoSocketId, socket_id);
-
-  if (hosts_.size() >= kMaxSocketStreamHosts) {
-    if (!Send(new SocketStreamMsg_Failed(socket_id,
-                                         net::ERR_TOO_MANY_SOCKET_STREAMS))) {
-      DVLOG(1) << "SocketStreamMsg_Failed failed.";
-    }
-    if (!Send(new SocketStreamMsg_Closed(socket_id))) {
-      DVLOG(1) << "SocketStreamMsg_Closed failed.";
-    }
-    return;
-  }
-
-  if (hosts_.Lookup(socket_id)) {
-    DVLOG(1) << "socket_id=" << socket_id << " already registered.";
-    return;
-  }
-
-  // Note that the SocketStreamHost is responsible for checking that |url|
-  // is valid.
-  SocketStreamHost* socket_stream_host =
-      new SocketStreamHost(this, render_process_id_, render_frame_id,
-                           socket_id);
-  hosts_.AddWithID(socket_stream_host, socket_id);
-  socket_stream_host->Connect(url, GetURLRequestContext());
-  DVLOG(2) << "SocketStreamDispatcherHost::OnConnect -> " << socket_id;
-}
-
-void SocketStreamDispatcherHost::OnSendData(
-    int socket_id, const std::vector<char>& data) {
-  DVLOG(2) << "SocketStreamDispatcherHost::OnSendData socket_id=" << socket_id;
-  SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
-  if (!socket_stream_host) {
-    DVLOG(1) << "socket_id=" << socket_id << " already closed.";
-    return;
-  }
-  if (!socket_stream_host->SendData(data)) {
-    // Cannot accept more data to send.
-    socket_stream_host->Close();
-  }
-}
-
-void SocketStreamDispatcherHost::OnCloseReq(int socket_id) {
-  DVLOG(2) << "SocketStreamDispatcherHost::OnCloseReq socket_id=" << socket_id;
-  SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
-  if (!socket_stream_host)
-    return;
-  socket_stream_host->Close();
-}
-
-void SocketStreamDispatcherHost::DeleteSocketStreamHost(int socket_id) {
-  SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
-  DCHECK(socket_stream_host);
-  delete socket_stream_host;
-  hosts_.Remove(socket_id);
-  if (!Send(new SocketStreamMsg_Closed(socket_id))) {
-    DVLOG(1) << "SocketStreamMsg_Closed failed.";
-  }
-}
-
-net::URLRequestContext* SocketStreamDispatcherHost::GetURLRequestContext() {
-  return request_context_callback_.Run(RESOURCE_TYPE_SUB_RESOURCE);
-}
-
-void SocketStreamDispatcherHost::Shutdown() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  // TODO(ukai): Implement IDMap::RemoveAll().
-  for (IDMap<SocketStreamHost>::const_iterator iter(&hosts_);
-       !iter.IsAtEnd();
-       iter.Advance()) {
-    int socket_id = iter.GetCurrentKey();
-    const SocketStreamHost* socket_stream_host = iter.GetCurrentValue();
-    delete socket_stream_host;
-    hosts_.Remove(socket_id);
-  }
-  on_shutdown_ = true;
-}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/socket_stream_dispatcher_host.h b/content/browser/renderer_host/socket_stream_dispatcher_host.h
deleted file mode 100644
index af1b83b7..0000000
--- a/content/browser/renderer_host/socket_stream_dispatcher_host.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_SOCKET_STREAM_DISPATCHER_HOST_H_
-#define CONTENT_BROWSER_RENDERER_HOST_SOCKET_STREAM_DISPATCHER_HOST_H_
-
-#include <vector>
-
-#include "base/callback_forward.h"
-#include "base/id_map.h"
-#include "content/public/browser/browser_message_filter.h"
-#include "content/public/common/resource_type.h"
-#include "net/socket_stream/socket_stream.h"
-
-class GURL;
-
-namespace net {
-class SSLInfo;
-}
-
-namespace content {
-class ResourceContext;
-class SocketStreamHost;
-
-// Dispatches ViewHostMsg_SocketStream_* messages sent from renderer.
-// It also acts as SocketStream::Delegate so that it sends
-// ViewMsg_SocketStream_* messages back to renderer.
-class SocketStreamDispatcherHost : public BrowserMessageFilter,
-                                   public net::SocketStream::Delegate {
- public:
-  typedef base::Callback<net::URLRequestContext*(ResourceType)>
-      GetRequestContextCallback;
-  SocketStreamDispatcherHost(
-      int render_process_id,
-      const GetRequestContextCallback& request_context_callback,
-      ResourceContext* resource_context);
-
-  // BrowserMessageFilter:
-  bool OnMessageReceived(const IPC::Message& message) override;
-
-  // Make this object inactive.
-  // Remove all active SocketStreamHost objects.
-  void Shutdown();
-
-  // SocketStream::Delegate:
-  void OnConnected(net::SocketStream* socket,
-                   int max_pending_send_allowed) override;
-  void OnSentData(net::SocketStream* socket, int amount_sent) override;
-  void OnReceivedData(net::SocketStream* socket,
-                      const char* data,
-                      int len) override;
-  void OnClose(net::SocketStream* socket) override;
-  void OnError(const net::SocketStream* socket, int error) override;
-  void OnSSLCertificateError(net::SocketStream* socket,
-                             const net::SSLInfo& ssl_info,
-                             bool fatal) override;
-  bool CanGetCookies(net::SocketStream* socket, const GURL& url) override;
-  bool CanSetCookie(net::SocketStream* request,
-                    const GURL& url,
-                    const std::string& cookie_line,
-                    net::CookieOptions* options) override;
-
- protected:
-  ~SocketStreamDispatcherHost() override;
-
- private:
-  // Message handlers called by OnMessageReceived.
-  void OnConnect(int render_frame_id, const GURL& url, int socket_id);
-  void OnSendData(int socket_id, const std::vector<char>& data);
-  void OnCloseReq(int socket_id);
-
-  void DeleteSocketStreamHost(int socket_id);
-
-  net::URLRequestContext* GetURLRequestContext();
-
-  IDMap<SocketStreamHost> hosts_;
-  int render_process_id_;
-  GetRequestContextCallback request_context_callback_;
-  ResourceContext* resource_context_;
-
-  bool on_shutdown_;
-
-  DISALLOW_COPY_AND_ASSIGN(SocketStreamDispatcherHost);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_RENDERER_HOST_SOCKET_STREAM_DISPATCHER_HOST_H_
diff --git a/content/browser/renderer_host/socket_stream_host.cc b/content/browser/renderer_host/socket_stream_host.cc
deleted file mode 100644
index deef6cc..0000000
--- a/content/browser/renderer_host/socket_stream_host.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/socket_stream_host.h"
-
-#include "base/logging.h"
-#include "content/common/socket_stream.h"
-#include "content/public/browser/content_browser_client.h"
-#include "net/socket_stream/socket_stream_job.h"
-#include "net/url_request/url_request_context.h"
-
-namespace content {
-namespace {
-
-const char* kSocketIdKey = "socketId";
-
-class SocketStreamId : public net::SocketStream::UserData {
- public:
-  explicit SocketStreamId(int socket_id) : socket_id_(socket_id) {}
-  ~SocketStreamId() override {}
-  int socket_id() const { return socket_id_; }
-
- private:
-  int socket_id_;
-};
-
-}  // namespace
-
-SocketStreamHost::SocketStreamHost(
-    net::SocketStream::Delegate* delegate,
-    int child_id,
-    int render_frame_id,
-    int socket_id)
-    : delegate_(delegate),
-      child_id_(child_id),
-      render_frame_id_(render_frame_id),
-      socket_id_(socket_id),
-      weak_ptr_factory_(this) {
-  DCHECK_NE(socket_id_, kNoSocketId);
-  VLOG(1) << "SocketStreamHost: render_frame_id=" << render_frame_id
-          << " socket_id=" << socket_id_;
-}
-
-/* static */
-int SocketStreamHost::SocketIdFromSocketStream(
-    const net::SocketStream* socket) {
-  net::SocketStream::UserData* d = socket->GetUserData(kSocketIdKey);
-  if (d) {
-    SocketStreamId* socket_stream_id = static_cast<SocketStreamId*>(d);
-    return socket_stream_id->socket_id();
-  }
-  return kNoSocketId;
-}
-
-SocketStreamHost::~SocketStreamHost() {
-  VLOG(1) << "SocketStreamHost destructed socket_id=" << socket_id_;
-  job_->DetachContext();
-  job_->DetachDelegate();
-}
-
-void SocketStreamHost::Connect(const GURL& url,
-                               net::URLRequestContext* request_context) {
-  VLOG(1) << "SocketStreamHost::Connect url=" << url;
-  job_ = net::SocketStreamJob::CreateSocketStreamJob(
-      url, delegate_, request_context->transport_security_state(),
-      request_context->ssl_config_service(),
-      request_context,
-      GetContentClient()->browser()->OverrideCookieStoreForRenderProcess(
-          child_id_));
-  job_->SetUserData(kSocketIdKey, new SocketStreamId(socket_id_));
-  job_->Connect();
-}
-
-bool SocketStreamHost::SendData(const std::vector<char>& data) {
-  VLOG(1) << "SocketStreamHost::SendData";
-  return job_.get() && job_->SendData(&data[0], data.size());
-}
-
-void SocketStreamHost::Close() {
-  VLOG(1) << "SocketStreamHost::Close";
-  if (!job_.get())
-    return;
-  job_->Close();
-}
-
-base::WeakPtr<SSLErrorHandler::Delegate>
-SocketStreamHost::AsSSLErrorHandlerDelegate() {
-  return weak_ptr_factory_.GetWeakPtr();
-}
-
-void SocketStreamHost::CancelSSLRequest(int error,
-                                        const net::SSLInfo* ssl_info) {
-  VLOG(1) << "SocketStreamHost::CancelSSLRequest socket_id=" << socket_id_;
-  if (!job_.get())
-    return;
-  if (ssl_info)
-    job_->CancelWithSSLError(*ssl_info);
-  else
-    job_->CancelWithError(error);
-}
-
-void SocketStreamHost::ContinueSSLRequest() {
-  VLOG(1) << "SocketStreamHost::ContinueSSLRequest socket_id=" << socket_id_;
-  if (!job_.get())
-    return;
-  job_->ContinueDespiteError();
-}
-
-}  // namespace content
diff --git a/content/browser/renderer_host/socket_stream_host.h b/content/browser/renderer_host/socket_stream_host.h
deleted file mode 100644
index 94234fb..0000000
--- a/content/browser/renderer_host/socket_stream_host.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_SOCKET_STREAM_HOST_H_
-#define CONTENT_BROWSER_RENDERER_HOST_SOCKET_STREAM_HOST_H_
-
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "content/browser/ssl/ssl_error_handler.h"
-#include "net/socket_stream/socket_stream.h"
-
-class GURL;
-
-namespace net {
-class SocketStreamJob;
-class URLRequestContext;
-class SSLInfo;
-}  // namespace net
-
-namespace content {
-
-// Host of SocketStreamHandle.  Each SocketStreamHandle will have an unique
-// socket_id assigned by SocketStreamHost constructor.  If socket id is
-// kNoSocketId, there is no SocketStreamHost.  Each SocketStreamHost has
-// SocketStream to manage bi-directional communication over socket stream.  The
-// lifetime of an instance of this class is completely controlled by the
-// SocketStreamDispatcherHost.
-class SocketStreamHost : public SSLErrorHandler::Delegate {
- public:
-  SocketStreamHost(net::SocketStream::Delegate* delegate,
-                   int child_id,
-                   int render_frame_id,
-                   int socket_id);
-  ~SocketStreamHost() override;
-
-  // Gets socket_id associated with |socket|.
-  static int SocketIdFromSocketStream(const net::SocketStream* socket);
-
-  int render_frame_id() const { return render_frame_id_; }
-  int socket_id() const { return socket_id_; }
-
-  // Starts to open connection to |url|.
-  void Connect(const GURL& url, net::URLRequestContext* request_context);
-
-  // Sends |data| over the socket stream.
-  // socket stream must be open to send data.
-  // Returns true if the data is put in transmit buffer in socket stream.
-  // Returns false otherwise (transmit buffer exceeds limit, or socket
-  // stream is closed).
-  bool SendData(const std::vector<char>& data);
-
-  // Closes the socket stream.
-  void Close();
-
-  base::WeakPtr<SSLErrorHandler::Delegate> AsSSLErrorHandlerDelegate();
-
-  // SSLErrorHandler::Delegate methods:
-  void CancelSSLRequest(int error, const net::SSLInfo* ssl_info) override;
-  void ContinueSSLRequest() override;
-
- private:
-  net::SocketStream::Delegate* delegate_;
-  int child_id_;
-  int render_frame_id_;
-  int socket_id_;
-
-  scoped_refptr<net::SocketStreamJob> job_;
-
-  base::WeakPtrFactory<SocketStreamHost> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(SocketStreamHost);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_RENDERER_HOST_SOCKET_STREAM_HOST_H_
diff --git a/content/browser/resources/media/client_renderer.js b/content/browser/resources/media/client_renderer.js
index 61281c1..0eedb35 100644
--- a/content/browser/resources/media/client_renderer.js
+++ b/content/browser/resources/media/client_renderer.js
@@ -122,6 +122,35 @@
       }
     },
 
+    createVideoCaptureFormatTable: function(formats) {
+      if (!formats || formats.length == 0)
+        return document.createTextNode('No formats');
+
+      var table = document.createElement('table');
+      var thead = document.createElement('thead');
+      var theadRow = document.createElement('tr');
+      for (var key in formats[0]) {
+        var th = document.createElement('th');
+        th.appendChild(document.createTextNode(key));
+        theadRow.appendChild(th);
+      }
+      thead.appendChild(theadRow);
+      table.appendChild(thead);
+      var tbody = document.createElement('tbody');
+      for (var i=0; i < formats.length; ++i) {
+        var tr = document.createElement('tr')
+        for (var key in formats[i]) {
+          var td = document.createElement('td');
+          td.appendChild(document.createTextNode(formats[i][key]));
+          tr.appendChild(td);
+        }
+        tbody.appendChild(tr);
+      }
+      table.appendChild(tbody);
+      table.classList.add('video-capture-formats-table');
+      return table;
+    },
+
     redrawVideoCaptureCapabilities: function(videoCaptureCapabilities, keys) {
       var copyButtonElement =
           document.getElementById('video-capture-capabilities-copy-button');
@@ -142,13 +171,7 @@
           var tableCell = document.createElement('td');
           var cellElement;
           if ((typeof value) == (typeof [])) {
-            cellElement = document.createElement('ul');
-            for (var i in value) {
-              var format = value[i];
-              var li = document.createElement('li');
-              li.appendChild(document.createTextNode(format))
-              cellElement.appendChild(li)
-            }
+            cellElement = this.createVideoCaptureFormatTable(value);
           } else {
             cellElement = document.createTextNode(
                 ((typeof value) == 'undefined') ? 'n/a' : value);
diff --git a/content/browser/resources/media/main.js b/content/browser/resources/media/main.js
index 23b30cf..7045197 100644
--- a/content/browser/resources/media/main.js
+++ b/content/browser/resources/media/main.js
@@ -47,7 +47,6 @@
 
   media.onReceiveVideoCaptureCapabilities = function(videoCaptureCapabilities) {
     manager.updateVideoCaptureCapabilities(videoCaptureCapabilities)
-    console.log("Video capabilities", videoCaptureCapabilities);
   }
 
   media.onReceiveConstants = function(constants) {
diff --git a/content/browser/resources/media/manager.js b/content/browser/resources/media/manager.js
index c2fd976..5508c66c 100644
--- a/content/browser/resources/media/manager.js
+++ b/content/browser/resources/media/manager.js
@@ -111,9 +111,45 @@
                                          value);
     },
 
+    parseVideoCaptureFormat_: function(format) {
+      /**
+       * Example:
+       *
+       * format:
+       *   "resolution: 1280x720, fps: 30.000000, pixel format: I420"
+       *
+       * formatDict:
+       *   {'resolution':'1280x720', 'fps': '30.00'}
+       */
+      var parts = format.split(', ');
+      var formatDict = {};
+      for (var i in parts) {
+        var kv = parts[i].split(': ');
+        formatDict[kv[0]] = kv[1];
+      }
+
+      // Round down the FPS to 2 decimals.
+      formatDict['fps'] = parseFloat(formatDict['fps']).toFixed(2);
+
+      // The camera does not actually output I420 so this info is misleading.
+      delete formatDict['pixel format'];
+
+      return formatDict;
+    },
+
     updateVideoCaptureCapabilities: function(videoCaptureCapabilities) {
+      // Parse the video formats to be structured for the table.
+      for (var i in videoCaptureCapabilities) {
+        for (var j in videoCaptureCapabilities[i]['formats']) {
+          videoCaptureCapabilities[i]['formats'][j] =
+              this.parseVideoCaptureFormat_(
+                    videoCaptureCapabilities[i]['formats'][j]);
+        }
+      }
+
       // The keys of each device to be shown in order of appearance.
-      var videoCaptureDeviceKeys = ['id','name','formats','captureApi'];
+      var videoCaptureDeviceKeys = ['name','formats','captureApi','id'];
+
       this.clientRenderer_.redrawVideoCaptureCapabilities(
           videoCaptureCapabilities, videoCaptureDeviceKeys);
     }
diff --git a/content/browser/resources/media/media_internals.css b/content/browser/resources/media/media_internals.css
index 912b557..0165c3f4 100644
--- a/content/browser/resources/media/media_internals.css
+++ b/content/browser/resources/media/media_internals.css
@@ -87,6 +87,12 @@
 #property-wrapper,
 #log-wrapper {
   display:block;
+  flex-grow: 0.25;
+  align-self: stretch;
+  overflow: auto;
+}
+
+#video-capture-capabilities-wrapper {
   flex-grow: 0.5;
   align-self: stretch;
   overflow: auto;
@@ -117,6 +123,37 @@
   min-width: 115px;
 }
 
+#video-capture-capabilities-table {
+  margin-bottom:30px;
+}
+
+#video-capture-capabilities-table th,
+#video-capture-capabilities-table td {
+  min-width:120px;
+}
+
+#video-capture-capabilities-table td {
+  padding:5px;
+}
+
 #video-capture-capabilities-table tr td {
   font-size:13px;
+  text-align:center;
+}
+
+#video-capture-capabilities-table .video-capture-formats-table th,
+#video-capture-capabilities-table .video-capture-formats-table td {
+  text-align:right;
+  min-width:80px;
+}
+
+#video-capture-capabilities-table .video-capture-formats-table th {
+  background:none;
+  color:#666;
+  font-size:13px;
+  font-weight:bold;
+}
+
+#video-capture-capabilities-table .video-capture-formats-table td {
+  padding:2px;
 }
diff --git a/content/browser/resources/media/media_internals.html b/content/browser/resources/media/media_internals.html
index d8b9f1ce..d271082 100644
--- a/content/browser/resources/media/media_internals.html
+++ b/content/browser/resources/media/media_internals.html
@@ -64,17 +64,17 @@
         <tbody></tbody>
       </table>
     </div>
-    <div id="video-capture-capabilities-container">
+    <div id="video-capture-capabilities-wrapper">
       <h2>Video Capture Device Capabilities</h2>
       <button id="video-capture-capabilities-copy-button">
         Copy to clipboard</button>
       <table id="video-capture-capabilities-table">
         <thead>
           <tr>
-            <th>Device ID</th>
             <th>Device Name</th>
             <th>Formats</th>
             <th>Capture API</th>
+            <th>Device ID</th>
           </tr>
         </thead>
         <tbody id="video-capture-capabilities-tbody">
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index 28e6a099e..3d8fe53 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -861,7 +861,13 @@
   return result;
 }
 
-IN_PROC_BROWSER_TEST_F(ServiceWorkerBlackBoxBrowserTest, Registration) {
+// Flaky timeouts on CrOS: http://crbug.com/387045
+#if defined(OS_CHROMEOS)
+#define MAYBE_Registration DISABLED_Registration
+#else
+#define MAYBE_Registration Registration
+#endif
+IN_PROC_BROWSER_TEST_F(ServiceWorkerBlackBoxBrowserTest, MAYBE_Registration) {
   // Close the only window to be sure we're not re-using its RenderProcessHost.
   shell()->Close();
   EXPECT_EQ(0, CountRenderProcessHosts());
diff --git a/content/browser/service_worker/service_worker_cache.cc b/content/browser/service_worker/service_worker_cache.cc
index 5026cef..6146de7 100644
--- a/content/browser/service_worker/service_worker_cache.cc
+++ b/content/browser/service_worker/service_worker_cache.cc
@@ -19,6 +19,7 @@
 #include "storage/browser/blob/blob_data_handle.h"
 #include "storage/browser/blob/blob_storage_context.h"
 #include "storage/browser/blob/blob_url_request_job_factory.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
 #include "third_party/WebKit/public/platform/WebServiceWorkerResponseType.h"
 
 namespace content {
@@ -41,6 +42,10 @@
 // Buffer size for cache and blob reading/writing.
 const int kBufferSize = 1024 * 512;
 
+void NotReachedCompletionCallback(int rv) {
+  NOTREACHED();
+}
+
 blink::WebServiceWorkerResponseType ProtoResponseTypeToWebResponseType(
     ServiceWorkerRequestResponseHeaders_ResponseType response_type) {
   switch (response_type) {
@@ -93,19 +98,21 @@
 // Streams data from a blob and writes it to a given disk_cache::Entry.
 class BlobReader : public net::URLRequest::Delegate {
  public:
-  typedef base::Callback<void(bool)> BoolCallback;
+  typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
+      EntryAndBoolCallback;
 
-  BlobReader(disk_cache::ScopedEntryPtr entry)
+  BlobReader()
       : cache_entry_offset_(0),
         buffer_(new net::IOBufferWithSize(kBufferSize)),
-        weak_ptr_factory_(this) {
+        weak_ptr_factory_(this) {}
+
+  // |entry| is passed to the callback once complete.
+  void StreamBlobToCache(disk_cache::ScopedEntryPtr entry,
+                         net::URLRequestContext* request_context,
+                         scoped_ptr<storage::BlobDataHandle> blob_data_handle,
+                         const EntryAndBoolCallback& callback) {
     DCHECK(entry);
     entry_ = entry.Pass();
-  }
-
-  void StreamBlobToCache(net::URLRequestContext* request_context,
-                         scoped_ptr<storage::BlobDataHandle> blob_data_handle,
-                         const BoolCallback& callback) {
     callback_ = callback;
     blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
         blob_data_handle.Pass(), request_context, this);
@@ -138,7 +145,7 @@
 
   void OnResponseStarted(net::URLRequest* request) override {
     if (!request->status().is_success()) {
-      callback_.Run(false);
+      callback_.Run(entry_.Pass(), false);
       return;
     }
     ReadFromBlob();
@@ -154,12 +161,12 @@
 
   void OnReadCompleted(net::URLRequest* request, int bytes_read) override {
     if (!request->status().is_success()) {
-      callback_.Run(false);
+      callback_.Run(entry_.Pass(), false);
       return;
     }
 
     if (bytes_read == 0) {
-      callback_.Run(true);
+      callback_.Run(entry_.Pass(), true);
       return;
     }
 
@@ -180,7 +187,7 @@
 
   void DidWriteDataToEntry(int expected_bytes, int rv) {
     if (rv != expected_bytes) {
-      callback_.Run(false);
+      callback_.Run(entry_.Pass(), false);
       return;
     }
 
@@ -192,23 +199,28 @@
   int cache_entry_offset_;
   disk_cache::ScopedEntryPtr entry_;
   scoped_ptr<net::URLRequest> blob_request_;
-  BoolCallback callback_;
+  EntryAndBoolCallback callback_;
   scoped_refptr<net::IOBufferWithSize> buffer_;
   base::WeakPtrFactory<BlobReader> weak_ptr_factory_;
 };
 
 // The state needed to pass between ServiceWorkerCache::Put callbacks.
 struct PutContext {
-  PutContext(scoped_ptr<ServiceWorkerFetchRequest> request,
-             scoped_ptr<ServiceWorkerResponse> response,
-             scoped_ptr<storage::BlobDataHandle> blob_data_handle,
-             const ServiceWorkerCache::ResponseCallback& callback,
-             net::URLRequestContext* request_context)
-      : request(request.Pass()),
+  PutContext(
+      const GURL& origin,
+      scoped_ptr<ServiceWorkerFetchRequest> request,
+      scoped_ptr<ServiceWorkerResponse> response,
+      scoped_ptr<storage::BlobDataHandle> blob_data_handle,
+      const ServiceWorkerCache::ResponseCallback& callback,
+      net::URLRequestContext* request_context,
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
+      : origin(origin),
+        request(request.Pass()),
         response(response.Pass()),
         blob_data_handle(blob_data_handle.Pass()),
         callback(callback),
         request_context(request_context),
+        quota_manager_proxy(quota_manager_proxy),
         cache_entry(NULL) {}
   ~PutContext() {
     if (cache_entry)
@@ -216,12 +228,13 @@
   }
 
   // Input parameters to the Put function.
+  GURL origin;
   scoped_ptr<ServiceWorkerFetchRequest> request;
   scoped_ptr<ServiceWorkerResponse> response;
   scoped_ptr<storage::BlobDataHandle> blob_data_handle;
   ServiceWorkerCache::ResponseCallback callback;
-
   net::URLRequestContext* request_context;
+  scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy;
 
   // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to
   // CreateEntry.
@@ -240,6 +253,7 @@
                         int rv);
 void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context,
                             scoped_ptr<BlobReader> blob_reader,
+                            disk_cache::ScopedEntryPtr entry,
                             bool success);
 
 // Match callbacks
@@ -269,10 +283,13 @@
                        scoped_ptr<ResponseReadContext> response_context);
 
 // Delete callbacks
-void DeleteDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
-                        const ServiceWorkerCache::ErrorCallback& callback,
-                        scoped_ptr<disk_cache::Entry*> entryptr,
-                        int rv);
+void DeleteDidOpenEntry(
+    const GURL& origin,
+    scoped_ptr<ServiceWorkerFetchRequest> request,
+    const ServiceWorkerCache::ErrorCallback& callback,
+    scoped_ptr<disk_cache::Entry*> entryptr,
+    const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
+    int rv);
 
 // Copy headers out of a cache entry and into a protobuf. The callback is
 // guaranteed to be run.
@@ -368,6 +385,14 @@
   // from the blob into the cache entry.
 
   if (put_context->response->blob_uuid.empty()) {
+    if (put_context->quota_manager_proxy.get()) {
+      put_context->quota_manager_proxy->NotifyStorageModified(
+          storage::QuotaClient::kServiceWorkerCache,
+          put_context->origin,
+          storage::kStorageTypeTemporary,
+          put_context->cache_entry->GetDataSize(INDEX_HEADERS));
+    }
+
     put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
                               put_context->response.Pass(),
                               scoped_ptr<storage::BlobDataHandle>());
@@ -378,8 +403,7 @@
 
   disk_cache::ScopedEntryPtr entry(put_context->cache_entry);
   put_context->cache_entry = NULL;
-  scoped_ptr<BlobReader> reader(new BlobReader(entry.Pass()));
-
+  scoped_ptr<BlobReader> reader(new BlobReader());
   BlobReader* reader_ptr = reader.get();
 
   // Grab some pointers before passing put_context in Bind.
@@ -387,7 +411,8 @@
   scoped_ptr<storage::BlobDataHandle> blob_data_handle =
       put_context->blob_data_handle.Pass();
 
-  reader_ptr->StreamBlobToCache(request_context,
+  reader_ptr->StreamBlobToCache(entry.Pass(),
+                                request_context,
                                 blob_data_handle.Pass(),
                                 base::Bind(PutDidWriteBlobToCache,
                                            base::Passed(put_context.Pass()),
@@ -396,7 +421,11 @@
 
 void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context,
                             scoped_ptr<BlobReader> blob_reader,
+                            disk_cache::ScopedEntryPtr entry,
                             bool success) {
+  DCHECK(entry);
+  put_context->cache_entry = entry.release();
+
   if (!success) {
     put_context->cache_entry->Doom();
     put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
@@ -405,6 +434,15 @@
     return;
   }
 
+  if (put_context->quota_manager_proxy.get()) {
+    put_context->quota_manager_proxy->NotifyStorageModified(
+        storage::QuotaClient::kServiceWorkerCache,
+        put_context->origin,
+        storage::kStorageTypeTemporary,
+        put_context->cache_entry->GetDataSize(INDEX_HEADERS) +
+            put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY));
+  }
+
   put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
                             put_context->response.Pass(),
                             put_context->out_blob_data_handle.Pass());
@@ -639,10 +677,13 @@
                blob_data_handle.Pass());
 }
 
-void DeleteDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
-                        const ServiceWorkerCache::ErrorCallback& callback,
-                        scoped_ptr<disk_cache::Entry*> entryptr,
-                        int rv) {
+void DeleteDidOpenEntry(
+    const GURL& origin,
+    scoped_ptr<ServiceWorkerFetchRequest> request,
+    const ServiceWorkerCache::ErrorCallback& callback,
+    scoped_ptr<disk_cache::Entry*> entryptr,
+    const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
+    int rv) {
   if (rv != net::OK) {
     callback.Run(ServiceWorkerCache::ErrorTypeNotFound);
     return;
@@ -651,6 +692,15 @@
   DCHECK(entryptr);
   disk_cache::ScopedEntryPtr entry(*entryptr);
 
+  if (quota_manager_proxy.get()) {
+    quota_manager_proxy->NotifyStorageModified(
+        storage::QuotaClient::kServiceWorkerCache,
+        origin,
+        storage::kStorageTypeTemporary,
+        -1 * (entry->GetDataSize(INDEX_HEADERS) +
+              entry->GetDataSize(INDEX_RESPONSE_BODY)));
+  }
+
   entry->Doom();
   callback.Run(ServiceWorkerCache::ErrorTypeOK);
 }
@@ -744,19 +794,26 @@
 
 // static
 scoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache(
+    const GURL& origin,
     net::URLRequestContext* request_context,
+    const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
     base::WeakPtr<storage::BlobStorageContext> blob_context) {
-  return make_scoped_refptr(
-      new ServiceWorkerCache(base::FilePath(), request_context, blob_context));
+  return make_scoped_refptr(new ServiceWorkerCache(origin,
+                                                   base::FilePath(),
+                                                   request_context,
+                                                   quota_manager_proxy,
+                                                   blob_context));
 }
 
 // static
 scoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache(
+    const GURL& origin,
     const base::FilePath& path,
     net::URLRequestContext* request_context,
+    const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
     base::WeakPtr<storage::BlobStorageContext> blob_context) {
-  return make_scoped_refptr(
-      new ServiceWorkerCache(path, request_context, blob_context));
+  return make_scoped_refptr(new ServiceWorkerCache(
+      origin, path, request_context, quota_manager_proxy, blob_context));
 }
 
 ServiceWorkerCache::~ServiceWorkerCache() {
@@ -860,9 +917,11 @@
 
   net::CompletionCallback open_entry_callback =
       base::Bind(DeleteDidOpenEntry,
+                 origin_,
                  base::Passed(request.Pass()),
                  callback,
-                 base::Passed(entry.Pass()));
+                 base::Passed(entry.Pass()),
+                 quota_manager_proxy_);
 
   int rv = backend_->OpenEntry(
       request_ptr->url.spec(), entry_ptr, open_entry_callback);
@@ -911,14 +970,47 @@
   backend_.reset();
 }
 
+int64 ServiceWorkerCache::MemoryBackedSize() const {
+  if (!backend_ || !memory_only_)
+    return 0;
+
+  scoped_ptr<disk_cache::Backend::Iterator> backend_iter =
+      backend_->CreateIterator();
+  disk_cache::Entry* entry = nullptr;
+
+  int64 sum = 0;
+
+  std::vector<disk_cache::Entry*> entries;
+  int rv = net::OK;
+  while ((rv = backend_iter->OpenNextEntry(
+              &entry, base::Bind(NotReachedCompletionCallback))) == net::OK) {
+    entries.push_back(entry);  // Open the entries without mutating them.
+  }
+  DCHECK(rv !=
+         net::ERR_IO_PENDING);  // Expect all memory ops to be synchronous.
+
+  for (disk_cache::Entry* entry : entries) {
+    sum += entry->GetDataSize(INDEX_HEADERS) +
+           entry->GetDataSize(INDEX_RESPONSE_BODY);
+    entry->Close();
+  }
+
+  return sum;
+}
+
 ServiceWorkerCache::ServiceWorkerCache(
+    const GURL& origin,
     const base::FilePath& path,
     net::URLRequestContext* request_context,
+    const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
     base::WeakPtr<storage::BlobStorageContext> blob_context)
-    : path_(path),
+    : origin_(origin),
+      path_(path),
       request_context_(request_context),
+      quota_manager_proxy_(quota_manager_proxy),
       blob_storage_context_(blob_context),
       initialized_(false),
+      memory_only_(path.empty()),
       weak_ptr_factory_(this) {
 }
 
@@ -934,11 +1026,13 @@
     return;
   }
 
-  scoped_ptr<PutContext> put_context(new PutContext(request.Pass(),
+  scoped_ptr<PutContext> put_context(new PutContext(origin_,
+                                                    request.Pass(),
                                                     response.Pass(),
                                                     blob_data_handle.Pass(),
                                                     callback,
-                                                    request_context_));
+                                                    request_context_,
+                                                    quota_manager_proxy_));
 
   if (put_context->blob_data_handle) {
     // Grab another handle to the blob for the callback response.
@@ -1051,8 +1145,7 @@
   DCHECK(!backend_);
 
   // Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction.
-  net::CacheType cache_type =
-      path_.empty() ? net::MEMORY_CACHE : net::APP_CACHE;
+  net::CacheType cache_type = memory_only_ ? net::MEMORY_CACHE : net::APP_CACHE;
 
   scoped_ptr<ScopedBackendPtr> backend_ptr(new ScopedBackendPtr());
 
diff --git a/content/browser/service_worker/service_worker_cache.h b/content/browser/service_worker/service_worker_cache.h
index a88845e..ae9b7f3d 100644
--- a/content/browser/service_worker/service_worker_cache.h
+++ b/content/browser/service_worker/service_worker_cache.h
@@ -22,6 +22,7 @@
 class BlobData;
 class BlobDataHandle;
 class BlobStorageContext;
+class QuotaManagerProxy;
 }
 
 namespace content {
@@ -54,11 +55,15 @@
       RequestsCallback;
 
   static scoped_refptr<ServiceWorkerCache> CreateMemoryCache(
+      const GURL& origin,
       net::URLRequestContext* request_context,
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
       base::WeakPtr<storage::BlobStorageContext> blob_context);
   static scoped_refptr<ServiceWorkerCache> CreatePersistentCache(
+      const GURL& origin,
       const base::FilePath& path,
       net::URLRequestContext* request_context,
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
       base::WeakPtr<storage::BlobStorageContext> blob_context);
 
   // Returns ErrorTypeNotFound if not found. The callback will always be called.
@@ -85,6 +90,10 @@
   // Prevent further operations on this object and delete the backend.
   void Close();
 
+  // The size of the cache contents in memory. Returns 0 if the cache backend is
+  // not a memory cache backend.
+  int64 MemoryBackedSize() const;
+
   void set_backend(scoped_ptr<disk_cache::Backend> backend) {
     backend_ = backend.Pass();
   }
@@ -97,9 +106,12 @@
   struct KeysContext;
   typedef std::vector<disk_cache::Entry*> Entries;
 
-  ServiceWorkerCache(const base::FilePath& path,
-                     net::URLRequestContext* request_context,
-                     base::WeakPtr<storage::BlobStorageContext> blob_context);
+  ServiceWorkerCache(
+      const GURL& origin,
+      const base::FilePath& path,
+      net::URLRequestContext* request_context,
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
+      base::WeakPtr<storage::BlobStorageContext> blob_context);
 
   // Operations in progress will complete after the cache is deleted but pending
   // operations (those operations waiting for init to finish) won't.
@@ -130,12 +142,17 @@
   // The backend can be deleted via the Close function at any time so always
   // check for its existence before use.
   scoped_ptr<disk_cache::Backend> backend_;
+  GURL origin_;
   base::FilePath path_;
   net::URLRequestContext* request_context_;
+  scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
   base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
   bool initialized_;
   std::vector<base::Closure> init_callbacks_;
 
+  // Whether or not to store data in disk or memory.
+  bool memory_only_;
+
   base::WeakPtrFactory<ServiceWorkerCache> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCache);
diff --git a/content/browser/service_worker/service_worker_cache_listener.cc b/content/browser/service_worker/service_worker_cache_listener.cc
index c4baad3..dd2f150 100644
--- a/content/browser/service_worker/service_worker_cache_listener.cc
+++ b/content/browser/service_worker/service_worker_cache_listener.cc
@@ -356,7 +356,8 @@
     return;
   }
 
-  StoreBlobDataHandle(blob_data_handle.Pass());
+  if (blob_data_handle)
+    StoreBlobDataHandle(blob_data_handle.Pass());
 
   Send(ServiceWorkerMsg_CacheMatchSuccess(request_id, *response));
 }
diff --git a/content/browser/service_worker/service_worker_cache_storage.cc b/content/browser/service_worker/service_worker_cache_storage.cc
index e048c688..b16d54ce 100644
--- a/content/browser/service_worker/service_worker_cache_storage.cc
+++ b/content/browser/service_worker/service_worker_cache_storage.cc
@@ -19,6 +19,7 @@
 #include "net/base/directory_lister.h"
 #include "net/base/net_errors.h"
 #include "storage/browser/blob/blob_storage_context.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
 
 namespace content {
 
@@ -34,12 +35,15 @@
   typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)>
       StringVectorCallback;
 
-  CacheLoader(base::SequencedTaskRunner* cache_task_runner,
-              net::URLRequestContext* request_context,
-              base::WeakPtr<storage::BlobStorageContext> blob_context,
-              const GURL& origin)
+  CacheLoader(
+      base::SequencedTaskRunner* cache_task_runner,
+      net::URLRequestContext* request_context,
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
+      base::WeakPtr<storage::BlobStorageContext> blob_context,
+      const GURL& origin)
       : cache_task_runner_(cache_task_runner),
         request_context_(request_context),
+        quota_manager_proxy_(quota_manager_proxy),
         blob_context_(blob_context),
         origin_(origin) {
     DCHECK(!origin_.is_empty());
@@ -72,6 +76,7 @@
  protected:
   scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
   net::URLRequestContext* request_context_;
+  scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
   base::WeakPtr<storage::BlobStorageContext> blob_context_;
   GURL origin_;
 };
@@ -83,22 +88,28 @@
 class ServiceWorkerCacheStorage::MemoryLoader
     : public ServiceWorkerCacheStorage::CacheLoader {
  public:
-  MemoryLoader(base::SequencedTaskRunner* cache_task_runner,
-               net::URLRequestContext* request_context,
-               base::WeakPtr<storage::BlobStorageContext> blob_context,
-               const GURL& origin)
-      : CacheLoader(cache_task_runner, request_context, blob_context, origin) {}
+  MemoryLoader(
+      base::SequencedTaskRunner* cache_task_runner,
+      net::URLRequestContext* request_context,
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
+      base::WeakPtr<storage::BlobStorageContext> blob_context,
+      const GURL& origin)
+      : CacheLoader(cache_task_runner,
+                    request_context,
+                    quota_manager_proxy,
+                    blob_context,
+                    origin) {}
 
   scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache(
       const std::string& cache_name) override {
-    return ServiceWorkerCache::CreateMemoryCache(request_context_,
-                                                 blob_context_);
+    return ServiceWorkerCache::CreateMemoryCache(
+        origin_, request_context_, quota_manager_proxy_, blob_context_);
   }
 
   void CreateCache(const std::string& cache_name,
                    const CacheCallback& callback) override {
     scoped_refptr<ServiceWorkerCache> cache =
-        ServiceWorkerCache::CreateMemoryCache(request_context_, blob_context_);
+        CreateServiceWorkerCache(cache_name);
     cache_refs_.insert(std::make_pair(cache_name, cache));
     callback.Run(cache);
   }
@@ -134,12 +145,18 @@
 class ServiceWorkerCacheStorage::SimpleCacheLoader
     : public ServiceWorkerCacheStorage::CacheLoader {
  public:
-  SimpleCacheLoader(const base::FilePath& origin_path,
-                    base::SequencedTaskRunner* cache_task_runner,
-                    net::URLRequestContext* request_context,
-                    base::WeakPtr<storage::BlobStorageContext> blob_context,
-                    const GURL& origin)
-      : CacheLoader(cache_task_runner, request_context, blob_context, origin),
+  SimpleCacheLoader(
+      const base::FilePath& origin_path,
+      base::SequencedTaskRunner* cache_task_runner,
+      net::URLRequestContext* request_context,
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
+      base::WeakPtr<storage::BlobStorageContext> blob_context,
+      const GURL& origin)
+      : CacheLoader(cache_task_runner,
+                    request_context,
+                    quota_manager_proxy,
+                    blob_context,
+                    origin),
         origin_path_(origin_path),
         weak_ptr_factory_(this) {}
 
@@ -148,8 +165,10 @@
     DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
     return ServiceWorkerCache::CreatePersistentCache(
+        origin_,
         CreatePersistentCachePath(origin_path_, cache_name),
         request_context_,
+        quota_manager_proxy_,
         blob_context_);
   }
 
@@ -345,6 +364,7 @@
     bool memory_only,
     base::SequencedTaskRunner* cache_task_runner,
     net::URLRequestContext* request_context,
+    const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
     base::WeakPtr<storage::BlobStorageContext> blob_context,
     const GURL& origin)
     : initialized_(false),
@@ -353,12 +373,16 @@
       memory_only_(memory_only),
       weak_factory_(this) {
   if (memory_only)
-    cache_loader_.reset(new MemoryLoader(
-        cache_task_runner_.get(), request_context, blob_context, origin));
+    cache_loader_.reset(new MemoryLoader(cache_task_runner_.get(),
+                                         request_context,
+                                         quota_manager_proxy,
+                                         blob_context,
+                                         origin));
   else
     cache_loader_.reset(new SimpleCacheLoader(origin_path_,
                                               cache_task_runner_.get(),
                                               request_context,
+                                              quota_manager_proxy,
                                               blob_context,
                                               origin));
 }
@@ -476,6 +500,20 @@
   }
 }
 
+int64 ServiceWorkerCacheStorage::MemoryBackedSize() const {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  if (!initialized_ || !memory_only_)
+    return 0;
+
+  int64 sum = 0;
+  for (auto& key_value : cache_map_) {
+    if (key_value.second)
+      sum += key_value.second->MemoryBackedSize();
+  }
+  return sum;
+}
+
 // Init is run lazily so that it is called on the proper MessageLoop.
 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/content/browser/service_worker/service_worker_cache_storage.h b/content/browser/service_worker/service_worker_cache_storage.h
index defe429..25ab831a 100644
--- a/content/browser/service_worker/service_worker_cache_storage.h
+++ b/content/browser/service_worker/service_worker_cache_storage.h
@@ -56,6 +56,7 @@
       bool memory_only,
       base::SequencedTaskRunner* cache_task_runner,
       net::URLRequestContext* request_context,
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
       base::WeakPtr<storage::BlobStorageContext> blob_context,
       const GURL& origin);
 
@@ -84,6 +85,10 @@
 
   void CloseAllCaches();
 
+  // The size of all of the origin's contents in memory. Returns 0 if the cache
+  // backend is not a memory backend.
+  int64 MemoryBackedSize() const;
+
  private:
   class MemoryLoader;
   class SimpleCacheLoader;
diff --git a/content/browser/service_worker/service_worker_cache_storage_manager.cc b/content/browser/service_worker/service_worker_cache_storage_manager.cc
index 09182df..ed3d3467 100644
--- a/content/browser/service_worker/service_worker_cache_storage_manager.cc
+++ b/content/browser/service_worker/service_worker_cache_storage_manager.cc
@@ -88,7 +88,7 @@
 ServiceWorkerCacheStorageManager::Create(
     const base::FilePath& path,
     const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner,
-    storage::QuotaManagerProxy* quota_manager_proxy) {
+    const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy) {
   base::FilePath root_path = path;
   if (!path.empty()) {
     root_path = path.Append(ServiceWorkerContextCore::kServiceWorkerDirectory)
@@ -185,8 +185,20 @@
     const storage::QuotaClient::GetUsageCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  // TODO(jkarlin): Get the actual disk usage for the origin.
-  callback.Run(0);
+  if (IsMemoryBacked()) {
+    int64 sum = 0;
+    for (const auto& key_value : cache_storage_map_)
+      sum += key_value.second->MemoryBackedSize();
+    callback.Run(sum);
+    return;
+  }
+
+  PostTaskAndReplyWithResult(
+      cache_task_runner_.get(),
+      FROM_HERE,
+      base::Bind(base::ComputeDirectorySize,
+                 ConstructOriginPath(root_path_, origin_url)),
+      base::Bind(callback));
 }
 
 void ServiceWorkerCacheStorageManager::GetOrigins(
@@ -260,15 +272,16 @@
 ServiceWorkerCacheStorageManager::ServiceWorkerCacheStorageManager(
     const base::FilePath& path,
     const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner,
-    storage::QuotaManagerProxy* quota_manager_proxy)
+    const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
     : root_path_(path),
       cache_task_runner_(cache_task_runner),
       quota_manager_proxy_(quota_manager_proxy),
       request_context_(NULL),
       weak_ptr_factory_(this) {
-  if (quota_manager_proxy_.get())
+  if (quota_manager_proxy_.get()) {
     quota_manager_proxy_->RegisterClient(
         new ServiceWorkerCacheQuotaClient(weak_ptr_factory_.GetWeakPtr()));
+  }
 }
 
 ServiceWorkerCacheStorage*
@@ -276,7 +289,6 @@
     const GURL& origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(request_context_);
-
   ServiceWorkerCacheStorageMap::const_iterator it =
       cache_storage_map_.find(origin);
   if (it == cache_storage_map_.end()) {
@@ -285,6 +297,7 @@
                                       IsMemoryBacked(),
                                       cache_task_runner_.get(),
                                       request_context_,
+                                      quota_manager_proxy_,
                                       blob_context_,
                                       origin);
     // The map owns fetch_stores.
diff --git a/content/browser/service_worker/service_worker_cache_storage_manager.h b/content/browser/service_worker/service_worker_cache_storage_manager.h
index 534d8f4..b549fbb 100644
--- a/content/browser/service_worker/service_worker_cache_storage_manager.h
+++ b/content/browser/service_worker/service_worker_cache_storage_manager.h
@@ -31,6 +31,7 @@
 namespace content {
 
 class ServiceWorkerCacheQuotaClient;
+class ServiceWorkerCacheStorageManagerTest;
 
 // Keeps track of a ServiceWorkerCacheStorage per origin. There is one
 // ServiceWorkerCacheStorageManager per ServiceWorkerContextCore.
@@ -41,7 +42,7 @@
   static scoped_ptr<ServiceWorkerCacheStorageManager> Create(
       const base::FilePath& path,
       const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner,
-      storage::QuotaManagerProxy* quota_manager_proxy);
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy);
 
   static scoped_ptr<ServiceWorkerCacheStorageManager> Create(
       ServiceWorkerCacheStorageManager* old_manager);
@@ -79,6 +80,7 @@
 
  private:
   friend class ServiceWorkerCacheQuotaClient;
+  friend class ServiceWorkerCacheStorageManagerTest;
 
   typedef std::map<GURL, ServiceWorkerCacheStorage*>
       ServiceWorkerCacheStorageMap;
@@ -86,7 +88,7 @@
   ServiceWorkerCacheStorageManager(
       const base::FilePath& path,
       const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner,
-      storage::QuotaManagerProxy* quota_manager_proxy);
+      const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy);
 
   // The returned ServiceWorkerCacheStorage* is owned by
   // service_worker_cache_storages_.
diff --git a/content/browser/service_worker/service_worker_cache_storage_manager_unittest.cc b/content/browser/service_worker/service_worker_cache_storage_manager_unittest.cc
index 09d3537..ee78a59 100644
--- a/content/browser/service_worker/service_worker_cache_storage_manager_unittest.cc
+++ b/content/browser/service_worker/service_worker_cache_storage_manager_unittest.cc
@@ -9,12 +9,14 @@
 #include "base/message_loop/message_loop_proxy.h"
 #include "base/run_loop.h"
 #include "content/browser/fileapi/chrome_blob_storage_context.h"
+#include "content/browser/quota/mock_quota_manager_proxy.h"
 #include "content/browser/service_worker/service_worker_cache_quota_client.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "storage/browser/blob/blob_storage_context.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
@@ -36,15 +38,22 @@
     // Wait for ChromeBlobStorageContext to finish initializing.
     base::RunLoop().RunUntilIdle();
 
+    quota_manager_proxy_ = new MockQuotaManagerProxy(
+        nullptr, base::MessageLoopProxy::current().get());
+
     net::URLRequestContext* url_request_context =
         browser_context_.GetRequestContext()->GetURLRequestContext();
     if (MemoryOnly()) {
       cache_manager_ = ServiceWorkerCacheStorageManager::Create(
-          base::FilePath(), base::MessageLoopProxy::current(), nullptr);
+          base::FilePath(),
+          base::MessageLoopProxy::current(),
+          quota_manager_proxy_);
     } else {
       ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
       cache_manager_ = ServiceWorkerCacheStorageManager::Create(
-          temp_dir_.path(), base::MessageLoopProxy::current(), nullptr);
+          temp_dir_.path(),
+          base::MessageLoopProxy::current(),
+          quota_manager_proxy_);
     }
 
     cache_manager_->SetBlobParametersForCache(
@@ -52,6 +61,7 @@
   }
 
   virtual void TearDown() override {
+    quota_manager_proxy_->SimulateQuotaManagerDestroyed();
     base::RunLoop().RunUntilIdle();
   }
 
@@ -200,11 +210,16 @@
     return !error;
   }
 
+  ServiceWorkerCacheStorage* CacheStorageForOrigin(const GURL& origin) {
+    return cache_manager_->FindOrCreateServiceWorkerCacheManager(origin);
+  }
+
  protected:
   TestBrowserContext browser_context_;
   TestBrowserThreadBundle browser_thread_bundle_;
 
   base::ScopedTempDir temp_dir_;
+  scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
   scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_;
 
   scoped_refptr<ServiceWorkerCache> callback_cache_;
@@ -350,6 +365,7 @@
   EXPECT_TRUE(Open(origin1_, "baz"));
   EXPECT_TRUE(Open(origin2_, "raz"));
   EXPECT_TRUE(Delete(origin1_, "bar"));
+  quota_manager_proxy_->SimulateQuotaManagerDestroyed();
   cache_manager_ =
       ServiceWorkerCacheStorageManager::Create(cache_manager_.get());
   EXPECT_TRUE(Keys(origin1_));
@@ -363,6 +379,7 @@
 TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, DataLostWhenMemoryOnly) {
   EXPECT_TRUE(Open(origin1_, "foo"));
   EXPECT_TRUE(Open(origin2_, "baz"));
+  quota_manager_proxy_->SimulateQuotaManagerDestroyed();
   cache_manager_ =
       ServiceWorkerCacheStorageManager::Create(cache_manager_.get());
   EXPECT_TRUE(Keys(origin1_));
@@ -425,6 +442,32 @@
   EXPECT_TRUE(callback_cache_->AsWeakPtr());
 }
 
+TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, MemoryBackedSize) {
+  ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_);
+  EXPECT_EQ(0, cache_storage->MemoryBackedSize());
+
+  EXPECT_TRUE(Open(origin1_, "foo"));
+  scoped_refptr<ServiceWorkerCache> foo_cache = callback_cache_;
+  EXPECT_TRUE(Open(origin1_, "bar"));
+  scoped_refptr<ServiceWorkerCache> bar_cache = callback_cache_;
+  EXPECT_EQ(0, cache_storage->MemoryBackedSize());
+
+  EXPECT_TRUE(CachePut(foo_cache, GURL("http://example.com/foo")));
+  EXPECT_LT(0, cache_storage->MemoryBackedSize());
+  int64 foo_size = cache_storage->MemoryBackedSize();
+
+  EXPECT_TRUE(CachePut(bar_cache, GURL("http://example.com/foo")));
+  EXPECT_EQ(foo_size * 2, cache_storage->MemoryBackedSize());
+}
+
+TEST_F(ServiceWorkerCacheStorageManagerTest, MemoryBackedSizePersistent) {
+  ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_);
+  EXPECT_EQ(0, cache_storage->MemoryBackedSize());
+  EXPECT_TRUE(Open(origin1_, "foo"));
+  EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo")));
+  EXPECT_EQ(0, cache_storage->MemoryBackedSize());
+}
+
 class ServiceWorkerCacheQuotaClientTest
     : public ServiceWorkerCacheStorageManagerTest {
  protected:
@@ -526,8 +569,7 @@
   EXPECT_EQ(0, QuotaGetOriginUsage(origin1_));
   EXPECT_TRUE(Open(origin1_, "foo"));
   EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo")));
-  // TODO(jkarlin): Once usage is working properly update this value.
-  EXPECT_EQ(0, QuotaGetOriginUsage(origin1_));
+  EXPECT_LT(0, QuotaGetOriginUsage(origin1_));
 }
 
 TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaGetOriginsForType) {
diff --git a/content/browser/service_worker/service_worker_cache_unittest.cc b/content/browser/service_worker/service_worker_cache_unittest.cc
index b1cd1d9..0920ed9 100644
--- a/content/browser/service_worker/service_worker_cache_unittest.cc
+++ b/content/browser/service_worker/service_worker_cache_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/run_loop.h"
 #include "content/browser/fileapi/chrome_blob_storage_context.h"
 #include "content/browser/fileapi/mock_url_request_delegate.h"
+#include "content/browser/quota/mock_quota_manager_proxy.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_context.h"
@@ -20,6 +21,7 @@
 #include "storage/browser/blob/blob_data_handle.h"
 #include "storage/browser/blob/blob_storage_context.h"
 #include "storage/browser/blob/blob_url_request_job_factory.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/common/blob/blob_data.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -53,6 +55,9 @@
     base::RunLoop().RunUntilIdle();
     blob_storage_context_ = blob_storage_context->context();
 
+    quota_manager_proxy_ = new MockQuotaManagerProxy(
+        nullptr, base::MessageLoopProxy::current().get());
+
     url_request_job_factory_.reset(new net::URLRequestJobFactoryImpl);
     url_request_job_factory_->SetProtocolHandler(
         "blob", CreateMockBlobProtocolHandler(blob_storage_context->context()));
@@ -66,18 +71,23 @@
 
     if (MemoryOnly()) {
       cache_ = ServiceWorkerCache::CreateMemoryCache(
+          GURL("http://example.com"),
           url_request_context,
+          quota_manager_proxy_,
           blob_storage_context->context()->AsWeakPtr());
     } else {
       ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
       cache_ = ServiceWorkerCache::CreatePersistentCache(
+          GURL("http://example.com"),
           temp_dir_.path(),
           url_request_context,
+          quota_manager_proxy_,
           blob_storage_context->context()->AsWeakPtr());
     }
   }
 
   virtual void TearDown() override {
+    quota_manager_proxy_->SimulateQuotaManagerDestroyed();
     base::RunLoop().RunUntilIdle();
   }
 
@@ -266,6 +276,7 @@
   TestBrowserContext browser_context_;
   TestBrowserThreadBundle browser_thread_bundle_;
   scoped_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
+  scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
   storage::BlobStorageContext* blob_storage_context_;
 
   base::ScopedTempDir temp_dir_;
@@ -289,6 +300,12 @@
   bool MemoryOnly() override { return !GetParam(); }
 };
 
+class ServiceWorkerCacheMemoryOnlyTest
+    : public ServiceWorkerCacheTest,
+      public testing::WithParamInterface<bool> {
+  bool MemoryOnly() override { return true; }
+};
+
 TEST_P(ServiceWorkerCacheTestP, PutNoBody) {
   EXPECT_TRUE(Put(no_body_request_, no_body_response_));
   EXPECT_TRUE(callback_response_);
@@ -530,6 +547,52 @@
   EXPECT_EQ("bar", request.headers["content-type"]);
 }
 
+TEST_P(ServiceWorkerCacheTestP, QuotaManagerModified) {
+  EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count());
+
+  EXPECT_TRUE(Put(no_body_request_, no_body_response_));
+  EXPECT_EQ(1, quota_manager_proxy_->notify_storage_modified_count());
+  EXPECT_LT(0, quota_manager_proxy_->last_notified_delta());
+  int64 sum_delta = quota_manager_proxy_->last_notified_delta();
+
+  EXPECT_TRUE(Put(body_request_, body_response_));
+  EXPECT_EQ(2, quota_manager_proxy_->notify_storage_modified_count());
+  EXPECT_LT(sum_delta, quota_manager_proxy_->last_notified_delta());
+  sum_delta += quota_manager_proxy_->last_notified_delta();
+
+  EXPECT_TRUE(Delete(body_request_));
+  EXPECT_EQ(3, quota_manager_proxy_->notify_storage_modified_count());
+  sum_delta += quota_manager_proxy_->last_notified_delta();
+
+  EXPECT_TRUE(Delete(no_body_request_));
+  EXPECT_EQ(4, quota_manager_proxy_->notify_storage_modified_count());
+  sum_delta += quota_manager_proxy_->last_notified_delta();
+
+  EXPECT_EQ(0, sum_delta);
+}
+
+TEST_F(ServiceWorkerCacheMemoryOnlyTest, MemoryBackedSize) {
+  EXPECT_EQ(0, cache_->MemoryBackedSize());
+  EXPECT_TRUE(Put(no_body_request_, no_body_response_));
+  EXPECT_LT(0, cache_->MemoryBackedSize());
+  int64 no_body_size = cache_->MemoryBackedSize();
+
+  EXPECT_TRUE(Delete(no_body_request_));
+  EXPECT_EQ(0, cache_->MemoryBackedSize());
+
+  EXPECT_TRUE(Put(body_request_, body_response_));
+  EXPECT_LT(no_body_size, cache_->MemoryBackedSize());
+
+  EXPECT_TRUE(Delete(body_request_));
+  EXPECT_EQ(0, cache_->MemoryBackedSize());
+}
+
+TEST_F(ServiceWorkerCacheTest, MemoryBackedSizePersistent) {
+  EXPECT_EQ(0, cache_->MemoryBackedSize());
+  EXPECT_TRUE(Put(no_body_request_, no_body_response_));
+  EXPECT_EQ(0, cache_->MemoryBackedSize());
+}
+
 INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheTest,
                         ServiceWorkerCacheTestP,
                         ::testing::Values(false, true));
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index c467a91..2272c958 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -23,6 +23,7 @@
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_storage.h"
 #include "content/public/browser/browser_thread.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
 #include "url/gurl.h"
 
 namespace content {
@@ -122,10 +123,10 @@
                                             disk_cache_thread,
                                             quota_manager_proxy,
                                             special_storage_policy)),
-      cache_manager_(
-          ServiceWorkerCacheStorageManager::Create(path,
-                                                   cache_task_runner.get(),
-                                                   quota_manager_proxy)),
+      cache_manager_(ServiceWorkerCacheStorageManager::Create(
+          path,
+          cache_task_runner.get(),
+          make_scoped_refptr(quota_manager_proxy))),
       embedded_worker_registry_(EmbeddedWorkerRegistry::Create(AsWeakPtr())),
       job_coordinator_(new ServiceWorkerJobCoordinator(AsWeakPtr())),
       next_handle_id_(0),
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h
index b442f01aa..04fb21d 100644
--- a/content/browser/service_worker/service_worker_provider_host.h
+++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -133,6 +133,7 @@
 
  private:
   friend class ServiceWorkerProviderHostTest;
+  friend class ServiceWorkerWriteToCacheJobTest;
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest,
                            UpdateBefore24Hours);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest,
diff --git a/content/browser/service_worker/service_worker_registration_handle.cc b/content/browser/service_worker/service_worker_registration_handle.cc
index 21aa31ef..195a33a 100644
--- a/content/browser/service_worker/service_worker_registration_handle.cc
+++ b/content/browser/service_worker/service_worker_registration_handle.cc
@@ -42,6 +42,7 @@
   ServiceWorkerRegistrationObjectInfo info;
   info.handle_id = handle_id_;
   info.scope = registration_->pattern();
+  info.registration_id = registration_->id();
   return info;
 }
 
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h
index 85e1a72..5241d26 100644
--- a/content/browser/service_worker/service_worker_storage.h
+++ b/content/browser/service_worker/service_worker_storage.h
@@ -168,6 +168,7 @@
   friend class ServiceWorkerControlleeRequestHandlerTest;
   friend class ServiceWorkerContextRequestHandlerTest;
   friend class ServiceWorkerRequestHandlerTest;
+  friend class ServiceWorkerWriteToCacheJobTest;
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
                            DeleteRegistration_NoLiveVersion);
   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerResourceStorageTest,
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc
index 35e41ab..43ff928 100644
--- a/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -79,10 +79,6 @@
   return base::Bind(&GetAllCallback, was_called, all);
 }
 
-void OnIOComplete(int* rv_out, int rv) {
-  *rv_out = rv;
-}
-
 void OnCompareComplete(
     ServiceWorkerStatusCode* status_out, bool* are_equal_out,
     ServiceWorkerStatusCode status, bool are_equal) {
@@ -104,16 +100,18 @@
   info->headers = new net::HttpResponseHeaders(headers);
   scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
       new HttpResponseInfoIOBuffer(info.release());
-
-  int rv = -1234;
-  writer->WriteInfo(info_buffer.get(), base::Bind(&OnIOComplete, &rv));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_LT(0, rv);
-
-  rv = -1234;
-  writer->WriteData(body, length, base::Bind(&OnIOComplete, &rv));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(length, rv);
+  {
+    TestCompletionCallback cb;
+    writer->WriteInfo(info_buffer.get(), cb.callback());
+    int rv = cb.WaitForResult();
+    EXPECT_LT(0, rv);
+  }
+  {
+    TestCompletionCallback cb;
+    writer->WriteData(body, length, cb.callback());
+    int rv = cb.WaitForResult();
+    EXPECT_EQ(length, rv);
+  }
 }
 
 void WriteStringResponse(
@@ -760,13 +758,7 @@
   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_, false));
 }
 
-// Android has flaky IO error: http://crbug.com/387045
-#if defined(OS_ANDROID)
-#define MAYBE_CleanupOnRestart DISABLED_CleanupOnRestart
-#else
-#define MAYBE_CleanupOnRestart CleanupOnRestart
-#endif
-TEST_F(ServiceWorkerResourceStorageDiskTest, MAYBE_CleanupOnRestart) {
+TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
   // Promote the worker to active and add a controllee.
   registration_->SetActiveVersion(registration_->waiting_version());
   registration_->SetWaitingVersion(NULL);
@@ -848,6 +840,11 @@
   ASSERT_EQ(1u, verify_ids.size());
   EXPECT_EQ(kNewResourceId, *verify_ids.begin());
 
+  // Purging resources needs interactions with SimpleCache's worker thread,
+  // so single RunUntilIdle() call may not be sufficient.
+  while (storage()->is_purge_pending_)
+    base::RunLoop().RunUntilIdle();
+
   verify_ids.clear();
   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
             storage()->database_->GetPurgeableResourceIds(&verify_ids));
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.cc b/content/browser/service_worker/service_worker_write_to_cache_job.cc
index ccf575a..0baf702a2 100644
--- a/content/browser/service_worker/service_worker_write_to_cache_job.cc
+++ b/content/browser/service_worker/service_worker_write_to_cache_job.cc
@@ -10,6 +10,7 @@
 #include "content/browser/service_worker/service_worker_metrics.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
+#include "net/http/http_network_session.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_util.h"
@@ -307,7 +308,7 @@
       net::URLRequestStatus::FAILED, net::ERR_FAILED));
 }
 
-void ServiceWorkerWriteToCacheJob:: OnSSLCertificateError(
+void ServiceWorkerWriteToCacheJob::OnSSLCertificateError(
     net::URLRequest* request,
     const net::SSLInfo& ssl_info,
     bool fatal) {
@@ -317,7 +318,7 @@
   // TODO(michaeln): Pass this thru to our jobs client,
   // see NotifySSLCertificateError.
   AsyncNotifyDoneHelper(net::URLRequestStatus(
-      net::URLRequestStatus::FAILED, net::ERR_FAILED));
+      net::URLRequestStatus::FAILED, net::ERR_INSECURE_RESPONSE));
 }
 
 void ServiceWorkerWriteToCacheJob::OnBeforeNetworkStart(
@@ -343,6 +344,17 @@
     // response to our consumer, just don't cache it?
     return;
   }
+  // OnSSLCertificateError is not called when the HTTPS connection is reused.
+  // So we check cert_status here.
+  if (net::IsCertStatusError(request->ssl_info().cert_status)) {
+    const net::HttpNetworkSession::Params* session_params =
+        request->context()->GetNetworkSessionParams();
+    if (!session_params || !session_params->ignore_certificate_errors) {
+      AsyncNotifyDoneHelper(net::URLRequestStatus(net::URLRequestStatus::FAILED,
+                                                  net::ERR_INSECURE_RESPONSE));
+      return;
+    }
+  }
   // To prevent most user-uploaded content from being used as a serviceworker.
   if (version_->script_url() == url_) {
     std::string mime_type;
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
new file mode 100644
index 0000000..7ec1f15
--- /dev/null
+++ b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
@@ -0,0 +1,300 @@
+// 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 "base/run_loop.h"
+#include "content/browser/fileapi/mock_url_request_delegate.h"
+#include "content/browser/service_worker/embedded_worker_test_helper.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_context_request_handler.h"
+#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/browser/service_worker/service_worker_utils.h"
+#include "content/common/resource_request_body.h"
+#include "content/public/test/mock_resource_context.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_job_factory_impl.h"
+#include "net/url_request/url_request_test_job.h"
+#include "net/url_request/url_request_test_util.h"
+#include "storage/browser/blob/blob_storage_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+int kMockRenderProcessId = 1224;
+int kMockProviderId = 1;
+const char kHeaders[] =
+    "HTTP/1.1 200 OK\0"
+    "Content-Type: text/javascript\0"
+    "Expires: Thu, 1 Jan 2100 20:00:00 GMT\0"
+    "\0";
+const char kScriptCode[] = "// no script code\n";
+
+void EmptyCallback() {
+}
+
+net::URLRequestJob* CreateNormalURLRequestJob(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate) {
+  return new net::URLRequestTestJob(request,
+                                    network_delegate,
+                                    std::string(kHeaders, arraysize(kHeaders)),
+                                    kScriptCode,
+                                    true);
+}
+
+net::URLRequestJob* CreateInvalidMimeTypeJob(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate) {
+  const char kPlainTextHeaders[] =
+      "HTTP/1.1 200 OK\0"
+      "Content-Type: text/plain\0"
+      "Expires: Thu, 1 Jan 2100 20:00:00 GMT\0"
+      "\0";
+  return new net::URLRequestTestJob(
+      request,
+      network_delegate,
+      std::string(kPlainTextHeaders, arraysize(kPlainTextHeaders)),
+      kScriptCode,
+      true);
+}
+
+class SSLCertificateErrorJob : public net::URLRequestTestJob {
+ public:
+  SSLCertificateErrorJob(net::URLRequest* request,
+                         net::NetworkDelegate* network_delegate,
+                         const std::string& response_headers,
+                         const std::string& response_data,
+                         bool auto_advance)
+      : net::URLRequestTestJob(request,
+                               network_delegate,
+                               response_headers,
+                               response_data,
+                               auto_advance),
+        weak_factory_(this) {}
+  virtual void Start() override {
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&SSLCertificateErrorJob::NotifyError,
+                   weak_factory_.GetWeakPtr()));
+  }
+  void NotifyError() {
+    net::SSLInfo info;
+    info.cert_status = net::CERT_STATUS_DATE_INVALID;
+    NotifySSLCertificateError(info, true);
+  }
+
+ protected:
+  ~SSLCertificateErrorJob() override {}
+  base::WeakPtrFactory<SSLCertificateErrorJob> weak_factory_;
+};
+
+net::URLRequestJob* CreateSSLCertificateErrorJob(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate) {
+  return new SSLCertificateErrorJob(request,
+                                    network_delegate,
+                                    std::string(kHeaders, arraysize(kHeaders)),
+                                    kScriptCode,
+                                    true);
+}
+
+class CertStatusErrorJob : public net::URLRequestTestJob {
+ public:
+  CertStatusErrorJob(net::URLRequest* request,
+                     net::NetworkDelegate* network_delegate,
+                     const std::string& response_headers,
+                     const std::string& response_data,
+                     bool auto_advance)
+      : net::URLRequestTestJob(request,
+                               network_delegate,
+                               response_headers,
+                               response_data,
+                               auto_advance) {}
+  virtual void GetResponseInfo(net::HttpResponseInfo* info) override {
+    URLRequestTestJob::GetResponseInfo(info);
+    info->ssl_info.cert_status = net::CERT_STATUS_DATE_INVALID;
+  }
+
+ protected:
+  ~CertStatusErrorJob() override {}
+};
+
+net::URLRequestJob* CreateCertStatusErrorJob(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate) {
+  return new CertStatusErrorJob(request,
+                                network_delegate,
+                                std::string(kHeaders, arraysize(kHeaders)),
+                                kScriptCode,
+                                true);
+}
+
+class MockHttpProtocolHandler
+    : public net::URLRequestJobFactory::ProtocolHandler {
+ public:
+  typedef base::Callback<
+      net::URLRequestJob*(net::URLRequest*, net::NetworkDelegate*)> JobCallback;
+
+  MockHttpProtocolHandler(ResourceContext* resource_context)
+      : resource_context_(resource_context) {}
+  ~MockHttpProtocolHandler() override {}
+
+  virtual net::URLRequestJob* MaybeCreateJob(
+      net::URLRequest* request,
+      net::NetworkDelegate* network_delegate) const override {
+    ServiceWorkerRequestHandler* handler =
+        ServiceWorkerRequestHandler::GetHandler(request);
+    if (handler) {
+      return handler->MaybeCreateJob(
+          request, network_delegate, resource_context_);
+    }
+    return create_job_callback_.Run(request, network_delegate);
+  }
+  void SetCreateJobCallback(const JobCallback& callback) {
+    create_job_callback_ = callback;
+  }
+
+ private:
+  ResourceContext* resource_context_;
+  JobCallback create_job_callback_;
+};
+}
+
+class ServiceWorkerWriteToCacheJobTest : public testing::Test {
+ public:
+  ServiceWorkerWriteToCacheJobTest()
+      : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
+        mock_protocol_handler_(NULL) {}
+  ~ServiceWorkerWriteToCacheJobTest() override {}
+
+  virtual void SetUp() override {
+    helper_.reset(new EmbeddedWorkerTestHelper(kMockRenderProcessId));
+
+    // A new unstored registration/version.
+    scope_ = GURL("https://host/scope/");
+    script_url_ = GURL("https://host/script.js");
+    registration_ =
+        new ServiceWorkerRegistration(scope_, 1L, context()->AsWeakPtr());
+    version_ = new ServiceWorkerVersion(
+        registration_.get(), script_url_, 1L, context()->AsWeakPtr());
+
+    // An empty host.
+    scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
+        kMockRenderProcessId, kMockProviderId, context()->AsWeakPtr(), NULL));
+    provider_host_ = host->AsWeakPtr();
+    context()->AddProviderHost(host.Pass());
+    provider_host_->running_hosted_version_ = version_;
+
+    context()->storage()->LazyInitialize(base::Bind(&EmptyCallback));
+    base::RunLoop().RunUntilIdle();
+
+    url_request_context_.reset(new net::URLRequestContext);
+    mock_protocol_handler_ = new MockHttpProtocolHandler(&resource_context_);
+    url_request_job_factory_.reset(new net::URLRequestJobFactoryImpl);
+    url_request_job_factory_->SetProtocolHandler("https",
+                                                 mock_protocol_handler_);
+    url_request_context_->set_job_factory(url_request_job_factory_.get());
+
+    request_ = url_request_context_->CreateRequest(
+        script_url_, net::DEFAULT_PRIORITY, &url_request_delegate_, NULL);
+    ServiceWorkerRequestHandler::InitializeHandler(
+        request_.get(),
+        context_wrapper(),
+        &blob_storage_context_,
+        kMockRenderProcessId,
+        kMockProviderId,
+        false,
+        FETCH_REQUEST_MODE_NO_CORS,
+        FETCH_CREDENTIALS_MODE_OMIT,
+        RESOURCE_TYPE_SERVICE_WORKER,
+        REQUEST_CONTEXT_TYPE_SERVICE_WORKER,
+        REQUEST_CONTEXT_FRAME_TYPE_NONE,
+        scoped_refptr<ResourceRequestBody>());
+  }
+
+  virtual void TearDown() override {
+    request_.reset();
+    url_request_context_.reset();
+    url_request_job_factory_.reset();
+    mock_protocol_handler_ = NULL;
+    version_ = NULL;
+    registration_ = NULL;
+    helper_.reset();
+    // URLRequestJobs may post clean-up tasks on destruction.
+    base::RunLoop().RunUntilIdle();
+  }
+
+  ServiceWorkerContextCore* context() const { return helper_->context(); }
+  ServiceWorkerContextWrapper* context_wrapper() const {
+    return helper_->context_wrapper();
+  }
+
+ protected:
+  TestBrowserThreadBundle browser_thread_bundle_;
+  scoped_ptr<EmbeddedWorkerTestHelper> helper_;
+  scoped_refptr<ServiceWorkerRegistration> registration_;
+  scoped_refptr<ServiceWorkerVersion> version_;
+  base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
+  scoped_ptr<net::URLRequestContext> url_request_context_;
+  scoped_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
+  scoped_ptr<net::URLRequest> request_;
+  MockHttpProtocolHandler* mock_protocol_handler_;
+
+  storage::BlobStorageContext blob_storage_context_;
+  content::MockResourceContext resource_context_;
+
+  MockURLRequestDelegate url_request_delegate_;
+  GURL scope_;
+  GURL script_url_;
+};
+
+TEST_F(ServiceWorkerWriteToCacheJobTest, Normal) {
+  mock_protocol_handler_->SetCreateJobCallback(
+      base::Bind(&CreateNormalURLRequestJob));
+  request_->Start();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(net::URLRequestStatus::SUCCESS, request_->status().status());
+  EXPECT_NE(kInvalidServiceWorkerResponseId,
+            version_->script_cache_map()->LookupResourceId(script_url_));
+}
+
+TEST_F(ServiceWorkerWriteToCacheJobTest, InvalidMimeType) {
+  mock_protocol_handler_->SetCreateJobCallback(
+      base::Bind(&CreateInvalidMimeTypeJob));
+  request_->Start();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
+  EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
+  EXPECT_EQ(kInvalidServiceWorkerResponseId,
+            version_->script_cache_map()->LookupResourceId(script_url_));
+}
+
+TEST_F(ServiceWorkerWriteToCacheJobTest, SSLCertificateError) {
+  mock_protocol_handler_->SetCreateJobCallback(
+      base::Bind(&CreateSSLCertificateErrorJob));
+  request_->Start();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
+  EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
+  EXPECT_EQ(kInvalidServiceWorkerResponseId,
+            version_->script_cache_map()->LookupResourceId(script_url_));
+}
+
+TEST_F(ServiceWorkerWriteToCacheJobTest, CertStatusError) {
+  mock_protocol_handler_->SetCreateJobCallback(
+      base::Bind(&CreateCertStatusErrorJob));
+  request_->Start();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(net::URLRequestStatus::FAILED, request_->status().status());
+  EXPECT_EQ(net::ERR_INSECURE_RESPONSE, request_->status().error());
+  EXPECT_EQ(kInvalidServiceWorkerResponseId,
+            version_->script_cache_map()->LookupResourceId(script_url_));
+}
+
+}  // namespace content
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 660b4c6..4c2a419 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -195,12 +195,11 @@
   host_resolver()->AddRule("*", "127.0.0.1");
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
   SetupCrossSiteRedirector(embedded_test_server());
-  embedded_test_server()->ServeFilesFromDirectory(GetTestFilePath("files", ""));
 }
 
-// It fails on ChromeOS and Android, so disabled while investigating.
+// It times out on Android, so disabled while investigating.
 // http://crbug.com/399775
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+#if defined(OS_ANDROID)
 #define MAYBE_CrossSiteIframe DISABLED_CrossSiteIframe
 #else
 #define MAYBE_CrossSiteIframe CrossSiteIframe
@@ -306,9 +305,9 @@
       proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());
 }
 
-// It fails on ChromeOS and Android, so disabled while investigating.
+// It times out on Android, so disabled while investigating.
 // http://crbug.com/399775
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+#if defined(OS_ANDROID)
 #define MAYBE_NavigateRemoteFrame DISABLED_NavigateRemoteFrame
 #else
 #define MAYBE_NavigateRemoteFrame NavigateRemoteFrame
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.cc b/content/browser/speech/speech_recognition_dispatcher_host.cc
index 4a90ba6d..f920c51 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.cc
+++ b/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -42,6 +42,10 @@
   return weak_factory_.GetWeakPtr();
 }
 
+void SpeechRecognitionDispatcherHost::OnDestruct() const {
+  BrowserThread::DeleteOnIOThread::Destruct(this);
+}
+
 bool SpeechRecognitionDispatcherHost::OnMessageReceived(
     const IPC::Message& message) {
   bool handled = true;
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.h b/content/browser/speech/speech_recognition_dispatcher_host.h
index c64904e..34b33320 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.h
+++ b/content/browser/speech/speech_recognition_dispatcher_host.h
@@ -50,6 +50,7 @@
                            float noise_volume) override;
 
   // BrowserMessageFilter implementation.
+  void OnDestruct() const override;
   bool OnMessageReceived(const IPC::Message& message) override;
   void OverrideThreadForMessage(const IPC::Message& message,
                                 BrowserThread::ID* thread) override;
@@ -57,6 +58,9 @@
   void OnChannelClosing() override;
 
  private:
+  friend class base::DeleteHelper<SpeechRecognitionDispatcherHost>;
+  friend class BrowserThread;
+
   ~SpeechRecognitionDispatcherHost() override;
 
   void OnStartRequest(
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 1e26255..d4e49f60 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -8,6 +8,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "content/browser/browser_main_loop.h"
 #include "content/browser/fileapi/browser_file_system_helper.h"
+#include "content/browser/geofencing/geofencing_manager.h"
 #include "content/browser/gpu/shader_disk_cache.h"
 #include "content/common/dom_storage/dom_storage_types.h"
 #include "content/public/browser/browser_context.h"
@@ -233,8 +234,11 @@
     quota_client_mask |= storage::QuotaClient::kAppcache;
   if (remove_mask & StoragePartition::REMOVE_DATA_MASK_INDEXEDDB)
     quota_client_mask |= storage::QuotaClient::kIndexedDatabase;
-  if (remove_mask & StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS)
+  if (remove_mask & StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS) {
     quota_client_mask |= storage::QuotaClient::kServiceWorker;
+    quota_client_mask |= storage::QuotaClient::kServiceWorkerCache;
+  }
+
 
   return quota_client_mask;
 }
@@ -363,7 +367,8 @@
     IndexedDBContextImpl* indexed_db_context,
     ServiceWorkerContextWrapper* service_worker_context,
     WebRTCIdentityStore* webrtc_identity_store,
-    storage::SpecialStoragePolicy* special_storage_policy)
+    storage::SpecialStoragePolicy* special_storage_policy,
+    GeofencingManager* geofencing_manager)
     : partition_path_(partition_path),
       quota_manager_(quota_manager),
       appcache_service_(appcache_service),
@@ -373,7 +378,8 @@
       indexed_db_context_(indexed_db_context),
       service_worker_context_(service_worker_context),
       webrtc_identity_store_(webrtc_identity_store),
-      special_storage_policy_(special_storage_policy) {
+      special_storage_policy_(special_storage_policy),
+      geofencing_manager_(geofencing_manager) {
 }
 
 StoragePartitionImpl::~StoragePartitionImpl() {
@@ -394,6 +400,9 @@
 
   if (GetServiceWorkerContext())
     GetServiceWorkerContext()->Shutdown();
+
+  if (GetGeofencingManager())
+    GetGeofencingManager()->Shutdown();
 }
 
 // TODO(ajwong): Break the direct dependency on |context|. We only
@@ -465,6 +474,10 @@
   scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy(
       context->GetSpecialStoragePolicy());
 
+  scoped_refptr<GeofencingManager> geofencing_manager =
+      new GeofencingManager(service_worker_context);
+  geofencing_manager->Init();
+
   return new StoragePartitionImpl(partition_path,
                                   quota_manager.get(),
                                   appcache_service.get(),
@@ -474,7 +487,8 @@
                                   indexed_db_context.get(),
                                   service_worker_context.get(),
                                   webrtc_identity_store.get(),
-                                  special_storage_policy.get());
+                                  special_storage_policy.get(),
+                                  geofencing_manager.get());
 }
 
 base::FilePath StoragePartitionImpl::GetPath() {
@@ -518,6 +532,10 @@
   return service_worker_context_.get();
 }
 
+GeofencingManager* StoragePartitionImpl::GetGeofencingManager() {
+  return geofencing_manager_.get();
+}
+
 void StoragePartitionImpl::ClearDataImpl(
     uint32 remove_mask,
     uint32 quota_storage_remove_mask,
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index f0c12d4..3037739 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -43,6 +43,7 @@
   DOMStorageContextWrapper* GetDOMStorageContext() override;
   IndexedDBContextImpl* GetIndexedDBContext() override;
   ServiceWorkerContextWrapper* GetServiceWorkerContext() override;
+  GeofencingManager* GetGeofencingManager() override;
 
   void ClearDataForOrigin(uint32 remove_mask,
                           uint32 quota_storage_remove_mask,
@@ -116,7 +117,8 @@
       IndexedDBContextImpl* indexed_db_context,
       ServiceWorkerContextWrapper* service_worker_context,
       WebRTCIdentityStore* webrtc_identity_store,
-      storage::SpecialStoragePolicy* special_storage_policy);
+      storage::SpecialStoragePolicy* special_storage_policy,
+      GeofencingManager* geofencing_manager);
 
   void ClearDataImpl(uint32 remove_mask,
                      uint32 quota_storage_remove_mask,
@@ -156,6 +158,7 @@
   scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
   scoped_refptr<WebRTCIdentityStore> webrtc_identity_store_;
   scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
+  scoped_refptr<GeofencingManager> geofencing_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(StoragePartitionImpl);
 };
diff --git a/content/browser/udev_linux.cc b/content/browser/udev_linux.cc
index f6f9443..80c929b 100644
--- a/content/browser/udev_linux.cc
+++ b/content/browser/udev_linux.cc
@@ -13,23 +13,21 @@
 UdevLinux::UdevLinux(const std::vector<UdevMonitorFilter>& filters,
                      const UdevNotificationCallback& callback)
     : udev_(udev_new()),
-      monitor_(NULL),
+      monitor_(udev_monitor_new_from_netlink(udev_.get(), "udev")),
       monitor_fd_(-1),
       callback_(callback) {
   CHECK(udev_);
-
-  monitor_ = udev_monitor_new_from_netlink(udev_, "udev");
   CHECK(monitor_);
 
   for (size_t i = 0; i < filters.size(); ++i) {
     int ret = udev_monitor_filter_add_match_subsystem_devtype(
-        monitor_, filters[i].subsystem, filters[i].devtype);
+        monitor_.get(), filters[i].subsystem, filters[i].devtype);
     CHECK_EQ(0, ret);
   }
 
-  int ret = udev_monitor_enable_receiving(monitor_);
+  int ret = udev_monitor_enable_receiving(monitor_.get());
   CHECK_EQ(0, ret);
-  monitor_fd_ = udev_monitor_get_fd(monitor_);
+  monitor_fd_ = udev_monitor_get_fd(monitor_.get());
   CHECK_GE(monitor_fd_, 0);
 
   bool success = base::MessageLoopForIO::current()->WatchFileDescriptor(
@@ -43,12 +41,10 @@
 
 UdevLinux::~UdevLinux() {
   monitor_watcher_.StopWatchingFileDescriptor();
-  udev_monitor_unref(monitor_);
-  udev_unref(udev_);
 }
 
 udev* UdevLinux::udev_handle() {
-  return udev_;
+  return udev_.get();
 }
 
 void UdevLinux::OnFileCanReadWithoutBlocking(int fd) {
@@ -56,12 +52,12 @@
   // change state. udev_monitor_receive_device() will return a device object
   // representing the device which changed and what type of change occured.
   DCHECK_EQ(monitor_fd_, fd);
-  udev_device* dev = udev_monitor_receive_device(monitor_);
+  device::ScopedUdevDevicePtr dev(
+      udev_monitor_receive_device(monitor_.get()));
   if (!dev)
     return;
 
-  callback_.Run(dev);
-  udev_device_unref(dev);
+  callback_.Run(dev.get());
 }
 
 void UdevLinux::OnFileCanWriteWithoutBlocking(int fd) {
diff --git a/content/browser/udev_linux.h b/content/browser/udev_linux.h
index e62d439..5ced8ce 100644
--- a/content/browser/udev_linux.h
+++ b/content/browser/udev_linux.h
@@ -42,6 +42,7 @@
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/message_loop/message_pump_libevent.h"
+#include "device/udev_linux/scoped_udev.h"
 
 extern "C" {
 struct udev;
@@ -83,8 +84,8 @@
 
   // libudev-related items, the main context, and the monitoring context to be
   // notified about changes to device states.
-  udev* udev_;
-  udev_monitor* monitor_;
+  device::ScopedUdevPtr udev_;
+  device::ScopedUdevMonitorPtr monitor_;
   int monitor_fd_;
   base::MessagePumpLibevent::FileDescriptorWatcher monitor_watcher_;
   UdevNotificationCallback callback_;
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc
index 1bef8a3..dd3b37f 100644
--- a/content/browser/web_contents/web_contents_android.cc
+++ b/content/browser/web_contents/web_contents_android.cc
@@ -363,4 +363,23 @@
       ConvertJavaStringToUTF16(env, script), js_callback);
 }
 
+// TODO(sgurun) add support for posting a frame whose name is known (only
+//               main frame is supported at this time, see crbug.com/389721)
+// TODO(sgurun) add support for passing message ports
+void WebContentsAndroid::PostMessageToFrame(JNIEnv* env, jobject obj,
+    jstring frame_name, jstring message, jstring source_origin,
+    jstring target_origin) {
+
+  RenderViewHost* host = web_contents_->GetRenderViewHost();
+  if (!host)
+    return;
+  ViewMsg_PostMessage_Params params;
+  params.source_origin = ConvertJavaStringToUTF16(env, source_origin);
+  params.target_origin = ConvertJavaStringToUTF16(env, target_origin);
+  params.data = ConvertJavaStringToUTF16(env, message);
+  params.is_data_raw_string = true;
+  params.source_routing_id = MSG_ROUTING_NONE;
+  host->Send(new ViewMsg_PostMessageEvent(host->GetRoutingID(), params));
+}
+
 }  // namespace content
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h
index 4ffedd4..7dfcccc 100644
--- a/content/browser/web_contents/web_contents_android.h
+++ b/content/browser/web_contents/web_contents_android.h
@@ -88,7 +88,8 @@
                           jobject obj,
                           jstring script,
                           jobject callback);
-
+  void PostMessageToFrame(JNIEnv* env, jobject obj, jstring frame_id,
+      jstring message, jstring source_origin, jstring target_origin);
  private:
   RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid();
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index f697a09..4ce4f972 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/command_line.h"
-#include "base/debug/crash_logging.h"
 #include "base/debug/trace_event.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
@@ -3589,32 +3588,8 @@
 }
 
 void WebContentsImpl::UpdateState(RenderViewHost* rvh,
-                                  int32 rvh_page_id,
                                   int32 page_id,
                                   const PageState& page_state) {
-  if (rvh_page_id != page_id) {
-    base::debug::SetCrashKeyValue("renderer_page_id",
-                                  base::IntToString(page_id));
-    base::debug::SetCrashKeyValue("browser_page_id",
-                                  base::IntToString(rvh_page_id));
-    NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
-        controller_.GetLastCommittedEntry());
-    // The question being answered here is: when there is a page id mismatch
-    // between the renderer and the browser, which value (if either) matches
-    // that of the last committed entry?
-    if (entry) {
-      if (entry->site_instance() == rvh->GetSiteInstance()) {
-        base::debug::SetCrashKeyValue("last_committed_page_id",
-                                      base::IntToString(entry->GetPageID()));
-      } else {
-        base::debug::SetCrashKeyValue("last_committed_page_id",
-                                      "site instance mismatch");
-      }
-    } else {
-      base::debug::SetCrashKeyValue("last_committed_page_id", "no entry");
-    }
-    CHECK(false);
-  }
   // Ensure that this state update comes from either the active RVH or one of
   // the swapped out RVHs.  We don't expect to hear from any other RVHs.
   // TODO(nasko): This should go through RenderFrameHost.
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 8201c9b..60fdc726 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -404,7 +404,6 @@
                             int error_code) override;
   void RenderViewDeleted(RenderViewHost* render_view_host) override;
   void UpdateState(RenderViewHost* render_view_host,
-                   int32 rvh_page_id,
                    int32 page_id,
                    const PageState& page_state) override;
   void UpdateTargetURL(const GURL& url) override;
diff --git a/content/child/appcache/web_application_cache_host_impl.cc b/content/child/appcache/web_application_cache_host_impl.cc
index 08ec0f4..bf110b1 100644
--- a/content/child/appcache/web_application_cache_host_impl.cc
+++ b/content/child/appcache/web_application_cache_host_impl.cc
@@ -255,6 +255,13 @@
     is_new_master_entry_ = NO;
 }
 
+void WebApplicationCacheHostImpl::didReceiveDataForMainResource(
+    const char* data, unsigned len) {
+  if (is_new_master_entry_ == NO)
+    return;
+  // TODO(michaeln): write me
+}
+
 void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) {
   if (is_new_master_entry_ == NO)
     return;
diff --git a/content/child/appcache/web_application_cache_host_impl.h b/content/child/appcache/web_application_cache_host_impl.h
index a01b028..4c81d46b 100644
--- a/content/child/appcache/web_application_cache_host_impl.h
+++ b/content/child/appcache/web_application_cache_host_impl.h
@@ -46,8 +46,7 @@
   virtual void selectCacheWithoutManifest();
   virtual bool selectCacheWithManifest(const blink::WebURL& manifestURL);
   virtual void didReceiveResponseForMainResource(const blink::WebURLResponse&);
-  // TODO(tyoshino): Revive didReceiveDataForMainResource once Blink side
-  // refactoring is done. See crbug.com/418885.
+  virtual void didReceiveDataForMainResource(const char* data, unsigned len);
   virtual void didFinishLoadingMainResource(bool success);
   virtual blink::WebApplicationCacheHost::Status status();
   virtual bool startUpdate();
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 84beac0d..aa62a54 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -35,7 +35,6 @@
 #include "content/child/geofencing/web_geofencing_provider_impl.h"
 #include "content/child/web_discardable_memory_impl.h"
 #include "content/child/web_gesture_curve_impl.h"
-#include "content/child/web_socket_stream_handle_impl.h"
 #include "content/child/web_url_loader_impl.h"
 #include "content/child/websocket_bridge.h"
 #include "content/child/webthread_impl.h"
@@ -62,7 +61,6 @@
 using blink::WebFallbackThemeEngine;
 using blink::WebLocalizedString;
 using blink::WebString;
-using blink::WebSocketStreamHandle;
 using blink::WebThemeEngine;
 using blink::WebURL;
 using blink::WebURLError;
@@ -441,10 +439,6 @@
       child_thread ? child_thread->resource_dispatcher() : NULL);
 }
 
-WebSocketStreamHandle* BlinkPlatformImpl::createSocketStreamHandle() {
-  return new WebSocketStreamHandleImpl;
-}
-
 blink::WebSocketHandle* BlinkPlatformImpl::createWebSocketHandle() {
   return new WebSocketBridge;
 }
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h
index 4a3c7b8..060fbf0 100644
--- a/content/child/blink_platform_impl.h
+++ b/content/child/blink_platform_impl.h
@@ -75,7 +75,6 @@
       size_t bytes);
   virtual size_t maxDecodedImageBytes() override;
   virtual blink::WebURLLoader* createURLLoader();
-  virtual blink::WebSocketStreamHandle* createSocketStreamHandle();
   virtual blink::WebSocketHandle* createWebSocketHandle() override;
   virtual blink::WebString userAgent();
   virtual blink::WebData parseDataURL(
diff --git a/content/child/child_thread.cc b/content/child/child_thread.cc
index 6bbc4a4..de85d4f 100644
--- a/content/child/child_thread.cc
+++ b/content/child/child_thread.cc
@@ -40,7 +40,6 @@
 #include "content/child/quota_message_filter.h"
 #include "content/child/resource_dispatcher.h"
 #include "content/child/service_worker/service_worker_message_filter.h"
-#include "content/child/socket_stream_dispatcher.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/child/websocket_dispatcher.h"
 #include "content/common/child_process_messages.h"
@@ -274,7 +273,6 @@
       base::MessageLoopProxy::current().get(), sync_message_filter_.get());
 
   resource_dispatcher_.reset(new ResourceDispatcher(this));
-  socket_stream_dispatcher_.reset(new SocketStreamDispatcher());
   websocket_dispatcher_.reset(new WebSocketDispatcher);
   file_system_dispatcher_.reset(new FileSystemDispatcher());
 
@@ -464,8 +462,6 @@
   // Resource responses are sent to the resource dispatcher.
   if (resource_dispatcher_->OnMessageReceived(msg))
     return true;
-  if (socket_stream_dispatcher_->OnMessageReceived(msg))
-    return true;
   if (websocket_dispatcher_->OnMessageReceived(msg))
     return true;
   if (file_system_dispatcher_->OnMessageReceived(msg))
diff --git a/content/child/child_thread.h b/content/child/child_thread.h
index c718000..6c71c0f 100644
--- a/content/child/child_thread.h
+++ b/content/child/child_thread.h
@@ -46,7 +46,6 @@
 class QuotaDispatcher;
 class QuotaMessageFilter;
 class ResourceDispatcher;
-class SocketStreamDispatcher;
 class ThreadSafeSender;
 class WebSocketDispatcher;
 struct RequestInfo;
@@ -106,10 +105,6 @@
     return resource_dispatcher_.get();
   }
 
-  SocketStreamDispatcher* socket_stream_dispatcher() const {
-    return socket_stream_dispatcher_.get();
-  }
-
   WebSocketDispatcher* websocket_dispatcher() const {
     return websocket_dispatcher_.get();
   }
@@ -222,9 +217,6 @@
   // Handles resource loads for this process.
   scoped_ptr<ResourceDispatcher> resource_dispatcher_;
 
-  // Handles SocketStream for this process.
-  scoped_ptr<SocketStreamDispatcher> socket_stream_dispatcher_;
-
   scoped_ptr<WebSocketDispatcher> websocket_dispatcher_;
 
   // The OnChannelError() callback was invoked - the channel is dead, don't
diff --git a/content/child/geofencing/geofencing_dispatcher.cc b/content/child/geofencing/geofencing_dispatcher.cc
index 1b0f849..eec721f 100644
--- a/content/child/geofencing/geofencing_dispatcher.cc
+++ b/content/child/geofencing/geofencing_dispatcher.cc
@@ -8,9 +8,11 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/thread_task_runner_handle.h"
+#include "content/child/service_worker/web_service_worker_registration_impl.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/child/worker_thread_task_runner.h"
 #include "content/common/geofencing_messages.h"
+#include "content/common/service_worker/service_worker_types.h"
 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"
 #include "third_party/WebKit/public/platform/WebGeofencingError.h"
 #include "third_party/WebKit/public/platform/WebGeofencingRegistration.h"
@@ -63,28 +65,60 @@
 void GeofencingDispatcher::RegisterRegion(
     const blink::WebString& region_id,
     const blink::WebCircularGeofencingRegion& region,
+    blink::WebServiceWorkerRegistration* service_worker_registration,
     blink::WebGeofencingCallbacks* callbacks) {
   DCHECK(callbacks);
   int request_id = region_registration_requests_.Add(callbacks);
-  Send(new GeofencingHostMsg_RegisterRegion(
-      CurrentWorkerId(), request_id, region_id.utf8(), region));
+  // TODO(mek): Immediately reject requests lacking a service worker
+  // registration, without bouncing through browser process.
+  int64 serviceworker_registration_id = kInvalidServiceWorkerRegistrationId;
+  if (service_worker_registration) {
+    serviceworker_registration_id =
+        static_cast<WebServiceWorkerRegistrationImpl*>(
+            service_worker_registration)->registration_id();
+  }
+  Send(new GeofencingHostMsg_RegisterRegion(CurrentWorkerId(),
+                                            request_id,
+                                            region_id.utf8(),
+                                            region,
+                                            serviceworker_registration_id));
 }
 
 void GeofencingDispatcher::UnregisterRegion(
     const blink::WebString& region_id,
+    blink::WebServiceWorkerRegistration* service_worker_registration,
     blink::WebGeofencingCallbacks* callbacks) {
   DCHECK(callbacks);
   int request_id = region_unregistration_requests_.Add(callbacks);
-  Send(new GeofencingHostMsg_UnregisterRegion(
-      CurrentWorkerId(), request_id, region_id.utf8()));
+  // TODO(mek): Immediately reject requests lacking a service worker
+  // registration, without bouncing through browser process.
+  int64 serviceworker_registration_id = kInvalidServiceWorkerRegistrationId;
+  if (service_worker_registration) {
+    serviceworker_registration_id =
+        static_cast<WebServiceWorkerRegistrationImpl*>(
+            service_worker_registration)->registration_id();
+  }
+  Send(new GeofencingHostMsg_UnregisterRegion(CurrentWorkerId(),
+                                              request_id,
+                                              region_id.utf8(),
+                                              serviceworker_registration_id));
 }
 
 void GeofencingDispatcher::GetRegisteredRegions(
+    blink::WebServiceWorkerRegistration* service_worker_registration,
     blink::WebGeofencingRegionsCallbacks* callbacks) {
   DCHECK(callbacks);
   int request_id = get_registered_regions_requests_.Add(callbacks);
-  Send(new GeofencingHostMsg_GetRegisteredRegions(CurrentWorkerId(),
-                                                  request_id));
+  // TODO(mek): Immediately reject requests lacking a service worker
+  // registration, without bouncing through browser process.
+  int64 serviceworker_registration_id = kInvalidServiceWorkerRegistrationId;
+  if (service_worker_registration) {
+    serviceworker_registration_id =
+        static_cast<WebServiceWorkerRegistrationImpl*>(
+            service_worker_registration)->registration_id();
+  }
+  Send(new GeofencingHostMsg_GetRegisteredRegions(
+      CurrentWorkerId(), request_id, serviceworker_registration_id));
 }
 
 GeofencingDispatcher* GeofencingDispatcher::GetOrCreateThreadSpecificInstance(
diff --git a/content/child/geofencing/geofencing_dispatcher.h b/content/child/geofencing/geofencing_dispatcher.h
index fc3988ef..57a2a43 100644
--- a/content/child/geofencing/geofencing_dispatcher.h
+++ b/content/child/geofencing/geofencing_dispatcher.h
@@ -33,12 +33,18 @@
   void OnMessageReceived(const IPC::Message& msg);
 
   // Corresponding to WebGeofencingProvider methods.
-  void RegisterRegion(const blink::WebString& region_id,
-                      const blink::WebCircularGeofencingRegion& region,
-                      blink::WebGeofencingCallbacks* callbacks);
-  void UnregisterRegion(const blink::WebString& region_id,
-                        blink::WebGeofencingCallbacks* callbacks);
-  void GetRegisteredRegions(blink::WebGeofencingRegionsCallbacks* callbacks);
+  void RegisterRegion(
+      const blink::WebString& region_id,
+      const blink::WebCircularGeofencingRegion& region,
+      blink::WebServiceWorkerRegistration* service_worker_registration,
+      blink::WebGeofencingCallbacks* callbacks);
+  void UnregisterRegion(
+      const blink::WebString& region_id,
+      blink::WebServiceWorkerRegistration* service_worker_registration,
+      blink::WebGeofencingCallbacks* callbacks);
+  void GetRegisteredRegions(
+      blink::WebServiceWorkerRegistration* service_worker_registration,
+      blink::WebGeofencingRegionsCallbacks* callbacks);
 
   // |thread_safe_sender| needs to be passed in because if the call leads to
   // construction it will be needed.
diff --git a/content/child/geofencing/web_geofencing_provider_impl.cc b/content/child/geofencing/web_geofencing_provider_impl.cc
index d058ffe..5d78b98 100644
--- a/content/child/geofencing/web_geofencing_provider_impl.cc
+++ b/content/child/geofencing/web_geofencing_provider_impl.cc
@@ -20,19 +20,24 @@
 void WebGeofencingProviderImpl::registerRegion(
     const blink::WebString& regionId,
     const blink::WebCircularGeofencingRegion& region,
+    blink::WebServiceWorkerRegistration* service_worker_registration,
     blink::WebGeofencingCallbacks* callbacks) {
-  GetDispatcher()->RegisterRegion(regionId, region, callbacks);
+  GetDispatcher()->RegisterRegion(
+      regionId, region, service_worker_registration, callbacks);
 }
 
 void WebGeofencingProviderImpl::unregisterRegion(
     const blink::WebString& regionId,
+    blink::WebServiceWorkerRegistration* service_worker_registration,
     blink::WebGeofencingCallbacks* callbacks) {
-  GetDispatcher()->UnregisterRegion(regionId, callbacks);
+  GetDispatcher()->UnregisterRegion(
+      regionId, service_worker_registration, callbacks);
 }
 
 void WebGeofencingProviderImpl::getRegisteredRegions(
+    blink::WebServiceWorkerRegistration* service_worker_registration,
     blink::WebGeofencingRegionsCallbacks* callbacks) {
-  GetDispatcher()->GetRegisteredRegions(callbacks);
+  GetDispatcher()->GetRegisteredRegions(service_worker_registration, callbacks);
 }
 
 GeofencingDispatcher* WebGeofencingProviderImpl::GetDispatcher() {
diff --git a/content/child/geofencing/web_geofencing_provider_impl.h b/content/child/geofencing/web_geofencing_provider_impl.h
index a1dd744..9aac795 100644
--- a/content/child/geofencing/web_geofencing_provider_impl.h
+++ b/content/child/geofencing/web_geofencing_provider_impl.h
@@ -21,12 +21,17 @@
 
  private:
   // WebGeofencingProvider implementation.
-  virtual void registerRegion(const blink::WebString& regionId,
-                              const blink::WebCircularGeofencingRegion& region,
-                              blink::WebGeofencingCallbacks* callbacks);
-  virtual void unregisterRegion(const blink::WebString& regionId,
-                                blink::WebGeofencingCallbacks* callbacks);
+  virtual void registerRegion(
+      const blink::WebString& regionId,
+      const blink::WebCircularGeofencingRegion& region,
+      blink::WebServiceWorkerRegistration* service_worker_registration,
+      blink::WebGeofencingCallbacks* callbacks);
+  virtual void unregisterRegion(
+      const blink::WebString& regionId,
+      blink::WebServiceWorkerRegistration* service_worker_registration,
+      blink::WebGeofencingCallbacks* callbacks);
   virtual void getRegisteredRegions(
+      blink::WebServiceWorkerRegistration* service_worker_registration,
       blink::WebGeofencingRegionsCallbacks* callbacks);
 
   GeofencingDispatcher* GetDispatcher();
diff --git a/content/child/service_worker/service_worker_registration_handle_reference.h b/content/child/service_worker/service_worker_registration_handle_reference.h
index 605094d..c7138e62 100644
--- a/content/child/service_worker/service_worker_registration_handle_reference.h
+++ b/content/child/service_worker/service_worker_registration_handle_reference.h
@@ -33,6 +33,7 @@
   const ServiceWorkerRegistrationObjectInfo& info() const { return info_; }
   int handle_id() const { return info_.handle_id; }
   GURL scope() const { return info_.scope; }
+  int64 registration_id() const { return info_.registration_id; }
 
  private:
   ServiceWorkerRegistrationHandleReference(
diff --git a/content/child/service_worker/web_service_worker_registration_impl.cc b/content/child/service_worker/web_service_worker_registration_impl.cc
index 833d22b..12db531 100644
--- a/content/child/service_worker/web_service_worker_registration_impl.cc
+++ b/content/child/service_worker/web_service_worker_registration_impl.cc
@@ -112,4 +112,8 @@
   return handle_ref_->scope();
 }
 
+int64 WebServiceWorkerRegistrationImpl::registration_id() const {
+  return handle_ref_->registration_id();
+}
+
 }  // namespace content
diff --git a/content/child/service_worker/web_service_worker_registration_impl.h b/content/child/service_worker/web_service_worker_registration_impl.h
index e143a5c..52ee1029 100644
--- a/content/child/service_worker/web_service_worker_registration_impl.h
+++ b/content/child/service_worker/web_service_worker_registration_impl.h
@@ -39,6 +39,8 @@
   virtual blink::WebServiceWorkerRegistrationProxy* proxy();
   virtual blink::WebURL scope() const;
 
+  int64 registration_id() const;
+
  private:
   enum QueuedTaskType {
     INSTALLING,
diff --git a/content/child/socket_stream_dispatcher.cc b/content/child/socket_stream_dispatcher.cc
deleted file mode 100644
index 789a31a1..0000000
--- a/content/child/socket_stream_dispatcher.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright (c) 2012 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/child/socket_stream_dispatcher.h"
-
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/id_map.h"
-#include "base/lazy_instance.h"
-#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/child/child_thread.h"
-#include "content/child/web_socket_stream_handle_bridge.h"
-#include "content/child/web_socket_stream_handle_delegate.h"
-#include "content/child/web_socket_stream_handle_impl.h"
-#include "content/common/socket_stream.h"
-#include "content/common/socket_stream_handle_data.h"
-#include "content/common/socket_stream_messages.h"
-#include "net/base/net_errors.h"
-#include "url/gurl.h"
-
-namespace content {
-
-// IPCWebSocketStreamHandleBridge is owned by each SocketStreamHandle.
-// It communicates with the main browser process via SocketStreamDispatcher.
-class IPCWebSocketStreamHandleBridge : public WebSocketStreamHandleBridge {
- public:
-  IPCWebSocketStreamHandleBridge(blink::WebSocketStreamHandle* handle,
-                                 WebSocketStreamHandleDelegate* delegate)
-      : socket_id_(kNoSocketId), handle_(handle), delegate_(delegate) {}
-
-  // Returns the handle having given id or NULL if there is no such handle.
-  static IPCWebSocketStreamHandleBridge* FromSocketId(int id);
-
-  // WebSocketStreamHandleBridge methods.
-  void Connect(const GURL& url) override;
-  bool Send(const std::vector<char>& data) override;
-  void Close() override;
-
-  // Called by SocketStreamDispatcher.
-  void OnConnected(int max_amount_send_allowed);
-  void OnSentData(int amount_sent);
-  void OnReceivedData(const std::vector<char>& data);
-  void OnClosed();
-  void OnFailed(int error_code, const std::string& error_msg);
-
- private:
-  ~IPCWebSocketStreamHandleBridge() override;
-
-  // The ID for this bridge and corresponding SocketStream instance in the
-  // browser process.
-  int socket_id_;
-
-  blink::WebSocketStreamHandle* handle_;
-  WebSocketStreamHandleDelegate* delegate_;
-
-  // Map from ID to bridge instance.
-  static base::LazyInstance<IDMap<IPCWebSocketStreamHandleBridge> >::Leaky
-      all_bridges;
-};
-
-// static
-base::LazyInstance<IDMap<IPCWebSocketStreamHandleBridge> >::Leaky
-    IPCWebSocketStreamHandleBridge::all_bridges = LAZY_INSTANCE_INITIALIZER;
-
-/* static */
-IPCWebSocketStreamHandleBridge* IPCWebSocketStreamHandleBridge::FromSocketId(
-    int id) {
-  return all_bridges.Get().Lookup(id);
-}
-
-IPCWebSocketStreamHandleBridge::~IPCWebSocketStreamHandleBridge() {
-  DVLOG(1) << "Bridge (" << this << ", socket_id_=" << socket_id_
-           << ") Destructor";
-
-  if (socket_id_ == kNoSocketId)
-    return;
-
-  ChildThread::current()->Send(new SocketStreamHostMsg_Close(socket_id_));
-  socket_id_ = kNoSocketId;
-}
-
-void IPCWebSocketStreamHandleBridge::Connect(const GURL& url) {
-  DVLOG(1) << "Bridge (" << this << ") Connect (url=" << url << ")";
-
-  DCHECK_EQ(socket_id_, kNoSocketId);
-  if (delegate_)
-    delegate_->WillOpenStream(handle_, url);
-
-  socket_id_ = all_bridges.Get().Add(this);
-  DCHECK_NE(socket_id_, kNoSocketId);
-  int render_frame_id = MSG_ROUTING_NONE;
-  WebSocketStreamHandleImpl* impl =
-      static_cast<WebSocketStreamHandleImpl*>(handle_);
-  const SocketStreamHandleData* data =
-      static_cast<SocketStreamHandleData*>(impl->GetUserData(handle_));
-  if (data)
-    render_frame_id = data->render_frame_id();
-  AddRef();  // Released in OnClosed().
-  ChildThread::current()->Send(
-      new SocketStreamHostMsg_Connect(render_frame_id, url, socket_id_));
-  DVLOG(1) << "Bridge #" << socket_id_ << " sent IPC Connect";
-  // TODO(ukai): timeout to OnConnected.
-}
-
-bool IPCWebSocketStreamHandleBridge::Send(const std::vector<char>& data) {
-  DVLOG(1) << "Bridge #" << socket_id_ << " Send (" << data.size()
-           << " bytes)";
-
-  ChildThread::current()->Send(
-      new SocketStreamHostMsg_SendData(socket_id_, data));
-  if (delegate_)
-    delegate_->WillSendData(handle_, &data[0], data.size());
-  return true;
-}
-
-void IPCWebSocketStreamHandleBridge::Close() {
-  DVLOG(1) << "Bridge #" << socket_id_ << " Close";
-
-  ChildThread::current()->Send(new SocketStreamHostMsg_Close(socket_id_));
-}
-
-void IPCWebSocketStreamHandleBridge::OnConnected(int max_pending_send_allowed) {
-  DVLOG(1) << "Bridge #" << socket_id_
-           << " OnConnected (max_pending_send_allowed="
-           << max_pending_send_allowed << ")";
-
-  if (delegate_)
-    delegate_->DidOpenStream(handle_, max_pending_send_allowed);
-}
-
-void IPCWebSocketStreamHandleBridge::OnSentData(int amount_sent) {
-  DVLOG(1) << "Bridge #" << socket_id_ << " OnSentData (" << amount_sent
-           << " bytes)";
-
-  if (delegate_)
-    delegate_->DidSendData(handle_, amount_sent);
-}
-
-void IPCWebSocketStreamHandleBridge::OnReceivedData(
-    const std::vector<char>& data) {
-  DVLOG(1) << "Bridge #" << socket_id_ << " OnReceiveData (" << data.size()
-           << " bytes)";
-  if (delegate_)
-    delegate_->DidReceiveData(handle_, &data[0], data.size());
-}
-
-void IPCWebSocketStreamHandleBridge::OnClosed() {
-  DVLOG(1) << "Bridge #" << socket_id_ << " OnClosed";
-
-  if (socket_id_ != kNoSocketId) {
-    all_bridges.Get().Remove(socket_id_);
-    socket_id_ = kNoSocketId;
-  }
-  if (delegate_)
-    delegate_->DidClose(handle_);
-  delegate_ = NULL;
-  Release();
-}
-
-void IPCWebSocketStreamHandleBridge::OnFailed(int error_code,
-                                              const std::string& error_msg) {
-  DVLOG(1) << "Bridge #" << socket_id_ << " OnFailed (error_code=" << error_code
-           << ")";
-  if (delegate_)
-    delegate_->DidFail(handle_, error_code, base::ASCIIToUTF16(error_msg));
-}
-
-SocketStreamDispatcher::SocketStreamDispatcher() {
-}
-
-// static
-WebSocketStreamHandleBridge* SocketStreamDispatcher::CreateBridge(
-    blink::WebSocketStreamHandle* handle,
-    WebSocketStreamHandleDelegate* delegate) {
-  return new IPCWebSocketStreamHandleBridge(handle, delegate);
-}
-
-bool SocketStreamDispatcher::OnMessageReceived(const IPC::Message& msg) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(SocketStreamDispatcher, msg)
-    IPC_MESSAGE_HANDLER(SocketStreamMsg_Connected, OnConnected)
-    IPC_MESSAGE_HANDLER(SocketStreamMsg_SentData, OnSentData)
-    IPC_MESSAGE_HANDLER(SocketStreamMsg_ReceivedData, OnReceivedData)
-    IPC_MESSAGE_HANDLER(SocketStreamMsg_Closed, OnClosed)
-    IPC_MESSAGE_HANDLER(SocketStreamMsg_Failed, OnFailed)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void SocketStreamDispatcher::OnConnected(int socket_id,
-                                         int max_pending_send_allowed) {
-  DVLOG(1) << "SocketStreamDispatcher::OnConnected (max_pending_send_allowed="
-           << max_pending_send_allowed << ") to socket_id=" << socket_id;
-
-  IPCWebSocketStreamHandleBridge* bridge =
-      IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
-  if (bridge)
-    bridge->OnConnected(max_pending_send_allowed);
-  else
-    DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
-}
-
-void SocketStreamDispatcher::OnSentData(int socket_id, int amount_sent) {
-  DVLOG(1) << "SocketStreamDispatcher::OnSentData (" << amount_sent
-           << " bytes) to socket_id=" << socket_id;
-
-  IPCWebSocketStreamHandleBridge* bridge =
-      IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
-  if (bridge)
-    bridge->OnSentData(amount_sent);
-  else
-    DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
-}
-
-void SocketStreamDispatcher::OnReceivedData(
-    int socket_id, const std::vector<char>& data) {
-  DVLOG(1) << "SocketStreamDispatcher::OnReceivedData (" << data.size()
-           << " bytes) to socket_id=" << socket_id;
-
-  IPCWebSocketStreamHandleBridge* bridge =
-      IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
-  if (bridge)
-    bridge->OnReceivedData(data);
-  else
-    DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
-}
-
-void SocketStreamDispatcher::OnClosed(int socket_id) {
-  DVLOG(1) << "SocketStreamDispatcher::OnClosed to socket_id=" << socket_id;
-
-  IPCWebSocketStreamHandleBridge* bridge =
-      IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
-  if (bridge)
-    bridge->OnClosed();
-  else
-    DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
-}
-
-void SocketStreamDispatcher::OnFailed(int socket_id, int error_code) {
-  IPCWebSocketStreamHandleBridge* bridge =
-      IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
-  if (bridge)
-    bridge->OnFailed(error_code, net::ErrorToString(error_code));
-  else
-    DLOG(ERROR) << "No bridge for socket_id=" << socket_id;
-}
-
-}  // namespace content
diff --git a/content/child/socket_stream_dispatcher.h b/content/child/socket_stream_dispatcher.h
deleted file mode 100644
index 25877f8..0000000
--- a/content/child/socket_stream_dispatcher.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012 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_CHILD_SOCKET_STREAM_DISPATCHER_H_
-#define CONTENT_CHILD_SOCKET_STREAM_DISPATCHER_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "ipc/ipc_listener.h"
-
-namespace blink {
-class WebSocketStreamHandle;
-}
-
-namespace content {
-
-class WebSocketStreamHandleBridge;
-class WebSocketStreamHandleDelegate;
-
-// Dispatches socket stream related messages sent to a child process from the
-// main browser process.  There is one instance per child process.  Messages
-// are dispatched on the main child thread.  The RenderThread class
-// creates an instance of SocketStreamDispatcher and delegates calls to it.
-class SocketStreamDispatcher : public IPC::Listener {
- public:
-  SocketStreamDispatcher();
-  ~SocketStreamDispatcher() override {}
-
-  static WebSocketStreamHandleBridge* CreateBridge(
-      blink::WebSocketStreamHandle* handle,
-      WebSocketStreamHandleDelegate* delegate);
-
-  // IPC::Listener implementation.
-  bool OnMessageReceived(const IPC::Message& msg) override;
-
- private:
-  void OnConnected(int socket_id, int max_amount_send_allowed);
-  void OnSentData(int socket_id, int amount_sent);
-  void OnReceivedData(int socket_id, const std::vector<char>& data);
-  void OnClosed(int socket_id);
-  void OnFailed(int socket_id, int error_code);
-
-  DISALLOW_COPY_AND_ASSIGN(SocketStreamDispatcher);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_SOCKET_STREAM_DISPATCHER_H_
diff --git a/content/child/web_socket_stream_handle_bridge.h b/content/child/web_socket_stream_handle_bridge.h
deleted file mode 100644
index 2655c102..0000000
--- a/content/child/web_socket_stream_handle_bridge.h
+++ /dev/null
@@ -1,37 +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 CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_BRIDGE_H_
-#define CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_BRIDGE_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-
-class GURL;
-
-namespace content {
-
-class WebSocketStreamHandleBridge
-    : public base::RefCountedThreadSafe<WebSocketStreamHandleBridge> {
- public:
-  virtual void Connect(const GURL& url) = 0;
-
-  virtual bool Send(const std::vector<char>& data) = 0;
-
-  virtual void Close() = 0;
-
- protected:
-  friend class base::RefCountedThreadSafe<WebSocketStreamHandleBridge>;
-  WebSocketStreamHandleBridge() {}
-  virtual ~WebSocketStreamHandleBridge() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleBridge);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_BRIDGE_H_
diff --git a/content/child/web_socket_stream_handle_delegate.h b/content/child/web_socket_stream_handle_delegate.h
deleted file mode 100644
index f7243637..0000000
--- a/content/child/web_socket_stream_handle_delegate.h
+++ /dev/null
@@ -1,44 +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 CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_DELEGATE_H_
-#define CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_DELEGATE_H_
-
-#include "base/strings/string16.h"
-
-class GURL;
-
-namespace blink {
-class WebSocketStreamHandle;
-}
-
-namespace content {
-
-class WebSocketStreamHandleDelegate {
- public:
-  WebSocketStreamHandleDelegate() {}
-
-  virtual void WillOpenStream(blink::WebSocketStreamHandle* handle,
-                              const GURL& url) {}
-  virtual void WillSendData(blink::WebSocketStreamHandle* handle,
-                            const char* data, int len) {}
-
-  virtual void DidOpenStream(blink::WebSocketStreamHandle* handle,
-                             int max_amount_send_allowed) {}
-  virtual void DidSendData(blink::WebSocketStreamHandle* handle,
-                           int amount_sent) {}
-  virtual void DidReceiveData(blink::WebSocketStreamHandle* handle,
-                              const char* data, int len) {}
-  virtual void DidClose(blink::WebSocketStreamHandle*) {}
-  virtual void DidFail(blink::WebSocketStreamHandle* handle,
-                       int error_code,
-                       const base::string16& error_msg) {}
-
- protected:
-  virtual ~WebSocketStreamHandleDelegate() {}
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_DELEGATE_H_
diff --git a/content/child/web_socket_stream_handle_impl.cc b/content/child/web_socket_stream_handle_impl.cc
deleted file mode 100644
index de66aeb..0000000
--- a/content/child/web_socket_stream_handle_impl.cc
+++ /dev/null
@@ -1,194 +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.
-
-// An implementation of WebSocketStreamHandle.
-
-#include "content/child/web_socket_stream_handle_impl.h"
-
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string16.h"
-#include "content/child/child_thread.h"
-#include "content/child/socket_stream_dispatcher.h"
-#include "content/child/web_socket_stream_handle_bridge.h"
-#include "content/child/web_socket_stream_handle_delegate.h"
-#include "third_party/WebKit/public/platform/WebData.h"
-#include "third_party/WebKit/public/platform/WebSocketStreamError.h"
-#include "third_party/WebKit/public/platform/WebSocketStreamHandleClient.h"
-#include "third_party/WebKit/public/platform/WebURL.h"
-
-using blink::WebData;
-using blink::WebSocketStreamError;
-using blink::WebSocketStreamHandle;
-using blink::WebSocketStreamHandleClient;
-using blink::WebURL;
-
-namespace content {
-
-// WebSocketStreamHandleImpl::Context -----------------------------------------
-
-class WebSocketStreamHandleImpl::Context
-    : public base::RefCounted<Context>,
-      public WebSocketStreamHandleDelegate {
- public:
-  explicit Context(WebSocketStreamHandleImpl* handle);
-
-  WebSocketStreamHandleClient* client() const { return client_; }
-  void set_client(WebSocketStreamHandleClient* client) {
-    client_ = client;
-  }
-
-  void Connect(const WebURL& url);
-  bool Send(const WebData& data);
-  void Close();
-
-  // Must be called before |handle_| or |client_| is deleted.
-  // Once detached, it never calls |client_| back.
-  void Detach();
-
-  // WebSocketStreamHandleDelegate methods:
-  void DidOpenStream(WebSocketStreamHandle*, int) override;
-  void DidSendData(WebSocketStreamHandle*, int) override;
-  void DidReceiveData(WebSocketStreamHandle*, const char*, int) override;
-  void DidClose(WebSocketStreamHandle*) override;
-  void DidFail(WebSocketStreamHandle*, int, const base::string16&) override;
-
- private:
-  friend class base::RefCounted<Context>;
-  ~Context() override {
-    DCHECK(!handle_);
-    DCHECK(!client_);
-    DCHECK(!bridge_.get());
-  }
-
-  WebSocketStreamHandleImpl* handle_;
-  WebSocketStreamHandleClient* client_;
-  // |bridge_| is alive from Connect to DidClose, so Context must be alive
-  // in the time period.
-  scoped_refptr<WebSocketStreamHandleBridge> bridge_;
-
-  DISALLOW_COPY_AND_ASSIGN(Context);
-};
-
-WebSocketStreamHandleImpl::Context::Context(WebSocketStreamHandleImpl* handle)
-    : handle_(handle),
-      client_(NULL) {
-}
-
-void WebSocketStreamHandleImpl::Context::Connect(const WebURL& url) {
-  VLOG(1) << "Connect url=" << url;
-  DCHECK(!bridge_.get());
-
-  SocketStreamDispatcher* dispatcher =
-      ChildThread::current()->socket_stream_dispatcher();
-  bridge_ = dispatcher->CreateBridge(handle_, this);
-
-  AddRef();  // Will be released by DidClose().
-  bridge_->Connect(url);
-}
-
-bool WebSocketStreamHandleImpl::Context::Send(const WebData& data) {
-  VLOG(1) << "Send data.size=" << data.size();
-  DCHECK(bridge_.get());
-  return bridge_->Send(
-      std::vector<char>(data.data(), data.data() + data.size()));
-}
-
-void WebSocketStreamHandleImpl::Context::Close() {
-  VLOG(1) << "Close";
-  if (bridge_.get())
-    bridge_->Close();
-}
-
-void WebSocketStreamHandleImpl::Context::Detach() {
-  handle_ = NULL;
-  client_ = NULL;
-  // If Connect was called, |bridge_| is not NULL, so that this Context closes
-  // the |bridge_| here.  Then |bridge_| will call back DidClose, and will
-  // be released by itself.
-  // Otherwise, |bridge_| is NULL.
-  if (bridge_.get())
-    bridge_->Close();
-}
-
-void WebSocketStreamHandleImpl::Context::DidOpenStream(
-    WebSocketStreamHandle* web_handle, int max_amount_send_allowed) {
-  VLOG(1) << "DidOpen";
-  if (client_)
-    client_->didOpenStream(handle_, max_amount_send_allowed);
-}
-
-void WebSocketStreamHandleImpl::Context::DidSendData(
-    WebSocketStreamHandle* web_handle, int amount_sent) {
-  if (client_)
-    client_->didSendData(handle_, amount_sent);
-}
-
-void WebSocketStreamHandleImpl::Context::DidReceiveData(
-    WebSocketStreamHandle* web_handle, const char* data, int size) {
-  if (client_)
-    client_->didReceiveData(handle_, WebData(data, size));
-}
-
-void WebSocketStreamHandleImpl::Context::DidClose(
-    WebSocketStreamHandle* web_handle) {
-  VLOG(1) << "DidClose";
-  bridge_ = NULL;
-  WebSocketStreamHandleImpl* handle = handle_;
-  handle_ = NULL;
-  if (client_) {
-    WebSocketStreamHandleClient* client = client_;
-    client_ = NULL;
-    client->didClose(handle);
-  }
-  Release();
-}
-
-void WebSocketStreamHandleImpl::Context::DidFail(
-    WebSocketStreamHandle* web_handle,
-    int error_code,
-    const base::string16& error_msg) {
-  VLOG(1) << "DidFail";
-  if (client_) {
-    client_->didFail(
-        handle_,
-        WebSocketStreamError(error_code, error_msg));
-  }
-}
-
-// WebSocketStreamHandleImpl ------------------------------------------------
-
-WebSocketStreamHandleImpl::WebSocketStreamHandleImpl()
-    : context_(new Context(this)) {
-}
-
-WebSocketStreamHandleImpl::~WebSocketStreamHandleImpl() {
-  // We won't receive any events from |context_|.
-  // |context_| is ref counted, and will be released when it received
-  // DidClose.
-  context_->Detach();
-}
-
-void WebSocketStreamHandleImpl::connect(
-    const WebURL& url, WebSocketStreamHandleClient* client) {
-  VLOG(1) << "connect url=" << url;
-  DCHECK(!context_->client());
-  context_->set_client(client);
-
-  context_->Connect(url);
-}
-
-bool WebSocketStreamHandleImpl::send(const WebData& data) {
-  return context_->Send(data);
-}
-
-void WebSocketStreamHandleImpl::close() {
-  context_->Close();
-}
-
-}  // namespace content
diff --git a/content/child/web_socket_stream_handle_impl.h b/content/child/web_socket_stream_handle_impl.h
deleted file mode 100644
index c8c2aca..0000000
--- a/content/child/web_socket_stream_handle_impl.h
+++ /dev/null
@@ -1,35 +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 CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_IMPL_H_
-#define CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_IMPL_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/supports_user_data.h"
-#include "third_party/WebKit/public/platform/WebSocketStreamHandle.h"
-
-namespace content {
-
-class WebSocketStreamHandleImpl : public base::SupportsUserData,
-                                  public blink::WebSocketStreamHandle {
- public:
-  WebSocketStreamHandleImpl();
-  virtual ~WebSocketStreamHandleImpl();
-
-  // WebSocketStreamHandle methods:
-  virtual void connect(const blink::WebURL& url,
-                       blink::WebSocketStreamHandleClient* client);
-  virtual bool send(const blink::WebData& data);
-  virtual void close();
-
- private:
-  class Context;
-  scoped_refptr<Context> context_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleImpl);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_WEB_SOCKET_STREAM_HANDLE_IMPL_H_
diff --git a/content/child/webblobregistry_impl.cc b/content/child/webblobregistry_impl.cc
index d22266d..9503ec5 100644
--- a/content/child/webblobregistry_impl.cc
+++ b/content/child/webblobregistry_impl.cc
@@ -163,11 +163,6 @@
 }
 
 void WebBlobRegistryImpl::addDataToStream(const WebURL& url,
-                                          WebThreadSafeData& data) {
-  addDataToStream(url, data.data(), data.size());
-}
-
-void WebBlobRegistryImpl::addDataToStream(const WebURL& url,
                                           const char* data, size_t length) {
   DCHECK(ChildThread::current());
   if (length == 0)
diff --git a/content/child/webblobregistry_impl.h b/content/child/webblobregistry_impl.h
index a6a9ac4..8fa967d 100644
--- a/content/child/webblobregistry_impl.h
+++ b/content/child/webblobregistry_impl.h
@@ -35,9 +35,6 @@
                                  const blink::WebString& content_type);
   virtual void registerStreamURL(const blink::WebURL& url,
                                  const blink::WebURL& src_url);
-  // TODO(tyoshino): Remove once removed in Blink side.
-  virtual void addDataToStream(const blink::WebURL& url,
-                               blink::WebThreadSafeData& data);
   virtual void addDataToStream(const blink::WebURL& url,
                                const char* data, size_t length);
   virtual void finalizeStream(const blink::WebURL& url);
diff --git a/content/child/webcrypto/algorithm_dispatch.cc b/content/child/webcrypto/algorithm_dispatch.cc
index a7b53bab..f8d7933c 100644
--- a/content/child/webcrypto/algorithm_dispatch.cc
+++ b/content/child/webcrypto/algorithm_dispatch.cc
@@ -104,14 +104,14 @@
 
 Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                    bool extractable,
-                   blink::WebCryptoKeyUsageMask usage_mask,
+                   blink::WebCryptoKeyUsageMask usages,
                    GenerateKeyResult* result) {
   const AlgorithmImplementation* impl = NULL;
   Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
   if (status.IsError())
     return status;
 
-  return impl->GenerateKey(algorithm, extractable, usage_mask, result);
+  return impl->GenerateKey(algorithm, extractable, usages, result);
 }
 
 // Note that this function may be called from the target Blink thread.
@@ -119,30 +119,27 @@
                  const CryptoData& key_data,
                  const blink::WebCryptoAlgorithm& algorithm,
                  bool extractable,
-                 blink::WebCryptoKeyUsageMask usage_mask,
+                 blink::WebCryptoKeyUsageMask usages,
                  blink::WebCryptoKey* key) {
   const AlgorithmImplementation* impl = NULL;
   Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
   if (status.IsError())
     return status;
 
-  status = impl->VerifyKeyUsagesBeforeImportKey(format, usage_mask);
+  status = impl->VerifyKeyUsagesBeforeImportKey(format, usages);
   if (status.IsError())
     return status;
 
   switch (format) {
     case blink::WebCryptoKeyFormatRaw:
-      return impl->ImportKeyRaw(
-          key_data, algorithm, extractable, usage_mask, key);
+      return impl->ImportKeyRaw(key_data, algorithm, extractable, usages, key);
     case blink::WebCryptoKeyFormatSpki:
-      return impl->ImportKeySpki(
-          key_data, algorithm, extractable, usage_mask, key);
+      return impl->ImportKeySpki(key_data, algorithm, extractable, usages, key);
     case blink::WebCryptoKeyFormatPkcs8:
       return impl->ImportKeyPkcs8(
-          key_data, algorithm, extractable, usage_mask, key);
+          key_data, algorithm, extractable, usages, key);
     case blink::WebCryptoKeyFormatJwk:
-      return impl->ImportKeyJwk(
-          key_data, algorithm, extractable, usage_mask, key);
+      return impl->ImportKeyJwk(key_data, algorithm, extractable, usages, key);
     default:
       return Status::ErrorUnsupported();
   }
@@ -213,7 +210,7 @@
                  const blink::WebCryptoAlgorithm& wrapping_algorithm,
                  const blink::WebCryptoAlgorithm& algorithm,
                  bool extractable,
-                 blink::WebCryptoKeyUsageMask usage_mask,
+                 blink::WebCryptoKeyUsageMask usages,
                  blink::WebCryptoKey* key) {
   if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey))
     return Status::ErrorUnexpected();
@@ -226,7 +223,7 @@
   if (status.IsError())
     return status;
 
-  status = import_impl->VerifyKeyUsagesBeforeImportKey(format, usage_mask);
+  status = import_impl->VerifyKeyUsagesBeforeImportKey(format, usages);
   if (status.IsError())
     return status;
 
@@ -242,7 +239,7 @@
   // key bytes however this should be OK. For more discussion see
   // http://crubg.com/372040
   return ImportKey(
-      format, CryptoData(buffer), algorithm, extractable, usage_mask, key);
+      format, CryptoData(buffer), algorithm, extractable, usages, key);
 }
 
 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
diff --git a/content/child/webcrypto/algorithm_dispatch.h b/content/child/webcrypto/algorithm_dispatch.h
index d13845b..3eefb46 100644
--- a/content/child/webcrypto/algorithm_dispatch.h
+++ b/content/child/webcrypto/algorithm_dispatch.h
@@ -45,14 +45,14 @@
 
 CONTENT_EXPORT Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                                   bool extractable,
-                                  blink::WebCryptoKeyUsageMask usage_mask,
+                                  blink::WebCryptoKeyUsageMask usages,
                                   GenerateKeyResult* result);
 
 CONTENT_EXPORT Status ImportKey(blink::WebCryptoKeyFormat format,
                                 const CryptoData& key_data,
                                 const blink::WebCryptoAlgorithm& algorithm,
                                 bool extractable,
-                                blink::WebCryptoKeyUsageMask usage_mask,
+                                blink::WebCryptoKeyUsageMask usages,
                                 blink::WebCryptoKey* key);
 
 CONTENT_EXPORT Status ExportKey(blink::WebCryptoKeyFormat format,
@@ -84,7 +84,7 @@
               const blink::WebCryptoAlgorithm& wrapping_algorithm,
               const blink::WebCryptoAlgorithm& algorithm,
               bool extractable,
-              blink::WebCryptoKeyUsageMask usage_mask,
+              blink::WebCryptoKeyUsageMask usages,
               blink::WebCryptoKey* key);
 
 CONTENT_EXPORT scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
diff --git a/content/child/webcrypto/algorithm_implementation.cc b/content/child/webcrypto/algorithm_implementation.cc
index e54f292..b815a52 100644
--- a/content/child/webcrypto/algorithm_implementation.cc
+++ b/content/child/webcrypto/algorithm_implementation.cc
@@ -55,14 +55,14 @@
 Status AlgorithmImplementation::GenerateKey(
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     GenerateKeyResult* result) const {
   return Status::ErrorUnsupported();
 }
 
 Status AlgorithmImplementation::VerifyKeyUsagesBeforeImportKey(
     blink::WebCryptoKeyFormat format,
-    blink::WebCryptoKeyUsageMask usage_mask) const {
+    blink::WebCryptoKeyUsageMask usages) const {
   return Status::ErrorUnsupportedImportKeyFormat();
 }
 
@@ -70,7 +70,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   return Status::ErrorUnsupportedImportKeyFormat();
 }
@@ -79,7 +79,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   return Status::ErrorUnsupportedImportKeyFormat();
 }
@@ -88,7 +88,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   return Status::ErrorUnsupportedImportKeyFormat();
 }
@@ -97,7 +97,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   return Status::ErrorUnsupportedImportKeyFormat();
 }
diff --git a/content/child/webcrypto/algorithm_implementation.h b/content/child/webcrypto/algorithm_implementation.h
index 1a240e2b3..e926ad0 100644
--- a/content/child/webcrypto/algorithm_implementation.h
+++ b/content/child/webcrypto/algorithm_implementation.h
@@ -74,11 +74,11 @@
 
   // This method corresponds to Web Crypto's crypto.subtle.generateKey().
   //
-  // Implementations MUST verify |usage_mask| and return an error if it is not
+  // Implementations MUST verify |usages| and return an error if it is not
   // appropriate.
   virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                              bool extractable,
-                             blink::WebCryptoKeyUsageMask usage_mask,
+                             blink::WebCryptoKeyUsageMask usages,
                              GenerateKeyResult* result) const;
 
   // -----------------------------------------------
@@ -99,14 +99,14 @@
   // ImportKeyJwk() must do the final usage check.
   virtual Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const;
+      blink::WebCryptoKeyUsageMask usages) const;
 
   // This method corresponds to Web Crypto's
   // crypto.subtle.importKey(format='raw').
   virtual Status ImportKeyRaw(const CryptoData& key_data,
                               const blink::WebCryptoAlgorithm& algorithm,
                               bool extractable,
-                              blink::WebCryptoKeyUsageMask usage_mask,
+                              blink::WebCryptoKeyUsageMask usages,
                               blink::WebCryptoKey* key) const;
 
   // This method corresponds to Web Crypto's
@@ -114,7 +114,7 @@
   virtual Status ImportKeyPkcs8(const CryptoData& key_data,
                                 const blink::WebCryptoAlgorithm& algorithm,
                                 bool extractable,
-                                blink::WebCryptoKeyUsageMask usage_mask,
+                                blink::WebCryptoKeyUsageMask usages,
                                 blink::WebCryptoKey* key) const;
 
   // This method corresponds to Web Crypto's
@@ -122,7 +122,7 @@
   virtual Status ImportKeySpki(const CryptoData& key_data,
                                const blink::WebCryptoAlgorithm& algorithm,
                                bool extractable,
-                               blink::WebCryptoKeyUsageMask usage_mask,
+                               blink::WebCryptoKeyUsageMask usages,
                                blink::WebCryptoKey* key) const;
 
   // This method corresponds to Web Crypto's
@@ -130,7 +130,7 @@
   virtual Status ImportKeyJwk(const CryptoData& key_data,
                               const blink::WebCryptoAlgorithm& algorithm,
                               bool extractable,
-                              blink::WebCryptoKeyUsageMask usage_mask,
+                              blink::WebCryptoKeyUsageMask usages,
                               blink::WebCryptoKey* key) const;
 
   // -----------------------------------------------
diff --git a/content/child/webcrypto/generate_key_result.cc b/content/child/webcrypto/generate_key_result.cc
index 1709e47b..3c61657 100644
--- a/content/child/webcrypto/generate_key_result.cc
+++ b/content/child/webcrypto/generate_key_result.cc
@@ -10,11 +10,7 @@
 
 namespace webcrypto {
 
-GenerateKeyResult::GenerateKeyResult()
-    : type_(TYPE_NULL),
-      secret_key_(blink::WebCryptoKey::createNull()),
-      public_key_(blink::WebCryptoKey::createNull()),
-      private_key_(blink::WebCryptoKey::createNull()) {
+GenerateKeyResult::GenerateKeyResult() : type_(TYPE_NULL) {
 }
 
 GenerateKeyResult::Type GenerateKeyResult::type() const {
diff --git a/content/child/webcrypto/jwk.cc b/content/child/webcrypto/jwk.cc
index e1ac96f..eb6b392 100644
--- a/content/child/webcrypto/jwk.cc
+++ b/content/child/webcrypto/jwk.cc
@@ -46,7 +46,7 @@
 // Web Crypto Key type            <-- (deduced)
 // Web Crypto Key extractable     <-- JWK ext + input extractable
 // Web Crypto Key algorithm       <-- JWK alg + input algorithm
-// Web Crypto Key keyUsage        <-- JWK use, key_ops + input usage_mask
+// Web Crypto Key keyUsage        <-- JWK use, key_ops + input usages
 // Web Crypto Key keying material <-- kty-specific parameters
 //
 // Values for each JWK entry are case-sensitive and defined in
@@ -183,7 +183,7 @@
 //   +-------+--------------------------------------------------------------+
 //
 // Consistency and conflict resolution
-// The 'algorithm', 'extractable', and 'usage_mask' input parameters
+// The 'algorithm', 'extractable', and 'usages' input parameters
 // may be different than the corresponding values inside the JWK. The Web
 // Crypto spec says that if a JWK value is present but is inconsistent with
 // the input value, it is an error and the operation must fail. If no
@@ -199,10 +199,10 @@
 //   false but the input parameter is true, it is an inconsistency. If both
 //   are true or both are false, use that value.
 //
-// usage_mask
-//   The input usage_mask must be a strict subset of the interpreted JWK use
-//   value, else it is judged inconsistent. In all cases the input usage_mask
-//   is used as the final usage_mask.
+// usages
+//   The input usages must be a strict subset of the interpreted JWK use
+//   value, else it is judged inconsistent. In all cases the input usages
+//   is used as the final usages.
 //
 
 namespace content {
@@ -224,10 +224,10 @@
  public:
   JwkWriter(const std::string& algorithm,
             bool extractable,
-            blink::WebCryptoKeyUsageMask usage_mask,
+            blink::WebCryptoKeyUsageMask usages,
             const std::string& kty) {
     dict_.SetString("alg", algorithm);
-    dict_.Set("key_ops", CreateJwkKeyOpsFromWebCryptoUsages(usage_mask));
+    dict_.Set("key_ops", CreateJwkKeyOpsFromWebCryptoUsages(usages));
     dict_.SetBoolean("ext", extractable);
     dict_.SetString("kty", kty);
   }
@@ -378,8 +378,8 @@
 }
 
 Status VerifyUsages(base::DictionaryValue* dict,
-                    blink::WebCryptoKeyUsageMask expected_usage_mask) {
-  // JWK "key_ops" (optional) --> usage_mask parameter
+                    blink::WebCryptoKeyUsageMask expected_usages) {
+  // JWK "key_ops" (optional) --> usages parameter
   base::ListValue* jwk_key_ops_value = NULL;
   bool has_jwk_key_ops;
   Status status =
@@ -392,12 +392,12 @@
         GetWebCryptoUsagesFromJwkKeyOps(jwk_key_ops_value, &jwk_key_ops_mask);
     if (status.IsError())
       return status;
-    // The input usage_mask must be a subset of jwk_key_ops_mask.
-    if (!ContainsKeyUsages(jwk_key_ops_mask, expected_usage_mask))
+    // The input usages must be a subset of jwk_key_ops_mask.
+    if (!ContainsKeyUsages(jwk_key_ops_mask, expected_usages))
       return Status::ErrorJwkKeyopsInconsistent();
   }
 
-  // JWK "use" (optional) --> usage_mask parameter
+  // JWK "use" (optional) --> usages parameter
   std::string jwk_use_value;
   bool has_jwk_use;
   status = GetOptionalJwkString(dict, "use", &jwk_use_value, &has_jwk_use);
@@ -411,8 +411,8 @@
       jwk_use_mask = kJwkSigUsage;
     else
       return Status::ErrorJwkUnrecognizedUse();
-    // The input usage_mask must be a subset of jwk_use_mask.
-    if (!ContainsKeyUsages(jwk_use_mask, expected_usage_mask))
+    // The input usages must be a subset of jwk_use_mask.
+    if (!ContainsKeyUsages(jwk_use_mask, expected_usages))
       return Status::ErrorJwkUseInconsistent();
   }
 
@@ -442,7 +442,7 @@
 
 Status ParseJwkCommon(const CryptoData& bytes,
                       bool expected_extractable,
-                      blink::WebCryptoKeyUsageMask expected_usage_mask,
+                      blink::WebCryptoKeyUsageMask expected_usages,
                       std::string* kty,
                       scoped_ptr<base::DictionaryValue>* dict) {
   // Parse the incoming JWK JSON.
@@ -469,25 +469,24 @@
   if (status.IsError())
     return status;
 
-  status = VerifyUsages(dict_value, expected_usage_mask);
+  status = VerifyUsages(dict_value, expected_usages);
   if (status.IsError())
     return status;
 
   return Status::Success();
 }
 
-Status ReadSecretKeyNoExpectedAlg(
-    const CryptoData& key_data,
-    bool expected_extractable,
-    blink::WebCryptoKeyUsageMask expected_usage_mask,
-    std::vector<uint8_t>* raw_key_data,
-    scoped_ptr<base::DictionaryValue>* dict) {
+Status ReadSecretKeyNoExpectedAlg(const CryptoData& key_data,
+                                  bool expected_extractable,
+                                  blink::WebCryptoKeyUsageMask expected_usages,
+                                  std::vector<uint8_t>* raw_key_data,
+                                  scoped_ptr<base::DictionaryValue>* dict) {
   if (!key_data.byte_length())
     return Status::ErrorImportEmptyKeyData();
 
   std::string kty;
   Status status = ParseJwkCommon(
-      key_data, expected_extractable, expected_usage_mask, &kty, dict);
+      key_data, expected_extractable, expected_usages, &kty, dict);
   if (status.IsError())
     return status;
 
@@ -508,9 +507,9 @@
 void WriteSecretKeyJwk(const CryptoData& raw_key_data,
                        const std::string& algorithm,
                        bool extractable,
-                       blink::WebCryptoKeyUsageMask usage_mask,
+                       blink::WebCryptoKeyUsageMask usages,
                        std::vector<uint8_t>* jwk_key_data) {
-  JwkWriter writer(algorithm, extractable, usage_mask, "oct");
+  JwkWriter writer(algorithm, extractable, usages, "oct");
   writer.SetBase64Encoded("k", raw_key_data);
   writer.ToBytes(jwk_key_data);
 }
@@ -518,11 +517,11 @@
 Status ReadSecretKeyJwk(const CryptoData& key_data,
                         const std::string& expected_algorithm,
                         bool expected_extractable,
-                        blink::WebCryptoKeyUsageMask expected_usage_mask,
+                        blink::WebCryptoKeyUsageMask expected_usages,
                         std::vector<uint8_t>* raw_key_data) {
   scoped_ptr<base::DictionaryValue> dict;
   Status status = ReadSecretKeyNoExpectedAlg(
-      key_data, expected_extractable, expected_usage_mask, raw_key_data, &dict);
+      key_data, expected_extractable, expected_usages, raw_key_data, &dict);
   if (status.IsError())
     return status;
   return VerifyAlg(dict.get(), expected_algorithm);
@@ -542,11 +541,11 @@
 Status ReadAesSecretKeyJwk(const CryptoData& key_data,
                            const std::string& algorithm_name_suffix,
                            bool expected_extractable,
-                           blink::WebCryptoKeyUsageMask expected_usage_mask,
+                           blink::WebCryptoKeyUsageMask expected_usages,
                            std::vector<uint8_t>* raw_key_data) {
   scoped_ptr<base::DictionaryValue> dict;
   Status status = ReadSecretKeyNoExpectedAlg(
-      key_data, expected_extractable, expected_usage_mask, raw_key_data, &dict);
+      key_data, expected_extractable, expected_usages, raw_key_data, &dict);
   if (status.IsError())
     return status;
 
@@ -579,9 +578,9 @@
                           const CryptoData& e,
                           const std::string& algorithm,
                           bool extractable,
-                          blink::WebCryptoKeyUsageMask usage_mask,
+                          blink::WebCryptoKeyUsageMask usages,
                           std::vector<uint8_t>* jwk_key_data) {
-  JwkWriter writer(algorithm, extractable, usage_mask, "RSA");
+  JwkWriter writer(algorithm, extractable, usages, "RSA");
   writer.SetBase64Encoded("n", n);
   writer.SetBase64Encoded("e", e);
   writer.ToBytes(jwk_key_data);
@@ -598,9 +597,9 @@
                            const CryptoData& qi,
                            const std::string& algorithm,
                            bool extractable,
-                           blink::WebCryptoKeyUsageMask usage_mask,
+                           blink::WebCryptoKeyUsageMask usages,
                            std::vector<uint8_t>* jwk_key_data) {
-  JwkWriter writer(algorithm, extractable, usage_mask, "RSA");
+  JwkWriter writer(algorithm, extractable, usages, "RSA");
 
   writer.SetBase64Encoded("n", n);
   writer.SetBase64Encoded("e", e);
@@ -624,7 +623,7 @@
 Status ReadRsaKeyJwk(const CryptoData& key_data,
                      const std::string& expected_algorithm,
                      bool expected_extractable,
-                     blink::WebCryptoKeyUsageMask expected_usage_mask,
+                     blink::WebCryptoKeyUsageMask expected_usages,
                      JwkRsaInfo* result) {
   if (!key_data.byte_length())
     return Status::ErrorImportEmptyKeyData();
@@ -632,7 +631,7 @@
   scoped_ptr<base::DictionaryValue> dict;
   std::string kty;
   Status status = ParseJwkCommon(
-      key_data, expected_extractable, expected_usage_mask, &kty, &dict);
+      key_data, expected_extractable, expected_usages, &kty, &dict);
   if (status.IsError())
     return status;
 
diff --git a/content/child/webcrypto/jwk.h b/content/child/webcrypto/jwk.h
index 9c7a7690..a587209 100644
--- a/content/child/webcrypto/jwk.h
+++ b/content/child/webcrypto/jwk.h
@@ -26,11 +26,11 @@
 //  * raw_key_data: The actual key data
 //  * algorithm: The JWK algorithm name (i.e. "alg")
 //  * extractable: The JWK extractability (i.e. "ext")
-//  * usage_mask: The JWK usages (i.e. "key_ops")
+//  * usages: The JWK usages (i.e. "key_ops")
 void WriteSecretKeyJwk(const CryptoData& raw_key_data,
                        const std::string& algorithm,
                        bool extractable,
-                       blink::WebCryptoKeyUsageMask usage_mask,
+                       blink::WebCryptoKeyUsageMask usages,
                        std::vector<uint8_t>* jwk_key_data);
 
 // Parses a UTF-8 encoded JWK (key_data), and extracts the key material to
@@ -39,11 +39,11 @@
 //   * expected_algorithm must match the JWK's "alg", if present.
 //   * expected_extractable must be consistent with the JWK's "ext", if
 //     present.
-//   * expected_usage_mask must be a subset of the JWK's "key_ops" if present.
+//   * expected_usages must be a subset of the JWK's "key_ops" if present.
 Status ReadSecretKeyJwk(const CryptoData& key_data,
                         const std::string& expected_algorithm,
                         bool expected_extractable,
-                        blink::WebCryptoKeyUsageMask expected_usage_mask,
+                        blink::WebCryptoKeyUsageMask expected_usages,
                         std::vector<uint8_t>* raw_key_data);
 
 // Creates an AES algorithm name for the given key size (in bytes). For
@@ -61,7 +61,7 @@
 Status ReadAesSecretKeyJwk(const CryptoData& key_data,
                            const std::string& algorithm_name_suffix,
                            bool expected_extractable,
-                           blink::WebCryptoKeyUsageMask expected_usage_mask,
+                           blink::WebCryptoKeyUsageMask expected_usages,
                            std::vector<uint8_t>* raw_key_data);
 
 // Writes a JWK-formated RSA public key and saves the result to
@@ -70,7 +70,7 @@
                           const CryptoData& e,
                           const std::string& algorithm,
                           bool extractable,
-                          blink::WebCryptoKeyUsageMask usage_mask,
+                          blink::WebCryptoKeyUsageMask usages,
                           std::vector<uint8_t>* jwk_key_data);
 
 // Writes a JWK-formated RSA private key and saves the result to
@@ -85,7 +85,7 @@
                            const CryptoData& qi,
                            const std::string& algorithm,
                            bool extractable,
-                           blink::WebCryptoKeyUsageMask usage_mask,
+                           blink::WebCryptoKeyUsageMask usages,
                            std::vector<uint8_t>* jwk_key_data);
 
 // Describes the RSA components for a parsed key. The names of the properties
@@ -113,11 +113,11 @@
 //   * expected_algorithm must match the JWK's "alg", if present.
 //   * expected_extractable must be consistent with the JWK's "ext", if
 //     present.
-//   * expected_usage_mask must be a subset of the JWK's "key_ops" if present.
+//   * expected_usages must be a subset of the JWK's "key_ops" if present.
 Status ReadRsaKeyJwk(const CryptoData& key_data,
                      const std::string& expected_algorithm,
                      bool expected_extractable,
-                     blink::WebCryptoKeyUsageMask expected_usage_mask,
+                     blink::WebCryptoKeyUsageMask expected_usages,
                      JwkRsaInfo* result);
 
 const char* GetJwkHmacAlgorithmName(blink::WebCryptoAlgorithmId hash);
diff --git a/content/child/webcrypto/nss/aes_gcm_nss.cc b/content/child/webcrypto/nss/aes_gcm_nss.cc
index 586e307..0ff3e4a 100644
--- a/content/child/webcrypto/nss/aes_gcm_nss.cc
+++ b/content/child/webcrypto/nss/aes_gcm_nss.cc
@@ -145,25 +145,24 @@
 
   virtual Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const override {
+      blink::WebCryptoKeyUsageMask usages) const override {
     // Prevent importing AES-GCM keys if it is unavailable.
     Status status = NssSupportsAesGcm();
     if (status.IsError())
       return status;
-    return AesAlgorithm::VerifyKeyUsagesBeforeImportKey(format, usage_mask);
+    return AesAlgorithm::VerifyKeyUsagesBeforeImportKey(format, usages);
   }
 
   virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                              bool extractable,
-                             blink::WebCryptoKeyUsageMask usage_mask,
+                             blink::WebCryptoKeyUsageMask usages,
                              GenerateKeyResult* result) const override {
     // Prevent generating AES-GCM keys if it is unavailable.
     Status status = NssSupportsAesGcm();
     if (status.IsError())
       return status;
 
-    return AesAlgorithm::GenerateKey(
-        algorithm, extractable, usage_mask, result);
+    return AesAlgorithm::GenerateKey(algorithm, extractable, usages, result);
   }
 
   virtual Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
diff --git a/content/child/webcrypto/nss/aes_key_nss.cc b/content/child/webcrypto/nss/aes_key_nss.cc
index dda4d6b..2bd0c57 100644
--- a/content/child/webcrypto/nss/aes_key_nss.cc
+++ b/content/child/webcrypto/nss/aes_key_nss.cc
@@ -40,9 +40,9 @@
 
 Status AesAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                                  bool extractable,
-                                 blink::WebCryptoKeyUsageMask usage_mask,
+                                 blink::WebCryptoKeyUsageMask usages,
                                  GenerateKeyResult* result) const {
-  Status status = CheckKeyCreationUsages(all_key_usages_, usage_mask);
+  Status status = CheckKeyCreationUsages(all_key_usages_, usages);
   if (status.IsError())
     return status;
 
@@ -54,7 +54,7 @@
   return GenerateSecretKeyNss(
       blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits),
       extractable,
-      usage_mask,
+      usages,
       keylen_bits / 8,
       CKM_AES_KEY_GEN,
       result);
@@ -62,11 +62,11 @@
 
 Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey(
     blink::WebCryptoKeyFormat format,
-    blink::WebCryptoKeyUsageMask usage_mask) const {
+    blink::WebCryptoKeyUsageMask usages) const {
   switch (format) {
     case blink::WebCryptoKeyFormatRaw:
     case blink::WebCryptoKeyFormatJwk:
-      return CheckKeyCreationUsages(all_key_usages_, usage_mask);
+      return CheckKeyCreationUsages(all_key_usages_, usages);
     default:
       return Status::ErrorUnsupportedImportKeyFormat();
   }
@@ -74,7 +74,7 @@
 Status AesAlgorithm::ImportKeyRaw(const CryptoData& key_data,
                                   const blink::WebCryptoAlgorithm& algorithm,
                                   bool extractable,
-                                  blink::WebCryptoKeyUsageMask usage_mask,
+                                  blink::WebCryptoKeyUsageMask usages,
                                   blink::WebCryptoKey* key) const {
   const unsigned int keylen_bytes = key_data.byte_length();
   Status status = VerifyAesKeyLengthForImport(keylen_bytes);
@@ -88,7 +88,7 @@
       key_data,
       blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits),
       extractable,
-      usage_mask,
+      usages,
       import_mechanism_,
       import_flags_,
       key);
@@ -97,16 +97,16 @@
 Status AesAlgorithm::ImportKeyJwk(const CryptoData& key_data,
                                   const blink::WebCryptoAlgorithm& algorithm,
                                   bool extractable,
-                                  blink::WebCryptoKeyUsageMask usage_mask,
+                                  blink::WebCryptoKeyUsageMask usages,
                                   blink::WebCryptoKey* key) const {
   std::vector<uint8_t> raw_data;
   Status status = ReadAesSecretKeyJwk(
-      key_data, jwk_suffix_, extractable, usage_mask, &raw_data);
+      key_data, jwk_suffix_, extractable, usages, &raw_data);
   if (status.IsError())
     return status;
 
   return ImportKeyRaw(
-      CryptoData(raw_data), algorithm, extractable, usage_mask, key);
+      CryptoData(raw_data), algorithm, extractable, usages, key);
 }
 
 Status AesAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/nss/aes_key_nss.h b/content/child/webcrypto/nss/aes_key_nss.h
index 6d80dd3..7f4c1b19 100644
--- a/content/child/webcrypto/nss/aes_key_nss.h
+++ b/content/child/webcrypto/nss/aes_key_nss.h
@@ -38,23 +38,23 @@
 
   virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                              bool extractable,
-                             blink::WebCryptoKeyUsageMask usage_mask,
+                             blink::WebCryptoKeyUsageMask usages,
                              GenerateKeyResult* result) const override;
 
   virtual Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const override;
+      blink::WebCryptoKeyUsageMask usages) const override;
 
   virtual Status ImportKeyRaw(const CryptoData& key_data,
                               const blink::WebCryptoAlgorithm& algorithm,
                               bool extractable,
-                              blink::WebCryptoKeyUsageMask usage_mask,
+                              blink::WebCryptoKeyUsageMask usages,
                               blink::WebCryptoKey* key) const override;
 
   virtual Status ImportKeyJwk(const CryptoData& key_data,
                               const blink::WebCryptoAlgorithm& algorithm,
                               bool extractable,
-                              blink::WebCryptoKeyUsageMask usage_mask,
+                              blink::WebCryptoKeyUsageMask usages,
                               blink::WebCryptoKey* key) const override;
 
   virtual Status ExportKeyRaw(const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/nss/hmac_nss.cc b/content/child/webcrypto/nss/hmac_nss.cc
index 74cdaef..82855f2 100644
--- a/content/child/webcrypto/nss/hmac_nss.cc
+++ b/content/child/webcrypto/nss/hmac_nss.cc
@@ -57,9 +57,9 @@
 
   virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                              bool extractable,
-                             blink::WebCryptoKeyUsageMask usage_mask,
+                             blink::WebCryptoKeyUsageMask usages,
                              GenerateKeyResult* result) const override {
-    Status status = CheckKeyCreationUsages(kAllKeyUsages, usage_mask);
+    Status status = CheckKeyCreationUsages(kAllKeyUsages, usages);
     if (status.IsError())
       return status;
 
@@ -79,7 +79,7 @@
     return GenerateSecretKeyNss(
         blink::WebCryptoKeyAlgorithm::createHmac(hash.id(), keylen_bits),
         extractable,
-        usage_mask,
+        usages,
         keylen_bits / 8,
         mechanism,
         result);
@@ -87,11 +87,11 @@
 
   virtual Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const override {
+      blink::WebCryptoKeyUsageMask usages) const override {
     switch (format) {
       case blink::WebCryptoKeyFormatRaw:
       case blink::WebCryptoKeyFormatJwk:
-        return CheckKeyCreationUsages(kAllKeyUsages, usage_mask);
+        return CheckKeyCreationUsages(kAllKeyUsages, usages);
       default:
         return Status::ErrorUnsupportedImportKeyFormat();
     }
@@ -100,7 +100,7 @@
   virtual Status ImportKeyRaw(const CryptoData& key_data,
                               const blink::WebCryptoAlgorithm& algorithm,
                               bool extractable,
-                              blink::WebCryptoKeyUsageMask usage_mask,
+                              blink::WebCryptoKeyUsageMask usages,
                               blink::WebCryptoKey* key) const override {
     const blink::WebCryptoAlgorithm& hash =
         algorithm.hmacImportParams()->hash();
@@ -119,7 +119,7 @@
                            blink::WebCryptoKeyAlgorithm::createHmac(
                                hash.id(), keylen_bits.ValueOrDie()),
                            extractable,
-                           usage_mask,
+                           usages,
                            mechanism,
                            CKF_SIGN | CKF_VERIFY,
                            key);
@@ -128,7 +128,7 @@
   virtual Status ImportKeyJwk(const CryptoData& key_data,
                               const blink::WebCryptoAlgorithm& algorithm,
                               bool extractable,
-                              blink::WebCryptoKeyUsageMask usage_mask,
+                              blink::WebCryptoKeyUsageMask usages,
                               blink::WebCryptoKey* key) const override {
     const char* algorithm_name =
         GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id());
@@ -137,12 +137,12 @@
 
     std::vector<uint8_t> raw_data;
     Status status = ReadSecretKeyJwk(
-        key_data, algorithm_name, extractable, usage_mask, &raw_data);
+        key_data, algorithm_name, extractable, usages, &raw_data);
     if (status.IsError())
       return status;
 
     return ImportKeyRaw(
-        CryptoData(raw_data), algorithm, extractable, usage_mask, key);
+        CryptoData(raw_data), algorithm, extractable, usages, key);
   }
 
   virtual Status ExportKeyRaw(const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/nss/rsa_key_nss.cc b/content/child/webcrypto/nss/rsa_key_nss.cc
index 1ad4cb30..370bdb2 100644
--- a/content/child/webcrypto/nss/rsa_key_nss.cc
+++ b/content/child/webcrypto/nss/rsa_key_nss.cc
@@ -307,7 +307,7 @@
 
 Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
                            bool extractable,
-                           blink::WebCryptoKeyUsageMask usage_mask,
+                           blink::WebCryptoKeyUsageMask usages,
                            const JwkRsaInfo& params,
                            blink::WebCryptoKey* key) {
   Status status = NssSupportsRsaPrivateKeyImport();
@@ -409,7 +409,7 @@
                                      blink::WebCryptoKeyTypePrivate,
                                      extractable,
                                      key_algorithm,
-                                     usage_mask);
+                                     usages);
   return Status::Success();
 }
 
@@ -425,7 +425,7 @@
 
 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
                           bool extractable,
-                          blink::WebCryptoKeyUsageMask usage_mask,
+                          blink::WebCryptoKeyUsageMask usages,
                           const CryptoData& modulus_data,
                           const CryptoData& exponent_data,
                           blink::WebCryptoKey* key) {
@@ -500,7 +500,7 @@
                                      blink::WebCryptoKeyTypePublic,
                                      extractable,
                                      key_algorithm,
-                                     usage_mask);
+                                     usages);
   return Status::Success();
 }
 
@@ -509,17 +509,17 @@
 Status RsaHashedAlgorithm::GenerateKey(
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask combined_usage_mask,
+    blink::WebCryptoKeyUsageMask combined_usages,
     GenerateKeyResult* result) const {
   Status status = CheckKeyCreationUsages(
-      all_public_key_usages_ | all_private_key_usages_, combined_usage_mask);
+      all_public_key_usages_ | all_private_key_usages_, combined_usages);
   if (status.IsError())
     return status;
 
-  const blink::WebCryptoKeyUsageMask public_usage_mask =
-      combined_usage_mask & all_public_key_usages_;
-  const blink::WebCryptoKeyUsageMask private_usage_mask =
-      combined_usage_mask & all_private_key_usages_;
+  const blink::WebCryptoKeyUsageMask public_usages =
+      combined_usages & all_public_key_usages_;
+  const blink::WebCryptoKeyUsageMask private_usages =
+      combined_usages & all_private_key_usages_;
 
   unsigned int public_exponent = 0;
   unsigned int modulus_length_bits = 0;
@@ -590,14 +590,14 @@
                                   blink::WebCryptoKeyTypePublic,
                                   true,
                                   key_algorithm,
-                                  public_usage_mask);
+                                  public_usages);
 
   blink::WebCryptoKey private_key =
       blink::WebCryptoKey::create(private_key_handle.release(),
                                   blink::WebCryptoKeyTypePrivate,
                                   extractable,
                                   key_algorithm,
-                                  private_usage_mask);
+                                  private_usages);
 
   result->AssignKeyPair(public_key, private_key);
   return Status::Success();
@@ -605,15 +605,15 @@
 
 Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(
     blink::WebCryptoKeyFormat format,
-    blink::WebCryptoKeyUsageMask usage_mask) const {
+    blink::WebCryptoKeyUsageMask usages) const {
   switch (format) {
     case blink::WebCryptoKeyFormatSpki:
-      return CheckKeyCreationUsages(all_public_key_usages_, usage_mask);
+      return CheckKeyCreationUsages(all_public_key_usages_, usages);
     case blink::WebCryptoKeyFormatPkcs8:
-      return CheckKeyCreationUsages(all_private_key_usages_, usage_mask);
+      return CheckKeyCreationUsages(all_private_key_usages_, usages);
     case blink::WebCryptoKeyFormatJwk:
       return CheckKeyCreationUsages(
-          all_public_key_usages_ | all_private_key_usages_, usage_mask);
+          all_public_key_usages_ | all_private_key_usages_, usages);
     default:
       return Status::ErrorUnsupportedImportKeyFormat();
   }
@@ -623,7 +623,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   Status status = NssSupportsRsaPrivateKeyImport();
   if (status.IsError())
@@ -678,7 +678,7 @@
                                      blink::WebCryptoKeyTypePrivate,
                                      extractable,
                                      key_algorithm,
-                                     usage_mask);
+                                     usages);
 
   return Status::Success();
 }
@@ -687,7 +687,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   if (!key_data.byte_length())
     return Status::ErrorImportEmptyKeyData();
@@ -731,7 +731,7 @@
                                      blink::WebCryptoKeyTypePublic,
                                      extractable,
                                      key_algorithm,
-                                     usage_mask);
+                                     usages);
 
   return Status::Success();
 }
@@ -756,7 +756,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   const char* jwk_algorithm =
       GetJwkAlgorithm(algorithm.rsaHashedImportParams()->hash().id());
@@ -766,22 +766,22 @@
 
   JwkRsaInfo jwk;
   Status status =
-      ReadRsaKeyJwk(key_data, jwk_algorithm, extractable, usage_mask, &jwk);
+      ReadRsaKeyJwk(key_data, jwk_algorithm, extractable, usages, &jwk);
   if (status.IsError())
     return status;
 
   // Once the key type is known, verify the usages.
   status = CheckKeyCreationUsages(
       jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_,
-      usage_mask);
+      usages);
   if (status.IsError())
     return Status::ErrorCreateKeyBadUsages();
 
   return jwk.is_private_key
-             ? ImportRsaPrivateKey(algorithm, extractable, usage_mask, jwk, key)
+             ? ImportRsaPrivateKey(algorithm, extractable, usages, jwk, key)
              : ImportRsaPublicKey(algorithm,
                                   extractable,
-                                  usage_mask,
+                                  usages,
                                   CryptoData(jwk.n),
                                   CryptoData(jwk.e),
                                   key);
diff --git a/content/child/webcrypto/nss/rsa_key_nss.h b/content/child/webcrypto/nss/rsa_key_nss.h
index 8004659..f11d919 100644
--- a/content/child/webcrypto/nss/rsa_key_nss.h
+++ b/content/child/webcrypto/nss/rsa_key_nss.h
@@ -45,23 +45,23 @@
 
   virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                              bool extractable,
-                             blink::WebCryptoKeyUsageMask usage_mask,
+                             blink::WebCryptoKeyUsageMask usages,
                              GenerateKeyResult* result) const override;
 
   virtual Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const override;
+      blink::WebCryptoKeyUsageMask usages) const override;
 
   virtual Status ImportKeyPkcs8(const CryptoData& key_data,
                                 const blink::WebCryptoAlgorithm& algorithm,
                                 bool extractable,
-                                blink::WebCryptoKeyUsageMask usage_mask,
+                                blink::WebCryptoKeyUsageMask usages,
                                 blink::WebCryptoKey* key) const override;
 
   virtual Status ImportKeySpki(const CryptoData& key_data,
                                const blink::WebCryptoAlgorithm& algorithm,
                                bool extractable,
-                               blink::WebCryptoKeyUsageMask usage_mask,
+                               blink::WebCryptoKeyUsageMask usages,
                                blink::WebCryptoKey* key) const override;
 
   virtual Status ExportKeyPkcs8(const blink::WebCryptoKey& key,
@@ -73,7 +73,7 @@
   virtual Status ImportKeyJwk(const CryptoData& key_data,
                               const blink::WebCryptoAlgorithm& algorithm,
                               bool extractable,
-                              blink::WebCryptoKeyUsageMask usage_mask,
+                              blink::WebCryptoKeyUsageMask usages,
                               blink::WebCryptoKey* key) const override;
 
   virtual Status ExportKeyJwk(const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/nss/rsa_oaep_nss.cc b/content/child/webcrypto/nss/rsa_oaep_nss.cc
index d129eac..55501b36f 100644
--- a/content/child/webcrypto/nss/rsa_oaep_nss.cc
+++ b/content/child/webcrypto/nss/rsa_oaep_nss.cc
@@ -170,23 +170,22 @@
 
   virtual Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                              bool extractable,
-                             blink::WebCryptoKeyUsageMask usage_mask,
+                             blink::WebCryptoKeyUsageMask usages,
                              GenerateKeyResult* result) const override {
     Status status = NssSupportsRsaOaep();
     if (status.IsError())
       return status;
     return RsaHashedAlgorithm::GenerateKey(
-        algorithm, extractable, usage_mask, result);
+        algorithm, extractable, usages, result);
   }
 
   virtual Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const override {
+      blink::WebCryptoKeyUsageMask usages) const override {
     Status status = NssSupportsRsaOaep();
     if (status.IsError())
       return status;
-    return RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(format,
-                                                              usage_mask);
+    return RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(format, usages);
   }
 
   virtual const char* GetJwkAlgorithm(
diff --git a/content/child/webcrypto/nss/sym_key_nss.cc b/content/child/webcrypto/nss/sym_key_nss.cc
index b779e92..5066d5d 100644
--- a/content/child/webcrypto/nss/sym_key_nss.cc
+++ b/content/child/webcrypto/nss/sym_key_nss.cc
@@ -20,7 +20,7 @@
 
 Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
                             bool extractable,
-                            blink::WebCryptoKeyUsageMask usage_mask,
+                            blink::WebCryptoKeyUsageMask usages,
                             unsigned keylen_bytes,
                             CK_MECHANISM_TYPE mechanism,
                             GenerateKeyResult* result) {
@@ -51,7 +51,7 @@
                                   blink::WebCryptoKeyTypeSecret,
                                   extractable,
                                   algorithm,
-                                  usage_mask));
+                                  usages));
 
   return Status::Success();
 }
@@ -59,7 +59,7 @@
 Status ImportKeyRawNss(const CryptoData& key_data,
                        const blink::WebCryptoKeyAlgorithm& algorithm,
                        bool extractable,
-                       blink::WebCryptoKeyUsageMask usage_mask,
+                       blink::WebCryptoKeyUsageMask usages,
                        CK_MECHANISM_TYPE mechanism,
                        CK_FLAGS flags,
                        blink::WebCryptoKey* key) {
@@ -85,7 +85,7 @@
                                      blink::WebCryptoKeyTypeSecret,
                                      extractable,
                                      algorithm,
-                                     usage_mask);
+                                     usages);
   return Status::Success();
 }
 
diff --git a/content/child/webcrypto/nss/sym_key_nss.h b/content/child/webcrypto/nss/sym_key_nss.h
index 5d05508f0..7f1e067 100644
--- a/content/child/webcrypto/nss/sym_key_nss.h
+++ b/content/child/webcrypto/nss/sym_key_nss.h
@@ -19,7 +19,7 @@
 
 Status GenerateSecretKeyNss(const blink::WebCryptoKeyAlgorithm& algorithm,
                             bool extractable,
-                            blink::WebCryptoKeyUsageMask usage_mask,
+                            blink::WebCryptoKeyUsageMask usages,
                             unsigned keylen_bytes,
                             CK_MECHANISM_TYPE mechanism,
                             GenerateKeyResult* result);
@@ -27,7 +27,7 @@
 Status ImportKeyRawNss(const CryptoData& key_data,
                        const blink::WebCryptoKeyAlgorithm& algorithm,
                        bool extractable,
-                       blink::WebCryptoKeyUsageMask usage_mask,
+                       blink::WebCryptoKeyUsageMask usages,
                        CK_MECHANISM_TYPE mechanism,
                        CK_FLAGS flags,
                        blink::WebCryptoKey* key);
diff --git a/content/child/webcrypto/openssl/aes_key_openssl.cc b/content/child/webcrypto/openssl/aes_key_openssl.cc
index 738b87b..14fa24e3 100644
--- a/content/child/webcrypto/openssl/aes_key_openssl.cc
+++ b/content/child/webcrypto/openssl/aes_key_openssl.cc
@@ -32,9 +32,9 @@
 
 Status AesAlgorithm::GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                                  bool extractable,
-                                 blink::WebCryptoKeyUsageMask usage_mask,
+                                 blink::WebCryptoKeyUsageMask usages,
                                  GenerateKeyResult* result) const {
-  Status status = CheckKeyCreationUsages(all_key_usages_, usage_mask);
+  Status status = CheckKeyCreationUsages(all_key_usages_, usages);
   if (status.IsError())
     return status;
 
@@ -46,18 +46,18 @@
   return GenerateSecretKeyOpenSsl(
       blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits),
       extractable,
-      usage_mask,
+      usages,
       keylen_bits / 8,
       result);
 }
 
 Status AesAlgorithm::VerifyKeyUsagesBeforeImportKey(
     blink::WebCryptoKeyFormat format,
-    blink::WebCryptoKeyUsageMask usage_mask) const {
+    blink::WebCryptoKeyUsageMask usages) const {
   switch (format) {
     case blink::WebCryptoKeyFormatRaw:
     case blink::WebCryptoKeyFormatJwk:
-      return CheckKeyCreationUsages(all_key_usages_, usage_mask);
+      return CheckKeyCreationUsages(all_key_usages_, usages);
     default:
       return Status::ErrorUnsupportedImportKeyFormat();
   }
@@ -66,7 +66,7 @@
 Status AesAlgorithm::ImportKeyRaw(const CryptoData& key_data,
                                   const blink::WebCryptoAlgorithm& algorithm,
                                   bool extractable,
-                                  blink::WebCryptoKeyUsageMask usage_mask,
+                                  blink::WebCryptoKeyUsageMask usages,
                                   blink::WebCryptoKey* key) const {
   const unsigned int keylen_bytes = key_data.byte_length();
   Status status = VerifyAesKeyLengthForImport(keylen_bytes);
@@ -80,23 +80,23 @@
       key_data,
       blink::WebCryptoKeyAlgorithm::createAes(algorithm.id(), keylen_bits),
       extractable,
-      usage_mask,
+      usages,
       key);
 }
 
 Status AesAlgorithm::ImportKeyJwk(const CryptoData& key_data,
                                   const blink::WebCryptoAlgorithm& algorithm,
                                   bool extractable,
-                                  blink::WebCryptoKeyUsageMask usage_mask,
+                                  blink::WebCryptoKeyUsageMask usages,
                                   blink::WebCryptoKey* key) const {
   std::vector<uint8_t> raw_data;
   Status status = ReadAesSecretKeyJwk(
-      key_data, jwk_suffix_, extractable, usage_mask, &raw_data);
+      key_data, jwk_suffix_, extractable, usages, &raw_data);
   if (status.IsError())
     return status;
 
   return ImportKeyRaw(
-      CryptoData(raw_data), algorithm, extractable, usage_mask, key);
+      CryptoData(raw_data), algorithm, extractable, usages, key);
 }
 
 Status AesAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/openssl/aes_key_openssl.h b/content/child/webcrypto/openssl/aes_key_openssl.h
index a77673a912..206a1e2 100644
--- a/content/child/webcrypto/openssl/aes_key_openssl.h
+++ b/content/child/webcrypto/openssl/aes_key_openssl.h
@@ -30,23 +30,23 @@
 
   Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                      bool extractable,
-                     blink::WebCryptoKeyUsageMask usage_mask,
+                     blink::WebCryptoKeyUsageMask usages,
                      GenerateKeyResult* result) const override;
 
   Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const override;
+      blink::WebCryptoKeyUsageMask usages) const override;
 
   Status ImportKeyRaw(const CryptoData& key_data,
                       const blink::WebCryptoAlgorithm& algorithm,
                       bool extractable,
-                      blink::WebCryptoKeyUsageMask usage_mask,
+                      blink::WebCryptoKeyUsageMask usages,
                       blink::WebCryptoKey* key) const override;
 
   Status ImportKeyJwk(const CryptoData& key_data,
                       const blink::WebCryptoAlgorithm& algorithm,
                       bool extractable,
-                      blink::WebCryptoKeyUsageMask usage_mask,
+                      blink::WebCryptoKeyUsageMask usages,
                       blink::WebCryptoKey* key) const override;
 
   Status ExportKeyRaw(const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/openssl/hmac_openssl.cc b/content/child/webcrypto/openssl/hmac_openssl.cc
index 946a2bc7..46cca84 100644
--- a/content/child/webcrypto/openssl/hmac_openssl.cc
+++ b/content/child/webcrypto/openssl/hmac_openssl.cc
@@ -72,9 +72,9 @@
 
   Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                      bool extractable,
-                     blink::WebCryptoKeyUsageMask usage_mask,
+                     blink::WebCryptoKeyUsageMask usages,
                      GenerateKeyResult* result) const override {
-    Status status = CheckKeyCreationUsages(kAllKeyUsages, usage_mask);
+    Status status = CheckKeyCreationUsages(kAllKeyUsages, usages);
     if (status.IsError())
       return status;
 
@@ -89,18 +89,18 @@
     return GenerateSecretKeyOpenSsl(blink::WebCryptoKeyAlgorithm::createHmac(
                                         params->hash().id(), keylen_bits),
                                     extractable,
-                                    usage_mask,
+                                    usages,
                                     keylen_bits / 8,
                                     result);
   }
 
   Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const override {
+      blink::WebCryptoKeyUsageMask usages) const override {
     switch (format) {
       case blink::WebCryptoKeyFormatRaw:
       case blink::WebCryptoKeyFormatJwk:
-        return CheckKeyCreationUsages(kAllKeyUsages, usage_mask);
+        return CheckKeyCreationUsages(kAllKeyUsages, usages);
       default:
         return Status::ErrorUnsupportedImportKeyFormat();
     }
@@ -109,7 +109,7 @@
   Status ImportKeyRaw(const CryptoData& key_data,
                       const blink::WebCryptoAlgorithm& algorithm,
                       bool extractable,
-                      blink::WebCryptoKeyUsageMask usage_mask,
+                      blink::WebCryptoKeyUsageMask usages,
                       blink::WebCryptoKey* key) const override {
     const blink::WebCryptoAlgorithm& hash =
         algorithm.hmacImportParams()->hash();
@@ -124,14 +124,14 @@
                                blink::WebCryptoKeyAlgorithm::createHmac(
                                    hash.id(), keylen_bits.ValueOrDie()),
                                extractable,
-                               usage_mask,
+                               usages,
                                key);
   }
 
   Status ImportKeyJwk(const CryptoData& key_data,
                       const blink::WebCryptoAlgorithm& algorithm,
                       bool extractable,
-                      blink::WebCryptoKeyUsageMask usage_mask,
+                      blink::WebCryptoKeyUsageMask usages,
                       blink::WebCryptoKey* key) const override {
     const char* algorithm_name =
         GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id());
@@ -140,12 +140,12 @@
 
     std::vector<uint8_t> raw_data;
     Status status = ReadSecretKeyJwk(
-        key_data, algorithm_name, extractable, usage_mask, &raw_data);
+        key_data, algorithm_name, extractable, usages, &raw_data);
     if (status.IsError())
       return status;
 
     return ImportKeyRaw(
-        CryptoData(raw_data), algorithm, extractable, usage_mask, key);
+        CryptoData(raw_data), algorithm, extractable, usages, key);
   }
 
   Status ExportKeyRaw(const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/openssl/rsa_key_openssl.cc b/content/child/webcrypto/openssl/rsa_key_openssl.cc
index 13b2333..4d01c8e 100644
--- a/content/child/webcrypto/openssl/rsa_key_openssl.cc
+++ b/content/child/webcrypto/openssl/rsa_key_openssl.cc
@@ -69,7 +69,6 @@
     blink::WebCryptoAlgorithmId hash_algorithm,
     EVP_PKEY* key,
     blink::WebCryptoKeyAlgorithm* key_algorithm) {
-  DCHECK(IsAlgorithmRsa(rsa_algorithm));
   DCHECK_EQ(EVP_PKEY_RSA, EVP_PKEY_id(key));
 
   crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(key));
@@ -96,7 +95,7 @@
     const blink::WebCryptoAlgorithmId rsa_algorithm_id,
     const blink::WebCryptoAlgorithm& hash,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) {
   blink::WebCryptoKeyAlgorithm key_algorithm;
   Status status = CreateRsaHashedKeyAlgorithm(
@@ -116,7 +115,7 @@
       blink::WebCryptoKeyTypePrivate,
       extractable,
       key_algorithm,
-      usage_mask);
+      usages);
   return Status::Success();
 }
 
@@ -125,7 +124,7 @@
     const blink::WebCryptoAlgorithmId rsa_algorithm_id,
     const blink::WebCryptoAlgorithm& hash,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) {
   blink::WebCryptoKeyAlgorithm key_algorithm;
   Status status = CreateRsaHashedKeyAlgorithm(
@@ -145,7 +144,7 @@
       blink::WebCryptoKeyTypePublic,
       extractable,
       key_algorithm,
-      usage_mask);
+      usages);
   return Status::Success();
 }
 
@@ -163,7 +162,7 @@
 
 Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm,
                            bool extractable,
-                           blink::WebCryptoKeyUsageMask usage_mask,
+                           blink::WebCryptoKeyUsageMask usages,
                            const JwkRsaInfo& params,
                            blink::WebCryptoKey* key) {
   crypto::ScopedRSA rsa(RSA_new());
@@ -196,13 +195,13 @@
                                    algorithm.id(),
                                    algorithm.rsaHashedImportParams()->hash(),
                                    extractable,
-                                   usage_mask,
+                                   usages,
                                    key);
 }
 
 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
                           bool extractable,
-                          blink::WebCryptoKeyUsageMask usage_mask,
+                          blink::WebCryptoKeyUsageMask usages,
                           const CryptoData& n,
                           const CryptoData& e,
                           blink::WebCryptoKey* key) {
@@ -223,7 +222,7 @@
                                   algorithm.id(),
                                   algorithm.rsaHashedImportParams()->hash(),
                                   extractable,
-                                  usage_mask,
+                                  usages,
                                   key);
 }
 
@@ -232,17 +231,17 @@
 Status RsaHashedAlgorithm::GenerateKey(
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask combined_usage_mask,
+    blink::WebCryptoKeyUsageMask combined_usages,
     GenerateKeyResult* result) const {
   Status status = CheckKeyCreationUsages(
-      all_public_key_usages_ | all_private_key_usages_, combined_usage_mask);
+      all_public_key_usages_ | all_private_key_usages_, combined_usages);
   if (status.IsError())
     return status;
 
-  const blink::WebCryptoKeyUsageMask public_usage_mask =
-      combined_usage_mask & all_public_key_usages_;
-  const blink::WebCryptoKeyUsageMask private_usage_mask =
-      combined_usage_mask & all_private_key_usages_;
+  const blink::WebCryptoKeyUsageMask public_usages =
+      combined_usages & all_public_key_usages_;
+  const blink::WebCryptoKeyUsageMask private_usages =
+      combined_usages & all_private_key_usages_;
 
   const blink::WebCryptoRsaHashedKeyGenParams* params =
       algorithm.rsaHashedKeyGenParams();
@@ -284,8 +283,8 @@
     return Status::OperationError();
   }
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
 
   // Note that extractable is unconditionally set to true. This is because per
   // the WebCrypto spec generated public keys are always public.
@@ -293,7 +292,7 @@
                                     algorithm.id(),
                                     params->hash(),
                                     true,
-                                    public_usage_mask,
+                                    public_usages,
                                     &public_key);
   if (status.IsError())
     return status;
@@ -302,7 +301,7 @@
                                      algorithm.id(),
                                      params->hash(),
                                      extractable,
-                                     private_usage_mask,
+                                     private_usages,
                                      &private_key);
   if (status.IsError())
     return status;
@@ -313,16 +312,16 @@
 
 Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(
     blink::WebCryptoKeyFormat format,
-    blink::WebCryptoKeyUsageMask usage_mask) const {
+    blink::WebCryptoKeyUsageMask usages) const {
   switch (format) {
     case blink::WebCryptoKeyFormatSpki:
-      return CheckKeyCreationUsages(all_public_key_usages_, usage_mask);
+      return CheckKeyCreationUsages(all_public_key_usages_, usages);
     case blink::WebCryptoKeyFormatPkcs8:
-      return CheckKeyCreationUsages(all_private_key_usages_, usage_mask);
+      return CheckKeyCreationUsages(all_private_key_usages_, usages);
     case blink::WebCryptoKeyFormatJwk:
       // TODO(eroman): http://crbug.com/395904
       return CheckKeyCreationUsages(
-          all_public_key_usages_ | all_private_key_usages_, usage_mask);
+          all_public_key_usages_ | all_private_key_usages_, usages);
     default:
       return Status::ErrorUnsupportedImportKeyFormat();
   }
@@ -332,7 +331,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   if (!key_data.byte_length())
     return Status::ErrorImportEmptyKeyData();
@@ -371,7 +370,7 @@
                                    algorithm.id(),
                                    algorithm.rsaHashedImportParams()->hash(),
                                    extractable,
-                                   usage_mask,
+                                   usages,
                                    key);
 }
 
@@ -379,7 +378,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   if (!key_data.byte_length())
     return Status::ErrorImportEmptyKeyData();
@@ -405,7 +404,7 @@
                                   algorithm.id(),
                                   algorithm.rsaHashedImportParams()->hash(),
                                   extractable,
-                                  usage_mask,
+                                  usages,
                                   key);
 }
 
@@ -413,7 +412,7 @@
     const CryptoData& key_data,
     const blink::WebCryptoAlgorithm& algorithm,
     bool extractable,
-    blink::WebCryptoKeyUsageMask usage_mask,
+    blink::WebCryptoKeyUsageMask usages,
     blink::WebCryptoKey* key) const {
   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
 
@@ -425,22 +424,22 @@
 
   JwkRsaInfo jwk;
   Status status =
-      ReadRsaKeyJwk(key_data, jwk_algorithm, extractable, usage_mask, &jwk);
+      ReadRsaKeyJwk(key_data, jwk_algorithm, extractable, usages, &jwk);
   if (status.IsError())
     return status;
 
   // Once the key type is known, verify the usages.
   status = CheckKeyCreationUsages(
       jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_,
-      usage_mask);
+      usages);
   if (status.IsError())
     return status;
 
   return jwk.is_private_key
-             ? ImportRsaPrivateKey(algorithm, extractable, usage_mask, jwk, key)
+             ? ImportRsaPrivateKey(algorithm, extractable, usages, jwk, key)
              : ImportRsaPublicKey(algorithm,
                                   extractable,
-                                  usage_mask,
+                                  usages,
                                   CryptoData(jwk.n),
                                   CryptoData(jwk.e),
                                   key);
diff --git a/content/child/webcrypto/openssl/rsa_key_openssl.h b/content/child/webcrypto/openssl/rsa_key_openssl.h
index a93550d..48d7b4c 100644
--- a/content/child/webcrypto/openssl/rsa_key_openssl.h
+++ b/content/child/webcrypto/openssl/rsa_key_openssl.h
@@ -40,29 +40,29 @@
 
   Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm,
                      bool extractable,
-                     blink::WebCryptoKeyUsageMask usage_mask,
+                     blink::WebCryptoKeyUsageMask usages,
                      GenerateKeyResult* result) const override;
 
   Status VerifyKeyUsagesBeforeImportKey(
       blink::WebCryptoKeyFormat format,
-      blink::WebCryptoKeyUsageMask usage_mask) const override;
+      blink::WebCryptoKeyUsageMask usages) const override;
 
   Status ImportKeyPkcs8(const CryptoData& key_data,
                         const blink::WebCryptoAlgorithm& algorithm,
                         bool extractable,
-                        blink::WebCryptoKeyUsageMask usage_mask,
+                        blink::WebCryptoKeyUsageMask usages,
                         blink::WebCryptoKey* key) const override;
 
   Status ImportKeySpki(const CryptoData& key_data,
                        const blink::WebCryptoAlgorithm& algorithm,
                        bool extractable,
-                       blink::WebCryptoKeyUsageMask usage_mask,
+                       blink::WebCryptoKeyUsageMask usages,
                        blink::WebCryptoKey* key) const override;
 
   Status ImportKeyJwk(const CryptoData& key_data,
                       const blink::WebCryptoAlgorithm& algorithm,
                       bool extractable,
-                      blink::WebCryptoKeyUsageMask usage_mask,
+                      blink::WebCryptoKeyUsageMask usages,
                       blink::WebCryptoKey* key) const override;
 
   Status ExportKeyPkcs8(const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/openssl/sym_key_openssl.cc b/content/child/webcrypto/openssl/sym_key_openssl.cc
index e03cc588..3923833 100644
--- a/content/child/webcrypto/openssl/sym_key_openssl.cc
+++ b/content/child/webcrypto/openssl/sym_key_openssl.cc
@@ -20,7 +20,7 @@
 
 Status GenerateSecretKeyOpenSsl(const blink::WebCryptoKeyAlgorithm& algorithm,
                                 bool extractable,
-                                blink::WebCryptoKeyUsageMask usage_mask,
+                                blink::WebCryptoKeyUsageMask usages,
                                 unsigned keylen_bytes,
                                 GenerateKeyResult* result) {
   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
@@ -37,7 +37,7 @@
                                   blink::WebCryptoKeyTypeSecret,
                                   extractable,
                                   algorithm,
-                                  usage_mask));
+                                  usages));
 
   return Status::Success();
 }
@@ -45,13 +45,13 @@
 Status ImportKeyRawOpenSsl(const CryptoData& key_data,
                            const blink::WebCryptoKeyAlgorithm& algorithm,
                            bool extractable,
-                           blink::WebCryptoKeyUsageMask usage_mask,
+                           blink::WebCryptoKeyUsageMask usages,
                            blink::WebCryptoKey* key) {
   *key = blink::WebCryptoKey::create(new SymKeyOpenSsl(key_data),
                                      blink::WebCryptoKeyTypeSecret,
                                      extractable,
                                      algorithm,
-                                     usage_mask);
+                                     usages);
   return Status::Success();
 }
 
diff --git a/content/child/webcrypto/openssl/sym_key_openssl.h b/content/child/webcrypto/openssl/sym_key_openssl.h
index ac68f5e..bb5def4 100644
--- a/content/child/webcrypto/openssl/sym_key_openssl.h
+++ b/content/child/webcrypto/openssl/sym_key_openssl.h
@@ -17,14 +17,14 @@
 
 Status GenerateSecretKeyOpenSsl(const blink::WebCryptoKeyAlgorithm& algorithm,
                                 bool extractable,
-                                blink::WebCryptoKeyUsageMask usage_mask,
+                                blink::WebCryptoKeyUsageMask usages,
                                 unsigned keylen_bytes,
                                 GenerateKeyResult* result);
 
 Status ImportKeyRawOpenSsl(const CryptoData& key_data,
                            const blink::WebCryptoKeyAlgorithm& algorithm,
                            bool extractable,
-                           blink::WebCryptoKeyUsageMask usage_mask,
+                           blink::WebCryptoKeyUsageMask usages,
                            blink::WebCryptoKey* key);
 
 }  // namespace webcrypto
diff --git a/content/child/webcrypto/structured_clone.cc b/content/child/webcrypto/structured_clone.cc
index 6bbf6d3..68d449a 100644
--- a/content/child/webcrypto/structured_clone.cc
+++ b/content/child/webcrypto/structured_clone.cc
@@ -109,7 +109,7 @@
 bool DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
                             blink::WebCryptoKeyType type,
                             bool extractable,
-                            blink::WebCryptoKeyUsageMask usage_mask,
+                            blink::WebCryptoKeyUsageMask usages,
                             const CryptoData& key_data,
                             blink::WebCryptoKey* key) {
   // TODO(eroman): This should not call into the platform crypto layer.
@@ -124,7 +124,7 @@
                             key_data,
                             KeyAlgorithmToImportAlgorithm(algorithm),
                             extractable,
-                            usage_mask,
+                            usages,
                             key);
   if (status.IsError())
     return false;
diff --git a/content/child/webcrypto/structured_clone.h b/content/child/webcrypto/structured_clone.h
index a72974c..3e218c85 100644
--- a/content/child/webcrypto/structured_clone.h
+++ b/content/child/webcrypto/structured_clone.h
@@ -23,7 +23,7 @@
 bool DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
                             blink::WebCryptoKeyType type,
                             bool extractable,
-                            blink::WebCryptoKeyUsageMask usage_mask,
+                            blink::WebCryptoKeyUsageMask usages,
                             const CryptoData& key_data,
                             blink::WebCryptoKey* key);
 
diff --git a/content/child/webcrypto/test/aes_cbc_unittest.cc b/content/child/webcrypto/test/aes_cbc_unittest.cc
index 467f8ed..b7f897c6 100644
--- a/content/child/webcrypto/test/aes_cbc_unittest.cc
+++ b/content/child/webcrypto/test/aes_cbc_unittest.cc
@@ -110,7 +110,7 @@
   std::vector<uint8_t> key_raw(1);
   std::vector<uint8_t> iv(16);
 
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   EXPECT_EQ(Status::ErrorImportAesKeyLength(),
             ImportKey(blink::WebCryptoKeyFormatRaw,
                       CryptoData(key_raw),
@@ -134,7 +134,7 @@
 }
 
 TEST(WebCryptoAesCbcTest, ImportKeyUnsupportedFormat) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   ASSERT_EQ(Status::ErrorUnsupportedImportKeyFormat(),
             ImportKey(blink::WebCryptoKeyFormatSpki,
                       CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -254,7 +254,7 @@
   const unsigned short kKeyLength[] = {128, 256};
   for (size_t key_length_i = 0; key_length_i < arraysize(kKeyLength);
        ++key_length_i) {
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey key;
 
     std::vector<std::vector<uint8_t> > keys;
     std::vector<uint8_t> key_bytes;
@@ -283,7 +283,7 @@
 
 TEST(WebCryptoAesCbcTest, GenerateKeyBadLength) {
   const unsigned short kKeyLen[] = {0, 127, 257};
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   for (size_t i = 0; i < arraysize(kKeyLen); ++i) {
     SCOPED_TRACE(i);
     EXPECT_EQ(Status::ErrorGenerateKeyLength(),
@@ -294,7 +294,7 @@
 
 // If key_ops is specified but empty, no key usages are allowed for the key.
 TEST(WebCryptoAesCbcTest, ImportKeyJwkEmptyKeyOps) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetBoolean("ext", false);
@@ -332,7 +332,7 @@
 
 // If key_ops is missing, then any key usages can be specified.
 TEST(WebCryptoAesCbcTest, ImportKeyJwkNoKeyOps) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -358,7 +358,7 @@
 }
 
 TEST(WebCryptoAesCbcTest, ImportKeyJwkKeyOpsEncryptDecrypt) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -404,7 +404,7 @@
 
 // Test failure if input usage is NOT a strict subset of the JWK usage.
 TEST(WebCryptoAesCbcTest, ImportKeyJwkKeyOpsNotSuperset) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -424,7 +424,7 @@
 }
 
 TEST(WebCryptoAesCbcTest, ImportKeyJwkUseEnc) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -449,7 +449,7 @@
 }
 
 TEST(WebCryptoAesCbcTest, ImportJwkInvalidJson) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   // Fail on empty JSON.
   EXPECT_EQ(Status::ErrorImportEmptyKeyData(),
             ImportKey(blink::WebCryptoKeyFormatJwk,
@@ -476,7 +476,7 @@
 
 // Fail on JWK alg present but incorrect (expecting A128CBC).
 TEST(WebCryptoAesCbcTest, ImportJwkIncorrectAlg) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -494,7 +494,7 @@
 
 // Fail on invalid kty.
 TEST(WebCryptoAesCbcTest, ImportJwkInvalidKty) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "foo");
@@ -510,7 +510,7 @@
 
 // Fail on missing kty.
 TEST(WebCryptoAesCbcTest, ImportJwkMissingKty) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -525,7 +525,7 @@
 
 // Fail on kty wrong type.
 TEST(WebCryptoAesCbcTest, ImportJwkKtyWrongType) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetDouble("kty", 0.1);
@@ -542,7 +542,7 @@
 
 // Fail on invalid use.
 TEST(WebCryptoAesCbcTest, ImportJwkUnrecognizedUse) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -560,7 +560,7 @@
 
 // Fail on invalid use (wrong type).
 TEST(WebCryptoAesCbcTest, ImportJwkUseWrongType) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -578,7 +578,7 @@
 
 // Fail on invalid extractable (wrong type).
 TEST(WebCryptoAesCbcTest, ImportJwkExtWrongType) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -596,7 +596,7 @@
 
 // Fail on invalid key_ops (wrong type).
 TEST(WebCryptoAesCbcTest, ImportJwkKeyOpsWrongType) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -615,7 +615,7 @@
 // Fail on inconsistent key_ops - asking for "encrypt" however JWK contains
 // only "foo".
 TEST(WebCryptoAesCbcTest, ImportJwkKeyOpsLacksUsages) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -636,10 +636,10 @@
 
 // Import a JWK with unrecognized values for "key_ops".
 TEST(WebCryptoAesCbcTest, ImportJwkUnrecognizedKeyOps) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   blink::WebCryptoAlgorithm algorithm =
       CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
-  blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt;
+  blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageEncrypt;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -655,15 +655,15 @@
   key_ops->AppendString("baz");
   key_ops->AppendString("encrypt");
   EXPECT_EQ(Status::Success(),
-            ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+            ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
 }
 
 // Import a JWK with a value in key_ops array that is not a string.
 TEST(WebCryptoAesCbcTest, ImportJwkNonStringKeyOp) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   blink::WebCryptoAlgorithm algorithm =
       CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
-  blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt;
+  blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageEncrypt;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -677,12 +677,12 @@
   key_ops->AppendString("encrypt");
   key_ops->AppendInteger(3);
   EXPECT_EQ(Status::ErrorJwkPropertyWrongType("key_ops[1]", "string"),
-            ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+            ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
 }
 
 // Fail on missing k.
 TEST(WebCryptoAesCbcTest, ImportJwkMissingK) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -698,7 +698,7 @@
 
 // Fail on bad b64 encoding for k.
 TEST(WebCryptoAesCbcTest, ImportJwkBadB64ForK) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -714,7 +714,7 @@
 
 // Fail on empty k.
 TEST(WebCryptoAesCbcTest, ImportJwkEmptyK) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -731,7 +731,7 @@
 
 // Fail on empty k (with alg specified).
 TEST(WebCryptoAesCbcTest, ImportJwkEmptyK2) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -750,7 +750,7 @@
 // Fail on k actual length (120 bits) inconsistent with the embedded JWK alg
 // value (128) for an AES key.
 TEST(WebCryptoAesCbcTest, ImportJwkInconsistentKLength) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -768,7 +768,7 @@
 // Fail on k actual length (192 bits) inconsistent with the embedded JWK alg
 // value (128) for an AES key.
 TEST(WebCryptoAesCbcTest, ImportJwkInconsistentKLength2) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -810,7 +810,7 @@
 // AES 192-bit is not allowed: http://crbug.com/381829
 TEST(WebCryptoAesCbcTest, ImportAesCbc192Raw) {
   std::vector<uint8_t> key_raw(24, 0);
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   Status status = ImportKey(blink::WebCryptoKeyFormatRaw,
                             CryptoData(key_raw),
                             CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
@@ -822,7 +822,7 @@
 
 // AES 192-bit is not allowed: http://crbug.com/381829
 TEST(WebCryptoAesCbcTest, ImportAesCbc192Jwk) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
@@ -840,7 +840,7 @@
 
 // AES 192-bit is not allowed: http://crbug.com/381829
 TEST(WebCryptoAesCbcTest, GenerateAesCbc192) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   Status status = GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(192),
                                     true,
                                     blink::WebCryptoKeyUsageEncrypt,
@@ -859,7 +859,7 @@
                              CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
                              blink::WebCryptoKeyUsageUnwrapKey);
 
-  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_key;
   ASSERT_EQ(Status::ErrorAes192BitUnsupported(),
             UnwrapKey(blink::WebCryptoKeyFormatRaw,
                       CryptoData(wrapped_key),
@@ -890,7 +890,7 @@
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey key;
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               ImportKey(blink::WebCryptoKeyFormatRaw,
                         CryptoData(key_bytes),
@@ -912,7 +912,7 @@
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey key;
 
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               GenerateSecretKey(
@@ -928,7 +928,7 @@
     return;
 
   // Generate the wrapping key.
-  blink::WebCryptoKey wrapping_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey wrapping_key;
   ASSERT_EQ(Status::Success(),
             GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(128),
                               true,
@@ -940,8 +940,8 @@
   const unsigned int modulus_length = 256;
   const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
   ASSERT_EQ(Status::Success(),
             GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
                                 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
@@ -990,7 +990,7 @@
       CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                      blink::WebCryptoAlgorithmIdSha256);
 
-  blink::WebCryptoKey unwrapped_public_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_public_key;
 
   ASSERT_EQ(Status::Success(),
             UnwrapKey(blink::WebCryptoKeyFormatSpki,
@@ -1002,7 +1002,7 @@
                       0,
                       &unwrapped_public_key));
 
-  blink::WebCryptoKey unwrapped_private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_private_key;
 
   ASSERT_EQ(Status::Success(),
             UnwrapKey(blink::WebCryptoKeyFormatPkcs8,
diff --git a/content/child/webcrypto/test/aes_gcm_unittest.cc b/content/child/webcrypto/test/aes_gcm_unittest.cc
index 8f4b910..8825741 100644
--- a/content/child/webcrypto/test/aes_gcm_unittest.cc
+++ b/content/child/webcrypto/test/aes_gcm_unittest.cc
@@ -109,7 +109,7 @@
   }
 
   const unsigned short kKeyLen[] = {0, 127, 257};
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   for (size_t i = 0; i < arraysize(kKeyLen); ++i) {
     SCOPED_TRACE(i);
     EXPECT_EQ(Status::ErrorGenerateKeyLength(),
diff --git a/content/child/webcrypto/test/aes_kw_unittest.cc b/content/child/webcrypto/test/aes_kw_unittest.cc
index f75b0209..5b073d9 100644
--- a/content/child/webcrypto/test/aes_kw_unittest.cc
+++ b/content/child/webcrypto/test/aes_kw_unittest.cc
@@ -25,7 +25,7 @@
 
 TEST(WebCryptoAesKwTest, GenerateKeyBadLength) {
   const unsigned short kKeyLen[] = {0, 127, 257};
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   for (size_t i = 0; i < arraysize(kKeyLen); ++i) {
     SCOPED_TRACE(i);
     EXPECT_EQ(Status::ErrorGenerateKeyLength(),
@@ -35,7 +35,7 @@
 }
 
 TEST(WebCryptoAesKwTest, ImportKeyJwkKeyOpsWrapUnwrap) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -87,7 +87,7 @@
 }
 
 TEST(WebCryptoAesKwTest, AesKwKeyImport) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   blink::WebCryptoAlgorithm algorithm =
       CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
 
@@ -180,7 +180,7 @@
   const std::vector<uint8_t> test_ciphertext =
       GetBytesFromHexString(test, "ciphertext");
 
-  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_key;
 
   // Using a wrapping algorithm that does not match the wrapping key algorithm
   // should fail.
@@ -237,7 +237,7 @@
     EXPECT_BYTES_EQ(test_ciphertext, wrapped_key);
 
     // Unwrap the known ciphertext to get a new test_key.
-    blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey unwrapped_key;
     ASSERT_EQ(
         Status::Success(),
         UnwrapKey(blink::WebCryptoKeyFormatRaw,
@@ -282,7 +282,7 @@
       test_kek, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
 
   // Unwrap the known ciphertext.
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   ASSERT_EQ(
       Status::Success(),
       UnwrapKey(blink::WebCryptoKeyFormatRaw,
@@ -349,7 +349,7 @@
   // Unwrap with wrapped data too small must fail.
   const std::vector<uint8_t> small_data(test_ciphertext.begin(),
                                         test_ciphertext.begin() + 23);
-  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_key;
   EXPECT_EQ(Status::ErrorDataTooSmall(),
             UnwrapKey(blink::WebCryptoKeyFormatRaw,
                       CryptoData(small_data),
@@ -395,7 +395,7 @@
 
   // Unwrap of a corrupted version of the known ciphertext should fail, due to
   // AES-KW's built-in integrity check.
-  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_key;
   EXPECT_EQ(Status::OperationError(),
             UnwrapKey(blink::WebCryptoKeyFormatRaw,
                       CryptoData(Corrupted(test_ciphertext)),
@@ -432,7 +432,7 @@
       wrapping_key_data, wrapping_algorithm, blink::WebCryptoKeyUsageUnwrapKey);
 
   // Unwrap the known wrapped key data to produce a new key
-  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_key;
   ASSERT_EQ(
       Status::Success(),
       UnwrapKey(blink::WebCryptoKeyFormatJwk,
@@ -483,7 +483,7 @@
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey key;
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               ImportKey(blink::WebCryptoKeyFormatRaw,
                         CryptoData(key_bytes),
@@ -510,7 +510,7 @@
   };
 
   // Import the wrapping key.
-  blink::WebCryptoKey wrapping_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey wrapping_key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatRaw,
                       CryptoData(std::vector<uint8_t>(16)),
@@ -529,7 +529,7 @@
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey key;
 
     ASSERT_EQ(
         Status::ErrorCreateKeyBadUsages(),
@@ -560,7 +560,7 @@
   };
 
   // Import the wrapping key.
-  blink::WebCryptoKey wrapping_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey wrapping_key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatRaw,
                       CryptoData(std::vector<uint8_t>(16)),
@@ -584,7 +584,7 @@
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey key;
 
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               UnwrapKey(blink::WebCryptoKeyFormatJwk,
diff --git a/content/child/webcrypto/test/hmac_unittest.cc b/content/child/webcrypto/test/hmac_unittest.cc
index fe5d082c..d57116c0 100644
--- a/content/child/webcrypto/test/hmac_unittest.cc
+++ b/content/child/webcrypto/test/hmac_unittest.cc
@@ -118,7 +118,7 @@
   std::vector<std::vector<uint8_t> > keys;
   for (int i = 0; i < 16; ++i) {
     std::vector<uint8_t> key_bytes;
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey key;
     blink::WebCryptoAlgorithm algorithm =
         CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 512);
     ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key));
@@ -143,7 +143,7 @@
 
 // If the key length is not provided, then the block size is used.
 TEST(WebCryptoHmacTest, GenerateKeyNoLengthSha1) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   blink::WebCryptoAlgorithm algorithm =
       CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 0);
   ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key));
@@ -161,7 +161,7 @@
 
 // If the key length is not provided, then the block size is used.
 TEST(WebCryptoHmacTest, GenerateKeyNoLengthSha512) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   blink::WebCryptoAlgorithm algorithm =
       CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha512, 0);
   ASSERT_EQ(Status::Success(), GenerateSecretKey(algorithm, true, 0, &key));
@@ -176,7 +176,7 @@
 }
 
 TEST(WebCryptoHmacTest, ImportKeyJwkKeyOpsSignVerify) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -210,7 +210,7 @@
 
 // Test 'use' inconsistent with 'key_ops'.
 TEST(WebCryptoHmacTest, ImportKeyJwkUseInconsisteWithKeyOps) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -233,7 +233,7 @@
 
 // Test JWK composite 'sig' use
 TEST(WebCryptoHmacTest, ImportKeyJwkUseSig) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
@@ -256,11 +256,11 @@
   // inconsistent with the input value, the operation must fail.
 
   // Consistency rules when JWK value is not present: Inputs should be used.
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   bool extractable = false;
   blink::WebCryptoAlgorithm algorithm =
       CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256);
-  blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageVerify;
+  blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageVerify;
   base::DictionaryValue dict;
   dict.SetString("kty", "oct");
   dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
@@ -270,7 +270,7 @@
                       CryptoData(json_vec),
                       algorithm,
                       extractable,
-                      usage_mask,
+                      usages,
                       &key));
   EXPECT_TRUE(key.handle());
   EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
@@ -297,7 +297,7 @@
                       CryptoData(json_vec),
                       algorithm,
                       extractable,
-                      usage_mask,
+                      usages,
                       &key));
 
   // Extractable cases:
@@ -310,22 +310,22 @@
                       CryptoData(json_vec),
                       algorithm,
                       true,
-                      usage_mask,
+                      usages,
                       &key));
   EXPECT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatJwk,
                       CryptoData(json_vec),
                       algorithm,
                       false,
-                      usage_mask,
+                      usages,
                       &key));
   EXPECT_FALSE(key.extractable());
   dict.SetBoolean("ext", true);
   EXPECT_EQ(Status::Success(),
-            ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key));
+            ImportKeyJwkFromDict(dict, algorithm, true, usages, &key));
   EXPECT_TRUE(key.extractable());
   EXPECT_EQ(Status::Success(),
-            ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+            ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
   EXPECT_FALSE(key.extractable());
   dict.SetBoolean("ext", true);  // restore previous value
 
@@ -359,7 +359,7 @@
                 CryptoData(json_vec),
                 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1),
                 extractable,
-                usage_mask,
+                usages,
                 &key));
 
   // Pass: JWK alg missing but input algorithm specified: use input value
@@ -369,12 +369,12 @@
                 dict,
                 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256),
                 extractable,
-                usage_mask,
+                usages,
                 &key));
   EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id());
   dict.SetString("alg", "HS256");
 
-  // Fail: Input usage_mask (encrypt) is not a subset of the JWK value
+  // Fail: Input usages (encrypt) is not a subset of the JWK value
   // (sign|verify). Moreover "encrypt" is not a valid usage for HMAC.
   EXPECT_EQ(Status::ErrorCreateKeyBadUsages(),
             ImportKey(blink::WebCryptoKeyFormatJwk,
@@ -384,16 +384,16 @@
                       blink::WebCryptoKeyUsageEncrypt,
                       &key));
 
-  // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK
+  // Fail: Input usages (encrypt|sign|verify) is not a subset of the JWK
   // value (sign|verify). Moreover "encrypt" is not a valid usage for HMAC.
-  usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign |
-               blink::WebCryptoKeyUsageVerify;
+  usages = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign |
+           blink::WebCryptoKeyUsageVerify;
   EXPECT_EQ(Status::ErrorCreateKeyBadUsages(),
             ImportKey(blink::WebCryptoKeyFormatJwk,
                       CryptoData(json_vec),
                       algorithm,
                       extractable,
-                      usage_mask,
+                      usages,
                       &key));
 
   // TODO(padolph): kty vs alg consistency tests: Depending on the kty value,
@@ -408,11 +408,11 @@
   // This test verifies the happy path of JWK import, including the application
   // of the imported key material.
 
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   bool extractable = false;
   blink::WebCryptoAlgorithm algorithm =
       CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256);
-  blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign;
+  blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
 
   // Import a symmetric key JWK and HMAC-SHA256 sign()
   // Uses the first SHA256 test vector from the HMAC sample set above.
@@ -424,9 +424,8 @@
   dict.SetBoolean("ext", false);
   dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
 
-  ASSERT_EQ(
-      Status::Success(),
-      ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key));
+  ASSERT_EQ(Status::Success(),
+            ImportKeyJwkFromDict(dict, algorithm, extractable, usages, &key));
 
   EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
             key.algorithm().hmacParams()->hash().id());
@@ -488,7 +487,7 @@
       CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1);
 
   blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageSign;
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   // Import a zero-byte HMAC key.
   const char key_data_hex[] = "";
@@ -527,7 +526,7 @@
 TEST(WebCryptoHmacTest, ImportRawKeyTooLarge) {
   CryptoData big_data(NULL, UINT_MAX);  // Invalid data of big length.
 
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   EXPECT_EQ(
       Status::ErrorDataTooLarge(),
       ImportKey(blink::WebCryptoKeyFormatRaw,
diff --git a/content/child/webcrypto/test/rsa_oaep_unittest.cc b/content/child/webcrypto/test/rsa_oaep_unittest.cc
index f6bec71..972ffaa9 100644
--- a/content/child/webcrypto/test/rsa_oaep_unittest.cc
+++ b/content/child/webcrypto/test/rsa_oaep_unittest.cc
@@ -47,7 +47,7 @@
     return;
   }
 
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey private_key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatPkcs8,
                       CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
@@ -67,7 +67,7 @@
 
   scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
   ASSERT_EQ(Status::Success(),
             ImportKeyJwkFromDict(*jwk.get(),
                                  CreateRsaHashedImportAlgorithm(
@@ -87,7 +87,7 @@
   scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
   jwk->SetString("alg", "RSA-OAEP");
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
   ASSERT_EQ(Status::Success(),
             ImportKeyJwkFromDict(*jwk.get(),
                                  CreateRsaHashedImportAlgorithm(
@@ -107,7 +107,7 @@
   scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
   jwk->SetString("alg", "RSA-OAEP-512");
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
   ASSERT_EQ(Status::ErrorJwkAlgorithmInconsistent(),
             ImportKeyJwkFromDict(*jwk.get(),
                                  CreateRsaHashedImportAlgorithm(
@@ -128,7 +128,7 @@
   jwk->SetString("kty", "oct");
   jwk->SetString("alg", "RSA-OAEP");
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
   ASSERT_EQ(Status::ErrorJwkUnexpectedKty("RSA"),
             ImportKeyJwkFromDict(*jwk.get(),
                                  CreateRsaHashedImportAlgorithm(
@@ -160,7 +160,7 @@
     jwk->SetString("alg", test_data.expected_jwk_alg);
 
     // Import the key in a known-good format
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
     ASSERT_EQ(Status::Success(),
               ImportKeyJwkFromDict(
                   *jwk.get(),
@@ -210,8 +210,8 @@
 
     blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
         blink::WebCryptoAlgorithmIdRsaOaep, digest_algorithm.id());
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
+    blink::WebCryptoKey private_key;
 
     ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(public_key_der,
                                              private_key_der,
@@ -256,7 +256,7 @@
 
   scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
   ASSERT_EQ(Status::Success(),
             ImportKeyJwkFromDict(*jwk.get(),
                                  CreateRsaHashedImportAlgorithm(
@@ -323,7 +323,7 @@
 
   scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
   ASSERT_EQ(Status::Success(),
             ImportKeyJwkFromDict(*jwk.get(),
                                  CreateRsaHashedImportAlgorithm(
@@ -353,7 +353,7 @@
     return;
   }
 
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey private_key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatPkcs8,
                       CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
@@ -387,8 +387,8 @@
 
   blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
       blink::WebCryptoAlgorithmIdRsaOaep, blink::WebCryptoAlgorithmIdSha1);
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
 
   ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
       HexStringToBytes(kPublicKeySpkiDerHex),
@@ -432,7 +432,7 @@
   EXPECT_BYTES_EQ_HEX(key_hex, decrypted_key);
 
   // Now attempt to unwrap the key, which should also decrypt the data.
-  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_key;
   ASSERT_EQ(Status::Success(),
             UnwrapKey(blink::WebCryptoKeyFormatRaw,
                       CryptoData(wrapped_key),
@@ -505,8 +505,8 @@
       "37f3e1972c45a477e66db95c9609bb27f862700ef93379930786cf751b";
   blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
       blink::WebCryptoAlgorithmIdRsaOaep, blink::WebCryptoAlgorithmIdSha1);
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
 
   ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
       HexStringToBytes(kPublicKey2048SpkiDerHex),
@@ -551,7 +551,7 @@
       decrypted_jwk, "A128CBC", key_hex, blink::WebCryptoKeyUsageEncrypt));
 
   // Now attempt to unwrap the key, which should also decrypt the data.
-  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey unwrapped_key;
   ASSERT_EQ(Status::Success(),
             UnwrapKey(blink::WebCryptoKeyFormatJwk,
                       CryptoData(wrapped_key),
@@ -598,7 +598,7 @@
                                        test.hash);
 
     // Import the spki to create a public key
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
     ASSERT_EQ(Status::Success(),
               ImportKey(blink::WebCryptoKeyFormatSpki,
                         CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -618,7 +618,7 @@
                                 test.usage));
 
     // Import the JWK back in to create a new key
-    blink::WebCryptoKey public_key2 = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key2;
     ASSERT_EQ(Status::Success(),
               ImportKey(blink::WebCryptoKeyFormatJwk,
                         CryptoData(jwk),
diff --git a/content/child/webcrypto/test/rsa_ssa_unittest.cc b/content/child/webcrypto/test/rsa_ssa_unittest.cc
index 33d0751..81f51012 100644
--- a/content/child/webcrypto/test/rsa_ssa_unittest.cc
+++ b/content/child/webcrypto/test/rsa_ssa_unittest.cc
@@ -38,7 +38,7 @@
 
 TEST(WebCryptoRsaSsaTest, ImportExportSpki) {
   // Passing case: Import a valid RSA key in SPKI format.
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatSpki,
                       CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -127,7 +127,7 @@
     return;
 
   // Passing case: Import a valid RSA key in PKCS#8 format.
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatPkcs8,
                       CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
@@ -226,7 +226,7 @@
         HexStringToBytes(kPrivateKeyPkcs8DerHex);
     corrupted_data[i] = ~corrupted_data[i];
 
-    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey key;
     EXPECT_EQ(Status::DataError(),
               ImportKey(blink::WebCryptoKeyFormatPkcs8,
                         CryptoData(corrupted_data),
@@ -247,7 +247,7 @@
   if (!SupportsRsaPrivateKeyImport())
     return;
 
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatPkcs8,
                       CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
@@ -341,7 +341,7 @@
     int modulus_length_bits = 0;
     ASSERT_TRUE(key_values->GetInteger("modulusLength", &modulus_length_bits));
 
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey private_key;
 
     // Import the key from JWK.
     ASSERT_EQ(
@@ -389,7 +389,7 @@
   base::DictionaryValue* key1_jwk;
   ASSERT_TRUE(key1_props->GetDictionary("jwk", &key1_jwk));
 
-  blink::WebCryptoKey key1 = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key1;
   ASSERT_EQ(Status::Success(),
             ImportKeyJwkFromDict(*key1_jwk,
                                  CreateRsaHashedImportAlgorithm(
@@ -413,7 +413,7 @@
 
   // This should fail, as the n,e,d parameters are not consistent. It MUST NOT
   // somehow return the key created earlier.
-  blink::WebCryptoKey key2 = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key2;
   ASSERT_EQ(Status::OperationError(),
             ImportKeyJwkFromDict(*key2_jwk,
                                  CreateRsaHashedImportAlgorithm(
@@ -432,7 +432,7 @@
 // This fails because JWA says that producers must include either ALL optional
 // parameters or NONE.
 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkMissingOptionalParams) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "RSA");
@@ -475,7 +475,7 @@
   if (!SupportsRsaPrivateKeyImport())
     return;
 
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   base::DictionaryValue dict;
   dict.SetString("kty", "RSA");
@@ -515,7 +515,7 @@
       "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm"
       "e7PUJHYW1PW6ENTP0ibeiNOfFvs");
 
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
 
   EXPECT_EQ(Status::ErrorJwkBigIntegerHasLeadingZero("e"),
             ImportKeyJwkFromDict(dict,
@@ -539,13 +539,13 @@
                                      modulus_length,
                                      public_exponent);
   bool extractable = true;
-  const blink::WebCryptoKeyUsageMask usage_mask = 0;
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  const blink::WebCryptoKeyUsageMask usages = 0;
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
 
   EXPECT_EQ(Status::Success(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
   EXPECT_FALSE(public_key.isNull());
   EXPECT_FALSE(private_key.isNull());
   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
@@ -560,8 +560,8 @@
             private_key.algorithm().rsaHashedParams()->hash().id());
   EXPECT_TRUE(public_key.extractable());
   EXPECT_EQ(extractable, private_key.extractable());
-  EXPECT_EQ(usage_mask, public_key.usages());
-  EXPECT_EQ(usage_mask, private_key.usages());
+  EXPECT_EQ(usages, public_key.usages());
+  EXPECT_EQ(usages, private_key.usages());
 
   // Try exporting the generated key pair, and then re-importing to verify that
   // the exported data was valid.
@@ -579,7 +579,7 @@
                             blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                             blink::WebCryptoAlgorithmIdSha256),
                         true,
-                        usage_mask,
+                        usages,
                         &public_key));
     EXPECT_EQ(modulus_length,
               public_key.algorithm().rsaHashedParams()->modulusLengthBits());
@@ -597,7 +597,7 @@
                             blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                             blink::WebCryptoAlgorithmIdSha256),
                         true,
-                        usage_mask,
+                        usages,
                         &private_key));
     EXPECT_EQ(modulus_length,
               private_key.algorithm().rsaHashedParams()->modulusLengthBits());
@@ -611,7 +611,7 @@
                                      public_exponent);
   EXPECT_EQ(Status::ErrorGenerateRsaUnsupportedModulus(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
 
   // Fail with bad exponent: larger than unsigned long.
   unsigned int exponent_length = sizeof(unsigned long) + 1;  // NOLINT
@@ -623,7 +623,7 @@
                                      long_exponent);
   EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
 
   // Fail with bad exponent: empty.
   const std::vector<uint8_t> empty_exponent;
@@ -634,7 +634,7 @@
                                      empty_exponent);
   EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
 
   // Fail with bad exponent: all zeros.
   std::vector<uint8_t> exponent_with_leading_zeros(15, 0x00);
@@ -645,7 +645,7 @@
                                      exponent_with_leading_zeros);
   EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
 
   // Key generation success using exponent with leading zeros.
   exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(),
@@ -658,15 +658,15 @@
                                      exponent_with_leading_zeros);
   EXPECT_EQ(Status::Success(),
             GenerateKeyPair(
-                algorithm, extractable, usage_mask, &public_key, &private_key));
+                algorithm, extractable, usages, &public_key, &private_key));
   EXPECT_FALSE(public_key.isNull());
   EXPECT_FALSE(private_key.isNull());
   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
   EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
   EXPECT_TRUE(public_key.extractable());
   EXPECT_EQ(extractable, private_key.extractable());
-  EXPECT_EQ(usage_mask, public_key.usages());
-  EXPECT_EQ(usage_mask, private_key.usages());
+  EXPECT_EQ(usages, public_key.usages());
+  EXPECT_EQ(usages, private_key.usages());
 
   // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha1)
   algorithm =
@@ -676,7 +676,7 @@
                                      public_exponent);
   EXPECT_EQ(
       Status::Success(),
-      GenerateKeyPair(algorithm, false, usage_mask, &public_key, &private_key));
+      GenerateKeyPair(algorithm, false, usages, &public_key, &private_key));
   EXPECT_FALSE(public_key.isNull());
   EXPECT_FALSE(private_key.isNull());
   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
@@ -693,8 +693,8 @@
   // extractable.
   EXPECT_TRUE(public_key.extractable());
   EXPECT_FALSE(private_key.extractable());
-  EXPECT_EQ(usage_mask, public_key.usages());
-  EXPECT_EQ(usage_mask, private_key.usages());
+  EXPECT_EQ(usages, public_key.usages());
+  EXPECT_EQ(usages, private_key.usages());
 
   // Exporting a private key as SPKI format doesn't make sense. However this
   // will first fail because the key is not extractable.
@@ -706,7 +706,7 @@
   // This should fail since spki is for public keys.
   EXPECT_EQ(
       Status::Success(),
-      GenerateKeyPair(algorithm, true, usage_mask, &public_key, &private_key));
+      GenerateKeyPair(algorithm, true, usages, &public_key, &private_key));
   EXPECT_EQ(Status::ErrorUnexpectedKeyType(),
             ExportKey(blink::WebCryptoKeyFormatSpki, private_key, &output));
 }
@@ -731,14 +731,13 @@
         modulus_length_bits,
         public_exponent);
     bool extractable = true;
-    const blink::WebCryptoKeyUsageMask usage_mask = 0;
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    const blink::WebCryptoKeyUsageMask usages = 0;
+    blink::WebCryptoKey public_key;
+    blink::WebCryptoKey private_key;
 
-    EXPECT_EQ(
-        Status::ErrorGenerateRsaUnsupportedModulus(),
-        GenerateKeyPair(
-            algorithm, extractable, usage_mask, &public_key, &private_key));
+    EXPECT_EQ(Status::ErrorGenerateRsaUnsupportedModulus(),
+              GenerateKeyPair(
+                  algorithm, extractable, usages, &public_key, &private_key));
   }
 }
 
@@ -763,8 +762,8 @@
         modulus_length,
         HexStringToBytes(kPublicExponents[i]));
 
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
+    blink::WebCryptoKey private_key;
 
     EXPECT_EQ(Status::ErrorGenerateKeyPublicExponent(),
               GenerateKeyPair(algorithm, true, 0, &public_key, &private_key));
@@ -779,8 +778,8 @@
   blink::WebCryptoAlgorithm import_algorithm =
       CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                      blink::WebCryptoAlgorithmIdSha1);
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
   ASSERT_NO_FATAL_FAILURE(
       ImportRsaKeyPair(HexStringToBytes(kPublicKeySpkiDerHex),
                        HexStringToBytes(kPrivateKeyPkcs8DerHex),
@@ -872,7 +871,7 @@
                  CryptoData(data),
                  &signature));
 
-  blink::WebCryptoKey public_key_256 = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key_256;
   EXPECT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatSpki,
                       CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -914,8 +913,8 @@
   blink::WebCryptoAlgorithm import_algorithm =
       CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                      blink::WebCryptoAlgorithmIdSha1);
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
   ASSERT_NO_FATAL_FAILURE(
       ImportRsaKeyPair(HexStringToBytes(kPublicKeySpkiDerHex),
                        HexStringToBytes(kPrivateKeyPkcs8DerHex),
@@ -976,7 +975,7 @@
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               ImportKey(blink::WebCryptoKeyFormatSpki,
                         CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -1009,7 +1008,7 @@
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               ImportKeyJwkFromDict(
                   dict, algorithm, false, bad_usages[i], &public_key));
@@ -1031,8 +1030,8 @@
   for (size_t i = 0; i < arraysize(bad_usages); ++i) {
     SCOPED_TRACE(i);
 
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
+    blink::WebCryptoKey private_key;
 
     ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
               GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
@@ -1054,8 +1053,8 @@
   const unsigned int modulus_length = 256;
   const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
 
-  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
-  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey public_key;
+  blink::WebCryptoKey private_key;
 
   ASSERT_EQ(Status::Success(),
             GenerateKeyPair(
@@ -1112,7 +1111,7 @@
             blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, test.hash);
 
     // Import the spki to create a public key
-    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key;
     ASSERT_EQ(Status::Success(),
               ImportKey(blink::WebCryptoKeyFormatSpki,
                         CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
@@ -1132,7 +1131,7 @@
                                 test.usage));
 
     // Import the JWK back in to create a new key
-    blink::WebCryptoKey public_key2 = blink::WebCryptoKey::createNull();
+    blink::WebCryptoKey public_key2;
     ASSERT_EQ(Status::Success(),
               ImportKey(blink::WebCryptoKeyFormatJwk,
                         CryptoData(jwk),
@@ -1159,8 +1158,8 @@
   blink::WebCryptoAlgorithm algorithm =
       CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
                                      blink::WebCryptoAlgorithmIdSha256);
-  blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageVerify;
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageVerify;
+  blink::WebCryptoKey key;
 
   // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent)
   // entry, while an RSA private key must have those plus at least a "d"
@@ -1170,7 +1169,7 @@
 
   // Baseline pass.
   EXPECT_EQ(Status::Success(),
-            ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+            ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
   EXPECT_EQ(algorithm.id(), key.algorithm().id());
   EXPECT_FALSE(key.extractable());
   EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages());
@@ -1184,19 +1183,19 @@
     // Fail on missing parameter.
     dict.Remove(kKtyParmName[idx], NULL);
     EXPECT_NE(Status::Success(),
-              ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
     RestoreJwkRsaDictionary(&dict);
 
     // Fail on bad b64 parameter encoding.
     dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0");
     EXPECT_NE(Status::Success(),
-              ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
     RestoreJwkRsaDictionary(&dict);
 
     // Fail on empty parameter.
     dict.SetString(kKtyParmName[idx], "");
     EXPECT_EQ(Status::ErrorJwkEmptyBigInteger(kKtyParmName[idx]),
-              ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key));
+              ImportKeyJwkFromDict(dict, algorithm, false, usages, &key));
     RestoreJwkRsaDictionary(&dict);
   }
 }
diff --git a/content/child/webcrypto/test/test_helpers.cc b/content/child/webcrypto/test/test_helpers.cc
index f7dc73c..00af762 100644
--- a/content/child/webcrypto/test/test_helpers.cc
+++ b/content/child/webcrypto/test/test_helpers.cc
@@ -75,7 +75,7 @@
 bool SupportsAesGcm() {
   std::vector<uint8_t> key_raw(16, 0);
 
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   Status status = ImportKey(blink::WebCryptoKeyFormatRaw,
                             CryptoData(key_raw),
                             CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
@@ -344,7 +344,7 @@
     const std::vector<uint8_t>& key_raw,
     const blink::WebCryptoAlgorithm& algorithm,
     blink::WebCryptoKeyUsageMask usage) {
-  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
+  blink::WebCryptoKey key;
   bool extractable = true;
   EXPECT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatRaw,
@@ -367,8 +367,8 @@
                       const std::vector<uint8_t>& pkcs8_der,
                       const blink::WebCryptoAlgorithm& algorithm,
                       bool extractable,
-                      blink::WebCryptoKeyUsageMask public_key_usage_mask,
-                      blink::WebCryptoKeyUsageMask private_key_usage_mask,
+                      blink::WebCryptoKeyUsageMask public_key_usages,
+                      blink::WebCryptoKeyUsageMask private_key_usages,
                       blink::WebCryptoKey* public_key,
                       blink::WebCryptoKey* private_key) {
   ASSERT_EQ(Status::Success(),
@@ -376,40 +376,40 @@
                       CryptoData(spki_der),
                       algorithm,
                       true,
-                      public_key_usage_mask,
+                      public_key_usages,
                       public_key));
   EXPECT_FALSE(public_key->isNull());
   EXPECT_TRUE(public_key->handle());
   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key->type());
   EXPECT_EQ(algorithm.id(), public_key->algorithm().id());
   EXPECT_TRUE(public_key->extractable());
-  EXPECT_EQ(public_key_usage_mask, public_key->usages());
+  EXPECT_EQ(public_key_usages, public_key->usages());
 
   ASSERT_EQ(Status::Success(),
             ImportKey(blink::WebCryptoKeyFormatPkcs8,
                       CryptoData(pkcs8_der),
                       algorithm,
                       extractable,
-                      private_key_usage_mask,
+                      private_key_usages,
                       private_key));
   EXPECT_FALSE(private_key->isNull());
   EXPECT_TRUE(private_key->handle());
   EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type());
   EXPECT_EQ(algorithm.id(), private_key->algorithm().id());
   EXPECT_EQ(extractable, private_key->extractable());
-  EXPECT_EQ(private_key_usage_mask, private_key->usages());
+  EXPECT_EQ(private_key_usages, private_key->usages());
 }
 
 Status ImportKeyJwkFromDict(const base::DictionaryValue& dict,
                             const blink::WebCryptoAlgorithm& algorithm,
                             bool extractable,
-                            blink::WebCryptoKeyUsageMask usage_mask,
+                            blink::WebCryptoKeyUsageMask usages,
                             blink::WebCryptoKey* key) {
   return ImportKey(blink::WebCryptoKeyFormatJwk,
                    CryptoData(MakeJsonVector(dict)),
                    algorithm,
                    extractable,
-                   usage_mask,
+                   usages,
                    key);
 }
 
@@ -601,10 +601,10 @@
 
 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
                          bool extractable,
-                         blink::WebCryptoKeyUsageMask usage_mask,
+                         blink::WebCryptoKeyUsageMask usages,
                          blink::WebCryptoKey* key) {
   GenerateKeyResult result;
-  Status status = GenerateKey(algorithm, extractable, usage_mask, &result);
+  Status status = GenerateKey(algorithm, extractable, usages, &result);
   if (status.IsError())
     return status;
 
@@ -618,11 +618,11 @@
 
 Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
                        bool extractable,
-                       blink::WebCryptoKeyUsageMask usage_mask,
+                       blink::WebCryptoKeyUsageMask usages,
                        blink::WebCryptoKey* public_key,
                        blink::WebCryptoKey* private_key) {
   GenerateKeyResult result;
-  Status status = GenerateKey(algorithm, extractable, usage_mask, &result);
+  Status status = GenerateKey(algorithm, extractable, usages, &result);
   if (status.IsError())
     return status;
 
diff --git a/content/child/webcrypto/test/test_helpers.h b/content/child/webcrypto/test/test_helpers.h
index 0605148..1505f09 100644
--- a/content/child/webcrypto/test/test_helpers.h
+++ b/content/child/webcrypto/test/test_helpers.h
@@ -129,15 +129,15 @@
                       const std::vector<uint8_t>& pkcs8_der,
                       const blink::WebCryptoAlgorithm& algorithm,
                       bool extractable,
-                      blink::WebCryptoKeyUsageMask public_key_usage_mask,
-                      blink::WebCryptoKeyUsageMask private_key_usage_mask,
+                      blink::WebCryptoKeyUsageMask public_key_usages,
+                      blink::WebCryptoKeyUsageMask private_key_usages,
                       blink::WebCryptoKey* public_key,
                       blink::WebCryptoKey* private_key);
 
 Status ImportKeyJwkFromDict(const base::DictionaryValue& dict,
                             const blink::WebCryptoAlgorithm& algorithm,
                             bool extractable,
-                            blink::WebCryptoKeyUsageMask usage_mask,
+                            blink::WebCryptoKeyUsageMask usages,
                             blink::WebCryptoKey* key);
 
 // Parses a vector of JSON into a dictionary.
@@ -179,11 +179,11 @@
 // expectation, then it fails with Status::ErrorUnexpected().
 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
                          bool extractable,
-                         blink::WebCryptoKeyUsageMask usage_mask,
+                         blink::WebCryptoKeyUsageMask usages,
                          blink::WebCryptoKey* key);
 Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
                        bool extractable,
-                       blink::WebCryptoKeyUsageMask usage_mask,
+                       blink::WebCryptoKeyUsageMask usages,
                        blink::WebCryptoKey* public_key,
                        blink::WebCryptoKey* private_key);
 
diff --git a/content/child/webcrypto/webcrypto_impl.cc b/content/child/webcrypto/webcrypto_impl.cc
index 418c0f8..2099a90 100644
--- a/content/child/webcrypto/webcrypto_impl.cc
+++ b/content/child/webcrypto/webcrypto_impl.cc
@@ -211,16 +211,16 @@
 struct GenerateKeyState : public BaseState {
   GenerateKeyState(const blink::WebCryptoAlgorithm& algorithm,
                    bool extractable,
-                   blink::WebCryptoKeyUsageMask usage_mask,
+                   blink::WebCryptoKeyUsageMask usages,
                    const blink::WebCryptoResult& result)
       : BaseState(result),
         algorithm(algorithm),
         extractable(extractable),
-        usage_mask(usage_mask) {}
+        usages(usages) {}
 
   const blink::WebCryptoAlgorithm algorithm;
   const bool extractable;
-  const blink::WebCryptoKeyUsageMask usage_mask;
+  const blink::WebCryptoKeyUsageMask usages;
 
   webcrypto::GenerateKeyResult generate_key_result;
 };
@@ -231,21 +231,20 @@
                  unsigned int key_data_size,
                  const blink::WebCryptoAlgorithm& algorithm,
                  bool extractable,
-                 blink::WebCryptoKeyUsageMask usage_mask,
+                 blink::WebCryptoKeyUsageMask usages,
                  const blink::WebCryptoResult& result)
       : BaseState(result),
         format(format),
         key_data(key_data, key_data + key_data_size),
         algorithm(algorithm),
         extractable(extractable),
-        usage_mask(usage_mask),
-        key(blink::WebCryptoKey::createNull()) {}
+        usages(usages) {}
 
   const blink::WebCryptoKeyFormat format;
   const std::vector<uint8_t> key_data;
   const blink::WebCryptoAlgorithm algorithm;
   const bool extractable;
-  const blink::WebCryptoKeyUsageMask usage_mask;
+  const blink::WebCryptoKeyUsageMask usages;
 
   blink::WebCryptoKey key;
 };
@@ -324,8 +323,7 @@
         unwrap_algorithm(unwrap_algorithm),
         unwrapped_key_algorithm(unwrapped_key_algorithm),
         extractable(extractable),
-        usages(usages),
-        unwrapped_key(blink::WebCryptoKey::createNull()) {}
+        usages(usages) {}
 
   const blink::WebCryptoKeyFormat format;
   const std::vector<uint8_t> wrapped_key;
@@ -405,7 +403,7 @@
     return;
   state->status = webcrypto::GenerateKey(state->algorithm,
                                          state->extractable,
-                                         state->usage_mask,
+                                         state->usages,
                                          &state->generate_key_result);
   state->origin_thread->PostTask(
       FROM_HERE, base::Bind(DoGenerateKeyReply, Passed(&passed_state)));
@@ -423,7 +421,7 @@
                                        webcrypto::CryptoData(state->key_data),
                                        state->algorithm,
                                        state->extractable,
-                                       state->usage_mask,
+                                       state->usages,
                                        &state->key);
   if (state->status.IsSuccess()) {
     DCHECK(state->key.handle());
@@ -593,12 +591,12 @@
 
 void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
                                 bool extractable,
-                                blink::WebCryptoKeyUsageMask usage_mask,
+                                blink::WebCryptoKeyUsageMask usages,
                                 blink::WebCryptoResult result) {
   DCHECK(!algorithm.isNull());
 
   scoped_ptr<GenerateKeyState> state(
-      new GenerateKeyState(algorithm, extractable, usage_mask, result));
+      new GenerateKeyState(algorithm, extractable, usages, result));
   if (!CryptoThreadPool::PostTask(FROM_HERE,
                                   base::Bind(DoGenerateKey, Passed(&state)))) {
     CompleteWithThreadPoolError(&result);
@@ -610,15 +608,10 @@
                               unsigned int key_data_size,
                               const blink::WebCryptoAlgorithm& algorithm,
                               bool extractable,
-                              blink::WebCryptoKeyUsageMask usage_mask,
+                              blink::WebCryptoKeyUsageMask usages,
                               blink::WebCryptoResult result) {
-  scoped_ptr<ImportKeyState> state(new ImportKeyState(format,
-                                                      key_data,
-                                                      key_data_size,
-                                                      algorithm,
-                                                      extractable,
-                                                      usage_mask,
-                                                      result));
+  scoped_ptr<ImportKeyState> state(new ImportKeyState(
+      format, key_data, key_data_size, algorithm, extractable, usages, result));
   if (!CryptoThreadPool::PostTask(FROM_HERE,
                                   base::Bind(DoImportKey, Passed(&state)))) {
     CompleteWithThreadPoolError(&result);
diff --git a/content/child/webcrypto/webcrypto_impl.h b/content/child/webcrypto/webcrypto_impl.h
index 8d5af3d..ce2262b 100644
--- a/content/child/webcrypto/webcrypto_impl.h
+++ b/content/child/webcrypto/webcrypto_impl.h
@@ -41,14 +41,14 @@
                       blink::WebCryptoResult result);
   virtual void generateKey(const blink::WebCryptoAlgorithm& algorithm,
                            bool extractable,
-                           blink::WebCryptoKeyUsageMask usage_mask,
+                           blink::WebCryptoKeyUsageMask usages,
                            blink::WebCryptoResult result);
   virtual void importKey(blink::WebCryptoKeyFormat format,
                          const unsigned char* key_data,
                          unsigned int key_data_size,
                          const blink::WebCryptoAlgorithm& algorithm,
                          bool extractable,
-                         blink::WebCryptoKeyUsageMask usage_mask,
+                         blink::WebCryptoKeyUsageMask usages,
                          blink::WebCryptoResult result);
   virtual void exportKey(blink::WebCryptoKeyFormat format,
                          const blink::WebCryptoKey& key,
diff --git a/content/child/webcrypto/webcrypto_util.cc b/content/child/webcrypto/webcrypto_util.cc
index 6ea78f2..27614d1 100644
--- a/content/child/webcrypto/webcrypto_util.cc
+++ b/content/child/webcrypto/webcrypto_util.cc
@@ -61,12 +61,12 @@
     {"wrapKey", blink::WebCryptoKeyUsageWrapKey},
     {"unwrapKey", blink::WebCryptoKeyUsageUnwrapKey}};
 
-// Modifies the input usage_mask by according to the key_op value.
+// Modifies the input usages by according to the key_op value.
 bool JwkKeyOpToWebCryptoUsage(const std::string& key_op,
-                              blink::WebCryptoKeyUsageMask* usage_mask) {
+                              blink::WebCryptoKeyUsageMask* usages) {
   for (size_t i = 0; i < arraysize(kJwkWebCryptoUsageMap); ++i) {
     if (kJwkWebCryptoUsageMap[i].jwk_key_op == key_op) {
-      *usage_mask |= kJwkWebCryptoUsageMap[i].webcrypto_usage;
+      *usages |= kJwkWebCryptoUsageMap[i].webcrypto_usage;
       return true;
     }
   }
@@ -74,10 +74,9 @@
 }
 
 // Composes a Web Crypto usage mask from an array of JWK key_ops values.
-Status GetWebCryptoUsagesFromJwkKeyOps(
-    const base::ListValue* jwk_key_ops_value,
-    blink::WebCryptoKeyUsageMask* usage_mask) {
-  *usage_mask = 0;
+Status GetWebCryptoUsagesFromJwkKeyOps(const base::ListValue* jwk_key_ops_value,
+                                       blink::WebCryptoKeyUsageMask* usages) {
+  *usages = 0;
   for (size_t i = 0; i < jwk_key_ops_value->GetSize(); ++i) {
     std::string key_op;
     if (!jwk_key_ops_value->GetString(i, &key_op)) {
@@ -85,7 +84,7 @@
           base::StringPrintf("key_ops[%d]", static_cast<int>(i)), "string");
     }
     // Unrecognized key_ops are silently skipped.
-    ignore_result(JwkKeyOpToWebCryptoUsage(key_op, usage_mask));
+    ignore_result(JwkKeyOpToWebCryptoUsage(key_op, usages));
   }
   return Status::Success();
 }
@@ -93,10 +92,10 @@
 // Composes a JWK key_ops List from a Web Crypto usage mask.
 // Note: Caller must assume ownership of returned instance.
 base::ListValue* CreateJwkKeyOpsFromWebCryptoUsages(
-    blink::WebCryptoKeyUsageMask usage_mask) {
+    blink::WebCryptoKeyUsageMask usages) {
   base::ListValue* jwk_key_ops = new base::ListValue();
   for (size_t i = 0; i < arraysize(kJwkWebCryptoUsageMap); ++i) {
-    if (usage_mask & kJwkWebCryptoUsageMap[i].webcrypto_usage)
+    if (usages & kJwkWebCryptoUsageMap[i].webcrypto_usage)
       jwk_key_ops->AppendString(kJwkWebCryptoUsageMap[i].jwk_key_op);
   }
   return jwk_key_ops;
@@ -133,12 +132,6 @@
   return ((key.usages() & usage) != 0);
 }
 
-bool IsAlgorithmRsa(blink::WebCryptoAlgorithmId alg_id) {
-  return alg_id == blink::WebCryptoAlgorithmIdRsaOaep ||
-         alg_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
-         alg_id == blink::WebCryptoAlgorithmIdRsaPss;
-}
-
 // The WebCrypto spec defines the default value for the tag length, as well as
 // the allowed values for tag length.
 Status GetAesGcmTagLengthInBits(const blink::WebCryptoAesGcmParams* params,
diff --git a/content/child/webcrypto/webcrypto_util.h b/content/child/webcrypto/webcrypto_util.h
index cdf44ac..af8c8e9 100644
--- a/content/child/webcrypto/webcrypto_util.h
+++ b/content/child/webcrypto/webcrypto_util.h
@@ -26,7 +26,7 @@
 
 // Composes a JWK key_ops array from a Web Crypto usage mask.
 base::ListValue* CreateJwkKeyOpsFromWebCryptoUsages(
-    blink::WebCryptoKeyUsageMask usage_mask);
+    blink::WebCryptoKeyUsageMask usages);
 
 // Creates a WebCryptoAlgorithm without any parameters.
 CONTENT_EXPORT blink::WebCryptoAlgorithm CreateAlgorithm(
@@ -51,8 +51,6 @@
 bool KeyUsageAllows(const blink::WebCryptoKey& key,
                     const blink::WebCryptoKeyUsage usage);
 
-bool IsAlgorithmRsa(blink::WebCryptoAlgorithmId alg_id);
-
 Status GetAesGcmTagLengthInBits(const blink::WebCryptoAesGcmParams* params,
                                 unsigned int* tag_length_bits);
 
diff --git a/content/common/accessibility_messages.h b/content/common/accessibility_messages.h
index 02af8070..5abf149 100644
--- a/content/common/accessibility_messages.h
+++ b/content/common/accessibility_messages.h
@@ -131,16 +131,32 @@
 // message was processed and it can send addition events.
 IPC_MESSAGE_ROUTED0(AccessibilityMsg_Events_ACK)
 
-// Kill the renderer because we got a fatal error in the accessibility tree.
+// Tell the renderer to reset and send a new accessibility tree from
+// scratch because the browser is out of sync. It passes a sequential
+// reset token. This should be rare, and if we need reset the same renderer
+// too many times we just kill it. After sending a reset, the browser ignores
+// incoming accessibility IPCs until it receives one with the matching reset
+// token. Conversely, it ignores IPCs with a reset token if it was not
+// expecting a reset.
+IPC_MESSAGE_ROUTED1(AccessibilityMsg_Reset,
+                    int /* reset token */);
+
+// Kill the renderer because we got a fatal error in the accessibility tree
+// and we've already reset too many times.
 IPC_MESSAGE_ROUTED0(AccessibilityMsg_FatalError)
 
 // Messages sent from the renderer to the browser.
 
 // Sent to notify the browser about renderer accessibility events.
 // The browser responds with a AccessibilityMsg_Events_ACK.
-IPC_MESSAGE_ROUTED1(
+// The second parameter, reset_token, is set if this IPC was sent in response
+// to a reset request from the browser. When the browser requests a reset,
+// it ignores incoming IPCs until it sees one with the correct reset token.
+// Any other time, it ignores IPCs with a reset token.
+IPC_MESSAGE_ROUTED2(
     AccessibilityHostMsg_Events,
-    std::vector<AccessibilityHostMsg_EventParams>)
+    std::vector<AccessibilityHostMsg_EventParams> /* events */,
+    int /* reset_token */)
 
 // Sent to update the browser of the location of accessibility objects.
 IPC_MESSAGE_ROUTED1(
diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h
index 2c143d96..763bea11 100644
--- a/content/common/content_message_generator.h
+++ b/content/common/content_message_generator.h
@@ -57,7 +57,6 @@
 #include "content/common/screen_orientation_messages.h"
 #include "content/common/service_worker/embedded_worker_messages.h"
 #include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/socket_stream_messages.h"
 #include "content/common/speech_recognition_messages.h"
 #include "content/common/text_input_client_messages.h"
 #include "content/common/utility_messages.h"
diff --git a/content/common/geofencing_messages.h b/content/common/geofencing_messages.h
index 5012be34..152b108e 100644
--- a/content/common/geofencing_messages.h
+++ b/content/common/geofencing_messages.h
@@ -30,20 +30,23 @@
 IPC_STRUCT_TRAITS_END()
 
 // Messages sent from the child process to the browser.
-IPC_MESSAGE_CONTROL4(GeofencingHostMsg_RegisterRegion,
+IPC_MESSAGE_CONTROL5(GeofencingHostMsg_RegisterRegion,
                      int /* thread_id */,
                      int /* request_id */,
                      std::string /* region_id */,
-                     blink::WebCircularGeofencingRegion /* region */)
+                     blink::WebCircularGeofencingRegion /* region */,
+                     int64 /* serviceworker_registration_id */)
 
-IPC_MESSAGE_CONTROL3(GeofencingHostMsg_UnregisterRegion,
+IPC_MESSAGE_CONTROL4(GeofencingHostMsg_UnregisterRegion,
                      int /* thread_id */,
                      int /* request_id */,
-                     std::string /* region_id */)
+                     std::string /* region_id */,
+                     int64 /* serviceworker_registration_id */)
 
-IPC_MESSAGE_CONTROL2(GeofencingHostMsg_GetRegisteredRegions,
+IPC_MESSAGE_CONTROL3(GeofencingHostMsg_GetRegisteredRegions,
                      int /* thread_id */,
-                     int /* request_id */)
+                     int /* request_id */,
+                     int64 /* serviceworker_registration_id */)
 
 // Messages sent from the browser to the child process.
 
diff --git a/content/common/gpu/client/gpu_video_encode_accelerator_host.cc b/content/common/gpu/client/gpu_video_encode_accelerator_host.cc
index c33e2707..026040f 100644
--- a/content/common/gpu/client/gpu_video_encode_accelerator_host.cc
+++ b/content/common/gpu/client/gpu_video_encode_accelerator_host.cc
@@ -74,7 +74,49 @@
   DCHECK(CalledOnValidThread());
   if (!channel_)
     return std::vector<media::VideoEncodeAccelerator::SupportedProfile>();
-  return channel_->gpu_info().video_encode_accelerator_supported_profiles;
+  return ConvertGpuToMediaProfiles(
+      channel_->gpu_info().video_encode_accelerator_supported_profiles);
+}
+
+// Make sure the enum values of media::VideoCodecProfile and
+// gpu::VideoCodecProfile match.
+#define STATIC_ASSERT_ENUM_MATCH(name)                                 \
+  static_assert(                                                       \
+      media::name == static_cast<media::VideoCodecProfile>(gpu::name), \
+      #name " value must match in media and gpu.")
+
+STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_UNKNOWN);
+STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_MIN);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_BASELINE);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_MAIN);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_EXTENDED);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH10PROFILE);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH422PROFILE);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH444PREDICTIVEPROFILE);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_SCALABLEBASELINE);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_SCALABLEHIGH);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_STEREOHIGH);
+STATIC_ASSERT_ENUM_MATCH(H264PROFILE_MULTIVIEWHIGH);
+STATIC_ASSERT_ENUM_MATCH(VP8PROFILE_ANY);
+STATIC_ASSERT_ENUM_MATCH(VP9PROFILE_ANY);
+STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_MAX);
+
+std::vector<media::VideoEncodeAccelerator::SupportedProfile>
+GpuVideoEncodeAcceleratorHost::ConvertGpuToMediaProfiles(const std::vector<
+    gpu::VideoEncodeAcceleratorSupportedProfile>& gpu_profiles) {
+  std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles;
+  for (size_t i = 0; i < gpu_profiles.size(); i++) {
+    media::VideoEncodeAccelerator::SupportedProfile profile;
+    profile.profile =
+        static_cast<media::VideoCodecProfile>(gpu_profiles[i].profile);
+    profile.max_resolution = gpu_profiles[i].max_resolution;
+    profile.max_framerate_numerator = gpu_profiles[i].max_framerate_numerator;
+    profile.max_framerate_denominator =
+        gpu_profiles[i].max_framerate_denominator;
+    profiles.push_back(profile);
+  }
+  return profiles;
 }
 
 bool GpuVideoEncodeAcceleratorHost::Initialize(
diff --git a/content/common/gpu/client/gpu_video_encode_accelerator_host.h b/content/common/gpu/client/gpu_video_encode_accelerator_host.h
index f4121ae..021eff4 100644
--- a/content/common/gpu/client/gpu_video_encode_accelerator_host.h
+++ b/content/common/gpu/client/gpu_video_encode_accelerator_host.h
@@ -12,6 +12,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/threading/non_thread_safe.h"
 #include "content/common/gpu/client/command_buffer_proxy_impl.h"
+#include "gpu/config/gpu_info.h"
 #include "ipc/ipc_listener.h"
 #include "media/video/video_encode_accelerator.h"
 
@@ -44,6 +45,10 @@
   GpuVideoEncodeAcceleratorHost(GpuChannelHost* channel,
                                 CommandBufferProxyImpl* impl);
 
+  static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
+  ConvertGpuToMediaProfiles(const std::vector<
+      gpu::VideoEncodeAcceleratorSupportedProfile>& gpu_profiles);
+
   // IPC::Listener implementation.
   bool OnMessageReceived(const IPC::Message& message) override;
   void OnChannelError() override;
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index b1d1497..1a8cc170 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -857,8 +857,6 @@
 void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) {
   DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point);
   sync_points_.pop_front();
-  if (context_group_->mailbox_manager()->UsesSync() && MakeCurrent())
-    context_group_->mailbox_manager()->PushTextureUpdates();
   GpuChannelManager* manager = channel_->gpu_channel_manager();
   manager->sync_point_manager()->RetireSyncPoint(sync_point);
 }
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index 3e25302..075f248 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -64,6 +64,9 @@
 IPC_ENUM_TRAITS_MIN_MAX_VALUE(gpu::CollectInfoResult,
                               gpu::kCollectInfoNone,
                               gpu::kCollectInfoFatalFailure)
+IPC_ENUM_TRAITS_MIN_MAX_VALUE(gpu::VideoCodecProfile,
+                              gpu::VIDEO_CODEC_PROFILE_MIN,
+                              gpu::VIDEO_CODEC_PROFILE_MAX)
 
 IPC_STRUCT_BEGIN(GPUCreateCommandBufferConfig)
   IPC_STRUCT_MEMBER(int32, share_group_id)
@@ -138,7 +141,7 @@
   IPC_STRUCT_TRAITS_MEMBER(device_string)
 IPC_STRUCT_TRAITS_END()
 
-IPC_STRUCT_TRAITS_BEGIN(media::VideoEncodeAccelerator::SupportedProfile)
+IPC_STRUCT_TRAITS_BEGIN(gpu::VideoEncodeAcceleratorSupportedProfile)
   IPC_STRUCT_TRAITS_MEMBER(profile)
   IPC_STRUCT_TRAITS_MEMBER(max_resolution)
   IPC_STRUCT_TRAITS_MEMBER(max_framerate_numerator)
@@ -197,6 +200,8 @@
   IPC_STRUCT_TRAITS_MEMBER(sync_query)
   IPC_STRUCT_TRAITS_MEMBER(image)
   IPC_STRUCT_TRAITS_MEMBER(blend_minmax)
+  IPC_STRUCT_TRAITS_MEMBER(blend_equation_advanced)
+  IPC_STRUCT_TRAITS_MEMBER(blend_equation_advanced_coherent)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(content::GPUVideoMemoryUsageStats::ProcessStats)
diff --git a/content/common/gpu/media/android_video_encode_accelerator.cc b/content/common/gpu/media/android_video_encode_accelerator.cc
index 2507ea4..9b703d70 100644
--- a/content/common/gpu/media/android_video_encode_accelerator.cc
+++ b/content/common/gpu/media/android_video_encode_accelerator.cc
@@ -4,6 +4,8 @@
 
 #include "content/common/gpu/media/android_video_encode_accelerator.h"
 
+#include <set>
+
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/logging.h"
@@ -26,8 +28,9 @@
 
 namespace content {
 
-enum {
+enum PixelFormat {
   // Subset of MediaCodecInfo.CodecCapabilities.
+  COLOR_FORMAT_YUV420_PLANAR = 19,
   COLOR_FORMAT_YUV420_SEMIPLANAR = 21,
 };
 
@@ -67,6 +70,19 @@
   return base::TimeDelta::FromMicroseconds(0);
 }
 
+static bool GetSupportedColorFormatForMime(const std::string& mime,
+                                           PixelFormat* pixel_format) {
+  std::set<int> formats = MediaCodecBridge::GetEncoderColorFormats(mime);
+  if (formats.count(COLOR_FORMAT_YUV420_SEMIPLANAR) > 0)
+    *pixel_format = COLOR_FORMAT_YUV420_SEMIPLANAR;
+  else if (formats.count(COLOR_FORMAT_YUV420_PLANAR) > 0)
+    *pixel_format = COLOR_FORMAT_YUV420_PLANAR;
+  else
+    return false;
+
+  return true;
+}
+
 AndroidVideoEncodeAccelerator::AndroidVideoEncodeAccelerator()
     : num_buffers_at_codec_(0),
       num_output_buffers_(-1),
@@ -142,17 +158,17 @@
     return false;
   }
 
-  // TODO(fischman): when there is more HW out there with different color-space
-  // support, this should turn into a negotiation with the codec for supported
-  // formats.  For now we use the only format supported by the only available
-  // HW.
-  media_codec_.reset(
-      media::VideoCodecBridge::CreateEncoder(media::kCodecVP8,
-                                             input_visible_size,
-                                             initial_bitrate,
-                                             INITIAL_FRAMERATE,
-                                             IFRAME_INTERVAL,
-                                             COLOR_FORMAT_YUV420_SEMIPLANAR));
+  PixelFormat pixel_format = COLOR_FORMAT_YUV420_SEMIPLANAR;
+  if (!GetSupportedColorFormatForMime("video/x-vnd.on2.vp8", &pixel_format)) {
+    DLOG(ERROR) << "No color format support.";
+    return false;
+  }
+  media_codec_.reset(media::VideoCodecBridge::CreateEncoder(media::kCodecVP8,
+                                                            input_visible_size,
+                                                            initial_bitrate,
+                                                            INITIAL_FRAMERATE,
+                                                            IFRAME_INTERVAL,
+                                                            pixel_format));
 
   if (!media_codec_) {
     DLOG(ERROR) << "Failed to create/start the codec: "
diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.cc b/content/common/gpu/media/gpu_video_encode_accelerator.cc
index 1f4c395cb..12b473fcc 100644
--- a/content/common/gpu/media/gpu_video_encode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_encode_accelerator.cc
@@ -163,18 +163,29 @@
 }
 
 // static
-std::vector<media::VideoEncodeAccelerator::SupportedProfile>
+std::vector<gpu::VideoEncodeAcceleratorSupportedProfile>
 GpuVideoEncodeAccelerator::GetSupportedProfiles() {
-#if defined(OS_CHROMEOS) && defined(USE_X11) && defined(ARCH_CPU_ARMEL)
-  // This is a work-around for M39 because the video device is not ready at
-  // boot.
-  // TODO(wuchengli): remove this after http://crbug.com/418762 is fixed.
-  return V4L2VideoEncodeAccelerator::GetSupportedProfilesStatic();
-#endif
   scoped_ptr<media::VideoEncodeAccelerator> encoder = CreateEncoder();
   if (!encoder)
-    return std::vector<media::VideoEncodeAccelerator::SupportedProfile>();
-  return encoder->GetSupportedProfiles();
+    return std::vector<gpu::VideoEncodeAcceleratorSupportedProfile>();
+  return ConvertMediaToGpuProfiles(encoder->GetSupportedProfiles());
+}
+
+std::vector<gpu::VideoEncodeAcceleratorSupportedProfile>
+GpuVideoEncodeAccelerator::ConvertMediaToGpuProfiles(const std::vector<
+    media::VideoEncodeAccelerator::SupportedProfile>& media_profiles) {
+  std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> profiles;
+  for (size_t i = 0; i < media_profiles.size(); i++) {
+    gpu::VideoEncodeAcceleratorSupportedProfile profile;
+    profile.profile =
+        static_cast<gpu::VideoCodecProfile>(media_profiles[i].profile);
+    profile.max_resolution = media_profiles[i].max_resolution;
+    profile.max_framerate_numerator = media_profiles[i].max_framerate_numerator;
+    profile.max_framerate_denominator =
+        media_profiles[i].max_framerate_denominator;
+    profiles.push_back(profile);
+  }
+  return profiles;
 }
 
 scoped_ptr<media::VideoEncodeAccelerator>
diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.h b/content/common/gpu/media/gpu_video_encode_accelerator.h
index 6f37abb2..ca60f6f 100644
--- a/content/common/gpu/media/gpu_video_encode_accelerator.h
+++ b/content/common/gpu/media/gpu_video_encode_accelerator.h
@@ -10,6 +10,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/common/gpu/gpu_command_buffer_stub.h"
+#include "gpu/config/gpu_info.h"
 #include "ipc/ipc_listener.h"
 #include "media/video/video_encode_accelerator.h"
 #include "ui/gfx/size.h"
@@ -58,8 +59,11 @@
 
   // Static query for supported profiles.  This query calls the appropriate
   // platform-specific version.
-  static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
-      GetSupportedProfiles();
+  static std::vector<gpu::VideoEncodeAcceleratorSupportedProfile>
+  GetSupportedProfiles();
+  static std::vector<gpu::VideoEncodeAcceleratorSupportedProfile>
+  ConvertMediaToGpuProfiles(const std::vector<
+      media::VideoEncodeAccelerator::SupportedProfile>& media_profiles);
 
  private:
   // Create the appropriate platform-specific VEA.
diff --git a/content/common/gpu/media/rendering_helper.cc b/content/common/gpu/media/rendering_helper.cc
index 37e7d92..5870cee 100644
--- a/content/common/gpu/media/rendering_helper.cc
+++ b/content/common/gpu/media/rendering_helper.cc
@@ -78,7 +78,7 @@
 }
 
 RenderingHelper::RenderedVideo::RenderedVideo()
-    : last_frame_rendered(false), is_flushing(false), frames_to_drop(0) {
+    : is_flushing(false), frames_to_drop(0) {
 }
 
 RenderingHelper::RenderedVideo::~RenderedVideo() {
@@ -307,7 +307,11 @@
   if (frame_duration_ != base::TimeDelta())
     WarmUpRendering(params.warm_up_iterations);
 
-  done->Signal();
+  // It's safe to use Unretained here since |rendering_thread_| will be stopped
+  // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is
+  // a member of that class. (See video_decode_accelerator_unittest.cc.)
+  gl_surface_->GetVSyncProvider()->GetVSyncParameters(base::Bind(
+      &RenderingHelper::UpdateVSyncParameters, base::Unretained(this), done));
 }
 
 // The rendering for the first few frames is slow (e.g., 100ms on Peach Pit).
@@ -425,28 +429,18 @@
   RenderedVideo* video = &videos_[window_id];
   DCHECK(!video->is_flushing);
 
-  // Start the rendering task when getting the first frame.
-  if (scheduled_render_time_.is_null() &&
-      (frame_duration_ != base::TimeDelta())) {
+  video->pending_frames.push(video_frame);
+
+  if (video->frames_to_drop > 0 && video->pending_frames.size() > 1) {
+    --video->frames_to_drop;
+    video->pending_frames.pop();
+  }
+
+  // Schedules the first RenderContent() if need.
+  if (scheduled_render_time_.is_null()) {
     scheduled_render_time_ = base::TimeTicks::Now();
     message_loop_->PostTask(FROM_HERE, render_task_.callback());
   }
-
-  if (video->frames_to_drop > 0) {
-    --video->frames_to_drop;
-    return;
-  }
-
-  // Pop the last frame if it has been rendered.
-  if (video->last_frame_rendered) {
-    // When last_frame_rendered is true, we should have only one pending frame.
-    // Since we are going to have a new frame, we can release the pending one.
-    DCHECK(video->pending_frames.size() == 1);
-    video->pending_frames.pop();
-    video->last_frame_rendered = false;
-  }
-
-  video->pending_frames.push(video_frame);
 }
 
 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) {
@@ -544,10 +538,15 @@
 void RenderingHelper::RenderContent() {
   CHECK_EQ(base::MessageLoop::current(), message_loop_);
 
-  scheduled_render_time_ += frame_duration_;
-  base::TimeDelta delay = scheduled_render_time_ - base::TimeTicks::Now();
-  message_loop_->PostDelayedTask(
-      FROM_HERE, render_task_.callback(), std::max(delay, base::TimeDelta()));
+  // Update the VSync params.
+  //
+  // It's safe to use Unretained here since |rendering_thread_| will be stopped
+  // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is
+  // a member of that class. (See video_decode_accelerator_unittest.cc.)
+  gl_surface_->GetVSyncProvider()->GetVSyncParameters(
+      base::Bind(&RenderingHelper::UpdateVSyncParameters,
+                 base::Unretained(this),
+                 static_cast<base::WaitableEvent*>(NULL)));
 
   glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
 
@@ -555,35 +554,35 @@
   // after this vector falls out of scope at the end of this method. We need
   // to keep references to them until after SwapBuffers() call below.
   std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned;
-
+  bool need_swap_buffer = false;
   if (render_as_thumbnails_) {
     // In render_as_thumbnails_ mode, we render the FBO content on the
     // screen instead of the decoded textures.
     GLSetViewPort(videos_[0].render_area);
     RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_);
+    need_swap_buffer = true;
   } else {
-    for (size_t i = 0; i < videos_.size(); ++i) {
-      RenderedVideo* video = &videos_[i];
-      if (video->pending_frames.empty())
+    for (RenderedVideo& video : videos_) {
+      if (video.pending_frames.empty())
         continue;
-      scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front();
-      GLSetViewPort(video->render_area);
+      need_swap_buffer = true;
+      scoped_refptr<VideoFrameTexture> frame = video.pending_frames.front();
+      GLSetViewPort(video.render_area);
       RenderTexture(frame->texture_target(), frame->texture_id());
 
-      if (video->last_frame_rendered)
-        ++video->frames_to_drop;
-
-      if (video->pending_frames.size() > 1 || video->is_flushing) {
-        frames_to_be_returned.push_back(video->pending_frames.front());
-        video->pending_frames.pop();
-        video->last_frame_rendered = false;
+      if (video.pending_frames.size() > 1 || video.is_flushing) {
+        frames_to_be_returned.push_back(video.pending_frames.front());
+        video.pending_frames.pop();
       } else {
-        video->last_frame_rendered = true;
+        ++video.frames_to_drop;
       }
     }
   }
 
-  gl_surface_->SwapBuffers();
+  if (need_swap_buffer)
+    gl_surface_->SwapBuffers();
+
+  ScheduleNextRenderContent();
 }
 
 // Helper function for the LayoutRenderingAreas(). The |lengths| are the
@@ -639,4 +638,49 @@
     videos_[i].render_area = gfx::Rect(x, y, w, h);
   }
 }
+
+void RenderingHelper::UpdateVSyncParameters(base::WaitableEvent* done,
+                                            const base::TimeTicks timebase,
+                                            const base::TimeDelta interval) {
+  vsync_timebase_ = timebase;
+  vsync_interval_ = interval;
+
+  if (done)
+    done->Signal();
+}
+
+void RenderingHelper::DropOneFrameForAllVideos() {
+  for (RenderedVideo& video : videos_) {
+    if (video.pending_frames.empty())
+      continue;
+
+    if (video.pending_frames.size() > 1 || video.is_flushing) {
+      video.pending_frames.pop();
+    } else {
+      ++video.frames_to_drop;
+    }
+  }
+}
+
+void RenderingHelper::ScheduleNextRenderContent() {
+  scheduled_render_time_ += frame_duration_;
+
+  // Schedules the next RenderContent() at latest VSYNC before the
+  // |scheduled_render_time_|.
+  base::TimeTicks now = base::TimeTicks::Now();
+  base::TimeTicks target =
+      std::max(now + vsync_interval_, scheduled_render_time_);
+
+  int64 intervals = (target - vsync_timebase_) / vsync_interval_;
+  target = vsync_timebase_ + intervals * vsync_interval_;
+
+  // When the rendering falls behind, drops frames.
+  while (scheduled_render_time_ < target) {
+    scheduled_render_time_ += frame_duration_;
+    DropOneFrameForAllVideos();
+  }
+
+  message_loop_->PostDelayedTask(
+      FROM_HERE, render_task_.callback(), target - now);
+}
 }  // namespace content
diff --git a/content/common/gpu/media/rendering_helper.h b/content/common/gpu/media/rendering_helper.h
index ce7f4e19..b080f681 100644
--- a/content/common/gpu/media/rendering_helper.h
+++ b/content/common/gpu/media/rendering_helper.h
@@ -129,17 +129,14 @@
     // The rect on the screen where the video will be rendered.
     gfx::Rect render_area;
 
-    // True if the last (and the only one) frame in pending_frames has
-    // been rendered. We keep the last remaining frame in pending_frames even
-    // after it has been rendered, so that we have something to display if the
-    // client is falling behind on providing us with new frames during
-    // timer-driven playback.
-    bool last_frame_rendered;
-
     // True if there won't be any new video frames comming.
     bool is_flushing;
 
-    // The number of frames need to be dropped to catch up the rendering.
+    // The number of frames need to be dropped to catch up the rendering. We
+    // always keep the last remaining frame in pending_frames even after it
+    // has been rendered, so that we have something to display if the client
+    // is falling behind on providing us with new frames during timer-driven
+    // playback.
     int frames_to_drop;
 
     // The video frames pending for rendering.
@@ -157,6 +154,13 @@
 
   void LayoutRenderingAreas(const std::vector<gfx::Size>& window_sizes);
 
+  void UpdateVSyncParameters(base::WaitableEvent* done,
+                             const base::TimeTicks timebase,
+                             const base::TimeDelta interval);
+
+  void DropOneFrameForAllVideos();
+  void ScheduleNextRenderContent();
+
   // Render |texture_id| to the current view port of the screen using target
   // |texture_target|.
   void RenderTexture(uint32 texture_target, uint32 texture_id);
@@ -182,6 +186,8 @@
   base::TimeDelta frame_duration_;
   base::TimeTicks scheduled_render_time_;
   base::CancelableClosure render_task_;
+  base::TimeTicks vsync_timebase_;
+  base::TimeDelta vsync_interval_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderingHelper);
 };
diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.cc b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
index 12f88d03..d69c97da 100644
--- a/content/common/gpu/media/v4l2_video_encode_accelerator.cc
+++ b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
@@ -282,11 +282,6 @@
 
 std::vector<media::VideoEncodeAccelerator::SupportedProfile>
 V4L2VideoEncodeAccelerator::GetSupportedProfiles() {
-  return GetSupportedProfilesStatic();
-}
-
-std::vector<media::VideoEncodeAccelerator::SupportedProfile>
-V4L2VideoEncodeAccelerator::GetSupportedProfilesStatic() {
   std::vector<SupportedProfile> profiles;
   SupportedProfile profile;
 
diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.h b/content/common/gpu/media/v4l2_video_encode_accelerator.h
index 900eb6b..267d0d0 100644
--- a/content/common/gpu/media/v4l2_video_encode_accelerator.h
+++ b/content/common/gpu/media/v4l2_video_encode_accelerator.h
@@ -45,9 +45,6 @@
   explicit V4L2VideoEncodeAccelerator(scoped_ptr<V4L2Device> device);
   virtual ~V4L2VideoEncodeAccelerator();
 
-  static std::vector<media::VideoEncodeAccelerator::SupportedProfile>
-      GetSupportedProfilesStatic();
-
   // media::VideoEncodeAccelerator implementation.
   virtual std::vector<media::VideoEncodeAccelerator::SupportedProfile>
       GetSupportedProfiles() override;
diff --git a/content/common/media/midi_messages.h b/content/common/media/midi_messages.h
index da131397..388d518e 100644
--- a/content/common/media/midi_messages.h
+++ b/content/common/media/midi_messages.h
@@ -43,21 +43,25 @@
 // Messages for IPC between MidiMessageFilter and MidiHost.
 
 // Renderer request to browser for access to MIDI services.
-IPC_MESSAGE_CONTROL1(MidiHostMsg_StartSession,
-                     int /* client id */)
+IPC_MESSAGE_CONTROL0(MidiHostMsg_StartSession)
 
 IPC_MESSAGE_CONTROL3(MidiHostMsg_SendData,
                      uint32 /* port */,
                      std::vector<uint8> /* data */,
                      double /* timestamp */)
 
+IPC_MESSAGE_CONTROL0(MidiHostMsg_EndSession)
+
 // Messages sent from the browser to the renderer.
 
-IPC_MESSAGE_CONTROL4(MidiMsg_SessionStarted,
-                     int /* client id */,
-                     media::MidiResult /* result */,
-                     media::MidiPortInfoList /* input ports */,
-                     media::MidiPortInfoList /* output ports */)
+IPC_MESSAGE_CONTROL1(MidiMsg_AddInputPort,
+                     media::MidiPortInfo /* input port */)
+
+IPC_MESSAGE_CONTROL1(MidiMsg_AddOutputPort,
+                     media::MidiPortInfo /* output port */)
+
+IPC_MESSAGE_CONTROL1(MidiMsg_SessionStarted,
+                     media::MidiResult /* result */)
 
 IPC_MESSAGE_CONTROL3(MidiMsg_DataReceived,
                      uint32 /* port */,
diff --git a/content/common/sandbox_linux/sandbox_linux.cc b/content/common/sandbox_linux/sandbox_linux.cc
index 7c7c856..12e11d8 100644
--- a/content/common/sandbox_linux/sandbox_linux.cc
+++ b/content/common/sandbox_linux/sandbox_linux.cc
@@ -18,6 +18,7 @@
 #include "base/debug/stack_trace.h"
 #include "base/files/scoped_file.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/singleton.h"
 #include "base/posix/eintr_wrapper.h"
@@ -34,8 +35,7 @@
 #include "sandbox/linux/services/yama.h"
 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
 
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
-     defined(LEAK_SANITIZER) || defined(UNDEFINED_SANITIZER)
+#if defined(ANY_OF_AMTLU_SANITIZER)
 #include <sanitizer/common_interface_defs.h>
 #endif
 
@@ -62,7 +62,6 @@
   VLOG(1) << activated_sandbox;
 }
 
-#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
 bool AddResourceLimit(int resource, rlim_t limit) {
   struct rlimit old_rlimit;
   if (getrlimit(resource, &old_rlimit))
@@ -75,7 +74,6 @@
   int rc = setrlimit(resource, &new_rlimit);
   return rc == 0;
 }
-#endif
 
 bool IsRunningTSAN() {
 #if defined(THREAD_SANITIZER)
@@ -116,8 +114,7 @@
   if (setuid_sandbox_client_ == NULL) {
     LOG(FATAL) << "Failed to instantiate the setuid sandbox client.";
   }
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
-     defined(LEAK_SANITIZER) || defined(UNDEFINED_SANITIZER)
+#if defined(ANY_OF_AMTLU_SANITIZER)
   sanitizer_args_ = make_scoped_ptr(new __sanitizer_sandbox_arguments);
   *sanitizer_args_ = {0};
 #endif
@@ -135,8 +132,7 @@
 void LinuxSandbox::PreinitializeSandbox() {
   CHECK(!pre_initialized_);
   seccomp_bpf_supported_ = false;
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
-    defined(LEAK_SANITIZER) || defined(UNDEFINED_SANITIZER)
+#if defined(ANY_OF_AMTLU_SANITIZER)
   // Sanitizers need to open some resources before the sandbox is enabled.
   // This should not fork, not launch threads, not open a directory.
   __sanitizer_sandbox_on_notify(sanitizer_args());
@@ -335,7 +331,8 @@
 
 bool LinuxSandbox::LimitAddressSpace(const std::string& process_type) {
   (void) process_type;
-#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
+#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
+    !defined(THREAD_SANITIZER)
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kNoSandbox)) {
     return false;
@@ -372,9 +369,13 @@
 
   return limited_as && limited_data;
 #else
+  // Silence the compiler warning about unused function. This doesn't actually
+  // call AddResourceLimit().
+  ignore_result(AddResourceLimit);
   base::SysInfo::AmountOfVirtualMemory();
   return false;
-#endif  // !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER)
+#endif  // !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) &&
+        // !defined(THREAD_SANITIZER)
 }
 
 bool LinuxSandbox::HasOpenDirectories() const {
diff --git a/content/common/sandbox_linux/sandbox_linux.h b/content/common/sandbox_linux/sandbox_linux.h
index 04f0748..a5a23227 100644
--- a/content/common/sandbox_linux/sandbox_linux.h
+++ b/content/common/sandbox_linux/sandbox_linux.h
@@ -12,8 +12,10 @@
 #include "content/public/common/sandbox_linux.h"
 
 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
-    defined(LEAK_SANITIZER) || defined(UNDEFINED_SANITIZER)
+    defined(THREAD_SANITIZER) || defined(LEAK_SANITIZER) || \
+    defined(UNDEFINED_SANITIZER)
 #include <sanitizer/common_interface_defs.h>
+#define ANY_OF_AMTLU_SANITIZER 1
 #endif
 
 template <typename T> struct DefaultSingletonTraits;
@@ -87,8 +89,7 @@
   // to make some vulnerabilities harder to exploit.
   bool LimitAddressSpace(const std::string& process_type);
 
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
-    defined(LEAK_SANITIZER) || defined(UNDEFINED_SANITIZER)
+#if defined(ANY_OF_AMTLU_SANITIZER)
   __sanitizer_sandbox_arguments* sanitizer_args() const {
     return sanitizer_args_.get();
   };
@@ -132,8 +133,7 @@
   bool seccomp_bpf_supported_;  // Accurate if pre_initialized_.
   bool yama_is_enforcing_;  // Accurate if pre_initialized_.
   scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client_;
-#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
-    defined(LEAK_SANITIZER) || defined(UNDEFINED_SANITIZER)
+#if defined(ANY_OF_AMTLU_SANITIZER)
   scoped_ptr<__sanitizer_sandbox_arguments> sanitizer_args_;
 #endif
 
diff --git a/content/common/sandbox_mac.mm b/content/common/sandbox_mac.mm
index 9ef3e1c..118919f 100644
--- a/content/common/sandbox_mac.mm
+++ b/content/common/sandbox_mac.mm
@@ -38,6 +38,11 @@
 #include "ui/base/layout.h"
 #include "ui/gl/gl_surface.h"
 
+extern "C" {
+void CGSSetDenyWindowServerConnections(bool);
+void CGSShutdownServerConnections();
+};
+
 namespace content {
 namespace {
 
@@ -268,8 +273,8 @@
         kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
 
     // Load in the color profiles we'll need (as a side effect).
-    (void) base::mac::GetSRGBColorSpace();
-    (void) base::mac::GetSystemColorSpace();
+    ignore_result(base::mac::GetSRGBColorSpace());
+    ignore_result(base::mac::GetSystemColorSpace());
 
     // CGColorSpaceCreateSystemDefaultCMYK - 10.6
     base::ScopedCFTypeRef<CGColorSpaceRef> cmyk_colorspace(
@@ -325,6 +330,18 @@
     NSColor* color = [NSColor controlTextColor];
     [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
   }
+
+  if (sandbox_type == SANDBOX_TYPE_RENDERER &&
+      base::mac::IsOSMountainLionOrLater()) {
+    // Now disconnect from WindowServer, after all objects have been warmed up.
+    // Shutting down the connection requires connecting to WindowServer,
+    // so do this before actually engaging the sandbox. This is only done on
+    // 10.8 and higher because doing it on earlier OSes causes layout tests to
+    // fail <http://crbug.com/397642#c48>. This may cause two log messages to
+    // be printed to the system logger on certain OS versions.
+    CGSSetDenyWindowServerConnections(true);
+    CGSShutdownServerConnections();
+  }
 }
 
 // static
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h
index 3857592..6b7b090 100644
--- a/content/common/service_worker/service_worker_messages.h
+++ b/content/common/service_worker/service_worker_messages.h
@@ -88,6 +88,7 @@
 IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerRegistrationObjectInfo)
   IPC_STRUCT_TRAITS_MEMBER(handle_id)
   IPC_STRUCT_TRAITS_MEMBER(scope)
+  IPC_STRUCT_TRAITS_MEMBER(registration_id)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerVersionAttributes)
diff --git a/content/common/service_worker/service_worker_types.cc b/content/common/service_worker/service_worker_types.cc
index 3c2b6043..d7c17851 100644
--- a/content/common/service_worker/service_worker_types.cc
+++ b/content/common/service_worker/service_worker_types.cc
@@ -73,6 +73,8 @@
       state(blink::WebServiceWorkerStateUnknown) {}
 
 ServiceWorkerRegistrationObjectInfo::ServiceWorkerRegistrationObjectInfo()
-    : handle_id(kInvalidServiceWorkerRegistrationHandleId) {}
+    : handle_id(kInvalidServiceWorkerRegistrationHandleId),
+      registration_id(kInvalidServiceWorkerRegistrationId) {
+}
 
 }  // namespace content
diff --git a/content/common/service_worker/service_worker_types.h b/content/common/service_worker/service_worker_types.h
index 36ad372..9fa5bc0 100644
--- a/content/common/service_worker/service_worker_types.h
+++ b/content/common/service_worker/service_worker_types.h
@@ -156,6 +156,7 @@
   ServiceWorkerRegistrationObjectInfo();
   int handle_id;
   GURL scope;
+  int64 registration_id;
 };
 
 struct ServiceWorkerVersionAttributes {
diff --git a/content/common/socket_stream.h b/content/common/socket_stream.h
deleted file mode 100644
index 3bce134..0000000
--- a/content/common/socket_stream.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012 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_COMMON_SOCKET_STREAM_H_
-#define CONTENT_COMMON_SOCKET_STREAM_H_
-
-namespace content {
-
-const int kNoSocketId = 0;
-
-}  // namespace content
-
-#endif  // CONTENT_COMMON_SOCKET_STREAM_H_
diff --git a/content/common/socket_stream_handle_data.h b/content/common/socket_stream_handle_data.h
deleted file mode 100644
index ad24178..0000000
--- a/content/common/socket_stream_handle_data.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012 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_SOCKET_STREAM_HANDLE_DATA_H_
-#define CONTENT_RENDERER_SOCKET_STREAM_HANDLE_DATA_H_
-
-#include "base/supports_user_data.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// User data stored in each WebSocketStreamHandleImpl.
-class SocketStreamHandleData : public base::SupportsUserData::Data {
- public:
-  explicit SocketStreamHandleData(int render_frame_id)
-      : render_frame_id_(render_frame_id) {}
-  ~SocketStreamHandleData() override {}
-
-  int render_frame_id() const { return render_frame_id_; }
-
- private:
-  int render_frame_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(SocketStreamHandleData);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_SOCKET_STREAM_HANDLE_DATA_H_
diff --git a/content/common/socket_stream_messages.h b/content/common/socket_stream_messages.h
deleted file mode 100644
index 6e24a157..0000000
--- a/content/common/socket_stream_messages.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Multiply-included message file, hence no include guard.
-#include <vector>
-
-#include "content/common/content_export.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_param_traits.h"
-#include "url/gurl.h"
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-#define IPC_MESSAGE_START SocketStreamMsgStart
-
-// Web Sockets messages sent from the renderer to the browser.
-
-// Open new Socket Stream for the |socket_url| identified by |socket_id|
-// in the renderer process.
-// The browser starts connecting asynchronously.
-// Once Socket Stream connection is established, the browser will send
-// SocketStreamMsg_Connected back.
-// |render_frame_id| must be the routing id of RenderFrameImpl to which the
-// Socket Stream belongs.
-IPC_MESSAGE_CONTROL3(SocketStreamHostMsg_Connect,
-                     int /* render_frame_id */,
-                     GURL /* socket_url */,
-                     int /* socket_id */)
-
-// Request to send data on the Socket Stream.
-// SocketStreamHandle can send data at most |max_pending_send_allowed| bytes,
-// which is given by ViewMsg_SocketStream_Connected at any time.
-// The number of pending bytes can be tracked by size of |data| sent
-// and |amount_sent| parameter of ViewMsg_SocketStream_DataSent.
-// That is, the following constraints is applied:
-//  (accumulated total of |data|) - (accumulated total of |amount_sent|)
-// <= |max_pending_send_allowed|
-// If the SocketStreamHandle ever tries to exceed the
-// |max_pending_send_allowed|, the connection will be closed.
-IPC_MESSAGE_CONTROL2(SocketStreamHostMsg_SendData,
-                     int /* socket_id */,
-                     std::vector<char> /* data */)
-
-// Request to close the Socket Stream.
-// The browser will send ViewMsg_SocketStream_Closed back when the Socket
-// Stream is completely closed.
-IPC_MESSAGE_CONTROL1(SocketStreamHostMsg_Close,
-                     int /* socket_id */)
-
-
-// Speech input messages sent from the browser to the renderer.
-
-// A |socket_id| is assigned by SocketStreamHostMsg_Connect.
-// The Socket Stream is connected. The SocketStreamHandle should keep track
-// of how much it has pending (how much it has requested to be sent) and
-// shouldn't go over |max_pending_send_allowed| bytes.
-IPC_MESSAGE_CONTROL2(SocketStreamMsg_Connected,
-                     int /* socket_id */,
-                     int /* max_pending_send_allowed */)
-
-// |data| is received on the Socket Stream.
-IPC_MESSAGE_CONTROL2(SocketStreamMsg_ReceivedData,
-                     int /* socket_id */,
-                     std::vector<char> /* data */)
-
-// |amount_sent| bytes of data requested by
-// SocketStreamHostMsg_SendData has been sent on the Socket Stream.
-IPC_MESSAGE_CONTROL2(SocketStreamMsg_SentData,
-                     int /* socket_id */,
-                     int /* amount_sent */)
-
-// The Socket Stream is closed.
-IPC_MESSAGE_CONTROL1(SocketStreamMsg_Closed,
-                     int /* socket_id */)
-
-// The Socket Stream is failed.
-IPC_MESSAGE_CONTROL2(SocketStreamMsg_Failed,
-                     int /* socket_id */,
-                     int /* error_code */)
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 537e793..3f55ab58 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -186,6 +186,7 @@
   IPC_STRUCT_TRAITS_MEMBER(title)
   IPC_STRUCT_TRAITS_MEMBER(default_file_name)
   IPC_STRUCT_TRAITS_MEMBER(accept_types)
+  IPC_STRUCT_TRAITS_MEMBER(need_local_path)
 #if defined(OS_ANDROID)
   IPC_STRUCT_TRAITS_MEMBER(capture)
 #endif
@@ -1374,10 +1375,11 @@
 IPC_MESSAGE_ROUTED1(ViewHostMsg_OpenDateTimeDialog,
                     ViewHostMsg_DateTimeDialogValue_Params /* value */)
 
-IPC_MESSAGE_ROUTED3(ViewHostMsg_TextInputTypeChanged,
+IPC_MESSAGE_ROUTED4(ViewHostMsg_TextInputTypeChanged,
                     ui::TextInputType /* TextInputType of the focused node */,
                     ui::TextInputMode /* TextInputMode of the focused node */,
-                    bool /* can_compose_inline in the focused node */)
+                    bool /* can_compose_inline in the focused node */,
+                    int /* flags in the focused node */)
 
 // Required for updating text input state.
 IPC_MESSAGE_ROUTED1(ViewHostMsg_TextInputStateChanged,
diff --git a/content/common/websocket_messages.h b/content/common/websocket_messages.h
index d42b38b..394c969 100644
--- a/content/common/websocket_messages.h
+++ b/content/common/websocket_messages.h
@@ -5,10 +5,7 @@
 // Multiply-included message file, hence no include guard.
 
 // This file defines the IPCs for the browser-side implementation of
-// WebSockets. For the legacy renderer-side implementation, see
-// socket_stream_messages.h.
-// TODO(ricea): Fix this comment when the legacy implementation has been
-// removed.
+// WebSockets.
 //
 // This IPC interface is based on the WebSocket multiplexing draft spec,
 // http://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-09
diff --git a/content/content.gyp b/content/content.gyp
index 1b07104a..5d843b64 100644
--- a/content/content.gyp
+++ b/content/content.gyp
@@ -150,6 +150,9 @@
           'variables': { 'enable_wexit_time_destructors': 1, },
           'includes': [
             'content_browser.gypi',
+            # Disable LTO due to ELF section name out of range
+            # crbug.com/422251
+            '../build/android/disable_lto.gypi',
           ],
           'dependencies': [
             'content_common',
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 34f846a..fac4cbe 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -447,8 +447,6 @@
       'browser/devtools/devtools_protocol.h',
       'browser/devtools/devtools_system_info_handler.cc',
       'browser/devtools/devtools_system_info_handler.h',
-      'browser/devtools/devtools_tracing_handler.h',
-      'browser/devtools/devtools_tracing_handler.cc',
       'browser/devtools/forwarding_agent_host.cc',
       'browser/devtools/forwarding_agent_host.h',
       'browser/devtools/ipc_devtools_agent_host.cc',
@@ -679,6 +677,9 @@
       'browser/geofencing/geofencing_manager.cc',
       'browser/geofencing/geofencing_manager.h',
       'browser/geofencing/geofencing_provider.h',
+      'browser/geofencing/geofencing_registration_delegate.h',
+      'browser/geofencing/geofencing_service.cc',
+      'browser/geofencing/geofencing_service.h',
       'browser/geolocation/empty_wifi_data_provider.cc',
       'browser/geolocation/empty_wifi_data_provider.h',
       'browser/geolocation/geolocation_dispatcher_host.cc',
@@ -1119,16 +1120,10 @@
       'browser/renderer_host/render_widget_resize_helper.h',
       'browser/renderer_host/renderer_frame_manager.cc',
       'browser/renderer_host/renderer_frame_manager.h',
-      'browser/renderer_host/routing_id_issuer.cc',
-      'browser/renderer_host/routing_id_issuer.h',
       'browser/renderer_host/sandbox_ipc_linux.cc',
       'browser/renderer_host/sandbox_ipc_linux.h',
       'browser/renderer_host/software_frame_manager.cc',
       'browser/renderer_host/software_frame_manager.h',
-      'browser/renderer_host/socket_stream_dispatcher_host.cc',
-      'browser/renderer_host/socket_stream_dispatcher_host.h',
-      'browser/renderer_host/socket_stream_host.cc',
-      'browser/renderer_host/socket_stream_host.h',
       'browser/renderer_host/text_input_client_mac.h',
       'browser/renderer_host/text_input_client_mac.mm',
       'browser/renderer_host/text_input_client_message_filter.h',
diff --git a/content/content_child.gypi b/content/content_child.gypi
index 2b374889..7e2b109 100644
--- a/content/content_child.gypi
+++ b/content/content_child.gypi
@@ -185,8 +185,6 @@
       'child/simple_webmimeregistry_impl.h',
       'child/site_isolation_policy.cc',
       'child/site_isolation_policy.h',
-      'child/socket_stream_dispatcher.cc',
-      'child/socket_stream_dispatcher.h',
       'child/sync_load_response.cc',
       'child/sync_load_response.h',
       'child/thread_safe_sender.cc',
@@ -199,10 +197,6 @@
       'child/web_discardable_memory_impl.h',
       'child/web_gesture_curve_impl.cc',
       'child/web_gesture_curve_impl.h',
-      'child/web_socket_stream_handle_bridge.h',
-      'child/web_socket_stream_handle_delegate.h',
-      'child/web_socket_stream_handle_impl.cc',
-      'child/web_socket_stream_handle_impl.h',
       'child/web_url_loader_impl.cc',
       'child/web_url_loader_impl.h',
       'child/web_url_request_util.cc',
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 47538d6..4d625ee 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -57,7 +57,6 @@
       'public/common/context_menu_params.h',
       'public/common/drop_data.cc',
       'public/common/drop_data.h',
-      'public/common/eme_constants.h',
       'public/common/favicon_url.cc',
       'public/common/favicon_url.h',
       'public/common/file_chooser_file_info.cc',
@@ -485,9 +484,6 @@
       'common/set_process_title.h',
       'common/set_process_title_linux.cc',
       'common/set_process_title_linux.h',
-      'common/socket_stream.h',
-      'common/socket_stream_handle_data.h',
-      'common/socket_stream_messages.h',
       'common/speech_recognition_messages.h',
       'common/ssl_status_serialization.cc',
       'common/ssl_status_serialization.h',
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index d3f0e19..f3f445d76 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -49,8 +49,6 @@
       'public/renderer/context_menu_client.h',
       'public/renderer/document_state.cc',
       'public/renderer/document_state.h',
-      'public/renderer/key_system_info.cc',
-      'public/renderer/key_system_info.h',
       'public/renderer/navigation_state.cc',
       'public/renderer/navigation_state.h',
       'public/renderer/pepper_plugin_instance.h',
@@ -364,6 +362,9 @@
       'renderer/sad_plugin.h',
       'renderer/savable_resources.cc',
       'renderer/savable_resources.h',
+      'renderer/scheduler/task_queue_manager.cc',
+      'renderer/scheduler/task_queue_manager.h',
+      'renderer/scheduler/task_queue_selector.h',
       'renderer/screen_orientation/screen_orientation_dispatcher.cc',
       'renderer/screen_orientation/screen_orientation_dispatcher.h',
       'renderer/screen_orientation/screen_orientation_observer.cc',
diff --git a/content/content_shell.gypi b/content/content_shell.gypi
index efa62364..1cec61e 100644
--- a/content/content_shell.gypi
+++ b/content/content_shell.gypi
@@ -118,6 +118,10 @@
         'shell/browser/layout_test/layout_test_url_request_context_getter.h',
         'shell/browser/notify_done_forwarder.cc',
         'shell/browser/notify_done_forwarder.h',
+        'shell/browser/shell.cc',
+        'shell/browser/shell.h',
+        'shell/browser/shell_access_token_store.cc',
+        'shell/browser/shell_access_token_store.h',
         'shell/browser/shell_android.cc',
         'shell/browser/shell_application_mac.h',
         'shell/browser/shell_application_mac.mm',
@@ -129,7 +133,6 @@
         'shell/browser/shell_browser_main_parts.cc',
         'shell/browser/shell_browser_main_parts.h',
         'shell/browser/shell_browser_main_parts_mac.mm',
-        'shell/browser/shell.cc',
         'shell/browser/shell_content_browser_client.cc',
         'shell/browser/shell_content_browser_client.h',
         'shell/browser/shell_devtools_delegate.cc',
@@ -138,7 +141,6 @@
         'shell/browser/shell_devtools_frontend.h',
         'shell/browser/shell_download_manager_delegate.cc',
         'shell/browser/shell_download_manager_delegate.h',
-        'shell/browser/shell.h',
         'shell/browser/shell_javascript_dialog.h',
         'shell/browser/shell_javascript_dialog_mac.mm',
         'shell/browser/shell_javascript_dialog_manager.cc',
@@ -189,8 +191,6 @@
         'shell/common/v8_breakpad_support_win.h',
         'shell/common/webkit_test_helpers.cc',
         'shell/common/webkit_test_helpers.h',
-        'shell/geolocation/shell_access_token_store.cc',
-        'shell/geolocation/shell_access_token_store.h',
         'shell/renderer/ipc_echo.cc',
         'shell/renderer/ipc_echo.h',
         'shell/renderer/layout_test/gc_controller.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index b502009..3fa41e33 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -54,8 +54,6 @@
       'public/test/render_view_test.h',
       'public/test/render_widget_test.cc',
       'public/test/render_widget_test.h',
-      'public/test/routing_id_mangling_disabler.cc',
-      'public/test/routing_id_mangling_disabler.h',
       'public/test/sandbox_file_system_test_helper.cc',
       'public/test/sandbox_file_system_test_helper.h',
       'public/test/test_browser_context.cc',
@@ -485,6 +483,7 @@
         'browser/gamepad/gamepad_test_helpers.cc',
         'browser/gamepad/gamepad_test_helpers.h',
         'browser/geofencing/geofencing_manager_unittest.cc',
+        'browser/geofencing/geofencing_service_unittest.cc',
         'browser/geolocation/geolocation_provider_impl_unittest.cc',
         'browser/geolocation/location_arbitrator_impl_unittest.cc',
         'browser/geolocation/network_location_provider_unittest.cc',
@@ -585,7 +584,6 @@
         'browser/renderer_host/render_widget_host_view_base_unittest.cc',
         'browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm',
         'browser/renderer_host/render_widget_host_view_mac_unittest.mm',
-        'browser/renderer_host/routing_id_issuer_unittest.cc',
         'browser/renderer_host/software_frame_manager_unittest.cc',
         'browser/renderer_host/text_input_client_mac_unittest.mm',
         'browser/renderer_host/web_input_event_aura_unittest.cc',
@@ -611,6 +609,7 @@
         'browser/service_worker/service_worker_url_request_job_unittest.cc',
         'browser/service_worker/service_worker_utils_unittest.cc',
         'browser/service_worker/service_worker_version_unittest.cc',
+        'browser/service_worker/service_worker_write_to_cache_job_unittest.cc',
         'browser/shared_worker/shared_worker_instance_unittest.cc',
         'browser/shared_worker/shared_worker_service_impl_unittest.cc',
         'browser/site_instance_impl_unittest.cc',
@@ -725,6 +724,7 @@
         'renderer/pepper/v8_var_converter_unittest.cc',
         'renderer/render_thread_impl_unittest.cc',
         'renderer/render_widget_unittest.cc',
+        'renderer/scheduler/task_queue_manager_unittest.cc',
         'renderer/screen_orientation/screen_orientation_dispatcher_unittest.cc',
         'renderer/skia_benchmarking_extension_unittest.cc',
         'renderer/v8_value_converter_impl_unittest.cc',
@@ -850,6 +850,21 @@
             '../third_party/webrtc/modules/modules.gyp:desktop_capture',
           ],
         }],
+        ['enable_webrtc==1 and OS=="mac"', {
+          'variables': {
+            'libpeer_target_type%': 'static_library',
+          },
+          'conditions': [
+            ['libpeer_target_type!="static_library"', {
+              'copies': [{
+                'destination': '<(PRODUCT_DIR)/Libraries',
+                'files': [
+                  '<(PRODUCT_DIR)/libpeerconnection.so',
+                ],
+              }],
+            }],
+          ],
+        }],
         ['enable_webrtc==1 and chromeos==1', {
           'sources': [
             'browser/media/capture/desktop_capture_device_aura_unittest.cc',
@@ -998,7 +1013,7 @@
             'content_unittests.isolate',
           ],
           'conditions': [
-            ['OS=="linux" and use_ozone==0', {
+            ['use_x11==1', {
               'dependencies': [
                 '../tools/xdisplaycheck/xdisplaycheck.gyp:xdisplaycheck',
               ],
@@ -1067,6 +1082,7 @@
             'content_shell_lib',
             '../skia/skia.gyp:skia',
             '../testing/gtest.gyp:gtest',
+            '../ui/accessibility/accessibility.gyp:ax_gen',
           ],
           'sources': [
             'test/content_test_launcher.cc',
@@ -1164,6 +1180,7 @@
           ],
           'sources': [
             'app/mojo/mojo_browsertest.cc',
+            'browser/accessibility/accessibility_ipc_error_browsertest.cc',
             'browser/accessibility/accessibility_mode_browsertest.cc',
             'browser/accessibility/accessibility_win_browsertest.cc',
             'browser/accessibility/android_hit_testing_browsertest.cc',
@@ -1355,6 +1372,7 @@
                 'browser/media/webrtc_browsertest.cc',
                 'browser/media/webrtc_getusermedia_browsertest.cc',
                 'browser/media/webrtc_internals_browsertest.cc',
+                'browser/media/webrtc_webcam_browsertest.cc',
                 'test/webrtc_content_browsertest_base.cc',
                 'test/webrtc_content_browsertest_base.h',
               ],
diff --git a/content/content_unittests.isolate b/content/content_unittests.isolate
index fe45bde1..184f7c5 100644
--- a/content/content_unittests.isolate
+++ b/content/content_unittests.isolate
@@ -58,6 +58,13 @@
         ],
       },
     }],
+    ['OS=="linux" and libpeer_target_type=="loadable_module"', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/lib/libpeerconnection.so',
+        ],
+      },
+    }],
     ['OS=="mac"', {
       'variables': {
         'command': [
@@ -97,6 +104,13 @@
         ],
       },
     }],
+    ['OS=="win" and libpeer_target_type=="loadable_module"', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/libpeerconnection.dll',
+        ],
+      },
+    }],
   ],
   'includes': [
     '../base/base.isolate',
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
index 0904975..ad84196 100644
--- a/content/ppapi_plugin/ppapi_blink_platform_impl.cc
+++ b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -220,12 +220,6 @@
   return NULL;
 }
 
-blink::WebSocketStreamHandle*
-PpapiBlinkPlatformImpl::createSocketStreamHandle() {
-  NOTREACHED();
-  return NULL;
-}
-
 void PpapiBlinkPlatformImpl::getPluginList(
     bool refresh,
     blink::WebPluginListBuilder* builder) {
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.h b/content/ppapi_plugin/ppapi_blink_platform_impl.h
index daba3f4..25076d8 100644
--- a/content/ppapi_plugin/ppapi_blink_platform_impl.h
+++ b/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -39,7 +39,6 @@
   virtual blink::WebString defaultLocale();
   virtual blink::WebThemeEngine* themeEngine();
   virtual blink::WebURLLoader* createURLLoader();
-  virtual blink::WebSocketStreamHandle* createSocketStreamHandle();
   virtual void getPluginList(bool refresh, blink::WebPluginListBuilder*);
   virtual blink::WebData loadResource(const char* name);
   virtual blink::WebStorageNamespace* createLocalStorageNamespace();
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 2f88578..b424046a 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -675,14 +675,6 @@
 
         mContainerView = containerView;
         mPositionObserver = new ViewPositionObserver(mContainerView);
-        String contentDescription = "Web View";
-        if (R.string.accessibility_content_view == 0) {
-            Log.w(TAG, "Setting contentDescription to 'Web View' as no value was specified.");
-        } else {
-            contentDescription = mContext.getResources().getString(
-                    R.string.accessibility_content_view);
-        }
-        mContainerView.setContentDescription(contentDescription);
         mContainerView.setWillNotDraw(false);
         mContainerView.setClickable(true);
         TraceEvent.end();
@@ -1178,23 +1170,6 @@
     }
 
     /**
-     * Post a message to a frame.
-     * TODO(sgurun) also add support for transferring a message channel port.
-     *
-     * @param frameName The name of the frame. If the name is null the message is posted
-     *                  to the main frame.
-     * @param message   The message
-     * @param sourceOrigin  The source origin
-     * @param targetOrigin  The target origin
-     */
-    public void postMessageToFrame(String frameName, String message,
-            String sourceOrigin, String targetOrigin) {
-        if (mNativeContentViewCore == 0) return;
-        nativePostMessageToFrame(mNativeContentViewCore, frameName, message, sourceOrigin,
-                targetOrigin);
-    }
-
-    /**
      * To be called when the ContentView is shown.
      */
     public void onShow() {
@@ -1909,6 +1884,14 @@
         return mHasSelection;
     }
 
+     /**
+     * @return Whether the page has an active, touch-controlled insertion handle.
+     */
+    @VisibleForTesting
+    protected boolean hasInsertion() {
+        return mHasInsertion;
+    }
+
     private void hidePastePopup() {
         if (mPastePopupMenu == null) return;
         mPastePopupMenu.hide();
@@ -2916,9 +2899,6 @@
             long nativeSelectPopupSourceFrame, int[] indices);
 
 
-    private native void nativePostMessageToFrame(long nativeContentViewCoreImpl, String frameId,
-            String message, String sourceOrigin, String targetOrigin);
-
     private native long nativeGetNativeImeAdapter(long nativeContentViewCoreImpl);
 
     private native int nativeGetCurrentRenderProcessId(long nativeContentViewCoreImpl);
diff --git a/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java b/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java
index 7437e16..81eab0f 100644
--- a/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java
+++ b/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java
@@ -49,6 +49,12 @@
     // The lock to access the mNativePtr.
     private final Object mNativePtrLock = new Object();
 
+    // The acceleration vector including gravity expressed in the body frame.
+    private float[] mAccelerationIncludingGravityVector;
+
+    // The geomagnetic vector expressed in the body frame.
+    private float[] mMagneticFieldVector;
+
     // Holds a shortened version of the rotation vector for compatibility purposes.
     private float[] mTruncatedRotationVector;
 
@@ -67,9 +73,12 @@
     static final int DEVICE_MOTION = 1;
     static final int DEVICE_LIGHT = 2;
 
-    static final Set<Integer> DEVICE_ORIENTATION_SENSORS = CollectionUtil.newHashSet(
+    static final Set<Integer> DEVICE_ORIENTATION_DEFAULT_SENSORS = CollectionUtil.newHashSet(
             Sensor.TYPE_ROTATION_VECTOR);
-
+    // Backup sensors are used when Sensor.TYPE_ROTATION_VECTOR is not available.
+    static final Set<Integer> DEVICE_ORIENTATION_BACKUP_SENSORS = CollectionUtil.newHashSet(
+            Sensor.TYPE_ACCELEROMETER,
+            Sensor.TYPE_MAGNETIC_FIELD);
     static final Set<Integer> DEVICE_MOTION_SENSORS = CollectionUtil.newHashSet(
             Sensor.TYPE_ACCELEROMETER,
             Sensor.TYPE_LINEAR_ACCELERATION,
@@ -79,9 +88,11 @@
 
     @VisibleForTesting
     final Set<Integer> mActiveSensors = new HashSet<Integer>();
+    Set<Integer> mDeviceOrientationSensors = DEVICE_ORIENTATION_DEFAULT_SENSORS;
     boolean mDeviceLightIsActive = false;
     boolean mDeviceMotionIsActive = false;
     boolean mDeviceOrientationIsActive = false;
+    boolean mUseBackupOrientationSensors = false;
 
     protected DeviceSensors(Context context) {
         mAppContext = context.getApplicationContext();
@@ -104,8 +115,14 @@
         synchronized (mNativePtrLock) {
             switch (eventType) {
                 case DEVICE_ORIENTATION:
-                    success = registerSensors(DEVICE_ORIENTATION_SENSORS, rateInMicroseconds,
-                        true);
+                    success = registerSensors(mDeviceOrientationSensors, rateInMicroseconds,
+                            true);
+                    if (!success) {
+                        mDeviceOrientationSensors = DEVICE_ORIENTATION_BACKUP_SENSORS;
+                        success = registerSensors(mDeviceOrientationSensors, rateInMicroseconds,
+                                true);
+                        mUseBackupOrientationSensors = success;
+                    }
                     break;
                 case DEVICE_MOTION:
                     // note: device motion spec does not require all sensors to be available
@@ -133,6 +150,11 @@
         return DEVICE_MOTION_SENSORS.size() - deviceMotionSensors.size();
     }
 
+    @CalledByNative
+    public boolean isUsingBackupSensorsForOrientation() {
+        return mUseBackupOrientationSensors;
+    }
+
     /**
      * Stop listening to sensors for a given event type. Ensures that sensors are not disabled
      * if they are still in use by a different event type.
@@ -157,7 +179,7 @@
                     break;
                 case DEVICE_MOTION:
                     if (mDeviceOrientationIsActive) {
-                        sensorsToRemainActive.addAll(DEVICE_ORIENTATION_SENSORS);
+                        sensorsToRemainActive.addAll(mDeviceOrientationSensors);
                     }
                     if (mDeviceLightIsActive) {
                         sensorsToRemainActive.addAll(DEVICE_LIGHT_SENSORS);
@@ -168,7 +190,7 @@
                         sensorsToRemainActive.addAll(DEVICE_MOTION_SENSORS);
                     }
                     if (mDeviceOrientationIsActive) {
-                        sensorsToRemainActive.addAll(DEVICE_ORIENTATION_SENSORS);
+                        sensorsToRemainActive.addAll(mDeviceOrientationSensors);
                     }
                     break;
                 default:
@@ -203,6 +225,9 @@
                 if (mDeviceMotionIsActive) {
                     gotAccelerationIncludingGravity(values[0], values[1], values[2]);
                 }
+                if (mDeviceOrientationIsActive && mUseBackupOrientationSensors) {
+                    getOrientationFromGeomagneticVectors(values, mMagneticFieldVector);
+                }
                 break;
             case Sensor.TYPE_LINEAR_ACCELERATION:
                 if (mDeviceMotionIsActive) {
@@ -231,6 +256,15 @@
                     }
                 }
                 break;
+            case Sensor.TYPE_MAGNETIC_FIELD:
+                if (mDeviceOrientationIsActive && mUseBackupOrientationSensors) {
+                    if (mMagneticFieldVector == null) {
+                        mMagneticFieldVector = new float[3];
+                    }
+                    System.arraycopy(values, 0, mMagneticFieldVector, 0,
+                            mMagneticFieldVector.length);
+                }
+                break;
             case Sensor.TYPE_LIGHT:
                 if (mDeviceLightIsActive) {
                     gotLight(values[0]);
@@ -338,6 +372,23 @@
                        Math.toDegrees(rotationAngles[2]));
     }
 
+    private void getOrientationFromGeomagneticVectors(float[] acceleration, float[] magnetic) {
+        float[] deviceRotationMatrix = new float[9];
+        if (acceleration == null || magnetic == null) {
+            return;
+        }
+        if (!SensorManager.getRotationMatrix(deviceRotationMatrix, null, acceleration, magnetic)) {
+            return;
+        }
+
+        double[] rotationAngles = new double[3];
+        computeDeviceOrientationFromRotationMatrix(deviceRotationMatrix, rotationAngles);
+
+        gotOrientation(Math.toDegrees(rotationAngles[0]),
+                       Math.toDegrees(rotationAngles[1]),
+                       Math.toDegrees(rotationAngles[2]));
+    }
+
     private SensorManagerProxy getSensorManagerProxy() {
         if (mSensorManagerProxy != null) {
             return mSensorManagerProxy;
diff --git a/content/public/android/java/src/org/chromium/content/browser/NavigationClient.java b/content/public/android/java/src/org/chromium/content/browser/NavigationClient.java
deleted file mode 100644
index 433ec0b..0000000
--- a/content/public/android/java/src/org/chromium/content/browser/NavigationClient.java
+++ /dev/null
@@ -1,28 +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.content.browser;
-
-import org.chromium.content_public.browser.NavigationHistory;
-
-/**
- * Provides functionality needed to query and page history and the ability to access
- * items in the history.
- */
-public interface NavigationClient {
-
-    /**
-     * Get a directed copy of the navigation history of the view.
-     * @param isForward Whether the returned history should be entries after the current entry.
-     * @param itemLimit The limit on the number of items included in the history.
-     * @return A directed navigation for the page.
-     */
-    public NavigationHistory getDirectedNavigationHistory(boolean isForward, int itemLimit);
-
-    /**
-     * Navigates to the specified index in the navigation entry for this page.
-     * @param index The navigation index to navigate to.
-     */
-    public void goToNavigationIndex(int index);
-}
diff --git a/content/public/android/java/src/org/chromium/content/browser/PopupZoomer.java b/content/public/android/java/src/org/chromium/content/browser/PopupZoomer.java
index 80e7dd2de..df6416c 100644
--- a/content/public/android/java/src/org/chromium/content/browser/PopupZoomer.java
+++ b/content/public/android/java/src/org/chromium/content/browser/PopupZoomer.java
@@ -4,6 +4,7 @@
 
 package org.chromium.content.browser;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -538,6 +539,7 @@
         return !mClipRect.contains(x, y);
     }
 
+    @SuppressLint("ClickableViewAccessibility")
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         mGestureDetector.onTouchEvent(event);
diff --git a/content/public/android/java/src/org/chromium/content/browser/WebContentsObserver.java b/content/public/android/java/src/org/chromium/content/browser/WebContentsObserver.java
index 12da56d8..4a98e92 100644
--- a/content/public/android/java/src/org/chromium/content/browser/WebContentsObserver.java
+++ b/content/public/android/java/src/org/chromium/content/browser/WebContentsObserver.java
@@ -125,7 +125,7 @@
      * @param isMainFrame Whether the load is happening for the main frame.
      * @param url The committed URL being navigated to.
      * @param transitionType The transition type as defined in
-     *                      {@link org.chromium.ui.base.PageTransitionTypes} for the load.
+     *                      {@link org.chromium.ui.base.PageTransition} for the load.
      */
     @CalledByNative
     public void didCommitProvisionalLoadForFrame(
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
index 5da02bf1..2fc2c34 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityInjector.java
@@ -74,20 +74,20 @@
             "https://ssl.gstatic.com/accessibility/javascript/android/chromeandroidvox.js";
 
     private static final String ACCESSIBILITY_SCREEN_READER_JAVASCRIPT_TEMPLATE =
-            "(function() {" +
-            "    var chooser = document.createElement('script');" +
-            "    chooser.type = 'text/javascript';" +
-            "    chooser.src = '%1s';" +
-            "    document.getElementsByTagName('head')[0].appendChild(chooser);" +
-            "  })();";
+            "(function() {"
+            + "    var chooser = document.createElement('script');"
+            + "    chooser.type = 'text/javascript';"
+            + "    chooser.src = '%1s';"
+            + "    document.getElementsByTagName('head')[0].appendChild(chooser);"
+            + "  })();";
 
     // JavaScript call to turn ChromeVox on or off.
     private static final String TOGGLE_CHROME_VOX_JAVASCRIPT =
-            "(function() {" +
-            "    if (typeof cvox !== 'undefined') {" +
-            "        cvox.ChromeVox.host.activateOrDeactivateChromeVox(%1s);" +
-            "    }" +
-            "  })();";
+            "(function() {"
+            + "    if (typeof cvox !== 'undefined') {"
+            + "        cvox.ChromeVox.host.activateOrDeactivateChromeVox(%1s);"
+            + "    }"
+            + "  })();";
 
     /**
      * Returns an instance of the {@link AccessibilityInjector} based on the SDK version.
@@ -135,8 +135,8 @@
         }
 
         String js = getScreenReaderInjectingJs();
-        if (mContentViewCore.isDeviceAccessibilityScriptInjectionEnabled() &&
-                js != null && mContentViewCore.isAlive()) {
+        if (mContentViewCore.isDeviceAccessibilityScriptInjectionEnabled()
+                && js != null && mContentViewCore.isAlive()) {
             addOrRemoveAccessibilityApisIfNecessary();
             mContentViewCore.getWebContents().evaluateJavaScript(js, null);
             mInjectedScriptEnabled = true;
@@ -167,9 +167,9 @@
      * Checks whether or not touch to explore is enabled on the system.
      */
     public boolean accessibilityIsAvailable() {
-        if (!getAccessibilityManager().isEnabled() ||
-                mContentViewCore.getContentSettings() == null ||
-                !mContentViewCore.getContentSettings().getJavaScriptEnabled()) {
+        if (!getAccessibilityManager().isEnabled()
+                || mContentViewCore.getContentSettings() == null
+                || !mContentViewCore.getContentSettings().getJavaScriptEnabled()) {
             return false;
         }
 
@@ -336,8 +336,8 @@
 
     private AccessibilityManager getAccessibilityManager() {
         if (mAccessibilityManager == null) {
-            mAccessibilityManager = (AccessibilityManager) mContentViewCore.getContext().
-                    getSystemService(Context.ACCESSIBILITY_SERVICE);
+            mAccessibilityManager = (AccessibilityManager) mContentViewCore.getContext()
+                    .getSystemService(Context.ACCESSIBILITY_SERVICE);
         }
 
         return mAccessibilityManager;
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
index 16dd813..c4b92d0 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/JellyBeanAccessibilityInjector.java
@@ -128,8 +128,8 @@
             if (arguments != null) {
                 if (action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY ||
                         action == AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY) {
-                    final int granularity = arguments.getInt(AccessibilityNodeInfo.
-                            ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
+                    final int granularity = arguments.getInt(
+                            AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
                     mAccessibilityJSONObject.accumulate("granularity", granularity);
                 } else if (action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT ||
                         action == AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java b/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
index ffb03af..f0b15e8e8 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
@@ -4,6 +4,7 @@
 
 package org.chromium.content.browser.input;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
@@ -121,6 +122,7 @@
         };
     }
 
+    @SuppressLint("ClickableViewAccessibility")
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         final PopupTouchHandleDrawableDelegate delegate = mDelegate.get();
@@ -205,7 +207,7 @@
         setVisibility(visible ? VISIBLE : INVISIBLE);
     }
 
-     private void updateAlpha() {
+    private void updateAlpha() {
         if (mAlpha == 1.f) return;
         long currentTimeMillis = AnimationUtils.currentAnimationTimeMillis();
         mAlpha = Math.min(1.f, (float) (currentTimeMillis - mFadeStartTime) / FADE_IN_DURATION_MS);
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
index 9cd3f0f8..99c318e 100644
--- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -227,6 +227,13 @@
         callback.handleJavaScriptResult(jsonResult);
     }
 
+    @Override
+    public void postMessageToFrame(String frameName, String message,
+            String sourceOrigin, String targetOrigin) {
+        nativePostMessageToFrame(mNativeWebContentsAndroid, frameName, message, sourceOrigin,
+                targetOrigin);
+    }
+
     private native String nativeGetTitle(long nativeWebContentsAndroid);
     private native String nativeGetVisibleURL(long nativeWebContentsAndroid);
     private native void nativeStop(long nativeWebContentsAndroid);
@@ -258,4 +265,6 @@
             String cssSelector);
     private native void nativeEvaluateJavaScript(long nativeWebContentsAndroid,
             String script, JavaScriptCallback callback);
+    private native void nativePostMessageToFrame(long nativeWebContentsAndroid, String frameId,
+            String message, String sourceOrigin, String targetOrigin);
 }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java b/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java
index 8482c5b..25a9f763 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java
@@ -7,7 +7,7 @@
 import org.chromium.base.CalledByNative;
 import org.chromium.base.JNINamespace;
 import org.chromium.content_public.common.Referrer;
-import org.chromium.ui.base.PageTransitionTypes;
+import org.chromium.ui.base.PageTransition;
 
 import java.util.Locale;
 import java.util.Map;
@@ -55,7 +55,7 @@
      * @param url the url to be loaded
      */
     public LoadUrlParams(String url) {
-        this(url, PageTransitionTypes.PAGE_TRANSITION_LINK);
+        this(url, PageTransition.LINK);
     }
 
     /**
@@ -110,7 +110,7 @@
 
         LoadUrlParams params = new LoadUrlParams(dataUrl.toString());
         params.setLoadType(LoadUrlParams.LOAD_TYPE_DATA);
-        params.setTransitionType(PageTransitionTypes.PAGE_TRANSITION_TYPED);
+        params.setTransitionType(PageTransition.TYPED);
         return params;
     }
 
@@ -174,7 +174,7 @@
             String url, byte[] postData) {
         LoadUrlParams params = new LoadUrlParams(url);
         params.setLoadType(LOAD_TYPE_BROWSER_INITIATED_HTTP_POST);
-        params.setTransitionType(PageTransitionTypes.PAGE_TRANSITION_TYPED);
+        params.setTransitionType(PageTransition.TYPED);
         params.setPostData(postData);
         return params;
     }
@@ -209,7 +209,7 @@
     }
 
     /**
-     * Set transition type of this load. Defaults to PAGE_TRANSITION_LINK.
+     * Set transition type of this load. Defaults to PageTransition.LINK.
      * @param transitionType One of PAGE_TRANSITION static constants in ContentView.
      */
     public void setTransitionType(int transitionType) {
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
index a76a5a0..e0cf864 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -163,4 +163,16 @@
      */
     public void evaluateJavaScript(String script, JavaScriptCallback callback);
 
+    /**
+     * Post a message to a frame.
+     * TODO(sgurun) also add support for transferring a message channel port.
+     *
+     * @param frameName The name of the frame. If the name is null the message is posted
+     *                  to the main frame.
+     * @param message   The message
+     * @param sourceOrigin  The source origin
+     * @param targetOrigin  The target origin
+     */
+    public void postMessageToFrame(String frameName, String message,
+            String sourceOrigin, String targetOrigin);
 }
diff --git a/content/public/android/java/strings/android_content_strings.grd b/content/public/android/java/strings/android_content_strings.grd
index ecb927c1..5aa9062 100644
--- a/content/public/android/java/strings/android_content_strings.grd
+++ b/content/public/android/java/strings/android_content_strings.grd
@@ -99,9 +99,6 @@
       <message desc="Contextual action bar item for using the selected text in a internet search. [CHAR-LIMIT=24]" name="IDS_ACTIONBAR_WEB_SEARCH">
         Web search
       </message>
-      <message desc="Content description for the content view that holds the web contents [CHAR-LIMIT=32]" name="IDS_ACCESSIBILITY_CONTENT_VIEW">
-        Web View
-      </message>
       <message desc="NO DESCRIPTION [CHAR-LIMIT=32]" name="IDS_MEDIA_PLAYER_ERROR_TITLE">
         Cannot play video
       </message>
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
index 50d0b4c6..a21dca6 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
@@ -32,6 +32,8 @@
             "<br/><input id=\"input_text\" type=\"text\" value=\"Sample Text\" />" +
             "<br/><textarea id=\"empty_textarea\" rows=\"2\" cols=\"20\"></textarea>" +
             "<br/><textarea id=\"textarea\" rows=\"2\" cols=\"20\">Sample Text</textarea>" +
+            "<br/><input id=\"readonly_text\" type=\"text\" readonly value=\"Sample Text\"/>" +
+            "<br/><input id=\"disabled_text\" type=\"text\" disabled value=\"Sample Text\" />" +
             "</form></body></html>");
 
     private ContentViewCore mContentViewCore;
@@ -173,6 +175,30 @@
         assertWaitForPastePopupStatus(false);
     }
 
+    @SmallTest
+    @Feature({"TextInput"})
+    public void testPastePopupNotShownOnLongPressingReadOnlyInput() throws Throwable {
+        copyStringToClipboard();
+        DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text");
+        assertWaitForPastePopupStatus(true);
+        assertTrue(mContentViewCore.hasInsertion());
+        DOMUtils.longPressNode(this, mContentViewCore, "readonly_text");
+        assertWaitForPastePopupStatus(false);
+        assertFalse(mContentViewCore.hasInsertion());
+    }
+
+    @SmallTest
+    @Feature({"TextInput"})
+    public void testPastePopupNotShownOnLongPressingDisabledInput() throws Throwable {
+        copyStringToClipboard();
+        DOMUtils.longPressNode(this, mContentViewCore, "empty_input_text");
+        assertWaitForPastePopupStatus(true);
+        assertTrue(mContentViewCore.hasInsertion());
+        DOMUtils.longPressNode(this, mContentViewCore, "disabled_text");
+        assertWaitForPastePopupStatus(false);
+        assertFalse(mContentViewCore.hasInsertion());
+    }
+
     private void assertWaitForSelectActionBarVisible(
             final boolean visible) throws InterruptedException {
         assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/DeviceSensorsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/DeviceSensorsTest.java
index 9abfc5b..c309c54 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/DeviceSensorsTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/DeviceSensorsTest.java
@@ -57,17 +57,37 @@
         assertTrue(start);
         assertTrue("should contain all orientation sensors",
                 mDeviceSensors.mActiveSensors.containsAll(
-                        DeviceSensors.DEVICE_ORIENTATION_SENSORS));
+                        DeviceSensors.DEVICE_ORIENTATION_DEFAULT_SENSORS));
         assertFalse(mDeviceSensors.mDeviceMotionIsActive);
         assertFalse(mDeviceSensors.mDeviceLightIsActive);
         assertTrue(mDeviceSensors.mDeviceOrientationIsActive);
+        assertFalse(mDeviceSensors.isUsingBackupSensorsForOrientation());
 
-        assertEquals(DeviceSensors.DEVICE_ORIENTATION_SENSORS.size(),
+        assertEquals(DeviceSensors.DEVICE_ORIENTATION_DEFAULT_SENSORS.size(),
                 mMockSensorManager.mNumRegistered);
         assertEquals(0, mMockSensorManager.mNumUnRegistered);
     }
 
     @SmallTest
+    public void testRegisterSensorsDeviceOrientationRotationVectorNotAvailable() {
+        MockSensorManager mockSensorManager = new MockSensorManager();
+        mockSensorManager.setRotationVectorAvailable(false);
+        mDeviceSensors.setSensorManagerProxy(mockSensorManager);
+        boolean startOrientation = mDeviceSensors.start(0, DeviceSensors.DEVICE_ORIENTATION, 100);
+
+        assertTrue(startOrientation);
+        assertTrue(mDeviceSensors.mDeviceOrientationIsActive);
+        assertTrue("should contain all backup orientation sensors",
+                mDeviceSensors.mActiveSensors.containsAll(
+                        DeviceSensors.DEVICE_ORIENTATION_BACKUP_SENSORS));
+        assertTrue(mDeviceSensors.isUsingBackupSensorsForOrientation());
+
+        assertEquals(DeviceSensors.DEVICE_ORIENTATION_BACKUP_SENSORS.size(),
+                mockSensorManager.mNumRegistered);
+        assertEquals(0, mockSensorManager.mNumUnRegistered);
+    }
+
+    @SmallTest
     public void testRegisterSensorsDeviceMotionAndOrientation() {
         boolean startOrientation = mDeviceSensors.start(0, DeviceSensors.DEVICE_ORIENTATION, 100);
         boolean startMotion = mDeviceSensors.start(0, DeviceSensors.DEVICE_MOTION, 100);
@@ -79,9 +99,9 @@
                         DeviceSensors.DEVICE_MOTION_SENSORS));
         assertTrue("should contain all orientation sensors",
                 mDeviceSensors.mActiveSensors.containsAll(
-                        DeviceSensors.DEVICE_ORIENTATION_SENSORS));
+                        DeviceSensors.DEVICE_ORIENTATION_DEFAULT_SENSORS));
 
-        Set<Integer> union = new HashSet<Integer>(DeviceSensors.DEVICE_ORIENTATION_SENSORS);
+        Set<Integer> union = new HashSet<Integer>(DeviceSensors.DEVICE_ORIENTATION_DEFAULT_SENSORS);
         union.addAll(DeviceSensors.DEVICE_MOTION_SENSORS);
 
         assertEquals(union.size(), mDeviceSensors.mActiveSensors.size());
@@ -133,7 +153,7 @@
         assertFalse(mDeviceSensors.mDeviceMotionIsActive);
         assertFalse(mDeviceSensors.mDeviceOrientationIsActive);
         assertFalse(mDeviceSensors.mDeviceLightIsActive);
-        assertEquals(DeviceSensors.DEVICE_ORIENTATION_SENSORS.size(),
+        assertEquals(DeviceSensors.DEVICE_ORIENTATION_DEFAULT_SENSORS.size(),
                 mMockSensorManager.mNumUnRegistered);
     }
 
@@ -145,17 +165,17 @@
 
         assertTrue("should contain all orientation sensors",
                 mDeviceSensors.mActiveSensors.containsAll(
-                        DeviceSensors.DEVICE_ORIENTATION_SENSORS));
+                        DeviceSensors.DEVICE_ORIENTATION_DEFAULT_SENSORS));
 
         Set<Integer> diff = new HashSet<Integer>(DeviceSensors.DEVICE_MOTION_SENSORS);
-        diff.removeAll(DeviceSensors.DEVICE_ORIENTATION_SENSORS);
+        diff.removeAll(DeviceSensors.DEVICE_ORIENTATION_DEFAULT_SENSORS);
 
         assertEquals(diff.size(), mMockSensorManager.mNumUnRegistered);
 
         mDeviceSensors.stop(DeviceSensors.DEVICE_ORIENTATION);
 
         assertTrue("should contain no sensors", mDeviceSensors.mActiveSensors.isEmpty());
-        assertEquals(diff.size() + DeviceSensors.DEVICE_ORIENTATION_SENSORS.size(),
+        assertEquals(diff.size() + DeviceSensors.DEVICE_ORIENTATION_DEFAULT_SENSORS.size(),
                 mMockSensorManager.mNumUnRegistered);
         assertEquals(0, mDeviceSensors.getNumberActiveDeviceMotionSensors());
     }
@@ -250,7 +270,6 @@
         mDeviceSensors.verifyValues(1, 2, 3);
     }
 
-
     // Tests for correct Device Orientation angles.
 
     @SmallTest
@@ -426,13 +445,21 @@
 
         private int mNumRegistered = 0;
         private int mNumUnRegistered = 0;
+        private boolean mRotationVectorAvailable = true;
 
         private MockSensorManager() {
         }
 
+        public void setRotationVectorAvailable(boolean available) {
+            mRotationVectorAvailable = available;
+        }
+
         @Override
         public boolean registerListener(SensorEventListener listener, int sensorType, int rate,
                 Handler handler) {
+            if (!mRotationVectorAvailable && sensorType == Sensor.TYPE_ROTATION_VECTOR) {
+                return false;
+            }
             mNumRegistered++;
             return true;
         }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/PostMessageTest.java b/content/public/android/javatests/src/org/chromium/content/browser/PostMessageTest.java
index 35f2a1d1..c11d66d 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/PostMessageTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/PostMessageTest.java
@@ -7,6 +7,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import org.chromium.base.test.util.Feature;
+import org.chromium.content_public.browser.WebContents;
 
 /**
  * The tests for content postMessage API.
@@ -71,10 +72,9 @@
     @SmallTest
     @Feature({"AndroidWebView", "Android-PostMessage"})
     public void testPostMessageToMainFrame() throws Throwable {
-        ContentViewCore contentViewCore = getContentViewCore();
-        loadDataSync(contentViewCore.getWebContents().getNavigationController(), URL1, "text/html",
-                false);
-        contentViewCore.postMessageToFrame(null, MESSAGE, SOURCE_ORIGIN, "*");
+        WebContents webContents = getContentViewCore().getWebContents();
+        loadDataSync(webContents.getNavigationController(), URL1, "text/html", false);
+        webContents.postMessageToFrame(null, MESSAGE, SOURCE_ORIGIN, "*");
         mMessageObject.waitForMessage();
         assertEquals(MESSAGE, mMessageObject.getData());
         assertEquals(SOURCE_ORIGIN, mMessageObject.getOrigin());
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
index 01a600b..30b879b 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
@@ -468,11 +468,8 @@
         assertEquals("", mConnection.getTextBeforeCursor(9, 0));
     }
 
-    /*
     @SmallTest
     @Feature({"TextInput", "Main"})
-    */
-    @DisabledTest
     public void testKeyCodesWhileSwipingText() throws Throwable {
         DOMUtils.focusNode(mWebContents, "textarea");
         assertWaitForKeyboardStatus(true);
@@ -607,11 +604,8 @@
         setComposingRegion(mConnection, 9, 0);
     }
 
-    /*
     @SmallTest
     @Feature({"TextInput", "Main"})
-    */
-    @DisabledTest
     public void testEnterKeyEventWhileComposingText() throws Throwable {
         DOMUtils.focusNode(mWebContents, "input_radio");
         assertWaitForKeyboardStatus(false);
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h
index 38f07ec..4ae7f3a2 100644
--- a/content/public/browser/render_process_host.h
+++ b/content/public/browser/render_process_host.h
@@ -229,6 +229,13 @@
   // Returns the ServiceRegistry for this process.
   virtual ServiceRegistry* GetServiceRegistry() = 0;
 
+  // PlzNavigate
+  // Returns the time the first call to Init completed successfully (after a new
+  // renderer process was created); further calls to Init won't change this
+  // value.
+  // Note: Do not use! Will disappear after PlzNavitate is completed.
+  virtual const base::TimeTicks& GetInitTimeForNavigationMetrics() const = 0;
+
   // Static management functions -----------------------------------------------
 
   // Flag to run the renderer in process.  This is primarily
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h
index 9fe797c7..86732ee 100644
--- a/content/public/browser/render_widget_host_view.h
+++ b/content/public/browser/render_widget_host_view.h
@@ -10,6 +10,7 @@
 #include "base/strings/string16.h"
 #include "content/common/content_export.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "ui/gfx/native_widget_types.h"
@@ -104,9 +105,12 @@
   // Returns the currently selected text.
   virtual base::string16 GetSelectedText() const = 0;
 
-  // Subclasses should override this method to do what is appropriate to set
-  // the background to be transparent or opaque.
-  virtual void SetBackgroundOpaque(bool opaque) = 0;
+  // Subclasses should override this method to set the background color. |color|
+  // could be transparent or opaque.
+  virtual void SetBackgroundColor(SkColor color) = 0;
+  // Convenience method to fill the background layer with the default color by
+  // calling |SetBackgroundColor|.
+  virtual void SetBackgroundColorToDefault() = 0;
   virtual bool GetBackgroundOpaque() = 0;
 
   // Return value indicates whether the mouse is locked successfully or not.
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index f4e558f6..c16e5e6 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -40,8 +40,9 @@
 
 class AppCacheService;
 class BrowserContext;
-class IndexedDBContext;
 class DOMStorageContext;
+class GeofencingManager;
+class IndexedDBContext;
 class ServiceWorkerContext;
 
 // Defines what persistent state a child process can access.
@@ -62,6 +63,7 @@
   virtual DOMStorageContext* GetDOMStorageContext() = 0;
   virtual IndexedDBContext* GetIndexedDBContext() = 0;
   virtual ServiceWorkerContext* GetServiceWorkerContext() = 0;
+  virtual GeofencingManager* GetGeofencingManager() = 0;
 
   static const uint32 REMOVE_DATA_MASK_APPCACHE        = 1 << 0;
   static const uint32 REMOVE_DATA_MASK_COOKIES         = 1 << 1;
diff --git a/content/public/common/file_chooser_params.cc b/content/public/common/file_chooser_params.cc
index c9c9571..97de9e3 100644
--- a/content/public/common/file_chooser_params.cc
+++ b/content/public/common/file_chooser_params.cc
@@ -6,7 +6,7 @@
 
 namespace content {
 
-FileChooserParams::FileChooserParams() : mode(Open) {
+FileChooserParams::FileChooserParams() : mode(Open), need_local_path(true) {
 }
 
 FileChooserParams::~FileChooserParams() {
diff --git a/content/public/common/file_chooser_params.h b/content/public/common/file_chooser_params.h
index 46043269..ad612ab 100644
--- a/content/public/common/file_chooser_params.h
+++ b/content/public/common/file_chooser_params.h
@@ -46,6 +46,9 @@
   // input element. It is used to restrict selectable files to such types.
   std::vector<base::string16> accept_types;
 
+  // Whether the caller needs native file path or not.
+  bool need_local_path;
+
 #if defined(OS_ANDROID)
   // See http://www.w3.org/TR/html-media-capture for more information.
   // If true, the data should be obtained using the device's camera/mic/etc.
diff --git a/content/public/common/push_messaging_status.h b/content/public/common/push_messaging_status.h
index 48a10b5..845741f3 100644
--- a/content/public/common/push_messaging_status.h
+++ b/content/public/common/push_messaging_status.h
@@ -7,30 +7,37 @@
 
 namespace content {
 
+// Push registration success / error codes for internal use & reporting in UMA.
 enum PushRegistrationStatus {
   // Registration was successful.
-  PUSH_REGISTRATION_STATUS_SUCCESS,
+  PUSH_REGISTRATION_STATUS_SUCCESS = 0,
 
   // Registration failed because there is no Service Worker.
-  PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER,
+  PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER = 1,
 
   // Registration failed because the push service is not available.
-  PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE,
+  PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE = 2,
 
   // Registration failed because the maximum number of registratons has been
   // reached.
-  PUSH_REGISTRATION_STATUS_LIMIT_REACHED,
+  PUSH_REGISTRATION_STATUS_LIMIT_REACHED = 3,
 
   // Registration failed because permission was denied.
-  PUSH_REGISTRATION_STATUS_PERMISSION_DENIED,
+  PUSH_REGISTRATION_STATUS_PERMISSION_DENIED = 4,
 
   // Registration failed in the push service implemented by the embedder.
-  PUSH_REGISTRATION_STATUS_SERVICE_ERROR,
+  PUSH_REGISTRATION_STATUS_SERVICE_ERROR = 5,
+
+  // NOTE: Do not renumber these as that would confuse interpretation of
+  // previously logged data. When making changes, also update the enum list
+  // in tools/metrics/histograms/histograms.xml to keep it in sync, and
+  // update PUSH_REGISTRATION_STATUS_LAST below.
 
   // Used for IPC message range checks.
   PUSH_REGISTRATION_STATUS_LAST = PUSH_REGISTRATION_STATUS_SERVICE_ERROR
 };
 
+// Push message delivery success / error codes for internal use.
 enum PushDeliveryStatus {
   // The message was successfully delivered.
   PUSH_DELIVERY_STATUS_SUCCESS,
@@ -41,6 +48,8 @@
   // The message could not be delivered because of a service worker error.
   PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR,
 
+  // When making changes, update PUSH_DELIVERY_STATUS_LAST below.
+
   // Used for IPC message range checks.
   PUSH_DELIVERY_STATUS_LAST = PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR
 };
diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc
index 88ca258..76f27ee 100644
--- a/content/public/renderer/content_renderer_client.cc
+++ b/content/public/renderer/content_renderer_client.cc
@@ -155,7 +155,7 @@
 }
 
 void ContentRendererClient::AddKeySystems(
-    std::vector<KeySystemInfo>* key_systems) {
+    std::vector<media::KeySystemInfo>* key_systems) {
 }
 
 bool ContentRendererClient::ShouldReportDetailedMessageForSource(
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index 9de7a084..daf8d4a 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -49,13 +49,16 @@
 struct WebURLError;
 }
 
+namespace media {
+struct KeySystemInfo;
+}
+
 namespace content {
 class BrowserPluginDelegate;
 class DocumentState;
 class RenderFrame;
 class RenderView;
 class SynchronousCompositor;
-struct KeySystemInfo;
 struct WebPluginInfo;
 
 // Embedder API for participating in renderer logic.
@@ -243,7 +246,7 @@
 
   // Gives the embedder a chance to register the key system(s) it supports by
   // populating |key_systems|.
-  virtual void AddKeySystems(std::vector<KeySystemInfo>* key_systems);
+  virtual void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems);
 
   // Returns true if we should report a detailed message (including a stack
   // trace) for console [logs|errors|exceptions]. |source| is the WebKit-
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc
index fb1206e..7b30a6f9 100644
--- a/content/public/test/mock_render_process_host.cc
+++ b/content/public/test/mock_render_process_host.cc
@@ -223,6 +223,12 @@
   return NULL;
 }
 
+const base::TimeTicks& MockRenderProcessHost::GetInitTimeForNavigationMetrics()
+    const {
+  static base::TimeTicks dummy_time = base::TimeTicks::Now();
+  return dummy_time;
+}
+
 void MockRenderProcessHost::FilterURL(bool empty_allowed, GURL* url) {
   RenderProcessHostImpl::FilterURL(this, empty_allowed, url);
 }
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h
index 802b7126..81df686 100644
--- a/content/public/test/mock_render_process_host.h
+++ b/content/public/test/mock_render_process_host.h
@@ -81,6 +81,7 @@
   void ResumeDeferredNavigation(const GlobalRequestID& request_id) override;
   void NotifyTimezoneChange() override;
   ServiceRegistry* GetServiceRegistry() override;
+  const base::TimeTicks& GetInitTimeForNavigationMetrics() const override;
 
   // IPC::Sender via RenderProcessHost.
   bool Send(IPC::Message* msg) override;
diff --git a/content/public/test/routing_id_mangling_disabler.cc b/content/public/test/routing_id_mangling_disabler.cc
deleted file mode 100644
index b1e83a12..0000000
--- a/content/public/test/routing_id_mangling_disabler.cc
+++ /dev/null
@@ -1,19 +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 "content/public/test/routing_id_mangling_disabler.h"
-
-#include "content/browser/renderer_host/routing_id_issuer.h"
-
-namespace content {
-
-RoutingIDManglingDisabler::RoutingIDManglingDisabler() {
-  RoutingIDIssuer::DisableIDMangling();
-}
-
-RoutingIDManglingDisabler::~RoutingIDManglingDisabler() {
-  RoutingIDIssuer::EnableIDMangling();
-}
-
-}  // namespace content
diff --git a/content/public/test/routing_id_mangling_disabler.h b/content/public/test/routing_id_mangling_disabler.h
deleted file mode 100644
index 5c23174..0000000
--- a/content/public/test/routing_id_mangling_disabler.h
+++ /dev/null
@@ -1,20 +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 CONTENT_PUBLIC_TEST_ROUTIND_ID_MANGLING_DISABLER_H_
-#define CONTENT_PUBLIC_TEST_ROUTIND_ID_MANGLING_DISABLER_H_
-
-namespace content {
-
-// Some tests unfortunately assume that the routing ID starts from
-// one. This class temporarily satisfies such an assumption.
-class RoutingIDManglingDisabler {
- public:
-  RoutingIDManglingDisabler();
-  ~RoutingIDManglingDisabler();
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_TEST_ROUTIND_ID_MANGLING_DISABLER_H_
diff --git a/content/renderer/accessibility/blink_ax_enum_conversion.cc b/content/renderer/accessibility/blink_ax_enum_conversion.cc
index 8d8b3471..a9e6347 100644
--- a/content/renderer/accessibility/blink_ax_enum_conversion.cc
+++ b/content/renderer/accessibility/blink_ax_enum_conversion.cc
@@ -333,7 +333,9 @@
     default:
       // We can't add an assertion here, that prevents us
       // from adding new role enums in Blink.
-      return static_cast<ui::AXRole>(-1);
+      LOG(WARNING) << "Warning: Blink WebAXRole " << role
+                   << " not handled by Chromium yet.";
+      return ui::AX_ROLE_UNKNOWN;
   }
 }
 
diff --git a/content/renderer/accessibility/renderer_accessibility.h b/content/renderer/accessibility/renderer_accessibility.h
index 426c1a7..5a9534c 100644
--- a/content/renderer/accessibility/renderer_accessibility.h
+++ b/content/renderer/accessibility/renderer_accessibility.h
@@ -60,6 +60,11 @@
   // testing.
   virtual RendererAccessibilityType GetType() = 0;
 
+  // This can be called before deleting a RendererAccessibility instance due
+  // to the accessibility mode changing, as opposed to during frame destruction
+  // (when there'd be no point).
+  virtual void DisableAccessibility() {}
+
  protected:
   // Returns the main top-level document for this page, or NULL if there's
   // no view or frame.
diff --git a/content/renderer/accessibility/renderer_accessibility_browsertest.cc b/content/renderer/accessibility/renderer_accessibility_browsertest.cc
index 18e7366..18c9a59 100644
--- a/content/renderer/accessibility/renderer_accessibility_browsertest.cc
+++ b/content/renderer/accessibility/renderer_accessibility_browsertest.cc
@@ -59,7 +59,7 @@
     const IPC::Message* message =
         sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID);
     ASSERT_TRUE(message);
-    Tuple1<std::vector<AccessibilityHostMsg_EventParams> > param;
+    Tuple2<std::vector<AccessibilityHostMsg_EventParams>, int> param;
     AccessibilityHostMsg_Events::Read(message, &param);
     ASSERT_GE(param.a.size(), 1U);
     *params = param.a[0];
@@ -406,7 +406,7 @@
   const IPC::Message* message =
       sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID);
   ASSERT_TRUE(message);
-  Tuple1<std::vector<AccessibilityHostMsg_EventParams> > param;
+  Tuple2<std::vector<AccessibilityHostMsg_EventParams>, int> param;
   AccessibilityHostMsg_Events::Read(message, &param);
   ASSERT_EQ(0U, param.a.size());
 }
diff --git a/content/renderer/accessibility/renderer_accessibility_complete.cc b/content/renderer/accessibility/renderer_accessibility_complete.cc
index e444e708f..28536b03 100644
--- a/content/renderer/accessibility/renderer_accessibility_complete.cc
+++ b/content/renderer/accessibility/renderer_accessibility_complete.cc
@@ -39,6 +39,7 @@
       serializer_(&tree_source_),
       last_scroll_offset_(gfx::Size()),
       ack_pending_(false),
+      reset_token_(0),
       weak_factory_(this) {
   WebView* web_view = render_frame_->GetRenderView()->GetWebView();
   WebSettings* settings = web_view->settings();
@@ -80,6 +81,7 @@
     IPC_MESSAGE_HANDLER(AccessibilityMsg_SetTextSelection,
                         OnSetTextSelection)
     IPC_MESSAGE_HANDLER(AccessibilityMsg_HitTest, OnHitTest)
+    IPC_MESSAGE_HANDLER(AccessibilityMsg_Reset, OnReset)
     IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
@@ -98,6 +100,22 @@
   }
 }
 
+void RendererAccessibilityComplete::DisableAccessibility() {
+  RenderView* render_view = render_frame_->GetRenderView();
+  if (!render_view)
+    return;
+
+  WebView* web_view = render_view->GetWebView();
+  if (!web_view)
+    return;
+
+  WebSettings* settings = web_view->settings();
+  if (!settings)
+    return;
+
+  settings->setAccessibilityEnabled(false);
+}
+
 void RendererAccessibilityComplete::HandleWebAccessibilityEvent(
     const blink::WebAXObject& obj, blink::WebAXEvent event) {
   HandleAXEvent(obj, AXEventFromBlink(event));
@@ -231,7 +249,8 @@
             << "\n" << event_msg.update.ToString();
   }
 
-  Send(new AccessibilityHostMsg_Events(routing_id(), event_msgs));
+  Send(new AccessibilityHostMsg_Events(routing_id(), event_msgs, reset_token_));
+  reset_token_ = 0;
 
   if (had_layout_complete_messages)
     SendLocationChanges();
@@ -418,6 +437,16 @@
     obj.setFocused(true);
 }
 
+void RendererAccessibilityComplete::OnReset(int reset_token) {
+  reset_token_ = reset_token;
+  serializer_.Reset();
+  pending_events_.clear();
+
+  const WebDocument& document = GetMainDocument();
+  if (!document.isNull())
+    HandleAXEvent(document.accessibilityObject(), ui::AX_EVENT_LAYOUT_COMPLETE);
+}
+
 void RendererAccessibilityComplete::OnFatalError() {
   CHECK(false) << "Invalid accessibility tree.";
 }
diff --git a/content/renderer/accessibility/renderer_accessibility_complete.h b/content/renderer/accessibility/renderer_accessibility_complete.h
index 96d1c6f..3f33c08 100644
--- a/content/renderer/accessibility/renderer_accessibility_complete.h
+++ b/content/renderer/accessibility/renderer_accessibility_complete.h
@@ -47,6 +47,7 @@
                                    blink::WebAXEvent event) override;
   RendererAccessibilityType GetType() override;
   void FocusedNodeChanged(const blink::WebNode& node) override;
+  virtual void DisableAccessibility() override;
 
   void HandleAXEvent(const blink::WebAXObject& obj, ui::AXEvent event);
 
@@ -69,6 +70,7 @@
   void OnSetFocus(int acc_obj_id);
   void OnSetTextSelection(int acc_obj_id, int start_offset, int end_offset);
   void OnHitTest(gfx::Point point);
+  void OnReset(int reset_token);
   void OnFatalError();
 
   // Events from Blink are collected until they are ready to be
@@ -92,6 +94,10 @@
   // Set if we are waiting for an accessibility event ack.
   bool ack_pending_;
 
+  // Nonzero if the browser requested we reset the accessibility state.
+  // We need to return this token in the next IPC.
+  int reset_token_;
+
   // So we can queue up tasks to be executed later.
   base::WeakPtrFactory<RendererAccessibilityComplete> weak_factory_;
 
diff --git a/content/renderer/dom_serializer_browsertest.cc b/content/renderer/dom_serializer_browsertest.cc
index 7b885f8..1bcd2bd0d 100644
--- a/content/renderer/dom_serializer_browsertest.cc
+++ b/content/renderer/dom_serializer_browsertest.cc
@@ -15,7 +15,6 @@
 #include "content/public/renderer/render_view_observer.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
-#include "content/public/test/routing_id_mangling_disabler.h"
 #include "content/public/test/test_utils.h"
 #include "content/renderer/savable_resources.h"
 #include "content/shell/browser/shell.h"
@@ -775,8 +774,6 @@
   // The local_directory_name_ is dummy relative path of directory which
   // contain all saved auxiliary files included all sub frames and resources.
   const base::FilePath local_directory_name_;
-
-  content::RoutingIDManglingDisabler mangling_disabler_;
 };
 
 // If original contents have document type, the serialized contents also have
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc
index dfc4abd1..f57a9a7 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -18,11 +18,16 @@
 #include "content/common/input/synthetic_tap_gesture_params.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/v8_value_converter.h"
+#include "content/renderer/chrome_object_extensions_utils.h"
 #include "content/renderer/gpu/render_widget_compositor.h"
 #include "content/renderer/render_thread_impl.h"
 #include "content/renderer/render_view_impl.h"
 #include "content/renderer/skia_benchmarking_extension.h"
+#include "gin/arguments.h"
+#include "gin/handle.h"
+#include "gin/object_template_builder.h"
 #include "third_party/WebKit/public/web/WebImageCache.h"
+#include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "third_party/skia/include/core/SkData.h"
@@ -40,26 +45,26 @@
 using blink::WebSize;
 using blink::WebView;
 
-const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking";
+namespace content {
+
+namespace {
 
 // offset parameter is deprecated/ignored, and will be remove from the
 // signature in a future skia release. <reed@google.com>
-static SkData* EncodeBitmapToData(size_t* offset, const SkBitmap& bm) {
-    SkPixelRef* pr = bm.pixelRef();
-    if (pr != NULL) {
-        SkData* data = pr->refEncodedData();
-        if (data != NULL)
-            return data;
-    }
-    std::vector<unsigned char> vector;
-    if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) {
-        return SkData::NewWithCopy(&vector.front() , vector.size());
-    }
-    return NULL;
+SkData* EncodeBitmapToData(size_t* offset, const SkBitmap& bm) {
+  SkPixelRef* pr = bm.pixelRef();
+  if (pr != NULL) {
+    SkData* data = pr->refEncodedData();
+    if (data != NULL)
+      return data;
+  }
+  std::vector<unsigned char> vector;
+  if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) {
+    return SkData::NewWithCopy(&vector.front(), vector.size());
+  }
+  return NULL;
 }
 
-namespace {
-
 class SkPictureSerializer {
  public:
   explicit SkPictureSerializer(const base::FilePath& dirpath)
@@ -67,7 +72,7 @@
         layer_id_(0) {
     // Let skia register known effect subclasses. This basically enables
     // reflection on those subclasses required for picture serialization.
-    content::SkiaBenchmarking::Initialize();
+    SkiaBenchmarking::Initialize();
   }
 
   // Recursively serializes the layer tree.
@@ -100,11 +105,33 @@
   int layer_id_;
 };
 
-}  // namespace
+template <typename T>
+bool GetArg(gin::Arguments* args, T* value) {
+  if (!args->GetNext(value)) {
+    args->ThrowError();
+    return false;
+  }
+  return true;
+}
 
-namespace content {
+template <>
+bool GetArg(gin::Arguments* args, int* value) {
+  float number;
+  bool ret = GetArg(args, &number);
+  *value = number;
+  return ret;
+}
 
-namespace {
+template <typename T>
+bool GetOptionalArg(gin::Arguments* args, T* value) {
+  if (args->PeekNext().IsEmpty())
+    return true;
+  if (args->PeekNext()->IsUndefined()) {
+    args->Skip();
+    return true;
+  }
+  return GetArg(args, value);
+}
 
 class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
  public:
@@ -208,716 +235,576 @@
   DISALLOW_COPY_AND_ASSIGN(GpuBenchmarkingContext);
 };
 
+void OnMicroBenchmarkCompleted(
+    CallbackAndContext* callback_and_context,
+    scoped_ptr<base::Value> result) {
+  v8::Isolate* isolate = callback_and_context->isolate();
+  v8::HandleScope scope(isolate);
+  v8::Handle<v8::Context> context = callback_and_context->GetContext();
+  v8::Context::Scope context_scope(context);
+  WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
+  if (frame) {
+    scoped_ptr<V8ValueConverter> converter =
+        make_scoped_ptr(V8ValueConverter::create());
+    v8::Handle<v8::Value> value = converter->ToV8Value(result.get(), context);
+    v8::Handle<v8::Value> argv[] = { value };
+
+    frame->callFunctionEvenIfScriptDisabled(
+        callback_and_context->GetCallback(),
+        v8::Object::New(isolate),
+        1,
+        argv);
+  }
+}
+
+void OnSnapshotCompleted(CallbackAndContext* callback_and_context,
+                         const gfx::Size& size,
+                         const std::vector<unsigned char>& png) {
+  v8::Isolate* isolate = callback_and_context->isolate();
+  v8::HandleScope scope(isolate);
+  v8::Handle<v8::Context> context = callback_and_context->GetContext();
+  v8::Context::Scope context_scope(context);
+  WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
+  if (frame) {
+    v8::Handle<v8::Value> result;
+
+    if (!size.IsEmpty()) {
+      v8::Handle<v8::Object> result_object;
+      result_object = v8::Object::New(isolate);
+
+      result_object->Set(v8::String::NewFromUtf8(isolate, "width"),
+                         v8::Number::New(isolate, size.width()));
+      result_object->Set(v8::String::NewFromUtf8(isolate, "height"),
+                         v8::Number::New(isolate, size.height()));
+
+      std::string base64_png;
+      base::Base64Encode(
+          base::StringPiece(reinterpret_cast<const char*>(&*png.begin()),
+                            png.size()),
+          &base64_png);
+
+      result_object->Set(v8::String::NewFromUtf8(isolate, "data"),
+                         v8::String::NewFromUtf8(isolate,
+                                                 base64_png.c_str(),
+                                                 v8::String::kNormalString,
+                                                 base64_png.size()));
+
+      result = result_object;
+    } else {
+      result = v8::Null(isolate);
+    }
+
+    v8::Handle<v8::Value> argv[] = {result};
+
+    frame->callFunctionEvenIfScriptDisabled(
+        callback_and_context->GetCallback(), v8::Object::New(isolate), 1, argv);
+  }
+}
+
+void OnSyntheticGestureCompleted(CallbackAndContext* callback_and_context) {
+  v8::Isolate* isolate = callback_and_context->isolate();
+  v8::HandleScope scope(isolate);
+  v8::Handle<v8::Context> context = callback_and_context->GetContext();
+  v8::Context::Scope context_scope(context);
+  WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
+  if (frame) {
+    frame->callFunctionEvenIfScriptDisabled(
+        callback_and_context->GetCallback(), v8::Object::New(isolate), 0, NULL);
+  }
+}
+
+bool BeginSmoothScroll(v8::Isolate* isolate,
+                       int pixels_to_scroll,
+                       v8::Handle<v8::Function> callback,
+                       int gesture_source_type,
+                       const std::string& direction,
+                       int speed_in_pixels_s,
+                       bool prevent_fling,
+                       int start_x,
+                       int start_y) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(false))
+    return false;
+
+  scoped_refptr<CallbackAndContext> callback_and_context =
+      new CallbackAndContext(
+          isolate, callback, context.web_frame()->mainWorldScriptContext());
+
+  scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
+      new SyntheticSmoothScrollGestureParams);
+
+  // Convert coordinates from CSS pixels to density independent pixels (DIPs).
+  float page_scale_factor = context.web_view()->pageScaleFactor();
+
+  if (gesture_source_type < 0 ||
+      gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
+    return false;
+  }
+  gesture_params->gesture_source_type =
+      static_cast<SyntheticGestureParams::GestureSourceType>(
+          gesture_source_type);
+
+  gesture_params->speed_in_pixels_s = speed_in_pixels_s;
+  gesture_params->prevent_fling = prevent_fling;
+
+  gesture_params->anchor.SetPoint(start_x * page_scale_factor,
+                                  start_y * page_scale_factor);
+
+  int distance_length = pixels_to_scroll * page_scale_factor;
+  gfx::Vector2d distance;
+  if (direction == "down")
+    distance.set_y(-distance_length);
+  else if (direction == "up")
+    distance.set_y(distance_length);
+  else if (direction == "right")
+    distance.set_x(-distance_length);
+  else if (direction == "left")
+    distance.set_x(distance_length);
+  else {
+    return false;
+  }
+  gesture_params->distances.push_back(distance);
+
+  // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
+  // progress, we will leak the callback and context. This needs to be fixed,
+  // somehow.
+  context.render_view_impl()->QueueSyntheticGesture(
+      gesture_params.Pass(),
+      base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
+
+  return true;
+}
+
 }  // namespace
 
-class GpuBenchmarkingWrapper : public v8::Extension {
- public:
-  GpuBenchmarkingWrapper() :
-      v8::Extension(kGpuBenchmarkingExtensionName,
-            "if (typeof(chrome) == 'undefined') {"
-            "  chrome = {};"
-            "};"
-            "if (typeof(chrome.gpuBenchmarking) == 'undefined') {"
-            "  chrome.gpuBenchmarking = {};"
-            "};"
-            "chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers = function() {"
-            "  native function SetNeedsDisplayOnAllLayers();"
-            "  return SetNeedsDisplayOnAllLayers();"
-            "};"
-            "chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent = "
-            "function() {"
-            "  native function SetRasterizeOnlyVisibleContent();"
-            "  return SetRasterizeOnlyVisibleContent();"
-            "};"
-            "chrome.gpuBenchmarking.printToSkPicture = function(dirname) {"
-            "  native function PrintToSkPicture();"
-            "  return PrintToSkPicture(dirname);"
-            "};"
-            "chrome.gpuBenchmarking.DEFAULT_INPUT = 0;"
-            "chrome.gpuBenchmarking.TOUCH_INPUT = 1;"
-            "chrome.gpuBenchmarking.MOUSE_INPUT = 2;"
-            "chrome.gpuBenchmarking.gestureSourceTypeSupported = "
-            "    function(gesture_source_type) {"
-            "  native function GestureSourceTypeSupported();"
-            "  return GestureSourceTypeSupported(gesture_source_type);"
-            "};"
-            "chrome.gpuBenchmarking.smoothScrollBy = "
-            "    function(pixels_to_scroll, opt_callback, opt_start_x,"
-            "             opt_start_y, opt_gesture_source_type,"
-            "             opt_direction, opt_speed_in_pixels_s) {"
-            "  pixels_to_scroll = pixels_to_scroll || 0;"
-            "  callback = opt_callback || function() { };"
-            "  gesture_source_type = opt_gesture_source_type ||"
-            "      chrome.gpuBenchmarking.DEFAULT_INPUT;"
-            "  direction = opt_direction || 'down';"
-            "  speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
-            "  native function BeginSmoothScroll();"
-            "  return BeginSmoothScroll(pixels_to_scroll, callback,"
-            "                           gesture_source_type, direction,"
-            "                           speed_in_pixels_s, true,"
-            "                           opt_start_x, opt_start_y);"
-            "};"
-            "chrome.gpuBenchmarking.swipe = "
-            "    function(direction, distance, opt_callback,"
-            "             opt_start_x, opt_start_y,"
-            "             opt_speed_in_pixels_s) {"
-            "  direction = direction || 'up';"
-            "  distance = distance || 0;"
-            "  callback = opt_callback || function() { };"
-            "  speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
-            "  native function BeginSmoothScroll();"
-            "  return BeginSmoothScroll(-distance, callback,"
-            "                           chrome.gpuBenchmarking.TOUCH_INPUT,"
-            "                           direction, speed_in_pixels_s, false,"
-            "                           opt_start_x, opt_start_y);"
-            "};"
-            "chrome.gpuBenchmarking.scrollBounce = "
-            "    function(direction, distance, overscroll, opt_repeat_count,"
-            "             opt_callback, opt_start_x, opt_start_y,"
-            "             opt_speed_in_pixels_s) {"
-            "  direction = direction || 'down';"
-            "  distance = distance || 0;"
-            "  overscroll = overscroll || 0;"
-            "  repeat_count = opt_repeat_count || 1;"
-            "  callback = opt_callback || function() { };"
-            "  speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
-            "  native function BeginScrollBounce();"
-            "  return BeginScrollBounce(direction, distance, overscroll,"
-            "                           repeat_count, callback,"
-            "                           speed_in_pixels_s,"
-            "                           opt_start_x, opt_start_y);"
-            "};"
-            // TODO(dominikg): Remove once JS interface changes have rolled into
-            //                 stable.
-            "chrome.gpuBenchmarking.newPinchInterface = true;"
-            "chrome.gpuBenchmarking.pinchBy = "
-            "    function(scale_factor, anchor_x, anchor_y,"
-            "             opt_callback, "
-            "opt_relative_pointer_speed_in_pixels_s) {"
-            "  callback = opt_callback || function() { };"
-            "  relative_pointer_speed_in_pixels_s ="
-            "      opt_relative_pointer_speed_in_pixels_s || 800;"
-            "  native function BeginPinch();"
-            "  return BeginPinch(scale_factor, anchor_x, anchor_y, callback,"
-            "                    relative_pointer_speed_in_pixels_s);"
-            "};"
-            "chrome.gpuBenchmarking.tap = "
-            "    function(position_x, position_y, opt_callback, "
-            "opt_duration_ms,"
-            "             opt_gesture_source_type) {"
-            "  callback = opt_callback || function() { };"
-            "  duration_ms = opt_duration_ms || 50;"
-            "  gesture_source_type = opt_gesture_source_type ||"
-            "      chrome.gpuBenchmarking.DEFAULT_INPUT;"
-            "  native function BeginTap();"
-            "  return BeginTap(position_x, position_y, callback, duration_ms,"
-            "                  gesture_source_type);"
-            "};"
-            "chrome.gpuBenchmarking.beginWindowSnapshotPNG = "
-            "function(callback) {"
-            "  native function BeginWindowSnapshotPNG();"
-            "  BeginWindowSnapshotPNG(callback);"
-            "};"
-            "chrome.gpuBenchmarking.clearImageCache = function() {"
-            "  native function ClearImageCache();"
-            "  ClearImageCache();"
-            "};"
-            "chrome.gpuBenchmarking.runMicroBenchmark ="
-            "    function(name, callback, opt_arguments) {"
-            "  arguments = opt_arguments || {};"
-            "  native function RunMicroBenchmark();"
-            "  return RunMicroBenchmark(name, callback, arguments);"
-            "};"
-            "chrome.gpuBenchmarking.sendMessageToMicroBenchmark ="
-            "    function(id, arguments) {"
-            "  native function SendMessageToMicroBenchmark();"
-            "  return SendMessageToMicroBenchmark(id, arguments);"
-            "};"
-            "chrome.gpuBenchmarking.hasGpuProcess = function() {"
-            "  native function HasGpuProcess();"
-            "  return HasGpuProcess();"
-            "};") {}
+gin::WrapperInfo GpuBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin};
 
-  v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
-      v8::Isolate* isolate,
-      v8::Handle<v8::String> name) override {
-    if (name->Equals(
-            v8::String::NewFromUtf8(isolate, "SetNeedsDisplayOnAllLayers")))
-      return v8::FunctionTemplate::New(isolate, SetNeedsDisplayOnAllLayers);
-    if (name->Equals(
-            v8::String::NewFromUtf8(isolate, "SetRasterizeOnlyVisibleContent")))
-      return v8::FunctionTemplate::New(isolate, SetRasterizeOnlyVisibleContent);
-    if (name->Equals(v8::String::NewFromUtf8(isolate, "PrintToSkPicture")))
-      return v8::FunctionTemplate::New(isolate, PrintToSkPicture);
-    if (name->Equals(
-            v8::String::NewFromUtf8(isolate, "GestureSourceTypeSupported")))
-      return v8::FunctionTemplate::New(isolate, GestureSourceTypeSupported);
-    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginSmoothScroll")))
-      return v8::FunctionTemplate::New(isolate, BeginSmoothScroll);
-    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginScrollBounce")))
-      return v8::FunctionTemplate::New(isolate, BeginScrollBounce);
-    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginPinch")))
-      return v8::FunctionTemplate::New(isolate, BeginPinch);
-    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginTap")))
-      return v8::FunctionTemplate::New(isolate, BeginTap);
-    if (name->Equals(
-            v8::String::NewFromUtf8(isolate, "BeginWindowSnapshotPNG")))
-      return v8::FunctionTemplate::New(isolate, BeginWindowSnapshotPNG);
-    if (name->Equals(v8::String::NewFromUtf8(isolate, "ClearImageCache")))
-      return v8::FunctionTemplate::New(isolate, ClearImageCache);
-    if (name->Equals(v8::String::NewFromUtf8(isolate, "RunMicroBenchmark")))
-      return v8::FunctionTemplate::New(isolate, RunMicroBenchmark);
-    if (name->Equals(
-            v8::String::NewFromUtf8(isolate, "SendMessageToMicroBenchmark")))
-      return v8::FunctionTemplate::New(isolate, SendMessageToMicroBenchmark);
-    if (name->Equals(v8::String::NewFromUtf8(isolate, "HasGpuProcess")))
-      return v8::FunctionTemplate::New(isolate, HasGpuProcess);
+// static
+void GpuBenchmarking::Install(blink::WebFrame* frame) {
+  v8::Isolate* isolate = blink::mainThreadIsolate();
+  v8::HandleScope handle_scope(isolate);
+  v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
+  if (context.IsEmpty())
+    return;
 
-    return v8::Handle<v8::FunctionTemplate>();
+  v8::Context::Scope context_scope(context);
+
+  gin::Handle<GpuBenchmarking> controller =
+      gin::CreateHandle(isolate, new GpuBenchmarking());
+  if (controller.IsEmpty())
+    return;
+
+  v8::Handle<v8::Object> chrome = GetOrCreateChromeObject(isolate,
+                                                          context->Global());
+  chrome->Set(gin::StringToV8(isolate, "gpuBenchmarking"), controller.ToV8());
+}
+
+GpuBenchmarking::GpuBenchmarking() {
+}
+
+GpuBenchmarking::~GpuBenchmarking() {
+}
+
+gin::ObjectTemplateBuilder GpuBenchmarking::GetObjectTemplateBuilder(
+    v8::Isolate* isolate) {
+  return gin::Wrappable<GpuBenchmarking>::GetObjectTemplateBuilder(isolate)
+      .SetMethod("setNeedsDisplayOnAllLayers",
+                 &GpuBenchmarking::SetNeedsDisplayOnAllLayers)
+      .SetMethod("setRasterizeOnlyVisibleContent",
+                 &GpuBenchmarking::SetRasterizeOnlyVisibleContent)
+      .SetMethod("printToSkPicture", &GpuBenchmarking::PrintToSkPicture)
+      .SetValue("DEFAULT_INPUT", 0)
+      .SetValue("TOUCH_INPUT", 1)
+      .SetValue("MOUSE_INPUT", 2)
+      .SetMethod("gestureSourceTypeSupported",
+                 &GpuBenchmarking::GestureSourceTypeSupported)
+      .SetMethod("smoothScrollBy", &GpuBenchmarking::SmoothScrollBy)
+      .SetMethod("swipe", &GpuBenchmarking::Swipe)
+      .SetMethod("scrollBounce", &GpuBenchmarking::ScrollBounce)
+      // TODO(dominikg): Remove once JS interface changes have rolled into
+      //                 stable.
+      .SetValue("newPinchInterface", true)
+      .SetMethod("pinchBy", &GpuBenchmarking::PinchBy)
+      .SetMethod("tap", &GpuBenchmarking::Tap)
+      .SetMethod("beginWindowSnapshotPNG",
+                 &GpuBenchmarking::BeginWindowSnapshotPNG)
+      .SetMethod("clearImageCache", &GpuBenchmarking::ClearImageCache)
+      .SetMethod("runMicroBenchmark", &GpuBenchmarking::RunMicroBenchmark)
+      .SetMethod("sendMessageToMicroBenchmark",
+                 &GpuBenchmarking::SendMessageToMicroBenchmark)
+      .SetMethod("hasGpuProcess", &GpuBenchmarking::HasGpuProcess);
+}
+
+void GpuBenchmarking::SetNeedsDisplayOnAllLayers() {
+  GpuBenchmarkingContext context;
+  if (!context.Init(true))
+    return;
+
+  context.compositor()->SetNeedsDisplayOnAllLayers();
+}
+
+void GpuBenchmarking::SetRasterizeOnlyVisibleContent() {
+  GpuBenchmarkingContext context;
+  if (!context.Init(true))
+    return;
+
+  context.compositor()->SetRasterizeOnlyVisibleContent();
+}
+
+void GpuBenchmarking::PrintToSkPicture(v8::Isolate* isolate,
+                                       const std::string& dirname) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(true))
+    return;
+
+  const cc::Layer* root_layer = context.compositor()->GetRootLayer();
+  if (!root_layer)
+    return;
+
+  base::FilePath dirpath = base::FilePath::FromUTF8Unsafe(dirname);
+  if (!base::CreateDirectory(dirpath) ||
+      !base::PathIsWritable(dirpath)) {
+    std::string msg("Path is not writable: ");
+    msg.append(dirpath.MaybeAsASCII());
+    isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
+        isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
+    return;
   }
 
-  static void SetNeedsDisplayOnAllLayers(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(true))
-      return;
+  SkPictureSerializer serializer(dirpath);
+  serializer.Serialize(root_layer);
+}
 
-    context.compositor()->SetNeedsDisplayOnAllLayers();
+bool GpuBenchmarking::GestureSourceTypeSupported(int gesture_source_type) {
+  if (gesture_source_type < 0 ||
+      gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
+    return false;
   }
 
-  static void SetRasterizeOnlyVisibleContent(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(true))
-      return;
+  return SyntheticGestureParams::IsGestureSourceTypeSupported(
+      static_cast<SyntheticGestureParams::GestureSourceType>(
+          gesture_source_type));
+}
 
-    context.compositor()->SetRasterizeOnlyVisibleContent();
+bool GpuBenchmarking::SmoothScrollBy(gin::Arguments* args) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(true))
+    return false;
+
+  float page_scale_factor = context.web_view()->pageScaleFactor();
+  blink::WebRect rect = context.render_view_impl()->windowRect();
+
+  int pixels_to_scroll = 0;
+  v8::Handle<v8::Function> callback;
+  int start_x = rect.width / (page_scale_factor * 2);
+  int start_y = rect.height / (page_scale_factor * 2);
+  int gesture_source_type = 0;  // DEFAULT_INPUT
+  std::string direction = "down";
+  int speed_in_pixels_s = 800;
+
+  if (!GetOptionalArg(args, &pixels_to_scroll) ||
+      !GetOptionalArg(args, &callback) ||
+      !GetOptionalArg(args, &start_x) ||
+      !GetOptionalArg(args, &start_y) ||
+      !GetOptionalArg(args, &gesture_source_type) ||
+      !GetOptionalArg(args, &direction) ||
+      !GetOptionalArg(args, &speed_in_pixels_s)) {
+    return false;
   }
 
-  static void PrintToSkPicture(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    if (args.Length() != 1)
-      return;
+  return BeginSmoothScroll(args->isolate(),
+                           pixels_to_scroll,
+                           callback,
+                           gesture_source_type,
+                           direction,
+                           speed_in_pixels_s,
+                           true,
+                           start_x,
+                           start_y);
+}
 
-    v8::String::Utf8Value dirname(args[0]);
-    if (dirname.length() == 0)
-      return;
+bool GpuBenchmarking::Swipe(gin::Arguments* args) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(true))
+    return false;
 
-    GpuBenchmarkingContext context;
-    if (!context.Init(true))
-      return;
+  float page_scale_factor = context.web_view()->pageScaleFactor();
+  blink::WebRect rect = context.render_view_impl()->windowRect();
 
-    const cc::Layer* root_layer = context.compositor()->GetRootLayer();
-    if (!root_layer)
-      return;
+  std::string direction = "up";
+  int pixels_to_scroll = 0;
+  v8::Handle<v8::Function> callback;
+  int start_x = rect.width / (page_scale_factor * 2);
+  int start_y = rect.height / (page_scale_factor * 2);
+  int speed_in_pixels_s = 800;
 
-    base::FilePath dirpath(
-        base::FilePath::StringType(*dirname, *dirname + dirname.length()));
-    if (!base::CreateDirectory(dirpath) ||
-        !base::PathIsWritable(dirpath)) {
-      std::string msg("Path is not writable: ");
-      msg.append(dirpath.MaybeAsASCII());
-      v8::Isolate* isolate = args.GetIsolate();
-      isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
-          isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
-      return;
-    }
-
-    SkPictureSerializer serializer(dirpath);
-    serializer.Serialize(root_layer);
+  if (!GetOptionalArg(args, &direction) ||
+      !GetOptionalArg(args, &pixels_to_scroll) ||
+      !GetOptionalArg(args, &callback) ||
+      !GetOptionalArg(args, &start_x) ||
+      !GetOptionalArg(args, &start_y) ||
+      !GetOptionalArg(args, &speed_in_pixels_s)) {
+    return false;
   }
 
-  static void OnSyntheticGestureCompleted(
-      CallbackAndContext* callback_and_context) {
-    v8::Isolate* isolate = callback_and_context->isolate();
-    v8::HandleScope scope(isolate);
-    v8::Handle<v8::Context> context = callback_and_context->GetContext();
-    v8::Context::Scope context_scope(context);
-    WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
-    if (frame) {
-      frame->callFunctionEvenIfScriptDisabled(
-          callback_and_context->GetCallback(),
-          v8::Object::New(isolate),
-          0,
-          NULL);
-    }
+  return BeginSmoothScroll(args->isolate(),
+                           -pixels_to_scroll,
+                           callback,
+                           1,  // TOUCH_INPUT
+                           direction,
+                           speed_in_pixels_s,
+                           false,
+                           start_x,
+                           start_y);
+}
+
+bool GpuBenchmarking::ScrollBounce(gin::Arguments* args) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(false))
+    return false;
+
+  float page_scale_factor = context.web_view()->pageScaleFactor();
+  blink::WebRect rect = context.render_view_impl()->windowRect();
+
+  std::string direction = "down";
+  int distance_length = 0;
+  int overscroll_length = 0;
+  int repeat_count = 1;
+  v8::Handle<v8::Function> callback;
+  int start_x = rect.width / (page_scale_factor * 2);
+  int start_y = rect.height / (page_scale_factor * 2);
+  int speed_in_pixels_s = 800;
+
+  if (!GetOptionalArg(args, &direction) ||
+      !GetOptionalArg(args, &distance_length) ||
+      !GetOptionalArg(args, &overscroll_length) ||
+      !GetOptionalArg(args, &repeat_count) ||
+      !GetOptionalArg(args, &callback) ||
+      !GetOptionalArg(args, &start_x) ||
+      !GetOptionalArg(args, &start_y) ||
+      !GetOptionalArg(args, &speed_in_pixels_s)) {
+    return false;
   }
 
-  static void GestureSourceTypeSupported(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    if (args.Length() != 1 || !args[0]->IsNumber()) {
-      args.GetReturnValue().Set(false);
-      return;
-    }
+  scoped_refptr<CallbackAndContext> callback_and_context =
+      new CallbackAndContext(args->isolate(),
+                             callback,
+                             context.web_frame()->mainWorldScriptContext());
 
-    int gesture_source_type = args[0]->IntegerValue();
-    if (gesture_source_type < 0 ||
-        gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
-      args.GetReturnValue().Set(false);
-      return;
-    }
+  scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
+      new SyntheticSmoothScrollGestureParams);
 
-    bool is_supported = SyntheticGestureParams::IsGestureSourceTypeSupported(
-        static_cast<SyntheticGestureParams::GestureSourceType>(
-            gesture_source_type));
-    args.GetReturnValue().Set(is_supported);
+  gesture_params->speed_in_pixels_s = speed_in_pixels_s;
+
+  gesture_params->anchor.SetPoint(start_x * page_scale_factor,
+                                  start_y * page_scale_factor);
+
+  distance_length *= page_scale_factor;
+  overscroll_length *= page_scale_factor;
+  gfx::Vector2d distance;
+  gfx::Vector2d overscroll;
+  if (direction == "down") {
+    distance.set_y(-distance_length);
+    overscroll.set_y(overscroll_length);
+  } else if (direction == "up") {
+    distance.set_y(distance_length);
+    overscroll.set_y(-overscroll_length);
+  } else if (direction == "right") {
+    distance.set_x(-distance_length);
+    overscroll.set_x(overscroll_length);
+  } else if (direction == "left") {
+    distance.set_x(distance_length);
+    overscroll.set_x(-overscroll_length);
+  } else {
+    return false;
   }
 
-  static void BeginSmoothScroll(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(false))
-      return;
-
-    // The last two arguments can be undefined. We check their validity later.
-    int arglen = args.Length();
-    if (arglen < 8 ||
-        !args[0]->IsNumber() ||
-        !args[1]->IsFunction() ||
-        !args[2]->IsNumber() ||
-        !args[3]->IsString() ||
-        !args[4]->IsNumber() ||
-        !args[5]->IsBoolean()) {
-      args.GetReturnValue().Set(false);
-      return;
-    }
-
-    v8::Local<v8::Function> callback_local =
-        v8::Local<v8::Function>::Cast(args[1]);
-
-    scoped_refptr<CallbackAndContext> callback_and_context =
-        new CallbackAndContext(args.GetIsolate(),
-                               callback_local,
-                               context.web_frame()->mainWorldScriptContext());
-
-    scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
-        new SyntheticSmoothScrollGestureParams);
-
-    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
-    float page_scale_factor = context.web_view()->pageScaleFactor();
-
-    int gesture_source_type = args[2]->IntegerValue();
-    if (gesture_source_type < 0 ||
-        gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
-      args.GetReturnValue().Set(false);
-      return;
-    }
-    gesture_params->gesture_source_type =
-        static_cast<SyntheticGestureParams::GestureSourceType>(
-            gesture_source_type);
-
-    gesture_params->speed_in_pixels_s = args[4]->IntegerValue();
-    gesture_params->prevent_fling = args[5]->BooleanValue();
-
-    // Account for the 2 optional arguments, start_x and start_y.
-    gfx::Point anchor;
-    if (args[6]->IsUndefined() || args[7]->IsUndefined()) {
-      blink::WebRect rect = context.render_view_impl()->windowRect();
-      anchor.SetPoint(rect.width / 2, rect.height / 2);
-    } else if (args[6]->IsNumber() && args[7]->IsNumber()) {
-      anchor.SetPoint(args[6]->IntegerValue() * page_scale_factor,
-                      args[7]->IntegerValue() * page_scale_factor);
-    } else {
-      args.GetReturnValue().Set(false);
-      return;
-    }
-    gesture_params->anchor = anchor;
-
-    int distance_length = args[0]->IntegerValue() * page_scale_factor;
-    gfx::Vector2d distance;
-    v8::String::Utf8Value direction(args[3]);
-    DCHECK(*direction);
-    std::string direction_str(*direction);
-    if (direction_str == "down")
-      distance.set_y(-distance_length);
-    else if (direction_str == "up")
-      distance.set_y(distance_length);
-    else if (direction_str == "right")
-      distance.set_x(-distance_length);
-    else if (direction_str == "left")
-      distance.set_x(distance_length);
-    else {
-      args.GetReturnValue().Set(false);
-      return;
-    }
+  for (int i = 0; i < repeat_count; i++) {
     gesture_params->distances.push_back(distance);
-
-    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
-    // progress, we will leak the callback and context. This needs to be fixed,
-    // somehow.
-    context.render_view_impl()->QueueSyntheticGesture(
-        gesture_params.Pass(),
-        base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
-
-    args.GetReturnValue().Set(true);
+    gesture_params->distances.push_back(-distance + overscroll);
   }
 
-  static void BeginScrollBounce(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(false))
-      return;
+  // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
+  // progress, we will leak the callback and context. This needs to be fixed,
+  // somehow.
+  context.render_view_impl()->QueueSyntheticGesture(
+      gesture_params.Pass(),
+      base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
 
-    // The last two arguments can be undefined. We check their validity later.
-    int arglen = args.Length();
-    if (arglen < 8 ||
-        !args[0]->IsString() ||
-        !args[1]->IsNumber() ||
-        !args[2]->IsNumber() ||
-        !args[3]->IsNumber() ||
-        !args[4]->IsFunction() ||
-        !args[5]->IsNumber()) {
-      args.GetReturnValue().Set(false);
-      return;
-    }
+  return true;
+}
 
-    v8::Local<v8::Function> callback_local =
-        v8::Local<v8::Function>::Cast(args[4]);
+bool GpuBenchmarking::PinchBy(gin::Arguments* args) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(false))
+    return false;
 
-    scoped_refptr<CallbackAndContext> callback_and_context =
-        new CallbackAndContext(args.GetIsolate(),
-                               callback_local,
-                               context.web_frame()->mainWorldScriptContext());
+  float scale_factor;
+  int anchor_x;
+  int anchor_y;
+  v8::Handle<v8::Function> callback;
+  int relative_pointer_speed_in_pixels_s = 800;
 
-    scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
-        new SyntheticSmoothScrollGestureParams);
 
-    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
-    float page_scale_factor = context.web_view()->pageScaleFactor();
-
-    gesture_params->speed_in_pixels_s = args[5]->IntegerValue();
-
-    // Account for the 2 optional arguments, start_x and start_y.
-    gfx::Point start;
-    if (args[6]->IsUndefined() || args[7]->IsUndefined()) {
-      blink::WebRect rect = context.render_view_impl()->windowRect();
-      start.SetPoint(rect.width / 2, rect.height / 2);
-    } else if (args[6]->IsNumber() && args[7]->IsNumber()) {
-      start.SetPoint(args[6]->IntegerValue() * page_scale_factor,
-                     args[7]->IntegerValue() * page_scale_factor);
-    } else {
-      args.GetReturnValue().Set(false);
-      return;
-    }
-
-    int distance_length = args[1]->IntegerValue() * page_scale_factor;
-    int overscroll_length = args[2]->IntegerValue() * page_scale_factor;
-    gfx::Vector2d distance;
-    gfx::Vector2d overscroll;
-    v8::String::Utf8Value direction(args[0]);
-    DCHECK(*direction);
-    std::string direction_str(*direction);
-    if (direction_str == "down") {
-      distance.set_y(-distance_length);
-      overscroll.set_y(overscroll_length);
-    }
-    else if (direction_str == "up") {
-      distance.set_y(distance_length);
-      overscroll.set_y(-overscroll_length);
-    }
-    else if (direction_str == "right") {
-      distance.set_x(-distance_length);
-      overscroll.set_x(overscroll_length);
-    }
-    else if (direction_str == "left") {
-      distance.set_x(distance_length);
-      overscroll.set_x(-overscroll_length);
-    }
-    else {
-      args.GetReturnValue().Set(false);
-      return;
-    }
-
-    int repeat_count = args[3]->IntegerValue();
-    gesture_params->anchor = start;
-    for (int i = 0; i < repeat_count; i++) {
-      gesture_params->distances.push_back(distance);
-      gesture_params->distances.push_back(-distance + overscroll);
-    }
-
-    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
-    // progress, we will leak the callback and context. This needs to be fixed,
-    // somehow.
-    context.render_view_impl()->QueueSyntheticGesture(
-        gesture_params.Pass(),
-        base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
-
-    args.GetReturnValue().Set(true);
+  if (!GetArg(args, &scale_factor) ||
+      !GetArg(args, &anchor_x) ||
+      !GetArg(args, &anchor_y) ||
+      !GetOptionalArg(args, &callback) ||
+      !GetOptionalArg(args, &relative_pointer_speed_in_pixels_s)) {
+    return false;
   }
 
-  static void BeginPinch(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(false))
-      return;
+  scoped_ptr<SyntheticPinchGestureParams> gesture_params(
+      new SyntheticPinchGestureParams);
 
-    int arglen = args.Length();
-    if (arglen < 5 ||
-        !args[0]->IsNumber() ||
-        !args[1]->IsNumber() ||
-        !args[2]->IsNumber() ||
-        !args[3]->IsFunction() ||
-        !args[4]->IsNumber()) {
-      args.GetReturnValue().Set(false);
-      return;
-    }
+  // Convert coordinates from CSS pixels to density independent pixels (DIPs).
+  float page_scale_factor = context.web_view()->pageScaleFactor();
 
-    scoped_ptr<SyntheticPinchGestureParams> gesture_params(
-        new SyntheticPinchGestureParams);
+  gesture_params->scale_factor = scale_factor;
+  gesture_params->anchor.SetPoint(anchor_x * page_scale_factor,
+                                  anchor_y * page_scale_factor);
+  gesture_params->relative_pointer_speed_in_pixels_s =
+      relative_pointer_speed_in_pixels_s;
 
-    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
-    float page_scale_factor = context.web_view()->pageScaleFactor();
-
-    gesture_params->scale_factor = args[0]->NumberValue();
-    gesture_params->anchor.SetPoint(
-        args[1]->IntegerValue() * page_scale_factor,
-        args[2]->IntegerValue() * page_scale_factor);
-    gesture_params->relative_pointer_speed_in_pixels_s =
-        args[4]->IntegerValue();
-
-    v8::Local<v8::Function> callback_local =
-        v8::Local<v8::Function>::Cast(args[3]);
-
-    scoped_refptr<CallbackAndContext> callback_and_context =
-        new CallbackAndContext(args.GetIsolate(),
-                               callback_local,
-                               context.web_frame()->mainWorldScriptContext());
+  scoped_refptr<CallbackAndContext> callback_and_context =
+      new CallbackAndContext(args->isolate(),
+                             callback,
+                             context.web_frame()->mainWorldScriptContext());
 
 
-    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
-    // progress, we will leak the callback and context. This needs to be fixed,
-    // somehow.
-    context.render_view_impl()->QueueSyntheticGesture(
-        gesture_params.Pass(),
-        base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
+  // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
+  // progress, we will leak the callback and context. This needs to be fixed,
+  // somehow.
+  context.render_view_impl()->QueueSyntheticGesture(
+      gesture_params.Pass(),
+      base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
 
-    args.GetReturnValue().Set(true);
+  return true;
+}
+
+bool GpuBenchmarking::Tap(gin::Arguments* args) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(false))
+    return false;
+
+  int position_x;
+  int position_y;
+  v8::Handle<v8::Function> callback;
+  int duration_ms = 50;
+  int gesture_source_type = 0;  // DEFAULT_INPUT
+
+  if (!GetArg(args, &position_x) ||
+      !GetArg(args, &position_y) ||
+      !GetOptionalArg(args, &callback) ||
+      !GetOptionalArg(args, &duration_ms) ||
+      !GetOptionalArg(args, &gesture_source_type)) {
+    return false;
   }
 
-  static void BeginTap(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(false))
-      return;
+  scoped_ptr<SyntheticTapGestureParams> gesture_params(
+      new SyntheticTapGestureParams);
 
-    int arglen = args.Length();
-    if (arglen < 5 ||
-        !args[0]->IsNumber() ||
-        !args[1]->IsNumber() ||
-        !args[2]->IsFunction() ||
-        !args[3]->IsNumber() ||
-        !args[4]->IsNumber()) {
-      args.GetReturnValue().Set(false);
-      return;
-    }
+  // Convert coordinates from CSS pixels to density independent pixels (DIPs).
+  float page_scale_factor = context.web_view()->pageScaleFactor();
 
-    scoped_ptr<SyntheticTapGestureParams> gesture_params(
-        new SyntheticTapGestureParams);
+  gesture_params->position.SetPoint(position_x * page_scale_factor,
+                                    position_y * page_scale_factor);
+  gesture_params->duration_ms = duration_ms;
 
-    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
-    float page_scale_factor = context.web_view()->pageScaleFactor();
+  if (gesture_source_type < 0 ||
+      gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
+    return false;
+  }
+  gesture_params->gesture_source_type =
+      static_cast<SyntheticGestureParams::GestureSourceType>(
+          gesture_source_type);
 
-    gesture_params->position.SetPoint(
-        args[0]->IntegerValue() * page_scale_factor,
-        args[1]->IntegerValue() * page_scale_factor);
-    gesture_params->duration_ms = args[3]->IntegerValue();
+  scoped_refptr<CallbackAndContext> callback_and_context =
+      new CallbackAndContext(args->isolate(),
+                             callback,
+                             context.web_frame()->mainWorldScriptContext());
 
-    int gesture_source_type = args[4]->IntegerValue();
-    if (gesture_source_type < 0 ||
-        gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
-      args.GetReturnValue().Set(false);
-      return;
-    }
-    gesture_params->gesture_source_type =
-        static_cast<SyntheticGestureParams::GestureSourceType>(
-            gesture_source_type);
+  // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
+  // progress, we will leak the callback and context. This needs to be fixed,
+  // somehow.
+  context.render_view_impl()->QueueSyntheticGesture(
+      gesture_params.Pass(),
+      base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
 
-    v8::Local<v8::Function> callback_local =
-        v8::Local<v8::Function>::Cast(args[2]);
+  return true;
+}
 
-    scoped_refptr<CallbackAndContext> callback_and_context =
-        new CallbackAndContext(args.GetIsolate(),
-                               callback_local,
-                               context.web_frame()->mainWorldScriptContext());
+void GpuBenchmarking::BeginWindowSnapshotPNG(
+    v8::Isolate* isolate,
+    v8::Handle<v8::Function> callback) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(false))
+    return;
 
+  scoped_refptr<CallbackAndContext> callback_and_context =
+      new CallbackAndContext(isolate,
+                             callback,
+                             context.web_frame()->mainWorldScriptContext());
 
-    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
-    // progress, we will leak the callback and context. This needs to be fixed,
-    // somehow.
-    context.render_view_impl()->QueueSyntheticGesture(
-        gesture_params.Pass(),
-        base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
+  context.render_view_impl()->GetWindowSnapshot(
+      base::Bind(&OnSnapshotCompleted, callback_and_context));
+}
 
-    args.GetReturnValue().Set(true);
+void GpuBenchmarking::ClearImageCache() {
+  WebImageCache::clear();
+}
+
+int GpuBenchmarking::RunMicroBenchmark(gin::Arguments* args) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(true))
+    return 0;
+
+  std::string name;
+  v8::Handle<v8::Function> callback;
+  v8::Handle<v8::Object> arguments;
+
+  if (!GetArg(args, &name) || !GetArg(args, &callback) ||
+      !GetOptionalArg(args, &arguments)) {
+    return 0;
   }
 
-  static void OnSnapshotCompleted(CallbackAndContext* callback_and_context,
-                                  const gfx::Size& size,
-                                  const std::vector<unsigned char>& png) {
-    v8::Isolate* isolate = callback_and_context->isolate();
-    v8::HandleScope scope(isolate);
-    v8::Handle<v8::Context> context = callback_and_context->GetContext();
-    v8::Context::Scope context_scope(context);
-    WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
-    if (frame) {
+  scoped_refptr<CallbackAndContext> callback_and_context =
+      new CallbackAndContext(args->isolate(),
+                             callback,
+                             context.web_frame()->mainWorldScriptContext());
 
-      v8::Handle<v8::Value> result;
+  scoped_ptr<V8ValueConverter> converter =
+      make_scoped_ptr(V8ValueConverter::create());
+  v8::Handle<v8::Context> v8_context = callback_and_context->GetContext();
+  scoped_ptr<base::Value> value =
+      make_scoped_ptr(converter->FromV8Value(arguments, v8_context));
 
-      if(!size.IsEmpty()) {
-        v8::Handle<v8::Object> result_object;
-        result_object = v8::Object::New(isolate);
+  return context.compositor()->ScheduleMicroBenchmark(
+      name,
+      value.Pass(),
+      base::Bind(&OnMicroBenchmarkCompleted, callback_and_context));
+}
 
-        result_object->Set(v8::String::NewFromUtf8(isolate, "width"),
-                           v8::Number::New(isolate, size.width()));
-        result_object->Set(v8::String::NewFromUtf8(isolate, "height"),
-                           v8::Number::New(isolate, size.height()));
+bool GpuBenchmarking::SendMessageToMicroBenchmark(
+    int id,
+    v8::Handle<v8::Object> message) {
+  GpuBenchmarkingContext context;
+  if (!context.Init(true))
+    return false;
 
-        std::string base64_png;
-        base::Base64Encode(base::StringPiece(
-            reinterpret_cast<const char*>(&*png.begin()), png.size()),
-            &base64_png);
+  scoped_ptr<V8ValueConverter> converter =
+      make_scoped_ptr(V8ValueConverter::create());
+  v8::Handle<v8::Context> v8_context =
+      context.web_frame()->mainWorldScriptContext();
+  scoped_ptr<base::Value> value =
+      make_scoped_ptr(converter->FromV8Value(message, v8_context));
 
-        result_object->Set(v8::String::NewFromUtf8(isolate, "data"),
-                           v8::String::NewFromUtf8(isolate,
-                                                   base64_png.c_str(),
-                                                   v8::String::kNormalString,
-                                                   base64_png.size()));
+  return context.compositor()->SendMessageToMicroBenchmark(id, value.Pass());
+}
 
-        result = result_object;
-      } else {
-        result = v8::Null(isolate);
-      }
-
-      v8::Handle<v8::Value> argv[] = { result };
-
-      frame->callFunctionEvenIfScriptDisabled(
-          callback_and_context->GetCallback(),
-          v8::Object::New(isolate),
-          1,
-          argv);
-    }
-  }
-
-  static void BeginWindowSnapshotPNG(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(false))
-      return;
-
-    if (!args[0]->IsFunction())
-      return;
-
-    v8::Local<v8::Function> callback_local =
-        v8::Local<v8::Function>::Cast(args[0]);
-
-    scoped_refptr<CallbackAndContext> callback_and_context =
-        new CallbackAndContext(args.GetIsolate(),
-                               callback_local,
-                               context.web_frame()->mainWorldScriptContext());
-
-    context.render_view_impl()->GetWindowSnapshot(
-        base::Bind(&OnSnapshotCompleted, callback_and_context));
-  }
-
-  static void ClearImageCache(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    WebImageCache::clear();
-  }
-
-  static void OnMicroBenchmarkCompleted(
-      CallbackAndContext* callback_and_context,
-      scoped_ptr<base::Value> result) {
-    v8::Isolate* isolate = callback_and_context->isolate();
-    v8::HandleScope scope(isolate);
-    v8::Handle<v8::Context> context = callback_and_context->GetContext();
-    v8::Context::Scope context_scope(context);
-    WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
-    if (frame) {
-      scoped_ptr<V8ValueConverter> converter =
-          make_scoped_ptr(V8ValueConverter::create());
-      v8::Handle<v8::Value> value = converter->ToV8Value(result.get(), context);
-      v8::Handle<v8::Value> argv[] = { value };
-
-      frame->callFunctionEvenIfScriptDisabled(
-          callback_and_context->GetCallback(),
-          v8::Object::New(isolate),
-          1,
-          argv);
-    }
-  }
-
-  static void RunMicroBenchmark(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(true)) {
-      args.GetReturnValue().Set(0);
-      return;
-    }
-
-    if (args.Length() != 3 ||
-        !args[0]->IsString() ||
-        !args[1]->IsFunction() ||
-        !args[2]->IsObject()) {
-      args.GetReturnValue().Set(0);
-      return;
-    }
-
-    v8::Local<v8::Function> callback_local =
-        v8::Local<v8::Function>::Cast(args[1]);
-
-    scoped_refptr<CallbackAndContext> callback_and_context =
-        new CallbackAndContext(args.GetIsolate(),
-                               callback_local,
-                               context.web_frame()->mainWorldScriptContext());
-
-    scoped_ptr<V8ValueConverter> converter =
-        make_scoped_ptr(V8ValueConverter::create());
-    v8::Handle<v8::Context> v8_context = callback_and_context->GetContext();
-    scoped_ptr<base::Value> value =
-        make_scoped_ptr(converter->FromV8Value(args[2], v8_context));
-
-    v8::String::Utf8Value benchmark(args[0]);
-    DCHECK(*benchmark);
-    args.GetReturnValue().Set(context.compositor()->ScheduleMicroBenchmark(
-        std::string(*benchmark),
-        value.Pass(),
-        base::Bind(&OnMicroBenchmarkCompleted, callback_and_context)));
-  }
-
-  static void SendMessageToMicroBenchmark(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-    GpuBenchmarkingContext context;
-    if (!context.Init(true)) {
-      args.GetReturnValue().Set(0);
-      return;
-    }
-
-    if (args.Length() != 2 || !args[0]->IsNumber() || !args[1]->IsObject()) {
-      args.GetReturnValue().Set(0);
-      return;
-    }
-
-    scoped_ptr<V8ValueConverter> converter =
-        make_scoped_ptr(V8ValueConverter::create());
-    v8::Handle<v8::Context> v8_context =
-        context.web_frame()->mainWorldScriptContext();
-    scoped_ptr<base::Value> value =
-        make_scoped_ptr(converter->FromV8Value(args[1], v8_context));
-
-    int id = 0;
-    converter->FromV8Value(args[0], v8_context)->GetAsInteger(&id);
-    args.GetReturnValue().Set(
-        context.compositor()->SendMessageToMicroBenchmark(id, value.Pass()));
-  }
-
-  static void HasGpuProcess(const v8::FunctionCallbackInfo<v8::Value>& args) {
+bool GpuBenchmarking::HasGpuProcess() {
     GpuChannelHost* gpu_channel = RenderThreadImpl::current()->GetGpuChannel();
-    args.GetReturnValue().Set(!!gpu_channel);
-  }
-};
-
-v8::Extension* GpuBenchmarkingExtension::Get() {
-  return new GpuBenchmarkingWrapper();
+    return !!gpu_channel;
 }
 
 }  // namespace content
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.h b/content/renderer/gpu/gpu_benchmarking_extension.h
index d2fe38cc..d657e91 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.h
+++ b/content/renderer/gpu/gpu_benchmarking_extension.h
@@ -5,16 +5,58 @@
 #ifndef CONTENT_RENDERER_GPU_GPU_BENCHMARKING_EXTENSION_H_
 #define CONTENT_RENDERER_GPU_GPU_BENCHMARKING_EXTENSION_H_
 
+#include "base/basictypes.h"
+#include "gin/wrappable.h"
+
+namespace blink {
+class WebFrame;
+}
+
+namespace gin {
+class Arguments;
+}
+
 namespace v8 {
-class Extension;
+class Function;
+class Isolate;
+class Object;
+template <typename T> class Handle;
 }
 
 namespace content {
 
-// V8 extension for gpu benchmarking
-class GpuBenchmarkingExtension {
+// gin class for gpu benchmarking
+class GpuBenchmarking : public gin::Wrappable<GpuBenchmarking> {
  public:
-  static v8::Extension* Get();
+  static gin::WrapperInfo kWrapperInfo;
+  static void Install(blink::WebFrame* frame);
+
+ private:
+  GpuBenchmarking();
+  virtual ~GpuBenchmarking();
+
+  // gin::Wrappable.
+  virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
+      v8::Isolate* isolate) override;
+
+  // JavaScript handlers.
+  void SetNeedsDisplayOnAllLayers();
+  void SetRasterizeOnlyVisibleContent();
+  void PrintToSkPicture(v8::Isolate* isolate, const std::string& dirname);
+  bool GestureSourceTypeSupported(int gesture_source_type);
+  bool SmoothScrollBy(gin::Arguments* args);
+  bool Swipe(gin::Arguments* args);
+  bool ScrollBounce(gin::Arguments* args);
+  bool PinchBy(gin::Arguments* args);
+  bool Tap(gin::Arguments* args);
+  void BeginWindowSnapshotPNG(v8::Isolate* isolate,
+                              v8::Handle<v8::Function> callback);
+  void ClearImageCache();
+  int RunMicroBenchmark(gin::Arguments* args);
+  bool SendMessageToMicroBenchmark(int id, v8::Handle<v8::Object> message);
+  bool HasGpuProcess();
+
+  DISALLOW_COPY_AND_ASSIGN(GpuBenchmarking);
 };
 
 }  // namespace content
diff --git a/content/renderer/media/crypto/encrypted_media_player_support_impl.cc b/content/renderer/media/crypto/encrypted_media_player_support_impl.cc
index aaa99c8f..cf24056f 100644
--- a/content/renderer/media/crypto/encrypted_media_player_support_impl.cc
+++ b/content/renderer/media/crypto/encrypted_media_player_support_impl.cc
@@ -180,11 +180,12 @@
 
     GURL security_origin(frame->document().securityOrigin().toString());
 
-    RenderCdmFactory cdm_factory(
 #if defined(ENABLE_PEPPER_CDMS)
-        base::Bind(&PepperCdmWrapperImpl::Create, frame)
+    RenderCdmFactory cdm_factory(
+        base::Bind(&PepperCdmWrapperImpl::Create, frame));
+#else
+    RenderCdmFactory cdm_factory;
 #endif
-    );
 
     if (!proxy_decryptor_->InitializeCDM(&cdm_factory, key_system,
                                          security_origin)) {
diff --git a/content/renderer/media/crypto/key_systems.cc b/content/renderer/media/crypto/key_systems.cc
index 7435d692..9c3ce04 100644
--- a/content/renderer/media/crypto/key_systems.cc
+++ b/content/renderer/media/crypto/key_systems.cc
@@ -13,10 +13,10 @@
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "content/public/common/content_client.h"
-#include "content/public/common/eme_constants.h"
 #include "content/public/renderer/content_renderer_client.h"
-#include "content/public/renderer/key_system_info.h"
 #include "content/renderer/media/crypto/key_systems_support_uma.h"
+#include "media/base/eme_constants.h"
+#include "media/base/key_system_info.h"
 
 #if defined(OS_ANDROID)
 #include "media/base/android/media_codec_bridge.h"
@@ -26,6 +26,12 @@
 
 namespace content {
 
+using media::EmeCodec;
+using media::EmeInitDataType;
+using media::KeySystemInfo;
+using media::SupportedInitDataTypes;
+using media::SupportedCodecs;
+
 const char kClearKeyKeySystem[] = "org.w3.clearkey";
 const char kPrefixedClearKeyKeySystem[] = "webkit-org.w3.clearkey";
 const char kUnsupportedClearKeyKeySystem[] = "unsupported-org.w3.clearkey";
@@ -38,9 +44,9 @@
 // Mapping between initialization data types names and enum values. When adding
 // entries, make sure to update IsSaneInitDataTypeWithContainer().
 static NamedInitDataType kInitDataTypeNames[] = {
-    {"webm", EME_INIT_DATA_TYPE_WEBM},
+    {"webm", media::EME_INIT_DATA_TYPE_WEBM},
 #if defined(USE_PROPRIETARY_CODECS)
-    {"cenc", EME_INIT_DATA_TYPE_CENC}
+    {"cenc", media::EME_INIT_DATA_TYPE_CENC}
 #endif  // defined(USE_PROPRIETARY_CODECS)
 };
 
@@ -53,25 +59,25 @@
 // Only audio codec can belong to a "audio/*" container. Both audio and video
 // codecs can belong to a "video/*" container.
 static NamedCodec kContainerToCodecMasks[] = {
-    {"audio/webm", EME_CODEC_WEBM_AUDIO_ALL},
-    {"video/webm", EME_CODEC_WEBM_ALL},
+    {"audio/webm", media::EME_CODEC_WEBM_AUDIO_ALL},
+    {"video/webm", media::EME_CODEC_WEBM_ALL},
 #if defined(USE_PROPRIETARY_CODECS)
-    {"audio/mp4", EME_CODEC_MP4_AUDIO_ALL},
-    {"video/mp4", EME_CODEC_MP4_ALL}
+    {"audio/mp4", media::EME_CODEC_MP4_AUDIO_ALL},
+    {"video/mp4", media::EME_CODEC_MP4_ALL}
 #endif  // defined(USE_PROPRIETARY_CODECS)
 };
 
 // Mapping between codec names and enum values.
 static NamedCodec kCodecStrings[] = {
-    {"vorbis", EME_CODEC_WEBM_VORBIS},
-    {"vp8", EME_CODEC_WEBM_VP8},
-    {"vp8.0", EME_CODEC_WEBM_VP8},
-    {"vp9", EME_CODEC_WEBM_VP9},
-    {"vp9.0", EME_CODEC_WEBM_VP9},
+    {"vorbis", media::EME_CODEC_WEBM_VORBIS},
+    {"vp8", media::EME_CODEC_WEBM_VP8},
+    {"vp8.0", media::EME_CODEC_WEBM_VP8},
+    {"vp9", media::EME_CODEC_WEBM_VP9},
+    {"vp9.0", media::EME_CODEC_WEBM_VP9},
 #if defined(USE_PROPRIETARY_CODECS)
-    {"mp4a", EME_CODEC_MP4_AAC},
-    {"avc1", EME_CODEC_MP4_AVC1},
-    {"avc3", EME_CODEC_MP4_AVC1}
+    {"mp4a", media::EME_CODEC_MP4_AAC},
+    {"avc1", media::EME_CODEC_MP4_AVC1},
+    {"avc3", media::EME_CODEC_MP4_AVC1}
 #endif  // defined(USE_PROPRIETARY_CODECS)
 };
 
@@ -82,18 +88,18 @@
   // http://developer.android.com/guide/appendix/media-formats.html
   // VP9 support is device dependent.
 
-  info.supported_init_data_types = EME_INIT_DATA_TYPE_WEBM;
-  info.supported_codecs = EME_CODEC_WEBM_ALL;
+  info.supported_init_data_types = media::EME_INIT_DATA_TYPE_WEBM;
+  info.supported_codecs = media::EME_CODEC_WEBM_ALL;
 
 #if defined(OS_ANDROID)
   // Temporarily disable VP9 support for Android.
   // TODO(xhwang): Use mime_util.h to query VP9 support on Android.
-  info.supported_codecs &= ~EME_CODEC_WEBM_VP9;
+  info.supported_codecs &= ~media::EME_CODEC_WEBM_VP9;
 #endif  // defined(OS_ANDROID)
 
 #if defined(USE_PROPRIETARY_CODECS)
-  info.supported_init_data_types |= EME_INIT_DATA_TYPE_CENC;
-  info.supported_codecs |= EME_CODEC_MP4_ALL;
+  info.supported_init_data_types |= media::EME_INIT_DATA_TYPE_CENC;
+  info.supported_codecs |= media::EME_CODEC_MP4_ALL;
 #endif  // defined(USE_PROPRIETARY_CODECS)
 
   info.use_aes_decryptor = true;
@@ -149,7 +155,7 @@
 
   struct KeySystemProperties {
     KeySystemProperties()
-        : use_aes_decryptor(false), supported_codecs(EME_CODEC_NONE) {}
+        : use_aes_decryptor(false), supported_codecs(media::EME_CODEC_NONE) {}
 
     bool use_aes_decryptor;
 #if defined(ENABLE_PEPPER_CDMS)
@@ -164,7 +170,7 @@
   typedef base::hash_map<std::string, std::string> ParentKeySystemMap;
   typedef base::hash_map<std::string, SupportedCodecs> ContainerCodecsMap;
   typedef base::hash_map<std::string, EmeCodec> CodecsMap;
-  typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap;
+  typedef base::hash_map<std::string, media::EmeInitDataType> InitDataTypesMap;
 
   KeySystems();
   ~KeySystems() {}
@@ -255,7 +261,7 @@
       init_data_type_name_map_.find(init_data_type);
   if (iter != init_data_type_name_map_.end())
     return iter->second;
-  return EME_INIT_DATA_TYPE_NONE;
+  return media::EME_INIT_DATA_TYPE_NONE;
 }
 
 SupportedCodecs KeySystems::GetCodecMaskForContainer(
@@ -264,14 +270,14 @@
       container_to_codec_mask_map_.find(container);
   if (iter != container_to_codec_mask_map_.end())
     return iter->second;
-  return EME_CODEC_NONE;
+  return media::EME_CODEC_NONE;
 }
 
 EmeCodec KeySystems::GetCodecForString(const std::string& codec) const {
   CodecsMap::const_iterator iter = codec_string_map_.find(codec);
   if (iter != codec_string_map_.end())
     return iter->second;
-  return EME_CODEC_NONE;
+  return media::EME_CODEC_NONE;
 }
 
 const std::string& KeySystems::GetConcreteKeySystemName(
diff --git a/content/renderer/media/crypto/key_systems_unittest.cc b/content/renderer/media/crypto/key_systems_unittest.cc
index 7b877ee..742dc00 100644
--- a/content/renderer/media/crypto/key_systems_unittest.cc
+++ b/content/renderer/media/crypto/key_systems_unittest.cc
@@ -6,11 +6,11 @@
 #include <vector>
 
 #include "content/public/common/content_client.h"
-#include "content/public/common/eme_constants.h"
 #include "content/public/renderer/content_renderer_client.h"
-#include "content/public/renderer/key_system_info.h"
 #include "content/renderer/media/crypto/key_systems.h"
 #include "content/test/test_content_client.h"
+#include "media/base/eme_constants.h"
+#include "media/base/key_system_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 
@@ -37,6 +37,7 @@
 namespace content {
 
 using blink::WebString;
+using media::KeySystemInfo;
 
 // These are the (fake) key systems that are registered for these tests.
 // kUsesAes uses the AesDecryptor like Clear Key.
@@ -65,8 +66,9 @@
   TEST_CODEC_FOO_ALL = TEST_CODEC_FOO_AUDIO_ALL | TEST_CODEC_FOO_VIDEO_ALL
 };
 
-COMPILE_ASSERT((TEST_CODEC_FOO_ALL & EME_CODEC_ALL) == EME_CODEC_NONE,
-                test_codec_masks_should_only_use_invalid_codec_masks);
+COMPILE_ASSERT((TEST_CODEC_FOO_ALL & media::EME_CODEC_ALL) ==
+                   media::EME_CODEC_NONE,
+               test_codec_masks_should_only_use_invalid_codec_masks);
 
 // Adds test container and codec masks.
 // This function must be called after SetContentClient() is called.
@@ -92,22 +94,22 @@
 }
 
 class TestContentRendererClient : public ContentRendererClient {
-  void AddKeySystems(std::vector<content::KeySystemInfo>* key_systems) override;
+  void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override;
 };
 
 void TestContentRendererClient::AddKeySystems(
-    std::vector<content::KeySystemInfo>* key_systems) {
+    std::vector<media::KeySystemInfo>* key_systems) {
   KeySystemInfo aes(kUsesAes);
-  aes.supported_codecs = EME_CODEC_WEBM_ALL;
+  aes.supported_codecs = media::EME_CODEC_WEBM_ALL;
   aes.supported_codecs |= TEST_CODEC_FOO_ALL;
-  aes.supported_init_data_types = EME_INIT_DATA_TYPE_WEBM;
+  aes.supported_init_data_types = media::EME_INIT_DATA_TYPE_WEBM;
   aes.use_aes_decryptor = true;
   key_systems->push_back(aes);
 
   KeySystemInfo ext(kExternal);
-  ext.supported_codecs = EME_CODEC_WEBM_ALL;
+  ext.supported_codecs = media::EME_CODEC_WEBM_ALL;
   ext.supported_codecs |= TEST_CODEC_FOO_ALL;
-  ext.supported_init_data_types = EME_INIT_DATA_TYPE_WEBM;
+  ext.supported_init_data_types = media::EME_INIT_DATA_TYPE_WEBM;
   ext.parent_key_system = kExternalParent;
 #if defined(ENABLE_PEPPER_CDMS)
   ext.pepper_type = "application/x-ppapi-external-cdm";
diff --git a/content/renderer/media/media_stream_audio_processor.cc b/content/renderer/media/media_stream_audio_processor.cc
index 65c668aa..82cca83 100644
--- a/content/renderer/media/media_stream_audio_processor.cc
+++ b/content/renderer/media/media_stream_audio_processor.cc
@@ -19,6 +19,7 @@
 #include "media/base/audio_fifo.h"
 #include "media/base/channel_layout.h"
 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
+#include "third_party/libjingle/overrides/init_webrtc.h"
 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.h"
 #include "third_party/webrtc/modules/audio_processing/typing_detection.h"
 
@@ -451,7 +452,7 @@
 #endif
 
   // Create and configure the webrtc::AudioProcessing.
-  audio_processing_.reset(webrtc::AudioProcessing::Create(config));
+  audio_processing_.reset(CreateWebRtcAudioProcessing(config));
 
   // Enable the audio processing components.
   if (echo_cancellation) {
diff --git a/content/renderer/media/media_stream_audio_processor_options.cc b/content/renderer/media/media_stream_audio_processor_options.cc
index 50eb6e2..cb4278d 100644
--- a/content/renderer/media/media_stream_audio_processor_options.cc
+++ b/content/renderer/media/media_stream_audio_processor_options.cc
@@ -251,15 +251,10 @@
 void StartEchoCancellationDump(AudioProcessing* audio_processing,
                                base::File aec_dump_file) {
   DCHECK(aec_dump_file.IsValid());
-
-  FILE* stream = base::FileToFILE(aec_dump_file.Pass(), "w");
-  if (!stream) {
-    LOG(ERROR) << "Failed to open AEC dump file";
-    return;
-  }
-
-  if (audio_processing->StartDebugRecording(stream))
+  if (audio_processing->StartDebugRecordingForPlatformFile(
+      aec_dump_file.TakePlatformFile())) {
     DLOG(ERROR) << "Fail to start AEC debug recording";
+  }
 }
 
 void StopEchoCancellationDump(AudioProcessing* audio_processing) {
diff --git a/content/renderer/media/midi_message_filter.cc b/content/renderer/media/midi_message_filter.cc
index 165451a5..982281f 100644
--- a/content/renderer/media/midi_message_filter.cc
+++ b/content/renderer/media/midi_message_filter.cc
@@ -4,6 +4,8 @@
 
 #include "content/renderer/media/midi_message_filter.h"
 
+#include <algorithm>
+
 #include "base/bind.h"
 #include "base/debug/trace_event.h"
 #include "base/message_loop/message_loop_proxy.h"
@@ -22,17 +24,82 @@
 
 namespace content {
 
+// TODO(crbug.com/425389): Rewrite this class as a RenderFrameObserver.
 MidiMessageFilter::MidiMessageFilter(
     const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
-    : sender_(NULL),
+    : sender_(nullptr),
       io_message_loop_(io_message_loop),
       main_message_loop_(base::MessageLoopProxy::current()),
-      next_available_id_(0),
-      unacknowledged_bytes_sent_(0) {
+      session_result_(media::MIDI_NOT_INITIALIZED),
+      unacknowledged_bytes_sent_(0u) {
 }
 
 MidiMessageFilter::~MidiMessageFilter() {}
 
+void MidiMessageFilter::AddClient(blink::WebMIDIAccessorClient* client) {
+  DCHECK(main_message_loop_->BelongsToCurrentThread());
+  TRACE_EVENT0("midi", "MidiMessageFilter::AddClient");
+  clients_waiting_session_queue_.push_back(client);
+  if (session_result_ != media::MIDI_NOT_INITIALIZED) {
+    HandleClientAdded(session_result_);
+  } else if (clients_waiting_session_queue_.size() == 1u) {
+    io_message_loop_->PostTask(FROM_HERE,
+        base::Bind(&MidiMessageFilter::StartSessionOnIOThread, this));
+  }
+}
+
+void MidiMessageFilter::RemoveClient(blink::WebMIDIAccessorClient* client) {
+  DCHECK(main_message_loop_->BelongsToCurrentThread());
+  clients_.erase(client);
+  ClientsQueue::iterator it = std::find(clients_waiting_session_queue_.begin(),
+                                        clients_waiting_session_queue_.end(),
+                                        client);
+  if (it != clients_waiting_session_queue_.end())
+    clients_waiting_session_queue_.erase(it);
+  if (clients_.empty() && clients_waiting_session_queue_.empty()) {
+    session_result_ = media::MIDI_NOT_INITIALIZED;
+    inputs_.clear();
+    outputs_.clear();
+    io_message_loop_->PostTask(FROM_HERE,
+        base::Bind(&MidiMessageFilter::EndSessionOnIOThread, this));
+  }
+}
+
+void MidiMessageFilter::SendMidiData(uint32 port,
+                                     const uint8* data,
+                                     size_t length,
+                                     double timestamp) {
+  DCHECK(main_message_loop_->BelongsToCurrentThread());
+  if ((kMaxUnacknowledgedBytesSent - unacknowledged_bytes_sent_) < length) {
+    // TODO(toyoshim): buffer up the data to send at a later time.
+    // For now we're just dropping these bytes on the floor.
+    return;
+  }
+
+  unacknowledged_bytes_sent_ += length;
+  std::vector<uint8> v(data, data + length);
+  io_message_loop_->PostTask(FROM_HERE, base::Bind(
+        &MidiMessageFilter::SendMidiDataOnIOThread, this, port, v, timestamp));
+}
+
+void MidiMessageFilter::StartSessionOnIOThread() {
+  TRACE_EVENT0("midi", "MidiMessageFilter::StartSessionOnIOThread");
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  Send(new MidiHostMsg_StartSession());
+}
+
+void MidiMessageFilter::SendMidiDataOnIOThread(uint32 port,
+                                               const std::vector<uint8>& data,
+                                               double timestamp) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  Send(new MidiHostMsg_SendData(port, data, timestamp));
+}
+
+void MidiMessageFilter::EndSessionOnIOThread() {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  Send(new MidiHostMsg_EndSession());
+}
+
 void MidiMessageFilter::Send(IPC::Message* message) {
   DCHECK(io_message_loop_->BelongsToCurrentThread());
   if (!sender_) {
@@ -47,6 +114,8 @@
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(MidiMessageFilter, message)
     IPC_MESSAGE_HANDLER(MidiMsg_SessionStarted, OnSessionStarted)
+    IPC_MESSAGE_HANDLER(MidiMsg_AddInputPort, OnAddInputPort)
+    IPC_MESSAGE_HANDLER(MidiMsg_AddOutputPort, OnAddOutputPort)
     IPC_MESSAGE_HANDLER(MidiMsg_DataReceived, OnDataReceived)
     IPC_MESSAGE_HANDLER(MidiMsg_AcknowledgeSentData, OnAcknowledgeSentData)
     IPC_MESSAGE_UNHANDLED(handled = false)
@@ -61,7 +130,6 @@
 
 void MidiMessageFilter::OnFilterRemoved() {
   DCHECK(io_message_loop_->BelongsToCurrentThread());
-
   // Once removed, a filter will not be used again.  At this time all
   // delegates must be notified so they release their reference.
   OnChannelClosing();
@@ -69,77 +137,56 @@
 
 void MidiMessageFilter::OnChannelClosing() {
   DCHECK(io_message_loop_->BelongsToCurrentThread());
-  sender_ = NULL;
+  sender_ = nullptr;
 }
 
-void MidiMessageFilter::StartSession(blink::WebMIDIAccessorClient* client) {
-  // Generate and keep track of a "client id" which is sent to the browser
-  // to ask permission to talk to MIDI hardware.
-  // This id is handed back when we receive the answer in OnAccessApproved().
-  if (clients_.find(client) == clients_.end()) {
-    int client_id = next_available_id_++;
-    clients_[client] = client_id;
-
-    io_message_loop_->PostTask(FROM_HERE,
-        base::Bind(&MidiMessageFilter::StartSessionOnIOThread, this,
-                   client_id));
-  }
-}
-
-void MidiMessageFilter::StartSessionOnIOThread(int client_id) {
-  Send(new MidiHostMsg_StartSession(client_id));
-}
-
-void MidiMessageFilter::RemoveClient(blink::WebMIDIAccessorClient* client) {
-  ClientsMap::iterator i = clients_.find(client);
-  if (i != clients_.end())
-    clients_.erase(i);
-}
-
-// Received from browser.
-
-void MidiMessageFilter::OnSessionStarted(
-    int client_id,
-    media::MidiResult result,
-    MidiPortInfoList inputs,
-    MidiPortInfoList outputs) {
+void MidiMessageFilter::OnSessionStarted(media::MidiResult result) {
+  TRACE_EVENT0("midi", "MidiMessageFilter::OnSessionStarted");
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
   // Handle on the main JS thread.
   main_message_loop_->PostTask(
       FROM_HERE,
-      base::Bind(&MidiMessageFilter::HandleSessionStarted, this,
-                 client_id, result, inputs, outputs));
+      base::Bind(&MidiMessageFilter::HandleClientAdded, this, result));
 }
 
-void MidiMessageFilter::HandleSessionStarted(
-    int client_id,
-    media::MidiResult result,
-    MidiPortInfoList inputs,
-    MidiPortInfoList outputs) {
-  blink::WebMIDIAccessorClient* client = GetClientFromId(client_id);
-  if (!client)
-    return;
+void MidiMessageFilter::OnAddInputPort(media::MidiPortInfo info) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  main_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&MidiMessageFilter::HandleAddInputPort, this, info));
+}
 
-  if (result == media::MIDI_OK) {
-    // Add the client's input and output ports.
-    const bool active = true;
-    for (size_t i = 0; i < inputs.size(); ++i) {
-      client->didAddInputPort(
-          base::UTF8ToUTF16(inputs[i].id),
-          base::UTF8ToUTF16(inputs[i].manufacturer),
-          base::UTF8ToUTF16(inputs[i].name),
-          base::UTF8ToUTF16(inputs[i].version),
-          active);
-    }
+void MidiMessageFilter::OnAddOutputPort(media::MidiPortInfo info) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  main_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&MidiMessageFilter::HandleAddOutputPort, this, info));
+}
 
-    for (size_t i = 0; i < outputs.size(); ++i) {
-      client->didAddOutputPort(
-          base::UTF8ToUTF16(outputs[i].id),
-          base::UTF8ToUTF16(outputs[i].manufacturer),
-          base::UTF8ToUTF16(outputs[i].name),
-          base::UTF8ToUTF16(outputs[i].version),
-          active);
-    }
-  }
+void MidiMessageFilter::OnDataReceived(uint32 port,
+                                       const std::vector<uint8>& data,
+                                       double timestamp) {
+  TRACE_EVENT0("midi", "MidiMessageFilter::OnDataReceived");
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  // Handle on the main JS thread.
+  main_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&MidiMessageFilter::HandleDataReceived, this, port, data,
+                 timestamp));
+}
+
+void MidiMessageFilter::OnAcknowledgeSentData(size_t bytes_sent) {
+  DCHECK(io_message_loop_->BelongsToCurrentThread());
+  main_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&MidiMessageFilter::HandleAckknowledgeSentData, this,
+                 bytes_sent));
+}
+
+void MidiMessageFilter::HandleClientAdded(media::MidiResult result) {
+  TRACE_EVENT0("midi", "MidiMessageFilter::HandleClientAdded");
+  DCHECK(main_message_loop_->BelongsToCurrentThread());
+  session_result_ = result;
   std::string error;
   std::string message;
   switch (result) {
@@ -158,82 +205,64 @@
       message = "Unknown internal error occurred.";
       break;
   }
-  client->didStartSession(result == media::MIDI_OK, base::UTF8ToUTF16(error),
-                          base::UTF8ToUTF16(message));
-}
+  base::string16 error16 = base::UTF8ToUTF16(error);
+  base::string16 message16 = base::UTF8ToUTF16(message);
+  for (blink::WebMIDIAccessorClient* client : clients_waiting_session_queue_) {
+    if (result == media::MIDI_OK) {
+      // Add the client's input and output ports.
+      const bool active = true;
+      for (const auto& info : inputs_) {
+        client->didAddInputPort(
+            base::UTF8ToUTF16(info.id),
+            base::UTF8ToUTF16(info.manufacturer),
+            base::UTF8ToUTF16(info.name),
+            base::UTF8ToUTF16(info.version),
+            active);
+      }
 
-blink::WebMIDIAccessorClient*
-MidiMessageFilter::GetClientFromId(int client_id) {
-  // Iterating like this seems inefficient, but in practice there generally
-  // will be very few clients (usually one).  Additionally, this lookup
-  // usually happens one time during page load. So the performance hit is
-  // negligible.
-  for (ClientsMap::iterator i = clients_.begin(); i != clients_.end(); ++i) {
-    if ((*i).second == client_id)
-      return (*i).first;
+      for (const auto& info : outputs_) {
+        client->didAddOutputPort(
+            base::UTF8ToUTF16(info.id),
+            base::UTF8ToUTF16(info.manufacturer),
+            base::UTF8ToUTF16(info.name),
+            base::UTF8ToUTF16(info.version),
+            active);
+      }
+    }
+    client->didStartSession(result == media::MIDI_OK, error16, message16);
+    clients_.insert(client);
   }
-  return NULL;
+  clients_waiting_session_queue_.clear();
 }
 
-void MidiMessageFilter::OnDataReceived(uint32 port,
-                                       const std::vector<uint8>& data,
-                                       double timestamp) {
-  TRACE_EVENT0("midi", "MidiMessageFilter::OnDataReceived");
-
-  main_message_loop_->PostTask(
-      FROM_HERE,
-      base::Bind(&MidiMessageFilter::HandleDataReceived, this,
-                 port, data, timestamp));
+void MidiMessageFilter::HandleAddInputPort(media::MidiPortInfo info) {
+  DCHECK(main_message_loop_->BelongsToCurrentThread());
+  inputs_.push_back(info);
+  // TODO(toyoshim): Notify to clients that were already added.
 }
 
-void MidiMessageFilter::OnAcknowledgeSentData(size_t bytes_sent) {
-  DCHECK_GE(unacknowledged_bytes_sent_, bytes_sent);
-  if (unacknowledged_bytes_sent_ >= bytes_sent)
-    unacknowledged_bytes_sent_ -= bytes_sent;
+void MidiMessageFilter::HandleAddOutputPort(media::MidiPortInfo info) {
+  DCHECK(main_message_loop_->BelongsToCurrentThread());
+  outputs_.push_back(info);
+  // TODO(toyoshim): Notify to clients that were already added.
 }
 
 void MidiMessageFilter::HandleDataReceived(uint32 port,
                                            const std::vector<uint8>& data,
                                            double timestamp) {
-  DCHECK(!data.empty());
   TRACE_EVENT0("midi", "MidiMessageFilter::HandleDataReceived");
+  DCHECK(main_message_loop_->BelongsToCurrentThread());
+  DCHECK(!data.empty());
 
-  for (ClientsMap::iterator i = clients_.begin(); i != clients_.end(); ++i)
-    (*i).first->didReceiveMIDIData(port, &data[0], data.size(), timestamp);
+  for (blink::WebMIDIAccessorClient* client : clients_)
+    client->didReceiveMIDIData(port, &data[0], data.size(), timestamp);
 }
 
-void MidiMessageFilter::SendMidiData(uint32 port,
-                                     const uint8* data,
-                                     size_t length,
-                                     double timestamp) {
-  if (length > kMaxUnacknowledgedBytesSent) {
-    // TODO(toyoshim): buffer up the data to send at a later time.
-    // For now we're just dropping these bytes on the floor.
-    return;
-  }
-
-  std::vector<uint8> v(data, data + length);
-  io_message_loop_->PostTask(FROM_HERE,
-      base::Bind(&MidiMessageFilter::SendMidiDataOnIOThread, this,
-                 port, v, timestamp));
-}
-
-void MidiMessageFilter::SendMidiDataOnIOThread(uint32 port,
-                                               const std::vector<uint8>& data,
-                                               double timestamp) {
-  size_t n = data.size();
-  if (n > kMaxUnacknowledgedBytesSent ||
-      unacknowledged_bytes_sent_ > kMaxUnacknowledgedBytesSent ||
-      n + unacknowledged_bytes_sent_ > kMaxUnacknowledgedBytesSent) {
-    // TODO(toyoshim): buffer up the data to send at a later time.
-    // For now we're just dropping these bytes on the floor.
-    return;
-  }
-
-  unacknowledged_bytes_sent_ += n;
-
-  // Send to the browser.
-  Send(new MidiHostMsg_SendData(port, data, timestamp));
+void MidiMessageFilter::HandleAckknowledgeSentData(size_t bytes_sent) {
+  DCHECK(main_message_loop_->BelongsToCurrentThread());
+  DCHECK_GE(unacknowledged_bytes_sent_, bytes_sent);
+  if (unacknowledged_bytes_sent_ >= bytes_sent)
+    unacknowledged_bytes_sent_ -= bytes_sent;
 }
 
 }  // namespace content
diff --git a/content/renderer/media/midi_message_filter.h b/content/renderer/media/midi_message_filter.h
index 4aa560a..f7e1a84 100644
--- a/content/renderer/media/midi_message_filter.h
+++ b/content/renderer/media/midi_message_filter.h
@@ -5,7 +5,7 @@
 #ifndef CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_
 #define CONTENT_RENDERER_MEDIA_MIDI_MESSAGE_FILTER_H_
 
-#include <map>
+#include <set>
 #include <vector>
 
 #include "base/memory/scoped_ptr.h"
@@ -29,9 +29,7 @@
 
   // Each client registers for MIDI access here.
   // If permission is granted, then the client's
-  // addInputPort() and addOutputPort() methods will be called,
-  // giving the client access to receive and send data.
-  void StartSession(blink::WebMIDIAccessorClient* client);
+  void AddClient(blink::WebMIDIAccessorClient* client);
   void RemoveClient(blink::WebMIDIAccessorClient* client);
 
   // A client will only be able to call this method if it has a suitable
@@ -50,6 +48,14 @@
   ~MidiMessageFilter() override;
 
  private:
+  void StartSessionOnIOThread();
+
+  void SendMidiDataOnIOThread(uint32 port,
+                              const std::vector<uint8>& data,
+                              double timestamp);
+
+  void EndSessionOnIOThread();
+
   // Sends an IPC message using |sender_|.
   void Send(IPC::Message* message);
 
@@ -61,10 +67,15 @@
 
   // Called when the browser process has approved (or denied) access to
   // MIDI hardware.
-  void OnSessionStarted(int client_id,
-                        media::MidiResult result,
-                        media::MidiPortInfoList inputs,
-                        media::MidiPortInfoList outputs);
+  void OnSessionStarted(media::MidiResult result);
+
+  // These functions are called in 2 cases:
+  //  (1) Just before calling |OnSessionStarted|, to notify the recipient about
+  //      existing ports.
+  //  (2) To notify the recipient that a new device was connected and that new
+  //      ports have been created.
+  void OnAddInputPort(media::MidiPortInfo info);
+  void OnAddOutputPort(media::MidiPortInfo info);
 
   // Called when the browser process has sent MIDI data containing one or
   // more messages.
@@ -77,22 +88,17 @@
   // sending too much data before knowing how much has already been sent.
   void OnAcknowledgeSentData(size_t bytes_sent);
 
-  void HandleSessionStarted(int client_id,
-                            media::MidiResult result,
-                            media::MidiPortInfoList inputs,
-                            media::MidiPortInfoList outputs);
+  // Following methods, Handle*, run on |main_message_loop_|.
+  void HandleClientAdded(media::MidiResult result);
+
+  void HandleAddInputPort(media::MidiPortInfo info);
+  void HandleAddOutputPort(media::MidiPortInfo info);
 
   void HandleDataReceived(uint32 port,
                           const std::vector<uint8>& data,
                           double timestamp);
 
-  void StartSessionOnIOThread(int client_id);
-
-  void SendMidiDataOnIOThread(uint32 port,
-                              const std::vector<uint8>& data,
-                              double timestamp);
-
-  blink::WebMIDIAccessorClient* GetClientFromId(int client_id);
+  void HandleAckknowledgeSentData(size_t bytes_sent);
 
   // IPC sender for Send(); must only be accessed on |io_message_loop_|.
   IPC::Sender* sender_;
@@ -103,15 +109,24 @@
   // Main thread's message loop.
   scoped_refptr<base::MessageLoopProxy> main_message_loop_;
 
+  /*
+   * Notice: Following members are designed to be accessed only on
+   * |main_message_loop_|.
+   */
   // Keeps track of all MIDI clients.
-  // We map client to "client id" used to track permission.
-  // When access has been approved, we add the input and output ports to
-  // the client, allowing it to actually receive and send MIDI data.
-  typedef std::map<blink::WebMIDIAccessorClient*, int> ClientsMap;
-  ClientsMap clients_;
+  typedef std::set<blink::WebMIDIAccessorClient*> ClientsSet;
+  ClientsSet clients_;
 
-  // Dishes out client ids.
-  int next_available_id_;
+  // Represents clients that are waiting for a session being open.
+  typedef std::vector<blink::WebMIDIAccessorClient*> ClientsQueue;
+  ClientsQueue clients_waiting_session_queue_;
+
+  // Represents a result on starting a session. Can be accessed only on
+  media::MidiResult session_result_;
+
+  // Holds MidiPortInfoList for input ports and output ports.
+  media::MidiPortInfoList inputs_;
+  media::MidiPortInfoList outputs_;
 
   size_t unacknowledged_bytes_sent_;
 
diff --git a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
index ad0f8cd..ab3d2f76 100644
--- a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
+++ b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
@@ -12,6 +12,7 @@
 #include "content/common/gpu/client/context_provider_command_buffer.h"
 #include "content/common/gpu/client/gl_helper.h"
 #include "content/common/gpu/client/gpu_channel_host.h"
+#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h"
 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
 #include "content/renderer/render_thread_impl.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
@@ -248,8 +249,9 @@
 std::vector<media::VideoEncodeAccelerator::SupportedProfile>
 RendererGpuVideoAcceleratorFactories::
     GetVideoEncodeAcceleratorSupportedProfiles() {
-  return gpu_channel_host_->gpu_info()
-      .video_encode_accelerator_supported_profiles;
+  return GpuVideoEncodeAcceleratorHost::ConvertGpuToMediaProfiles(
+      gpu_channel_host_->gpu_info()
+          .video_encode_accelerator_supported_profiles);
 }
 
 }  // namespace content
diff --git a/content/renderer/media/renderer_webmidiaccessor_impl.cc b/content/renderer/media/renderer_webmidiaccessor_impl.cc
index 75b6b972..b67f48a 100644
--- a/content/renderer/media/renderer_webmidiaccessor_impl.cc
+++ b/content/renderer/media/renderer_webmidiaccessor_impl.cc
@@ -21,7 +21,7 @@
 }
 
 void RendererWebMIDIAccessorImpl::startSession() {
-  midi_message_filter()->StartSession(client_);
+  midi_message_filter()->AddClient(client_);
 }
 
 void RendererWebMIDIAccessorImpl::sendMIDIData(
diff --git a/content/renderer/media/webrtc/video_destination_handler.cc b/content/renderer/media/webrtc/video_destination_handler.cc
index 16053716..d2dfb8f1 100644
--- a/content/renderer/media/webrtc/video_destination_handler.cc
+++ b/content/renderer/media/webrtc/video_destination_handler.cc
@@ -41,6 +41,13 @@
 
  private:
   friend class base::RefCountedThreadSafe<FrameWriterDelegate>;
+  // Endian in memory order, e.g. AXXX stands for uint8 pixel[4] = {A, x, x, x};
+  enum PixelEndian {
+    UNKNOWN,
+    AXXX,
+    XXXA,
+  };
+
   virtual ~FrameWriterDelegate();
 
   void StartDeliverOnIO(const VideoCaptureDeliverFrameCB& frame_callback);
@@ -52,9 +59,11 @@
 
   scoped_refptr<base::MessageLoopProxy> io_message_loop_;
 
-  // |frame_pool_| and |new_frame_callback_| are only used on the IO-thread.
+  // |frame_pool_|, |new_frame_callback_| and |endian_| are only used on the
+  // IO-thread.
   media::VideoFramePool frame_pool_;
   VideoCaptureDeliverFrameCB new_frame_callback_;
+  PixelEndian endian_;
 
   // Used to DCHECK that we are called on the main render thread.
   base::ThreadChecker thread_checker_;
@@ -62,7 +71,7 @@
 
 PpFrameWriter::FrameWriterDelegate::FrameWriterDelegate(
     const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy)
-    : io_message_loop_(io_message_loop_proxy) {
+    : io_message_loop_(io_message_loop_proxy), endian_(UNKNOWN) {
 }
 
 PpFrameWriter::FrameWriterDelegate::~FrameWriterDelegate() {
@@ -101,6 +110,8 @@
                << "The image_data's mapped bitmap is NULL.";
     return;
   }
+  // We only support PP_IMAGEDATAFORMAT_BGRA_PREMUL at the moment.
+  DCHECK(image_data->format() == PP_IMAGEDATAFORMAT_BGRA_PREMUL);
   io_message_loop_->PostTaskAndReply(
       FROM_HERE,
       base::Bind(&FrameWriterDelegate::DeliverFrameOnIO, this,
@@ -141,10 +152,6 @@
   const base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
       time_stamp_ns / base::Time::kNanosecondsPerMicrosecond);
 
-  // TODO(perkj): It would be more efficient to use I420 here. Using YV12 will
-  // force a copy into a tightly packed I420 frame in
-  // WebRtcVideoCapturerAdapter before the frame is delivered to libJingle.
-  // crbug/359587.
   scoped_refptr<media::VideoFrame> new_frame =
       frame_pool_.CreateFrame(media::VideoFrame::YV12, frame_size,
                               gfx::Rect(frame_size), frame_size, timestamp);
@@ -153,15 +160,46 @@
       MediaStreamVideoSource::kUnknownFrameRate,
       media::PIXEL_FORMAT_YV12);
 
-  libyuv::BGRAToI420(data,
-                     stride,
-                     new_frame->data(media::VideoFrame::kYPlane),
-                     new_frame->stride(media::VideoFrame::kYPlane),
-                     new_frame->data(media::VideoFrame::kUPlane),
-                     new_frame->stride(media::VideoFrame::kUPlane),
-                     new_frame->data(media::VideoFrame::kVPlane),
-                     new_frame->stride(media::VideoFrame::kVPlane),
-                     frame_size.width(), frame_size.height());
+  // TODO(magjed): Remove this and always use libyuv::ARGBToI420 when
+  // crbug/426020 is fixed.
+  // Due to a change in endianness, we try to determine it from the data.
+  // The alpha channel is always 255. It is unlikely for other color channels to
+  // be 255, so we will most likely break on the first few pixels in the first
+  // frame.
+  uint8* row_ptr = data;
+  // Note that we only do this if endian_ is still UNKNOWN.
+  for (int y = 0; y < height && endian_ == UNKNOWN; ++y) {
+    for (int x = 0; x < width; ++x) {
+      if (row_ptr[x * 4 + 0] != 255) {  // First byte is not Alpha => XXXA.
+        endian_ = XXXA;
+        break;
+      }
+      if (row_ptr[x * 4 + 3] != 255) {  // Fourth byte is not Alpha => AXXX.
+        endian_ = AXXX;
+        break;
+      }
+    }
+    row_ptr += stride;
+  }
+  if (endian_ == UNKNOWN) {
+    LOG(WARNING) << "PpFrameWriter::FrameWriterDelegate::DeliverFrameOnIO - "
+                 << "Could not determine endianness.";
+  }
+  // libyuv specifies fourcc/channel ordering the same as webrtc. That is why
+  // the naming is reversed compared to PixelEndian and PP_ImageDataFormat which
+  // describes the memory layout from the lowest address to the highest.
+  auto xxxxToI420 =
+      (endian_ == AXXX) ? &libyuv::BGRAToI420 : &libyuv::ARGBToI420;
+  xxxxToI420(data,
+             stride,
+             new_frame->data(media::VideoFrame::kYPlane),
+             new_frame->stride(media::VideoFrame::kYPlane),
+             new_frame->data(media::VideoFrame::kUPlane),
+             new_frame->stride(media::VideoFrame::kUPlane),
+             new_frame->data(media::VideoFrame::kVPlane),
+             new_frame->stride(media::VideoFrame::kVPlane),
+             width,
+             height);
 
   // The local time when this frame is generated is unknown so give a null
   // value to |estimated_capture_time|.
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
index 603edb3..7d1cb4f 100644
--- a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
+++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
@@ -8,21 +8,323 @@
 #include "base/debug/trace_event.h"
 #include "base/memory/aligned_memory.h"
 #include "media/base/video_frame.h"
+#include "media/base/video_frame_pool.h"
+#include "third_party/libjingle/source/talk/media/base/videoframe.h"
+#include "third_party/libjingle/source/talk/media/base/videoframefactory.h"
+#include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.h"
+#include "third_party/libyuv/include/libyuv/convert_from.h"
 #include "third_party/libyuv/include/libyuv/scale.h"
 
 namespace content {
+namespace {
+
+// Empty method used for keeping a reference to the original media::VideoFrame.
+// The reference to |frame| is kept in the closure that calls this method.
+void ReleaseOriginalFrame(const scoped_refptr<media::VideoFrame>& frame) {
+}
+
+// Thin map between an existing media::VideoFrame and cricket::VideoFrame to
+// avoid premature deep copies.
+// This implementation is only safe to use in a const context and should never
+// be written to.
+class VideoFrameWrapper : public cricket::VideoFrame {
+ public:
+  VideoFrameWrapper(const scoped_refptr<media::VideoFrame>& frame,
+                    int64 elapsed_time)
+      : frame_(media::VideoFrame::WrapVideoFrame(
+            frame,
+            frame->visible_rect(),
+            frame->natural_size(),
+            base::Bind(&ReleaseOriginalFrame, frame))),
+        elapsed_time_(elapsed_time) {}
+
+  virtual VideoFrame* Copy() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return new VideoFrameWrapper(frame_, elapsed_time_);
+  }
+
+  virtual size_t GetWidth() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return static_cast<size_t>(frame_->visible_rect().width());
+  }
+
+  virtual size_t GetHeight() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return static_cast<size_t>(frame_->visible_rect().height());
+  }
+
+  virtual const uint8* GetYPlane() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->visible_data(media::VideoFrame::kYPlane);
+  }
+
+  virtual const uint8* GetUPlane() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->visible_data(media::VideoFrame::kUPlane);
+  }
+
+  virtual const uint8* GetVPlane() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->visible_data(media::VideoFrame::kVPlane);
+  }
+
+  virtual uint8* GetYPlane() override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->visible_data(media::VideoFrame::kYPlane);
+  }
+
+  virtual uint8* GetUPlane() override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->visible_data(media::VideoFrame::kUPlane);
+  }
+
+  virtual uint8* GetVPlane() override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->visible_data(media::VideoFrame::kVPlane);
+  }
+
+  virtual int32 GetYPitch() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->stride(media::VideoFrame::kYPlane);
+  }
+
+  virtual int32 GetUPitch() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->stride(media::VideoFrame::kUPlane);
+  }
+
+  virtual int32 GetVPitch() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->stride(media::VideoFrame::kVPlane);
+  }
+
+  virtual void* GetNativeHandle() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return NULL;
+  }
+
+  virtual size_t GetPixelWidth() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return 1;
+  }
+  virtual size_t GetPixelHeight() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return 1;
+  }
+
+  virtual int64 GetElapsedTime() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return elapsed_time_;
+  }
+
+  virtual int64 GetTimeStamp() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return frame_->timestamp().InMicroseconds() *
+           base::Time::kNanosecondsPerMicrosecond;
+  }
+
+  virtual void SetElapsedTime(int64 elapsed_time) override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    elapsed_time_ = elapsed_time;
+  }
+
+  virtual void SetTimeStamp(int64 time_stamp) override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    // Round to closest microsecond.
+    frame_->set_timestamp(base::TimeDelta::FromMicroseconds(
+        (time_stamp + base::Time::kNanosecondsPerMicrosecond / 2) /
+        base::Time::kNanosecondsPerMicrosecond));
+  }
+
+  virtual int GetRotation() const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    return 0;
+  }
+
+  // TODO(magjed): Refactor into base class.
+  virtual size_t ConvertToRgbBuffer(uint32 to_fourcc,
+                                    uint8* buffer,
+                                    size_t size,
+                                    int stride_rgb) const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    const size_t needed = std::abs(stride_rgb) * GetHeight();
+    if (size < needed) {
+      DLOG(WARNING) << "RGB buffer is not large enough";
+      return needed;
+    }
+
+    if (libyuv::ConvertFromI420(GetYPlane(),
+                                GetYPitch(),
+                                GetUPlane(),
+                                GetUPitch(),
+                                GetVPlane(),
+                                GetVPitch(),
+                                buffer,
+                                stride_rgb,
+                                static_cast<int>(GetWidth()),
+                                static_cast<int>(GetHeight()),
+                                to_fourcc)) {
+      DLOG(ERROR) << "RGB type not supported: " << to_fourcc;
+      return 0;  // 0 indicates error
+    }
+    return needed;
+  }
+
+  // The rest of the public methods are NOTIMPLEMENTED.
+  virtual bool InitToBlack(int w,
+                           int h,
+                           size_t pixel_width,
+                           size_t pixel_height,
+                           int64 elapsed_time,
+                           int64 time_stamp) override {
+    NOTIMPLEMENTED();
+    return false;
+  }
+
+  virtual bool Reset(uint32 fourcc,
+                     int w,
+                     int h,
+                     int dw,
+                     int dh,
+                     uint8* sample,
+                     size_t sample_size,
+                     size_t pixel_width,
+                     size_t pixel_height,
+                     int64 elapsed_time,
+                     int64 time_stamp,
+                     int rotation) override {
+    NOTIMPLEMENTED();
+    return false;
+  }
+
+  virtual bool MakeExclusive() override {
+    NOTIMPLEMENTED();
+    return false;
+  }
+
+  virtual size_t CopyToBuffer(uint8* buffer, size_t size) const override {
+    NOTIMPLEMENTED();
+    return 0;
+  }
+
+ protected:
+  // TODO(magjed): Refactor as a static method in WebRtcVideoFrame.
+  virtual VideoFrame* CreateEmptyFrame(int w,
+                                       int h,
+                                       size_t pixel_width,
+                                       size_t pixel_height,
+                                       int64 elapsed_time,
+                                       int64 time_stamp) const override {
+    DCHECK(thread_checker_.CalledOnValidThread());
+    VideoFrame* frame = new cricket::WebRtcVideoFrame();
+    frame->InitToBlack(
+        w, h, pixel_width, pixel_height, elapsed_time, time_stamp);
+    return frame;
+  }
+
+ private:
+  scoped_refptr<media::VideoFrame> frame_;
+  int64 elapsed_time_;
+  base::ThreadChecker thread_checker_;
+};
+
+}  // anonymous namespace
+
+// A cricket::VideoFrameFactory for media::VideoFrame. The purpose of this
+// class is to avoid a premature frame copy. A media::VideoFrame is injected
+// with SetFrame, and converted into a cricket::VideoFrame with
+// CreateAliasedFrame. SetFrame should be called before CreateAliasedFrame
+// for every frame.
+class WebRtcVideoCapturerAdapter::MediaVideoFrameFactory
+    : public cricket::VideoFrameFactory {
+ public:
+  void SetFrame(const scoped_refptr<media::VideoFrame>& frame,
+                int64_t elapsed_time) {
+    DCHECK(frame.get());
+    // Create a CapturedFrame that only contains header information, not the
+    // actual pixel data.
+    captured_frame_.width = frame->natural_size().width();
+    captured_frame_.height = frame->natural_size().height();
+    captured_frame_.elapsed_time = elapsed_time;
+    captured_frame_.time_stamp = frame->timestamp().InMicroseconds() *
+                                 base::Time::kNanosecondsPerMicrosecond;
+    captured_frame_.pixel_height = 1;
+    captured_frame_.pixel_width = 1;
+    captured_frame_.rotation = 0;
+    captured_frame_.data = NULL;
+    captured_frame_.data_size = cricket::CapturedFrame::kUnknownDataSize;
+    captured_frame_.fourcc = static_cast<uint32>(cricket::FOURCC_ANY);
+
+    frame_ = frame;
+  }
+
+  void ReleaseFrame() { frame_ = NULL; }
+
+  const cricket::CapturedFrame* GetCapturedFrame() const {
+    return &captured_frame_;
+  }
+
+  virtual cricket::VideoFrame* CreateAliasedFrame(
+      const cricket::CapturedFrame* captured_frame,
+      int dst_width,
+      int dst_height) const override {
+    // Check that captured_frame is actually our frame.
+    DCHECK(captured_frame == &captured_frame_);
+    DCHECK(frame_.get());
+
+    scoped_refptr<media::VideoFrame> video_frame = frame_;
+    // Check if scaling is needed.
+    if (dst_width != frame_->visible_rect().width() ||
+        dst_height != frame_->visible_rect().height()) {
+      video_frame =
+          scaled_frame_pool_.CreateFrame(media::VideoFrame::I420,
+                                         gfx::Size(dst_width, dst_height),
+                                         gfx::Rect(0, 0, dst_width, dst_height),
+                                         gfx::Size(dst_width, dst_height),
+                                         frame_->timestamp());
+      libyuv::I420Scale(frame_->visible_data(media::VideoFrame::kYPlane),
+                        frame_->stride(media::VideoFrame::kYPlane),
+                        frame_->visible_data(media::VideoFrame::kUPlane),
+                        frame_->stride(media::VideoFrame::kUPlane),
+                        frame_->visible_data(media::VideoFrame::kVPlane),
+                        frame_->stride(media::VideoFrame::kVPlane),
+                        frame_->visible_rect().width(),
+                        frame_->visible_rect().height(),
+                        video_frame->data(media::VideoFrame::kYPlane),
+                        video_frame->stride(media::VideoFrame::kYPlane),
+                        video_frame->data(media::VideoFrame::kUPlane),
+                        video_frame->stride(media::VideoFrame::kUPlane),
+                        video_frame->data(media::VideoFrame::kVPlane),
+                        video_frame->stride(media::VideoFrame::kVPlane),
+                        dst_width,
+                        dst_height,
+                        libyuv::kFilterBilinear);
+    }
+
+    // Create a shallow cricket::VideoFrame wrapper around the
+    // media::VideoFrame. The caller has ownership of the returned frame.
+    return new VideoFrameWrapper(video_frame, captured_frame_.elapsed_time);
+  }
+
+ private:
+  scoped_refptr<media::VideoFrame> frame_;
+  cricket::CapturedFrame captured_frame_;
+  // This is used only if scaling is needed.
+  mutable media::VideoFramePool scaled_frame_pool_;
+};
 
 WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast)
     : is_screencast_(is_screencast),
       running_(false),
-      buffer_(NULL),
-      buffer_size_(0) {
+      first_frame_timestamp_(media::kNoTimestamp()),
+      frame_factory_(new MediaVideoFrameFactory) {
   thread_checker_.DetachFromThread();
+  // The base class takes ownership of the frame factory.
+  set_frame_factory(frame_factory_);
 }
 
 WebRtcVideoCapturerAdapter::~WebRtcVideoCapturerAdapter() {
   DVLOG(3) << " WebRtcVideoCapturerAdapter::dtor";
-  base::AlignedFree(buffer_);
 }
 
 cricket::CaptureState WebRtcVideoCapturerAdapter::Start(
@@ -53,10 +355,10 @@
 bool WebRtcVideoCapturerAdapter::GetPreferredFourccs(
     std::vector<uint32>* fourccs) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  if (!fourccs)
-    return false;
-  fourccs->push_back(cricket::FOURCC_I420);
-  return true;
+  DCHECK(!fourccs || fourccs->empty());
+  if (fourccs)
+    fourccs->push_back(cricket::FOURCC_I420);
+  return fourccs != NULL;
 }
 
 bool WebRtcVideoCapturerAdapter::IsScreencast() const {
@@ -97,97 +399,18 @@
   if (first_frame_timestamp_ == media::kNoTimestamp())
     first_frame_timestamp_ = frame->timestamp();
 
-  cricket::CapturedFrame captured_frame;
-  captured_frame.width = frame->natural_size().width();
-  captured_frame.height = frame->natural_size().height();
-  // cricket::CapturedFrame time is in nanoseconds.
-  captured_frame.elapsed_time =
+  const int64 elapsed_time =
       (frame->timestamp() - first_frame_timestamp_).InMicroseconds() *
       base::Time::kNanosecondsPerMicrosecond;
-  captured_frame.time_stamp = frame->timestamp().InMicroseconds() *
-                              base::Time::kNanosecondsPerMicrosecond;
-  captured_frame.pixel_height = 1;
-  captured_frame.pixel_width = 1;
 
-  // TODO(perkj):
-  // Libjingle expects contiguous layout of image planes as input.
-  // The only format where that is true in Chrome is I420 where the
-  // coded_size == natural_size().
-  if (frame->format() != media::VideoFrame::I420 ||
-      frame->coded_size() != frame->natural_size()) {
-    // Cropping / Scaling and or switching UV planes is needed.
-    UpdateI420Buffer(frame);
-    captured_frame.data = buffer_;
-    captured_frame.data_size = buffer_size_;
-    captured_frame.fourcc = cricket::FOURCC_I420;
-  } else {
-    captured_frame.fourcc = media::VideoFrame::I420 == frame->format() ?
-        cricket::FOURCC_I420 : cricket::FOURCC_YV12;
-    captured_frame.data = frame->data(0);
-    captured_frame.data_size =
-        media::VideoFrame::AllocationSize(frame->format(), frame->coded_size());
-  }
+  // Inject the frame via the VideoFrameFractory.
+  DCHECK(frame_factory_ == frame_factory());
+  frame_factory_->SetFrame(frame, elapsed_time);
 
   // This signals to libJingle that a new VideoFrame is available.
-  // libJingle have no assumptions on what thread this signal come from.
-  SignalFrameCaptured(this, &captured_frame);
-}
+  SignalFrameCaptured(this, frame_factory_->GetCapturedFrame());
 
-void WebRtcVideoCapturerAdapter::UpdateI420Buffer(
-    const scoped_refptr<media::VideoFrame>& src) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  const int dst_width = src->natural_size().width();
-  const int dst_height = src->natural_size().height();
-  DCHECK(src->visible_rect().width() >= dst_width &&
-         src->visible_rect().height() >= dst_height);
-
-  const gfx::Rect& visible_rect = src->visible_rect();
-
-  const uint8* src_y = src->data(media::VideoFrame::kYPlane) +
-      visible_rect.y() * src->stride(media::VideoFrame::kYPlane) +
-      visible_rect.x();
-  const uint8* src_u = src->data(media::VideoFrame::kUPlane) +
-      visible_rect.y() / 2 * src->stride(media::VideoFrame::kUPlane) +
-      visible_rect.x() / 2;
-  const uint8* src_v = src->data(media::VideoFrame::kVPlane) +
-      visible_rect.y() / 2 * src->stride(media::VideoFrame::kVPlane) +
-      visible_rect.x() / 2;
-
-  const size_t dst_size =
-      media::VideoFrame::AllocationSize(src->format(), src->natural_size());
-
-  if (dst_size != buffer_size_) {
-    base::AlignedFree(buffer_);
-    buffer_ = reinterpret_cast<uint8*>(
-        base::AlignedAlloc(dst_size + media::VideoFrame::kFrameSizePadding,
-                           media::VideoFrame::kFrameAddressAlignment));
-    buffer_size_ = dst_size;
-  }
-
-  uint8* dst_y = buffer_;
-  const int dst_stride_y = dst_width;
-  uint8* dst_u = dst_y + dst_width * dst_height;
-  const int dst_halfwidth = (dst_width + 1) / 2;
-  const int dst_halfheight = (dst_height + 1) / 2;
-  uint8* dst_v = dst_u + dst_halfwidth * dst_halfheight;
-
-  libyuv::I420Scale(src_y,
-                    src->stride(media::VideoFrame::kYPlane),
-                    src_u,
-                    src->stride(media::VideoFrame::kUPlane),
-                    src_v,
-                    src->stride(media::VideoFrame::kVPlane),
-                    visible_rect.width(),
-                    visible_rect.height(),
-                    dst_y,
-                    dst_stride_y,
-                    dst_u,
-                    dst_halfwidth,
-                    dst_v,
-                    dst_halfwidth,
-                    dst_width,
-                    dst_height,
-                    libyuv::kFilterBilinear);
+  frame_factory_->ReleaseFrame();  // Release the frame ASAP.
 }
 
 }  // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h
index d8cf5540..f70ae894 100644
--- a/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h
+++ b/content/renderer/media/webrtc/webrtc_video_capturer_adapter.h
@@ -48,19 +48,17 @@
                             cricket::VideoFormat* best_format) override;
   bool IsScreencast() const override;
 
-  void UpdateI420Buffer(const scoped_refptr<media::VideoFrame>& src);
-
   // |thread_checker_| is bound to the libjingle worker thread.
   base::ThreadChecker thread_checker_;
 
   const bool is_screencast_;
   bool running_;
   base::TimeDelta first_frame_timestamp_;
-  // |buffer_| used if cropping is needed. It is created only if needed and
-  // owned by WebRtcVideoCapturerAdapter. If its created, it exists until
-  // WebRtcVideoCapturerAdapter is destroyed.
-  uint8* buffer_;
-  size_t buffer_size_;
+
+  // This is an alias to the frame_factory_ in the base class
+  // cricket::VideoCapturer.
+  class MediaVideoFrameFactory;
+  MediaVideoFrameFactory* frame_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(WebRtcVideoCapturerAdapter);
 };
diff --git a/content/renderer/media/webrtc_audio_renderer.cc b/content/renderer/media/webrtc_audio_renderer.cc
index 41e7cb9..34e0f48 100644
--- a/content/renderer/media/webrtc_audio_renderer.cc
+++ b/content/renderer/media/webrtc_audio_renderer.cc
@@ -140,8 +140,10 @@
   return media::AudioParameters::NO_EFFECTS;
 }
 
-// Helper method to get platform specific optimal buffer size.
-int GetOptimalBufferSize(int sample_rate, int hardware_buffer_size) {
+}  // namespace
+
+int WebRtcAudioRenderer::GetOptimalBufferSize(int sample_rate,
+                                              int hardware_buffer_size) {
   // Use native hardware buffer size as default. On Windows, we strive to open
   // up using this native hardware buffer size to achieve best
   // possible performance and to ensure that no FIFO is needed on the browser
@@ -173,8 +175,6 @@
   return frames_per_buffer;
 }
 
-}  // namespace
-
 WebRtcAudioRenderer::WebRtcAudioRenderer(
     const scoped_refptr<webrtc::MediaStreamInterface>& media_stream,
     int source_render_view_id,
diff --git a/content/renderer/media/webrtc_audio_renderer.h b/content/renderer/media/webrtc_audio_renderer.h
index 11985347..9accf6a 100644
--- a/content/renderer/media/webrtc_audio_renderer.h
+++ b/content/renderer/media/webrtc_audio_renderer.h
@@ -69,6 +69,10 @@
     float volume_;
   };
 
+
+  // Returns platform specific optimal buffer size for rendering audio.
+  static int GetOptimalBufferSize(int sample_rate, int hardware_buffer_size);
+
   WebRtcAudioRenderer(
       const scoped_refptr<webrtc::MediaStreamInterface>& media_stream,
       int source_render_view_id,
diff --git a/content/renderer/media/webrtc_local_audio_renderer.cc b/content/renderer/media/webrtc_local_audio_renderer.cc
index 61aca70..dd657eb 100644
--- a/content/renderer/media/webrtc_local_audio_renderer.cc
+++ b/content/renderer/media/webrtc_local_audio_renderer.cc
@@ -12,6 +12,7 @@
 #include "content/renderer/media/audio_device_factory.h"
 #include "content/renderer/media/media_stream_dispatcher.h"
 #include "content/renderer/media/webrtc_audio_capturer.h"
+#include "content/renderer/media/webrtc_audio_renderer.h"
 #include "content/renderer/render_frame_impl.h"
 #include "media/audio/audio_output_device.h"
 #include "media/base/audio_block_fifo.h"
@@ -284,15 +285,8 @@
   sink_params_ = media::AudioParameters(source_params_.format(),
       source_params_.channel_layout(), source_params_.sample_rate(),
       source_params_.bits_per_sample(),
-#if defined(OS_ANDROID)
-      // On Android, input and output use the same sample rate. In order to
-      // use the low latency mode, we need to use the buffer size suggested by
-      // the AudioManager for the sink.  It will later be used to decide
-      // the buffer size of the shared memory buffer.
-      frames_per_buffer_,
-#else
-      2 * source_params_.frames_per_buffer(),
-#endif
+      WebRtcAudioRenderer::GetOptimalBufferSize(source_params_.sample_rate(),
+                                                frames_per_buffer_),
       // If DUCKING is enabled on the source, it needs to be enabled on the
       // sink as well.
       source_params_.effects() | implicit_ducking_effect);
diff --git a/content/renderer/npapi/webplugin_delegate_proxy.cc b/content/renderer/npapi/webplugin_delegate_proxy.cc
index d64c3a0..3576b19 100644
--- a/content/renderer/npapi/webplugin_delegate_proxy.cc
+++ b/content/renderer/npapi/webplugin_delegate_proxy.cc
@@ -924,7 +924,7 @@
       render_view_->routing_id(),
       static_cast<ui::TextInputType>(input_type),
       ui::TEXT_INPUT_MODE_DEFAULT,
-      true));
+      true, 0));
 
   ViewHostMsg_SelectionBounds_Params bounds_params;
   bounds_params.anchor_rect = bounds_params.focus_rect = caret_rect;
diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/content/renderer/pepper/content_renderer_pepper_host_factory.cc
index 79fb12e9..93306eb 100644
--- a/content/renderer/pepper/content_renderer_pepper_host_factory.cc
+++ b/content/renderer/pepper/content_renderer_pepper_host_factory.cc
@@ -34,6 +34,12 @@
 #include "third_party/WebKit/public/web/WebElement.h"
 #include "third_party/WebKit/public/web/WebPluginContainer.h"
 
+#if defined(OS_WIN)
+#include "base/command_line.h"
+#include "base/win/windows_version.h"
+#include "content/public/common/content_switches.h"
+#endif
+
 using ppapi::host::ResourceHost;
 using ppapi::UnpackMessage;
 
@@ -142,8 +148,24 @@
         NOTREACHED();
         return scoped_ptr<ResourceHost>();
       }
+      ppapi::PPB_ImageData_Shared::ImageDataType image_type =
+          ppapi::PPB_ImageData_Shared::PLATFORM;
+#if defined(OS_WIN)
+      // If Win32K lockdown mitigations are enabled for Windows 8 and beyond
+      // we use the SIMPLE image data type as the PLATFORM image data type
+      // calls GDI functions to create DIB sections etc which fail in Win32K
+      // lockdown mode.
+      // TODO(ananta)
+      // Look into whether this causes a loss of functionality. From cursory
+      // testing things seem to work well.
+      if (CommandLine::ForCurrentProcess()->HasSwitch(
+              switches::kEnableWin32kRendererLockDown) &&
+          base::win::GetVersion() >= base::win::VERSION_WIN8) {
+        image_type = ppapi::PPB_ImageData_Shared::SIMPLE;
+      }
+#endif
       scoped_refptr<PPB_ImageData_Impl> image_data(new PPB_ImageData_Impl(
-          instance, ppapi::PPB_ImageData_Shared::PLATFORM));
+          instance, image_type));
       return scoped_ptr<ResourceHost>(
           PepperGraphics2DHost::Create(host_,
                                        instance,
diff --git a/content/renderer/pepper/pepper_file_chooser_host.cc b/content/renderer/pepper/pepper_file_chooser_host.cc
index f0b0697..63cd7a6 100644
--- a/content/renderer/pepper/pepper_file_chooser_host.cc
+++ b/content/renderer/pepper/pepper_file_chooser_host.cc
@@ -141,13 +141,14 @@
   } else {
     params.multiSelect = open_multiple;
   }
-  std::vector<blink::WebString> mine_types(accept_mime_types.size());
+  std::vector<blink::WebString> mime_types(accept_mime_types.size());
   for (size_t i = 0; i < accept_mime_types.size(); i++) {
-    mine_types[i] = blink::WebString::fromUTF8(accept_mime_types[i].data(),
+    mime_types[i] = blink::WebString::fromUTF8(accept_mime_types[i].data(),
                                                accept_mime_types[i].size());
   }
-  params.acceptTypes = mine_types;
+  params.acceptTypes = mime_types;
   params.directory = false;
+  params.needLocalPath = true;
 
   handler_ = new CompletionHandler(AsWeakPtr());
   RenderViewImpl* render_view = static_cast<RenderViewImpl*>(
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 97a85c9..e22101ba 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -583,13 +583,9 @@
       GetContentClient()->renderer()->IsExternalPepperPlugin(module->name()))
     external_document_load_ = true;
 
-  // TODO(tommycli): Insert heuristics to determine whether plugin content
-  // is peripheral here.
-  bool is_peripheral_content = true;
-  power_saver_enabled_ = is_peripheral_content &&
-      module->name() == kFlashPluginName &&
-      CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnablePluginPowerSaver);
+  power_saver_enabled_ = CommandLine::ForCurrentProcess()->HasSwitch(
+                             switches::kEnablePluginPowerSaver) &&
+                         IsPeripheralContent();
 
   if (power_saver_enabled_) {
     throttler_.reset(new PepperPluginInstanceThrottler(
@@ -3299,6 +3295,27 @@
   }
 }
 
+bool PepperPluginInstanceImpl::IsPeripheralContent() const {
+  if (module_->name() != kFlashPluginName)
+    return false;
+
+  // Peripheral plugin content is defined to be peripheral when the plugin
+  // content's origin differs from the top level frame's origin. For example:
+  //  - Peripheral:      a.com -> b.com/plugin.swf
+  //  - Peripheral:      a.com -> b.com/iframe.html -> b.com/plugin.swf
+  //  - NOT peripheral:  a.com -> b.com/iframe-to-a.html -> a.com/plugin.swf
+
+  // TODO(alexmos): Update this to use the origin of the RemoteFrame when 426512
+  // is fixed. For now, case 3 in the comment above doesn't work in
+  // --site-per-process mode.
+  WebFrame* main_frame = render_frame_->GetWebFrame()->view()->mainFrame();
+  if (main_frame->isWebRemoteFrame())
+     return true;
+
+  GURL main_frame_url = main_frame->document().url();
+  return plugin_url_.GetOrigin() != main_frame_url.GetOrigin();
+}
+
 void PepperPluginInstanceImpl::SetPluginThrottled(bool throttled) {
   // Do not throttle if we've already disabled power saver.
   if (!power_saver_enabled_ && throttled)
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h
index 4b14931..36d2a26 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -687,6 +687,9 @@
                                  int pending_host_id,
                                  const ppapi::URLResponseInfoData& data);
 
+  // Peripheral content is cross-origin plugin content determined heuristically
+  // to be not the "main attraction" of the webpage.
+  bool IsPeripheralContent() const;
   void SetPluginThrottled(bool throttled);
 
   RenderFrameImpl* render_frame_;
diff --git a/content/renderer/pepper/resource_creation_impl.cc b/content/renderer/pepper/resource_creation_impl.cc
index 29ac94d..bb0b9f1 100644
--- a/content/renderer/pepper/resource_creation_impl.cc
+++ b/content/renderer/pepper/resource_creation_impl.cc
@@ -21,6 +21,12 @@
 #include "ppapi/shared_impl/ppb_input_event_shared.h"
 #include "ppapi/shared_impl/var.h"
 
+#if defined(OS_WIN)
+#include "base/command_line.h"
+#include "base/win/windows_version.h"
+#include "content/public/common/content_switches.h"
+#endif
+
 using ppapi::InputEventData;
 using ppapi::PPB_InputEvent_Shared;
 using ppapi::StringVar;
@@ -125,6 +131,20 @@
                                                   PP_ImageDataFormat format,
                                                   const PP_Size* size,
                                                   PP_Bool init_to_zero) {
+#if defined(OS_WIN)
+  // If Win32K lockdown mitigations are enabled for Windows 8 and beyond,
+  // we use the SIMPLE image data type as the PLATFORM image data type
+  // calls GDI functions to create DIB sections etc which fail in Win32K
+  // lockdown mode.
+  // TODO(ananta)
+  // Look into whether this causes a loss of functionality. From cursory
+  // testing things seem to work well.
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableWin32kRendererLockDown) &&
+      base::win::GetVersion() >= base::win::VERSION_WIN8) {
+    return CreateImageDataSimple(instance, format, size, init_to_zero);
+  }
+#endif
   return PPB_ImageData_Impl::Create(instance,
                                     ppapi::PPB_ImageData_Shared::PLATFORM,
                                     format,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index ce82a4d8..63ab694 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -26,7 +26,6 @@
 #include "content/child/service_worker/service_worker_network_provider.h"
 #include "content/child/service_worker/service_worker_provider_context.h"
 #include "content/child/service_worker/web_service_worker_provider_impl.h"
-#include "content/child/web_socket_stream_handle_impl.h"
 #include "content/child/web_url_loader_impl.h"
 #include "content/child/web_url_request_util.h"
 #include "content/child/webmessageportchannel_impl.h"
@@ -36,7 +35,6 @@
 #include "content/common/frame_messages.h"
 #include "content/common/input_messages.h"
 #include "content/common/service_worker/service_worker_types.h"
-#include "content/common/socket_stream_handle_data.h"
 #include "content/common/swapped_out_messages.h"
 #include "content/common/view_messages.h"
 #include "content/public/common/bindings_policy.h"
@@ -97,6 +95,7 @@
 #include "content/renderer/websharedworker_proxy.h"
 #include "gin/modules/module_registry.h"
 #include "media/base/audio_renderer_mixer_input.h"
+#include "media/base/renderer.h"
 #include "media/blink/webmediaplayer_impl.h"
 #include "media/blink/webmediaplayer_params.h"
 #include "media/filters/gpu_video_accelerator_factories.h"
@@ -1360,6 +1359,11 @@
     return;
   accessibility_mode_ = new_mode;
   if (renderer_accessibility_) {
+    // Note: this isn't called automatically by the destructor because
+    // there'd be no point in calling it in frame teardown, only if there's
+    // an accessibility mode change but the frame is persisting.
+    renderer_accessibility_->DisableAccessibility();
+
     delete renderer_accessibility_;
     renderer_accessibility_ = NULL;
   }
@@ -1687,10 +1691,8 @@
       render_thread->compositor_message_loop_proxy(),
       base::Bind(&EncryptedMediaPlayerSupportImpl::Create),
       initial_cdm);
-  return new media::WebMediaPlayerImpl(frame,
-                                       client,
-                                       weak_factory_.GetWeakPtr(),
-                                       params);
+  return new media::WebMediaPlayerImpl(
+      frame, client, weak_factory_.GetWeakPtr(), nullptr, params);
 #endif  // defined(OS_ANDROID)
 }
 
@@ -1701,13 +1703,14 @@
     const blink::WebString& key_system) {
   DCHECK(!frame_ || frame_ == frame);
 
-  RenderCdmFactory cdm_factory(
 #if defined(ENABLE_PEPPER_CDMS)
-      base::Bind(&PepperCdmWrapperImpl::Create, frame)
+  RenderCdmFactory cdm_factory(
+      base::Bind(&PepperCdmWrapperImpl::Create, frame));
 #elif defined(ENABLE_BROWSER_CDMS)
-      GetCdmManager()
+  RenderCdmFactory cdm_factory(GetCdmManager());
+#else
+  RenderCdmFactory cdm_factory;
 #endif
-  );
 
   return WebContentDecryptionModuleImpl::Create(&cdm_factory, security_origin,
                                                 key_system);
@@ -3099,13 +3102,6 @@
       QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks));
 }
 
-void RenderFrameImpl::willOpenSocketStream(
-    blink::WebSocketStreamHandle* handle) {
-  WebSocketStreamHandleImpl* impl =
-      static_cast<WebSocketStreamHandleImpl*>(handle);
-  impl->SetUserData(handle, new SocketStreamHandleData(routing_id_));
-}
-
 void RenderFrameImpl::willOpenWebSocket(blink::WebSocketHandle* handle) {
   WebSocketBridge* impl = static_cast<WebSocketBridge*>(handle);
   impl->set_render_frame_id(routing_id_);
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index a67458c..9457afc 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -437,8 +437,6 @@
                                    blink::WebStorageQuotaType type,
                                    unsigned long long requested_size,
                                    blink::WebStorageQuotaCallbacks callbacks);
-  virtual void willOpenSocketStream(
-      blink::WebSocketStreamHandle* handle);
   virtual void willOpenWebSocket(blink::WebSocketHandle* handle);
   virtual blink::WebGeolocationClient* geolocationClient();
   virtual blink::WebPushClient* pushClient();
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 9cc2e7e0..1e31fa86 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -74,7 +74,6 @@
 #include "content/renderer/dom_storage/webstoragearea_impl.h"
 #include "content/renderer/dom_storage/webstoragenamespace_impl.h"
 #include "content/renderer/gpu/compositor_output_surface.h"
-#include "content/renderer/gpu/gpu_benchmarking_extension.h"
 #include "content/renderer/input/input_event_filter.h"
 #include "content/renderer/input/input_handler_manager.h"
 #include "content/renderer/media/aec_dump_message_filter.h"
@@ -486,8 +485,6 @@
   InitSkiaEventTracer();
 
   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
-  if (command_line.HasSwitch(cc::switches::kEnableGpuBenchmarking))
-      RegisterExtension(GpuBenchmarkingExtension::Get());
 
   is_impl_side_painting_enabled_ =
       command_line.HasSwitch(switches::kEnableImplSidePainting);
@@ -1510,7 +1507,7 @@
   }
 
   if (memory_pressure_level ==
-      base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL) {
+      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
     if (blink_platform_impl_) {
       // Clear the image cache. Do not call into blink if it is not initialized.
       blink::WebImageCache::clear();
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 2e8f9bc..4ce5772 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -48,7 +48,6 @@
 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
 #include "content/common/input_messages.h"
 #include "content/common/pepper_messages.h"
-#include "content/common/socket_stream_handle_data.h"
 #include "content/common/ssl_status_serialization.h"
 #include "content/common/view_messages.h"
 #include "content/public/common/bindings_policy.h"
@@ -77,6 +76,7 @@
 #include "content/renderer/disambiguation_popup_helper.h"
 #include "content/renderer/dom_storage/webstoragenamespace_impl.h"
 #include "content/renderer/drop_data_builder.h"
+#include "content/renderer/gpu/gpu_benchmarking_extension.h"
 #include "content/renderer/gpu/render_widget_compositor.h"
 #include "content/renderer/history_controller.h"
 #include "content/renderer/history_serialization.h"
@@ -128,7 +128,6 @@
 #include "third_party/WebKit/public/platform/WebPoint.h"
 #include "third_party/WebKit/public/platform/WebRect.h"
 #include "third_party/WebKit/public/platform/WebSize.h"
-#include "third_party/WebKit/public/platform/WebSocketStreamHandle.h"
 #include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
@@ -279,7 +278,6 @@
 using blink::WebSerializedScriptValue;
 using blink::WebSettings;
 using blink::WebSize;
-using blink::WebSocketStreamHandle;
 using blink::WebStorageNamespace;
 using blink::WebStorageQuotaCallbacks;
 using blink::WebStorageQuotaError;
@@ -1807,6 +1805,7 @@
   ipc_params.accept_types.reserve(params.acceptTypes.size());
   for (size_t i = 0; i < params.acceptTypes.size(); ++i)
     ipc_params.accept_types.push_back(params.acceptTypes[i]);
+  ipc_params.need_local_path = params.needLocalPath;
 #if defined(OS_ANDROID)
   ipc_params.capture = params.useMediaCapture;
 #endif
@@ -2381,6 +2380,9 @@
   if (command_line.HasSwitch(switches::kEnableSkiaBenchmarking))
     SkiaBenchmarking::Install(frame);
 
+  if (command_line.HasSwitch(cc::switches::kEnableGpuBenchmarking))
+    GpuBenchmarking::Install(frame);
+
   if (command_line.HasSwitch(switches::kEnableMemoryBenchmarking))
     MemoryBenchmarkingExtension::Install(frame);
 }
@@ -2526,8 +2528,11 @@
 
   if (node.isElementNode()) {
     const WebElement& element = node.toConst<WebElement>();
-    if (element.isTextFormControlElement())
-      return true;
+    if (element.isTextFormControlElement()) {
+      if (!(element.hasAttribute("readonly") ||
+            element.hasAttribute("disabled")))
+        return true;
+    }
 
     // Also return true if it has an ARIA role of 'textbox'.
     for (unsigned i = 0; i < element.attributeCount(); ++i) {
@@ -3019,6 +3024,12 @@
     selected_file.path = files[i].file_path.AsUTF16Unsafe();
     selected_file.displayName =
         base::FilePath(files[i].display_name).AsUTF16Unsafe();
+    if (files[i].file_system_url.is_valid()) {
+      selected_file.fileSystemURL = files[i].file_system_url;
+      selected_file.length = files[i].length;
+      selected_file.modificationTime = files[i].modification_time.ToDoubleT();
+      selected_file.isDirectory = files[i].is_directory;
+    }
     selected_files[i] = selected_file;
   }
 
@@ -3325,8 +3336,13 @@
   WebFrame* main_frame = webview()->mainFrame();
   for (WebFrame* frame = main_frame; frame;
        frame = frame->traverseNext(false)) {
-    if (frame->isWebLocalFrame())
+    // TODO(nasko): This is a hack for the case in which the top-level
+    // frame is being rendered in another process. It will not
+    // behave correctly for out of process iframes.
+    if (frame->isWebLocalFrame()) {
       main_frame = frame;
+      break;
+    }
   }
 
   // If we have a provisional frame we are between the start and commit stages
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 21d2ec5..530210d 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -99,7 +99,6 @@
 class WebMouseEvent;
 class WebPeerConnectionHandler;
 class WebPeerConnectionHandlerClient;
-class WebSocketStreamHandle;
 class WebSpeechRecognizer;
 class WebStorageNamespace;
 class WebTouchEvent;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 57b7abfd..6644306b 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -403,6 +403,7 @@
       input_method_is_active_(false),
       text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
       text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
+      text_input_flags_(0),
       can_compose_inline_(true),
       popup_type_(popup_type),
       pending_window_rect_count_(0),
@@ -1078,13 +1079,9 @@
     }
   }
 
-  // Unconsumed touchmove acks should never be throttled as they're required to
-  // dispatch compositor-handled scroll gestures.
   bool event_type_can_be_rate_limited =
       input_event->type == WebInputEvent::MouseMove ||
-      input_event->type == WebInputEvent::MouseWheel ||
-      (input_event->type == WebInputEvent::TouchMove &&
-       ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
+      input_event->type == WebInputEvent::MouseWheel;
 
   bool frame_pending = compositor_ && compositor_->BeginMainFrameRequested();
 
@@ -1780,17 +1777,21 @@
   if (webwidget_)
     new_info = webwidget_->textInputInfo();
   const ui::TextInputMode new_mode = ConvertInputMode(new_info.inputMode);
+  int new_flags = new_info.flags;
 
   if (text_input_type_ != new_type
       || can_compose_inline_ != new_can_compose_inline
-      || text_input_mode_ != new_mode) {
+      || text_input_mode_ != new_mode
+      || text_input_flags_ != new_flags) {
     Send(new ViewHostMsg_TextInputTypeChanged(routing_id(),
                                               new_type,
                                               new_mode,
-                                              new_can_compose_inline));
+                                              new_can_compose_inline,
+                                              new_flags));
     text_input_type_ = new_type;
     can_compose_inline_ = new_can_compose_inline;
     text_input_mode_ = new_mode;
+    text_input_flags_ = new_flags;
   }
 }
 
@@ -1845,13 +1846,15 @@
     Send(new ViewHostMsg_TextInputTypeChanged(routing_id(),
                                               new_type,
                                               text_input_mode_,
-                                              new_can_compose_inline));
+                                              new_can_compose_inline,
+                                              new_info.flags));
 #endif
     Send(new ViewHostMsg_TextInputStateChanged(routing_id(), p));
 
     text_input_info_ = new_info;
     text_input_type_ = new_type;
     can_compose_inline_ = new_can_compose_inline;
+    text_input_flags_ = new_info.flags;
   }
 }
 #endif
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index f9e7ea0..6b17db7 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -656,6 +656,9 @@
   // Stores the current text input mode of |webwidget_|.
   ui::TextInputMode text_input_mode_;
 
+  // Stores the current text input flags of |webwidget_|.
+  int text_input_flags_;
+
   // Stores the current type of composition text rendering of |webwidget_|.
   bool can_compose_inline_;
 
diff --git a/content/renderer/resource_fetcher_browsertest.cc b/content/renderer/resource_fetcher_browsertest.cc
index 1695f0e..c016754 100644
--- a/content/renderer/resource_fetcher_browsertest.cc
+++ b/content/renderer/resource_fetcher_browsertest.cc
@@ -15,7 +15,6 @@
 #include "content/public/renderer/render_view.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
-#include "content/public/test/routing_id_mangling_disabler.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "third_party/WebKit/public/platform/WebURLResponse.h"
@@ -285,8 +284,6 @@
     EXPECT_EQ(delegate->response().httpStatusCode(), 200);
     EXPECT_EQ(kHeader, delegate->data());
   }
-
-  content::RoutingIDManglingDisabler routing_id_mangling_disabler_;
 };
 
 #if defined(OS_ANDROID)
diff --git a/content/renderer/scheduler/task_queue_manager.cc b/content/renderer/scheduler/task_queue_manager.cc
new file mode 100644
index 0000000..227a7e87
--- /dev/null
+++ b/content/renderer/scheduler/task_queue_manager.cc
@@ -0,0 +1,295 @@
+// 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 "content/renderer/scheduler/task_queue_manager.h"
+
+#include "base/bind.h"
+#include "base/debug/trace_event.h"
+#include "content/renderer/scheduler/task_queue_selector.h"
+
+namespace content {
+namespace internal {
+
+class TaskQueue : public base::SingleThreadTaskRunner {
+ public:
+  TaskQueue(TaskQueueManager* task_queue_manager);
+
+  // base::SingleThreadTaskRunner implementation.
+  virtual bool RunsTasksOnCurrentThread() const override;
+  virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
+                               const base::Closure& task,
+                               base::TimeDelta delay) override;
+  virtual bool PostNonNestableDelayedTask(
+      const tracked_objects::Location& from_here,
+      const base::Closure& task,
+      base::TimeDelta delay) override;
+
+  // Adds a task at the end of the incoming task queue and schedules a call to
+  // TaskQueueManager::DoWork() if the incoming queue was empty and automatic
+  // pumping is enabled. Can be called on an arbitrary thread.
+  void EnqueueTask(const base::PendingTask& pending_task);
+
+  bool IsQueueEmpty() const;
+
+  void SetAutoPump(bool auto_pump);
+  void PumpQueue();
+
+  bool UpdateWorkQueue();
+  base::PendingTask TakeTaskFromWorkQueue();
+
+  void WillDeleteTaskQueueManager();
+
+  base::TaskQueue& work_queue() { return work_queue_; }
+
+ private:
+  virtual ~TaskQueue();
+
+  void PumpQueueLocked();
+  void EnqueueTaskLocked(const base::PendingTask& pending_task);
+
+  // This lock protects all members except the work queue.
+  mutable base::Lock lock_;
+  TaskQueueManager* task_queue_manager_;
+  base::TaskQueue incoming_queue_;
+  bool auto_pump_;
+
+  base::TaskQueue work_queue_;
+
+  DISALLOW_COPY_AND_ASSIGN(TaskQueue);
+};
+
+TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager)
+    : task_queue_manager_(task_queue_manager), auto_pump_(true) {
+}
+
+TaskQueue::~TaskQueue() {
+}
+
+void TaskQueue::WillDeleteTaskQueueManager() {
+  base::AutoLock lock(lock_);
+  task_queue_manager_ = nullptr;
+}
+
+bool TaskQueue::RunsTasksOnCurrentThread() const {
+  base::AutoLock lock(lock_);
+  if (!task_queue_manager_)
+    return false;
+  return task_queue_manager_->RunsTasksOnCurrentThread();
+}
+
+bool TaskQueue::PostDelayedTask(const tracked_objects::Location& from_here,
+                                const base::Closure& task,
+                                base::TimeDelta delay) {
+  base::AutoLock lock(lock_);
+  if (!task_queue_manager_)
+    return false;
+
+  base::PendingTask pending_task(from_here, task);
+  task_queue_manager_->DidQueueTask(&pending_task);
+
+  if (delay > base::TimeDelta()) {
+    return task_queue_manager_->PostDelayedTask(
+        from_here, Bind(&TaskQueue::EnqueueTask, this, pending_task), delay);
+  }
+  EnqueueTaskLocked(pending_task);
+  return true;
+}
+
+bool TaskQueue::PostNonNestableDelayedTask(
+    const tracked_objects::Location& from_here,
+    const base::Closure& task,
+    base::TimeDelta delay) {
+  base::AutoLock lock(lock_);
+  if (!task_queue_manager_)
+    return false;
+  return task_queue_manager_->PostNonNestableDelayedTask(
+      from_here, task, delay);
+}
+
+bool TaskQueue::IsQueueEmpty() const {
+  if (!work_queue_.empty())
+    return false;
+
+  {
+    base::AutoLock lock(lock_);
+    return incoming_queue_.empty();
+  }
+}
+
+bool TaskQueue::UpdateWorkQueue() {
+  if (!work_queue_.empty())
+    return true;
+
+  {
+    base::AutoLock lock(lock_);
+    if (!auto_pump_ || incoming_queue_.empty())
+      return false;
+    work_queue_.Swap(&incoming_queue_);
+    return true;
+  }
+}
+
+base::PendingTask TaskQueue::TakeTaskFromWorkQueue() {
+  base::PendingTask pending_task = work_queue_.front();
+  work_queue_.pop();
+  return pending_task;
+}
+
+void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) {
+  base::AutoLock lock(lock_);
+  EnqueueTaskLocked(pending_task);
+}
+
+void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) {
+  lock_.AssertAcquired();
+  if (!task_queue_manager_)
+    return;
+  if (auto_pump_ && incoming_queue_.empty())
+    task_queue_manager_->PostDoWorkOnMainRunner();
+  incoming_queue_.push(pending_task);
+}
+
+void TaskQueue::SetAutoPump(bool auto_pump) {
+  base::AutoLock lock(lock_);
+  if (auto_pump) {
+    auto_pump_ = true;
+    PumpQueueLocked();
+  } else {
+    auto_pump_ = false;
+  }
+}
+
+void TaskQueue::PumpQueueLocked() {
+  lock_.AssertAcquired();
+  while (!incoming_queue_.empty()) {
+    work_queue_.push(incoming_queue_.front());
+    incoming_queue_.pop();
+  }
+  if (!work_queue_.empty())
+    task_queue_manager_->PostDoWorkOnMainRunner();
+}
+
+void TaskQueue::PumpQueue() {
+  base::AutoLock lock(lock_);
+  PumpQueueLocked();
+}
+
+}  // namespace
+
+TaskQueueManager::TaskQueueManager(
+    size_t task_queue_count,
+    scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+    TaskQueueSelector* selector)
+    : main_task_runner_(main_task_runner),
+      selector_(selector),
+      weak_factory_(this) {
+  DCHECK(main_task_runner->RunsTasksOnCurrentThread());
+
+  task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr();
+  for (size_t i = 0; i < task_queue_count; i++) {
+    scoped_refptr<internal::TaskQueue> queue(
+        make_scoped_refptr(new internal::TaskQueue(this)));
+    queues_.push_back(queue);
+  }
+
+  std::vector<const base::TaskQueue*> work_queues;
+  for (const auto& queue: queues_)
+    work_queues.push_back(&queue->work_queue());
+  selector_->RegisterWorkQueues(work_queues);
+}
+
+TaskQueueManager::~TaskQueueManager() {
+  for (auto& queue : queues_)
+    queue->WillDeleteTaskQueueManager();
+}
+
+internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const {
+  DCHECK_LT(queue_index, queues_.size());
+  return queues_[queue_index].get();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+TaskQueueManager::TaskRunnerForQueue(size_t queue_index) const {
+  return Queue(queue_index);
+}
+
+bool TaskQueueManager::IsQueueEmpty(size_t queue_index) const {
+  internal::TaskQueue* queue = Queue(queue_index);
+  return queue->IsQueueEmpty();
+}
+
+void TaskQueueManager::SetAutoPump(size_t queue_index, bool auto_pump) {
+  main_thread_checker_.CalledOnValidThread();
+  internal::TaskQueue* queue = Queue(queue_index);
+  queue->SetAutoPump(auto_pump);
+}
+
+void TaskQueueManager::PumpQueue(size_t queue_index) {
+  main_thread_checker_.CalledOnValidThread();
+  internal::TaskQueue* queue = Queue(queue_index);
+  queue->PumpQueue();
+}
+
+bool TaskQueueManager::UpdateWorkQueues() {
+  // TODO(skyostil): This is not efficient when the number of queues grows very
+  // large due to the number of locks taken. Consider optimizing when we get
+  // there.
+  main_thread_checker_.CalledOnValidThread();
+  bool has_work = false;
+  for (auto& queue : queues_)
+    has_work |= queue->UpdateWorkQueue();
+  return has_work;
+}
+
+void TaskQueueManager::PostDoWorkOnMainRunner() {
+  main_task_runner_->PostTask(
+      FROM_HERE, Bind(&TaskQueueManager::DoWork, task_queue_manager_weak_ptr_));
+}
+
+void TaskQueueManager::DoWork() {
+  main_thread_checker_.CalledOnValidThread();
+  if (!UpdateWorkQueues())
+    return;
+
+  size_t queue_index;
+  if (!selector_->SelectWorkQueueToService(&queue_index))
+    return;
+  PostDoWorkOnMainRunner();
+  RunTaskFromWorkQueue(queue_index);
+}
+
+void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) {
+  pending_task->sequence_num = task_sequence_num_.GetNext();
+  task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task);
+}
+
+void TaskQueueManager::RunTaskFromWorkQueue(size_t queue_index) {
+  main_thread_checker_.CalledOnValidThread();
+  internal::TaskQueue* queue = Queue(queue_index);
+  base::PendingTask pending_task = queue->TakeTaskFromWorkQueue();
+  task_annotator_.RunTask(
+      "TaskQueueManager::PostTask", "TaskQueueManager::RunTask", pending_task);
+}
+
+bool TaskQueueManager::RunsTasksOnCurrentThread() const {
+  return main_task_runner_->RunsTasksOnCurrentThread();
+}
+
+bool TaskQueueManager::PostDelayedTask(
+    const tracked_objects::Location& from_here,
+    const base::Closure& task,
+    base::TimeDelta delay) {
+  DCHECK(delay > base::TimeDelta());
+  return main_task_runner_->PostDelayedTask(from_here, task, delay);
+}
+
+bool TaskQueueManager::PostNonNestableDelayedTask(
+    const tracked_objects::Location& from_here,
+    const base::Closure& task,
+    base::TimeDelta delay) {
+  // Defer non-nestable work to the main task runner.
+  return main_task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
+}
+
+}  // namespace content
diff --git a/content/renderer/scheduler/task_queue_manager.h b/content/renderer/scheduler/task_queue_manager.h
new file mode 100644
index 0000000..b1b7935
--- /dev/null
+++ b/content/renderer/scheduler/task_queue_manager.h
@@ -0,0 +1,118 @@
+// 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 CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
+#define CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
+
+#include "base/atomic_sequence_num.h"
+#include "base/debug/task_annotator.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/pending_task.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
+#include "content/common/content_export.h"
+
+namespace content {
+namespace internal {
+class TaskQueue;
+}
+class TaskQueueSelector;
+
+// The task queue manager provides N task queues and a selector interface for
+// choosing which task queue to service next. Each task queue consists of two
+// sub queues:
+//
+// 1. Incoming task queue. Tasks that are posted get immediately appended here.
+//    When a task is appended into an empty incoming queue, the task manager
+//    work function (DoWork) is scheduled to run on the main task runner.
+//
+// 2. Work queue. If a work queue is empty when DoWork() is entered, tasks from
+//    the incoming task queue (if any) are moved here. The work queues are
+//    registered with the selector as input to the scheduling decision.
+//
+class CONTENT_EXPORT TaskQueueManager {
+ public:
+  // Create a task queue manager with |task_queue_count| task queues.
+  // |main_task_runner| identifies the thread on which where the tasks are
+  // eventually run. |selector| is used to choose which task queue to service.
+  // It should outlive this class.
+  TaskQueueManager(size_t task_queue_count,
+                   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+                   TaskQueueSelector* selector);
+  ~TaskQueueManager();
+
+  // Returns the task runner which targets the queue selected by |queue_index|.
+  scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerForQueue(
+      size_t queue_index) const;
+
+  // If |auto_pump| is false, tasks posted to the given incoming queue will not
+  // be automatically scheduled for execution or transferred to the work queue.
+  // Instead, the selector should call PumpQueue() when necessary to bring in
+  // new tasks for execution.
+  void SetAutoPump(size_t queue_index, bool auto_pump);
+
+  // Reloads new tasks from the incoming queue for |queue_index| into the work
+  // queue, regardless of whether the work queue is empty or not. After this,
+  // this function ensures that the tasks in the work queue, if any, are
+  // scheduled for execution.
+  //
+  // This function only needs to be called if automatic pumping is disabled
+  // for |queue_index|. See |SetQueueAutoPump|. By default automatic pumping is
+  // enabled for all queues.
+  void PumpQueue(size_t queue_index);
+
+  // Returns true if there no tasks in either the work or incoming task queue
+  // identified by |queue_index|. Note that this function involves taking a
+  // lock, so calling it has some overhead.
+  bool IsQueueEmpty(size_t queue_index) const;
+
+ private:
+  friend class internal::TaskQueue;
+
+  // Called by the task queue to register a new pending task and allocate a
+  // sequence number for it.
+  void DidQueueTask(base::PendingTask* pending_task);
+
+  // Post a task to call DoWork() on the main task runner.
+  void PostDoWorkOnMainRunner();
+
+  // Use the selector to choose a pending task and run it.
+  void DoWork();
+
+  // Reloads any empty work queues which have automatic pumping enabled.
+  // Returns true if any work queue has tasks after doing this.
+  bool UpdateWorkQueues();
+
+  // Runs a single task from the work queue designated by |queue_index|. The
+  // queue must not be empty.
+  void RunTaskFromWorkQueue(size_t queue_index);
+
+  bool RunsTasksOnCurrentThread() const;
+  bool PostDelayedTask(const tracked_objects::Location& from_here,
+                       const base::Closure& task,
+                       base::TimeDelta delay);
+  bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
+                                  const base::Closure& task,
+                                  base::TimeDelta delay);
+  internal::TaskQueue* Queue(size_t queue_index) const;
+
+  std::vector<scoped_refptr<internal::TaskQueue>> queues_;
+  base::AtomicSequenceNumber task_sequence_num_;
+  base::debug::TaskAnnotator task_annotator_;
+
+  base::ThreadChecker main_thread_checker_;
+  scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+  TaskQueueSelector* selector_;
+
+  base::WeakPtr<TaskQueueManager> task_queue_manager_weak_ptr_;
+  base::WeakPtrFactory<TaskQueueManager> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
diff --git a/content/renderer/scheduler/task_queue_manager_unittest.cc b/content/renderer/scheduler/task_queue_manager_unittest.cc
new file mode 100644
index 0000000..4323825
--- /dev/null
+++ b/content/renderer/scheduler/task_queue_manager_unittest.cc
@@ -0,0 +1,358 @@
+// 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 "content/renderer/scheduler/task_queue_manager.h"
+
+#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread.h"
+#include "content/renderer/scheduler/task_queue_selector.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class SelectorForTest : public TaskQueueSelector {
+ public:
+  SelectorForTest() {}
+
+  void RegisterWorkQueues(
+      const std::vector<const base::TaskQueue*>& work_queues) override {
+    work_queues_ = work_queues;
+  }
+
+  bool SelectWorkQueueToService(size_t* out_queue_index) override {
+    if (queues_to_service_.empty())
+      return false;
+    *out_queue_index = queues_to_service_.front();
+    queues_to_service_.pop_front();
+    return true;
+  }
+
+  void AppendQueueToService(size_t queue_index) {
+    queues_to_service_.push_back(queue_index);
+  }
+
+  const std::vector<const base::TaskQueue*>& work_queues() {
+    return work_queues_;
+  }
+
+ private:
+  std::deque<size_t> queues_to_service_;
+  std::vector<const base::TaskQueue*> work_queues_;
+
+  DISALLOW_COPY_AND_ASSIGN(SelectorForTest);
+};
+
+class TaskQueueManagerTest : public testing::Test {
+ protected:
+  void Initialize(size_t num_queues) {
+    test_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner());
+    selector_ = make_scoped_ptr(new SelectorForTest);
+    manager_ = make_scoped_ptr(
+        new TaskQueueManager(num_queues, test_task_runner_, selector_.get()));
+  }
+
+  scoped_refptr<base::TestSimpleTaskRunner> test_task_runner_;
+  scoped_ptr<SelectorForTest> selector_;
+  scoped_ptr<TaskQueueManager> manager_;
+};
+
+void TestTask(int value, std::vector<int>* out_result) {
+  out_result->push_back(value);
+}
+
+TEST_F(TaskQueueManagerTest, SingleQueuePosting) {
+  Initialize(1u);
+  EXPECT_EQ(1u, selector_->work_queues().size());
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+
+  selector_->AppendQueueToService(0);
+  selector_->AppendQueueToService(0);
+  selector_->AppendQueueToService(0);
+
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+  EXPECT_EQ(2, run_order[1]);
+  EXPECT_EQ(3, run_order[2]);
+}
+
+TEST_F(TaskQueueManagerTest, MultiQueuePosting) {
+  Initialize(3u);
+  EXPECT_EQ(3u, selector_->work_queues().size());
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runners[3] = {
+      manager_->TaskRunnerForQueue(0),
+      manager_->TaskRunnerForQueue(1),
+      manager_->TaskRunnerForQueue(2)};
+
+  selector_->AppendQueueToService(0);
+  selector_->AppendQueueToService(1);
+  selector_->AppendQueueToService(2);
+  selector_->AppendQueueToService(0);
+  selector_->AppendQueueToService(1);
+  selector_->AppendQueueToService(2);
+
+  runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+  runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+  runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
+  runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
+  runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order));
+  runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order));
+
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+  EXPECT_EQ(3, run_order[1]);
+  EXPECT_EQ(5, run_order[2]);
+  EXPECT_EQ(2, run_order[3]);
+  EXPECT_EQ(4, run_order[4]);
+  EXPECT_EQ(6, run_order[5]);
+}
+
+TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) {
+  Initialize(1u);
+  EXPECT_EQ(1u, selector_->work_queues().size());
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  runner->PostNonNestableTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+
+  // Non-nestable tasks never make it to the selector.
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+}
+
+TEST_F(TaskQueueManagerTest, QueuePolling) {
+  Initialize(1u);
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  EXPECT_TRUE(manager_->IsQueueEmpty(0));
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+  EXPECT_FALSE(manager_->IsQueueEmpty(0));
+
+  selector_->AppendQueueToService(0);
+  test_task_runner_->RunUntilIdle();
+  EXPECT_TRUE(manager_->IsQueueEmpty(0));
+}
+
+TEST_F(TaskQueueManagerTest, DelayedTaskPosting) {
+  Initialize(1u);
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  selector_->AppendQueueToService(0);
+
+  base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
+  runner->PostDelayedTask(
+      FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay);
+  EXPECT_EQ(delay, test_task_runner_->NextPendingTaskDelay());
+  EXPECT_TRUE(manager_->IsQueueEmpty(0));
+  EXPECT_TRUE(run_order.empty());
+
+  // The task is inserted to the incoming queue only after the delay.
+  test_task_runner_->RunPendingTasks();
+  EXPECT_FALSE(manager_->IsQueueEmpty(0));
+  EXPECT_TRUE(run_order.empty());
+
+  // After the delay the task runs normally.
+  selector_->AppendQueueToService(0);
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumping) {
+  Initialize(1u);
+  manager_->SetAutoPump(0, false);
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  // Posting a task when pumping is disabled doesn't result in work getting
+  // posted.
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+  EXPECT_FALSE(test_task_runner_->HasPendingTask());
+
+  // However polling still works.
+  EXPECT_FALSE(manager_->IsQueueEmpty(0));
+
+  // After pumping the task runs normally.
+  manager_->PumpQueue(0);
+  EXPECT_TRUE(test_task_runner_->HasPendingTask());
+  selector_->AppendQueueToService(0);
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumpingToggle) {
+  Initialize(1u);
+  manager_->SetAutoPump(0, false);
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  // Posting a task when pumping is disabled doesn't result in work getting
+  // posted.
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+  EXPECT_FALSE(test_task_runner_->HasPendingTask());
+
+  // When pumping is enabled the task runs normally.
+  manager_->SetAutoPump(0, true);
+  EXPECT_TRUE(test_task_runner_->HasPendingTask());
+  selector_->AppendQueueToService(0);
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+}
+
+TEST_F(TaskQueueManagerTest, DenyRunning) {
+  Initialize(1u);
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+
+  // Since we haven't appended a work queue to be selected, the task doesn't
+  // run.
+  test_task_runner_->RunUntilIdle();
+  EXPECT_TRUE(run_order.empty());
+
+  // Pumping the queue again with a selected work queue runs the task.
+  manager_->PumpQueue(0);
+  selector_->AppendQueueToService(0);
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) {
+  Initialize(1u);
+  manager_->SetAutoPump(0, false);
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  // Posting a delayed task when pumping will apply the delay, but won't cause
+  // work to executed afterwards.
+  base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
+  runner->PostDelayedTask(
+      FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay);
+  test_task_runner_->RunUntilIdle();
+  EXPECT_TRUE(run_order.empty());
+
+  // After pumping the task runs normally.
+  manager_->PumpQueue(0);
+  EXPECT_TRUE(test_task_runner_->HasPendingTask());
+  selector_->AppendQueueToService(0);
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+}
+
+TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) {
+  Initialize(1u);
+  manager_->SetAutoPump(0, false);
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  // Posting two tasks and pumping twice should result in two tasks in the work
+  // queue.
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+  manager_->PumpQueue(0);
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
+  manager_->PumpQueue(0);
+
+  EXPECT_EQ(2u, selector_->work_queues()[0]->size());
+}
+
+void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
+                       int countdown,
+                       std::vector<int>* out_result) {
+  out_result->push_back(countdown);
+  if (--countdown) {
+    runner->PostTask(FROM_HERE,
+                     Bind(&ReentrantTestTask, runner, countdown, out_result));
+  }
+}
+
+TEST_F(TaskQueueManagerTest, ReentrantPosting) {
+  Initialize(1u);
+  EXPECT_EQ(1u, selector_->work_queues().size());
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  runner->PostTask(FROM_HERE, Bind(&ReentrantTestTask, runner, 3, &run_order));
+
+  selector_->AppendQueueToService(0);
+  selector_->AppendQueueToService(0);
+  selector_->AppendQueueToService(0);
+
+  test_task_runner_->RunUntilIdle();
+  EXPECT_EQ(3, run_order[0]);
+  EXPECT_EQ(2, run_order[1]);
+  EXPECT_EQ(1, run_order[2]);
+}
+
+TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) {
+  Initialize(1u);
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+  manager_.reset();
+  selector_.reset();
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
+
+  test_task_runner_->RunUntilIdle();
+  EXPECT_TRUE(run_order.empty());
+}
+
+void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner,
+                      std::vector<int>* run_order) {
+  runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, run_order));
+}
+
+TEST_F(TaskQueueManagerTest, PostFromThread) {
+  base::MessageLoop message_loop;
+  selector_ = make_scoped_ptr(new SelectorForTest);
+  manager_ = make_scoped_ptr(
+      new TaskQueueManager(1u, message_loop.task_runner(), selector_.get()));
+
+  std::vector<int> run_order;
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
+      manager_->TaskRunnerForQueue(0);
+
+  base::Thread thread("TestThread");
+  thread.Start();
+  thread.message_loop()->PostTask(
+      FROM_HERE, base::Bind(&PostTaskToRunner, runner, &run_order));
+  thread.Stop();
+
+  selector_->AppendQueueToService(0);
+  message_loop.RunUntilIdle();
+  EXPECT_EQ(1, run_order[0]);
+}
+
+}  // namespace
+}  // namespace content
diff --git a/content/renderer/scheduler/task_queue_selector.h b/content/renderer/scheduler/task_queue_selector.h
new file mode 100644
index 0000000..afab36a
--- /dev/null
+++ b/content/renderer/scheduler/task_queue_selector.h
@@ -0,0 +1,37 @@
+// 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 CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_SELECTOR_H_
+#define CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_SELECTOR_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+
+namespace base {
+class TaskQueue;
+}
+
+namespace content {
+
+class TaskQueueSelector {
+ public:
+  virtual ~TaskQueueSelector() {}
+
+  // Called once to register the work queues to be selected from. This function
+  // is called on the main thread.
+  virtual void RegisterWorkQueues(
+      const std::vector<const base::TaskQueue*>& work_queues) = 0;
+
+  // Called to choose the work queue from which the next task should be taken
+  // and run. Return true if |out_queue| indicates the queue to service or
+  // false to avoid running any task.
+  //
+  // This function is called on the main thread.
+  virtual bool SelectWorkQueueToService(size_t* out_queue_index) = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_SELECTOR_H_
diff --git a/content/renderer/service_worker/service_worker_cache_storage_dispatcher.cc b/content/renderer/service_worker/service_worker_cache_storage_dispatcher.cc
index b483b7d8..2f6e1b21 100644
--- a/content/renderer/service_worker/service_worker_cache_storage_dispatcher.cc
+++ b/content/renderer/service_worker/service_worker_cache_storage_dispatcher.cc
@@ -520,12 +520,13 @@
                             base::ASCIIToUTF16(i.second));
   }
 
-  web_response->setBlob(blink::WebString::fromUTF8(response.blob_uuid),
-                        response.blob_size);
-
-  // Let the host know that it can release its reference to the blob.
-  script_context_->Send(new ServiceWorkerHostMsg_BlobDataHandled(
-      script_context_->GetRoutingID(), response.blob_uuid));
+  if (!response.blob_uuid.empty()) {
+    web_response->setBlob(blink::WebString::fromUTF8(response.blob_uuid),
+                          response.blob_size);
+    // Let the host know that it can release its reference to the blob.
+    script_context_->Send(new ServiceWorkerHostMsg_BlobDataHandled(
+        script_context_->GetRoutingID(), response.blob_uuid));
+  }
 }
 
 blink::WebVector<blink::WebServiceWorkerResponse>
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
index fbfb707..a2b6639 100644
--- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc
+++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -40,8 +40,7 @@
       const blink::WebApplicationCacheHost*) {}
   virtual void didReceiveResponseForMainResource(const blink::WebURLResponse&) {
   }
-  // TODO(tyoshino): Revive didReceiveDataForMainResource once Blink side
-  // refactoring is done. See crbug.com/418885.
+  virtual void didReceiveDataForMainResource(const char* data, unsigned len) {}
   virtual void didFinishLoadingMainResource(bool success) {}
 
   // Cache selection is also different for workers. We know at construction
@@ -52,7 +51,8 @@
     return true;
   }
 };
-}
+
+}  // namespace
 
 EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
     const GURL& url,
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 3f81c75..75761e2b 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -67,6 +67,10 @@
     "browser/layout_test/layout_test_url_request_context_getter.h",
     "browser/notify_done_forwarder.cc",
     "browser/notify_done_forwarder.h",
+    "browser/shell.cc",
+    "browser/shell.h",
+    "browser/shell_access_token_store.cc",
+    "browser/shell_access_token_store.h",
     "browser/shell_android.cc",
     "browser/shell_application_mac.h",
     "browser/shell_application_mac.mm",
@@ -77,7 +81,6 @@
     "browser/shell_browser_main_parts.cc",
     "browser/shell_browser_main_parts.h",
     "browser/shell_browser_main_parts_mac.mm",
-    "browser/shell.cc",
     "browser/shell_content_browser_client.cc",
     "browser/shell_content_browser_client.h",
     "browser/shell_devtools_delegate.cc",
@@ -86,7 +89,6 @@
     "browser/shell_devtools_frontend.h",
     "browser/shell_download_manager_delegate.cc",
     "browser/shell_download_manager_delegate.h",
-    "browser/shell.h",
     "browser/shell_javascript_dialog.h",
     "browser/shell_javascript_dialog_mac.mm",
     "browser/shell_javascript_dialog_manager.cc",
@@ -134,8 +136,6 @@
     "common/test_runner/test_preferences.h",
     "common/webkit_test_helpers.cc",
     "common/webkit_test_helpers.h",
-    "geolocation/shell_access_token_store.cc",
-    "geolocation/shell_access_token_store.h",
     "renderer/ipc_echo.cc",
     "renderer/ipc_echo.h",
     "renderer/layout_test/gc_controller.cc",
diff --git a/content/shell/android/browsertests_apk/AndroidManifest.xml b/content/shell/android/browsertests_apk/AndroidManifest.xml
index 175ab14..3a7549d 100644
--- a/content/shell/android/browsertests_apk/AndroidManifest.xml
+++ b/content/shell/android/browsertests_apk/AndroidManifest.xml
@@ -131,7 +131,7 @@
                  android:exported="false" />
     </application>
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.CAMERA" />
diff --git a/content/shell/android/javatests/AndroidManifest.xml b/content/shell/android/javatests/AndroidManifest.xml
index ef310a1..fccf3f8 100644
--- a/content/shell/android/javatests/AndroidManifest.xml
+++ b/content/shell/android/javatests/AndroidManifest.xml
@@ -12,7 +12,7 @@
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.content_shell_apk"
         android:label="Tests for org.chromium.content_shell_apk"/>
diff --git a/content/shell/android/linker_test_apk/AndroidManifest.xml b/content/shell/android/linker_test_apk/AndroidManifest.xml
index d95d2068..741a5517 100644
--- a/content/shell/android/linker_test_apk/AndroidManifest.xml
+++ b/content/shell/android/linker_test_apk/AndroidManifest.xml
@@ -131,7 +131,7 @@
                  android:exported="false" />
     </application>
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.CAMERA" />
diff --git a/content/shell/android/shell_apk/AndroidManifest.xml b/content/shell/android/shell_apk/AndroidManifest.xml
index 53a23017..4df60274 100644
--- a/content/shell/android/shell_apk/AndroidManifest.xml
+++ b/content/shell/android/shell_apk/AndroidManifest.xml
@@ -134,7 +134,7 @@
                    android:value="org.chromium.content.browser.SmartClipProvider" />
     </application>
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.cc b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
index 5194da29..54d42af7 100644
--- a/content/shell/browser/layout_test/layout_test_content_browser_client.cc
+++ b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
@@ -35,6 +35,10 @@
 
 LayoutTestContentBrowserClient::LayoutTestContentBrowserClient() {
   DCHECK(!g_layout_test_browser_client);
+
+  layout_test_notification_manager_.reset(
+      new LayoutTestNotificationManager());
+
   g_layout_test_browser_client = this;
 }
 
@@ -48,12 +52,6 @@
 
 LayoutTestNotificationManager*
 LayoutTestContentBrowserClient::GetLayoutTestNotificationManager() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  if (!layout_test_notification_manager_) {
-    layout_test_notification_manager_.reset(
-        new LayoutTestNotificationManager());
-  }
-
   return layout_test_notification_manager_.get();
 }
 
@@ -97,4 +95,13 @@
   return blink::WebNotificationPermissionAllowed;
 }
 
+void LayoutTestContentBrowserClient::ShowDesktopNotification(
+    const ShowDesktopNotificationHostMsgParams& params,
+    RenderFrameHost* render_frame_host,
+    scoped_ptr<DesktopNotificationDelegate> delegate,
+    base::Closure* cancel_callback) {
+  if (auto* manager = GetLayoutTestNotificationManager())
+    manager->Show(params, delegate.Pass(), cancel_callback);
+}
+
 }  // namespace content
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.h b/content/shell/browser/layout_test/layout_test_content_browser_client.h
index f58032a0..3049c06a 100644
--- a/content/shell/browser/layout_test/layout_test_content_browser_client.h
+++ b/content/shell/browser/layout_test/layout_test_content_browser_client.h
@@ -33,6 +33,11 @@
       const GURL& source_url,
       ResourceContext* context,
       int render_process_id) override;
+  void ShowDesktopNotification(
+      const ShowDesktopNotificationHostMsgParams& params,
+      RenderFrameHost* render_frame_host,
+      scoped_ptr<DesktopNotificationDelegate> delegate,
+      base::Closure* cancel_callback) override;
 
  private:
   scoped_ptr<LayoutTestNotificationManager> layout_test_notification_manager_;
diff --git a/content/shell/browser/layout_test/layout_test_message_filter.cc b/content/shell/browser/layout_test/layout_test_message_filter.cc
index d0c3b0d..2b80628 100644
--- a/content/shell/browser/layout_test/layout_test_message_filter.cc
+++ b/content/shell/browser/layout_test/layout_test_message_filter.cc
@@ -42,6 +42,8 @@
     const IPC::Message& message, BrowserThread::ID* thread) {
   if (message.type() == ShellViewHostMsg_ClearAllDatabases::ID)
     *thread = BrowserThread::FILE;
+  if (message.type() == ShellViewHostMsg_SimulateWebNotificationClick::ID)
+    *thread = BrowserThread::UI;
 }
 
 bool LayoutTestMessageFilter::OnMessageReceived(const IPC::Message& message) {
@@ -58,6 +60,8 @@
                         OnGrantWebNotificationPermission)
     IPC_MESSAGE_HANDLER(ShellViewHostMsg_ClearWebNotificationPermissions,
                         OnClearWebNotificationPermissions)
+    IPC_MESSAGE_HANDLER(ShellViewHostMsg_SimulateWebNotificationClick,
+                        OnSimulateWebNotificationClick)
     IPC_MESSAGE_HANDLER(ShellViewHostMsg_AcceptAllCookies, OnAcceptAllCookies)
     IPC_MESSAGE_HANDLER(ShellViewHostMsg_DeleteAllCookies, OnDeleteAllCookies)
     IPC_MESSAGE_UNHANDLED(handled = false)
@@ -128,6 +132,14 @@
     manager->ClearPermissions();
 }
 
+void LayoutTestMessageFilter::OnSimulateWebNotificationClick(
+    const std::string& title) {
+  LayoutTestNotificationManager* manager =
+      LayoutTestContentBrowserClient::Get()->GetLayoutTestNotificationManager();
+  if (manager)
+    manager->SimulateClick(title);
+}
+
 void LayoutTestMessageFilter::OnAcceptAllCookies(bool accept) {
   ShellNetworkDelegate::SetAcceptAllCookies(accept);
 }
diff --git a/content/shell/browser/layout_test/layout_test_message_filter.h b/content/shell/browser/layout_test/layout_test_message_filter.h
index 044a4d2..5abfe066 100644
--- a/content/shell/browser/layout_test/layout_test_message_filter.h
+++ b/content/shell/browser/layout_test/layout_test_message_filter.h
@@ -54,6 +54,7 @@
   void OnGrantWebNotificationPermission(const GURL& origin,
                                         bool permission_granted);
   void OnClearWebNotificationPermissions();
+  void OnSimulateWebNotificationClick(const std::string& title);
   void OnAcceptAllCookies(bool accept);
   void OnDeleteAllCookies();
 
diff --git a/content/shell/browser/layout_test/layout_test_notification_manager.cc b/content/shell/browser/layout_test/layout_test_notification_manager.cc
index 99a6a23..b3f64b4 100644
--- a/content/shell/browser/layout_test/layout_test_notification_manager.cc
+++ b/content/shell/browser/layout_test/layout_test_notification_manager.cc
@@ -4,14 +4,21 @@
 
 #include "content/shell/browser/layout_test/layout_test_notification_manager.h"
 
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/desktop_notification_delegate.h"
+#include "content/public/common/show_desktop_notification_params.h"
+
 namespace content {
 
-LayoutTestNotificationManager::LayoutTestNotificationManager() {}
+LayoutTestNotificationManager::LayoutTestNotificationManager()
+    : weak_factory_(this) {}
 
 LayoutTestNotificationManager::~LayoutTestNotificationManager() {}
 
 blink::WebNotificationPermission
 LayoutTestNotificationManager::CheckPermission(const GURL& origin) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   NotificationPermissionMap::iterator iter =
       permission_map_.find(origin);
   if (iter == permission_map_.end())
@@ -23,17 +30,73 @@
 void LayoutTestNotificationManager::RequestPermission(
     const GURL& origin,
     const base::Callback<void(blink::WebNotificationPermission)>& callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   callback.Run(CheckPermission(origin));
 }
 
 void LayoutTestNotificationManager::SetPermission(
     const GURL& origin,
     blink::WebNotificationPermission permission) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   permission_map_[origin] = permission;
 }
 
 void LayoutTestNotificationManager::ClearPermissions() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   permission_map_.clear();
 }
 
+void LayoutTestNotificationManager::Show(
+    const ShowDesktopNotificationHostMsgParams& params,
+    scoped_ptr<DesktopNotificationDelegate> delegate,
+    base::Closure* cancel_callback) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  std::string title = base::UTF16ToUTF8(params.title);
+
+  DCHECK(cancel_callback);
+  *cancel_callback = base::Bind(&LayoutTestNotificationManager::Close,
+                                weak_factory_.GetWeakPtr(),
+                                title);
+
+  if (params.replace_id.length()) {
+    std::string replace_id = base::UTF16ToUTF8(params.replace_id);
+    auto replace_iter = replacements_.find(replace_id);
+    if (replace_iter != replacements_.end()) {
+      const std::string& previous_title = replace_iter->second;
+      auto notification_iter = notifications_.find(previous_title);
+      if (notification_iter != notifications_.end()) {
+        DesktopNotificationDelegate* previous_delegate =
+            notification_iter->second;
+        previous_delegate->NotificationClosed(false);
+
+        notifications_.erase(notification_iter);
+        delete previous_delegate;
+      }
+    }
+
+    replacements_[replace_id] = title;
+  }
+
+  notifications_[title] = delegate.release();
+  notifications_[title]->NotificationDisplayed();
+}
+
+void LayoutTestNotificationManager::SimulateClick(const std::string& title) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  auto iterator = notifications_.find(title);
+  if (iterator == notifications_.end())
+    return;
+
+  iterator->second->NotificationClick();
+}
+
+void LayoutTestNotificationManager::Close(const std::string& title) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  auto iterator = notifications_.find(title);
+  if (iterator == notifications_.end())
+    return;
+
+  iterator->second->NotificationClosed(false);
+}
+
 }  // namespace content
diff --git a/content/shell/browser/layout_test/layout_test_notification_manager.h b/content/shell/browser/layout_test/layout_test_notification_manager.h
index b97efa4..258f84a 100644
--- a/content/shell/browser/layout_test/layout_test_notification_manager.h
+++ b/content/shell/browser/layout_test/layout_test_notification_manager.h
@@ -6,42 +6,68 @@
 #define CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_NOTIFICATION_MANAGER_H_
 
 #include <map>
+#include <string>
 
 #include "base/callback.h"
+#include "base/memory/weak_ptr.h"
 #include "third_party/WebKit/public/platform/WebNotificationPermission.h"
 #include "url/gurl.h"
 
 namespace content {
 
+struct ShowDesktopNotificationHostMsgParams;
+class DesktopNotificationDelegate;
+
 // Responsible for tracking active notifications and allowed origins for the
-// Web Notification API when running layout tests. The methods in this class
-// should only be used on the IO thread.
+// Web Notification API when running layout tests.
 class LayoutTestNotificationManager {
  public:
   LayoutTestNotificationManager();
   ~LayoutTestNotificationManager();
 
   // Checks whether |origin| has permission to display notifications in tests.
+  // Must be called on the IO thread.
   blink::WebNotificationPermission CheckPermission(
       const GURL& origin);
 
   // Requests permission for |origin| to display notifications in layout tests.
+  // Must be called on the IO thread.
   void RequestPermission(
       const GURL& origin,
       const base::Callback<void(blink::WebNotificationPermission)>& callback);
 
   // Sets the permission to display notifications for |origin| to |permission|.
+  // Must be called on the IO thread.
   void SetPermission(const GURL& origin,
                      blink::WebNotificationPermission permission);
 
-  // Clears the currently granted permissions.
+  // Clears the currently granted permissions. Must be called on the IO thread.
   void ClearPermissions();
 
+  // Pretends to show the given notification for testing, storing a delegate so
+  // that interaction with the notification can be simulated later on. Must
+  // be called on the UI thread.
+  void Show(const ShowDesktopNotificationHostMsgParams& params,
+            scoped_ptr<DesktopNotificationDelegate> delegate,
+            base::Closure* cancel_callback);
+
+  // Simulates a click on the notification titled |title|. Must be called on the
+  // UI thread.
+  void SimulateClick(const std::string& title);
+
  private:
+  // Closes the notification titled |title|. Must be called on the UI thread.
+  void Close(const std::string& title);
+
   typedef std::map<GURL, blink::WebNotificationPermission>
       NotificationPermissionMap;
   NotificationPermissionMap permission_map_;
 
+  std::map<std::string, DesktopNotificationDelegate*> notifications_;
+  std::map<std::string, std::string> replacements_;
+
+  base::WeakPtrFactory<LayoutTestNotificationManager> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(LayoutTestNotificationManager);
 };
 
diff --git a/content/shell/geolocation/shell_access_token_store.cc b/content/shell/browser/shell_access_token_store.cc
similarity index 96%
rename from content/shell/geolocation/shell_access_token_store.cc
rename to content/shell/browser/shell_access_token_store.cc
index bdcf699..9f8136e 100644
--- a/content/shell/geolocation/shell_access_token_store.cc
+++ b/content/shell/browser/shell_access_token_store.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/shell/geolocation/shell_access_token_store.h"
+#include "content/shell/browser/shell_access_token_store.h"
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
diff --git a/content/shell/geolocation/shell_access_token_store.h b/content/shell/browser/shell_access_token_store.h
similarity index 86%
rename from content/shell/geolocation/shell_access_token_store.h
rename to content/shell/browser/shell_access_token_store.h
index df46146..d218845 100644
--- a/content/shell/geolocation/shell_access_token_store.h
+++ b/content/shell/browser/shell_access_token_store.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_
-#define CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_
+#ifndef CONTENT_SHELL_BROWSER_SHELL_ACCESS_TOKEN_STORE_H_
+#define CONTENT_SHELL_BROWSER_SHELL_ACCESS_TOKEN_STORE_H_
 
 #include "base/memory/ref_counted.h"
 #include "content/public/browser/access_token_store.h"
@@ -39,4 +39,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_SHELL_GEOLOCATION_SHELL_ACCESS_TOKEN_STORE_H_
+#endif  // CONTENT_SHELL_BROWSER_SHELL_ACCESS_TOKEN_STORE_H_
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 3f0a98be..711db5a 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -20,6 +20,7 @@
 #include "content/shell/browser/layout_test/layout_test_browser_main_parts.h"
 #include "content/shell/browser/layout_test/layout_test_resource_dispatcher_host_delegate.h"
 #include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_access_token_store.h"
 #include "content/shell/browser/shell_browser_context.h"
 #include "content/shell/browser/shell_browser_main_parts.h"
 #include "content/shell/browser/shell_devtools_delegate.h"
@@ -31,7 +32,6 @@
 #include "content/shell/common/shell_messages.h"
 #include "content/shell/common/shell_switches.h"
 #include "content/shell/common/webkit_test_helpers.h"
-#include "content/shell/geolocation/shell_access_token_store.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "url/gurl.h"
 
diff --git a/content/shell/browser/shell_network_delegate.cc b/content/shell/browser/shell_network_delegate.cc
index 5ed9634..633fb46 100644
--- a/content/shell/browser/shell_network_delegate.cc
+++ b/content/shell/browser/shell_network_delegate.cc
@@ -114,10 +114,4 @@
   return false;
 }
 
-int ShellNetworkDelegate::OnBeforeSocketStreamConnect(
-    net::SocketStream* socket,
-    const net::CompletionCallback& callback) {
-  return net::OK;
-}
-
 }  // namespace content
diff --git a/content/shell/browser/shell_network_delegate.h b/content/shell/browser/shell_network_delegate.h
index fbd4485..df0608e 100644
--- a/content/shell/browser/shell_network_delegate.h
+++ b/content/shell/browser/shell_network_delegate.h
@@ -54,9 +54,6 @@
   bool OnCanAccessFile(const net::URLRequest& request,
                        const base::FilePath& path) const override;
   bool OnCanThrottleRequest(const net::URLRequest& request) const override;
-  int OnBeforeSocketStreamConnect(
-      net::SocketStream* stream,
-      const net::CompletionCallback& callback) override;
 
   DISALLOW_COPY_AND_ASSIGN(ShellNetworkDelegate);
 };
diff --git a/content/shell/common/shell_messages.h b/content/shell/common/shell_messages.h
index dd602c1..cc6e2b2 100644
--- a/content/shell/common/shell_messages.h
+++ b/content/shell/common/shell_messages.h
@@ -105,6 +105,8 @@
                     GURL /* origin */,
                     bool /* permission_granted */)
 IPC_MESSAGE_ROUTED0(ShellViewHostMsg_ClearWebNotificationPermissions)
+IPC_MESSAGE_ROUTED1(ShellViewHostMsg_SimulateWebNotificationClick,
+                    std::string /* title */)
 IPC_MESSAGE_ROUTED1(ShellViewHostMsg_AcceptAllCookies,
                     bool /* accept */)
 IPC_MESSAGE_ROUTED0(ShellViewHostMsg_DeleteAllCookies)
diff --git a/content/shell/renderer/layout_test/webkit_test_runner.cc b/content/shell/renderer/layout_test/webkit_test_runner.cc
index 9059d814..80fa28a 100644
--- a/content/shell/renderer/layout_test/webkit_test_runner.cc
+++ b/content/shell/renderer/layout_test/webkit_test_runner.cc
@@ -431,6 +431,10 @@
   Send(new ShellViewHostMsg_ClearWebNotificationPermissions(routing_id()));
 }
 
+void WebKitTestRunner::SimulateWebNotificationClick(const std::string& title) {
+  Send(new ShellViewHostMsg_SimulateWebNotificationClick(routing_id(), title));
+}
+
 void WebKitTestRunner::SetDeviceScaleFactor(float factor) {
   content::SetDeviceScaleFactor(render_view(), factor);
 }
diff --git a/content/shell/renderer/layout_test/webkit_test_runner.h b/content/shell/renderer/layout_test/webkit_test_runner.h
index 4bba3db5..96f189b 100644
--- a/content/shell/renderer/layout_test/webkit_test_runner.h
+++ b/content/shell/renderer/layout_test/webkit_test_runner.h
@@ -93,6 +93,7 @@
   void GrantWebNotificationPermission(const GURL& origin,
                                       bool permission_granted) override;
   void ClearWebNotificationPermissions() override;
+  void SimulateWebNotificationClick(const std::string& title) override;
   void SetDeviceScaleFactor(float factor) override;
   void SetDeviceColorProfile(const std::string& name) override;
   void SetFocus(WebTestProxyBase* proxy, bool focus) override;
diff --git a/content/shell/renderer/test_runner/test_runner.cc b/content/shell/renderer/test_runner/test_runner.cc
index a477f401..75e91f3 100644
--- a/content/shell/renderer/test_runner/test_runner.cc
+++ b/content/shell/renderer/test_runner/test_runner.cc
@@ -273,7 +273,7 @@
   void SetMIDISysexPermission(bool value);
   void GrantWebNotificationPermission(gin::Arguments* args);
   void ClearWebNotificationPermissions();
-  bool SimulateWebNotificationClick(const std::string& value);
+  void SimulateWebNotificationClick(const std::string& title);
   void AddMockSpeechRecognitionResult(const std::string& transcript,
                                       double confidence);
   void SetMockSpeechRecognitionError(const std::string& error,
@@ -1307,11 +1307,10 @@
     runner_->ClearWebNotificationPermissions();
 }
 
-bool TestRunnerBindings::SimulateWebNotificationClick(
-    const std::string& value) {
+void TestRunnerBindings::SimulateWebNotificationClick(
+    const std::string& title) {
   if (runner_)
-    return runner_->SimulateWebNotificationClick(value);
-  return false;
+    runner_->SimulateWebNotificationClick(title);
 }
 
 void TestRunnerBindings::AddMockSpeechRecognitionResult(
@@ -2753,8 +2752,12 @@
   delegate_->ClearWebNotificationPermissions();
 }
 
-bool TestRunner::SimulateWebNotificationClick(const std::string& value) {
-  return notification_presenter_->SimulateClick(value);
+void TestRunner::SimulateWebNotificationClick(const std::string& title) {
+  delegate_->SimulateWebNotificationClick(title);
+
+  // TODO(peter): Remove this call once Web Notifications switch away from the
+  // WebFrame-based code path.
+  notification_presenter_->SimulateClick(title);
 }
 
 void TestRunner::AddMockSpeechRecognitionResult(const std::string& transcript,
diff --git a/content/shell/renderer/test_runner/test_runner.h b/content/shell/renderer/test_runner/test_runner.h
index 3abed945..9b3737f3 100644
--- a/content/shell/renderer/test_runner/test_runner.h
+++ b/content/shell/renderer/test_runner/test_runner.h
@@ -526,7 +526,7 @@
   void ClearWebNotificationPermissions();
 
   // Simulates a click on a desktop notification.
-  bool SimulateWebNotificationClick(const std::string& value);
+  void SimulateWebNotificationClick(const std::string& title);
 
   // Speech recognition related functions.
   void AddMockSpeechRecognitionResult(const std::string& transcript,
diff --git a/content/shell/renderer/test_runner/web_test_delegate.h b/content/shell/renderer/test_runner/web_test_delegate.h
index 35b8154..459a1408 100644
--- a/content/shell/renderer/test_runner/web_test_delegate.h
+++ b/content/shell/renderer/test_runner/web_test_delegate.h
@@ -141,6 +141,7 @@
   virtual void GrantWebNotificationPermission(const GURL& origin,
                                               bool permission_granted) = 0;
   virtual void ClearWebNotificationPermissions() = 0;
+  virtual void SimulateWebNotificationClick(const std::string& title) = 0;
 
   // Controls the device scale factor of the main WebView for hidpi tests.
   virtual void SetDeviceScaleFactor(float factor) = 0;
diff --git a/content/test/browser_test_utils_browsertest.cc b/content/test/browser_test_utils_browsertest.cc
index b8131fe..d2b691e2 100644
--- a/content/test/browser_test_utils_browsertest.cc
+++ b/content/test/browser_test_utils_browsertest.cc
@@ -57,7 +57,6 @@
   host_resolver()->AddRule("*", "127.0.0.1");
   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
   SetupCrossSiteRedirector(embedded_test_server());
-  embedded_test_server()->ServeFilesFromDirectory(GetTestFilePath("files", ""));
 
   // Navigate to http://localhost:<port>/cross-site/foo.com/title2.html and
   // ensure that the redirector forwards the navigation to
diff --git a/content/test/data/accessibility/aria-checked-expected-android.txt b/content/test/data/accessibility/aria-checked-expected-android.txt
new file mode 100644
index 0000000..c7bd54ea
--- /dev/null
+++ b/content/test/data/accessibility/aria-checked-expected-android.txt
@@ -0,0 +1,5 @@
+android.webkit.WebView focusable focused scrollable
+    android.widget.CheckBox checkable checked focusable
+    android.widget.CheckBox checkable focusable
+    android.widget.CheckBox checkable focusable
+
diff --git a/content/test/data/accessibility/aria-checked-expected-mac.txt b/content/test/data/accessibility/aria-checked-expected-mac.txt
new file mode 100644
index 0000000..72e47ad
--- /dev/null
+++ b/content/test/data/accessibility/aria-checked-expected-mac.txt
@@ -0,0 +1,5 @@
+AXWebArea AXRoleDescription='HTML content'
+    AXCheckBox AXRoleDescription='check box' AXValue='1'
+    AXCheckBox AXRoleDescription='check box' AXValue='0'
+    AXCheckBox AXRoleDescription='check box' AXValue='2'
+
diff --git a/content/test/data/accessibility/aria-checked-expected-win.txt b/content/test/data/accessibility/aria-checked-expected-win.txt
new file mode 100644
index 0000000..d336a60
--- /dev/null
+++ b/content/test/data/accessibility/aria-checked-expected-win.txt
@@ -0,0 +1,5 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    ROLE_SYSTEM_CHECKBUTTON CHECKED FOCUSABLE
+    ROLE_SYSTEM_CHECKBUTTON FOCUSABLE
+    ROLE_SYSTEM_CHECKBUTTON MIXED FOCUSABLE
+
diff --git a/content/test/data/accessibility/aria-checked.html b/content/test/data/accessibility/aria-checked.html
new file mode 100644
index 0000000..3a8fe3f
--- /dev/null
+++ b/content/test/data/accessibility/aria-checked.html
@@ -0,0 +1,13 @@
+<!--
+@MAC-ALLOW:AXRole*
+@WIN-ALLOW:CHECKED*
+@WIN-ALLOW:MIXED*
+-->
+<html>
+<body>
+  <div role="checkbox" tabindex=0 aria-checked="true"></div>
+  <div role="checkbox" tabindex=1 aria-checked="false"></div>
+  <div role="checkbox" tabindex=2 aria-checked="mixed"></div>
+</body>
+</html>
+
diff --git a/content/test/data/accessibility/aria-definition-expected-android.txt b/content/test/data/accessibility/aria-definition-expected-android.txt
new file mode 100644
index 0000000..189ebe9
--- /dev/null
+++ b/content/test/data/accessibility/aria-definition-expected-android.txt
@@ -0,0 +1,3 @@
+android.webkit.WebView focusable focused scrollable
+    android.view.View
+
diff --git a/content/test/data/accessibility/aria-definition-expected-mac.txt b/content/test/data/accessibility/aria-definition-expected-mac.txt
new file mode 100644
index 0000000..1cedee8
--- /dev/null
+++ b/content/test/data/accessibility/aria-definition-expected-mac.txt
@@ -0,0 +1,2 @@
+AXWebArea AXRoleDescription='HTML content'
+    AXGroup AXSubrole=AXDefinition AXRoleDescription='definition'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-definition-expected-win.txt b/content/test/data/accessibility/aria-definition-expected-win.txt
new file mode 100644
index 0000000..e91d91e2
--- /dev/null
+++ b/content/test/data/accessibility/aria-definition-expected-win.txt
@@ -0,0 +1,2 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    IA2_ROLE_PARAGRAPH READONLY xml-roles:definition
diff --git a/content/test/data/accessibility/aria-definition.html b/content/test/data/accessibility/aria-definition.html
new file mode 100644
index 0000000..be2f56f
--- /dev/null
+++ b/content/test/data/accessibility/aria-definition.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<!--
+@MAC-ALLOW:AXRole*
+@MAC-ALLOW:AXSubrole*
+@WIN-ALLOW:xml-roles:*
+-->
+<html>
+<body>
+<div role="definition"></div>
+</body>
+</html>
diff --git a/content/test/data/accessibility/aria-flowto-expected-mac.txt b/content/test/data/accessibility/aria-flowto-expected-mac.txt
index 1ab9ab256..98ac3870 100644
--- a/content/test/data/accessibility/aria-flowto-expected-mac.txt
+++ b/content/test/data/accessibility/aria-flowto-expected-mac.txt
@@ -1,5 +1,5 @@
 AXWebArea AXRoleDescription='HTML content'
-    AXGroup AXRoleDescription='group' AXLinkedUIElements=["AXGroup footer"]
+    AXGroup AXRoleDescription='region' AXLinkedUIElements=["AXGroup footer"]
         AXStaticText AXRoleDescription='text' AXValue='Lorem ipsum'
     AXGroup AXRoleDescription='footer'
         AXStaticText AXRoleDescription='text' AXValue='dolor sit amet'
diff --git a/content/test/data/accessibility/aria-listbox-expected-android.txt b/content/test/data/accessibility/aria-listbox-expected-android.txt
new file mode 100644
index 0000000..1334fee
--- /dev/null
+++ b/content/test/data/accessibility/aria-listbox-expected-android.txt
@@ -0,0 +1,4 @@
+android.webkit.WebView focusable focused scrollable
+    android.widget.ListView collection item_count=2 row_count=2
+        android.view.View clickable collection_item focusable name='Item 1'
+        android.view.View clickable collection_item focusable name='Item 2' item_index=1 row_index=1
diff --git a/content/test/data/accessibility/aria-listbox-expected-mac.txt b/content/test/data/accessibility/aria-listbox-expected-mac.txt
new file mode 100644
index 0000000..9e04ac8
--- /dev/null
+++ b/content/test/data/accessibility/aria-listbox-expected-mac.txt
@@ -0,0 +1,4 @@
+AXWebArea AXRoleDescription='HTML content'
+    AXList AXRoleDescription='list'
+        AXStaticText AXRoleDescription='text' AXTitle='Item 1'
+        AXStaticText AXRoleDescription='text' AXTitle='Item 2'
diff --git a/content/test/data/accessibility/aria-listbox-expected-win.txt b/content/test/data/accessibility/aria-listbox-expected-win.txt
new file mode 100644
index 0000000..a0bd220
--- /dev/null
+++ b/content/test/data/accessibility/aria-listbox-expected-win.txt
@@ -0,0 +1,4 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    ROLE_SYSTEM_LIST xml-roles:listbox
+        ROLE_SYSTEM_LISTITEM name='Item 1' FOCUSABLE xml-roles:option
+        ROLE_SYSTEM_LISTITEM name='Item 2' FOCUSABLE xml-roles:option
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-listbox.html b/content/test/data/accessibility/aria-listbox.html
new file mode 100644
index 0000000..ad073aa
--- /dev/null
+++ b/content/test/data/accessibility/aria-listbox.html
@@ -0,0 +1,12 @@
+<!--
+@MAC-ALLOW:AXRole*
+@WIN-ALLOW:xml-roles*
+-->
+<html>
+<body>
+<div role="listbox">
+  <div tabIndex="0" role="option">Item 1</div>
+  <div tabIndex="1" role="option">Item 2</div>
+</div>
+</body>
+</html>
diff --git a/content/test/data/accessibility/aria-menubar-expected-android.txt b/content/test/data/accessibility/aria-menubar-expected-android.txt
new file mode 100644
index 0000000..3a3ba6a
--- /dev/null
+++ b/content/test/data/accessibility/aria-menubar-expected-android.txt
@@ -0,0 +1,6 @@
+android.webkit.WebView focusable focused scrollable
+    android.view.View
+        android.view.MenuItem clickable name='File'
+        android.view.MenuItem clickable name='Edit'
+        android.view.MenuItem clickable name='View'
+
diff --git a/content/test/data/accessibility/aria-menubar-expected-mac.txt b/content/test/data/accessibility/aria-menubar-expected-mac.txt
new file mode 100644
index 0000000..97ee3c1
--- /dev/null
+++ b/content/test/data/accessibility/aria-menubar-expected-mac.txt
@@ -0,0 +1,6 @@
+AXWebArea
+    AXMenuBar
+        AXMenuItem AXTitle='File'
+        AXMenuItem AXTitle='Edit'
+        AXMenuItem AXTitle='View'
+
diff --git a/content/test/data/accessibility/aria-menubar-expected-win.txt b/content/test/data/accessibility/aria-menubar-expected-win.txt
new file mode 100644
index 0000000..2e2021e
--- /dev/null
+++ b/content/test/data/accessibility/aria-menubar-expected-win.txt
@@ -0,0 +1,6 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    ROLE_SYSTEM_MENUBAR
+        ROLE_SYSTEM_MENUITEM name='File'
+        ROLE_SYSTEM_MENUITEM name='Edit'
+        ROLE_SYSTEM_MENUITEM name='View'
+
diff --git a/content/test/data/accessibility/aria-menubar.html b/content/test/data/accessibility/aria-menubar.html
new file mode 100644
index 0000000..0302f822
--- /dev/null
+++ b/content/test/data/accessibility/aria-menubar.html
@@ -0,0 +1,15 @@
+<!--
+@MAC-DENY:AXValue*
+@MAC-ALLOW:AXLinkedUIElements*
+@WIN-DENY:description=''
+-->
+<html>
+  <body>
+    <ul role="menubar" style="list-style-type: none">
+      <li role="menuitem" aria-controls="filemenu">File</span>
+      <li role="menuitem">Edit</span>
+      <li role="menuitem">View</span>
+    </ul>
+  </body>
+</html>
+
diff --git a/content/test/data/accessibility/region-expected-android.txt b/content/test/data/accessibility/aria-region-expected-android.txt
similarity index 63%
copy from content/test/data/accessibility/region-expected-android.txt
copy to content/test/data/accessibility/aria-region-expected-android.txt
index 2d5b1a0a..0aa6027 100644
--- a/content/test/data/accessibility/region-expected-android.txt
+++ b/content/test/data/accessibility/aria-region-expected-android.txt
@@ -1,3 +1,2 @@
 android.webkit.WebView focusable focused scrollable
-    android.view.View clickable name='This is a section element.'
     android.view.View clickable name='This is an ARIA region.'
diff --git a/content/test/data/accessibility/aria-region-expected-mac.txt b/content/test/data/accessibility/aria-region-expected-mac.txt
new file mode 100644
index 0000000..536f106
--- /dev/null
+++ b/content/test/data/accessibility/aria-region-expected-mac.txt
@@ -0,0 +1,3 @@
+AXWebArea AXRoleDescription='HTML content'
+    AXGroup AXSubrole=AXDocumentRegion AXRoleDescription='region'
+        AXStaticText AXRoleDescription='text' AXValue='This is an ARIA region.'
diff --git a/content/test/data/accessibility/aria-region-expected-win.txt b/content/test/data/accessibility/aria-region-expected-win.txt
new file mode 100644
index 0000000..6d3dbdc2
--- /dev/null
+++ b/content/test/data/accessibility/aria-region-expected-win.txt
@@ -0,0 +1,3 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    ROLE_SYSTEM_PANE xml-roles:region
+        ROLE_SYSTEM_STATICTEXT name='This is an ARIA region.'
diff --git a/content/test/data/accessibility/aria-region.html b/content/test/data/accessibility/aria-region.html
new file mode 100644
index 0000000..b374203
--- /dev/null
+++ b/content/test/data/accessibility/aria-region.html
@@ -0,0 +1,15 @@
+<!--
+@MAC-ALLOW:AXRole*
+@MAC-ALLOW:AXSubrole*
+@WIN-ALLOW:xml-roles:*
+-->
+<!DOCTYPE html>
+<html>
+<body>
+
+  <div role="region">
+    This is an ARIA region.
+  </div>
+
+</body>
+</html>
diff --git a/content/test/data/accessibility/aria-required-expected-android.txt b/content/test/data/accessibility/aria-required-expected-android.txt
new file mode 100644
index 0000000..bc06bf82
--- /dev/null
+++ b/content/test/data/accessibility/aria-required-expected-android.txt
@@ -0,0 +1,3 @@
+android.webkit.WebView focusable focused scrollable
+    android.widget.RadioButton checkable
+    android.widget.RadioButton checkable
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-required-expected-mac.txt b/content/test/data/accessibility/aria-required-expected-mac.txt
new file mode 100644
index 0000000..4df9f3a
--- /dev/null
+++ b/content/test/data/accessibility/aria-required-expected-mac.txt
@@ -0,0 +1,3 @@
+AXWebArea AXRequired='0'
+    AXRadioButton AXValue='0' AXRequired='1'
+    AXRadioButton AXValue='0' AXRequired='0'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-required-expected-win.txt b/content/test/data/accessibility/aria-required-expected-win.txt
new file mode 100644
index 0000000..eacb715
--- /dev/null
+++ b/content/test/data/accessibility/aria-required-expected-win.txt
@@ -0,0 +1,3 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    ROLE_SYSTEM_RADIOBUTTON IA2_STATE_REQUIRED
+    ROLE_SYSTEM_RADIOBUTTON
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-required.html b/content/test/data/accessibility/aria-required.html
new file mode 100644
index 0000000..3dc7f72
--- /dev/null
+++ b/content/test/data/accessibility/aria-required.html
@@ -0,0 +1,11 @@
+<!--
+@MAC-ALLOW:AXRequired*
+@WIN-ALLOW:IA2_STATE_REQUIRED
+-->
+<!DOCTYPE html>
+<html>
+<body>
+  <div role="radio" aria-required="true"></div>
+  <div role="radio" aria-required="false"></div>
+</body>
+</html>
diff --git a/content/test/data/accessibility/aria-separator-expected-android.txt b/content/test/data/accessibility/aria-separator-expected-android.txt
new file mode 100644
index 0000000..1cbd9ce0
--- /dev/null
+++ b/content/test/data/accessibility/aria-separator-expected-android.txt
@@ -0,0 +1,4 @@
+android.webkit.WebView focusable focused scrollable
+    android.view.View clickable name='Before'
+    android.view.View clickable name='This is ARIA separator.'
+    android.view.View clickable name='After'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-separator-expected-mac.txt b/content/test/data/accessibility/aria-separator-expected-mac.txt
new file mode 100644
index 0000000..0f1b9f1
--- /dev/null
+++ b/content/test/data/accessibility/aria-separator-expected-mac.txt
@@ -0,0 +1,7 @@
+AXWebArea AXRoleDescription='HTML content'
+    AXGroup AXRoleDescription='group'
+        AXStaticText AXRoleDescription='text' AXValue='Before'
+    AXSplitter AXRoleDescription='splitter'
+        AXStaticText AXRoleDescription='text' AXValue='This is ARIA separator.'
+    AXGroup AXRoleDescription='group'
+        AXStaticText AXRoleDescription='text' AXValue='After'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-separator-expected-win.txt b/content/test/data/accessibility/aria-separator-expected-win.txt
new file mode 100644
index 0000000..223abbad
--- /dev/null
+++ b/content/test/data/accessibility/aria-separator-expected-win.txt
@@ -0,0 +1,7 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    IA2_ROLE_SECTION READONLY
+        ROLE_SYSTEM_STATICTEXT name='Before'
+    ROLE_SYSTEM_SEPARATOR xml-roles:separator
+        ROLE_SYSTEM_STATICTEXT name='This is ARIA separator.'
+    IA2_ROLE_SECTION READONLY
+        ROLE_SYSTEM_STATICTEXT name='After'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-separator.html b/content/test/data/accessibility/aria-separator.html
new file mode 100644
index 0000000..3ba0eafa
--- /dev/null
+++ b/content/test/data/accessibility/aria-separator.html
@@ -0,0 +1,12 @@
+<!--
+@MAC-ALLOW:AXRole*
+@WIN-ALLOW:xml-roles:*
+-->
+<!DOCTYPE html>
+<html>
+<body>
+Before
+<div role="separator">This is ARIA separator.</div>
+After
+</body>
+</html>
diff --git a/content/test/data/accessibility/aria-tree-expected-android.txt b/content/test/data/accessibility/aria-tree-expected-android.txt
new file mode 100644
index 0000000..42e3fa0
--- /dev/null
+++ b/content/test/data/accessibility/aria-tree-expected-android.txt
@@ -0,0 +1,3 @@
+android.webkit.WebView focusable focused scrollable
+    android.view.View collection hierarchical
+
diff --git a/content/test/data/accessibility/aria-tree-expected-mac.txt b/content/test/data/accessibility/aria-tree-expected-mac.txt
new file mode 100644
index 0000000..0f71904d
--- /dev/null
+++ b/content/test/data/accessibility/aria-tree-expected-mac.txt
@@ -0,0 +1,2 @@
+AXWebArea AXRoleDescription='HTML content'
+    AXOutline AXRoleDescription='outline'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria-tree-expected-win.txt b/content/test/data/accessibility/aria-tree-expected-win.txt
new file mode 100644
index 0000000..fcd7187b
--- /dev/null
+++ b/content/test/data/accessibility/aria-tree-expected-win.txt
@@ -0,0 +1,2 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    ROLE_SYSTEM_OUTLINE READONLY xml-roles:tree
diff --git a/content/test/data/accessibility/aria-tree.html b/content/test/data/accessibility/aria-tree.html
new file mode 100644
index 0000000..cd745bd
--- /dev/null
+++ b/content/test/data/accessibility/aria-tree.html
@@ -0,0 +1,11 @@
+<!--
+@MAC-ALLOW:AXRole*
+@WIN-ALLOW:xml-roles:*
+-->
+<html>
+<body>
+  <div role="tree">
+  </div>
+</table> 
+</body>
+</html>
diff --git a/content/test/data/accessibility/head-expected-android.txt b/content/test/data/accessibility/head-expected-android.txt
new file mode 100644
index 0000000..dfa2315
--- /dev/null
+++ b/content/test/data/accessibility/head-expected-android.txt
@@ -0,0 +1 @@
+android.webkit.WebView focusable focused scrollable
\ No newline at end of file
diff --git a/content/test/data/accessibility/head-expected-mac.txt b/content/test/data/accessibility/head-expected-mac.txt
new file mode 100644
index 0000000..84c6683
--- /dev/null
+++ b/content/test/data/accessibility/head-expected-mac.txt
@@ -0,0 +1 @@
+AXWebArea
\ No newline at end of file
diff --git a/content/test/data/accessibility/head-expected-win.txt b/content/test/data/accessibility/head-expected-win.txt
new file mode 100644
index 0000000..20958109
--- /dev/null
+++ b/content/test/data/accessibility/head-expected-win.txt
@@ -0,0 +1 @@
+#<skip -- not mapped>
\ No newline at end of file
diff --git a/content/test/data/accessibility/head.html b/content/test/data/accessibility/head.html
new file mode 100644
index 0000000..2655f4e
--- /dev/null
+++ b/content/test/data/accessibility/head.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+</body>
+</html>
diff --git a/content/test/data/accessibility/input-date.html b/content/test/data/accessibility/input-date.html
index b6181ce..7bf6e0d 100644
--- a/content/test/data/accessibility/input-date.html
+++ b/content/test/data/accessibility/input-date.html
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html>
 <body>
 
diff --git a/content/test/data/accessibility/input-submit-expected-android.txt b/content/test/data/accessibility/input-submit-expected-android.txt
new file mode 100644
index 0000000..64c01bd9
--- /dev/null
+++ b/content/test/data/accessibility/input-submit-expected-android.txt
@@ -0,0 +1,4 @@
+android.webkit.WebView focusable focused scrollable
+    android.view.View
+        android.widget.EditText editable_text focusable input_type=1
+        android.widget.Button clickable focusable name='Submit'
\ No newline at end of file
diff --git a/content/test/data/accessibility/input-submit-expected-mac.txt b/content/test/data/accessibility/input-submit-expected-mac.txt
new file mode 100644
index 0000000..8c5b236
--- /dev/null
+++ b/content/test/data/accessibility/input-submit-expected-mac.txt
@@ -0,0 +1,4 @@
+AXWebArea AXRoleDescription='HTML content'
+    AXGroup AXRoleDescription='group'
+        AXTextField AXRoleDescription='text field'
+        AXButton AXRoleDescription='button' AXTitle='Submit'
\ No newline at end of file
diff --git a/content/test/data/accessibility/input-submit-expected-win.txt b/content/test/data/accessibility/input-submit-expected-win.txt
new file mode 100644
index 0000000..1668194
--- /dev/null
+++ b/content/test/data/accessibility/input-submit-expected-win.txt
@@ -0,0 +1,4 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    IA2_ROLE_FORM
+        ROLE_SYSTEM_TEXT FOCUSABLE
+        ROLE_SYSTEM_PUSHBUTTON name='Submit' FOCUSABLE
diff --git a/content/test/data/accessibility/input-submit.html b/content/test/data/accessibility/input-submit.html
new file mode 100644
index 0000000..c9189348
--- /dev/null
+++ b/content/test/data/accessibility/input-submit.html
@@ -0,0 +1,15 @@
+<!--
+@MAC-ALLOW:AXRole*
+-->
+<!DOCTYPE html>
+<html>
+<body>
+
+<form>
+  <input type="text" name="Name"><br>
+  <input type="submit" value="Submit">
+</form>
+
+</body>
+</html>
+
diff --git a/content/test/data/accessibility/input-tel-expected-android.txt b/content/test/data/accessibility/input-tel-expected-android.txt
new file mode 100644
index 0000000..51ab1251
--- /dev/null
+++ b/content/test/data/accessibility/input-tel-expected-android.txt
@@ -0,0 +1,3 @@
+android.webkit.WebView focusable focused scrollable
+    android.view.View
+        android.widget.EditText editable_text focusable input_type=3
\ No newline at end of file
diff --git a/content/test/data/accessibility/input-tel-expected-mac.txt b/content/test/data/accessibility/input-tel-expected-mac.txt
new file mode 100644
index 0000000..e1e511b
--- /dev/null
+++ b/content/test/data/accessibility/input-tel-expected-mac.txt
@@ -0,0 +1,3 @@
+AXWebArea
+    AXGroup
+        AXTextField
diff --git a/content/test/data/accessibility/input-tel-expected-win.txt b/content/test/data/accessibility/input-tel-expected-win.txt
new file mode 100644
index 0000000..6d9763d
--- /dev/null
+++ b/content/test/data/accessibility/input-tel-expected-win.txt
@@ -0,0 +1,3 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    IA2_ROLE_SECTION READONLY
+        ROLE_SYSTEM_TEXT FOCUSABLE text-input-type:tel
\ No newline at end of file
diff --git a/content/test/data/accessibility/input-tel.html b/content/test/data/accessibility/input-tel.html
new file mode 100644
index 0000000..1112139
--- /dev/null
+++ b/content/test/data/accessibility/input-tel.html
@@ -0,0 +1,9 @@
+<!--
+@WIN-ALLOW:text-input-type*
+-->
+<!DOCTYPE html>
+<html>
+<body>
+  <input type="tel">
+</body>
+</html>
diff --git a/content/test/data/accessibility/input-text-name-calc-expected-android.txt b/content/test/data/accessibility/input-text-name-calc-expected-android.txt
index 84cb5f7e..5dff5f1a 100644
--- a/content/test/data/accessibility/input-text-name-calc-expected-android.txt
+++ b/content/test/data/accessibility/input-text-name-calc-expected-android.txt
@@ -4,6 +4,6 @@
         android.widget.EditText clickable editable_text focusable name='Title1' input_type=1
         android.widget.EditText clickable editable_text focusable name='AriaLabel2' input_type=1
         android.widget.EditText clickable editable_text focusable name='LabelledBy3' input_type=1
-        android.widget.EditText editable_text focusable input_type=1
+        android.widget.EditText clickable editable_text focusable name='Placeholder4' input_type=1
         android.widget.EditText clickable editable_text focusable name='Title5' input_type=1
         android.widget.EditText clickable editable_text focusable name='LabelledBy6' input_type=1
diff --git a/content/test/data/accessibility/modal-dialog-closed-expected-win.txt b/content/test/data/accessibility/modal-dialog-closed-expected-win.txt
index c172cd1..b215ffdc 100644
--- a/content/test/data/accessibility/modal-dialog-closed-expected-win.txt
+++ b/content/test/data/accessibility/modal-dialog-closed-expected-win.txt
@@ -1,7 +1,7 @@
 ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
     IA2_ROLE_SECTION READONLY
         ROLE_SYSTEM_STATICTEXT name='Test that elements respawn in the accessibility tree after a modal dialog closes.'
-    IA2_ROLE_SECTION READONLY
+    IA2_ROLE_SECTION
         ROLE_SYSTEM_COMBOBOX FOCUSABLE
             ROLE_SYSTEM_CLIENT
                 ROLE_SYSTEM_LISTITEM FOCUSABLE
diff --git a/content/test/data/accessibility/noscript-expected-android.txt b/content/test/data/accessibility/noscript-expected-android.txt
new file mode 100644
index 0000000..5a84c1a2
--- /dev/null
+++ b/content/test/data/accessibility/noscript-expected-android.txt
@@ -0,0 +1 @@
+#<skip -- Not mapped>
\ No newline at end of file
diff --git a/content/test/data/accessibility/noscript-expected-mac.txt b/content/test/data/accessibility/noscript-expected-mac.txt
new file mode 100644
index 0000000..5a84c1a2
--- /dev/null
+++ b/content/test/data/accessibility/noscript-expected-mac.txt
@@ -0,0 +1 @@
+#<skip -- Not mapped>
\ No newline at end of file
diff --git a/content/test/data/accessibility/noscript-expected-win.txt b/content/test/data/accessibility/noscript-expected-win.txt
new file mode 100644
index 0000000..5a84c1a2
--- /dev/null
+++ b/content/test/data/accessibility/noscript-expected-win.txt
@@ -0,0 +1 @@
+#<skip -- Not mapped>
\ No newline at end of file
diff --git a/content/test/data/accessibility/noscript.html b/content/test/data/accessibility/noscript.html
new file mode 100644
index 0000000..c462835
--- /dev/null
+++ b/content/test/data/accessibility/noscript.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <noscript>Test to check noscript tag.</noscript>
+</body>
+</html>
diff --git a/content/test/data/accessibility/region-expected-mac.txt b/content/test/data/accessibility/region-expected-mac.txt
deleted file mode 100644
index c501c6b..0000000
--- a/content/test/data/accessibility/region-expected-mac.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-AXWebArea
-    AXGroup AXSubrole=AXDocumentRegion
-        AXStaticText AXValue='This is a section element.'
-    AXGroup AXSubrole=AXDocumentRegion
-        AXStaticText AXValue='This is an ARIA region.'
diff --git a/content/test/data/accessibility/region-expected-win.txt b/content/test/data/accessibility/region-expected-win.txt
deleted file mode 100644
index c10024ab..0000000
--- a/content/test/data/accessibility/region-expected-win.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
-    IA2_ROLE_SECTION READONLY xml-roles:region
-        ROLE_SYSTEM_STATICTEXT name='This is a section element.'
-    IA2_ROLE_SECTION READONLY xml-roles:region
-        ROLE_SYSTEM_STATICTEXT name='This is an ARIA region.'
diff --git a/content/test/data/accessibility/region.html b/content/test/data/accessibility/region.html
deleted file mode 100644
index 29e729b3..0000000
--- a/content/test/data/accessibility/region.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
-@MAC-ALLOW:AXSubrole=AXDocumentRegion
-@MAC-DENY:AXTitle*
-@WIN-ALLOW:xml-roles:region
--->
-<!doctype html>
-<html>
-<body>
-  <section>
-    This is a section element.
-  </section>
-
-  <div role="region">
-    This is an ARIA region.
-  </div>
-</body>
-</html>
diff --git a/content/test/data/accessibility/region-expected-android.txt b/content/test/data/accessibility/section-expected-android.txt
similarity index 65%
rename from content/test/data/accessibility/region-expected-android.txt
rename to content/test/data/accessibility/section-expected-android.txt
index 2d5b1a0a..ab9de9e 100644
--- a/content/test/data/accessibility/region-expected-android.txt
+++ b/content/test/data/accessibility/section-expected-android.txt
@@ -1,3 +1,2 @@
 android.webkit.WebView focusable focused scrollable
     android.view.View clickable name='This is a section element.'
-    android.view.View clickable name='This is an ARIA region.'
diff --git a/content/test/data/accessibility/section-expected-mac.txt b/content/test/data/accessibility/section-expected-mac.txt
new file mode 100644
index 0000000..3732cf5
--- /dev/null
+++ b/content/test/data/accessibility/section-expected-mac.txt
@@ -0,0 +1,3 @@
+AXWebArea AXRoleDescription='HTML content'
+    AXGroup AXSubrole=AXDocumentRegion AXRoleDescription='region'
+        AXStaticText AXRoleDescription='text' AXValue='This is a section element.'
diff --git a/content/test/data/accessibility/section-expected-win.txt b/content/test/data/accessibility/section-expected-win.txt
new file mode 100644
index 0000000..d7b0b29
--- /dev/null
+++ b/content/test/data/accessibility/section-expected-win.txt
@@ -0,0 +1,3 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    IA2_ROLE_SECTION xml-roles:region
+        ROLE_SYSTEM_STATICTEXT name='This is a section element.'
diff --git a/content/test/data/accessibility/section.html b/content/test/data/accessibility/section.html
new file mode 100644
index 0000000..281a61771
--- /dev/null
+++ b/content/test/data/accessibility/section.html
@@ -0,0 +1,15 @@
+<!--
+@MAC-ALLOW:AXRole*
+@MAC-ALLOW:AXSubrole*
+@WIN-ALLOW:xml-roles:*
+-->
+<!DOCTYPE html>
+<html>
+<body>
+
+<section>
+  This is a section element.
+</section>
+
+</body>
+</html>
diff --git a/content/test/data/accessibility/textarea-expected-android.txt b/content/test/data/accessibility/textarea-expected-android.txt
new file mode 100644
index 0000000..bea1bf2
--- /dev/null
+++ b/content/test/data/accessibility/textarea-expected-android.txt
@@ -0,0 +1,5 @@
+#<skip - crbug.com/425485>
+android.webkit.WebView focusable focused scrollable
+    android.view.View
+        android.widget.EditText clickable editable_text focusable multiline name='The textarea tag defines a multi-line text input control.
+'
\ No newline at end of file
diff --git a/content/test/data/accessibility/textarea-expected-mac.txt b/content/test/data/accessibility/textarea-expected-mac.txt
new file mode 100644
index 0000000..4cc58a0
--- /dev/null
+++ b/content/test/data/accessibility/textarea-expected-mac.txt
@@ -0,0 +1,5 @@
+#<skip -- AXValue for AXTextArea is not in same line crbug.com/425485>
+AXWebArea AXRoleDescription='HTML content'
+    AXGroup AXRoleDescription='group'
+        AXTextArea AXRoleDescription='text entry area' AXValue='The textarea tag defines a multi-line text input control.
+'
diff --git a/content/test/data/accessibility/textarea-expected-win.txt b/content/test/data/accessibility/textarea-expected-win.txt
new file mode 100644
index 0000000..aef8b5f
--- /dev/null
+++ b/content/test/data/accessibility/textarea-expected-win.txt
@@ -0,0 +1,3 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+    IA2_ROLE_SECTION READONLY
+        ROLE_SYSTEM_TEXT FOCUSABLE
diff --git a/content/test/data/accessibility/textarea.html b/content/test/data/accessibility/textarea.html
new file mode 100644
index 0000000..eee3569d
--- /dev/null
+++ b/content/test/data/accessibility/textarea.html
@@ -0,0 +1,14 @@
+<!--
+@MAC-ALLOW:AXRole*
+-->
+<!DOCTYPE html>
+<html>
+<body>
+
+<textarea rows="4" cols="50">
+The textarea tag defines a multi-line text input control.
+</textarea>
+
+</body>
+</html>
+
diff --git a/content/test/data/accessibility/title-expected-android.txt b/content/test/data/accessibility/title-expected-android.txt
new file mode 100644
index 0000000..9b491c4
--- /dev/null
+++ b/content/test/data/accessibility/title-expected-android.txt
@@ -0,0 +1 @@
+android.webkit.WebView clickable focusable focused scrollable name='Title of the document'
\ No newline at end of file
diff --git a/content/test/data/accessibility/title-expected-mac.txt b/content/test/data/accessibility/title-expected-mac.txt
new file mode 100644
index 0000000..c09466d
--- /dev/null
+++ b/content/test/data/accessibility/title-expected-mac.txt
@@ -0,0 +1 @@
+AXWebArea AXTitle='Title of the document'
\ No newline at end of file
diff --git a/content/test/data/accessibility/title-expected-win.txt b/content/test/data/accessibility/title-expected-win.txt
new file mode 100644
index 0000000..5ae7831dc
--- /dev/null
+++ b/content/test/data/accessibility/title-expected-win.txt
@@ -0,0 +1 @@
+ROLE_SYSTEM_DOCUMENT name='Title of the document' READONLY FOCUSABLE
diff --git a/content/test/data/accessibility/title.html b/content/test/data/accessibility/title.html
new file mode 100644
index 0000000..b3218c6f
--- /dev/null
+++ b/content/test/data/accessibility/title.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Title of the document</title>
+</head>
+<body>
+</body>
+</html>
+
diff --git a/content/test/data/media/getusermedia-real-webcam.html b/content/test/data/media/getusermedia-real-webcam.html
new file mode 100644
index 0000000..8215c0f
--- /dev/null
+++ b/content/test/data/media/getusermedia-real-webcam.html
@@ -0,0 +1,36 @@
+<html>
+<head>
+  <script type="text/javascript" src="webrtc_test_utilities.js"></script>
+  <script type="text/javascript">
+  $ = function(id) {
+    return document.getElementById(id);
+  };
+
+  function getUserMediaAndReturnVideoDimensions(constraints) {
+    navigator.webkitGetUserMedia(
+        constraints, gotStreamCallback, failedCallback);
+  }
+
+  function failedCallback(error) {
+    failTest('GetUserMedia call failed with code ' + error.code);
+  }
+
+  function gotStreamCallback(stream) {
+    var localView = $('local-view');
+    localView.src = URL.createObjectURL(stream);
+    detectVideoPlaying('local-view', function() {
+      sendValueToTest(localView.videoWidth + 'x' + localView.videoHeight);
+    });
+  }
+  </script>
+</head>
+<body>
+  <table border="0">
+    <tr>
+      <td><video id="local-view" autoplay="autoplay">
+          </video></td>
+      <td><canvas id="local-view-canvas" style="display:none"></canvas></td>
+    </tr>
+  </table>
+</body>
+</html>
diff --git a/content/test/data/media/webrtc_test_utilities.js b/content/test/data/media/webrtc_test_utilities.js
index 0f8f0a94..5fd3811 100644
--- a/content/test/data/media/webrtc_test_utilities.js
+++ b/content/test/data/media/webrtc_test_utilities.js
@@ -213,3 +213,19 @@
   }
 }
 
+// Returns has-video-input-device to the test if there's a webcam available on
+// the system.
+function hasVideoInputDeviceOnSystem() {
+  MediaStreamTrack.getSources(function(devices) {
+    var hasVideoInputDevice = false;
+    devices.forEach(function(device) {
+      if (device.kind == 'video')
+        hasVideoInputDevice = true;
+    });
+
+    if (hasVideoInputDevice)
+      sendValueToTest('has-video-input-device');
+    else
+      sendValueToTest('no-video-input-devices');
+  });
+}
\ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index 729ea81..92f3cd9 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -27,14 +27,6 @@
     # Fails on all platforms
     self.Fail('conformance/glsl/misc/shaders-with-invariance.html',
         bug=421710)
-    self.Fail('conformance/glsl/misc/struct-unary-operators.html',
-        bug=421709)
-    self.Fail('conformance/renderbuffers/feedback-loop.html',
-        bug=421695)
-
-    # Flaky on Win
-    self.Fail('conformance/extensions/webgl-draw-buffers.html',
-        ['win'], bug=369349)
 
     # Win failures
     self.Fail('conformance/glsl/misc/struct-equals.html',
@@ -51,12 +43,13 @@
         ['win'], bug=420357)
     self.Fail('conformance/glsl/misc/ternary-operators-in-global-initializers.html',
         ['win'], bug=415694)
-    self.Fail('conformance/glsl/misc/ternary-operators-in-initializers.html',
-        ['win'], bug=415694)
     # This test still causes itself and any tests afterwards to time out
     # in Win Debug bots.
     self.Skip('conformance/textures/texture-copying-feedback-loops.html',
         ['Win'], bug=421695)
+    # Flaky on Win
+    self.Fail('conformance/extensions/webgl-draw-buffers.html',
+        ['win'], bug=369349)
 
     # Win7 / Intel failures
     self.Fail('conformance/rendering/gl-scissor-test.html',
diff --git a/content/test/mock_webblob_registry_impl.cc b/content/test/mock_webblob_registry_impl.cc
index a5136778..9ddfa5a 100644
--- a/content/test/mock_webblob_registry_impl.cc
+++ b/content/test/mock_webblob_registry_impl.cc
@@ -10,7 +10,6 @@
 
 using blink::WebBlobData;
 using blink::WebString;
-using blink::WebThreadSafeData;
 using blink::WebURL;
 
 namespace content {
@@ -47,10 +46,6 @@
 }
 
 void MockWebBlobRegistryImpl::addDataToStream(const WebURL& url,
-                                              WebThreadSafeData& data) {
-}
-
-void MockWebBlobRegistryImpl::addDataToStream(const WebURL& url,
                                               const char* data,
                                               size_t length) {
 }
diff --git a/content/test/mock_webblob_registry_impl.h b/content/test/mock_webblob_registry_impl.h
index 9e3c35e0..a4ac7d4 100644
--- a/content/test/mock_webblob_registry_impl.h
+++ b/content/test/mock_webblob_registry_impl.h
@@ -8,10 +8,6 @@
 #include "base/macros.h"
 #include "third_party/WebKit/public/platform/WebBlobRegistry.h"
 
-namespace blink {
-class WebThreadSafeData;
-}  // namespace blink
-
 namespace content {
 
 class MockWebBlobRegistryImpl : public blink::WebBlobRegistry {
@@ -32,9 +28,6 @@
                                  const blink::WebString& content_type);
   virtual void registerStreamURL(const blink::WebURL& url,
                                  const blink::WebURL& src_url);
-  // TODO(tyoshino): Remove once removed in Blink side.
-  virtual void addDataToStream(const blink::WebURL& url,
-                               blink::WebThreadSafeData& data);
   virtual void addDataToStream(const blink::WebURL& url,
                                const char* data, size_t length);
   virtual void finalizeStream(const blink::WebURL& url);
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h
index 575d0bd..5d9d186 100644
--- a/content/test/test_render_view_host.h
+++ b/content/test/test_render_view_host.h
@@ -98,7 +98,8 @@
   void UpdateCursor(const WebCursor& cursor) override {}
   void TextInputTypeChanged(ui::TextInputType type,
                             ui::TextInputMode input_mode,
-                            bool can_compose_inline) override {}
+                            bool can_compose_inline,
+                            int flags) override {}
   void ImeCancelComposition() override {}
 #if defined(OS_MACOSX) || defined(USE_AURA)
   void ImeCompositionRangeChanged(
diff --git a/content/test/webrtc_content_browsertest_base.cc b/content/test/webrtc_content_browsertest_base.cc
index e6c3b46..f37eb90 100644
--- a/content/test/webrtc_content_browsertest_base.cc
+++ b/content/test/webrtc_content_browsertest_base.cc
@@ -24,12 +24,11 @@
 namespace content {
 
 void WebRtcContentBrowserTest::SetUpCommandLine(CommandLine* command_line) {
-  // We need fake devices in this test since we want to run on naked VMs. We
-  // assume these switches are set by default in content_browsertests.
-  ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kUseFakeDeviceForMediaStream));
+  // Assume this is set by the content test launcher.
   ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kUseFakeUIForMediaStream));
+  ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kUseFakeDeviceForMediaStream));
 
   // Always include loopback interface in network list, in case the test device
   // doesn't have other interfaces available.
@@ -38,6 +37,7 @@
 }
 
 void WebRtcContentBrowserTest::SetUp() {
+  // We need pixel output when we dig pixels out of video tags for verification.
   EnablePixelOutput();
 #if defined(OS_CHROMEOS)
     chromeos::CrasAudioHandler::InitializeForTesting();
diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h
index 7f1cc51..38002eb 100644
--- a/device/bluetooth/bluetooth_adapter_mac.h
+++ b/device/bluetooth/bluetooth_adapter_mac.h
@@ -38,62 +38,58 @@
   static base::WeakPtr<BluetoothAdapter> CreateAdapter();
 
   // BluetoothAdapter:
-  virtual void AddObserver(BluetoothAdapter::Observer* observer) override;
-  virtual void RemoveObserver(BluetoothAdapter::Observer* observer) override;
-  virtual std::string GetAddress() const override;
-  virtual std::string GetName() const override;
-  virtual void SetName(const std::string& name,
+  void AddObserver(BluetoothAdapter::Observer* observer) override;
+  void RemoveObserver(BluetoothAdapter::Observer* observer) override;
+  std::string GetAddress() const override;
+  std::string GetName() const override;
+  void SetName(const std::string& name,
+               const base::Closure& callback,
+               const ErrorCallback& error_callback) override;
+  bool IsInitialized() const override;
+  bool IsPresent() const override;
+  bool IsPowered() const override;
+  void SetPowered(bool powered,
+                  const base::Closure& callback,
+                  const ErrorCallback& error_callback) override;
+  bool IsDiscoverable() const override;
+  void SetDiscoverable(bool discoverable,
                        const base::Closure& callback,
                        const ErrorCallback& error_callback) override;
-  virtual bool IsInitialized() const override;
-  virtual bool IsPresent() const override;
-  virtual bool IsPowered() const override;
-  virtual void SetPowered(
-      bool powered,
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override;
-  virtual bool IsDiscoverable() const override;
-  virtual void SetDiscoverable(
-      bool discoverable,
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override;
-  virtual bool IsDiscovering() const override;
-  virtual void CreateRfcommService(
+  bool IsDiscovering() const override;
+  void CreateRfcommService(
       const BluetoothUUID& uuid,
       const ServiceOptions& options,
       const CreateServiceCallback& callback,
       const CreateServiceErrorCallback& error_callback) override;
-  virtual void CreateL2capService(
+  void CreateL2capService(
       const BluetoothUUID& uuid,
       const ServiceOptions& options,
       const CreateServiceCallback& callback,
       const CreateServiceErrorCallback& error_callback) override;
 
   // BluetoothDiscoveryManagerMac::Observer overrides
-  virtual void DeviceFound(IOBluetoothDevice* device) override;
-  virtual void DiscoveryStopped(bool unexpected) override;
+  void DeviceFound(IOBluetoothDevice* device) override;
+  void DiscoveryStopped(bool unexpected) override;
 
   // Registers that a new |device| has connected to the local host.
   void DeviceConnected(IOBluetoothDevice* device);
 
  protected:
   // BluetoothAdapter:
-  virtual void RemovePairingDelegateInternal(
+  void RemovePairingDelegateInternal(
       device::BluetoothDevice::PairingDelegate* pairing_delegate) override;
 
  private:
   friend class BluetoothAdapterMacTest;
 
   BluetoothAdapterMac();
-  virtual ~BluetoothAdapterMac();
+  ~BluetoothAdapterMac() override;
 
   // BluetoothAdapter:
-  virtual void AddDiscoverySession(
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override;
-  virtual void RemoveDiscoverySession(
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override;
+  void AddDiscoverySession(const base::Closure& callback,
+                           const ErrorCallback& error_callback) override;
+  void RemoveDiscoverySession(const base::Closure& callback,
+                              const ErrorCallback& error_callback) override;
 
   void Init();
   void InitForTest(scoped_refptr<base::SequencedTaskRunner> ui_task_runner);
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc
index 88d94c92..8e9e1145 100644
--- a/device/bluetooth/bluetooth_adapter_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -17,108 +17,74 @@
   TestBluetoothAdapter() {
   }
 
-  virtual void AddObserver(BluetoothAdapter::Observer* observer) override {
-  }
+  void AddObserver(BluetoothAdapter::Observer* observer) override {}
 
-  virtual void RemoveObserver(BluetoothAdapter::Observer* observer) override {
+  void RemoveObserver(BluetoothAdapter::Observer* observer) override {}
 
-  }
+  std::string GetAddress() const override { return ""; }
 
-  virtual std::string GetAddress() const override {
-    return "";
-  }
+  std::string GetName() const override { return ""; }
 
-  virtual std::string GetName() const override {
-    return "";
-  }
+  void SetName(const std::string& name,
+               const base::Closure& callback,
+               const ErrorCallback& error_callback) override {}
 
-  virtual void SetName(const std::string& name,
+  bool IsInitialized() const override { return false; }
+
+  bool IsPresent() const override { return false; }
+
+  bool IsPowered() const override { return false; }
+
+  void SetPowered(bool powered,
+                  const base::Closure& callback,
+                  const ErrorCallback& error_callback) override {}
+
+  bool IsDiscoverable() const override { return false; }
+
+  void SetDiscoverable(bool discoverable,
                        const base::Closure& callback,
-                       const ErrorCallback& error_callback) override {
-  }
+                       const ErrorCallback& error_callback) override {}
 
-  virtual bool IsInitialized() const override {
-    return false;
-  }
+  bool IsDiscovering() const override { return false; }
 
-  virtual bool IsPresent() const override {
-    return false;
-  }
+  void StartDiscoverySession(const DiscoverySessionCallback& callback,
+                             const ErrorCallback& error_callback) override {}
 
-  virtual bool IsPowered() const override {
-    return false;
-  }
-
-  virtual void SetPowered(
-      bool powered,
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override {
-  }
-
-  virtual bool IsDiscoverable() const override {
-    return false;
-  }
-
-  virtual void SetDiscoverable(
-      bool discoverable,
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override {
-  }
-
-  virtual bool IsDiscovering() const override {
-    return false;
-  }
-
-  virtual void StartDiscoverySession(
-      const DiscoverySessionCallback& callback,
-      const ErrorCallback& error_callback) override {
-  }
-
-  virtual void CreateRfcommService(
+  void CreateRfcommService(
       const BluetoothUUID& uuid,
       const ServiceOptions& options,
       const CreateServiceCallback& callback,
-      const CreateServiceErrorCallback& error_callback) override {
-  }
+      const CreateServiceErrorCallback& error_callback) override {}
 
-  virtual void CreateL2capService(
+  void CreateL2capService(
       const BluetoothUUID& uuid,
       const ServiceOptions& options,
       const CreateServiceCallback& callback,
-      const CreateServiceErrorCallback& error_callback) override {
-  }
+      const CreateServiceErrorCallback& error_callback) override {}
 
  protected:
-  virtual ~TestBluetoothAdapter() {}
+  ~TestBluetoothAdapter() override {}
 
-  virtual void AddDiscoverySession(
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override {
-  }
+  void AddDiscoverySession(const base::Closure& callback,
+                           const ErrorCallback& error_callback) override {}
 
-  virtual void RemoveDiscoverySession(
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override {
-  }
+  void RemoveDiscoverySession(const base::Closure& callback,
+                              const ErrorCallback& error_callback) override {}
 
-  virtual void RemovePairingDelegateInternal(
-      BluetoothDevice::PairingDelegate* pairing_delegate) override {
-  }
+  void RemovePairingDelegateInternal(
+      BluetoothDevice::PairingDelegate* pairing_delegate) override {}
 };
 
 class TestPairingDelegate : public BluetoothDevice::PairingDelegate {
   public:
-   virtual void RequestPinCode(BluetoothDevice* device) override {}
-   virtual void RequestPasskey(BluetoothDevice* device) override {}
-   virtual void DisplayPinCode(BluetoothDevice* device,
-                               const std::string& pincode) override {}
-   virtual void DisplayPasskey(BluetoothDevice* device,
-                               uint32 passkey) override {}
-   virtual void KeysEntered(BluetoothDevice* device,
-                            uint32 entered) override {}
-   virtual void ConfirmPasskey(BluetoothDevice* device,
-                               uint32 passkey) override {}
-   virtual void AuthorizePairing(BluetoothDevice* device) override {}
+   void RequestPinCode(BluetoothDevice* device) override {}
+   void RequestPasskey(BluetoothDevice* device) override {}
+   void DisplayPinCode(BluetoothDevice* device,
+                       const std::string& pincode) override {}
+   void DisplayPasskey(BluetoothDevice* device, uint32 passkey) override {}
+   void KeysEntered(BluetoothDevice* device, uint32 entered) override {}
+   void ConfirmPasskey(BluetoothDevice* device, uint32 passkey) override {}
+   void AuthorizePairing(BluetoothDevice* device) override {}
 };
 
 
diff --git a/device/bluetooth/bluetooth_device_mac.h b/device/bluetooth/bluetooth_device_mac.h
index 299fe91..8f0ed08 100644
--- a/device/bluetooth/bluetooth_device_mac.h
+++ b/device/bluetooth/bluetooth_device_mac.h
@@ -21,53 +21,50 @@
 class BluetoothDeviceMac : public BluetoothDevice {
  public:
   explicit BluetoothDeviceMac(IOBluetoothDevice* device);
-  virtual ~BluetoothDeviceMac();
+  ~BluetoothDeviceMac() override;
 
   // BluetoothDevice override
-  virtual uint32 GetBluetoothClass() const override;
-  virtual std::string GetAddress() const override;
-  virtual VendorIDSource GetVendorIDSource() const override;
-  virtual uint16 GetVendorID() const override;
-  virtual uint16 GetProductID() const override;
-  virtual uint16 GetDeviceID() const override;
-  virtual int GetRSSI() const override;
-  virtual int GetCurrentHostTransmitPower() const override;
-  virtual int GetMaximumHostTransmitPower() const override;
-  virtual bool IsPaired() const override;
-  virtual bool IsConnected() const override;
-  virtual bool IsConnectable() const override;
-  virtual bool IsConnecting() const override;
-  virtual UUIDList GetUUIDs() const override;
-  virtual bool ExpectingPinCode() const override;
-  virtual bool ExpectingPasskey() const override;
-  virtual bool ExpectingConfirmation() const override;
-  virtual void Connect(
-      PairingDelegate* pairing_delegate,
-      const base::Closure& callback,
-      const ConnectErrorCallback& error_callback) override;
-  virtual void SetPinCode(const std::string& pincode) override;
-  virtual void SetPasskey(uint32 passkey) override;
-  virtual void ConfirmPairing() override;
-  virtual void RejectPairing() override;
-  virtual void CancelPairing() override;
-  virtual void Disconnect(
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override;
-  virtual void Forget(const ErrorCallback& error_callback) override;
-  virtual void ConnectToService(
+  uint32 GetBluetoothClass() const override;
+  std::string GetAddress() const override;
+  VendorIDSource GetVendorIDSource() const override;
+  uint16 GetVendorID() const override;
+  uint16 GetProductID() const override;
+  uint16 GetDeviceID() const override;
+  int GetRSSI() const override;
+  int GetCurrentHostTransmitPower() const override;
+  int GetMaximumHostTransmitPower() const override;
+  bool IsPaired() const override;
+  bool IsConnected() const override;
+  bool IsConnectable() const override;
+  bool IsConnecting() const override;
+  UUIDList GetUUIDs() const override;
+  bool ExpectingPinCode() const override;
+  bool ExpectingPasskey() const override;
+  bool ExpectingConfirmation() const override;
+  void Connect(PairingDelegate* pairing_delegate,
+               const base::Closure& callback,
+               const ConnectErrorCallback& error_callback) override;
+  void SetPinCode(const std::string& pincode) override;
+  void SetPasskey(uint32 passkey) override;
+  void ConfirmPairing() override;
+  void RejectPairing() override;
+  void CancelPairing() override;
+  void Disconnect(const base::Closure& callback,
+                  const ErrorCallback& error_callback) override;
+  void Forget(const ErrorCallback& error_callback) override;
+  void ConnectToService(
       const BluetoothUUID& uuid,
       const ConnectToServiceCallback& callback,
       const ConnectToServiceErrorCallback& error_callback) override;
-  virtual void ConnectToServiceInsecurely(
+  void ConnectToServiceInsecurely(
       const BluetoothUUID& uuid,
       const ConnectToServiceCallback& callback,
       const ConnectToServiceErrorCallback& error_callback) override;
-  virtual void CreateGattConnection(
+  void CreateGattConnection(
       const GattConnectionCallback& callback,
       const ConnectErrorCallback& error_callback) override;
-  virtual void StartConnectionMonitor(
-      const base::Closure& callback,
-      const ErrorCallback& error_callback) override;
+  void StartConnectionMonitor(const base::Closure& callback,
+                              const ErrorCallback& error_callback) override;
 
   // Returns the timestamp when the device was last seen during an inquiry.
   // Returns nil if the device has never been seen during an inquiry.
@@ -79,7 +76,7 @@
 
  protected:
   // BluetoothDevice override
-  virtual std::string GetDeviceName() const override;
+  std::string GetDeviceName() const override;
 
  private:
   friend class BluetoothAdapterMac;
diff --git a/device/bluetooth/bluetooth_discovery_manager_mac.mm b/device/bluetooth/bluetooth_discovery_manager_mac.mm
index abc9cd88..1555c6f5 100644
--- a/device/bluetooth/bluetooth_discovery_manager_mac.mm
+++ b/device/bluetooth/bluetooth_discovery_manager_mac.mm
@@ -44,13 +44,13 @@
         inquiry_([[IOBluetoothDeviceInquiry alloc]
             initWithDelegate:inquiry_delegate_]) {}
 
-  virtual ~BluetoothDiscoveryManagerMacClassic() {}
+  ~BluetoothDiscoveryManagerMacClassic() override {}
 
   // BluetoothDiscoveryManagerMac override.
-  virtual bool IsDiscovering() const override { return should_do_discovery_; }
+  bool IsDiscovering() const override { return should_do_discovery_; }
 
   // BluetoothDiscoveryManagerMac override.
-  virtual bool StartDiscovery() override {
+  bool StartDiscovery() override {
     DVLOG(1) << "Bluetooth Classic: StartDiscovery";
     DCHECK(!should_do_discovery_);
 
@@ -78,7 +78,7 @@
   }
 
   // BluetoothDiscoveryManagerMac override.
-  virtual bool StopDiscovery() override {
+  bool StopDiscovery() override {
     DVLOG(1) << "Bluetooth Classic: StopDiscovery";
     DCHECK(should_do_discovery_);
 
diff --git a/device/bluetooth/bluetooth_l2cap_channel_mac.h b/device/bluetooth/bluetooth_l2cap_channel_mac.h
index eafe8f51..de085e65 100644
--- a/device/bluetooth/bluetooth_l2cap_channel_mac.h
+++ b/device/bluetooth/bluetooth_l2cap_channel_mac.h
@@ -24,7 +24,7 @@
   // NOTE: The |channel| is expected to already be retained.
   BluetoothL2capChannelMac(BluetoothSocketMac* socket,
                            IOBluetoothL2CAPChannel* channel);
-  virtual ~BluetoothL2capChannelMac();
+  ~BluetoothL2capChannelMac() override;
 
   // Opens a new L2CAP channel with Channel ID |channel_id| to the target
   // |device|. Returns the opened channel and sets |status| to kIOReturnSuccess
@@ -37,12 +37,10 @@
       IOReturn* status);
 
   // BluetoothChannelMac:
-  virtual void SetSocket(BluetoothSocketMac* socket) override;
-  virtual IOBluetoothDevice* GetDevice() override;
-  virtual uint16_t GetOutgoingMTU() override;
-  virtual IOReturn WriteAsync(void* data,
-                              uint16_t length,
-                              void* refcon) override;
+  void SetSocket(BluetoothSocketMac* socket) override;
+  IOBluetoothDevice* GetDevice() override;
+  uint16_t GetOutgoingMTU() override;
+  IOReturn WriteAsync(void* data, uint16_t length, void* refcon) override;
 
   void OnChannelOpenComplete(IOBluetoothL2CAPChannel* channel,
                              IOReturn status);
diff --git a/device/bluetooth/bluetooth_rfcomm_channel_mac.h b/device/bluetooth/bluetooth_rfcomm_channel_mac.h
index 665e2d3..5f98f27 100644
--- a/device/bluetooth/bluetooth_rfcomm_channel_mac.h
+++ b/device/bluetooth/bluetooth_rfcomm_channel_mac.h
@@ -24,7 +24,7 @@
   // NOTE: The |channel| is expected to already be retained.
   BluetoothRfcommChannelMac(BluetoothSocketMac* socket,
                             IOBluetoothRFCOMMChannel* channel);
-  virtual ~BluetoothRfcommChannelMac();
+  ~BluetoothRfcommChannelMac() override;
 
   // Opens a new RFCOMM channel with Channel ID |channel_id| to the target
   // |device|. Returns the opened channel and sets |status| to kIOReturnSuccess
@@ -37,12 +37,10 @@
       IOReturn* status);
 
   // BluetoothChannelMac:
-  virtual void SetSocket(BluetoothSocketMac* socket) override;
-  virtual IOBluetoothDevice* GetDevice() override;
-  virtual uint16_t GetOutgoingMTU() override;
-  virtual IOReturn WriteAsync(void* data,
-                              uint16_t length,
-                              void* refcon) override;
+  void SetSocket(BluetoothSocketMac* socket) override;
+  IOBluetoothDevice* GetDevice() override;
+  uint16_t GetOutgoingMTU() override;
+  IOReturn WriteAsync(void* data, uint16_t length, void* refcon) override;
 
   void OnChannelOpenComplete(IOBluetoothRFCOMMChannel* channel,
                              IOReturn status);
diff --git a/device/bluetooth/bluetooth_socket_mac.h b/device/bluetooth/bluetooth_socket_mac.h
index f51f252..768b850 100644
--- a/device/bluetooth/bluetooth_socket_mac.h
+++ b/device/bluetooth/bluetooth_socket_mac.h
@@ -75,18 +75,17 @@
                         const ErrorCompletionCallback& error_callback);
 
   // BluetoothSocket:
-  virtual void Close() override;
-  virtual void Disconnect(const base::Closure& callback) override;
-  virtual void Receive(
-      int /* buffer_size */,
-      const ReceiveCompletionCallback& success_callback,
-      const ReceiveErrorCompletionCallback& error_callback) override;
-  virtual void Send(scoped_refptr<net::IOBuffer> buffer,
-                    int buffer_size,
-                    const SendCompletionCallback& success_callback,
-                    const ErrorCompletionCallback& error_callback) override;
-  virtual void Accept(const AcceptCompletionCallback& success_callback,
-                      const ErrorCompletionCallback& error_callback) override;
+  void Close() override;
+  void Disconnect(const base::Closure& callback) override;
+  void Receive(int /* buffer_size */,
+               const ReceiveCompletionCallback& success_callback,
+               const ReceiveErrorCompletionCallback& error_callback) override;
+  void Send(scoped_refptr<net::IOBuffer> buffer,
+            int buffer_size,
+            const SendCompletionCallback& success_callback,
+            const ErrorCompletionCallback& error_callback) override;
+  void Accept(const AcceptCompletionCallback& success_callback,
+              const ErrorCompletionCallback& error_callback) override;
 
   // Callback that is invoked when the OS completes an SDP query.
   // |status| is the returned status from the SDP query, |device| is the
@@ -145,7 +144,7 @@
   };
 
   BluetoothSocketMac();
-  virtual ~BluetoothSocketMac();
+  ~BluetoothSocketMac() override;
 
   // Accepts a single incoming connection.
   void AcceptConnectionRequest();
diff --git a/device/bluetooth/bluetooth_socket_net.h b/device/bluetooth/bluetooth_socket_net.h
index ed6323a..74117767 100644
--- a/device/bluetooth/bluetooth_socket_net.h
+++ b/device/bluetooth/bluetooth_socket_net.h
@@ -31,21 +31,20 @@
 class BluetoothSocketNet : public BluetoothSocket {
  public:
   // BluetoothSocket:
-  virtual void Close() override;
-  virtual void Disconnect(const base::Closure& callback) override;
-  virtual void Receive(int buffer_size,
-                       const ReceiveCompletionCallback& success_callback,
-                       const ReceiveErrorCompletionCallback& error_callback)
-      override;
-  virtual void Send(scoped_refptr<net::IOBuffer> buffer,
-                    int buffer_size,
-                    const SendCompletionCallback& success_callback,
-                    const ErrorCompletionCallback& error_callback) override;
+  void Close() override;
+  void Disconnect(const base::Closure& callback) override;
+  void Receive(int buffer_size,
+               const ReceiveCompletionCallback& success_callback,
+               const ReceiveErrorCompletionCallback& error_callback) override;
+  void Send(scoped_refptr<net::IOBuffer> buffer,
+            int buffer_size,
+            const SendCompletionCallback& success_callback,
+            const ErrorCompletionCallback& error_callback) override;
 
  protected:
   BluetoothSocketNet(scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
                      scoped_refptr<BluetoothSocketThread> socket_thread);
-  virtual ~BluetoothSocketNet();
+  ~BluetoothSocketNet() override;
 
   // Resets locally held data after a socket is closed. Default implementation
   // does nothing, subclasses may override.
diff --git a/device/hid/device_monitor_linux.h b/device/hid/device_monitor_linux.h
index 7f5d242..bbf1e52 100644
--- a/device/hid/device_monitor_linux.h
+++ b/device/hid/device_monitor_linux.h
@@ -14,7 +14,7 @@
 #include "base/message_loop/message_pump_libevent.h"
 #include "base/observer_list.h"
 #include "base/threading/thread_checker.h"
-#include "device/udev_linux/udev.h"
+#include "device/udev_linux/scoped_udev.h"
 
 struct udev_device;
 
diff --git a/device/hid/hid_connection_mac.h b/device/hid/hid_connection_mac.h
index 2da606d..daac83b 100644
--- a/device/hid/hid_connection_mac.h
+++ b/device/hid/hid_connection_mac.h
@@ -32,20 +32,19 @@
       scoped_refptr<base::SingleThreadTaskRunner> file_task_runner);
 
  private:
-  virtual ~HidConnectionMac();
+  ~HidConnectionMac() override;
 
   // HidConnection implementation.
-  virtual void PlatformClose() override;
-  virtual void PlatformRead(const ReadCallback& callback) override;
-  virtual void PlatformWrite(scoped_refptr<net::IOBuffer> buffer,
-                             size_t size,
-                             const WriteCallback& callback) override;
-  virtual void PlatformGetFeatureReport(uint8_t report_id,
-                                        const ReadCallback& callback) override;
-  virtual void PlatformSendFeatureReport(
-      scoped_refptr<net::IOBuffer> buffer,
-      size_t size,
-      const WriteCallback& callback) override;
+  void PlatformClose() override;
+  void PlatformRead(const ReadCallback& callback) override;
+  void PlatformWrite(scoped_refptr<net::IOBuffer> buffer,
+                     size_t size,
+                     const WriteCallback& callback) override;
+  void PlatformGetFeatureReport(uint8_t report_id,
+                                const ReadCallback& callback) override;
+  void PlatformSendFeatureReport(scoped_refptr<net::IOBuffer> buffer,
+                                 size_t size,
+                                 const WriteCallback& callback) override;
 
   static void InputReportCallback(void* context,
                                   IOReturn result,
diff --git a/device/hid/hid_service.cc b/device/hid/hid_service.cc
index 12ea5829b..d2ccaa3 100644
--- a/device/hid/hid_service.cc
+++ b/device/hid/hid_service.cc
@@ -30,11 +30,11 @@
  public:
   explicit Destroyer(HidService* hid_service)
       : hid_service_(hid_service) {}
-  virtual ~Destroyer() {}
+  ~Destroyer() override {}
 
  private:
   // base::MessageLoop::DestructionObserver implementation.
-  virtual void WillDestroyCurrentMessageLoop() override {
+  void WillDestroyCurrentMessageLoop() override {
     base::MessageLoop::current()->RemoveDestructionObserver(this);
     delete hid_service_;
     delete this;
diff --git a/device/hid/hid_service_linux.cc b/device/hid/hid_service_linux.cc
index e5fcb52..45688f5 100644
--- a/device/hid/hid_service_linux.cc
+++ b/device/hid/hid_service_linux.cc
@@ -20,7 +20,7 @@
 #include "device/hid/hid_connection_linux.h"
 #include "device/hid/hid_device_info.h"
 #include "device/hid/hid_report_descriptor.h"
-#include "device/udev_linux/udev.h"
+#include "device/udev_linux/scoped_udev.h"
 
 #if defined(OS_CHROMEOS)
 #include "base/sys_info.h"
@@ -146,7 +146,7 @@
   uint32_t int_property = 0;
   const char* str_property = NULL;
 
-  udev_device *parent = udev_device_get_parent(device);
+  udev_device* parent = udev_device_get_parent(device);
   if (!parent) {
     return;
   }
diff --git a/device/hid/hid_service_mac.h b/device/hid/hid_service_mac.h
index 44f63d4..bfb58bd 100644
--- a/device/hid/hid_service_mac.h
+++ b/device/hid/hid_service_mac.h
@@ -27,11 +27,11 @@
  public:
   HidServiceMac(scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
 
-  virtual void Connect(const HidDeviceId& device_id,
-                       const ConnectCallback& connect) override;
+  void Connect(const HidDeviceId& device_id,
+               const ConnectCallback& connect) override;
 
  private:
-  virtual ~HidServiceMac();
+  ~HidServiceMac() override;
 
   // IOService matching callbacks.
   static void FirstMatchCallback(void* context, io_iterator_t iterator);
diff --git a/device/nfc/nfc_tag_technology.h b/device/nfc/nfc_tag_technology.h
index 45b3146..8ada39b 100644
--- a/device/nfc/nfc_tag_technology.h
+++ b/device/nfc/nfc_tag_technology.h
@@ -71,7 +71,7 @@
   // The ErrorCallback is used by methods to asynchronously report errors.
   typedef base::Closure ErrorCallback;
 
-  virtual ~NfcNdefTagTechnology();
+  ~NfcNdefTagTechnology() override;
 
   // Interface for observing changes from NFC tags related to NDEF records.
   class Observer {
@@ -93,7 +93,7 @@
   virtual void RemoveObserver(Observer* observer) = 0;
 
   // NfcTagTechnology override.
-  virtual bool IsSupportedByTag() const override;
+  bool IsSupportedByTag() const override;
 
   // Returns all NDEF records that were received from the tag in the form of an
   // NDEF message. If the returned NDEF message contains no records, this only
diff --git a/device/serial/data_receiver.cc b/device/serial/data_receiver.cc
index b6e44a9..d7a47fa 100644
--- a/device/serial/data_receiver.cc
+++ b/device/serial/data_receiver.cc
@@ -63,13 +63,13 @@
          PendingReceive* receive,
          const char* buffer,
          uint32_t buffer_size);
-  virtual ~Buffer();
+  ~Buffer() override;
 
   // ReadOnlyBuffer overrides.
-  virtual const char* GetData() override;
-  virtual uint32_t GetSize() override;
-  virtual void Done(uint32_t bytes_consumed) override;
-  virtual void DoneWithError(uint32_t bytes_consumed, int32_t error) override;
+  const char* GetData() override;
+  uint32_t GetSize() override;
+  void Done(uint32_t bytes_consumed) override;
+  void DoneWithError(uint32_t bytes_consumed, int32_t error) override;
 
  private:
   // The DataReceiver whose data pipe we are providing a view.
diff --git a/device/serial/data_receiver.h b/device/serial/data_receiver.h
index df37018..79121f7 100644
--- a/device/serial/data_receiver.h
+++ b/device/serial/data_receiver.h
@@ -43,14 +43,14 @@
   struct PendingError;
   friend class base::RefCounted<DataReceiver>;
 
-  virtual ~DataReceiver();
+  ~DataReceiver() override;
 
   // serial::DataSourceClient override. Invoked by the DataSource to report
   // errors.
-  virtual void OnError(uint32_t bytes_since_last_error, int32_t error) override;
+  void OnError(uint32_t bytes_since_last_error, int32_t error) override;
 
   // mojo::ErrorHandler override. Calls ShutDown().
-  virtual void OnConnectionError() override;
+  void OnConnectionError() override;
 
   // Invoked by the PendingReceive to report that the user is done with the
   // receive buffer, having read |bytes_read| bytes from it.
diff --git a/device/serial/data_sender.h b/device/serial/data_sender.h
index 6e5c89e..89f729c 100644
--- a/device/serial/data_sender.h
+++ b/device/serial/data_sender.h
@@ -33,7 +33,7 @@
              uint32_t buffer_size,
              int32_t fatal_error_value);
 
-  virtual ~DataSender();
+  ~DataSender() override;
 
   // Starts an asynchronous send of |data|. If the send completes successfully,
   // |callback| will be called. Otherwise, |error_callback| will be called with
@@ -53,14 +53,14 @@
   class PendingSend;
 
   // serial::DataSinkClient overrides.
-  virtual void ReportBytesSent(uint32_t bytes_sent) override;
-  virtual void ReportBytesSentAndError(
+  void ReportBytesSent(uint32_t bytes_sent) override;
+  void ReportBytesSentAndError(
       uint32_t bytes_sent,
       int32_t error,
       const mojo::Callback<void(uint32_t)>& callback) override;
 
   // mojo::ErrorHandler override.
-  virtual void OnConnectionError() override;
+  void OnConnectionError() override;
 
   // Copies data from |pending_sends_| into the data pipe and starts |waiter_|
   // waiting if the pipe is full. When a PendingSend in |pending_sends_| has
diff --git a/device/serial/data_sink_receiver.cc b/device/serial/data_sink_receiver.cc
index 767f036..3d52e48 100644
--- a/device/serial/data_sink_receiver.cc
+++ b/device/serial/data_sink_receiver.cc
@@ -44,15 +44,15 @@
   Buffer(scoped_refptr<DataSinkReceiver> receiver,
          const char* buffer,
          uint32_t buffer_size);
-  virtual ~Buffer();
+  ~Buffer() override;
 
   void Cancel(int32_t error);
 
   // ReadOnlyBuffer overrides.
-  virtual const char* GetData() override;
-  virtual uint32_t GetSize() override;
-  virtual void Done(uint32_t bytes_read) override;
-  virtual void DoneWithError(uint32_t bytes_read, int32_t error) override;
+  const char* GetData() override;
+  uint32_t GetSize() override;
+  void Done(uint32_t bytes_read) override;
+  void DoneWithError(uint32_t bytes_read, int32_t error) override;
 
  private:
   // The DataSinkReceiver whose data pipe we are providing a view.
diff --git a/device/serial/data_sink_receiver.h b/device/serial/data_sink_receiver.h
index 75d85e6..711650b 100644
--- a/device/serial/data_sink_receiver.h
+++ b/device/serial/data_sink_receiver.h
@@ -46,12 +46,12 @@
   class PendingFlush;
   friend class base::RefCounted<DataSinkReceiver>;
 
-  virtual ~DataSinkReceiver();
+  ~DataSinkReceiver() override;
 
   // mojo::InterfaceImpl<serial::DataSink> overrides.
-  virtual void Init(mojo::ScopedDataPipeConsumerHandle handle) override;
-  virtual void Cancel(int32_t error) override;
-  virtual void OnConnectionError() override;
+  void Init(mojo::ScopedDataPipeConsumerHandle handle) override;
+  void Cancel(int32_t error) override;
+  void OnConnectionError() override;
 
   // Starts waiting for |handle_| to be ready for reads.
   void StartWaiting();
diff --git a/device/serial/data_source_sender.cc b/device/serial/data_source_sender.cc
index 4eaee758b..0738e3c1 100644
--- a/device/serial/data_source_sender.cc
+++ b/device/serial/data_source_sender.cc
@@ -49,13 +49,13 @@
          PendingSend* send,
          char* buffer,
          uint32_t buffer_size);
-  virtual ~Buffer();
+  ~Buffer() override;
 
   // WritableBuffer overrides.
-  virtual char* GetData() override;
-  virtual uint32_t GetSize() override;
-  virtual void Done(uint32_t bytes_written) override;
-  virtual void DoneWithError(uint32_t bytes_written, int32_t error) override;
+  char* GetData() override;
+  uint32_t GetSize() override;
+  void Done(uint32_t bytes_written) override;
+  void DoneWithError(uint32_t bytes_written, int32_t error) override;
 
  private:
   // The DataSourceSender whose data pipe we are providing a view.
diff --git a/device/serial/data_source_sender.h b/device/serial/data_source_sender.h
index 59782aa..9020a97 100644
--- a/device/serial/data_source_sender.h
+++ b/device/serial/data_source_sender.h
@@ -38,13 +38,13 @@
   friend class base::RefCounted<DataSourceSender>;
   class PendingSend;
 
-  virtual ~DataSourceSender();
+  ~DataSourceSender() override;
 
   // mojo::InterfaceImpl<serial::DataSourceSender> overrides.
-  virtual void Init(mojo::ScopedDataPipeProducerHandle handle) override;
-  virtual void Resume() override;
+  void Init(mojo::ScopedDataPipeProducerHandle handle) override;
+  void Resume() override;
   // Invoked in the event of a connection error. Calls DispatchFatalError().
-  virtual void OnConnectionError() override;
+  void OnConnectionError() override;
 
   // Starts waiting for |handle_| to be ready for writes.
   void StartWaiting();
diff --git a/device/serial/serial_connection.h b/device/serial/serial_connection.h
index c578a9dd..66f9c54 100644
--- a/device/serial/serial_connection.h
+++ b/device/serial/serial_connection.h
@@ -23,19 +23,19 @@
   SerialConnection(scoped_refptr<SerialIoHandler> io_handler,
                    mojo::InterfaceRequest<serial::DataSink> sink,
                    mojo::InterfaceRequest<serial::DataSource> source);
-  virtual ~SerialConnection();
+  ~SerialConnection() override;
 
   // mojo::InterfaceImpl<serial::Connection> overrides.
-  virtual void GetInfo(
+  void GetInfo(
       const mojo::Callback<void(serial::ConnectionInfoPtr)>& callback) override;
-  virtual void SetOptions(serial::ConnectionOptionsPtr options,
-                          const mojo::Callback<void(bool)>& callback) override;
-  virtual void SetControlSignals(
-      serial::HostControlSignalsPtr signals,
-      const mojo::Callback<void(bool)>& callback) override;
-  virtual void GetControlSignals(const mojo::Callback<
-      void(serial::DeviceControlSignalsPtr)>& callback) override;
-  virtual void Flush(const mojo::Callback<void(bool)>& callback) override;
+  void SetOptions(serial::ConnectionOptionsPtr options,
+                  const mojo::Callback<void(bool)>& callback) override;
+  void SetControlSignals(serial::HostControlSignalsPtr signals,
+                         const mojo::Callback<void(bool)>& callback) override;
+  void GetControlSignals(
+      const mojo::Callback<void(serial::DeviceControlSignalsPtr)>& callback)
+      override;
+  void Flush(const mojo::Callback<void(bool)>& callback) override;
 
  private:
   void OnSendPipeReady(scoped_ptr<ReadOnlyBuffer> buffer);
diff --git a/device/serial/serial_connection_unittest.cc b/device/serial/serial_connection_unittest.cc
index b18e95e..4b69158e 100644
--- a/device/serial/serial_connection_unittest.cc
+++ b/device/serial/serial_connection_unittest.cc
@@ -24,7 +24,7 @@
 namespace {
 
 class FakeSerialDeviceEnumerator : public SerialDeviceEnumerator {
-  virtual mojo::Array<serial::DeviceInfoPtr> GetDevices() override {
+  mojo::Array<serial::DeviceInfoPtr> GetDevices() override {
     mojo::Array<serial::DeviceInfoPtr> devices(1);
     devices[0] = serial::DeviceInfo::New();
     devices[0]->path = "device";
@@ -168,7 +168,7 @@
     EventReceived(EVENT_RECEIVE_ERROR);
   }
 
-  virtual void OnConnectionError() override {
+  void OnConnectionError() override {
     EventReceived(EVENT_ERROR);
     FAIL() << "Connection error";
   }
diff --git a/device/serial/serial_device_enumerator_linux.cc b/device/serial/serial_device_enumerator_linux.cc
index f2fb9fa..389b8035 100644
--- a/device/serial/serial_device_enumerator_linux.cc
+++ b/device/serial/serial_device_enumerator_linux.cc
@@ -19,19 +19,7 @@
 const char kProductIDKey[] = "ID_MODEL_ID";
 const char kProductNameKey[] = "ID_MODEL";
 
-struct UdevEnumerateDeleter {
-  void operator()(udev_enumerate* enumerate) {
-    udev_enumerate_unref(enumerate);
-  }
-};
-
-struct UdevDeviceDeleter {
-  void operator()(udev_device* device) { udev_device_unref(device); }
-};
-
-typedef scoped_ptr<udev_enumerate, UdevEnumerateDeleter> ScopedUdevEnumeratePtr;
-typedef scoped_ptr<udev_device, UdevDeviceDeleter> ScopedUdevDevicePtr;
-}
+}  // namespace
 
 // static
 scoped_ptr<SerialDeviceEnumerator> SerialDeviceEnumerator::Create() {
@@ -100,8 +88,4 @@
   return devices.Pass();
 }
 
-void SerialDeviceEnumeratorLinux::UdevDeleter::operator()(udev* handle) {
-  udev_unref(handle);
-}
-
 }  // namespace device
diff --git a/device/serial/serial_device_enumerator_linux.h b/device/serial/serial_device_enumerator_linux.h
index 71eee69..fe3c3b86 100644
--- a/device/serial/serial_device_enumerator_linux.h
+++ b/device/serial/serial_device_enumerator_linux.h
@@ -5,10 +5,8 @@
 #ifndef DEVICE_SERIAL_SERIAL_DEVICE_ENUMERATOR_LINUX_H_
 #define DEVICE_SERIAL_SERIAL_DEVICE_ENUMERATOR_LINUX_H_
 
-#include <libudev.h>
-
-#include "base/memory/scoped_ptr.h"
 #include "device/serial/serial_device_enumerator.h"
+#include "device/udev_linux/scoped_udev.h"
 
 namespace device {
 
@@ -22,11 +20,7 @@
   virtual mojo::Array<serial::DeviceInfoPtr> GetDevices() override;
 
  private:
-  struct UdevDeleter {
-    void operator()(udev* handle);
-  };
-
-  scoped_ptr<udev, UdevDeleter> udev_;
+  ScopedUdevPtr udev_;
 
   DISALLOW_COPY_AND_ASSIGN(SerialDeviceEnumeratorLinux);
 };
diff --git a/device/serial/serial_device_enumerator_mac.h b/device/serial/serial_device_enumerator_mac.h
index ad4d674..125b4bf 100644
--- a/device/serial/serial_device_enumerator_mac.h
+++ b/device/serial/serial_device_enumerator_mac.h
@@ -13,10 +13,10 @@
 class SerialDeviceEnumeratorMac : public SerialDeviceEnumerator {
  public:
   SerialDeviceEnumeratorMac();
-  virtual ~SerialDeviceEnumeratorMac();
+  ~SerialDeviceEnumeratorMac() override;
 
   // Implementation for SerialDeviceEnumerator.
-  virtual mojo::Array<serial::DeviceInfoPtr> GetDevices() override;
+  mojo::Array<serial::DeviceInfoPtr> GetDevices() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(SerialDeviceEnumeratorMac);
diff --git a/device/serial/serial_io_handler_posix.h b/device/serial/serial_io_handler_posix.h
index 7a6d97cb..aacd883 100644
--- a/device/serial/serial_io_handler_posix.h
+++ b/device/serial/serial_io_handler_posix.h
@@ -14,21 +14,21 @@
                              public base::MessageLoopForIO::Watcher {
  protected:
   // SerialIoHandler impl.
-  virtual void ReadImpl() override;
-  virtual void WriteImpl() override;
-  virtual void CancelReadImpl() override;
-  virtual void CancelWriteImpl() override;
-  virtual bool Flush() const override;
-  virtual serial::DeviceControlSignalsPtr GetControlSignals() const override;
-  virtual bool SetControlSignals(
+  void ReadImpl() override;
+  void WriteImpl() override;
+  void CancelReadImpl() override;
+  void CancelWriteImpl() override;
+  bool Flush() const override;
+  serial::DeviceControlSignalsPtr GetControlSignals() const override;
+  bool SetControlSignals(
       const serial::HostControlSignals& control_signals) override;
-  virtual bool ConfigurePort(const serial::ConnectionOptions& options) override;
-  virtual serial::ConnectionInfoPtr GetPortInfo() const override;
-  virtual void RequestAccess(
+  bool ConfigurePort(const serial::ConnectionOptions& options) override;
+  serial::ConnectionInfoPtr GetPortInfo() const override;
+  void RequestAccess(
       const std::string& port,
       scoped_refptr<base::MessageLoopProxy> file_message_loop,
       scoped_refptr<base::MessageLoopProxy> ui_message_loop) override;
-  virtual bool PostOpen() override;
+  bool PostOpen() override;
 
  private:
   friend class SerialIoHandler;
@@ -36,11 +36,11 @@
   SerialIoHandlerPosix(
       scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
       scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop);
-  virtual ~SerialIoHandlerPosix();
+  ~SerialIoHandlerPosix() override;
 
   // base::MessageLoopForIO::Watcher implementation.
-  virtual void OnFileCanWriteWithoutBlocking(int fd) override;
-  virtual void OnFileCanReadWithoutBlocking(int fd) override;
+  void OnFileCanWriteWithoutBlocking(int fd) override;
+  void OnFileCanReadWithoutBlocking(int fd) override;
 
   void EnsureWatchingReads();
   void EnsureWatchingWrites();
diff --git a/device/serial/serial_service_impl.h b/device/serial/serial_service_impl.h
index 796a1d4..ea48e46 100644
--- a/device/serial/serial_service_impl.h
+++ b/device/serial/serial_service_impl.h
@@ -21,7 +21,7 @@
       scoped_refptr<SerialConnectionFactory> connection_factory);
   SerialServiceImpl(scoped_refptr<SerialConnectionFactory> connection_factory,
                     scoped_ptr<SerialDeviceEnumerator> device_enumerator);
-  virtual ~SerialServiceImpl();
+  ~SerialServiceImpl() override;
 
   static void Create(scoped_refptr<base::MessageLoopProxy> io_message_loop,
                      scoped_refptr<base::MessageLoopProxy> ui_message_loop,
@@ -33,14 +33,14 @@
       mojo::InterfaceRequest<serial::SerialService> request);
 
   // mojo::InterfaceImpl<SerialService> overrides.
-  virtual void GetDevices(const mojo::Callback<
-      void(mojo::Array<serial::DeviceInfoPtr>)>& callback) override;
-  virtual void Connect(
-      const mojo::String& path,
-      serial::ConnectionOptionsPtr options,
-      mojo::InterfaceRequest<serial::Connection> connection_request,
-      mojo::InterfaceRequest<serial::DataSink> sink,
-      mojo::InterfaceRequest<serial::DataSource> source) override;
+  void GetDevices(
+      const mojo::Callback<void(mojo::Array<serial::DeviceInfoPtr>)>& callback)
+      override;
+  void Connect(const mojo::String& path,
+               serial::ConnectionOptionsPtr options,
+               mojo::InterfaceRequest<serial::Connection> connection_request,
+               mojo::InterfaceRequest<serial::DataSink> sink,
+               mojo::InterfaceRequest<serial::DataSource> source) override;
 
  private:
   SerialDeviceEnumerator* GetDeviceEnumerator();
diff --git a/device/serial/serial_service_unittest.cc b/device/serial/serial_service_unittest.cc
index 24558ae0..489d88e 100644
--- a/device/serial/serial_service_unittest.cc
+++ b/device/serial/serial_service_unittest.cc
@@ -17,7 +17,7 @@
 namespace {
 
 class FakeSerialDeviceEnumerator : public SerialDeviceEnumerator {
-  virtual mojo::Array<serial::DeviceInfoPtr> GetDevices() override {
+  mojo::Array<serial::DeviceInfoPtr> GetDevices() override {
     mojo::Array<serial::DeviceInfoPtr> devices(1);
     devices[0] = serial::DeviceInfo::New();
     devices[0]->path = "device";
@@ -27,13 +27,13 @@
 
 class FailToOpenIoHandler : public TestSerialIoHandler {
  public:
-  virtual void Open(const std::string& port,
-                    const OpenCompleteCallback& callback) override {
+  void Open(const std::string& port,
+            const OpenCompleteCallback& callback) override {
     callback.Run(false);
   }
 
  protected:
-  virtual ~FailToOpenIoHandler() {}
+  ~FailToOpenIoHandler() override {}
 };
 
 }  // namespace
@@ -47,7 +47,7 @@
     StopMessageLoop();
   }
 
-  virtual void OnConnectionError() override {
+  void OnConnectionError() override {
     StopMessageLoop();
     EXPECT_TRUE(expecting_error_);
   }
diff --git a/device/serial/test_serial_io_handler.h b/device/serial/test_serial_io_handler.h
index 3633555..dfa27dbf 100644
--- a/device/serial/test_serial_io_handler.h
+++ b/device/serial/test_serial_io_handler.h
@@ -20,18 +20,17 @@
   static scoped_refptr<SerialIoHandler> Create();
 
   // SerialIoHandler overrides.
-  virtual void Open(const std::string& port,
-                    const OpenCompleteCallback& callback) override;
-  virtual bool ConfigurePort(const serial::ConnectionOptions& options) override;
-  virtual void ReadImpl() override;
-  virtual void CancelReadImpl() override;
-  virtual void WriteImpl() override;
-  virtual void CancelWriteImpl() override;
-  virtual serial::DeviceControlSignalsPtr GetControlSignals() const override;
-  virtual serial::ConnectionInfoPtr GetPortInfo() const override;
-  virtual bool Flush() const override;
-  virtual bool SetControlSignals(
-      const serial::HostControlSignals& signals) override;
+  void Open(const std::string& port,
+            const OpenCompleteCallback& callback) override;
+  bool ConfigurePort(const serial::ConnectionOptions& options) override;
+  void ReadImpl() override;
+  void CancelReadImpl() override;
+  void WriteImpl() override;
+  void CancelWriteImpl() override;
+  serial::DeviceControlSignalsPtr GetControlSignals() const override;
+  serial::ConnectionInfoPtr GetPortInfo() const override;
+  bool Flush() const override;
+  bool SetControlSignals(const serial::HostControlSignals& signals) override;
 
   serial::ConnectionInfo* connection_info() { return &info_; }
   serial::DeviceControlSignals* device_control_signals() {
@@ -47,7 +46,7 @@
   }
 
  protected:
-  virtual ~TestSerialIoHandler();
+  ~TestSerialIoHandler() override;
 
  private:
   bool opened_;
diff --git a/device/test/usb_test_gadget_impl.cc b/device/test/usb_test_gadget_impl.cc
index 5fa8e9f..d2272df 100644
--- a/device/test/usb_test_gadget_impl.cc
+++ b/device/test/usb_test_gadget_impl.cc
@@ -64,14 +64,14 @@
 
 class UsbTestGadgetImpl : public UsbTestGadget {
  public:
-  virtual ~UsbTestGadgetImpl();
+  ~UsbTestGadgetImpl() override;
 
-  virtual bool Unclaim() override;
-  virtual bool Disconnect() override;
-  virtual bool Reconnect() override;
-  virtual bool SetType(Type type) override;
-  virtual UsbDevice* GetDevice() const override;
-  virtual std::string GetSerialNumber() const override;
+  bool Unclaim() override;
+  bool Disconnect() override;
+  bool Reconnect() override;
+  bool SetType(Type type) override;
+  UsbDevice* GetDevice() const override;
+  std::string GetSerialNumber() const override;
 
  protected:
   UsbTestGadgetImpl();
@@ -93,13 +93,13 @@
   class Delegate : public net::URLFetcherDelegate {
    public:
     Delegate() {}
-    virtual ~Delegate() {}
+    ~Delegate() override {}
 
     void WaitForCompletion() {
       run_loop_.Run();
     }
 
-    virtual void OnURLFetchComplete(const net::URLFetcher* source) override {
+    void OnURLFetchComplete(const net::URLFetcher* source) override {
       run_loop_.Quit();
     }
 
diff --git a/device/udev_linux/BUILD.gn b/device/udev_linux/BUILD.gn
index 917a7e59..a32319b 100644
--- a/device/udev_linux/BUILD.gn
+++ b/device/udev_linux/BUILD.gn
@@ -7,8 +7,7 @@
 if (use_udev) {
   source_set("udev_linux") {
     sources = [
-      "udev.cc",
-      "udev.h",
+      "scoped_udev.h",
     ]
 
     deps = [
diff --git a/device/udev_linux/udev.h b/device/udev_linux/scoped_udev.h
similarity index 62%
rename from device/udev_linux/udev.h
rename to device/udev_linux/scoped_udev.h
index cffb6723..54df387 100644
--- a/device/udev_linux/udev.h
+++ b/device/udev_linux/scoped_udev.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_UDEV_LINUX_UDEV_H_
-#define DEVICE_UDEV_LINUX_UDEV_H_
+#ifndef DEVICE_UDEV_LINUX_SCOPED_UDEV_H_
+#define DEVICE_UDEV_LINUX_SCOPED_UDEV_H_
 
 #include <libudev.h>
 
@@ -16,16 +16,24 @@
 namespace device {
 
 struct UdevDeleter {
-  void operator()(udev* dev) const;
+  void operator()(udev* dev) const {
+    udev_unref(dev);
+  }
 };
 struct UdevEnumerateDeleter {
-  void operator()(udev_enumerate* enumerate) const;
+  void operator()(udev_enumerate* enumerate) const {
+    udev_enumerate_unref(enumerate);
+  }
 };
 struct UdevDeviceDeleter {
-  void operator()(udev_device* device) const;
+  void operator()(udev_device* device) const {
+    udev_device_unref(device);
+  }
 };
 struct UdevMonitorDeleter {
-  void operator()(udev_monitor* monitor) const;
+  void operator()(udev_monitor* monitor) const {
+    udev_monitor_unref(monitor);
+  }
 };
 
 typedef scoped_ptr<udev, UdevDeleter> ScopedUdevPtr;
@@ -35,4 +43,4 @@
 
 }  // namespace device
 
-#endif  // DEVICE_UDEV_LINUX_UDEV_H_
+#endif  // DEVICE_UDEV_LINUX_SCOPED_UDEV_H_
diff --git a/device/udev_linux/udev.cc b/device/udev_linux/udev.cc
deleted file mode 100644
index e10074b..0000000
--- a/device/udev_linux/udev.cc
+++ /dev/null
@@ -1,27 +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 <libudev.h>
-
-#include "device/udev_linux/udev.h"
-
-namespace device {
-
-void UdevDeleter::operator()(udev* dev) const {
-  udev_unref(dev);
-}
-
-void UdevEnumerateDeleter::operator()(udev_enumerate* enumerate) const {
-  udev_enumerate_unref(enumerate);
-}
-
-void UdevDeviceDeleter::operator()(udev_device* device) const {
-  udev_device_unref(device);
-}
-
-void UdevMonitorDeleter::operator()(udev_monitor* monitor) const {
-  udev_monitor_unref(monitor);
-}
-
-}  // namespace device
diff --git a/device/udev_linux/udev.gyp b/device/udev_linux/udev.gyp
index 6d142ac..cc434307 100644
--- a/device/udev_linux/udev.gyp
+++ b/device/udev_linux/udev.gyp
@@ -20,8 +20,7 @@
             '../..',
           ],
           'sources': [
-            'udev.cc',
-            'udev.h',
+            'scoped_udev.h',
           ],
         },
       ],
diff --git a/device/usb/usb_context.cc b/device/usb/usb_context.cc
index dac86fe8..cb8214f 100644
--- a/device/usb/usb_context.cc
+++ b/device/usb/usb_context.cc
@@ -20,10 +20,10 @@
 class UsbContext::UsbEventHandler : public base::PlatformThread::Delegate {
  public:
   explicit UsbEventHandler(libusb_context* context);
-  virtual ~UsbEventHandler();
+  ~UsbEventHandler() override;
 
   // base::PlatformThread::Delegate
-  virtual void ThreadMain() override;
+  void ThreadMain() override;
 
  private:
   base::subtle::Atomic32 running_;
diff --git a/device/usb/usb_context_unittest.cc b/device/usb/usb_context_unittest.cc
index e00062cc..e3fb017 100644
--- a/device/usb/usb_context_unittest.cc
+++ b/device/usb/usb_context_unittest.cc
@@ -20,7 +20,7 @@
         : UsbContext(context) {}
 
    private:
-    virtual ~UsbContextForTest() {}
+    ~UsbContextForTest() override {}
     DISALLOW_COPY_AND_ASSIGN(UsbContextForTest);
   };
 };
diff --git a/device/usb/usb_device_handle_impl.h b/device/usb/usb_device_handle_impl.h
index b92f779..4488ec9 100644
--- a/device/usb/usb_device_handle_impl.h
+++ b/device/usb/usb_device_handle_impl.h
@@ -33,50 +33,48 @@
 // UsbDeviceHandle class provides basic I/O related functionalities.
 class UsbDeviceHandleImpl : public UsbDeviceHandle {
  public:
-  virtual scoped_refptr<UsbDevice> GetDevice() const override;
-  virtual void Close() override;
-  virtual bool ClaimInterface(int interface_number) override;
-  virtual bool ReleaseInterface(int interface_number) override;
-  virtual bool SetInterfaceAlternateSetting(int interface_number,
-                                            int alternate_setting) override;
-  virtual bool ResetDevice() override;
-  virtual bool GetStringDescriptor(uint8 string_id,
-                                   base::string16* string) override;
+  scoped_refptr<UsbDevice> GetDevice() const override;
+  void Close() override;
+  bool ClaimInterface(int interface_number) override;
+  bool ReleaseInterface(int interface_number) override;
+  bool SetInterfaceAlternateSetting(int interface_number,
+                                    int alternate_setting) override;
+  bool ResetDevice() override;
+  bool GetStringDescriptor(uint8 string_id, base::string16* string) override;
 
-  virtual void ControlTransfer(UsbEndpointDirection direction,
-                               TransferRequestType request_type,
-                               TransferRecipient recipient,
-                               uint8 request,
-                               uint16 value,
-                               uint16 index,
-                               net::IOBuffer* buffer,
-                               size_t length,
-                               unsigned int timeout,
-                               const UsbTransferCallback& callback) override;
+  void ControlTransfer(UsbEndpointDirection direction,
+                       TransferRequestType request_type,
+                       TransferRecipient recipient,
+                       uint8 request,
+                       uint16 value,
+                       uint16 index,
+                       net::IOBuffer* buffer,
+                       size_t length,
+                       unsigned int timeout,
+                       const UsbTransferCallback& callback) override;
 
-  virtual void BulkTransfer(UsbEndpointDirection direction,
-                            uint8 endpoint,
-                            net::IOBuffer* buffer,
-                            size_t length,
-                            unsigned int timeout,
-                            const UsbTransferCallback& callback) override;
+  void BulkTransfer(UsbEndpointDirection direction,
+                    uint8 endpoint,
+                    net::IOBuffer* buffer,
+                    size_t length,
+                    unsigned int timeout,
+                    const UsbTransferCallback& callback) override;
 
-  virtual void InterruptTransfer(UsbEndpointDirection direction,
-                                 uint8 endpoint,
-                                 net::IOBuffer* buffer,
-                                 size_t length,
-                                 unsigned int timeout,
-                                 const UsbTransferCallback& callback) override;
+  void InterruptTransfer(UsbEndpointDirection direction,
+                         uint8 endpoint,
+                         net::IOBuffer* buffer,
+                         size_t length,
+                         unsigned int timeout,
+                         const UsbTransferCallback& callback) override;
 
-  virtual void IsochronousTransfer(
-      UsbEndpointDirection direction,
-      uint8 endpoint,
-      net::IOBuffer* buffer,
-      size_t length,
-      unsigned int packets,
-      unsigned int packet_length,
-      unsigned int timeout,
-      const UsbTransferCallback& callback) override;
+  void IsochronousTransfer(UsbEndpointDirection direction,
+                           uint8 endpoint,
+                           net::IOBuffer* buffer,
+                           size_t length,
+                           unsigned int packets,
+                           unsigned int packet_length,
+                           unsigned int timeout,
+                           const UsbTransferCallback& callback) override;
 
   PlatformUsbDeviceHandle handle() const { return handle_; }
 
@@ -89,7 +87,7 @@
                       PlatformUsbDeviceHandle handle,
                       const UsbConfigDescriptor& config);
 
-  virtual ~UsbDeviceHandleImpl();
+  ~UsbDeviceHandleImpl() override;
 
  private:
   class InterfaceClaimer;
diff --git a/device/usb/usb_device_impl.cc b/device/usb/usb_device_impl.cc
index 17e9c13..36ddfe7 100644
--- a/device/usb/usb_device_impl.cc
+++ b/device/usb/usb_device_impl.cc
@@ -26,7 +26,7 @@
 #endif  // defined(OS_CHROMEOS)
 
 #if defined(USE_UDEV)
-#include "device/udev_linux/udev.h"
+#include "device/udev_linux/scoped_udev.h"
 #endif  // defined(USE_UDEV)
 
 namespace device {
diff --git a/device/usb/usb_device_impl.h b/device/usb/usb_device_impl.h
index 2718998..e962c6da 100644
--- a/device/usb/usb_device_impl.h
+++ b/device/usb/usb_device_impl.h
@@ -36,12 +36,12 @@
       int interface_id,
       const base::Callback<void(bool success)>& callback) override;
 #endif  // OS_CHROMEOS
-  virtual scoped_refptr<UsbDeviceHandle> Open() override;
-  virtual bool Close(scoped_refptr<UsbDeviceHandle> handle) override;
-  virtual const UsbConfigDescriptor& GetConfiguration() override;
-  virtual bool GetManufacturer(base::string16* manufacturer) override;
-  virtual bool GetProduct(base::string16* product) override;
-  virtual bool GetSerialNumber(base::string16* serial_number) override;
+  scoped_refptr<UsbDeviceHandle> Open() override;
+  bool Close(scoped_refptr<UsbDeviceHandle> handle) override;
+  const UsbConfigDescriptor& GetConfiguration() override;
+  bool GetManufacturer(base::string16* manufacturer) override;
+  bool GetProduct(base::string16* product) override;
+  bool GetSerialNumber(base::string16* serial_number) override;
 
  protected:
   friend class UsbServiceImpl;
@@ -54,7 +54,7 @@
                 uint16 product_id,
                 uint32 unique_id);
 
-  virtual ~UsbDeviceImpl();
+  ~UsbDeviceImpl() override;
 
   // Called only by UsbService.
   void OnDisconnect();
diff --git a/device/usb/usb_service_impl.cc b/device/usb/usb_service_impl.cc
index e639870..215aba1 100644
--- a/device/usb/usb_service_impl.cc
+++ b/device/usb/usb_service_impl.cc
@@ -34,16 +34,15 @@
   explicit UsbServiceImpl(
       PlatformUsbContext context,
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
-  virtual ~UsbServiceImpl();
+  ~UsbServiceImpl() override;
 
  private:
   // device::UsbService implementation
-  virtual scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) override;
-  virtual void GetDevices(
-      std::vector<scoped_refptr<UsbDevice> >* devices) override;
+  scoped_refptr<UsbDevice> GetDeviceById(uint32 unique_id) override;
+  void GetDevices(std::vector<scoped_refptr<UsbDevice>>* devices) override;
 
   // base::MessageLoop::DestructionObserver implementation.
-  virtual void WillDestroyCurrentMessageLoop() override;
+  void WillDestroyCurrentMessageLoop() override;
 
   // Enumerate USB devices from OS and update devices_ map.
   void RefreshDevices();
diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn
index 2f66a2ed8..51da3925 100644
--- a/extensions/BUILD.gn
+++ b/extensions/BUILD.gn
@@ -195,6 +195,7 @@
     "browser/info_map_unittest.cc",
     "browser/lazy_background_task_queue_unittest.cc",
     "browser/management_policy_unittest.cc",
+    "browser/mojo/keep_alive_impl_unittest.cc",
     "browser/process_manager_unittest.cc",
     "browser/process_map_unittest.cc",
     "browser/quota_service_unittest.cc",
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 06ed4162..3fdd209 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -15,7 +15,7 @@
     "//components/keyed_service/content",
     "//components/keyed_service/core",
     "//components/pref_registry",
-    "//components/sessions",
+    "//components/sessions:sessions_content",
     "//components/web_cache/browser",
     "//components/web_modal",
     "//content/public/browser",
@@ -370,6 +370,7 @@
       "guest_view/mime_handler_view/mime_handler_view_constants.h",
       "guest_view/mime_handler_view/mime_handler_view_guest.h",
       "guest_view/mime_handler_view/mime_handler_view_guest.cc",
+      "guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc",
       "guest_view/mime_handler_view/mime_handler_view_guest_delegate.h",
       "guest_view/web_view/javascript_dialog_helper.cc",
       "guest_view/web_view/javascript_dialog_helper.h",
@@ -403,6 +404,10 @@
       "lazy_background_task_queue.h",
       "management_policy.cc",
       "management_policy.h",
+      "mojo/keep_alive_impl.cc",
+      "mojo/keep_alive_impl.h",
+      "mojo/stash_backend.cc",
+      "mojo/stash_backend.h",
       "pref_names.cc",
       "pref_names.h",
       "process_manager.cc",
@@ -422,8 +427,6 @@
       "script_execution_observer.h",
       "script_executor.cc",
       "script_executor.h",
-      "stash_backend.cc",
-      "stash_backend.h",
       "state_store.cc",
       "state_store.h",
       "suggest_permission_util.cc",
diff --git a/extensions/browser/PRESUBMIT.py b/extensions/browser/PRESUBMIT.py
index 7c237f6..689b8ad37 100644
--- a/extensions/browser/PRESUBMIT.py
+++ b/extensions/browser/PRESUBMIT.py
@@ -13,7 +13,7 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_chromeos_rel_swarming': set(['defaulttests']),
+      'linux_chromium_chromeos_rel': set(['defaulttests']),
     }
   }
 
diff --git a/extensions/browser/api/app_window/app_window_api.cc b/extensions/browser/api/app_window/app_window_api.cc
index c0b2401..d0e52f2b1 100644
--- a/extensions/browser/api/app_window/app_window_api.cc
+++ b/extensions/browser/api/app_window/app_window_api.cc
@@ -250,6 +250,8 @@
       const char* whitelist[] = {
 #if defined(OS_CHROMEOS)
         "B58B99751225318C7EB8CF4688B5434661083E07",  // http://crbug.com/410550
+        "06BE211D5F014BAB34BC22D9DDA09C63A81D828E",  // http://crbug.com/425539
+        "F94EE6AB36D6C6588670B2B01EB65212D9C64E33",
 #endif
         "0F42756099D914A026DADFA182871C015735DD95",  // http://crbug.com/323773
         "2D22CDB6583FD0A13758AEBE8B15E45208B4E9A7",
diff --git a/extensions/browser/api/bluetooth/bluetooth_api.cc b/extensions/browser/api/bluetooth/bluetooth_api.cc
index c59a084..2e1e4bc7 100644
--- a/extensions/browser/api/bluetooth/bluetooth_api.cc
+++ b/extensions/browser/api/bluetooth/bluetooth_api.cc
@@ -9,7 +9,6 @@
 #include "base/bind_helpers.h"
 #include "base/lazy_instance.h"
 #include "base/memory/ref_counted.h"
-#include "base/profiler/scoped_profile.h"
 #include "content/public/browser/browser_thread.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_device.h"
@@ -86,10 +85,6 @@
 }
 
 void BluetoothAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("BluetoothAPI::OnListenerAdded"));
-
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (event_router()->IsBluetoothSupported())
     event_router()->OnListenerAdded();
diff --git a/extensions/browser/api/capture_web_contents_function.cc b/extensions/browser/api/capture_web_contents_function.cc
index 9fbce6b..a888284deb 100644
--- a/extensions/browser/api/capture_web_contents_function.cc
+++ b/extensions/browser/api/capture_web_contents_function.cc
@@ -76,12 +76,10 @@
   gfx::Size bitmap_size = view_size;
   const gfx::NativeView native_view = view->GetNativeView();
   gfx::Screen* const screen = gfx::Screen::GetScreenFor(native_view);
-  if (screen->IsDIPEnabled()) {
-    const float scale =
-        screen->GetDisplayNearestWindow(native_view).device_scale_factor();
-    if (scale > 1.0f)
-      bitmap_size = gfx::ToCeiledSize(gfx::ScaleSize(view_size, scale));
-  }
+  const float scale =
+      screen->GetDisplayNearestWindow(native_view).device_scale_factor();
+  if (scale > 1.0f)
+    bitmap_size = gfx::ToCeiledSize(gfx::ScaleSize(view_size, scale));
 
   host->CopyFromBackingStore(
       gfx::Rect(view_size),
diff --git a/extensions/browser/api/device_permissions_manager.cc b/extensions/browser/api/device_permissions_manager.cc
index a005adb..e0b0686 100644
--- a/extensions/browser/api/device_permissions_manager.cc
+++ b/extensions/browser/api/device_permissions_manager.cc
@@ -381,4 +381,12 @@
   return new DevicePermissionsManager(context);
 }
 
+BrowserContext* DevicePermissionsManagerFactory::GetBrowserContextToUse(
+    BrowserContext* context) const {
+  // Return the original (possibly off-the-record) browser context so that a
+  // separate instance of the DevicePermissionsManager is used in incognito
+  // mode. The parent class's implemenation returns NULL.
+  return context;
+}
+
 }  // namespace extensions
diff --git a/extensions/browser/api/device_permissions_manager.h b/extensions/browser/api/device_permissions_manager.h
index 246017d..dea9b13 100644
--- a/extensions/browser/api/device_permissions_manager.h
+++ b/extensions/browser/api/device_permissions_manager.h
@@ -142,6 +142,8 @@
   // BrowserContextKeyedServiceFactory
   KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
+  virtual content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
 
   DISALLOW_COPY_AND_ASSIGN(DevicePermissionsManagerFactory);
 };
diff --git a/extensions/browser/api/system_info/system_info_api.cc b/extensions/browser/api/system_info/system_info_api.cc
index 3a1c1b5f..a5b85bf 100644
--- a/extensions/browser/api/system_info/system_info_api.cc
+++ b/extensions/browser/api/system_info/system_info_api.cc
@@ -10,7 +10,6 @@
 #include "base/lazy_instance.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/singleton.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "components/storage_monitor/removable_storage_observer.h"
@@ -238,10 +237,6 @@
 }
 
 void SystemInfoAPI::OnListenerAdded(const EventListenerInfo& details) {
-  // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-  tracked_objects::ScopedProfile tracking_profile(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION("SystemInfoAPI::OnListenerAdded"));
-
   if (IsSystemStorageEvent(details.event_name)) {
     StorageMonitor::GetInstance()->EnsureInitialized(
         base::Bind(&AddEventListener, details.event_name));
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index a188447..c1e8f9d3 100644
--- a/extensions/browser/api/web_request/web_request_api.cc
+++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -2213,8 +2213,9 @@
       ipc_sender.get() ? ipc_sender->render_process_id() : -1;
 
   const Extension* extension =
-      extension_info_map()->extensions().GetByID(extension_id());
-  std::string extension_name = extension ? extension->name() : extension_id();
+      extension_info_map()->extensions().GetByID(extension_id_safe());
+  std::string extension_name =
+      extension ? extension->name() : extension_id_safe();
 
   bool is_web_view_guest = webview_instance_id != 0;
   // We check automatically whether the extension has the 'webRequest'
@@ -2244,7 +2245,7 @@
 
   bool success =
       ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
-          profile_id(), extension_id(), extension_name,
+          profile_id(), extension_id_safe(), extension_name,
           event_name, sub_event_name, filter, extra_info_spec,
           embedder_process_id, webview_instance_id, ipc_sender_weak());
   EXTENSION_FUNCTION_VALIDATE(success);
@@ -2269,7 +2270,7 @@
   error_ = error;
   ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
       profile_id(),
-      extension_id(),
+      extension_id_safe(),
       event_name,
       sub_event_name,
       request_id,
@@ -2296,9 +2297,9 @@
 
     if (!value->empty()) {
       base::Time install_time =
-          extension_info_map()->GetInstallTime(extension_id());
+          extension_info_map()->GetInstallTime(extension_id_safe());
       response.reset(new ExtensionWebRequestEventRouter::EventResponse(
-          extension_id(), install_time));
+          extension_id_safe(), install_time));
     }
 
     if (value->HasKey("cancel")) {
@@ -2421,7 +2422,7 @@
   }
 
   ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
-      profile_id(), extension_id(), event_name, sub_event_name, request_id,
+      profile_id(), extension_id_safe(), event_name, sub_event_name, request_id,
       response.release());
 
   return true;
@@ -2445,7 +2446,7 @@
   // Post warning message.
   WarningSet warnings;
   warnings.insert(
-      Warning::CreateRepeatedCacheFlushesWarning(extension_id()));
+      Warning::CreateRepeatedCacheFlushesWarning(extension_id_safe()));
   BrowserThread::PostTask(
       BrowserThread::UI,
       FROM_HERE,
diff --git a/extensions/browser/api/web_request/web_request_api.h b/extensions/browser/api/web_request/web_request_api.h
index 773cb587..f519409 100644
--- a/extensions/browser/api/web_request/web_request_api.h
+++ b/extensions/browser/api/web_request/web_request_api.h
@@ -13,6 +13,7 @@
 
 #include "base/memory/singleton.h"
 #include "base/memory/weak_ptr.h"
+#include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "content/public/common/resource_type.h"
 #include "extensions/browser/api/declarative/rules_registry.h"
@@ -488,8 +489,20 @@
   DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter);
 };
 
+class WebRequestInternalFunction : public SyncIOThreadExtensionFunction {
+ public:
+  WebRequestInternalFunction() {}
+
+ protected:
+  ~WebRequestInternalFunction() override {}
+
+  const std::string& extension_id_safe() const {
+    return extension() ? extension_id() : base::EmptyString();
+  }
+};
+
 class WebRequestInternalAddEventListenerFunction
-    : public SyncIOThreadExtensionFunction {
+    : public WebRequestInternalFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener",
                              WEBREQUESTINTERNAL_ADDEVENTLISTENER)
@@ -502,7 +515,7 @@
 };
 
 class WebRequestInternalEventHandledFunction
-    : public SyncIOThreadExtensionFunction {
+    : public WebRequestInternalFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled",
                              WEBREQUESTINTERNAL_EVENTHANDLED)
@@ -526,7 +539,7 @@
 };
 
 class WebRequestHandlerBehaviorChangedFunction
-    : public SyncIOThreadExtensionFunction {
+    : public WebRequestInternalFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged",
                              WEBREQUEST_HANDLERBEHAVIORCHANGED)
diff --git a/extensions/browser/api/web_request/web_request_api_helpers.cc b/extensions/browser/api/web_request/web_request_api_helpers.cc
index 680a953..825b0bd 100644
--- a/extensions/browser/api/web_request/web_request_api_helpers.cc
+++ b/extensions/browser/api/web_request/web_request_api_helpers.cc
@@ -1206,9 +1206,11 @@
 
   extensions::RuntimeData* runtime_data =
       extensions::ExtensionSystem::Get(browser_context)->runtime_data();
-  if (runtime_data->HasUsedWebRequest(extension.get()))
-    return;
-  runtime_data->SetHasUsedWebRequest(extension.get(), true);
+  if (extension.get()) {
+    if (runtime_data->HasUsedWebRequest(extension.get()))
+      return;
+    runtime_data->SetHasUsedWebRequest(extension.get(), true);
+  }
 
   for (content::RenderProcessHost::iterator it =
            content::RenderProcessHost::AllHostsIterator();
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc
index d3fcc2d..d006d1e 100644
--- a/extensions/browser/event_router.cc
+++ b/extensions/browser/event_router.cc
@@ -9,7 +9,6 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
-#include "base/profiler/scoped_profile.h"
 #include "base/stl_util.h"
 #include "base/values.h"
 #include "content/public/browser/child_process_security_policy.h"
@@ -238,13 +237,8 @@
                                   listener->GetBrowserContext());
   std::string base_event_name = GetBaseEventName(listener->event_name());
   ObserverMap::iterator observer = observers_.find(base_event_name);
-  if (observer != observers_.end()) {
-    // TODO(vadimt): Remove ScopedProfile below once crbug.com/417106 is fixed.
-    tracked_objects::ScopedProfile tracking_profile(
-        FROM_HERE_WITH_EXPLICIT_FUNCTION(
-            "EventRouter_OnListenerAdded_ObserverCall"));
+  if (observer != observers_.end())
     observer->second->OnListenerAdded(details);
-  }
 }
 
 void EventRouter::OnListenerRemoved(const EventListener* listener) {
diff --git a/extensions/browser/extension_function.h b/extensions/browser/extension_function.h
index f4ffaa27..2a933ab 100644
--- a/extensions/browser/extension_function.h
+++ b/extensions/browser/extension_function.h
@@ -218,7 +218,14 @@
     extension_ = extension;
   }
   const extensions::Extension* extension() const { return extension_.get(); }
-  const std::string& extension_id() const { return extension_->id(); }
+  const std::string& extension_id() const {
+    DCHECK(extension())
+        << "extension_id() called without an Extension. If " << name()
+        << " is allowed to be called without any Extension then you should "
+        << "check extension() first. If not, there is a bug in the Extension "
+        << "platform, so page somebody in extensions/OWNERS";
+    return extension_->id();
+  }
 
   void set_request_id(int request_id) { request_id_ = request_id; }
   int request_id() { return request_id_; }
diff --git a/extensions/browser/extension_function_dispatcher.cc b/extensions/browser/extension_function_dispatcher.cc
index f9bbec5..5edb3ec 100644
--- a/extensions/browser/extension_function_dispatcher.cc
+++ b/extensions/browser/extension_function_dispatcher.cc
@@ -229,8 +229,6 @@
     const ExtensionHostMsg_Request_Params& params) {
   const Extension* extension =
       extension_info_map->extensions().GetByID(params.extension_id);
-  if (!extension)
-    return;
 
   ExtensionFunction::ResponseCallback callback(
       base::Bind(&IOThreadResponseCallback, ipc_sender, routing_id,
@@ -255,12 +253,21 @@
   }
   function_io->set_ipc_sender(ipc_sender, routing_id);
   function_io->set_extension_info_map(extension_info_map);
-  function->set_include_incognito(
-      extension_info_map->IsIncognitoEnabled(extension->id()));
+  if (extension) {
+    function->set_include_incognito(
+        extension_info_map->IsIncognitoEnabled(extension->id()));
+  }
 
   if (!CheckPermissions(function.get(), params, callback))
     return;
 
+  if (!extension) {
+    // Skip all of the UMA, quota, event page, activity logging stuff if there
+    // isn't an extension, e.g. if the function call was from WebUI.
+    function->Run()->Execute();
+    return;
+  }
+
   QuotaService* quota = extension_info_map->GetQuotaService();
   std::string violation_error = quota->Assess(extension->id(),
                                               function.get(),
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index ed68aed6..67c2ada3 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -966,6 +966,7 @@
   BOOKMARKMANAGERPRIVATE_SETVERSION,
   FILESYSTEMPROVIDER_NOTIFY,
   USB_GETUSERSELECTEDDEVICES,
+  INPUTMETHODPRIVATE_GETINPUTMETHODCONFIG,
   // Last entry: Add new entries above and ensure to update
   // tools/metrics/histograms/histograms.xml.
   ENUM_BOUNDARY
diff --git a/extensions/browser/guest_view/guest_view_base.cc b/extensions/browser/guest_view/guest_view_base.cc
index 2fbbf60..859d205 100644
--- a/extensions/browser/guest_view/guest_view_base.cc
+++ b/extensions/browser/guest_view/guest_view_base.cc
@@ -91,9 +91,10 @@
   void Destroy() {
     if (destroyed_)
       return;
+
     destroyed_ = true;
+    guest_->EmbedderWillBeDestroyed();
     guest_->embedder_web_contents_ = NULL;
-    guest_->EmbedderDestroyed();
     guest_->Destroy();
   }
 
diff --git a/extensions/browser/guest_view/guest_view_base.h b/extensions/browser/guest_view/guest_view_base.h
index e8b0fa80..5a176a4 100644
--- a/extensions/browser/guest_view/guest_view_base.h
+++ b/extensions/browser/guest_view/guest_view_base.h
@@ -87,12 +87,11 @@
   // completed loading.
   virtual void DidStopLoading() {}
 
-  // This method is called when the guest's embedder WebContents has been
-  // destroyed and the guest will be destroyed shortly.
-  //
-  // This gives the derived class an opportunity to perform some cleanup prior
-  // to destruction.
-  virtual void EmbedderDestroyed() {}
+  // This method is called before the embedder is destroyed.
+  // |embedder_web_contents_| should still be valid during this call. This
+  // allows the derived class to perform some cleanup related to the embedder
+  // web contents.
+  virtual void EmbedderWillBeDestroyed() {}
 
   // This method is called when the guest WebContents has been destroyed. This
   // object will be destroyed after this call returns.
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
index ab25a52..9230f34c 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -147,6 +147,14 @@
     delegate_->ChangeZoom(zoom_in);
 }
 
+bool MimeHandlerViewGuest::HandleContextMenu(
+    const content::ContextMenuParams& params) {
+  if (delegate_)
+    return delegate_->HandleContextMenu(web_contents(), params);
+
+  return false;
+}
+
 void MimeHandlerViewGuest::HandleKeyboardEvent(
     WebContents* source,
     const content::NativeWebKeyboardEvent& event) {
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
index d788cb5..f678d4e 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -10,6 +10,7 @@
 
 namespace content {
 class WebContents;
+struct ContextMenuParams;
 }  // namespace content
 
 namespace extensions {
@@ -47,6 +48,7 @@
 
   // WebContentsDelegate implementation.
   void ContentsZoomChange(bool zoom_in) override;
+  bool HandleContextMenu(const content::ContextMenuParams& params) override;
   void HandleKeyboardEvent(
       content::WebContents* source,
       const content::NativeWebKeyboardEvent& event) override;
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc
new file mode 100644
index 0000000..63b81b8a7
--- /dev/null
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc
@@ -0,0 +1,15 @@
+// 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 "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
+
+namespace extensions {
+
+bool MimeHandlerViewGuestDelegate::HandleContextMenu(
+    content::WebContents* web_contents,
+    const content::ContextMenuParams& params) {
+  return false;
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h
index 53e8cc71..b9a6fe3 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h
@@ -9,6 +9,7 @@
 
 namespace content {
 class WebContents;
+struct ContextMenuParams;
 }  // namespace content
 
 namespace extensions {
@@ -24,6 +25,10 @@
   // Attaches helpers upon initializing the WebContents.
   virtual void AttachHelpers() {}
 
+  // Handles context menu, or returns false if unhandled.
+  virtual bool HandleContextMenu(content::WebContents* web_contents,
+                                 const content::ContextMenuParams& params);
+
   // Request to change the zoom level of the top level page containing
   // this view.
   virtual void ChangeZoom(bool zoom_in) {}
diff --git a/extensions/browser/guest_view/web_view/web_view_apitest.cc b/extensions/browser/guest_view/web_view/web_view_apitest.cc
index a30b78a..574e334 100644
--- a/extensions/browser/guest_view/web_view/web_view_apitest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_apitest.cc
@@ -140,8 +140,9 @@
 
   embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
 
-  ASSERT_TRUE(extension_system_->LoadApp(test_data_dir));
-  extension_system_->LaunchApp();
+  const Extension* extension = extension_system_->LoadApp(test_data_dir);
+  ASSERT_TRUE(extension);
+  extension_system_->LaunchApp(extension->id());
 
   ExtensionTestMessageListener launch_listener("LAUNCHED", false);
   ASSERT_TRUE(launch_listener.WaitUntilSatisfied());
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 ab95833..50b8dbcb 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -349,7 +349,10 @@
       new GuestViewBase::Event(webview::kEventLoadStop, args.Pass()));
 }
 
-void WebViewGuest::EmbedderDestroyed() {
+void WebViewGuest::EmbedderWillBeDestroyed() {
+  if (web_view_guest_delegate_)
+    web_view_guest_delegate_->OnEmbedderWillBeDestroyed();
+
   content::BrowserThread::PostTask(
       content::BrowserThread::IO,
       FROM_HERE,
@@ -377,8 +380,15 @@
   // WebContents::GetRenderWidgetHostView will return the RWHV of an
   // interstitial page if one is showing at this time. We only want opacity
   // to apply to web pages.
-  web_contents()->GetRenderViewHost()->GetView()->
-      SetBackgroundOpaque(guest_opaque_);
+  if (guest_opaque_) {
+    web_contents()
+        ->GetRenderViewHost()
+        ->GetView()
+        ->SetBackgroundColorToDefault();
+  } else {
+    web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
+        SK_ColorTRANSPARENT);
+  }
   if (web_view_guest_delegate_)
     web_view_guest_delegate_->OnGuestReady();
 }
@@ -1032,7 +1042,15 @@
   if (!web_contents()->GetRenderViewHost()->GetView())
     return;
 
-  web_contents()->GetRenderViewHost()->GetView()->SetBackgroundOpaque(!allow);
+  if (guest_opaque_) {
+    web_contents()
+        ->GetRenderViewHost()
+        ->GetView()
+        ->SetBackgroundColorToDefault();
+  } else {
+    web_contents()->GetRenderViewHost()->GetView()->SetBackgroundColor(
+        SK_ColorTRANSPARENT);
+  }
 }
 
 bool WebViewGuest::LoadDataWithBaseURL(const std::string& data_url,
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h
index 645a4e7..7225ff8 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.h
+++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -94,7 +94,7 @@
   void DidAttachToEmbedder() override;
   void DidInitialize() override;
   void DidStopLoading() override;
-  void EmbedderDestroyed() override;
+  void EmbedderWillBeDestroyed() override;
   void GuestDestroyed() override;
   void GuestReady() override;
   void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
diff --git a/extensions/browser/guest_view/web_view/web_view_guest_delegate.h b/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
index fa9a5516..5dee1c48 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
+++ b/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
@@ -56,6 +56,9 @@
   // Called immediately after the guest WebContents is ready.
   virtual void OnGuestReady() = 0;
 
+  // Called before the embedder is destroyed.
+  virtual void OnEmbedderWillBeDestroyed() = 0;
+
   // Called immediately after the guest WebContents has been destroyed.
   virtual void OnGuestDestroyed() = 0;
 
diff --git a/extensions/browser/mojo/keep_alive_impl.cc b/extensions/browser/mojo/keep_alive_impl.cc
new file mode 100644
index 0000000..4073ce1
--- /dev/null
+++ b/extensions/browser/mojo/keep_alive_impl.cc
@@ -0,0 +1,35 @@
+// 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 "extensions/browser/mojo/keep_alive_impl.h"
+
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/process_manager.h"
+
+namespace extensions {
+
+// static
+void KeepAliveImpl::Create(content::BrowserContext* context,
+                           const Extension* extension,
+                           mojo::InterfaceRequest<KeepAlive> request) {
+  mojo::BindToRequest(new KeepAliveImpl(context, extension), &request);
+}
+
+KeepAliveImpl::KeepAliveImpl(content::BrowserContext* context,
+                             const Extension* extension)
+    : context_(context), extension_(extension) {
+  ExtensionSystem* system = ExtensionSystem::Get(context_);
+  if (!system)
+    return;
+  system->process_manager()->IncrementLazyKeepaliveCount(extension_);
+}
+
+KeepAliveImpl::~KeepAliveImpl() {
+  ExtensionSystem* system = ExtensionSystem::Get(context_);
+  if (!system)
+    return;
+  system->process_manager()->DecrementLazyKeepaliveCount(extension_);
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/mojo/keep_alive_impl.h b/extensions/browser/mojo/keep_alive_impl.h
new file mode 100644
index 0000000..0544f958
--- /dev/null
+++ b/extensions/browser/mojo/keep_alive_impl.h
@@ -0,0 +1,41 @@
+// 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 EXTENSIONS_BROWSER_MOJO_KEEP_ALIVE_IMPL_H_
+#define EXTENSIONS_BROWSER_MOJO_KEEP_ALIVE_IMPL_H_
+
+#include "base/callback.h"
+#include "extensions/common/mojo/keep_alive.mojom.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace extensions {
+class Extension;
+
+// An RAII mojo service implementation for extension keep alives. This adds a
+// keep alive on construction and removes it on destruction.
+class KeepAliveImpl : public mojo::InterfaceImpl<KeepAlive> {
+ public:
+  // Create a keep alive for |extension| running in |context| and connect it to
+  // |request|. When the requester closes its pipe, the keep alive ends.
+  static void Create(content::BrowserContext* context,
+                     const Extension* extension,
+                     mojo::InterfaceRequest<KeepAlive> request);
+
+ private:
+  KeepAliveImpl(content::BrowserContext* context, const Extension* extension);
+  ~KeepAliveImpl() override;
+
+  content::BrowserContext* context_;
+  const Extension* extension_;
+
+  DISALLOW_COPY_AND_ASSIGN(KeepAliveImpl);
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_MOJO_KEEP_ALIVE_IMPL_H_
diff --git a/extensions/browser/mojo/keep_alive_impl_unittest.cc b/extensions/browser/mojo/keep_alive_impl_unittest.cc
new file mode 100644
index 0000000..eea8f83
--- /dev/null
+++ b/extensions/browser/mojo/keep_alive_impl_unittest.cc
@@ -0,0 +1,127 @@
+// 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 "extensions/browser/mojo/keep_alive_impl.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "content/public/browser/notification_service.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/extensions_test.h"
+#include "extensions/browser/mock_extension_system.h"
+#include "extensions/browser/process_manager.h"
+#include "extensions/browser/test_extensions_browser_client.h"
+#include "extensions/common/extension_builder.h"
+
+namespace extensions {
+
+namespace {
+
+class TestExtensionSystem : public MockExtensionSystem {
+ public:
+  explicit TestExtensionSystem(content::BrowserContext* context)
+      : MockExtensionSystem(context),
+        process_manager_(ProcessManager::Create(context)) {}
+
+  ProcessManager* process_manager() override { return process_manager_.get(); }
+
+ private:
+  scoped_ptr<ProcessManager> process_manager_;
+};
+
+}  // namespace
+
+class KeepAliveTest : public ExtensionsTest {
+ public:
+  KeepAliveTest()
+      : notification_service_(content::NotificationService::Create()) {}
+  ~KeepAliveTest() override {}
+
+  void SetUp() override {
+    ExtensionsTest::SetUp();
+    message_loop_.reset(new base::MessageLoop);
+    browser_client_.reset(new TestExtensionsBrowserClient(browser_context()));
+    browser_client_->set_extension_system_factory(&extension_system_factory_);
+    ExtensionsBrowserClient::Set(browser_client_.get());
+    extension_ =
+        ExtensionBuilder()
+            .SetManifest(
+                 DictionaryBuilder()
+                     .Set("name", "app")
+                     .Set("version", "1")
+                     .Set("manifest_version", 2)
+                     .Set("app",
+                          DictionaryBuilder().Set(
+                              "background",
+                              DictionaryBuilder().Set(
+                                  "scripts",
+                                  ListBuilder().Append("background.js")))))
+            .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
+            .Build();
+  }
+
+  void TearDown() override {
+    message_loop_.reset();
+    ExtensionsTest::TearDown();
+  }
+
+  void WaitUntilLazyKeepAliveChanges() {
+    int initial_keep_alive_count = GetKeepAliveCount();
+    while (GetKeepAliveCount() == initial_keep_alive_count) {
+      base::RunLoop().RunUntilIdle();
+    }
+  }
+
+  void CreateKeepAlive(mojo::InterfaceRequest<KeepAlive> request) {
+    KeepAliveImpl::Create(browser_context(), extension_.get(), request.Pass());
+  }
+
+  const Extension* extension() { return extension_.get(); }
+
+  int GetKeepAliveCount() {
+    return ExtensionSystem::Get(browser_context())
+        ->process_manager()
+        ->GetLazyKeepaliveCount(extension());
+  }
+
+ private:
+  scoped_ptr<base::MessageLoop> message_loop_;
+  MockExtensionSystemFactory<TestExtensionSystem> extension_system_factory_;
+  scoped_ptr<content::NotificationService> notification_service_;
+  scoped_refptr<const Extension> extension_;
+  scoped_ptr<TestExtensionsBrowserClient> browser_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(KeepAliveTest);
+};
+
+TEST_F(KeepAliveTest, Basic) {
+  mojo::InterfacePtr<KeepAlive> keep_alive;
+  CreateKeepAlive(mojo::GetProxy(&keep_alive));
+  EXPECT_EQ(1, GetKeepAliveCount());
+
+  keep_alive.reset();
+  WaitUntilLazyKeepAliveChanges();
+  EXPECT_EQ(0, GetKeepAliveCount());
+}
+
+TEST_F(KeepAliveTest, TwoKeepAlives) {
+  mojo::InterfacePtr<KeepAlive> keep_alive;
+  CreateKeepAlive(mojo::GetProxy(&keep_alive));
+  EXPECT_EQ(1, GetKeepAliveCount());
+
+  mojo::InterfacePtr<KeepAlive> other_keep_alive;
+  CreateKeepAlive(mojo::GetProxy(&other_keep_alive));
+  EXPECT_EQ(2, GetKeepAliveCount());
+
+  keep_alive.reset();
+  WaitUntilLazyKeepAliveChanges();
+  EXPECT_EQ(1, GetKeepAliveCount());
+
+  other_keep_alive.reset();
+  WaitUntilLazyKeepAliveChanges();
+  EXPECT_EQ(0, GetKeepAliveCount());
+}
+
+}  // namespace extensions
diff --git a/extensions/browser/stash_backend.cc b/extensions/browser/mojo/stash_backend.cc
similarity index 97%
rename from extensions/browser/stash_backend.cc
rename to extensions/browser/mojo/stash_backend.cc
index 793f76d..da4842d 100644
--- a/extensions/browser/stash_backend.cc
+++ b/extensions/browser/mojo/stash_backend.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/stash_backend.h"
+#include "extensions/browser/mojo/stash_backend.h"
 
 namespace extensions {
 
diff --git a/extensions/browser/stash_backend.h b/extensions/browser/mojo/stash_backend.h
similarity index 85%
rename from extensions/browser/stash_backend.h
rename to extensions/browser/mojo/stash_backend.h
index 33d5e5df..b90e43d 100644
--- a/extensions/browser/stash_backend.h
+++ b/extensions/browser/mojo/stash_backend.h
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_STASH_BACKEND_H_
-#define EXTENSIONS_BROWSER_STASH_BACKEND_H_
+#ifndef EXTENSIONS_BROWSER_MOJO_STASH_BACKEND_H_
+#define EXTENSIONS_BROWSER_MOJO_STASH_BACKEND_H_
 
 #include <vector>
 
 #include "base/memory/linked_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "extensions/common/stash.mojom.h"
+#include "extensions/common/mojo/stash.mojom.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 
 namespace extensions {
@@ -42,4 +42,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_STASH_BACKEND_H_
+#endif  // EXTENSIONS_BROWSER_MOJO_STASH_BACKEND_H_
diff --git a/extensions/browser/stash_backend_unittest.cc b/extensions/browser/mojo/stash_backend_unittest.cc
similarity index 98%
rename from extensions/browser/stash_backend_unittest.cc
rename to extensions/browser/mojo/stash_backend_unittest.cc
index 04c5233..0a0244b1 100644
--- a/extensions/browser/stash_backend_unittest.cc
+++ b/extensions/browser/mojo/stash_backend_unittest.cc
@@ -5,7 +5,7 @@
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "extensions/browser/stash_backend.h"
+#include "extensions/browser/mojo/stash_backend.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace extensions {
diff --git a/extensions/browser/updater/manifest_fetch_data.cc b/extensions/browser/updater/manifest_fetch_data.cc
index 1b813fe..2f73acb3 100644
--- a/extensions/browser/updater/manifest_fetch_data.cc
+++ b/extensions/browser/updater/manifest_fetch_data.cc
@@ -11,17 +11,31 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "extensions/common/extension.h"
 #include "net/base/escape.h"
 
+namespace extensions {
+
 namespace {
 
 // Maximum length of an extension manifest update check url, since it is a GET
 // request. We want to stay under 2K because of proxies, etc.
 const int kExtensionsManifestMaxURLSize = 2000;
 
-}  // namespace
+void AddMetricsToPing(std::string* ping_value,
+                      const ManifestFetchData::PingData* ping_data) {
+  *ping_value += "&e=" + std::string(ping_data->is_enabled ? "1" : "0");
+  if (!ping_data->is_enabled) {
+    // Add a dr=<number> param for each bit set in disable reasons.
+    for (int enum_value = 1; enum_value < Extension::DISABLE_REASON_LAST;
+         enum_value <<= 1) {
+      if (ping_data->disable_reasons & enum_value)
+        *ping_value += "&dr=" + base::IntToString(enum_value);
+    }
+  }
+}
 
-namespace extensions {
+}  // namespace
 
 ManifestFetchData::ManifestFetchData(const GURL& update_url,
                                      int request_id,
@@ -106,14 +120,13 @@
       parts.push_back(base::StringPrintf("brand=%s", brand_code_.c_str()));
 
     std::string ping_value;
-    pings_[id] = PingData(0, 0, false);
+    pings_[id] = PingData(0, 0, false, 0);
     if (ping_data) {
       if (ping_data->rollcall_days == kNeverPinged ||
           ping_data->rollcall_days > 0) {
         ping_value += "r=" + base::IntToString(ping_data->rollcall_days);
-        if (ping_mode_ == PING_WITH_METRICS) {
-          ping_value += "&e=" + std::string(ping_data->is_enabled ? "1" : "0");
-        }
+        if (ping_mode_ == PING_WITH_METRICS)
+          AddMetricsToPing(&ping_value, ping_data);
         pings_[id].rollcall_days = ping_data->rollcall_days;
         pings_[id].is_enabled = ping_data->is_enabled;
       }
diff --git a/extensions/browser/updater/manifest_fetch_data.h b/extensions/browser/updater/manifest_fetch_data.h
index a9f33555..8f33ab39 100644
--- a/extensions/browser/updater/manifest_fetch_data.h
+++ b/extensions/browser/updater/manifest_fetch_data.h
@@ -50,12 +50,24 @@
     // server's perspective.
     int rollcall_days;
     int active_days;
-    // Wether the extension is enabled or not.
+
+    // Whether the extension is enabled or not.
     bool is_enabled;
 
-    PingData() : rollcall_days(0), active_days(0), is_enabled(true) {}
-    PingData(int rollcall, int active, bool enabled)
-        : rollcall_days(rollcall), active_days(active), is_enabled(enabled) {}
+    // A bitmask of Extension::DisableReason's, which may contain one or more
+    // reasons why an extension is disabled.
+    int disable_reasons;
+
+    PingData()
+        : rollcall_days(0),
+          active_days(0),
+          is_enabled(true),
+          disable_reasons(0) {}
+    PingData(int rollcall, int active, bool enabled, int reasons)
+        : rollcall_days(rollcall),
+          active_days(active),
+          is_enabled(enabled),
+          disable_reasons(reasons) {}
   };
 
   ManifestFetchData(const GURL& update_url,
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index 42359cd4..d59b6e9 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -5,12 +5,6 @@
 import("//build/config/features.gni")
 import("//mojo/public/tools/bindings/mojom.gni")
 
-mojom("mojo") {
-  sources = [
-    "stash.mojom",
-  ]
-}
-
 # GYP version: extensions/extensions.gyp:extensions_common_constants
 source_set("common_constants") {
   sources = [
@@ -25,6 +19,16 @@
   }
 }
 
+if (enable_extensions) {
+
+mojom("mojo") {
+  sources = [
+    "mojo/keep_alive.mojom",
+    "mojo/stash.mojom",
+  ]
+}
+
+
 # GYP version: extensions/extensions.gyp:extensions_common
 source_set("common") {
   sources = [
@@ -60,7 +64,6 @@
     "extension.h",
     "extension_api.cc",
     "extension_api.h",
-    "extension_api_stub.cc",
     "extension_icon_set.cc",
     "extension_icon_set.h",
     "extension_l10n_util.cc",
@@ -225,7 +228,11 @@
     "//components/url_matcher",
     "//content/public/common",
     "//crypto",
+    "//device/bluetooth",
+    "//device/usb",
+    "//extensions/common/api",
     "//extensions/strings",
+    "//extensions:extensions_resources",
     "//ipc",
     "//net",
     "//third_party/icu",
@@ -237,40 +244,6 @@
     "//url",
   ]
 
-  if (enable_extensions) {
-    sources -= [
-      "extension_api_stub.cc",
-    ]
-
-    deps += [
-      "//device/bluetooth",
-      "//device/usb",
-      "//extensions/common/api",
-      "//extensions:extensions_resources",
-    ]
-  } else {
-    sources -= [
-      "api/bluetooth/bluetooth_manifest_data.cc",
-      "api/bluetooth/bluetooth_manifest_data.h",
-      "api/bluetooth/bluetooth_manifest_handler.cc",
-      "api/bluetooth/bluetooth_manifest_handler.h",
-      "api/bluetooth/bluetooth_manifest_permission.cc",
-      "api/bluetooth/bluetooth_manifest_permission.h",
-      "api/messaging/message.h",
-      "api/sockets/sockets_manifest_data.cc",
-      "api/sockets/sockets_manifest_data.h",
-      "api/sockets/sockets_manifest_handler.cc",
-      "api/sockets/sockets_manifest_handler.h",
-      "api/sockets/sockets_manifest_permission.cc",
-      "api/sockets/sockets_manifest_permission.h",
-      "extension_api.cc",
-      "manifest_handlers/externally_connectable.cc",
-      "manifest_handlers/externally_connectable.h",
-      "manifest_handlers/options_page_info.cc",
-      "manifest_handlers/options_page_info.h",
-    ]
-  }
-
   if (enable_nacl) {
     sources += [
       "manifest_handlers/nacl_modules_handler.cc",
@@ -284,3 +257,5 @@
     ]
   }
 }
+
+} # enable_extensions
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json
index 8f3a0ed..b535a37 100644
--- a/extensions/common/api/_permission_features.json
+++ b/extensions/common/api/_permission_features.json
@@ -52,6 +52,14 @@
         "F16F23C83C5F6DAD9B65A120448B34056DD80691",
         "0F585FB1D0FDFBEBCE1FEB5E9DFFB6DA476B8C9B"
       ]
+    },
+    {
+      "channel": "stable",
+      "extension_types": ["extension"],
+      "whitelist": [
+        "06BE211D5F014BAB34BC22D9DDA09C63A81D828E",  // http://crbug.com/425539
+        "F94EE6AB36D6C6588670B2B01EB65212D9C64E33"
+      ]
     }
   ],
   "app.window.shape": {
diff --git a/extensions/common/extension.h b/extensions/common/extension.h
index 668f52f..4c76478 100644
--- a/extensions/common/extension.h
+++ b/extensions/common/extension.h
@@ -28,6 +28,10 @@
 #include "ui/gfx/size.h"
 #include "url/gurl.h"
 
+#if !defined(ENABLE_EXTENSIONS)
+#error "Extensions must be enabled"
+#endif
+
 namespace base {
 class DictionaryValue;
 class Version;
diff --git a/extensions/common/extension_api_stub.cc b/extensions/common/extension_api_stub.cc
deleted file mode 100644
index 4b44f97..0000000
--- a/extensions/common/extension_api_stub.cc
+++ /dev/null
@@ -1,59 +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.
-
-// Stub methods to be used when extensions are disabled
-// i.e. ENABLE_EXTENSIONS is not defined
-
-#include "extensions/common/extension_api.h"
-
-#include "extensions/common/features/feature.h"
-#include "url/gurl.h"
-
-namespace extensions {
-
-// static
-ExtensionAPI* ExtensionAPI::GetSharedInstance() {
-  return NULL;
-}
-
-// static
-ExtensionAPI* ExtensionAPI::CreateWithDefaultConfiguration() {
-  return NULL;
-}
-
-Feature::Availability ExtensionAPI::IsAvailable(
-    const std::string& api_full_name,
-    const Extension* extension,
-    Feature::Context context,
-    const GURL& url) {
-  return Feature::CreateAvailability(Feature::NOT_PRESENT, "");
-}
-
-bool ExtensionAPI::IsAnyFeatureAvailableToContext(const Feature& api,
-                                                  const Extension* extension,
-                                                  Feature::Context context,
-                                                  const GURL& url) {
-  return false;
-}
-
-bool ExtensionAPI::IsAvailableInUntrustedContext(const std::string& full_name,
-                                                 const Extension* extension) {
-  return false;
-}
-
-bool ExtensionAPI::IsAvailableToWebUI(const std::string& name,
-                                      const GURL& url) {
-  return false;
-}
-
-const base::DictionaryValue* ExtensionAPI::GetSchema(
-    const std::string& full_name) {
-  return NULL;
-}
-
-Feature* ExtensionAPI::GetFeatureDependency(const std::string& name) {
-  return NULL;
-}
-
-}  // namespace extensions
diff --git a/extensions/common/mojo/keep_alive.mojom b/extensions/common/mojo/keep_alive.mojom
new file mode 100644
index 0000000..75b08b4
--- /dev/null
+++ b/extensions/common/mojo/keep_alive.mojom
@@ -0,0 +1,12 @@
+// 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.
+
+module extensions {
+
+// An RAII service for keep alives. While KeepAlive services for an extension
+// remain, the background page for that extension will remain alive.
+interface KeepAlive {
+};
+
+}
diff --git a/extensions/common/stash.mojom b/extensions/common/mojo/stash.mojom
similarity index 100%
rename from extensions/common/stash.mojom
rename to extensions/common/mojo/stash.mojom
diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc
index 0ad9601..936a8e22 100644
--- a/extensions/common/permissions/extensions_api_permissions.cc
+++ b/extensions/common/permissions/extensions_api_permissions.cc
@@ -51,6 +51,7 @@
       {APIPermission::kFullscreen, "app.window.fullscreen"},
       {APIPermission::kHid, "hid", APIPermissionInfo::kFlagNone,
        IDS_EXTENSION_PROMPT_WARNING_HID, PermissionMessage::kHid},
+      {APIPermission::kImeWindowEnabled, "app.window.ime"},
       {APIPermission::kOverrideEscFullscreen,
        "app.window.fullscreen.overrideEsc"},
       {APIPermission::kPower, "power"},
@@ -92,7 +93,6 @@
       {APIPermission::kWebView, "webview",
        APIPermissionInfo::kFlagCannotBeOptional},
       {APIPermission::kWindowShape, "app.window.shape"},
-      {APIPermission::kImeWindowEnabled, "app.window.ime"},
   };
 
   std::vector<APIPermissionInfo*> permissions;
diff --git a/extensions/common/switches.cc b/extensions/common/switches.cc
index 31f9d28..0a8cdd8 100644
--- a/extensions/common/switches.cc
+++ b/extensions/common/switches.cc
@@ -16,6 +16,10 @@
 const char kAllowLegacyExtensionManifests[] =
     "allow-legacy-extension-manifests";
 
+// Disables the App Info dialog from being launched from the chrome://extensions
+// page (reverts to the old-style permissions dialog instead).
+const char kDisableExtensionInfoDialog[] = "disable-extension-info-dialog";
+
 // Enables extension options to be embedded in chrome://extensions rather than
 // a new tab.
 const char kEmbeddedExtensionOptions[] = "embedded-extension-options";
@@ -42,9 +46,6 @@
 const char kEnableExtensionActionRedesign[] =
     "enable-extension-action-redesign";
 
-// Enables the App Info dialog to be launched from the chrome://extensions page.
-const char kEnableExtensionInfoDialog[] = "enable-extension-info-dialog";
-
 // Hack so that feature switch can work with about_flags. See
 // kEnableScriptsRequireAction.
 const char kEnableMimeHandlerView[] = "enable-mime-handler-view";
diff --git a/extensions/common/switches.h b/extensions/common/switches.h
index 196931f..cc68ed8f 100644
--- a/extensions/common/switches.h
+++ b/extensions/common/switches.h
@@ -13,13 +13,13 @@
 
 extern const char kAllowHTTPBackgroundPage[];
 extern const char kAllowLegacyExtensionManifests[];
+extern const char kDisableExtensionInfoDialog[];
 extern const char kEmbeddedExtensionOptions[];
 extern const char kEnableAppsShowOnFirstPaint[];
 extern const char kEnableAppWindowControls[];
 extern const char kEnableEmbeddedExtensionOptions[];
 extern const char kEnableExperimentalExtensionApis[];
 extern const char kEnableExtensionActionRedesign[];
-extern const char kEnableExtensionInfoDialog[];
 extern const char kEnableMimeHandlerView[];
 extern const char kEnableOverrideBookmarksUI[];
 extern const char kEnableRemoteAssistance[];
diff --git a/extensions/components/native_app_window/native_app_window_views.cc b/extensions/components/native_app_window/native_app_window_views.cc
index c460527..b52807b 100644
--- a/extensions/components/native_app_window/native_app_window_views.cc
+++ b/extensions/components/native_app_window/native_app_window_views.cc
@@ -293,7 +293,7 @@
   if (app_window_->requested_alpha_enabled() && CanHaveAlphaEnabled()) {
     content::RenderWidgetHostView* view = render_view_host->GetView();
     DCHECK(view);
-    view->SetBackgroundOpaque(false);
+    view->SetBackgroundColor(SK_ColorTRANSPARENT);
   }
 }
 
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 0c9a8ac4..0c107b1 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -18,7 +18,8 @@
         '../mojo/public/tools/bindings/mojom_bindings_generator.gypi',
       ],
       'sources': [
-        'common/stash.mojom',
+        'common/mojo/keep_alive.mojom',
+        'common/mojo/stash.mojom',
       ],
     },
     {
@@ -97,7 +98,6 @@
         'common/extension.h',
         'common/extension_api.cc',
         'common/extension_api.h',
-        'common/extension_api_stub.cc',
         'common/extension_icon_set.cc',
         'common/extension_icon_set.h',
         'common/extension_l10n_util.cc',
@@ -250,8 +250,10 @@
         'common/value_counter.h',
         'common/view_type.cc',
         'common/view_type.h',
-        '<(SHARED_INTERMEDIATE_DIR)/extensions/common/stash.mojom.cc',
-        '<(SHARED_INTERMEDIATE_DIR)/extensions/common/stash.mojom.h',
+        '<(SHARED_INTERMEDIATE_DIR)/extensions/common/mojo/keep_alive.mojom.cc',
+        '<(SHARED_INTERMEDIATE_DIR)/extensions/common/mojo/keep_alive.mojom.h',
+        '<(SHARED_INTERMEDIATE_DIR)/extensions/common/mojo/stash.mojom.cc',
+        '<(SHARED_INTERMEDIATE_DIR)/extensions/common/mojo/stash.mojom.h',
       ],
       # Disable c4267 warnings until we fix size_t to int truncations.
       'msvs_disabled_warnings': [ 4267, ],
@@ -264,9 +266,6 @@
             '../device/serial/serial.gyp:device_serial_mojo',
             '../device/usb/usb.gyp:device_usb',
           ],
-          'sources!': [
-            'common/extension_api_stub.cc',
-          ],
         }, {  # enable_extensions == 0
           'sources!': [
             'common/api/bluetooth/bluetooth_manifest_data.cc',
@@ -310,7 +309,7 @@
         '../components/components.gyp:keyed_service_content',
         '../components/components.gyp:keyed_service_core',
         '../components/components.gyp:pref_registry',
-        '../components/components.gyp:sessions',
+        '../components/components.gyp:sessions_content',
         '../components/components.gyp:storage_monitor',
         '../components/components.gyp:web_cache_browser',
         '../components/components.gyp:web_modal',
@@ -668,6 +667,7 @@
         'browser/guest_view/guest_view.h',
         'browser/guest_view/mime_handler_view/mime_handler_view_constants.cc',
         'browser/guest_view/mime_handler_view/mime_handler_view_constants.h',
+        'browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.cc',
         'browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h',
         'browser/guest_view/mime_handler_view/mime_handler_view_guest.cc',
         'browser/guest_view/mime_handler_view/mime_handler_view_guest.h',
@@ -707,6 +707,10 @@
         'browser/lazy_background_task_queue.h',
         'browser/management_policy.cc',
         'browser/management_policy.h',
+        'browser/mojo/keep_alive_impl.cc',
+        'browser/mojo/keep_alive_impl.h',
+        'browser/mojo/stash_backend.cc',
+        'browser/mojo/stash_backend.h',
         'browser/notification_types.h',
         'browser/null_app_sorting.cc',
         'browser/null_app_sorting.h',
@@ -729,8 +733,6 @@
         'browser/script_execution_observer.h',
         'browser/script_executor.cc',
         'browser/script_executor.h',
-        'browser/stash_backend.cc',
-        'browser/stash_backend.h',
         'browser/state_store.cc',
         'browser/state_store.h',
         'browser/suggest_permission_util.cc',
@@ -1160,11 +1162,12 @@
         'browser/info_map_unittest.cc',
         'browser/lazy_background_task_queue_unittest.cc',
         'browser/management_policy_unittest.cc',
+        'browser/mojo/keep_alive_impl_unittest.cc',
+        'browser/mojo/stash_backend_unittest.cc',
         'browser/process_manager_unittest.cc',
         'browser/process_map_unittest.cc',
         'browser/quota_service_unittest.cc',
         'browser/runtime_data_unittest.cc',
-        'browser/stash_backend_unittest.cc',
         'browser/value_store/leveldb_value_store_unittest.cc',
         'browser/value_store/testing_value_store_unittest.cc',
         'browser/value_store/value_store_change_unittest.cc',
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index 5b4f932..2e42d71 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -334,6 +334,8 @@
   // The API will be automatically set up when first used.
   if (context->GetAvailability("webViewInternal").is_available()) {
     module_system->Require("webView");
+    module_system->Require("webViewConstants");
+    module_system->Require("webViewAttributes");
     if (context->GetAvailability("webViewExperimentalInternal")
             .is_available()) {
       module_system->Require("webViewExperimental");
@@ -548,6 +550,10 @@
   // Note: webView not webview so that this doesn't interfere with the
   // chrome.webview API bindings.
   resources.push_back(std::make_pair("webView", IDR_WEB_VIEW_JS));
+  resources.push_back(std::make_pair("webViewAttributes",
+                                     IDR_WEB_VIEW_ATTRIBUTES_JS));
+  resources.push_back(std::make_pair("webViewConstants",
+                                     IDR_WEB_VIEW_CONSTANTS_JS));
   resources.push_back(std::make_pair("webViewEvents", IDR_WEB_VIEW_EVENTS_JS));
   resources.push_back(
       std::make_pair("webViewExperimental", IDR_WEB_VIEW_EXPERIMENTAL_JS));
diff --git a/extensions/renderer/resources/extensions_renderer_resources.grd b/extensions/renderer/resources/extensions_renderer_resources.grd
index 119889a..2913fdf 100644
--- a/extensions/renderer/resources/extensions_renderer_resources.grd
+++ b/extensions/renderer/resources/extensions_renderer_resources.grd
@@ -35,6 +35,8 @@
       <include name="IDR_UNCAUGHT_EXCEPTION_HANDLER_JS" file="uncaught_exception_handler.js" type="BINDATA" />
       <include name="IDR_UNLOAD_EVENT_JS" file="unload_event.js" type="BINDATA" />
       <include name="IDR_UTILS_JS" file="utils.js" type="BINDATA" />
+      <include name="IDR_WEB_VIEW_ATTRIBUTES_JS" file="guest_view/web_view_attributes.js" type="BINDATA" />
+      <include name="IDR_WEB_VIEW_CONSTANTS_JS" file="guest_view/web_view_constants.js" type="BINDATA" />
       <include name="IDR_WEB_VIEW_DENY_JS" file="guest_view/web_view_deny.js" type="BINDATA" />
       <include name="IDR_WEB_VIEW_EVENTS_JS" file="guest_view/web_view_events.js" type="BINDATA" />
       <include name="IDR_WEB_VIEW_EXPERIMENTAL_JS" file="guest_view/web_view_experimental.js" type="BINDATA" />
diff --git a/extensions/renderer/resources/guest_view/web_view.js b/extensions/renderer/resources/guest_view/web_view.js
index 6079264..8405e384 100644
--- a/extensions/renderer/resources/guest_view/web_view.js
+++ b/extensions/renderer/resources/guest_view/web_view.js
@@ -11,76 +11,19 @@
     require('binding').Binding.create('guestViewInternal').generate();
 var guestViewInternalNatives = requireNative('guest_view_internal');
 var IdGenerator = requireNative('id_generator');
+var WebViewConstants = require('webViewConstants').WebViewConstants;
 var WebViewEvents = require('webViewEvents').WebViewEvents;
 var WebViewInternal = require('webViewInternal').WebViewInternal;
 
 // Attributes.
-var WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY = 'allowtransparency';
-var WEB_VIEW_ATTRIBUTE_AUTOSIZE = 'autosize';
-var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight';
-var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth';
-var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight';
-var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth';
-var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition';
 var AUTO_SIZE_ATTRIBUTES = [
-  WEB_VIEW_ATTRIBUTE_AUTOSIZE,
-  WEB_VIEW_ATTRIBUTE_MAXHEIGHT,
-  WEB_VIEW_ATTRIBUTE_MAXWIDTH,
-  WEB_VIEW_ATTRIBUTE_MINHEIGHT,
-  WEB_VIEW_ATTRIBUTE_MINWIDTH
+  WebViewConstants.ATTRIBUTE_AUTOSIZE,
+  WebViewConstants.ATTRIBUTE_MAXHEIGHT,
+  WebViewConstants.ATTRIBUTE_MAXWIDTH,
+  WebViewConstants.ATTRIBUTE_MINHEIGHT,
+  WebViewConstants.ATTRIBUTE_MINWIDTH
 ];
 
-// Error messages.
-var ERROR_MSG_ALREADY_NAVIGATED =
-    'The object has already navigated, so its partition cannot be changed.';
-var ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview>: ' +
-    'Script cannot be injected into content until the page has loaded.';
-var ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = '<webview>: ' +
-    'contentWindow is not available at this time. It will become available ' +
-    'when the page has finished loading.';
-var ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.';
-
-// Represents the state of the storage partition.
-function Partition() {
-  this.validPartitionId = true;
-  this.persistStorage = false;
-  this.storagePartitionId = '';
-}
-
-Partition.prototype.toAttribute = function() {
-  if (!this.validPartitionId) {
-    return '';
-  }
-  return (this.persistStorage ? 'persist:' : '') + this.storagePartitionId;
-};
-
-Partition.prototype.fromAttribute = function(value, hasNavigated) {
-  var result = {};
-  if (hasNavigated) {
-    result.error = ERROR_MSG_ALREADY_NAVIGATED;
-    return result;
-  }
-  if (!value) {
-    value = '';
-  }
-
-  var LEN = 'persist:'.length;
-  if (value.substr(0, LEN) == 'persist:') {
-    value = value.substr(LEN);
-    if (!value) {
-      this.validPartitionId = false;
-      result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
-      return result;
-    }
-    this.persistStorage = true;
-  } else {
-    this.persistStorage = false;
-  }
-
-  this.storagePartitionId = value;
-  return result;
-};
-
 // Represents the internal state of the WebView node.
 function WebView(webviewNode) {
   privates(webviewNode).internal = this;
@@ -103,8 +46,7 @@
 
   this.browserPluginNode = this.createBrowserPluginNode();
   var shadowRoot = this.webviewNode.createShadowRoot();
-  this.partition = new Partition();
-
+  this.setupWebViewAttributes();
   this.setupWebViewSrcAttributeMutationObserver();
   this.setupFocusPropagation();
   this.setupWebviewNodeProperties();
@@ -141,7 +83,8 @@
     this.guestInstanceId = undefined;
     this.beforeFirstNavigation = true;
     this.validPartitionId = true;
-    this.partition.validPartitionId = true;
+    this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId =
+        true;
     this.contentWindow = null;
   }
   this.internalInstanceId = 0;
@@ -180,16 +123,17 @@
 // Validation helper function for executeScript() and insertCSS().
 WebView.prototype.validateExecuteCodeCall  = function() {
   if (!this.guestInstanceId) {
-    throw new Error(ERROR_MSG_CANNOT_INJECT_SCRIPT);
+    throw new Error(WebViewConstants.ERROR_MSG_CANNOT_INJECT_SCRIPT);
   }
 };
 
 WebView.prototype.setupAutoSizeProperties = function() {
   $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) {
-    this[attributeName] = this.webviewNode.getAttribute(attributeName);
+    this.attributes[attributeName].setValue(
+        this.webviewNode.getAttribute(attributeName));
     Object.defineProperty(this.webviewNode, attributeName, {
       get: function() {
-        return this[attributeName];
+        return this.attributes[attributeName].getValue();
       }.bind(this),
       set: function(value) {
         this.webviewNode.setAttribute(attributeName, value);
@@ -203,13 +147,15 @@
   this.setupAutoSizeProperties();
 
   Object.defineProperty(this.webviewNode,
-                        WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY, {
+                        WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, {
     get: function() {
-      return this.allowtransparency;
+      return this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].
+          getValue();
     }.bind(this),
     set: function(value) {
-      this.webviewNode.setAttribute(WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY,
-                                    value);
+      this.webviewNode.setAttribute(
+          WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY,
+          value);
     }.bind(this),
     enumerable: true
   });
@@ -221,45 +167,49 @@
       if (this.contentWindow) {
         return this.contentWindow;
       }
-      window.console.error(ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE);
+      window.console.error(
+          WebViewConstants.ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE);
     }.bind(this),
     // No setter.
     enumerable: true
   });
 
-  Object.defineProperty(this.webviewNode, 'name', {
+  Object.defineProperty(this.webviewNode, WebViewConstants.ATTRIBUTE_NAME, {
     get: function() {
-      return this.name;
+      return this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue();
     }.bind(this),
     set: function(value) {
-      this.webviewNode.setAttribute('name', value);
+      this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_NAME, value);
     }.bind(this),
     enumerable: true
   });
 
-  Object.defineProperty(this.webviewNode, 'partition', {
+  Object.defineProperty(this.webviewNode,
+                        WebViewConstants.ATTRIBUTE_PARTITION, {
     get: function() {
-      return this.partition.toAttribute();
+      return this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].getValue();
     }.bind(this),
     set: function(value) {
-      var result = this.partition.fromAttribute(value, this.hasNavigated());
+      var result = this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].
+          setValue(value);
       if (result.error) {
         throw result.error;
       }
-      this.webviewNode.setAttribute('partition', value);
+      this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_PARTITION,
+                                    value);
     }.bind(this),
     enumerable: true
   });
 
-  this.src = this.webviewNode.getAttribute('src');
-  Object.defineProperty(this.webviewNode, 'src', {
+  this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue(
+      this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC));
+  Object.defineProperty(this.webviewNode, WebViewConstants.ATTRIBUTE_SRC, {
     get: function() {
-      return this.src;
+      return this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
     }.bind(this),
     set: function(value) {
-      this.webviewNode.setAttribute('src', value);
+      this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, value);
     }.bind(this),
-    // No setter.
     enumerable: true
   });
 };
@@ -284,7 +234,8 @@
   var params = {
     attributes: true,
     attributeOldValue: true,
-    attributeFilter: ['src', 'partition']
+    attributeFilter: [WebViewConstants.ATTRIBUTE_SRC,
+                      WebViewConstants.ATTRIBUTE_PARTITION]
   };
   this.srcAndPartitionObserver.observe(this.webviewNode, params);
 };
@@ -297,25 +248,30 @@
 WebView.prototype.handleWebviewAttributeMutation =
       function(name, oldValue, newValue) {
   if (AUTO_SIZE_ATTRIBUTES.indexOf(name) > -1) {
-    this[name] = newValue;
+    this.attributes[name].setValue(newValue);
     if (!this.guestInstanceId) {
       return;
     }
     // Convert autosize attribute to boolean.
-    var autosize = this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE);
+    var autosize = this.webviewNode.hasAttribute(
+        WebViewConstants.ATTRIBUTE_AUTOSIZE);
     GuestViewInternal.setAutoSize(this.guestInstanceId, {
       'enableAutoSize': autosize,
       'min': {
-        'width': parseInt(this.minwidth || 0),
-        'height': parseInt(this.minheight || 0)
+        'width': parseInt(this.
+            attributes[WebViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0),
+        'height': parseInt(this.
+            attributes[WebViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || 0)
       },
       'max': {
-        'width': parseInt(this.maxwidth || 0),
-        'height': parseInt(this.maxheight || 0)
+        'width': parseInt(this.
+            attributes[WebViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0),
+        'height': parseInt(this.
+            attributes[WebViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0)
       }
     });
     return;
-  } else if (name == WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY) {
+  } else if (name == WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY) {
     // We treat null attribute (attribute removed) and the empty string as
     // one case.
     oldValue = oldValue || '';
@@ -324,16 +280,19 @@
     if (oldValue === newValue) {
       return;
     }
-    this.allowtransparency = newValue != '';
+    this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].
+        setValue(newValue != '');
 
     if (!this.guestInstanceId) {
       return;
     }
 
-    WebViewInternal.setAllowTransparency(this.guestInstanceId,
-                                         this.allowtransparency);
+    WebViewInternal.setAllowTransparency(
+        this.guestInstanceId,
+        this.attributes[WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].
+            getValue());
     return;
-  } else if (name == 'name') {
+  } else if (name == WebViewConstants.ATTRIBUTE_NAME) {
     // We treat null attribute (attribute removed) and the empty string as
     // one case.
     oldValue = oldValue || '';
@@ -342,13 +301,13 @@
     if (oldValue === newValue) {
       return;
     }
-    this.name = newValue;
+    this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValue(newValue);
     if (!this.guestInstanceId) {
       return;
     }
     WebViewInternal.setName(this.guestInstanceId, newValue);
     return;
-  } else if (name == 'src') {
+  } else if (name == WebViewConstants.ATTRIBUTE_SRC) {
     // We treat null attribute (attribute removed) and the empty string as
     // one case.
     oldValue = oldValue || '';
@@ -361,10 +320,10 @@
       // the next src attribute handler call to avoid reloading the page
       // on every guest-initiated navigation.
       this.ignoreNextSrcAttributeChange = true;
-      this.webviewNode.setAttribute('src', oldValue);
+      this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, oldValue);
       return;
     }
-    this.src = newValue;
+    this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue(newValue);
     if (this.ignoreNextSrcAttributeChange) {
       // Don't allow the src mutation observer to see this change.
       this.srcAndPartitionObserver.takeRecords();
@@ -377,16 +336,18 @@
     if (result.error) {
       throw result.error;
     }
-  } else if (name == 'partition') {
+  } else if (name == WebViewConstants.ATTRIBUTE_PARTITION) {
     // Note that throwing error here won't synchronously propagate.
-    this.partition.fromAttribute(newValue, this.hasNavigated());
+    this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue(newValue);
   }
 };
 
 WebView.prototype.handleBrowserPluginAttributeMutation =
     function(name, oldValue, newValue) {
-  if (name == 'internalinstanceid' && !oldValue && !!newValue) {
-    this.browserPluginNode.removeAttribute('internalinstanceid');
+  if (name == WebViewConstants.ATTRIBUTE_INTERNALINSTANCEID &&
+      !oldValue && !!newValue) {
+    this.browserPluginNode.removeAttribute(
+        WebViewConstants.ATTRIBUTE_INTERNALINSTANCEID);
     this.internalInstanceId = parseInt(newValue);
 
     if (!!this.guestInstanceId && this.guestInstanceId != 0) {
@@ -419,17 +380,17 @@
   // Check the current bounds to make sure we do not resize <webview>
   // outside of current constraints.
   var maxWidth;
-  if (node.hasAttribute(WEB_VIEW_ATTRIBUTE_MAXWIDTH) &&
-      node[WEB_VIEW_ATTRIBUTE_MAXWIDTH]) {
-    maxWidth = node[WEB_VIEW_ATTRIBUTE_MAXWIDTH];
+  if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MAXWIDTH) &&
+      node[WebViewConstants.ATTRIBUTE_MAXWIDTH]) {
+    maxWidth = node[WebViewConstants.ATTRIBUTE_MAXWIDTH];
   } else {
     maxWidth = width;
   }
 
   var minWidth;
-  if (node.hasAttribute(WEB_VIEW_ATTRIBUTE_MINWIDTH) &&
-      node[WEB_VIEW_ATTRIBUTE_MINWIDTH]) {
-    minWidth = node[WEB_VIEW_ATTRIBUTE_MINWIDTH];
+  if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MINWIDTH) &&
+      node[WebViewConstants.ATTRIBUTE_MINWIDTH]) {
+    minWidth = node[WebViewConstants.ATTRIBUTE_MINWIDTH];
   } else {
     minWidth = width;
   }
@@ -438,17 +399,17 @@
   }
 
   var maxHeight;
-  if (node.hasAttribute(WEB_VIEW_ATTRIBUTE_MAXHEIGHT) &&
-      node[WEB_VIEW_ATTRIBUTE_MAXHEIGHT]) {
-    maxHeight = node[WEB_VIEW_ATTRIBUTE_MAXHEIGHT];
+  if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MAXHEIGHT) &&
+      node[WebViewConstants.ATTRIBUTE_MAXHEIGHT]) {
+    maxHeight = node[WebViewConstants.ATTRIBUTE_MAXHEIGHT];
   } else {
     maxHeight = height;
   }
 
   var minHeight;
-  if (node.hasAttribute(WEB_VIEW_ATTRIBUTE_MINHEIGHT) &&
-      node[WEB_VIEW_ATTRIBUTE_MINHEIGHT]) {
-    minHeight = node[WEB_VIEW_ATTRIBUTE_MINHEIGHT];
+  if (node.hasAttribute(WebViewConstants.ATTRIBUTE_MINHEIGHT) &&
+      node[WebViewConstants.ATTRIBUTE_MINHEIGHT]) {
+    minHeight = node[WebViewConstants.ATTRIBUTE_MINHEIGHT];
   } else {
     minHeight = height;
   }
@@ -456,7 +417,7 @@
     minHeight = maxHeight;
   }
 
-  if (!this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE) ||
+  if (!this.webviewNode.hasAttribute(WebViewConstants.ATTRIBUTE_AUTOSIZE) ||
       (newWidth >= minWidth &&
        newWidth <= maxWidth &&
        newHeight >= minHeight &&
@@ -479,13 +440,14 @@
 };
 
 WebView.prototype.parseSrcAttribute = function(result) {
-  if (!this.partition.validPartitionId) {
-    result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
+  if (!this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].validPartitionId) {
+    result.error = WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
     return;
   }
-  this.src = this.webviewNode.getAttribute('src');
+  this.attributes[WebViewConstants.ATTRIBUTE_SRC].setValue(
+      this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC));
 
-  if (!this.src) {
+  if (!this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue()) {
     return;
   }
 
@@ -498,16 +460,19 @@
   }
 
   // Navigate to |this.src|.
-  WebViewInternal.navigate(this.guestInstanceId, this.src);
+  WebViewInternal.navigate(
+      this.guestInstanceId,
+      this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue());
 };
 
 WebView.prototype.parseAttributes = function() {
   if (!this.elementAttached) {
     return;
   }
-  var hasNavigated = this.hasNavigated();
-  var attributeValue = this.webviewNode.getAttribute('partition');
-  var result = this.partition.fromAttribute(attributeValue, hasNavigated);
+  var attributeValue = this.webviewNode.getAttribute(
+      WebViewConstants.ATTRIBUTE_PARTITION);
+  var result = this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue(
+      attributeValue);
   this.parseSrcAttribute(result);
 };
 
@@ -516,8 +481,8 @@
     return;
   }
   var storagePartitionId =
-      this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) ||
-      this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION];
+      this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_PARTITION) ||
+      this.webviewNode[WebViewConstants.ATTRIBUTE_PARTITION];
   var params = {
     'storagePartitionId': storagePartitionId
   };
@@ -537,11 +502,13 @@
 };
 
 WebView.prototype.onFrameNameChanged = function(name) {
-  this.name = name || '';
-  if (this.name === '') {
-    this.webviewNode.removeAttribute('name');
+  this.attributes[WebViewConstants.ATTRIBUTE_NAME].setValue(name || '');
+  if (this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue() === '') {
+    this.webviewNode.removeAttribute(WebViewConstants.ATTRIBUTE_NAME);
   } else {
-    this.webviewNode.setAttribute('name', this.name);
+    this.webviewNode.setAttribute(
+        WebViewConstants.ATTRIBUTE_NAME,
+        this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue());
   }
 };
 
@@ -576,37 +543,47 @@
   this.currentEntryIndex = currentEntryIndex;
   this.entryCount = entryCount;
   this.processId = processId;
-  var oldValue = this.webviewNode.getAttribute('src');
+  var oldValue = this.webviewNode.getAttribute(WebViewConstants.ATTRIBUTE_SRC);
   var newValue = url;
   if (isTopLevel && (oldValue != newValue)) {
     // Touching the src attribute triggers a navigation. To avoid
     // triggering a page reload on every guest-initiated navigation,
     // we use the flag ignoreNextSrcAttributeChange here.
     this.ignoreNextSrcAttributeChange = true;
-    this.webviewNode.setAttribute('src', newValue);
+    this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_SRC, newValue);
   }
 };
 
 WebView.prototype.onAttach = function(storagePartitionId) {
-  this.webviewNode.setAttribute('partition', storagePartitionId);
-  this.partition.fromAttribute(storagePartitionId, this.hasNavigated());
+  this.webviewNode.setAttribute(WebViewConstants.ATTRIBUTE_PARTITION,
+                                storagePartitionId);
+  this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].setValue(
+      storagePartitionId);
 };
 
 WebView.prototype.buildAttachParams = function(isNewWindow) {
   var params = {
-    'allowtransparency': this.allowtransparency || false,
-    'autosize': this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE),
+    'allowtransparency': this.attributes[
+      WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].getValue() || false,
+    'autosize': this.webviewNode.hasAttribute(
+        WebViewConstants.ATTRIBUTE_AUTOSIZE),
     'instanceId': this.viewInstanceId,
-    'maxheight': parseInt(this.maxheight || 0),
-    'maxwidth': parseInt(this.maxwidth || 0),
-    'minheight': parseInt(this.minheight || 0),
-    'minwidth': parseInt(this.minwidth || 0),
-    'name': this.name,
+    'maxheight': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MAXHEIGHT].
+        getValue() || 0),
+    'maxwidth': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MAXWIDTH].
+        getValue() || 0),
+    'minheight': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MINHEIGHT].
+        getValue() || 0),
+    'minwidth': parseInt(this.attributes[WebViewConstants.ATTRIBUTE_MINWIDTH].
+        getValue() || 0),
+    'name': this.attributes[WebViewConstants.ATTRIBUTE_NAME].getValue(),
     // We don't need to navigate new window from here.
-    'src': isNewWindow ? undefined : this.src,
+    'src': isNewWindow ? undefined :
+        this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue(),
     // If we have a partition from the opener, that will also be already
     // set via this.onAttach().
-    'storagePartitionId': this.partition.toAttribute(),
+    'storagePartitionId': this.attributes[WebViewConstants.ATTRIBUTE_PARTITION].
+        getValue(),
     'userAgentOverride': this.userAgentOverride
   };
   return params;
@@ -664,7 +641,7 @@
 // Injects JavaScript code into the guest page.
 WebView.prototype.executeScript = function(var_args) {
   this.validateExecuteCodeCall();
-  var webviewSrc = this.src;
+  var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
   if (this.baseUrlForDataUrl != '') {
     webviewSrc = this.baseUrlForDataUrl;
   }
@@ -717,7 +694,7 @@
 // Injects CSS into the guest page.
 WebView.prototype.insertCSS = function(var_args) {
   this.validateExecuteCodeCall();
-  var webviewSrc = this.src;
+  var webviewSrc = this.attributes[WebViewConstants.ATTRIBUTE_SRC].getValue();
   if (this.baseUrlForDataUrl != '') {
     webviewSrc = this.baseUrlForDataUrl;
   }
diff --git a/extensions/renderer/resources/guest_view/web_view_attributes.js b/extensions/renderer/resources/guest_view/web_view_attributes.js
new file mode 100644
index 0000000..56f38740
--- /dev/null
+++ b/extensions/renderer/resources/guest_view/web_view_attributes.js
@@ -0,0 +1,97 @@
+// Copyright (c) 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.
+
+// This module implements the attributes of the <webview> tag.
+
+var WebView = require('webView').WebView;
+var WebViewConstants = require('webViewConstants').WebViewConstants;
+
+// -----------------------------------------------------------------------------
+// Attribute objects.
+
+// Default implementation of a WebView attribute.
+function WebViewAttribute(name, webViewImpl) {
+  this.name = name;
+  this.value = '';
+  this.webViewImpl = webViewImpl;
+}
+
+WebViewAttribute.prototype.getValue = function() {
+  return this.value || '';
+};
+
+WebViewAttribute.prototype.setValue = function(value) {
+  this.value = value;
+};
+
+// Attribute representing the state of the storage partition.
+function Partition(webViewImpl) {
+  this.validPartitionId = true;
+  this.persistStorage = false;
+  this.storagePartitionId = '';
+  this.webViewImpl = webViewImpl;
+}
+
+Partition.prototype = new WebViewAttribute(
+    WebViewConstants.ATTRIBUTE_PARTITION);
+
+Partition.prototype.getValue = function() {
+  if (!this.validPartitionId) {
+    return '';
+  }
+  return (this.persistStorage ? 'persist:' : '') + this.storagePartitionId;
+};
+
+Partition.prototype.setValue = function(value) {
+  var result = {};
+  var hasNavigated = !this.webViewImpl.beforeFirstNavigation;
+  if (hasNavigated) {
+    result.error = WebViewConstants.ERROR_MSG_ALREADY_NAVIGATED;
+    return result;
+  }
+  if (!value) {
+    value = '';
+  }
+
+  var LEN = 'persist:'.length;
+  if (value.substr(0, LEN) == 'persist:') {
+    value = value.substr(LEN);
+    if (!value) {
+      this.validPartitionId = false;
+      result.error = WebViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
+      return result;
+    }
+    this.persistStorage = true;
+  } else {
+    this.persistStorage = false;
+  }
+
+  this.storagePartitionId = value;
+  return result;
+};
+
+// -----------------------------------------------------------------------------
+
+// Sets up all of the webview attributes.
+WebView.prototype.setupWebViewAttributes = function() {
+  this.attributes = {};
+
+  // Initialize the attributes with special behavior (and custom attribute
+  // objects).
+  this.attributes[WebViewConstants.ATTRIBUTE_PARTITION] = new Partition(this);
+
+  // Initialize the remaining attributes, which have default behavior.
+  var defaultAttributes = [WebViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY,
+                           WebViewConstants.ATTRIBUTE_AUTOSIZE,
+                           WebViewConstants.ATTRIBUTE_MAXHEIGHT,
+                           WebViewConstants.ATTRIBUTE_MAXWIDTH,
+                           WebViewConstants.ATTRIBUTE_MINHEIGHT,
+                           WebViewConstants.ATTRIBUTE_MINWIDTH,
+                           WebViewConstants.ATTRIBUTE_NAME,
+                           WebViewConstants.ATTRIBUTE_SRC];
+  for (var i = 0; defaultAttributes[i]; ++i) {
+    this.attributes[defaultAttributes[i]] =
+        new WebViewAttribute(defaultAttributes[i], this);
+  }
+};
diff --git a/extensions/renderer/resources/guest_view/web_view_constants.js b/extensions/renderer/resources/guest_view/web_view_constants.js
new file mode 100644
index 0000000..40cf6ba2
--- /dev/null
+++ b/extensions/renderer/resources/guest_view/web_view_constants.js
@@ -0,0 +1,34 @@
+// Copyright (c) 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.
+
+// This module contains constants used in webview.
+
+// Container for the webview constants.
+var WebViewConstants = {
+  // Attributes.
+  ATTRIBUTE_ALLOWTRANSPARENCY: 'allowtransparency',
+  ATTRIBUTE_AUTOSIZE: 'autosize',
+  ATTRIBUTE_MAXHEIGHT: 'maxheight',
+  ATTRIBUTE_MAXWIDTH: 'maxwidth',
+  ATTRIBUTE_MINHEIGHT: 'minheight',
+  ATTRIBUTE_MINWIDTH: 'minwidth',
+  ATTRIBUTE_NAME: 'name',
+  ATTRIBUTE_PARTITION: 'partition',
+  ATTRIBUTE_SRC: 'src',
+
+  // Internal attribute.
+  ATTRIBUTE_INTERNALINSTANCEID: 'internalinstanceid',
+
+  // Error messages.
+  ERROR_MSG_ALREADY_NAVIGATED:
+      'The object has already navigated, so its partition cannot be changed.',
+  ERROR_MSG_CANNOT_INJECT_SCRIPT: '<webview>: ' +
+      'Script cannot be injected into content until the page has loaded.',
+  ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE: '<webview>: ' +
+      'contentWindow is not available at this time. It will become available ' +
+      'when the page has finished loading.',
+  ERROR_MSG_INVALID_PARTITION_ATTRIBUTE: 'Invalid partition attribute.'
+};
+
+exports.WebViewConstants = WebViewConstants;
diff --git a/extensions/shell/browser/default_shell_browser_main_delegate.cc b/extensions/shell/browser/default_shell_browser_main_delegate.cc
index 491fe437..7e49f52 100644
--- a/extensions/shell/browser/default_shell_browser_main_delegate.cc
+++ b/extensions/shell/browser/default_shell_browser_main_delegate.cc
@@ -7,6 +7,7 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/strings/string_tokenizer.h"
 #include "extensions/shell/browser/shell_desktop_controller.h"
 #include "extensions/shell/browser/shell_extension_system.h"
 #include "extensions/shell/common/switches.h"
@@ -23,15 +24,25 @@
     content::BrowserContext* browser_context) {
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kAppShellAppPath)) {
-    base::FilePath app_dir(
-        command_line->GetSwitchValueNative(switches::kAppShellAppPath));
-    base::FilePath app_absolute_dir = base::MakeAbsoluteFilePath(app_dir);
-
     ShellExtensionSystem* extension_system = static_cast<ShellExtensionSystem*>(
         ExtensionSystem::Get(browser_context));
-    if (!extension_system->LoadApp(app_absolute_dir))
-      return;
-    extension_system->LaunchApp();
+    extension_system->Init();
+
+    CommandLine::StringType path_list =
+        command_line->GetSwitchValueNative(switches::kAppShellAppPath);
+
+    base::StringTokenizerT<CommandLine::StringType,
+                           CommandLine::StringType::const_iterator>
+        tokenizer(path_list, FILE_PATH_LITERAL(","));
+    while (tokenizer.GetNext()) {
+      base::FilePath app_absolute_dir =
+          base::MakeAbsoluteFilePath(base::FilePath(tokenizer.token()));
+
+      const Extension* extension = extension_system->LoadApp(app_absolute_dir);
+      if (!extension)
+        continue;
+      extension_system->LaunchApp(extension->id());
+    }
   } else {
     LOG(ERROR) << "--" << switches::kAppShellAppPath
                << " unset; boredom is in your future";
diff --git a/extensions/shell/browser/desktop_controller.h b/extensions/shell/browser/desktop_controller.h
index 116d692..40a4e53 100644
--- a/extensions/shell/browser/desktop_controller.h
+++ b/extensions/shell/browser/desktop_controller.h
@@ -46,6 +46,9 @@
   // Attaches the window to our window hierarchy.
   virtual void AddAppWindow(aura::Window* window) = 0;
 
+  // Removes the window from the desktop.
+  virtual void RemoveAppWindow(AppWindow* window) = 0;
+
   // Closes and destroys the app windows.
   virtual void CloseAppWindows() = 0;
 };
diff --git a/extensions/shell/browser/shell_desktop_controller.cc b/extensions/shell/browser/shell_desktop_controller.cc
index 59e84a5..1ec98c8 100644
--- a/extensions/shell/browser/shell_desktop_controller.cc
+++ b/extensions/shell/browser/shell_desktop_controller.cc
@@ -4,6 +4,7 @@
 
 #include "extensions/shell/browser/shell_desktop_controller.h"
 
+#include <algorithm>
 #include <string>
 #include <vector>
 
@@ -160,7 +161,7 @@
 }  // namespace
 
 ShellDesktopController::ShellDesktopController()
-    : app_window_client_(new ShellAppWindowClient), app_window_(NULL) {
+    : app_window_client_(new ShellAppWindowClient) {
   extensions::AppWindowClient::Set(app_window_client_.get());
 
 #if defined(OS_CHROMEOS)
@@ -191,8 +192,9 @@
 AppWindow* ShellDesktopController::CreateAppWindow(
     content::BrowserContext* context,
     const Extension* extension) {
-  app_window_ = new AppWindow(context, new ShellAppDelegate, extension);
-  return app_window_;
+  app_windows_.push_back(
+      new AppWindow(context, new ShellAppDelegate, extension));
+  return app_windows_.back();
 }
 
 void ShellDesktopController::AddAppWindow(aura::Window* window) {
@@ -200,11 +202,20 @@
   root_window->AddChild(window);
 }
 
+void ShellDesktopController::RemoveAppWindow(AppWindow* window) {
+  auto iter = std::find(app_windows_.begin(), app_windows_.end(), window);
+  DCHECK(iter != app_windows_.end());
+  app_windows_.erase(iter);
+}
+
 void ShellDesktopController::CloseAppWindows() {
-  if (app_window_) {
-    app_window_->GetBaseWindow()->Close();  // Close() deletes |app_window_|.
-    app_window_ = NULL;
-  }
+  // Create a copy of the window vector, because closing the windows will
+  // trigger RemoveAppWindow, which will invalidate the iterator.
+  // This vector should be small enough that this should not be an issue.
+  std::vector<AppWindow*> app_windows(app_windows_);
+  for (AppWindow* app_window : app_windows)
+    app_window->GetBaseWindow()->Close();  // Close() deletes |app_window|.
+  app_windows_.clear();
 }
 
 aura::Window* ShellDesktopController::GetDefaultParent(
diff --git a/extensions/shell/browser/shell_desktop_controller.h b/extensions/shell/browser/shell_desktop_controller.h
index 14aa466..0b75e6b 100644
--- a/extensions/shell/browser/shell_desktop_controller.h
+++ b/extensions/shell/browser/shell_desktop_controller.h
@@ -5,6 +5,8 @@
 #ifndef EXTENSIONS_SHELL_BROWSER_SHELL_DESKTOP_CONTROLLER_H_
 #define EXTENSIONS_SHELL_BROWSER_SHELL_DESKTOP_CONTROLLER_H_
 
+#include <vector>
+
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
@@ -69,6 +71,7 @@
   virtual AppWindow* CreateAppWindow(content::BrowserContext* context,
                                      const Extension* extension) override;
   virtual void AddAppWindow(aura::Window* window) override;
+  virtual void RemoveAppWindow(AppWindow* window) override;
   virtual void CloseAppWindows() override;
 
   // aura::client::WindowTreeClient overrides:
@@ -131,8 +134,8 @@
 
   scoped_ptr<AppWindowClient> app_window_client_;
 
-  // The desktop supports a single app window.
-  AppWindow* app_window_;  // NativeAppWindow::Close() deletes this.
+  // NativeAppWindow::Close() deletes the AppWindow.
+  std::vector<AppWindow*> app_windows_;
 
   DISALLOW_COPY_AND_ASSIGN(ShellDesktopController);
 };
diff --git a/extensions/shell/browser/shell_extension_system.cc b/extensions/shell/browser/shell_extension_system.cc
index 317a4100..6337108 100644
--- a/extensions/shell/browser/shell_extension_system.cc
+++ b/extensions/shell/browser/shell_extension_system.cc
@@ -37,21 +37,20 @@
 ShellExtensionSystem::~ShellExtensionSystem() {
 }
 
-bool ShellExtensionSystem::LoadApp(const base::FilePath& app_dir) {
+const Extension* ShellExtensionSystem::LoadApp(const base::FilePath& app_dir) {
   // app_shell only supports unpacked extensions.
   // NOTE: If you add packed extension support consider removing the flag
   // FOLLOW_SYMLINKS_ANYWHERE below. Packed extensions should not have symlinks.
   CHECK(base::DirectoryExists(app_dir)) << app_dir.AsUTF8Unsafe();
   int load_flags = Extension::FOLLOW_SYMLINKS_ANYWHERE;
   std::string load_error;
-  extension_ = file_util::LoadExtension(
+  scoped_refptr<Extension> extension = file_util::LoadExtension(
       app_dir, Manifest::COMMAND_LINE, load_flags, &load_error);
-  if (!extension_.get()) {
+  if (!extension.get()) {
     LOG(ERROR) << "Loading extension at " << app_dir.value()
                << " failed with: " << load_error;
-    return false;
+    return nullptr;
   }
-  app_id_ = extension_->id();
 
   // TODO(jamescook): We may want to do some of these things here:
   // * Create a PermissionsUpdater.
@@ -60,29 +59,36 @@
   // * Call ExtensionPrefs::OnExtensionInstalled().
   // * Send NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED.
 
-  ExtensionRegistry::Get(browser_context_)->AddEnabled(extension_);
+  ExtensionRegistry::Get(browser_context_)->AddEnabled(extension.get());
 
-  RegisterExtensionWithRequestContexts(extension_.get());
+  RegisterExtensionWithRequestContexts(extension.get());
 
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
       content::Source<BrowserContext>(browser_context_),
-      content::Details<const Extension>(extension_.get()));
+      content::Details<const Extension>(extension.get()));
 
+  return extension.get();
+}
+
+void ShellExtensionSystem::Init() {
   // Inform the rest of the extensions system to start.
   ready_.Signal();
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
       content::Source<BrowserContext>(browser_context_),
       content::NotificationService::NoDetails());
-  return true;
 }
 
-void ShellExtensionSystem::LaunchApp() {
+void ShellExtensionSystem::LaunchApp(const ExtensionId& extension_id) {
   // Send the onLaunched event.
-  DCHECK(extension_.get());
-  AppRuntimeEventRouter::DispatchOnLaunchedEvent(browser_context_,
-                                                 extension_.get());
+  DCHECK(ExtensionRegistry::Get(browser_context_)
+             ->enabled_extensions()
+             .Contains(extension_id));
+  const Extension* extension = ExtensionRegistry::Get(browser_context_)
+                                   ->enabled_extensions()
+                                   .GetByID(extension_id);
+  AppRuntimeEventRouter::DispatchOnLaunchedEvent(browser_context_, extension);
 }
 
 void ShellExtensionSystem::Shutdown() {
diff --git a/extensions/shell/browser/shell_extension_system.h b/extensions/shell/browser/shell_extension_system.h
index 08004ce..28113b7 100644
--- a/extensions/shell/browser/shell_extension_system.h
+++ b/extensions/shell/browser/shell_extension_system.h
@@ -38,17 +38,19 @@
   explicit ShellExtensionSystem(content::BrowserContext* browser_context);
   ~ShellExtensionSystem() override;
 
-  // Loads an unpacked application from a directory. Returns true on success.
-  bool LoadApp(const base::FilePath& app_dir);
+  // Loads an unpacked application from a directory. Returns the extension on
+  // success, or null otherwise.
+  const Extension* LoadApp(const base::FilePath& app_dir);
 
-  // Launch the currently loaded app.
-  void LaunchApp();
+  // Initializes the extension system.
+  void Init();
+
+  // Launch the app with id |extension_id|.
+  void LaunchApp(const std::string& extension_id);
 
   // KeyedService implementation:
   void Shutdown() override;
 
-  scoped_refptr<Extension> extension() { return extension_; }
-
   // ExtensionSystem implementation:
   void InitForRegularProfile(bool extensions_enabled) override;
   ExtensionService* extension_service() override;
@@ -81,11 +83,6 @@
  private:
   content::BrowserContext* browser_context_;  // Not owned.
 
-  // Extension ID for the app.
-  std::string app_id_;
-
-  scoped_refptr<Extension> extension_;
-
   // Data to be accessed on the IO thread. Must outlive process_manager_.
   scoped_refptr<InfoMap> info_map_;
 
diff --git a/extensions/shell/browser/shell_native_app_window.cc b/extensions/shell/browser/shell_native_app_window.cc
index 97968a9..1581a71 100644
--- a/extensions/shell/browser/shell_native_app_window.cc
+++ b/extensions/shell/browser/shell_native_app_window.cc
@@ -92,6 +92,7 @@
 }
 
 void ShellNativeAppWindow::Close() {
+  DesktopController::instance()->RemoveAppWindow(app_window_);
   app_window_->OnNativeClose();
 }
 
diff --git a/extensions/shell/test/shell_apitest.cc b/extensions/shell/test/shell_apitest.cc
index b60bf5b..f1ea7a2f 100644
--- a/extensions/shell/test/shell_apitest.cc
+++ b/extensions/shell/test/shell_apitest.cc
@@ -24,11 +24,11 @@
   test_data_dir = test_data_dir.AppendASCII(app_dir);
   ResultCatcher catcher;
 
-  bool loaded = extension_system_->LoadApp(test_data_dir);
-  if (!loaded)
+  const Extension* extension = extension_system_->LoadApp(test_data_dir);
+  if (!extension)
     return false;
 
-  extension_system_->LaunchApp();
+  extension_system_->LaunchApp(extension->id());
 
   if (!catcher.GetNextResult()) {
     message_ = catcher.message();
diff --git a/gin/array_buffer.h b/gin/array_buffer.h
index 048a35f..fe3fae2 100644
--- a/gin/array_buffer.h
+++ b/gin/array_buffer.h
@@ -16,9 +16,9 @@
 
 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
  public:
-  virtual void* Allocate(size_t length) override;
-  virtual void* AllocateUninitialized(size_t length) override;
-  virtual void Free(void* data, size_t length) override;
+  void* Allocate(size_t length) override;
+  void* AllocateUninitialized(size_t length) override;
+  void Free(void* data, size_t length) override;
 
   GIN_EXPORT static ArrayBufferAllocator* SharedInstance();
 };
diff --git a/gin/function_template.h b/gin/function_template.h
index 7ba54b59..955ff53 100644
--- a/gin/function_template.h
+++ b/gin/function_template.h
@@ -1,16 +1,10 @@
-// This file was GENERATED by command:
-//     pump.py function_template.h.pump
-// DO NOT EDIT BY HAND!!!
-
-
+// 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 GIN_FUNCTION_TEMPLATE_H_
 #define GIN_FUNCTION_TEMPLATE_H_
 
-// 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 "base/callback.h"
 #include "base/logging.h"
 #include "gin/arguments.h"
@@ -80,180 +74,6 @@
   DISALLOW_COPY_AND_ASSIGN(CallbackHolder);
 };
 
-
-// This set of templates invokes a base::Callback, converts the return type to a
-// JavaScript value, and returns that value to script via the provided
-// gin::Arguments object.
-//
-// In C++, you can declare the function foo(void), but you can't pass a void
-// expression to foo. As a result, we must specialize the case of Callbacks that
-// have the void return type.
-template<typename R, typename P1 = void, typename P2 = void,
-    typename P3 = void, typename P4 = void, typename P5 = void,
-    typename P6 = void>
-struct Invoker {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<R(P1, P2, P3, P4, P5, P6)>& callback,
-      const P1& a1,
-      const P2& a2,
-      const P3& a3,
-      const P4& a4,
-      const P5& a5,
-      const P6& a6) {
-    args->Return(callback.Run(a1, a2, a3, a4, a5, a6));
-  }
-};
-template<typename P1, typename P2, typename P3, typename P4, typename P5,
-    typename P6>
-struct Invoker<void, P1, P2, P3, P4, P5, P6> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<void(P1, P2, P3, P4, P5, P6)>& callback,
-      const P1& a1,
-      const P2& a2,
-      const P3& a3,
-      const P4& a4,
-      const P5& a5,
-      const P6& a6) {
-    callback.Run(a1, a2, a3, a4, a5, a6);
-  }
-};
-
-template<typename R, typename P1, typename P2, typename P3, typename P4,
-    typename P5>
-struct Invoker<R, P1, P2, P3, P4, P5, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<R(P1, P2, P3, P4, P5)>& callback,
-      const P1& a1,
-      const P2& a2,
-      const P3& a3,
-      const P4& a4,
-      const P5& a5) {
-    args->Return(callback.Run(a1, a2, a3, a4, a5));
-  }
-};
-template<typename P1, typename P2, typename P3, typename P4, typename P5>
-struct Invoker<void, P1, P2, P3, P4, P5, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<void(P1, P2, P3, P4, P5)>& callback,
-      const P1& a1,
-      const P2& a2,
-      const P3& a3,
-      const P4& a4,
-      const P5& a5) {
-    callback.Run(a1, a2, a3, a4, a5);
-  }
-};
-
-template<typename R, typename P1, typename P2, typename P3, typename P4>
-struct Invoker<R, P1, P2, P3, P4, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<R(P1, P2, P3, P4)>& callback,
-      const P1& a1,
-      const P2& a2,
-      const P3& a3,
-      const P4& a4) {
-    args->Return(callback.Run(a1, a2, a3, a4));
-  }
-};
-template<typename P1, typename P2, typename P3, typename P4>
-struct Invoker<void, P1, P2, P3, P4, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<void(P1, P2, P3, P4)>& callback,
-      const P1& a1,
-      const P2& a2,
-      const P3& a3,
-      const P4& a4) {
-    callback.Run(a1, a2, a3, a4);
-  }
-};
-
-template<typename R, typename P1, typename P2, typename P3>
-struct Invoker<R, P1, P2, P3, void, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<R(P1, P2, P3)>& callback,
-      const P1& a1,
-      const P2& a2,
-      const P3& a3) {
-    args->Return(callback.Run(a1, a2, a3));
-  }
-};
-template<typename P1, typename P2, typename P3>
-struct Invoker<void, P1, P2, P3, void, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<void(P1, P2, P3)>& callback,
-      const P1& a1,
-      const P2& a2,
-      const P3& a3) {
-    callback.Run(a1, a2, a3);
-  }
-};
-
-template<typename R, typename P1, typename P2>
-struct Invoker<R, P1, P2, void, void, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<R(P1, P2)>& callback,
-      const P1& a1,
-      const P2& a2) {
-    args->Return(callback.Run(a1, a2));
-  }
-};
-template<typename P1, typename P2>
-struct Invoker<void, P1, P2, void, void, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<void(P1, P2)>& callback,
-      const P1& a1,
-      const P2& a2) {
-    callback.Run(a1, a2);
-  }
-};
-
-template<typename R, typename P1>
-struct Invoker<R, P1, void, void, void, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<R(P1)>& callback,
-      const P1& a1) {
-    args->Return(callback.Run(a1));
-  }
-};
-template<typename P1>
-struct Invoker<void, P1, void, void, void, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<void(P1)>& callback,
-      const P1& a1) {
-    callback.Run(a1);
-  }
-};
-
-template<typename R>
-struct Invoker<R, void, void, void, void, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<R()>& callback) {
-    args->Return(callback.Run());
-  }
-};
-template<>
-struct Invoker<void, void, void, void, void, void, void> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<void()>& callback) {
-    callback.Run();
-  }
-};
-
-
 template<typename T>
 bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
                      T* result) {
@@ -284,15 +104,88 @@
   return true;
 }
 
+// Classes for generating and storing an argument pack of integer indices
+// (based on well-known "indices trick", see: http://goo.gl/bKKojn):
+template <size_t... indices>
+struct IndicesHolder {};
+
+template <size_t requested_index, size_t... indices>
+struct IndicesGenerator {
+  using type = typename IndicesGenerator<requested_index - 1,
+                                         requested_index - 1,
+                                         indices...>::type;
+};
+template <size_t... indices>
+struct IndicesGenerator<0, indices...> {
+  using type = IndicesHolder<indices...>;
+};
+
+// Class template for extracting and storing single argument for callback
+// at position |index|.
+template <size_t index, typename ArgType>
+struct ArgumentHolder {
+  using ArgLocalType = typename CallbackParamTraits<ArgType>::LocalType;
+
+  ArgLocalType value;
+  bool ok;
+
+  ArgumentHolder(Arguments* args, int create_flags)
+      : ok(GetNextArgument(args, create_flags, index == 0, &value)) {
+    if (!ok)
+      args->ThrowError();
+  }
+};
+
+// Class template for converting arguments from JavaScript to C++ and running
+// the callback with them.
+template <typename IndicesType, typename... ArgTypes>
+class Invoker {};
+
+template <size_t... indices, typename... ArgTypes>
+class Invoker<IndicesHolder<indices...>, ArgTypes...>
+    : public ArgumentHolder<indices, ArgTypes>... {
+ public:
+  // Invoker<> inherits from ArgumentHolder<> for each argument.
+  // C++ has always been strict about the class initialization order,
+  // so it is guaranteed ArgumentHolders will be initialized (and thus, will
+  // extract arguments from Arguments) in the right order.
+  Invoker(Arguments* args, int create_flags)
+      : ArgumentHolder<indices, ArgTypes>(args, create_flags)...,
+        args_(args) {}
+
+  bool IsOK() {
+    return And(ArgumentHolder<indices, ArgTypes>::ok...);
+  }
+
+  template <typename ReturnType>
+  void DispatchToCallback(base::Callback<ReturnType(ArgTypes...)> callback) {
+    args_->Return(callback.Run(ArgumentHolder<indices, ArgTypes>::value...));
+  }
+
+  // In C++, you can declare the function foo(void), but you can't pass a void
+  // expression to foo. As a result, we must specialize the case of Callbacks
+  // that have the void return type.
+  void DispatchToCallback(base::Callback<void(ArgTypes...)> callback) {
+    callback.Run(ArgumentHolder<indices, ArgTypes>::value...);
+  }
+
+ private:
+  static bool And() { return true; }
+  template <typename... T>
+  static bool And(bool arg1, T... args) {
+    return arg1 && And(args...);
+  }
+
+  Arguments* args_;
+};
 
 // DispatchToCallback converts all the JavaScript arguments to C++ types and
 // invokes the base::Callback.
-template<typename Sig>
-struct Dispatcher {
-};
+template <typename Sig>
+struct Dispatcher {};
 
-template<typename R>
-struct Dispatcher<R()> {
+template <typename ReturnType, typename... ArgTypes>
+struct Dispatcher<ReturnType(ArgTypes...)> {
   static void DispatchToCallback(
       const v8::FunctionCallbackInfo<v8::Value>& info) {
     Arguments args(info);
@@ -301,182 +194,13 @@
     CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
         v8_holder->Value());
 
-    typedef CallbackHolder<R()> HolderT;
+    typedef CallbackHolder<ReturnType(ArgTypes...)> HolderT;
     HolderT* holder = static_cast<HolderT*>(holder_base);
 
-    Invoker<R>::Go(&args, holder->callback);
-  }
-};
-
-template<typename R, typename P1>
-struct Dispatcher<R(P1)> {
-  static void DispatchToCallback(
-      const v8::FunctionCallbackInfo<v8::Value>& info) {
-    Arguments args(info);
-    v8::Handle<v8::External> v8_holder;
-    CHECK(args.GetData(&v8_holder));
-    CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
-        v8_holder->Value());
-
-    typedef CallbackHolder<R(P1)> HolderT;
-    HolderT* holder = static_cast<HolderT*>(holder_base);
-
-    typename CallbackParamTraits<P1>::LocalType a1;
-    if (!GetNextArgument(&args, holder->flags, true, &a1)) {
-      args.ThrowError();
-      return;
-    }
-
-    Invoker<R, P1>::Go(&args, holder->callback, a1);
-  }
-};
-
-template<typename R, typename P1, typename P2>
-struct Dispatcher<R(P1, P2)> {
-  static void DispatchToCallback(
-      const v8::FunctionCallbackInfo<v8::Value>& info) {
-    Arguments args(info);
-    v8::Handle<v8::External> v8_holder;
-    CHECK(args.GetData(&v8_holder));
-    CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
-        v8_holder->Value());
-
-    typedef CallbackHolder<R(P1, P2)> HolderT;
-    HolderT* holder = static_cast<HolderT*>(holder_base);
-
-    typename CallbackParamTraits<P1>::LocalType a1;
-    typename CallbackParamTraits<P2>::LocalType a2;
-    if (!GetNextArgument(&args, holder->flags, true, &a1) ||
-        !GetNextArgument(&args, holder->flags, false, &a2)) {
-      args.ThrowError();
-      return;
-    }
-
-    Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
-  }
-};
-
-template<typename R, typename P1, typename P2, typename P3>
-struct Dispatcher<R(P1, P2, P3)> {
-  static void DispatchToCallback(
-      const v8::FunctionCallbackInfo<v8::Value>& info) {
-    Arguments args(info);
-    v8::Handle<v8::External> v8_holder;
-    CHECK(args.GetData(&v8_holder));
-    CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
-        v8_holder->Value());
-
-    typedef CallbackHolder<R(P1, P2, P3)> HolderT;
-    HolderT* holder = static_cast<HolderT*>(holder_base);
-
-    typename CallbackParamTraits<P1>::LocalType a1;
-    typename CallbackParamTraits<P2>::LocalType a2;
-    typename CallbackParamTraits<P3>::LocalType a3;
-    if (!GetNextArgument(&args, holder->flags, true, &a1) ||
-        !GetNextArgument(&args, holder->flags, false, &a2) ||
-        !GetNextArgument(&args, holder->flags, false, &a3)) {
-      args.ThrowError();
-      return;
-    }
-
-    Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
-  }
-};
-
-template<typename R, typename P1, typename P2, typename P3, typename P4>
-struct Dispatcher<R(P1, P2, P3, P4)> {
-  static void DispatchToCallback(
-      const v8::FunctionCallbackInfo<v8::Value>& info) {
-    Arguments args(info);
-    v8::Handle<v8::External> v8_holder;
-    CHECK(args.GetData(&v8_holder));
-    CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
-        v8_holder->Value());
-
-    typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT;
-    HolderT* holder = static_cast<HolderT*>(holder_base);
-
-    typename CallbackParamTraits<P1>::LocalType a1;
-    typename CallbackParamTraits<P2>::LocalType a2;
-    typename CallbackParamTraits<P3>::LocalType a3;
-    typename CallbackParamTraits<P4>::LocalType a4;
-    if (!GetNextArgument(&args, holder->flags, true, &a1) ||
-        !GetNextArgument(&args, holder->flags, false, &a2) ||
-        !GetNextArgument(&args, holder->flags, false, &a3) ||
-        !GetNextArgument(&args, holder->flags, false, &a4)) {
-      args.ThrowError();
-      return;
-    }
-
-    Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
-  }
-};
-
-template<typename R, typename P1, typename P2, typename P3, typename P4,
-    typename P5>
-struct Dispatcher<R(P1, P2, P3, P4, P5)> {
-  static void DispatchToCallback(
-      const v8::FunctionCallbackInfo<v8::Value>& info) {
-    Arguments args(info);
-    v8::Handle<v8::External> v8_holder;
-    CHECK(args.GetData(&v8_holder));
-    CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
-        v8_holder->Value());
-
-    typedef CallbackHolder<R(P1, P2, P3, P4, P5)> HolderT;
-    HolderT* holder = static_cast<HolderT*>(holder_base);
-
-    typename CallbackParamTraits<P1>::LocalType a1;
-    typename CallbackParamTraits<P2>::LocalType a2;
-    typename CallbackParamTraits<P3>::LocalType a3;
-    typename CallbackParamTraits<P4>::LocalType a4;
-    typename CallbackParamTraits<P5>::LocalType a5;
-    if (!GetNextArgument(&args, holder->flags, true, &a1) ||
-        !GetNextArgument(&args, holder->flags, false, &a2) ||
-        !GetNextArgument(&args, holder->flags, false, &a3) ||
-        !GetNextArgument(&args, holder->flags, false, &a4) ||
-        !GetNextArgument(&args, holder->flags, false, &a5)) {
-      args.ThrowError();
-      return;
-    }
-
-    Invoker<R, P1, P2, P3, P4, P5>::Go(&args, holder->callback, a1, a2, a3, a4,
-        a5);
-  }
-};
-
-template<typename R, typename P1, typename P2, typename P3, typename P4,
-    typename P5, typename P6>
-struct Dispatcher<R(P1, P2, P3, P4, P5, P6)> {
-  static void DispatchToCallback(
-      const v8::FunctionCallbackInfo<v8::Value>& info) {
-    Arguments args(info);
-    v8::Handle<v8::External> v8_holder;
-    CHECK(args.GetData(&v8_holder));
-    CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
-        v8_holder->Value());
-
-    typedef CallbackHolder<R(P1, P2, P3, P4, P5, P6)> HolderT;
-    HolderT* holder = static_cast<HolderT*>(holder_base);
-
-    typename CallbackParamTraits<P1>::LocalType a1;
-    typename CallbackParamTraits<P2>::LocalType a2;
-    typename CallbackParamTraits<P3>::LocalType a3;
-    typename CallbackParamTraits<P4>::LocalType a4;
-    typename CallbackParamTraits<P5>::LocalType a5;
-    typename CallbackParamTraits<P6>::LocalType a6;
-    if (!GetNextArgument(&args, holder->flags, true, &a1) ||
-        !GetNextArgument(&args, holder->flags, false, &a2) ||
-        !GetNextArgument(&args, holder->flags, false, &a3) ||
-        !GetNextArgument(&args, holder->flags, false, &a4) ||
-        !GetNextArgument(&args, holder->flags, false, &a5) ||
-        !GetNextArgument(&args, holder->flags, false, &a6)) {
-      args.ThrowError();
-      return;
-    }
-
-    Invoker<R, P1, P2, P3, P4, P5, P6>::Go(&args, holder->callback, a1, a2, a3,
-        a4, a5, a6);
+    using Indices = typename IndicesGenerator<sizeof...(ArgTypes)>::type;
+    Invoker<Indices, ArgTypes...> invoker(&args, holder->flags);
+    if (invoker.IsOK())
+      invoker.DispatchToCallback(holder->callback);
   }
 };
 
diff --git a/gin/function_template.h.pump b/gin/function_template.h.pump
deleted file mode 100644
index 20b2821e..0000000
--- a/gin/function_template.h.pump
+++ /dev/null
@@ -1,240 +0,0 @@
-$$ This is a pump file for generating file templates.  Pump is a python
-$$ script that is part of the Google Test suite of utilities.  Description
-$$ can be found here:
-$$
-$$ http://code.google.com/p/googletest/wiki/PumpManual
-$$
-
-#ifndef GIN_FUNCTION_TEMPLATE_H_
-#define GIN_FUNCTION_TEMPLATE_H_
-
-$var MAX_ARITY = 6
-
-// 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 "base/callback.h"
-#include "base/logging.h"
-#include "gin/arguments.h"
-#include "gin/converter.h"
-#include "gin/gin_export.h"
-#include "v8/include/v8.h"
-
-namespace gin {
-
-class PerIsolateData;
-
-enum CreateFunctionTemplateFlags {
-  HolderIsFirstArgument = 1 << 0,
-};
-
-namespace internal {
-
-template<typename T>
-struct CallbackParamTraits {
-  typedef T LocalType;
-};
-template<typename T>
-struct CallbackParamTraits<const T&> {
-  typedef T LocalType;
-};
-template<typename T>
-struct CallbackParamTraits<const T*> {
-  typedef T* LocalType;
-};
-
-
-// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
-// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
-// DispatchToCallback, where it is invoked.
-
-// This simple base class is used so that we can share a single object template
-// among every CallbackHolder instance.
-class GIN_EXPORT CallbackHolderBase {
- public:
-  v8::Handle<v8::External> GetHandle(v8::Isolate* isolate);
-
- protected:
-  explicit CallbackHolderBase(v8::Isolate* isolate);
-  virtual ~CallbackHolderBase();
-
- private:
-  static void WeakCallback(
-      const v8::WeakCallbackData<v8::External, CallbackHolderBase>& data);
-
-  v8::Persistent<v8::External> v8_ref_;
-
-  DISALLOW_COPY_AND_ASSIGN(CallbackHolderBase);
-};
-
-template<typename Sig>
-class CallbackHolder : public CallbackHolderBase {
- public:
-  CallbackHolder(v8::Isolate* isolate,
-                 const base::Callback<Sig>& callback,
-                 int flags)
-      : CallbackHolderBase(isolate), callback(callback), flags(flags) {}
-  base::Callback<Sig> callback;
-  int flags;
- private:
-  virtual ~CallbackHolder() {}
-
-  DISALLOW_COPY_AND_ASSIGN(CallbackHolder);
-};
-
-
-// This set of templates invokes a base::Callback, converts the return type to a
-// JavaScript value, and returns that value to script via the provided
-// gin::Arguments object.
-//
-// In C++, you can declare the function foo(void), but you can't pass a void
-// expression to foo. As a result, we must specialize the case of Callbacks that
-// have the void return type.
-
-$range ARITY 0..MAX_ARITY
-$for ARITY [[
-$var INV_ARITY = MAX_ARITY - ARITY
-$range ARG 1..INV_ARITY
-$range VOID INV_ARITY+1..MAX_ARITY
-
-$if ARITY == 0 [[
-template<typename R$for ARG [[, typename P$(ARG) = void]]>
-struct Invoker {
-]] $else [[
-template<typename R$for ARG [[, typename P$(ARG)]]>
-struct Invoker<R$for ARG [[, P$(ARG)]]$for VOID [[, void]]> {
-]]
-
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<R($for ARG , [[P$(ARG)]])>& callback$for ARG [[, 
-      const P$(ARG)& a$(ARG)]]) {
-    args->Return(callback.Run($for ARG, [[a$(ARG)]]));
-  }
-};
-template<$for ARG , [[typename P$(ARG)]]>
-struct Invoker<void$for ARG [[, P$(ARG)]]$for VOID [[, void]]> {
-  inline static void Go(
-      Arguments* args,
-      const base::Callback<void($for ARG , [[P$(ARG)]])>& callback$for ARG [[,
-      const P$(ARG)& a$(ARG)]]) {
-    callback.Run($for ARG, [[a$(ARG)]]);
-  }
-};
-
-
-]]
-
-template<typename T>
-bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
-                     T* result) {
-  if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
-    return args->GetHolder(result);
-  } else {
-    return args->GetNext(result);
-  }
-}
-
-// For advanced use cases, we allow callers to request the unparsed Arguments
-// object and poke around in it directly.
-inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
-                            Arguments* result) {
-  *result = *args;
-  return true;
-}
-inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
-                            Arguments** result) {
-  *result = args;
-  return true;
-}
-
-// It's common for clients to just need the isolate, so we make that easy.
-inline bool GetNextArgument(Arguments* args, int create_flags,
-                            bool is_first, v8::Isolate** result) {
-  *result = args->isolate();
-  return true;
-}
-
-
-// DispatchToCallback converts all the JavaScript arguments to C++ types and
-// invokes the base::Callback.
-template<typename Sig>
-struct Dispatcher {
-};
-
-$range ARITY 0..MAX_ARITY
-$for ARITY [[
-$range ARG 1..ARITY
-
-template<typename R$for ARG [[, typename P$(ARG)]]>
-struct Dispatcher<R($for ARG , [[P$(ARG)]])> {
-  static void DispatchToCallback(
-      const v8::FunctionCallbackInfo<v8::Value>& info) {
-    Arguments args(info);
-    v8::Handle<v8::External> v8_holder;
-    CHECK(args.GetData(&v8_holder));
-    CallbackHolderBase* holder_base = reinterpret_cast<CallbackHolderBase*>(
-        v8_holder->Value());
-
-    typedef CallbackHolder<R($for ARG , [[P$(ARG)]])> HolderT;
-    HolderT* holder = static_cast<HolderT*>(holder_base);
-
-$if ARITY != 0 [[
-
-
-$for ARG [[    typename CallbackParamTraits<P$(ARG)>::LocalType a$(ARG);
-
-]]
-    if ($for ARG  ||
-        [[!GetNextArgument(&args, holder->flags, $if ARG == 1 [[true]] $else [[false]], &a$(ARG))]]) {
-      args.ThrowError();
-      return;
-    }
-
-]]
-
-    Invoker<R$for ARG [[, P$(ARG)]]>::Go(&args, holder->callback$for ARG [[, a$(ARG)]]);
-  }
-};
-
-]]
-
-}  // namespace internal
-
-
-// CreateFunctionTemplate creates a v8::FunctionTemplate that will create
-// JavaScript functions that execute a provided C++ function or base::Callback.
-// JavaScript arguments are automatically converted via gin::Converter, as is
-// the return value of the C++ function, if any.
-template<typename Sig>
-v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
-    v8::Isolate* isolate, const base::Callback<Sig> callback,
-    int callback_flags = 0) {
-  typedef internal::CallbackHolder<Sig> HolderT;
-  HolderT* holder = new HolderT(isolate, callback, callback_flags);
-
-  return v8::FunctionTemplate::New(
-      isolate,
-      &internal::Dispatcher<Sig>::DispatchToCallback,
-      ConvertToV8<v8::Handle<v8::External> >(isolate,
-                                             holder->GetHandle(isolate)));
-}
-
-// CreateFunctionHandler installs a CallAsFunction handler on the given
-// object template that forwards to a provided C++ function or base::Callback.
-template<typename Sig>
-void CreateFunctionHandler(v8::Isolate* isolate,
-                           v8::Local<v8::ObjectTemplate> tmpl,
-                           const base::Callback<Sig> callback,
-                           int callback_flags = 0) {
-  typedef internal::CallbackHolder<Sig> HolderT;
-  HolderT* holder = new HolderT(isolate, callback, callback_flags);
-  tmpl->SetCallAsFunctionHandler(&internal::Dispatcher<Sig>::DispatchToCallback,
-                                 ConvertToV8<v8::Handle<v8::External> >(
-                                     isolate, holder->GetHandle(isolate)));
-}
-
-}  // namespace gin
-
-#endif  // GIN_FUNCTION_TEMPLATE_H_
diff --git a/gin/interceptor_unittest.cc b/gin/interceptor_unittest.cc
index d267100..4d2d7fb8 100644
--- a/gin/interceptor_unittest.cc
+++ b/gin/interceptor_unittest.cc
@@ -31,9 +31,8 @@
   void set_value(int value) { value_ = value; }
 
   // gin::NamedPropertyInterceptor
-  virtual v8::Local<v8::Value> GetNamedProperty(v8::Isolate* isolate,
-                                                const std::string& property)
-      override {
+  v8::Local<v8::Value> GetNamedProperty(v8::Isolate* isolate,
+                                        const std::string& property) override {
     if (property == "value") {
       return ConvertToV8(isolate, value_);
     } else if (property == "func") {
@@ -42,16 +41,16 @@
       return v8::Local<v8::Value>();
     }
   }
-  virtual bool SetNamedProperty(v8::Isolate* isolate,
-                                const std::string& property,
-                                v8::Local<v8::Value> value) override {
+  bool SetNamedProperty(v8::Isolate* isolate,
+                        const std::string& property,
+                        v8::Local<v8::Value> value) override {
     if (property == "value") {
       ConvertFromV8(isolate, value, &value_);
       return true;
     }
     return false;
   }
-  virtual std::vector<std::string> EnumerateNamedProperties(
+  std::vector<std::string> EnumerateNamedProperties(
       v8::Isolate* isolate) override {
     std::vector<std::string> result;
     result.push_back("func");
@@ -60,15 +59,15 @@
   }
 
   // gin::IndexedPropertyInterceptor
-  virtual v8::Local<v8::Value> GetIndexedProperty(v8::Isolate* isolate,
-                                                  uint32_t index) override {
+  v8::Local<v8::Value> GetIndexedProperty(v8::Isolate* isolate,
+                                          uint32_t index) override {
     if (index == 0)
       return ConvertToV8(isolate, value_);
     return v8::Local<v8::Value>();
   }
-  virtual bool SetIndexedProperty(v8::Isolate* isolate,
-                                  uint32_t index,
-                                  v8::Local<v8::Value> value) override {
+  bool SetIndexedProperty(v8::Isolate* isolate,
+                          uint32_t index,
+                          v8::Local<v8::Value> value) override {
     if (index == 0) {
       ConvertFromV8(isolate, value, &value_);
       return true;
@@ -76,8 +75,8 @@
     // Don't allow bypassing the interceptor.
     return true;
   }
-  virtual std::vector<uint32_t> EnumerateIndexedProperties(v8::Isolate* isolate)
-      override {
+  std::vector<uint32_t> EnumerateIndexedProperties(
+      v8::Isolate* isolate) override {
     std::vector<uint32_t> result;
     result.push_back(0);
     return result;
@@ -89,11 +88,11 @@
         IndexedPropertyInterceptor(isolate, this),
         value_(0),
         template_cache_(isolate) {}
-  virtual ~MyInterceptor() {}
+  ~MyInterceptor() override {}
 
   // gin::Wrappable
-  virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate)
-      override {
+  ObjectTemplateBuilder GetObjectTemplateBuilder(
+      v8::Isolate* isolate) override {
     return Wrappable<MyInterceptor>::GetObjectTemplateBuilder(isolate)
         .AddNamedPropertyInterceptor()
         .AddIndexedPropertyInterceptor();
diff --git a/gin/modules/module_registry_unittest.cc b/gin/modules/module_registry_unittest.cc
index 57bc02d..3d784dc 100644
--- a/gin/modules/module_registry_unittest.cc
+++ b/gin/modules/module_registry_unittest.cc
@@ -35,7 +35,7 @@
  public:
   ModuleRegistryObserverImpl() : did_add_count_(0) {}
 
-  virtual void OnDidAddPendingModule(
+  void OnDidAddPendingModule(
       const std::string& id,
       const std::vector<std::string>& dependencies) override {
     did_add_count_++;
diff --git a/gin/modules/module_runner_delegate.h b/gin/modules/module_runner_delegate.h
index 421e23a8..bd174f0 100644
--- a/gin/modules/module_runner_delegate.h
+++ b/gin/modules/module_runner_delegate.h
@@ -26,7 +26,7 @@
  public:
   explicit ModuleRunnerDelegate(
       const std::vector<base::FilePath>& search_paths);
-  virtual ~ModuleRunnerDelegate();
+  ~ModuleRunnerDelegate() override;
 
   void AddBuiltinModule(const std::string& id, ModuleGetter getter);
   void AddBuiltinModule(const std::string& id,
@@ -39,11 +39,11 @@
   typedef std::map<std::string, ModuleGetterCallback> BuiltinModuleMap;
 
   // From ShellRunnerDelegate:
-  virtual v8::Handle<v8::ObjectTemplate> GetGlobalTemplate(
+  v8::Handle<v8::ObjectTemplate> GetGlobalTemplate(
       ShellRunner* runner,
       v8::Isolate* isolate) override;
-  virtual void DidCreateContext(ShellRunner* runner) override;
-  virtual void DidRunScript(ShellRunner* runner) override;
+  void DidCreateContext(ShellRunner* runner) override;
+  void DidRunScript(ShellRunner* runner) override;
 
   BuiltinModuleMap builtin_modules_;
   FileModuleProvider module_provider_;
diff --git a/gin/modules/timer.h b/gin/modules/timer.h
index 6284668..4913477 100644
--- a/gin/modules/timer.h
+++ b/gin/modules/timer.h
@@ -29,13 +29,12 @@
   static Handle<Timer> Create(TimerType type, v8::Isolate* isolate,
                               int delay_ms, v8::Handle<v8::Function> function);
 
-  virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
-      v8::Isolate* isolate) override;
+  ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
 
  private:
   Timer(v8::Isolate* isolate, bool repeating, int delay_ms,
         v8::Handle<v8::Function> function);
-  virtual ~Timer();
+  ~Timer() override;
   void OnTimerFired();
 
   base::Timer timer_;
@@ -55,10 +54,9 @@
 
  private:
   TimerModule();
-  virtual ~TimerModule();
+  ~TimerModule() override;
 
-  virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
-      v8::Isolate* isolate) override;
+  ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
 };
 
 }  // namespace gin
diff --git a/gin/modules/timer_unittest.cc b/gin/modules/timer_unittest.cc
index 42d7050..705bdc56 100644
--- a/gin/modules/timer_unittest.cc
+++ b/gin/modules/timer_unittest.cc
@@ -37,10 +37,9 @@
   Result() : count_(0) {
   }
 
-  virtual ~Result() {
-  }
+  ~Result() override {}
 
-  virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
+  ObjectTemplateBuilder GetObjectTemplateBuilder(
       v8::Isolate* isolate) override {
     return Wrappable<Result>::GetObjectTemplateBuilder(isolate)
         .SetProperty("count", &Result::count, &Result::set_count)
diff --git a/gin/per_context_data.h b/gin/per_context_data.h
index 0d11653..de8f179 100644
--- a/gin/per_context_data.h
+++ b/gin/per_context_data.h
@@ -24,7 +24,7 @@
  public:
   PerContextData(ContextHolder* context_holder,
                  v8::Handle<v8::Context> context);
-  virtual ~PerContextData();
+  ~PerContextData() override;
 
   // Can return NULL after the ContextHolder has detached from context.
   static PerContextData* From(v8::Handle<v8::Context> context);
diff --git a/gin/public/v8_platform.h b/gin/public/v8_platform.h
index 59e2147..a4fc28a 100644
--- a/gin/public/v8_platform.h
+++ b/gin/public/v8_platform.h
@@ -19,17 +19,17 @@
   static V8Platform* Get();
 
   // v8::Platform implementation.
-  virtual void CallOnBackgroundThread(
+  void CallOnBackgroundThread(
       v8::Task* task,
       v8::Platform::ExpectedRuntime expected_runtime) override;
-  virtual void CallOnForegroundThread(v8::Isolate* isolate,
-                                      v8::Task* task) override;
-  virtual double MonotonicallyIncreasingTime() override;
+  void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override;
+  double MonotonicallyIncreasingTime() override;
+
  private:
   friend struct base::DefaultLazyInstanceTraits<V8Platform>;
 
   V8Platform();
-  virtual ~V8Platform();
+  ~V8Platform() override;
 
   DISALLOW_COPY_AND_ASSIGN(V8Platform);
 };
diff --git a/gin/run_microtasks_observer.h b/gin/run_microtasks_observer.h
index d31d804..7f1431f 100644
--- a/gin/run_microtasks_observer.h
+++ b/gin/run_microtasks_observer.h
@@ -18,8 +18,8 @@
  public:
   RunMicrotasksObserver(v8::Isolate* isolate);
 
-  virtual void WillProcessTask(const base::PendingTask& pending_task) override;
-  virtual void DidProcessTask(const base::PendingTask& pending_task) override;
+  void WillProcessTask(const base::PendingTask& pending_task) override;
+  void DidProcessTask(const base::PendingTask& pending_task) override;
 
  private:
   v8::Isolate* isolate_;
diff --git a/gin/shell/gin_main.cc b/gin/shell/gin_main.cc
index 77b167a4..b17ec0af 100644
--- a/gin/shell/gin_main.cc
+++ b/gin/shell/gin_main.cc
@@ -44,8 +44,7 @@
     AddBuiltinModule(Console::kModuleName, Console::GetModule);
   }
 
-  virtual void UnhandledException(ShellRunner* runner,
-                                  TryCatch& try_catch) override {
+  void UnhandledException(ShellRunner* runner, TryCatch& try_catch) override {
     ModuleRunnerDelegate::UnhandledException(runner, try_catch);
     LOG(ERROR) << try_catch.GetStackTrace();
   }
diff --git a/gin/shell_runner.h b/gin/shell_runner.h
index ca88a5d..9a5b4ef 100644
--- a/gin/shell_runner.h
+++ b/gin/shell_runner.h
@@ -37,19 +37,19 @@
 class GIN_EXPORT ShellRunner : public Runner {
  public:
   ShellRunner(ShellRunnerDelegate* delegate, v8::Isolate* isolate);
-  virtual ~ShellRunner();
+  ~ShellRunner() override;
 
   // Before running script in this context, you'll need to enter the runner's
   // context by creating an instance of Runner::Scope on the stack.
 
   // Runner overrides:
-  virtual void Run(const std::string& source,
-                   const std::string& resource_name) override;
-  virtual v8::Handle<v8::Value> Call(v8::Handle<v8::Function> function,
-                                     v8::Handle<v8::Value> receiver,
-                                     int argc,
-                                     v8::Handle<v8::Value> argv[]) override;
-  virtual ContextHolder* GetContextHolder() override;
+  void Run(const std::string& source,
+           const std::string& resource_name) override;
+  v8::Handle<v8::Value> Call(v8::Handle<v8::Function> function,
+                             v8::Handle<v8::Value> receiver,
+                             int argc,
+                             v8::Handle<v8::Value> argv[]) override;
+  ContextHolder* GetContextHolder() override;
 
  private:
   friend class Scope;
diff --git a/gin/test/file_runner.h b/gin/test/file_runner.h
index 5082cd59..9f7ab4b0 100644
--- a/gin/test/file_runner.h
+++ b/gin/test/file_runner.h
@@ -20,12 +20,11 @@
 class FileRunnerDelegate : public ModuleRunnerDelegate {
  public:
   FileRunnerDelegate();
-  virtual ~FileRunnerDelegate();
+  ~FileRunnerDelegate() override;
 
  private:
   // From ModuleRunnerDelegate:
-  virtual void UnhandledException(ShellRunner* runner,
-                                  TryCatch& try_catch) override;
+  void UnhandledException(ShellRunner* runner, TryCatch& try_catch) override;
 
   DISALLOW_COPY_AND_ASSIGN(FileRunnerDelegate);
 };
diff --git a/gin/wrappable_unittest.cc b/gin/wrappable_unittest.cc
index 0e10c32..ef0dce4 100644
--- a/gin/wrappable_unittest.cc
+++ b/gin/wrappable_unittest.cc
@@ -40,9 +40,8 @@
 
  protected:
   MyObject() : value_(0) {}
-  virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
-      v8::Isolate* isolate) override;
-  virtual ~MyObject() {}
+  ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
+  ~MyObject() override {}
 
  private:
   int value_;
@@ -61,7 +60,7 @@
   std::string result;
 
  private:
-  virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
+  ObjectTemplateBuilder GetObjectTemplateBuilder(
       v8::Isolate* isolate) override {
     return MyObject::GetObjectTemplateBuilder(isolate)
         .SetMethod("sayHello", &MyObjectSubclass::SayHello);
@@ -70,8 +69,7 @@
   MyObjectSubclass() {
   }
 
-  virtual ~MyObjectSubclass() {
-  }
+  ~MyObjectSubclass() override {}
 };
 
 class MyCallableObject : public Wrappable<MyCallableObject> {
@@ -85,7 +83,7 @@
   int result() { return result_; }
 
  private:
-  virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
+  ObjectTemplateBuilder GetObjectTemplateBuilder(
       v8::Isolate* isolate) override {
     return Wrappable<MyCallableObject>::GetObjectTemplateBuilder(isolate)
         .SetCallAsFunctionHandler(&MyCallableObject::Call);
@@ -94,14 +92,13 @@
   MyCallableObject() : result_(0) {
   }
 
-  virtual ~MyCallableObject() {
-  }
+  ~MyCallableObject() override {}
 
-  void Call(int val, const gin::Arguments& arguments) {
+  void Call(int val1, int val2, int val3, const gin::Arguments& arguments) {
     if (arguments.IsConstructCall())
       arguments.ThrowTypeError("Cannot be called as constructor.");
     else
-      result_ = val;
+      result_ = val1;
   }
 
   int result_;
@@ -233,7 +230,7 @@
   EXPECT_EQ(0, object->result());
   v8::Handle<v8::String> source = StringToV8(isolate,
                                              "(function(obj) {"
-                                             "obj(42);"
+                                             "obj(42, 2, 5);"
                                              "})");
   gin::TryCatch try_catch;
   v8::Handle<v8::Script> script = v8::Script::Compile(source);
@@ -256,7 +253,7 @@
   EXPECT_EQ(0, object->result());
   v8::Handle<v8::String> source = StringToV8(isolate,
                                              "(function(obj) {"
-                                             "new obj(42);"
+                                             "new obj(42, 2, 5);"
                                              "})");
   gin::TryCatch try_catch;
   v8::Handle<v8::Script> script = v8::Script::Compile(source);
diff --git a/google_apis/drive/auth_service.cc b/google_apis/drive/auth_service.cc
index 82fc529..db497609 100644
--- a/google_apis/drive/auth_service.cc
+++ b/google_apis/drive/auth_service.cc
@@ -41,15 +41,15 @@
               net::URLRequestContextGetter* url_request_context_getter,
               const AuthStatusCallback& callback,
               const std::vector<std::string>& scopes);
-  virtual ~AuthRequest();
+  ~AuthRequest() override;
 
  private:
   // Overridden from OAuth2TokenService::Consumer:
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
   AuthStatusCallback callback_;
   scoped_ptr<OAuth2TokenService::Request> request_;
diff --git a/google_apis/drive/auth_service.h b/google_apis/drive/auth_service.h
index 2c74ad1..381abebc 100644
--- a/google_apis/drive/auth_service.h
+++ b/google_apis/drive/auth_service.h
@@ -37,21 +37,21 @@
               const std::string& account_id,
               net::URLRequestContextGetter* url_request_context_getter,
               const std::vector<std::string>& scopes);
-  virtual ~AuthService();
+  ~AuthService() override;
 
   // Overriden from AuthServiceInterface:
-  virtual void AddObserver(AuthServiceObserver* observer) override;
-  virtual void RemoveObserver(AuthServiceObserver* observer) override;
-  virtual void StartAuthentication(const AuthStatusCallback& callback) override;
-  virtual bool HasAccessToken() const override;
-  virtual bool HasRefreshToken() const override;
-  virtual const std::string& access_token() const override;
-  virtual void ClearAccessToken() override;
-  virtual void ClearRefreshToken() override;
+  void AddObserver(AuthServiceObserver* observer) override;
+  void RemoveObserver(AuthServiceObserver* observer) override;
+  void StartAuthentication(const AuthStatusCallback& callback) override;
+  bool HasAccessToken() const override;
+  bool HasRefreshToken() const override;
+  const std::string& access_token() const override;
+  void ClearAccessToken() override;
+  void ClearRefreshToken() override;
 
   // Overridden from OAuth2TokenService::Observer:
-  virtual void OnRefreshTokenAvailable(const std::string& account_id) override;
-  virtual void OnRefreshTokenRevoked(const std::string& account_id) override;
+  void OnRefreshTokenAvailable(const std::string& account_id) override;
+  void OnRefreshTokenRevoked(const std::string& account_id) override;
 
  private:
   // Called when the state of the refresh token changes.
diff --git a/google_apis/drive/base_requests.h b/google_apis/drive/base_requests.h
index 5721933..fb1bf08 100644
--- a/google_apis/drive/base_requests.h
+++ b/google_apis/drive/base_requests.h
@@ -89,7 +89,7 @@
   ResponseWriter(base::SequencedTaskRunner* file_task_runner,
                  const base::FilePath& file_path,
                  const GetContentCallback& get_content_callback);
-  virtual ~ResponseWriter();
+  ~ResponseWriter() override;
 
   const std::string& data() const { return data_; }
 
@@ -97,11 +97,11 @@
   void DisownFile();
 
   // URLFetcherResponseWriter overrides:
-  virtual int Initialize(const net::CompletionCallback& callback) override;
-  virtual int Write(net::IOBuffer* buffer,
-                    int num_bytes,
-                    const net::CompletionCallback& callback) override;
-  virtual int Finish(const net::CompletionCallback& callback) override;
+  int Initialize(const net::CompletionCallback& callback) override;
+  int Write(net::IOBuffer* buffer,
+            int num_bytes,
+            const net::CompletionCallback& callback) override;
+  int Finish(const net::CompletionCallback& callback) override;
 
  private:
   void DidWrite(scoped_refptr<net::IOBuffer> buffer,
@@ -123,15 +123,15 @@
                             public net::URLFetcherDelegate {
  public:
   // AuthenticatedRequestInterface overrides.
-  virtual void Start(const std::string& access_token,
-                     const std::string& custom_user_agent,
-                     const ReAuthenticateCallback& callback) override;
-  virtual base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() override;
-  virtual void Cancel() override;
+  void Start(const std::string& access_token,
+             const std::string& custom_user_agent,
+             const ReAuthenticateCallback& callback) override;
+  base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() override;
+  void Cancel() override;
 
  protected:
   explicit UrlFetchRequestBase(RequestSender* sender);
-  virtual ~UrlFetchRequestBase();
+  ~UrlFetchRequestBase() override;
 
   // Gets URL for the request.
   virtual GURL GetURL() const = 0;
@@ -194,10 +194,10 @@
 
  private:
   // URLFetcherDelegate overrides.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // AuthenticatedRequestInterface overrides.
-  virtual void OnAuthFailed(GDataErrorCode code) override;
+  void OnAuthFailed(GDataErrorCode code) override;
 
   ReAuthenticateCallback re_authenticate_callback_;
   int re_authenticate_count_;
@@ -228,12 +228,12 @@
   // failure. It must not be null.
   EntryActionRequest(RequestSender* sender,
                      const EntryActionCallback& callback);
-  virtual ~EntryActionRequest();
+  ~EntryActionRequest() override;
 
  protected:
   // Overridden from UrlFetchRequestBase.
-  virtual void ProcessURLFetchResults(const net::URLFetcher* source) override;
-  virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) override;
+  void ProcessURLFetchResults(const net::URLFetcher* source) override;
+  void RunCallbackOnPrematureFailure(GDataErrorCode code) override;
 
  private:
   const EntryActionCallback callback_;
@@ -268,12 +268,12 @@
                             const InitiateUploadCallback& callback,
                             const std::string& content_type,
                             int64 content_length);
-  virtual ~InitiateUploadRequestBase();
+  ~InitiateUploadRequestBase() override;
 
   // UrlFetchRequestBase overrides.
-  virtual void ProcessURLFetchResults(const net::URLFetcher* source) override;
-  virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) override;
-  virtual std::vector<std::string> GetExtraRequestHeaders() const override;
+  void ProcessURLFetchResults(const net::URLFetcher* source) override;
+  void RunCallbackOnPrematureFailure(GDataErrorCode code) override;
+  std::vector<std::string> GetExtraRequestHeaders() const override;
 
  private:
   const InitiateUploadCallback callback_;
@@ -311,13 +311,13 @@
  protected:
   // |upload_url| is the URL of where to upload the file to.
   UploadRangeRequestBase(RequestSender* sender, const GURL& upload_url);
-  virtual ~UploadRangeRequestBase();
+  ~UploadRangeRequestBase() override;
 
   // UrlFetchRequestBase overrides.
-  virtual GURL GetURL() const override;
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual void ProcessURLFetchResults(const net::URLFetcher* source) override;
-  virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) override;
+  GURL GetURL() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  void ProcessURLFetchResults(const net::URLFetcher* source) override;
+  void RunCallbackOnPrematureFailure(GDataErrorCode code) override;
 
   // This method will be called when the request is done, regardless of
   // whether it is succeeded or failed.
@@ -378,14 +378,14 @@
                           int64 content_length,
                           const std::string& content_type,
                           const base::FilePath& local_file_path);
-  virtual ~ResumeUploadRequestBase();
+  ~ResumeUploadRequestBase() override;
 
   // UrlFetchRequestBase overrides.
-  virtual std::vector<std::string> GetExtraRequestHeaders() const override;
-  virtual bool GetContentFile(base::FilePath* local_file_path,
-                              int64* range_offset,
-                              int64* range_length,
-                              std::string* upload_content_type) override;
+  std::vector<std::string> GetExtraRequestHeaders() const override;
+  bool GetContentFile(base::FilePath* local_file_path,
+                      int64* range_offset,
+                      int64* range_length,
+                      std::string* upload_content_type) override;
 
  private:
   // The parameters for the request. See ResumeUploadParams for the details.
@@ -416,11 +416,11 @@
   GetUploadStatusRequestBase(RequestSender* sender,
                              const GURL& upload_url,
                              int64 content_length);
-  virtual ~GetUploadStatusRequestBase();
+  ~GetUploadStatusRequestBase() override;
 
  protected:
   // UrlFetchRequestBase overrides.
-  virtual std::vector<std::string> GetExtraRequestHeaders() const override;
+  std::vector<std::string> GetExtraRequestHeaders() const override;
 
  private:
   const int64 content_length_;
@@ -462,20 +462,20 @@
       const ProgressCallback& progress_callback,
       const GURL& download_url,
       const base::FilePath& output_file_path);
-  virtual ~DownloadFileRequestBase();
+  ~DownloadFileRequestBase() override;
 
  protected:
   // UrlFetchRequestBase overrides.
-  virtual GURL GetURL() const override;
-  virtual void GetOutputFilePath(
-      base::FilePath* local_file_path,
-      GetContentCallback* get_content_callback) override;
-  virtual void ProcessURLFetchResults(const net::URLFetcher* source) override;
-  virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) override;
+  GURL GetURL() const override;
+  void GetOutputFilePath(base::FilePath* local_file_path,
+                         GetContentCallback* get_content_callback) override;
+  void ProcessURLFetchResults(const net::URLFetcher* source) override;
+  void RunCallbackOnPrematureFailure(GDataErrorCode code) override;
 
   // net::URLFetcherDelegate overrides.
-  virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source,
-                                          int64 current, int64 total) override;
+  void OnURLFetchDownloadProgress(const net::URLFetcher* source,
+                                  int64 current,
+                                  int64 total) override;
 
  private:
   const DownloadActionCallback download_action_callback_;
diff --git a/google_apis/drive/base_requests_unittest.cc b/google_apis/drive/base_requests_unittest.cc
index 3865eee..e4e918b 100644
--- a/google_apis/drive/base_requests_unittest.cc
+++ b/google_apis/drive/base_requests_unittest.cc
@@ -35,15 +35,14 @@
         url_(url) {
   }
 
-  virtual ~FakeUrlFetchRequest() {
-  }
+  ~FakeUrlFetchRequest() override {}
 
  protected:
-  virtual GURL GetURL() const override { return url_; }
-  virtual void ProcessURLFetchResults(const net::URLFetcher* source) override {
+  GURL GetURL() const override { return url_; }
+  void ProcessURLFetchResults(const net::URLFetcher* source) override {
     callback_.Run(GetErrorCode());
   }
-  virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) override {
+  void RunCallbackOnPrematureFailure(GDataErrorCode code) override {
     callback_.Run(code);
   }
 
diff --git a/google_apis/drive/drive_api_requests.h b/google_apis/drive/drive_api_requests.h
index a160eeb9..f7ff826 100644
--- a/google_apis/drive/drive_api_requests.h
+++ b/google_apis/drive/drive_api_requests.h
@@ -47,7 +47,7 @@
 class DriveApiPartialFieldRequest : public UrlFetchRequestBase {
  public:
   explicit DriveApiPartialFieldRequest(RequestSender* sender);
-  virtual ~DriveApiPartialFieldRequest();
+  ~DriveApiPartialFieldRequest() override;
 
   // Optional parameter.
   const std::string& fields() const { return fields_; }
@@ -55,7 +55,7 @@
 
  protected:
   // UrlFetchRequestBase overrides.
-  virtual GURL GetURL() const override;
+  GURL GetURL() const override;
 
   // Derived classes should override GetURLInternal instead of GetURL()
   // directly.
@@ -146,7 +146,7 @@
   FilesGetRequest(RequestSender* sender,
                   const DriveApiUrlGenerator& url_generator,
                   const FileResourceCallback& callback);
-  virtual ~FilesGetRequest();
+  ~FilesGetRequest() override;
 
   // Required parameter.
   const std::string& file_id() const { return file_id_; }
@@ -154,7 +154,7 @@
 
  protected:
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -172,7 +172,7 @@
   FilesAuthorizeRequest(RequestSender* sender,
                         const DriveApiUrlGenerator& url_generator,
                         const FileResourceCallback& callback);
-  virtual ~FilesAuthorizeRequest();
+  ~FilesAuthorizeRequest() override;
 
   // Required parameter.
   const std::string& file_id() const { return file_id_; }
@@ -182,10 +182,10 @@
 
  protected:
   // Overridden from GetDataRequest.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
 
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -207,7 +207,7 @@
   FilesInsertRequest(RequestSender* sender,
                      const DriveApiUrlGenerator& url_generator,
                      const FileResourceCallback& callback);
-  virtual ~FilesInsertRequest();
+  ~FilesInsertRequest() override;
 
   // Optional request body.
   const base::Time& last_viewed_by_me_date() const {
@@ -235,12 +235,12 @@
 
  protected:
   // Overridden from GetDataRequest.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual bool GetContentData(std::string* upload_content_type,
-                              std::string* upload_content) override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  bool GetContentData(std::string* upload_content_type,
+                      std::string* upload_content) override;
 
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -264,7 +264,7 @@
   FilesPatchRequest(RequestSender* sender,
                     const DriveApiUrlGenerator& url_generator,
                     const FileResourceCallback& callback);
-  virtual ~FilesPatchRequest();
+  ~FilesPatchRequest() override;
 
   // Required parameter.
   const std::string& file_id() const { return file_id_; }
@@ -305,13 +305,13 @@
 
  protected:
   // Overridden from URLFetchRequestBase.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual std::vector<std::string> GetExtraRequestHeaders() const override;
-  virtual bool GetContentData(std::string* upload_content_type,
-                              std::string* upload_content) override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  std::vector<std::string> GetExtraRequestHeaders() const override;
+  bool GetContentData(std::string* upload_content_type,
+                      std::string* upload_content) override;
 
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -339,7 +339,7 @@
   FilesCopyRequest(RequestSender* sender,
                    const DriveApiUrlGenerator& url_generator,
                    const FileResourceCallback& callback);
-  virtual ~FilesCopyRequest();
+  ~FilesCopyRequest() override;
 
   // Required parameter.
   const std::string& file_id() const { return file_id_; }
@@ -359,12 +359,12 @@
 
  protected:
   // Overridden from URLFetchRequestBase.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual bool GetContentData(std::string* upload_content_type,
-                              std::string* upload_content) override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  bool GetContentData(std::string* upload_content_type,
+                      std::string* upload_content) override;
 
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -390,7 +390,7 @@
   FilesListRequest(RequestSender* sender,
                    const DriveApiUrlGenerator& url_generator,
                    const FileListCallback& callback);
-  virtual ~FilesListRequest();
+  ~FilesListRequest() override;
 
   // Optional parameter
   int max_results() const { return max_results_; }
@@ -406,7 +406,7 @@
 
  protected:
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -427,14 +427,14 @@
  public:
   FilesListNextPageRequest(RequestSender* sender,
                            const FileListCallback& callback);
-  virtual ~FilesListNextPageRequest();
+  ~FilesListNextPageRequest() override;
 
   const GURL& next_link() const { return next_link_; }
   void set_next_link(const GURL& next_link) { next_link_ = next_link; }
 
  protected:
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   GURL next_link_;
@@ -452,7 +452,7 @@
   FilesDeleteRequest(RequestSender* sender,
                      const DriveApiUrlGenerator& url_generator,
                      const EntryActionCallback& callback);
-  virtual ~FilesDeleteRequest();
+  ~FilesDeleteRequest() override;
 
   // Required parameter.
   const std::string& file_id() const { return file_id_; }
@@ -461,9 +461,9 @@
 
  protected:
   // Overridden from UrlFetchRequestBase.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual GURL GetURL() const override;
-  virtual std::vector<std::string> GetExtraRequestHeaders() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  GURL GetURL() const override;
+  std::vector<std::string> GetExtraRequestHeaders() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -483,7 +483,7 @@
   FilesTrashRequest(RequestSender* sender,
                     const DriveApiUrlGenerator& url_generator,
                     const FileResourceCallback& callback);
-  virtual ~FilesTrashRequest();
+  ~FilesTrashRequest() override;
 
   // Required parameter.
   const std::string& file_id() const { return file_id_; }
@@ -491,10 +491,10 @@
 
  protected:
   // Overridden from UrlFetchRequestBase.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
 
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -513,11 +513,11 @@
   AboutGetRequest(RequestSender* sender,
                   const DriveApiUrlGenerator& url_generator,
                   const AboutResourceCallback& callback);
-  virtual ~AboutGetRequest();
+  ~AboutGetRequest() override;
 
  protected:
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -538,7 +538,7 @@
   ChangesListRequest(RequestSender* sender,
                      const DriveApiUrlGenerator& url_generator,
                      const ChangeListCallback& callback);
-  virtual ~ChangesListRequest();
+  ~ChangesListRequest() override;
 
   // Optional parameter
   bool include_deleted() const { return include_deleted_; }
@@ -561,7 +561,7 @@
 
  protected:
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -583,14 +583,14 @@
  public:
   ChangesListNextPageRequest(RequestSender* sender,
                              const ChangeListCallback& callback);
-  virtual ~ChangesListNextPageRequest();
+  ~ChangesListNextPageRequest() override;
 
   const GURL& next_link() const { return next_link_; }
   void set_next_link(const GURL& next_link) { next_link_ = next_link; }
 
  protected:
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   GURL next_link_;
@@ -609,11 +609,11 @@
                   const DriveApiUrlGenerator& url_generator,
                   bool use_internal_endpoint,
                   const AppListCallback& callback);
-  virtual ~AppsListRequest();
+  ~AppsListRequest() override;
 
  protected:
   // Overridden from DriveApiDataRequest.
-  virtual GURL GetURLInternal() const override;
+  GURL GetURLInternal() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -632,7 +632,7 @@
   AppsDeleteRequest(RequestSender* sender,
                     const DriveApiUrlGenerator& url_generator,
                     const EntryActionCallback& callback);
-  virtual ~AppsDeleteRequest();
+  ~AppsDeleteRequest() override;
 
   // Required parameter.
   const std::string& app_id() const { return app_id_; }
@@ -640,8 +640,8 @@
 
  protected:
   // Overridden from UrlFetchRequestBase.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual GURL GetURL() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  GURL GetURL() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -660,7 +660,7 @@
   ChildrenInsertRequest(RequestSender* sender,
                         const DriveApiUrlGenerator& url_generator,
                         const EntryActionCallback& callback);
-  virtual ~ChildrenInsertRequest();
+  ~ChildrenInsertRequest() override;
 
   // Required parameter.
   const std::string& folder_id() const { return folder_id_; }
@@ -674,10 +674,10 @@
 
  protected:
   // UrlFetchRequestBase overrides.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual GURL GetURL() const override;
-  virtual bool GetContentData(std::string* upload_content_type,
-                              std::string* upload_content) override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  GURL GetURL() const override;
+  bool GetContentData(std::string* upload_content_type,
+                      std::string* upload_content) override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -698,7 +698,7 @@
   ChildrenDeleteRequest(RequestSender* sender,
                         const DriveApiUrlGenerator& url_generator,
                         const EntryActionCallback& callback);
-  virtual ~ChildrenDeleteRequest();
+  ~ChildrenDeleteRequest() override;
 
   // Required parameter.
   const std::string& child_id() const { return child_id_; }
@@ -713,8 +713,8 @@
 
  protected:
   // UrlFetchRequestBase overrides.
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual GURL GetURL() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  GURL GetURL() const override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -740,7 +740,7 @@
                                const std::string& parent_resource_id,
                                const std::string& title,
                                const InitiateUploadCallback& callback);
-  virtual ~InitiateUploadNewFileRequest();
+  ~InitiateUploadNewFileRequest() override;
 
   // Optional parameters.
   const base::Time& modified_date() const { return modified_date_; }
@@ -756,10 +756,10 @@
 
  protected:
   // UrlFetchRequestBase overrides.
-  virtual GURL GetURL() const override;
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual bool GetContentData(std::string* upload_content_type,
-                              std::string* upload_content) override;
+  GURL GetURL() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  bool GetContentData(std::string* upload_content_type,
+                      std::string* upload_content) override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -790,8 +790,7 @@
                                     const std::string& resource_id,
                                     const std::string& etag,
                                     const InitiateUploadCallback& callback);
-  virtual ~InitiateUploadExistingFileRequest();
-
+  ~InitiateUploadExistingFileRequest() override;
 
   // Optional parameters.
   const std::string& parent_resource_id() const { return parent_resource_id_; }
@@ -813,11 +812,11 @@
 
  protected:
   // UrlFetchRequestBase overrides.
-  virtual GURL GetURL() const override;
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual std::vector<std::string> GetExtraRequestHeaders() const override;
-  virtual bool GetContentData(std::string* upload_content_type,
-                              std::string* upload_content) override;
+  GURL GetURL() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  std::vector<std::string> GetExtraRequestHeaders() const override;
+  bool GetContentData(std::string* upload_content_type,
+                      std::string* upload_content) override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
@@ -853,16 +852,16 @@
                       const base::FilePath& local_file_path,
                       const UploadRangeCallback& callback,
                       const ProgressCallback& progress_callback);
-  virtual ~ResumeUploadRequest();
+  ~ResumeUploadRequest() override;
 
  protected:
   // UploadRangeRequestBase overrides.
-  virtual void OnRangeRequestComplete(
-      const UploadRangeResponse& response,
-      scoped_ptr<base::Value> value) override;
+  void OnRangeRequestComplete(const UploadRangeResponse& response,
+                              scoped_ptr<base::Value> value) override;
   // content::UrlFetcherDelegate overrides.
-  virtual void OnURLFetchUploadProgress(const net::URLFetcher* source,
-                                        int64 current, int64 total) override;
+  void OnURLFetchUploadProgress(const net::URLFetcher* source,
+                                int64 current,
+                                int64 total) override;
 
  private:
   const UploadRangeCallback callback_;
@@ -882,13 +881,12 @@
                          const GURL& upload_url,
                          int64 content_length,
                          const UploadRangeCallback& callback);
-  virtual ~GetUploadStatusRequest();
+  ~GetUploadStatusRequest() override;
 
  protected:
   // UploadRangeRequestBase overrides.
-  virtual void OnRangeRequestComplete(
-      const UploadRangeResponse& response,
-      scoped_ptr<base::Value> value) override;
+  void OnRangeRequestComplete(const UploadRangeResponse& response,
+                              scoped_ptr<base::Value> value) override;
 
  private:
   const UploadRangeCallback callback_;
@@ -909,7 +907,7 @@
                       const DownloadActionCallback& download_action_callback,
                       const GetContentCallback& get_content_callback,
                       const ProgressCallback& progress_callback);
-  virtual ~DownloadFileRequest();
+  ~DownloadFileRequest() override;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadFileRequest);
 };
@@ -939,7 +937,7 @@
   PermissionsInsertRequest(RequestSender* sender,
                            const DriveApiUrlGenerator& url_generator,
                            const EntryActionCallback& callback);
-  virtual ~PermissionsInsertRequest();
+  ~PermissionsInsertRequest() override;
 
   void set_id(const std::string& id) { id_ = id; }
   void set_type(PermissionType type) { type_ = type; }
@@ -947,10 +945,10 @@
   void set_value(const std::string& value) { value_ = value; }
 
   // UrlFetchRequestBase overrides.
-  virtual GURL GetURL() const override;
-  virtual net::URLFetcher::RequestType GetRequestType() const override;
-  virtual bool GetContentData(std::string* upload_content_type,
-                              std::string* upload_content) override;
+  GURL GetURL() const override;
+  net::URLFetcher::RequestType GetRequestType() const override;
+  bool GetContentData(std::string* upload_content_type,
+                      std::string* upload_content) override;
 
  private:
   const DriveApiUrlGenerator url_generator_;
diff --git a/google_apis/drive/dummy_auth_service.h b/google_apis/drive/dummy_auth_service.h
index 38b6774..87236e6a 100644
--- a/google_apis/drive/dummy_auth_service.h
+++ b/google_apis/drive/dummy_auth_service.h
@@ -24,14 +24,14 @@
   const std::string& refresh_token() const { return refresh_token_; }
 
   // AuthServiceInterface overrides.
-  virtual void AddObserver(AuthServiceObserver* observer) override;
-  virtual void RemoveObserver(AuthServiceObserver* observer) override;
-  virtual void StartAuthentication(const AuthStatusCallback& callback) override;
-  virtual bool HasAccessToken() const override;
-  virtual bool HasRefreshToken() const override;
-  virtual const std::string& access_token() const override;
-  virtual void ClearAccessToken() override;
-  virtual void ClearRefreshToken() override;
+  void AddObserver(AuthServiceObserver* observer) override;
+  void RemoveObserver(AuthServiceObserver* observer) override;
+  void StartAuthentication(const AuthStatusCallback& callback) override;
+  bool HasAccessToken() const override;
+  bool HasRefreshToken() const override;
+  const std::string& access_token() const override;
+  void ClearAccessToken() override;
+  void ClearRefreshToken() override;
 
  private:
   std::string access_token_;
diff --git a/google_apis/drive/gdata_wapi_parser.h b/google_apis/drive/gdata_wapi_parser.h
index f7bce81..5d2ec50 100644
--- a/google_apis/drive/gdata_wapi_parser.h
+++ b/google_apis/drive/gdata_wapi_parser.h
@@ -317,7 +317,7 @@
     ENTRY_KIND_FILE
   };
   ResourceEntry();
-  virtual ~ResourceEntry();
+  ~ResourceEntry() override;
 
   // Extracts "entry" dictionary from the JSON value, and parse the contents,
   // using CreateFrom(). Returns NULL on failure. The input JSON data, coming
@@ -517,7 +517,7 @@
 class ResourceList : public CommonMetadata {
  public:
   ResourceList();
-  virtual ~ResourceList();
+  ~ResourceList() override;
 
   // Extracts "feed" dictionary from the JSON value, and parse the contents,
   // using CreateFrom(). Returns NULL on failure. The input JSON data, coming
diff --git a/google_apis/drive/gdata_wapi_requests.h b/google_apis/drive/gdata_wapi_requests.h
index aa4e69f..4a9962ba 100644
--- a/google_apis/drive/gdata_wapi_requests.h
+++ b/google_apis/drive/gdata_wapi_requests.h
@@ -28,13 +28,13 @@
                           const std::string& resource_id,
                           const GURL& embed_origin,
                           const GetResourceEntryCallback& callback);
-  virtual ~GetResourceEntryRequest();
+  ~GetResourceEntryRequest() override;
 
  protected:
   // UrlFetchRequestBase overrides.
-  virtual void ProcessURLFetchResults(const net::URLFetcher* source) override;
-  virtual void RunCallbackOnPrematureFailure(GDataErrorCode error) override;
-  virtual GURL GetURL() const override;
+  void ProcessURLFetchResults(const net::URLFetcher* source) override;
+  void RunCallbackOnPrematureFailure(GDataErrorCode error) override;
+  GURL GetURL() const override;
 
  private:
   void OnDataParsed(GDataErrorCode error, scoped_ptr<ResourceEntry> entry);
diff --git a/google_apis/drive/request_sender_unittest.cc b/google_apis/drive/request_sender_unittest.cc
index 7771164..5452578 100644
--- a/google_apis/drive/request_sender_unittest.cc
+++ b/google_apis/drive/request_sender_unittest.cc
@@ -31,8 +31,7 @@
  public:
   TestAuthService() : auth_try_count_(0) {}
 
-  virtual void StartAuthentication(
-      const AuthStatusCallback& callback) override {
+  void StartAuthentication(const AuthStatusCallback& callback) override {
     // RequestSender should clear the rejected access token before starting
     // to request another one.
     EXPECT_FALSE(HasAccessToken());
@@ -95,9 +94,9 @@
     return passed_reauth_callback_;
   }
 
-  virtual void Start(const std::string& access_token,
-                     const std::string& custom_user_agent,
-                     const ReAuthenticateCallback& callback) override {
+  void Start(const std::string& access_token,
+             const std::string& custom_user_agent,
+             const ReAuthenticateCallback& callback) override {
     *start_called_ = true;
     passed_access_token_ = access_token;
     passed_reauth_callback_ = callback;
@@ -106,18 +105,18 @@
     // Each test case should respond properly by using the above methods.
   }
 
-  virtual void Cancel() override {
+  void Cancel() override {
     EXPECT_TRUE(*start_called_);
     *finish_reason_ = CANCEL;
     sender_->RequestFinished(this);
   }
 
-  virtual void OnAuthFailed(GDataErrorCode code) override {
+  void OnAuthFailed(GDataErrorCode code) override {
     *finish_reason_ = AUTH_FAILURE;
     sender_->RequestFinished(this);
   }
 
-  virtual base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() override {
+  base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() override {
     return weak_ptr_factory_.GetWeakPtr();
   }
 
diff --git a/google_apis/gaia/account_tracker.h b/google_apis/gaia/account_tracker.h
index 2d32b7d1..41ebd2e 100644
--- a/google_apis/gaia/account_tracker.h
+++ b/google_apis/gaia/account_tracker.h
@@ -45,7 +45,7 @@
  public:
   AccountTracker(IdentityProvider* identity_provider,
                  net::URLRequestContextGetter* request_context_getter);
-  virtual ~AccountTracker();
+  ~AccountTracker() override;
 
   class Observer {
    public:
@@ -67,16 +67,16 @@
   AccountIds FindAccountIdsByGaiaId(const std::string& gaia_id);
 
   // OAuth2TokenService::Observer implementation.
-  virtual void OnRefreshTokenAvailable(const std::string& account_key) override;
-  virtual void OnRefreshTokenRevoked(const std::string& account_key) override;
+  void OnRefreshTokenAvailable(const std::string& account_key) override;
+  void OnRefreshTokenRevoked(const std::string& account_key) override;
 
   void OnUserInfoFetchSuccess(AccountIdFetcher* fetcher,
                               const std::string& gaia_id);
   void OnUserInfoFetchFailure(AccountIdFetcher* fetcher);
 
   // IdentityProvider::Observer implementation.
-  virtual void OnActiveAccountLogin() override;
-  virtual void OnActiveAccountLogout() override;
+  void OnActiveAccountLogin() override;
+  void OnActiveAccountLogout() override;
 
   // Sets the state of an account. Does not fire notifications.
   void SetAccountStateForTest(AccountIds ids, bool is_signed_in);
@@ -120,23 +120,23 @@
                    net::URLRequestContextGetter* request_context_getter,
                    AccountTracker* tracker,
                    const std::string& account_key);
-  virtual ~AccountIdFetcher();
+  ~AccountIdFetcher() override;
 
   const std::string& account_key() { return account_key_; }
 
   void Start();
 
   // OAuth2TokenService::Consumer implementation.
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
   // gaia::GaiaOAuthClient::Delegate implementation.
-  virtual void OnGetUserIdResponse(const std::string& gaia_id) override;
-  virtual void OnOAuthError() override;
-  virtual void OnNetworkError(int response_code) override;
+  void OnGetUserIdResponse(const std::string& gaia_id) override;
+  void OnOAuthError() override;
+  void OnNetworkError(int response_code) override;
 
  private:
   OAuth2TokenService* token_service_;
diff --git a/google_apis/gaia/account_tracker_unittest.cc b/google_apis/gaia/account_tracker_unittest.cc
index 8b6d298f..f3792a71 100644
--- a/google_apis/gaia/account_tracker_unittest.cc
+++ b/google_apis/gaia/account_tracker_unittest.cc
@@ -136,10 +136,10 @@
   void SortEventsByUser();
 
   // AccountTracker::Observer implementation
-  virtual void OnAccountAdded(const AccountIds& ids) override;
-  virtual void OnAccountRemoved(const AccountIds& ids) override;
-  virtual void OnAccountSignInChanged(const AccountIds& ids, bool is_signed_in)
-      override;
+  void OnAccountAdded(const AccountIds& ids) override;
+  void OnAccountRemoved(const AccountIds& ids) override;
+  void OnAccountSignInChanged(const AccountIds& ids,
+                              bool is_signed_in) override;
 
  private:
   testing::AssertionResult CheckEvents(
diff --git a/google_apis/gaia/fake_gaia.cc b/google_apis/gaia/fake_gaia.cc
index 9c4836f..b1a3942c 100644
--- a/google_apis/gaia/fake_gaia.cc
+++ b/google_apis/gaia/fake_gaia.cc
@@ -51,6 +51,8 @@
 const char kTestOAuthLoginLSID[] = "fake-oauth-LSID-cookie";
 const char kTestOAuthLoginAuthCode[] = "fake-oauth-auth-code";
 
+const char kDefaultGaiaId[]  ="12345";
+
 const base::FilePath::CharType kServiceLogin[] =
     FILE_PATH_LITERAL("google_apis/test/service_login.html");
 
@@ -163,6 +165,30 @@
   merge_session_params_ = params;
 }
 
+void FakeGaia::MapEmailToGaiaId(const std::string& email,
+                                const std::string& gaia_id) {
+  DCHECK(!email.empty());
+  DCHECK(!gaia_id.empty());
+  email_to_gaia_id_map_[email] = gaia_id;
+}
+
+std::string FakeGaia::GetGaiaIdOfEmail(const std::string& email) const {
+  DCHECK(!email.empty());
+  auto it = email_to_gaia_id_map_.find(email);
+  return it == email_to_gaia_id_map_.end() ? std::string(kDefaultGaiaId) :
+      it->second;
+}
+
+void FakeGaia::AddGoogleAccountsSigninHeader(
+    net::test_server::BasicHttpResponse* http_response,
+    const std::string& email) const {
+  DCHECK(!email.empty());
+  http_response->AddCustomHeader("google-accounts-signin",
+      base::StringPrintf(
+          "email=\"%s\", obfuscatedid=\"%s\", sessionindex=0",
+          email.c_str(), GetGaiaIdOfEmail(email).c_str()));
+}
+
 void FakeGaia::Initialize() {
   GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
   // Handles /MergeSession GAIA call.
@@ -415,8 +441,11 @@
   std::string redirect_url = continue_url;
 
   std::string email;
-  if (GetQueryParameter(request.content, "Email", &email) &&
-      saml_account_idp_map_.find(email) != saml_account_idp_map_.end()) {
+  const bool is_saml =
+      GetQueryParameter(request.content, "Email", &email) &&
+      saml_account_idp_map_.find(email) != saml_account_idp_map_.end();
+
+  if (is_saml) {
     GURL url(saml_account_idp_map_[email]);
     url = net::AppendQueryParameter(url, "SAMLRequest", "fake_request");
     url = net::AppendQueryParameter(url, "RelayState", continue_url);
@@ -431,8 +460,12 @@
 
   http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
   http_response->AddCustomHeader("Location", redirect_url);
-  http_response->AddCustomHeader("google-accounts-signin",
-      base::StringPrintf("email=\"%s\", sessionindex=0", email.c_str()));
+
+  // SAML sign-ins complete in HandleSSO().
+  if (is_saml)
+    return;
+
+  AddGoogleAccountsSigninHeader(http_response, email);
 }
 
 void FakeGaia::HandleSSO(const HttpRequest& request,
@@ -449,6 +482,9 @@
   http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
   http_response->AddCustomHeader("Location", redirect_url);
   http_response->AddCustomHeader("Google-Accounts-SAML", "End");
+
+  if (!merge_session_params_.email.empty())
+    AddGoogleAccountsSigninHeader(http_response, merge_session_params_.email);
 }
 
 void FakeGaia::HandleAuthToken(const HttpRequest& request,
@@ -580,3 +616,4 @@
       merge_session_params_.email.c_str()));
   http_response->set_code(net::HTTP_OK);
 }
+
diff --git a/google_apis/gaia/fake_gaia.h b/google_apis/gaia/fake_gaia.h
index 4db3b84..e00a80a7 100644
--- a/google_apis/gaia/fake_gaia.h
+++ b/google_apis/gaia/fake_gaia.h
@@ -86,6 +86,11 @@
   // Sets the initial value of tokens and cookies.
   void SetMergeSessionParams(const MergeSessionParams& params);
 
+  // Sets the specified |gaia_id| as corresponding to the given |email|
+  // address when setting GAIA response headers.  If no mapping is given for
+  // an email address, a default GAIA Id is used.
+  void MapEmailToGaiaId(const std::string& email, const std::string& gaia_id);
+
   // Initializes HTTP request handlers. Should be called after switches
   // for tweaking GaiaUrls are in place.
   void Initialize();
@@ -121,8 +126,15 @@
 
  private:
   typedef std::multimap<std::string, AccessTokenInfo> AccessTokenInfoMap;
+  typedef std::map<std::string, std::string> EmailToGaiaIdMap;
   typedef std::map<std::string, GURL> SamlAccountIdpMap;
 
+  std::string GetGaiaIdOfEmail(const std::string& email) const;
+
+  void AddGoogleAccountsSigninHeader(
+      net::test_server::BasicHttpResponse* http_response,
+      const std::string& email) const;
+
   // Formats a JSON response with the data in |response_dict|.
   void FormatJSONResponse(const base::DictionaryValue& response_dict,
                           net::test_server::BasicHttpResponse* http_response);
@@ -169,6 +181,7 @@
       const;
 
   MergeSessionParams merge_session_params_;
+  EmailToGaiaIdMap email_to_gaia_id_map_;
   AccessTokenInfoMap access_token_info_map_;
   RequestHandlerMap request_handlers_;
   std::string service_login_response_;
diff --git a/google_apis/gaia/fake_identity_provider.h b/google_apis/gaia/fake_identity_provider.h
index 1ba0f50..2140808 100644
--- a/google_apis/gaia/fake_identity_provider.h
+++ b/google_apis/gaia/fake_identity_provider.h
@@ -17,16 +17,16 @@
 class FakeIdentityProvider : public IdentityProvider {
  public:
   explicit FakeIdentityProvider(OAuth2TokenService* token_service);
-  virtual ~FakeIdentityProvider();
+  ~FakeIdentityProvider() override;
 
   void LogIn(const std::string& account_id);
   void LogOut();
 
   // IdentityProvider:
-  virtual std::string GetActiveUsername() override;
-  virtual std::string GetActiveAccountId() override;
-  virtual OAuth2TokenService* GetTokenService() override;
-  virtual bool RequestLogin() override;
+  std::string GetActiveUsername() override;
+  std::string GetActiveAccountId() override;
+  OAuth2TokenService* GetTokenService() override;
+  bool RequestLogin() override;
 
  private:
   std::string account_id_;
diff --git a/google_apis/gaia/fake_oauth2_token_service.h b/google_apis/gaia/fake_oauth2_token_service.h
index 79f9f84..ffe7b6a 100644
--- a/google_apis/gaia/fake_oauth2_token_service.h
+++ b/google_apis/gaia/fake_oauth2_token_service.h
@@ -20,9 +20,9 @@
 class FakeOAuth2TokenService : public OAuth2TokenService {
  public:
   FakeOAuth2TokenService();
-  virtual ~FakeOAuth2TokenService();
+  ~FakeOAuth2TokenService() override;
 
-  virtual std::vector<std::string> GetAccounts() override;
+  std::vector<std::string> GetAccounts() override;
 
   void AddAccount(const std::string& account_id);
   void RemoveAccount(const std::string& account_id);
@@ -42,20 +42,19 @@
 
  protected:
   // OAuth2TokenService overrides.
-  virtual void FetchOAuth2Token(RequestImpl* request,
-                                const std::string& account_id,
-                                net::URLRequestContextGetter* getter,
-                                const std::string& client_id,
-                                const std::string& client_secret,
-                                const ScopeSet& scopes) override;
+  void FetchOAuth2Token(RequestImpl* request,
+                        const std::string& account_id,
+                        net::URLRequestContextGetter* getter,
+                        const std::string& client_id,
+                        const std::string& client_secret,
+                        const ScopeSet& scopes) override;
 
-  virtual void InvalidateOAuth2Token(const std::string& account_id,
-                                     const std::string& client_id,
-                                     const ScopeSet& scopes,
-                                     const std::string& access_token) override;
+  void InvalidateOAuth2Token(const std::string& account_id,
+                             const std::string& client_id,
+                             const ScopeSet& scopes,
+                             const std::string& access_token) override;
 
-  virtual bool RefreshTokenIsAvailable(const std::string& account_id) const
-      override;
+  bool RefreshTokenIsAvailable(const std::string& account_id) const override;
 
  private:
   struct PendingRequest {
@@ -70,9 +69,9 @@
   };
 
   // OAuth2TokenService overrides.
-  virtual net::URLRequestContextGetter* GetRequestContext() override;
+  net::URLRequestContextGetter* GetRequestContext() override;
 
-  virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
+  OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
       const std::string& account_id,
       net::URLRequestContextGetter* getter,
       OAuth2AccessTokenConsumer* consumer) override;
diff --git a/google_apis/gaia/gaia_auth_fetcher.h b/google_apis/gaia/gaia_auth_fetcher.h
index 4e745d3f6..744c33f 100644
--- a/google_apis/gaia/gaia_auth_fetcher.h
+++ b/google_apis/gaia/gaia_auth_fetcher.h
@@ -53,7 +53,7 @@
   GaiaAuthFetcher(GaiaAuthConsumer* consumer,
                   const std::string& source,
                   net::URLRequestContextGetter* getter);
-  virtual ~GaiaAuthFetcher();
+  ~GaiaAuthFetcher() override;
 
   // Start a request to obtain the SID and LSID cookies for the the account
   // identified by |username| and |password|.  If |service| is not null or
@@ -192,7 +192,7 @@
   void StartGetCheckConnectionInfo();
 
   // Implementation of net::URLFetcherDelegate
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // StartClientLogin been called && results not back yet?
   bool HasPendingFetch();
diff --git a/google_apis/gaia/gaia_auth_util.cc b/google_apis/gaia/gaia_auth_util.cc
index eba0d7b..c3cc764 100644
--- a/google_apis/gaia/gaia_auth_util.cc
+++ b/google_apis/gaia/gaia_auth_util.cc
@@ -25,8 +25,9 @@
   char at = '@';
   base::SplitString(email_address, at, &parts);
   if (parts.size() != 2U) {
-    NOTREACHED() << "expecting exactly one @, but got " << parts.size()-1 <<
-        " : " << email_address;
+    NOTREACHED() << "expecting exactly one @, but got "
+                 << (parts.empty() ? 0 : parts.size() - 1)
+                 << " : " << email_address;
   } else {
     if (change_googlemail_to_gmail && parts[1] == kGooglemailDomain)
       parts[1] = kGmailDomain;
diff --git a/google_apis/gaia/gaia_oauth_client.cc b/google_apis/gaia/gaia_oauth_client.cc
index 8f2565e..0660507 100644
--- a/google_apis/gaia/gaia_oauth_client.cc
+++ b/google_apis/gaia/gaia_oauth_client.cc
@@ -65,7 +65,7 @@
                     Delegate* delegate);
 
   // net::URLFetcherDelegate implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  private:
   friend class base::RefCountedThreadSafe<Core>;
@@ -80,7 +80,7 @@
     USER_INFO,
   };
 
-  virtual ~Core() {}
+  ~Core() override {}
 
   void GetUserInfoImpl(RequestType type,
                        const std::string& oauth_access_token,
diff --git a/google_apis/gaia/gaia_oauth_client_unittest.cc b/google_apis/gaia/gaia_oauth_client_unittest.cc
index a5509bee..e9d2a29 100644
--- a/google_apis/gaia/gaia_oauth_client_unittest.cc
+++ b/google_apis/gaia/gaia_oauth_client_unittest.cc
@@ -48,9 +48,9 @@
     SetResponseString(results);
   }
 
-  virtual ~MockOAuthFetcher() { }
+  ~MockOAuthFetcher() override {}
 
-  virtual void Start() override {
+  void Start() override {
     if ((GetResponseCode() != net::HTTP_OK) && (max_failure_count_ != -1) &&
         (current_failure_count_ == max_failure_count_)) {
       set_response_code(net::HTTP_OK);
@@ -87,12 +87,11 @@
         response_code_(net::HTTP_OK),
         complete_immediately_(true) {
   }
-  virtual ~MockOAuthFetcherFactory() {}
-  virtual net::URLFetcher* CreateURLFetcher(
-      int id,
-      const GURL& url,
-      net::URLFetcher::RequestType request_type,
-      net::URLFetcherDelegate* d) override {
+  ~MockOAuthFetcherFactory() override {}
+  net::URLFetcher* CreateURLFetcher(int id,
+                                    const GURL& url,
+                                    net::URLFetcher::RequestType request_type,
+                                    net::URLFetcherDelegate* d) override {
     url_fetcher_ = new MockOAuthFetcher(
         response_code_,
         max_failure_count_,
diff --git a/google_apis/gaia/identity_provider.h b/google_apis/gaia/identity_provider.h
index b84d838..6ee9b8c0c 100644
--- a/google_apis/gaia/identity_provider.h
+++ b/google_apis/gaia/identity_provider.h
@@ -41,7 +41,7 @@
     virtual ~Observer();
   };
 
-  virtual ~IdentityProvider();
+  ~IdentityProvider() override;
 
   // Adds and removes observers that will be notified of changes to the refresh
   // token availability for the active account.
@@ -69,9 +69,9 @@
   void RemoveObserver(Observer* observer);
 
   // OAuth2TokenService::Observer:
-  virtual void OnRefreshTokenAvailable(const std::string& account_id) override;
-  virtual void OnRefreshTokenRevoked(const std::string& account_id) override;
-  virtual void OnRefreshTokensLoaded() override;
+  void OnRefreshTokenAvailable(const std::string& account_id) override;
+  void OnRefreshTokenRevoked(const std::string& account_id) override;
+  void OnRefreshTokensLoaded() override;
 
  protected:
   IdentityProvider();
diff --git a/google_apis/gaia/merge_session_helper.h b/google_apis/gaia/merge_session_helper.h
index 46cf686..dd3bf5f 100644
--- a/google_apis/gaia/merge_session_helper.h
+++ b/google_apis/gaia/merge_session_helper.h
@@ -57,7 +57,7 @@
     typedef std::map<std::string, std::string> ResultMap;
 
     ExternalCcResultFetcher(MergeSessionHelper* helper);
-    virtual ~ExternalCcResultFetcher();
+    ~ExternalCcResultFetcher() override;
 
     // Gets the current value of the external connection check result string.
     std::string GetExternalCcResult();
@@ -79,14 +79,13 @@
 
    private:
     // Overridden from GaiaAuthConsumer.
-    virtual void OnGetCheckConnectionInfoSuccess(
-        const std::string& data) override;
+    void OnGetCheckConnectionInfoSuccess(const std::string& data) override;
 
     // Creates and initializes a URL fetcher for doing a connection check.
     net::URLFetcher* CreateFetcher(const GURL& url);
 
     // Overridden from URLFetcherDelgate.
-    virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+    void OnURLFetchComplete(const net::URLFetcher* source) override;
 
     // Any fetches still ongoing after this call are considered timed out.
     void Timeout();
@@ -106,7 +105,7 @@
                      const std::string& source,
                      net::URLRequestContextGetter* request_context,
                      Observer* observer);
-  virtual ~MergeSessionHelper();
+  ~MergeSessionHelper() override;
 
   void LogIn(const std::string& account_id);
 
@@ -148,13 +147,12 @@
   net::URLRequestContextGetter* request_context() { return request_context_; }
 
   // Overridden from UbertokenConsumer.
-  virtual void OnUbertokenSuccess(const std::string& token) override;
-  virtual void OnUbertokenFailure(const GoogleServiceAuthError& error) override;
+  void OnUbertokenSuccess(const std::string& token) override;
+  void OnUbertokenFailure(const GoogleServiceAuthError& error) override;
 
   // Overridden from GaiaAuthConsumer.
-  virtual void OnMergeSessionSuccess(const std::string& data) override;
-  virtual void OnMergeSessionFailure(const GoogleServiceAuthError& error)
-      override;
+  void OnMergeSessionSuccess(const std::string& data) override;
+  void OnMergeSessionFailure(const GoogleServiceAuthError& error) override;
 
   void LogOutInternal(const std::string& account_id,
                       const std::vector<std::string>& accounts);
@@ -170,7 +168,7 @@
   void HandleNextAccount();
 
   // Overridden from URLFetcherDelgate.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   OAuth2TokenService* token_service_;
   net::URLRequestContextGetter* request_context_;
diff --git a/google_apis/gaia/mock_url_fetcher_factory.h b/google_apis/gaia/mock_url_fetcher_factory.h
index ca61dc7..68e30aa63 100644
--- a/google_apis/gaia/mock_url_fetcher_factory.h
+++ b/google_apis/gaia/mock_url_fetcher_factory.h
@@ -31,9 +31,9 @@
               net::URLFetcher::RequestType request_type,
               net::URLFetcherDelegate* d);
 
-  virtual ~MockFetcher();
+  ~MockFetcher() override;
 
-  virtual void Start() override;
+  void Start() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockFetcher);
diff --git a/google_apis/gaia/oauth2_access_token_fetcher_impl.h b/google_apis/gaia/oauth2_access_token_fetcher_impl.h
index c079bfdc..6944d24 100644
--- a/google_apis/gaia/oauth2_access_token_fetcher_impl.h
+++ b/google_apis/gaia/oauth2_access_token_fetcher_impl.h
@@ -51,17 +51,17 @@
   OAuth2AccessTokenFetcherImpl(OAuth2AccessTokenConsumer* consumer,
                                net::URLRequestContextGetter* getter,
                                const std::string& refresh_token);
-  virtual ~OAuth2AccessTokenFetcherImpl();
+  ~OAuth2AccessTokenFetcherImpl() override;
 
   // Implementation of OAuth2AccessTokenFetcher
-  virtual void Start(const std::string& client_id,
-                     const std::string& client_secret,
-                     const std::vector<std::string>& scopes) override;
+  void Start(const std::string& client_id,
+             const std::string& client_secret,
+             const std::vector<std::string>& scopes) override;
 
-  virtual void CancelRequest() override;
+  void CancelRequest() override;
 
   // Implementation of net::URLFetcherDelegate
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  private:
   enum State {
diff --git a/google_apis/gaia/oauth2_api_call_flow.h b/google_apis/gaia/oauth2_api_call_flow.h
index 26feefba..164e2d1 100644
--- a/google_apis/gaia/oauth2_api_call_flow.h
+++ b/google_apis/gaia/oauth2_api_call_flow.h
@@ -32,14 +32,14 @@
  public:
   OAuth2ApiCallFlow();
 
-  virtual ~OAuth2ApiCallFlow();
+  ~OAuth2ApiCallFlow() override;
 
   // Start the flow.
   virtual void Start(net::URLRequestContextGetter* context,
                      const std::string& access_token);
 
   // net::URLFetcherDelegate implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  protected:
   // Template methods for sub-classes.
diff --git a/google_apis/gaia/oauth2_mint_token_flow.h b/google_apis/gaia/oauth2_mint_token_flow.h
index aded2eef..1f4180d22 100644
--- a/google_apis/gaia/oauth2_mint_token_flow.h
+++ b/google_apis/gaia/oauth2_mint_token_flow.h
@@ -99,17 +99,15 @@
   };
 
   OAuth2MintTokenFlow(Delegate* delegate, const Parameters& parameters);
-  virtual ~OAuth2MintTokenFlow();
+  ~OAuth2MintTokenFlow() override;
 
  protected:
   // Implementation of template methods in OAuth2ApiCallFlow.
-  virtual GURL CreateApiCallUrl() override;
-  virtual std::string CreateApiCallBody() override;
+  GURL CreateApiCallUrl() override;
+  std::string CreateApiCallBody() override;
 
-  virtual void ProcessApiCallSuccess(
-      const net::URLFetcher* source) override;
-  virtual void ProcessApiCallFailure(
-      const net::URLFetcher* source) override;
+  void ProcessApiCallSuccess(const net::URLFetcher* source) override;
+  void ProcessApiCallFailure(const net::URLFetcher* source) override;
 
  private:
   friend class OAuth2MintTokenFlowTest;
diff --git a/google_apis/gaia/oauth2_token_service.cc b/google_apis/gaia/oauth2_token_service.cc
index 9152c51..df46b2cd 100644
--- a/google_apis/gaia/oauth2_token_service.cc
+++ b/google_apis/gaia/oauth2_token_service.cc
@@ -128,7 +128,7 @@
                                  const std::string& client_secret,
                                  const ScopeSet& scopes,
                                  base::WeakPtr<RequestImpl> waiting_request);
-  virtual ~Fetcher();
+  ~Fetcher() override;
 
   // Add a request that is waiting for the result of this Fetcher.
   void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request);
@@ -151,10 +151,9 @@
 
  protected:
    // OAuth2AccessTokenConsumer
-  virtual void OnGetTokenSuccess(const std::string& access_token,
-                                 const base::Time& expiration_date) override;
-  virtual void OnGetTokenFailure(
-      const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const std::string& access_token,
+                         const base::Time& expiration_date) override;
+  void OnGetTokenFailure(const GoogleServiceAuthError& error) override;
 
  private:
   Fetcher(OAuth2TokenService* oauth2_token_service,
diff --git a/google_apis/gaia/oauth2_token_service.h b/google_apis/gaia/oauth2_token_service.h
index 1824da3..202d7d22 100644
--- a/google_apis/gaia/oauth2_token_service.h
+++ b/google_apis/gaia/oauth2_token_service.h
@@ -215,10 +215,10 @@
    public:
     // |consumer| is required to outlive this.
     explicit RequestImpl(const std::string& account_id, Consumer* consumer);
-    virtual ~RequestImpl();
+    ~RequestImpl() override;
 
     // Overridden from Request:
-    virtual std::string GetAccountId() const override;
+    std::string GetAccountId() const override;
 
     std::string GetConsumerId() const;
 
diff --git a/google_apis/gaia/oauth2_token_service_request.cc b/google_apis/gaia/oauth2_token_service_request.cc
index 8301fd5..ee7d650 100644
--- a/google_apis/gaia/oauth2_token_service_request.cc
+++ b/google_apis/gaia/oauth2_token_service_request.cc
@@ -163,21 +163,21 @@
               const OAuth2TokenService::ScopeSet& scopes);
 
   // OAuth2TokenService::Consumer.  Must be called on the token service thread.
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
  private:
   friend class base::RefCountedThreadSafe<RequestCore>;
 
   // Must be destroyed on the owner thread.
-  virtual ~RequestCore();
+  ~RequestCore() override;
 
   // Core implementation.
-  virtual void StartOnTokenServiceThread() override;
-  virtual void StopOnTokenServiceThread() override;
+  void StartOnTokenServiceThread() override;
+  void StopOnTokenServiceThread() override;
 
   void InformOwnerOnGetTokenSuccess(std::string access_token,
                                     base::Time expiration_time);
@@ -279,11 +279,11 @@
   friend class base::RefCountedThreadSafe<InvalidateCore>;
 
   // Must be destroyed on the owner thread.
-  virtual ~InvalidateCore();
+  ~InvalidateCore() override;
 
   // Core implementation.
-  virtual void StartOnTokenServiceThread() override;
-  virtual void StopOnTokenServiceThread() override;
+  void StartOnTokenServiceThread() override;
+  void StopOnTokenServiceThread() override;
 
   std::string access_token_;
   std::string account_id_;
diff --git a/google_apis/gaia/oauth2_token_service_request.h b/google_apis/gaia/oauth2_token_service_request.h
index ecf605fc..8d81ba4 100644
--- a/google_apis/gaia/oauth2_token_service_request.h
+++ b/google_apis/gaia/oauth2_token_service_request.h
@@ -87,10 +87,10 @@
       const OAuth2TokenService::ScopeSet& scopes,
       const std::string& access_token);
 
-  virtual ~OAuth2TokenServiceRequest();
+  ~OAuth2TokenServiceRequest() override;
 
   // OAuth2TokenService::Request.
-  virtual std::string GetAccountId() const override;
+  std::string GetAccountId() const override;
 
  private:
   OAuth2TokenServiceRequest(const std::string& account_id);
diff --git a/google_apis/gaia/oauth2_token_service_request_unittest.cc b/google_apis/gaia/oauth2_token_service_request_unittest.cc
index 0cb08d33..691c3542 100644
--- a/google_apis/gaia/oauth2_token_service_request_unittest.cc
+++ b/google_apis/gaia/oauth2_token_service_request_unittest.cc
@@ -22,13 +22,13 @@
 class TestingOAuth2TokenServiceConsumer : public OAuth2TokenService::Consumer {
  public:
   TestingOAuth2TokenServiceConsumer();
-  virtual ~TestingOAuth2TokenServiceConsumer();
+  ~TestingOAuth2TokenServiceConsumer() override;
 
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
   int num_get_token_success_;
   int num_get_token_failure_;
@@ -67,7 +67,7 @@
 class MockOAuth2TokenService : public FakeOAuth2TokenService {
  public:
   MockOAuth2TokenService();
-  virtual ~MockOAuth2TokenService();
+  ~MockOAuth2TokenService() override;
 
   void SetResponse(const GoogleServiceAuthError& error,
                    const std::string& access_token,
@@ -80,17 +80,17 @@
   }
 
  protected:
-  virtual void FetchOAuth2Token(RequestImpl* request,
-                                const std::string& account_id,
-                                net::URLRequestContextGetter* getter,
-                                const std::string& client_id,
-                                const std::string& client_secret,
-                                const ScopeSet& scopes) override;
+  void FetchOAuth2Token(RequestImpl* request,
+                        const std::string& account_id,
+                        net::URLRequestContextGetter* getter,
+                        const std::string& client_id,
+                        const std::string& client_secret,
+                        const ScopeSet& scopes) override;
 
-  virtual void InvalidateOAuth2Token(const std::string& account_id,
-                                     const std::string& client_id,
-                                     const ScopeSet& scopes,
-                                     const std::string& access_token) override;
+  void InvalidateOAuth2Token(const std::string& account_id,
+                             const std::string& client_id,
+                             const ScopeSet& scopes,
+                             const std::string& access_token) override;
 
  private:
   GoogleServiceAuthError response_error_;
@@ -154,12 +154,12 @@
     Provider(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
              OAuth2TokenService* token_service);
 
-    virtual scoped_refptr<base::SingleThreadTaskRunner>
-        GetTokenServiceTaskRunner() override;
-    virtual OAuth2TokenService* GetTokenService() override;
+    scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner()
+        override;
+    OAuth2TokenService* GetTokenService() override;
 
    private:
-    virtual ~Provider();
+    ~Provider() override;
 
     scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
     OAuth2TokenService* token_service_;
diff --git a/google_apis/gaia/oauth2_token_service_test_util.h b/google_apis/gaia/oauth2_token_service_test_util.h
index f31cf58..6a14f139 100644
--- a/google_apis/gaia/oauth2_token_service_test_util.h
+++ b/google_apis/gaia/oauth2_token_service_test_util.h
@@ -16,14 +16,14 @@
 class TestingOAuth2TokenServiceConsumer : public OAuth2TokenService::Consumer {
  public:
   TestingOAuth2TokenServiceConsumer();
-  virtual ~TestingOAuth2TokenServiceConsumer();
+  ~TestingOAuth2TokenServiceConsumer() override;
 
   // OAuth2TokenService::Consumer overrides.
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& token,
-                                 const base::Time& expiration_date) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& token,
+                         const base::Time& expiration_date) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
   std::string last_token_;
   int number_of_successful_tokens_;
diff --git a/google_apis/gaia/oauth2_token_service_unittest.cc b/google_apis/gaia/oauth2_token_service_unittest.cc
index 71c8d32..153db657 100644
--- a/google_apis/gaia/oauth2_token_service_unittest.cc
+++ b/google_apis/gaia/oauth2_token_service_unittest.cc
@@ -27,10 +27,10 @@
       const std::string& account_id)
       : oauth2_service_(oauth2_service),
         account_id_(account_id) {}
-  virtual ~RetryingTestingOAuth2TokenServiceConsumer() {}
+  ~RetryingTestingOAuth2TokenServiceConsumer() override {}
 
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override {
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override {
     TestingOAuth2TokenServiceConsumer::OnGetTokenFailure(request, error);
     request_.reset(oauth2_service_->StartRequest(
         account_id_, OAuth2TokenService::ScopeSet(), this).release());
@@ -62,8 +62,7 @@
       refresh_tokens_[account_id] = refresh_token;
   }
 
-  virtual bool RefreshTokenIsAvailable(const std::string& account_id) const
-      override {
+  bool RefreshTokenIsAvailable(const std::string& account_id) const override {
     std::map<std::string, std::string>::const_iterator it =
         refresh_tokens_.find(account_id);
 
@@ -72,11 +71,11 @@
 
  private:
   // OAuth2TokenService implementation.
-  virtual net::URLRequestContextGetter* GetRequestContext() override {
+  net::URLRequestContextGetter* GetRequestContext() override {
     return request_context_getter_.get();
   }
 
-  virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
+  OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
       const std::string& account_id,
       net::URLRequestContextGetter* getter,
       OAuth2AccessTokenConsumer* consumer) override {
diff --git a/google_apis/gaia/ubertoken_fetcher.h b/google_apis/gaia/ubertoken_fetcher.h
index 9172ce15..54835e1 100644
--- a/google_apis/gaia/ubertoken_fetcher.h
+++ b/google_apis/gaia/ubertoken_fetcher.h
@@ -46,22 +46,21 @@
                    UbertokenConsumer* consumer,
                    const std::string& source,
                    net::URLRequestContextGetter* request_context);
-  virtual ~UbertokenFetcher();
+  ~UbertokenFetcher() override;
 
   // Start fetching the token for |account_id|.
   virtual void StartFetchingToken(const std::string& account_id);
 
   // Overriden from GaiaAuthConsumer
-  virtual void OnUberAuthTokenSuccess(const std::string& token) override;
-  virtual void OnUberAuthTokenFailure(
-      const GoogleServiceAuthError& error) override;
+  void OnUberAuthTokenSuccess(const std::string& token) override;
+  void OnUberAuthTokenFailure(const GoogleServiceAuthError& error) override;
 
   // Overriden from OAuth2TokenService::Consumer:
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
  private:
   // Request a login-scoped access token from the token service.
diff --git a/google_apis/gaia/ubertoken_fetcher_unittest.cc b/google_apis/gaia/ubertoken_fetcher_unittest.cc
index ad5a5b9..6659cca 100644
--- a/google_apis/gaia/ubertoken_fetcher_unittest.cc
+++ b/google_apis/gaia/ubertoken_fetcher_unittest.cc
@@ -24,15 +24,14 @@
         last_error_(GoogleServiceAuthError::AuthErrorNone()),
         nb_error_(0) {
   }
-  virtual ~MockUbertokenConsumer() {}
+  ~MockUbertokenConsumer() override {}
 
-  virtual void OnUbertokenSuccess(const std::string& token) override {
+  void OnUbertokenSuccess(const std::string& token) override {
     last_token_ = token;
     ++ nb_correct_token_;
   }
 
-  virtual void OnUbertokenFailure(const GoogleServiceAuthError& error)
-      override {
+  void OnUbertokenFailure(const GoogleServiceAuthError& error) override {
     last_error_ = error;
     ++nb_error_;
   }
diff --git a/google_apis/gcm/base/fake_encryptor.h b/google_apis/gcm/base/fake_encryptor.h
index 894d50b..4277292 100644
--- a/google_apis/gcm/base/fake_encryptor.h
+++ b/google_apis/gcm/base/fake_encryptor.h
@@ -14,13 +14,13 @@
 // ciphertext.  Obviously, this should be used only for testing.
 class FakeEncryptor : public Encryptor {
  public:
-  virtual ~FakeEncryptor();
+  ~FakeEncryptor() override;
 
-  virtual bool EncryptString(const std::string& plaintext,
-                             std::string* ciphertext) override;
+  bool EncryptString(const std::string& plaintext,
+                     std::string* ciphertext) override;
 
-  virtual bool DecryptString(const std::string& ciphertext,
-                             std::string* plaintext) override;
+  bool DecryptString(const std::string& ciphertext,
+                     std::string* plaintext) override;
 };
 
 }  // namespace gcm
diff --git a/google_apis/gcm/base/socket_stream.h b/google_apis/gcm/base/socket_stream.h
index 4a490f2..527056a 100644
--- a/google_apis/gcm/base/socket_stream.h
+++ b/google_apis/gcm/base/socket_stream.h
@@ -63,13 +63,13 @@
 
   // |socket| should already be connected.
   explicit SocketInputStream(net::StreamSocket* socket);
-  virtual ~SocketInputStream();
+  ~SocketInputStream() override;
 
   // ZeroCopyInputStream implementation.
-  virtual bool Next(const void** data, int* size) override;
-  virtual void BackUp(int count) override;
-  virtual bool Skip(int count) override;  // Not implemented.
-  virtual int64 ByteCount() const override;
+  bool Next(const void** data, int* size) override;
+  void BackUp(int count) override;
+  bool Skip(int count) override;  // Not implemented.
+  int64 ByteCount() const override;
 
   // The remaining amount of valid data available to be read.
   int UnreadByteCount() const;
@@ -159,12 +159,12 @@
 
   // |socket| should already be connected.
   explicit SocketOutputStream(net::StreamSocket* socket);
-  virtual ~SocketOutputStream();
+  ~SocketOutputStream() override;
 
   // ZeroCopyOutputStream implementation.
-  virtual bool Next(void** data, int* size) override;
-  virtual void BackUp(int count) override;
-  virtual int64 ByteCount() const override;
+  bool Next(void** data, int* size) override;
+  void BackUp(int count) override;
+  int64 ByteCount() const override;
 
   // Writes the buffer into the Socket.
   net::Error Flush(const base::Closure& callback);
diff --git a/google_apis/gcm/engine/checkin_request.h b/google_apis/gcm/engine/checkin_request.h
index af9e48f89..e3ad8ed 100644
--- a/google_apis/gcm/engine/checkin_request.h
+++ b/google_apis/gcm/engine/checkin_request.h
@@ -64,12 +64,12 @@
                  const CheckinRequestCallback& callback,
                  net::URLRequestContextGetter* request_context_getter,
                  GCMStatsRecorder* recorder);
-  virtual ~CheckinRequest();
+  ~CheckinRequest() override;
 
   void Start();
 
   // URLFetcherDelegate implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  private:
   // Schedules a retry attempt, informs the backoff of a previous request's
diff --git a/google_apis/gcm/engine/connection_factory_impl.h b/google_apis/gcm/engine/connection_factory_impl.h
index 21eeedbe..b28e8f6 100644
--- a/google_apis/gcm/engine/connection_factory_impl.h
+++ b/google_apis/gcm/engine/connection_factory_impl.h
@@ -42,23 +42,23 @@
       const scoped_refptr<net::HttpNetworkSession>& http_network_session,
       net::NetLog* net_log,
       GCMStatsRecorder* recorder);
-  virtual ~ConnectionFactoryImpl();
+  ~ConnectionFactoryImpl() override;
 
   // ConnectionFactory implementation.
-  virtual void Initialize(
+  void Initialize(
       const BuildLoginRequestCallback& request_builder,
       const ConnectionHandler::ProtoReceivedCallback& read_callback,
       const ConnectionHandler::ProtoSentCallback& write_callback) override;
-  virtual ConnectionHandler* GetConnectionHandler() const override;
-  virtual void Connect() override;
-  virtual bool IsEndpointReachable() const override;
-  virtual std::string GetConnectionStateString() const override;
-  virtual base::TimeTicks NextRetryAttempt() const override;
-  virtual void SignalConnectionReset(ConnectionResetReason reason) override;
-  virtual void SetConnectionListener(ConnectionListener* listener) override;
+  ConnectionHandler* GetConnectionHandler() const override;
+  void Connect() override;
+  bool IsEndpointReachable() const override;
+  std::string GetConnectionStateString() const override;
+  base::TimeTicks NextRetryAttempt() const override;
+  void SignalConnectionReset(ConnectionResetReason reason) override;
+  void SetConnectionListener(ConnectionListener* listener) override;
 
   // NetworkChangeObserver implementation.
-  virtual void OnNetworkChanged(
+  void OnNetworkChanged(
       net::NetworkChangeNotifier::ConnectionType type) override;
 
   // Returns the server to which the factory is currently connected, or if
diff --git a/google_apis/gcm/engine/connection_factory_impl_unittest.cc b/google_apis/gcm/engine/connection_factory_impl_unittest.cc
index 415602ed..af04fb74 100644
--- a/google_apis/gcm/engine/connection_factory_impl_unittest.cc
+++ b/google_apis/gcm/engine/connection_factory_impl_unittest.cc
@@ -83,9 +83,9 @@
 class TestBackoffEntry : public net::BackoffEntry {
  public:
   explicit TestBackoffEntry(base::SimpleTestTickClock* tick_clock);
-  virtual ~TestBackoffEntry();
+  ~TestBackoffEntry() override;
 
-  virtual base::TimeTicks ImplGetTimeNow() const override;
+  base::TimeTicks ImplGetTimeNow() const override;
 
  private:
   base::SimpleTestTickClock* tick_clock_;
@@ -107,22 +107,22 @@
 class TestConnectionFactoryImpl : public ConnectionFactoryImpl {
  public:
   TestConnectionFactoryImpl(const base::Closure& finished_callback);
-  virtual ~TestConnectionFactoryImpl();
+  ~TestConnectionFactoryImpl() override;
 
   void InitializeFactory();
 
   // Overridden stubs.
-  virtual void ConnectImpl() override;
-  virtual void InitHandler() override;
-  virtual scoped_ptr<net::BackoffEntry> CreateBackoffEntry(
+  void ConnectImpl() override;
+  void InitHandler() override;
+  scoped_ptr<net::BackoffEntry> CreateBackoffEntry(
       const net::BackoffEntry::Policy* const policy) override;
-  virtual scoped_ptr<ConnectionHandler> CreateConnectionHandler(
+  scoped_ptr<ConnectionHandler> CreateConnectionHandler(
       base::TimeDelta read_timeout,
       const ConnectionHandler::ProtoReceivedCallback& read_callback,
       const ConnectionHandler::ProtoSentCallback& write_callback,
       const ConnectionHandler::ConnectionChangedCallback& connection_callback)
-          override;
-  virtual base::TimeTicks NowTicks() override;
+      override;
+  base::TimeTicks NowTicks() override;
 
   // Helpers for verifying connection attempts are made. Connection results
   // must be consumed.
@@ -266,9 +266,9 @@
   void WaitForConnections();
 
   // ConnectionFactory::ConnectionListener
-  virtual void OnConnected(const GURL& current_server,
-                           const net::IPEndPoint& ip_endpoint) override;
-  virtual void OnDisconnected() override;
+  void OnConnected(const GURL& current_server,
+                   const net::IPEndPoint& ip_endpoint) override;
+  void OnDisconnected() override;
 
  private:
   void ConnectionsComplete();
diff --git a/google_apis/gcm/engine/connection_handler_impl.cc b/google_apis/gcm/engine/connection_handler_impl.cc
index 751b1cd..ccb63629 100644
--- a/google_apis/gcm/engine/connection_handler_impl.cc
+++ b/google_apis/gcm/engine/connection_handler_impl.cc
@@ -22,7 +22,13 @@
 const int kVersionPacketLen = 1;
 // # of bytes a tag packet consumes.
 const int kTagPacketLen = 1;
-// Max # of bytes a length packet consumes.
+// Max # of bytes a length packet consumes. A Varint32 can consume up to 5 bytes
+// (the MSB in each byte is reserved for denoting whether more bytes follow).
+// But, the protocol only allows for 4KiB payloads, and the socket stream buffer
+// is only of size 8KiB. As such we should never need more than 2 bytes (max
+// value of 16KiB). Anything higher than that will result in an error, either
+// because the socket stream buffer overflowed or too many bytes were required
+// in the size packet.
 const int kSizePacketLenMin = 1;
 const int kSizePacketLenMax = 2;
 
@@ -321,7 +327,7 @@
   }
 
   bool need_another_byte = false;
-  int prev_byte_count = input_stream_->ByteCount();
+  int prev_byte_count = input_stream_->UnreadByteCount();
   {
     CodedInputStream coded_input_stream(input_stream_.get());
     if (!coded_input_stream.ReadVarint32(&message_size_))
@@ -332,12 +338,12 @@
     DVLOG(1) << "Expecting another message size byte.";
     if (prev_byte_count >= kSizePacketLenMax) {
       // Already had enough bytes, something else went wrong.
-      LOG(ERROR) << "Failed to process message size.";
-      read_callback_.Run(scoped_ptr<google::protobuf::MessageLite>());
+      LOG(ERROR) << "Failed to process message size, too many bytes needed.";
+      connection_callback_.Run(net::ERR_FILE_TOO_BIG);
       return;
     }
     // Back up by the amount read (should always be 1 byte).
-    int bytes_read = prev_byte_count - input_stream_->ByteCount();
+    int bytes_read = prev_byte_count - input_stream_->UnreadByteCount();
     DCHECK_EQ(bytes_read, 1);
     input_stream_->BackUp(bytes_read);
     WaitForData(MCS_FULL_SIZE);
@@ -367,8 +373,7 @@
     return;
   }
 
-  if (!protobuf.get() ||
-      input_stream_->GetState() != SocketInputStream::READY) {
+  if (input_stream_->GetState() != SocketInputStream::READY) {
     LOG(ERROR) << "Failed to extract protobuf bytes of type "
                << static_cast<unsigned int>(message_tag_);
     // Reset the connection.
@@ -376,6 +381,13 @@
     return;
   }
 
+  if (!protobuf.get()) {
+     LOG(ERROR) << "Received message of invalid type "
+                << static_cast<unsigned int>(message_tag_);
+     connection_callback_.Run(net::ERR_INVALID_ARGUMENT);
+     return;
+   }
+
   {
     CodedInputStream coded_input_stream(input_stream_.get());
     if (!protobuf->ParsePartialFromCodedStream(&coded_input_stream)) {
diff --git a/google_apis/gcm/engine/connection_handler_impl.h b/google_apis/gcm/engine/connection_handler_impl.h
index 296bf6d..fc965fb 100644
--- a/google_apis/gcm/engine/connection_handler_impl.h
+++ b/google_apis/gcm/engine/connection_handler_impl.h
@@ -30,15 +30,14 @@
       const ProtoReceivedCallback& read_callback,
       const ProtoSentCallback& write_callback,
       const ConnectionChangedCallback& connection_callback);
-  virtual ~ConnectionHandlerImpl();
+  ~ConnectionHandlerImpl() override;
 
   // ConnectionHandler implementation.
-  virtual void Init(const mcs_proto::LoginRequest& login_request,
-                    net::StreamSocket* socket) override;
-  virtual void Reset() override;
-  virtual bool CanSendMessage() const override;
-  virtual void SendMessage(const google::protobuf::MessageLite& message)
-      override;
+  void Init(const mcs_proto::LoginRequest& login_request,
+            net::StreamSocket* socket) override;
+  void Reset() override;
+  bool CanSendMessage() const override;
+  void SendMessage(const google::protobuf::MessageLite& message) override;
 
  private:
   // State machine for handling incoming data. See WaitForData(..) for usage.
diff --git a/google_apis/gcm/engine/connection_handler_impl_unittest.cc b/google_apis/gcm/engine/connection_handler_impl_unittest.cc
index 6b89644..4e3ef69 100644
--- a/google_apis/gcm/engine/connection_handler_impl_unittest.cc
+++ b/google_apis/gcm/engine/connection_handler_impl_unittest.cc
@@ -41,6 +41,7 @@
     "this is a second long from that will result in a message > 128 bytes";
 const char kDataMsgCategoryLong2[] =
     "this is a second long category that will result in a message > 128 bytes";
+const uint8 kInvalidTag = 100;  // An invalid tag.
 
 // ---- Helpers for building messages. ----
 
@@ -136,8 +137,6 @@
   ReadList mock_reads_;
   WriteList mock_writes_;
   scoped_ptr<net::DelayedSocketData> data_provider_;
-  scoped_ptr<SocketInputStream> socket_input_stream_;
-  scoped_ptr<SocketOutputStream> socket_output_stream_;
 
   // The connection handler being tested.
   scoped_ptr<ConnectionHandlerImpl> connection_handler_;
@@ -674,8 +673,8 @@
 }
 
 // Receive a message whose size field was corrupted and is larger than the
-// socket's buffer. Should fail gracefully.
-TEST_F(GCMConnectionHandlerImplTest, CorruptedSize) {
+// socket's buffer. Should fail gracefully with a size error.
+TEST_F(GCMConnectionHandlerImplTest, OutOfBuffer) {
   std::string handshake_request = EncodeHandshakeRequest();
   WriteList write_list(1, net::MockWrite(net::ASYNC,
                                          handshake_request.c_str(),
@@ -705,5 +704,106 @@
   EXPECT_EQ(net::ERR_FILE_TOO_BIG, last_error());
 }
 
+// Receive a message whose size field was corrupted and takes more than two
+// bytes to encode. Should fail gracefully with a size error.
+TEST_F(GCMConnectionHandlerImplTest, InvalidSizePacket) {
+  std::string handshake_request = EncodeHandshakeRequest();
+  WriteList write_list(1, net::MockWrite(net::ASYNC,
+                                         handshake_request.c_str(),
+                                         handshake_request.size()));
+  std::string handshake_response = EncodeHandshakeResponse();
+
+  // Fill a string with 20000 character zero (which uses more than 2 bytes to
+  // encode the size packet).
+  std::string data_message_proto(20000, '0');
+  std::string data_message_pkt =
+      EncodePacket(kDataMessageStanzaTag, data_message_proto);
+  ReadList read_list;
+  read_list.push_back(net::MockRead(net::ASYNC,
+                                    handshake_response.c_str(),
+                                    handshake_response.size()));
+  read_list.push_back(net::MockRead(net::ASYNC,
+                                    data_message_pkt.c_str(),
+                                    data_message_pkt.size()));
+  BuildSocket(read_list, write_list);
+
+  ScopedMessage received_message;
+  Connect(&received_message);
+  WaitForMessage();  // The login send.
+  WaitForMessage();  // The login response.
+  received_message.reset();
+  WaitForMessage();  // The data message.
+  EXPECT_FALSE(received_message.get());
+  EXPECT_EQ(net::ERR_FILE_TOO_BIG, last_error());
+}
+
+// Make sure a message with an invalid tag is handled gracefully and resets
+// the connection with an invalid argument error.
+TEST_F(GCMConnectionHandlerImplTest, InvalidTag) {
+  std::string handshake_request = EncodeHandshakeRequest();
+  WriteList write_list(1, net::MockWrite(net::ASYNC,
+                                         handshake_request.c_str(),
+                                         handshake_request.size()));
+  std::string handshake_response = EncodeHandshakeResponse();
+
+  std::string invalid_message = "0";
+  std::string invalid_message_pkt =
+      EncodePacket(kInvalidTag, invalid_message);
+  ReadList read_list;
+  read_list.push_back(net::MockRead(net::ASYNC,
+                                    handshake_response.c_str(),
+                                    handshake_response.size()));
+  read_list.push_back(net::MockRead(net::ASYNC,
+                                    invalid_message_pkt.c_str(),
+                                    invalid_message_pkt.size()));
+  BuildSocket(read_list, write_list);
+
+  ScopedMessage received_message;
+  Connect(&received_message);
+  WaitForMessage();  // The login send.
+  WaitForMessage();  // The login response.
+  received_message.reset();
+  WaitForMessage();  // The invalid message.
+  EXPECT_FALSE(received_message.get());
+  EXPECT_EQ(net::ERR_INVALID_ARGUMENT, last_error());
+}
+
+// Receive a message where the size field spans two socket reads.
+TEST_F(GCMConnectionHandlerImplTest, RecvMsgSplitSize) {
+  std::string handshake_request = EncodeHandshakeRequest();
+  WriteList write_list(1, net::MockWrite(net::ASYNC,
+                                         handshake_request.c_str(),
+                                         handshake_request.size()));
+  std::string handshake_response = EncodeHandshakeResponse();
+
+  std::string data_message_proto =
+      BuildDataMessage(kDataMsgFromLong, kDataMsgCategoryLong);
+  std::string data_message_pkt =
+      EncodePacket(kDataMessageStanzaTag, data_message_proto);
+  DCHECK_GT(data_message_pkt.size(), 128U);
+  ReadList read_list;
+  read_list.push_back(net::MockRead(net::ASYNC,
+                                    handshake_response.c_str(),
+                                    handshake_response.size()));
+  // The first two bytes are the tag byte and the first byte of the size packet.
+  read_list.push_back(net::MockRead(net::ASYNC,
+                                    data_message_pkt.c_str(),
+                                    2));
+  // Start from the second byte of the size packet.
+  read_list.push_back(net::MockRead(net::ASYNC,
+                                    data_message_pkt.c_str() + 2,
+                                    data_message_pkt.size() - 2));
+  BuildSocket(read_list, write_list);
+
+  ScopedMessage received_message;
+  Connect(&received_message);
+  WaitForMessage();  // The login send.
+  WaitForMessage();  // The login response.
+  WaitForMessage();  // The data message.
+  ASSERT_TRUE(received_message.get());
+  EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
+  EXPECT_EQ(net::OK, last_error());
+}
+
 }  // namespace
 }  // namespace gcm
diff --git a/google_apis/gcm/engine/fake_connection_factory.h b/google_apis/gcm/engine/fake_connection_factory.h
index dfba154..9826270 100644
--- a/google_apis/gcm/engine/fake_connection_factory.h
+++ b/google_apis/gcm/engine/fake_connection_factory.h
@@ -17,20 +17,20 @@
 class FakeConnectionFactory : public ConnectionFactory {
  public:
   FakeConnectionFactory();
-  virtual ~FakeConnectionFactory();
+  ~FakeConnectionFactory() override;
 
   // ConnectionFactory implementation.
-  virtual void Initialize(
+  void Initialize(
       const BuildLoginRequestCallback& request_builder,
       const ConnectionHandler::ProtoReceivedCallback& read_callback,
       const ConnectionHandler::ProtoSentCallback& write_callback) override;
-  virtual ConnectionHandler* GetConnectionHandler() const override;
-  virtual void Connect() override;
-  virtual bool IsEndpointReachable() const override;
-  virtual std::string GetConnectionStateString() const override;
-  virtual base::TimeTicks NextRetryAttempt() const override;
-  virtual void SignalConnectionReset(ConnectionResetReason reason) override;
-  virtual void SetConnectionListener(ConnectionListener* listener) override;
+  ConnectionHandler* GetConnectionHandler() const override;
+  void Connect() override;
+  bool IsEndpointReachable() const override;
+  std::string GetConnectionStateString() const override;
+  base::TimeTicks NextRetryAttempt() const override;
+  void SignalConnectionReset(ConnectionResetReason reason) override;
+  void SetConnectionListener(ConnectionListener* listener) override;
 
   // Whether a connection reset has been triggered and is yet to run.
   bool reconnect_pending() const { return reconnect_pending_; }
diff --git a/google_apis/gcm/engine/fake_connection_handler.h b/google_apis/gcm/engine/fake_connection_handler.h
index e176e3a..4e43d12 100644
--- a/google_apis/gcm/engine/fake_connection_handler.h
+++ b/google_apis/gcm/engine/fake_connection_handler.h
@@ -19,15 +19,14 @@
   FakeConnectionHandler(
       const ConnectionHandler::ProtoReceivedCallback& read_callback,
       const ConnectionHandler::ProtoSentCallback& write_callback);
-  virtual ~FakeConnectionHandler();
+  ~FakeConnectionHandler() override;
 
   // ConnectionHandler implementation.
-  virtual void Init(const mcs_proto::LoginRequest& login_request,
-                    net::StreamSocket* socket) override;
-  virtual void Reset() override;
-  virtual bool CanSendMessage() const override;
-  virtual void SendMessage(const google::protobuf::MessageLite& message)
-      override;
+  void Init(const mcs_proto::LoginRequest& login_request,
+            net::StreamSocket* socket) override;
+  void Reset() override;
+  bool CanSendMessage() const override;
+  void SendMessage(const google::protobuf::MessageLite& message) override;
 
   // EXPECT's receipt of |message| via SendMessage(..).
   void ExpectOutgoingMessage(const MCSMessage& message);
diff --git a/google_apis/gcm/engine/gcm_store_impl.h b/google_apis/gcm/engine/gcm_store_impl.h
index b597d6f..283b920 100644
--- a/google_apis/gcm/engine/gcm_store_impl.h
+++ b/google_apis/gcm/engine/gcm_store_impl.h
@@ -28,70 +28,68 @@
   GCMStoreImpl(const base::FilePath& path,
                scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
                scoped_ptr<Encryptor> encryptor);
-  virtual ~GCMStoreImpl();
+  ~GCMStoreImpl() override;
 
   // Load the directory and pass the initial state back to caller.
-  virtual void Load(const LoadCallback& callback) override;
+  void Load(const LoadCallback& callback) override;
 
   // Closes the GCM store.
-  virtual void Close() override;
+  void Close() override;
 
   // Clears the GCM store of all data and destroys any LevelDB files associated
   // with this store.
   // WARNING: this will permanently destroy any pending outgoing messages
   // and require the device to re-create credentials and serial number mapping
   // tables.
-  virtual void Destroy(const UpdateCallback& callback) override;
+  void Destroy(const UpdateCallback& callback) override;
 
   // Sets this device's messaging credentials.
-  virtual void SetDeviceCredentials(uint64 device_android_id,
-                                    uint64 device_security_token,
-                                    const UpdateCallback& callback) override;
+  void SetDeviceCredentials(uint64 device_android_id,
+                            uint64 device_security_token,
+                            const UpdateCallback& callback) override;
 
   // Registration info.
-  virtual void AddRegistration(const std::string& app_id,
-                               const linked_ptr<RegistrationInfo>& registration,
-                               const UpdateCallback& callback) override;
-  virtual void RemoveRegistration(const std::string& app_id,
-                                  const UpdateCallback& callback) override;
+  void AddRegistration(const std::string& app_id,
+                       const linked_ptr<RegistrationInfo>& registration,
+                       const UpdateCallback& callback) override;
+  void RemoveRegistration(const std::string& app_id,
+                          const UpdateCallback& callback) override;
 
   // Unacknowledged incoming message handling.
-  virtual void AddIncomingMessage(const std::string& persistent_id,
-                                  const UpdateCallback& callback) override;
-  virtual void RemoveIncomingMessage(const std::string& persistent_id,
-                                     const UpdateCallback& callback) override;
-  virtual void RemoveIncomingMessages(const PersistentIdList& persistent_ids,
-                                      const UpdateCallback& callback) override;
+  void AddIncomingMessage(const std::string& persistent_id,
+                          const UpdateCallback& callback) override;
+  void RemoveIncomingMessage(const std::string& persistent_id,
+                             const UpdateCallback& callback) override;
+  void RemoveIncomingMessages(const PersistentIdList& persistent_ids,
+                              const UpdateCallback& callback) override;
 
   // Unacknowledged outgoing messages handling.
-  virtual bool AddOutgoingMessage(const std::string& persistent_id,
-                                  const MCSMessage& message,
-                                  const UpdateCallback& callback) override;
-  virtual void OverwriteOutgoingMessage(const std::string& persistent_id,
-                                        const MCSMessage& message,
-                                        const UpdateCallback& callback)
-      override;
-  virtual void RemoveOutgoingMessage(const std::string& persistent_id,
-                                     const UpdateCallback& callback) override;
-  virtual void RemoveOutgoingMessages(const PersistentIdList& persistent_ids,
-                                      const UpdateCallback& callback) override;
+  bool AddOutgoingMessage(const std::string& persistent_id,
+                          const MCSMessage& message,
+                          const UpdateCallback& callback) override;
+  void OverwriteOutgoingMessage(const std::string& persistent_id,
+                                const MCSMessage& message,
+                                const UpdateCallback& callback) override;
+  void RemoveOutgoingMessage(const std::string& persistent_id,
+                             const UpdateCallback& callback) override;
+  void RemoveOutgoingMessages(const PersistentIdList& persistent_ids,
+                              const UpdateCallback& callback) override;
 
   // Sets last device's checkin information.
-  virtual void SetLastCheckinInfo(const base::Time& time,
-                                  const std::set<std::string>& accounts,
-                                  const UpdateCallback& callback) override;
+  void SetLastCheckinInfo(const base::Time& time,
+                          const std::set<std::string>& accounts,
+                          const UpdateCallback& callback) override;
 
   // G-service settings handling.
-  virtual void SetGServicesSettings(
-      const std::map<std::string, std::string>& settings,
-      const std::string& settings_digest,
-      const UpdateCallback& callback) override;
+  void SetGServicesSettings(const std::map<std::string, std::string>& settings,
+                            const std::string& settings_digest,
+                            const UpdateCallback& callback) override;
 
   // Sets the account information related to device to account mapping.
-  virtual void AddAccountMapping(const AccountMapping& account_mapping,
-                                 const UpdateCallback& callback) override;
-  virtual void RemoveAccountMapping(const std::string& account_id,
-                                    const UpdateCallback& callback) override;
+  void AddAccountMapping(const AccountMapping& account_mapping,
+                         const UpdateCallback& callback) override;
+  void RemoveAccountMapping(const std::string& account_id,
+                            const UpdateCallback& callback) override;
 
  private:
   typedef std::map<std::string, int> AppIdToMessageCountMap;
diff --git a/google_apis/gcm/engine/mcs_client_unittest.cc b/google_apis/gcm/engine/mcs_client_unittest.cc
index 348531b..b72fa69 100644
--- a/google_apis/gcm/engine/mcs_client_unittest.cc
+++ b/google_apis/gcm/engine/mcs_client_unittest.cc
@@ -74,7 +74,7 @@
       next_id_(0) {
   }
 
-  virtual std::string GetNextPersistentId() override {
+  std::string GetNextPersistentId() override {
     return base::UintToString(++next_id_);
   }
 
diff --git a/google_apis/gcm/engine/registration_request.h b/google_apis/gcm/engine/registration_request.h
index 736f4b4..1f707b9 100644
--- a/google_apis/gcm/engine/registration_request.h
+++ b/google_apis/gcm/engine/registration_request.h
@@ -89,12 +89,12 @@
       int max_retry_count,
       scoped_refptr<net::URLRequestContextGetter> request_context_getter,
       GCMStatsRecorder* recorder);
-  virtual ~RegistrationRequest();
+  ~RegistrationRequest() override;
 
   void Start();
 
   // URLFetcherDelegate implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  private:
   // Schedules a retry attempt, informs the backoff of a previous request's
diff --git a/google_apis/gcm/engine/unregistration_request.h b/google_apis/gcm/engine/unregistration_request.h
index 39887ab..c5c0eb5 100644
--- a/google_apis/gcm/engine/unregistration_request.h
+++ b/google_apis/gcm/engine/unregistration_request.h
@@ -80,13 +80,13 @@
       const UnregistrationCallback& callback,
       scoped_refptr<net::URLRequestContextGetter> request_context_getter,
       GCMStatsRecorder* recorder);
-  virtual ~UnregistrationRequest();
+  ~UnregistrationRequest() override;
 
   // Starts an unregistration request.
   void Start();
 
   // URLFetcherDelegate implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  private:
   // Schedules a retry attempt and informs the backoff of previous request's
diff --git a/google_apis/gcm/monitoring/fake_gcm_stats_recorder.h b/google_apis/gcm/monitoring/fake_gcm_stats_recorder.h
index 9e8646e..d4503dd 100644
--- a/google_apis/gcm/monitoring/fake_gcm_stats_recorder.h
+++ b/google_apis/gcm/monitoring/fake_gcm_stats_recorder.h
@@ -13,54 +13,51 @@
 class FakeGCMStatsRecorder : public GCMStatsRecorder {
  public:
   FakeGCMStatsRecorder();
-  virtual ~FakeGCMStatsRecorder();
+  ~FakeGCMStatsRecorder() override;
 
-  virtual void RecordCheckinInitiated(uint64 android_id) override;
-  virtual void RecordCheckinDelayedDueToBackoff(int64 delay_msec) override;
-  virtual void RecordCheckinSuccess() override;
-  virtual void RecordCheckinFailure(std::string status,
-                                    bool will_retry) override;
-  virtual void RecordConnectionInitiated(const std::string& host) override;
-  virtual void RecordConnectionDelayedDueToBackoff(int64 delay_msec) override;
-  virtual void RecordConnectionSuccess() override;
-  virtual void RecordConnectionFailure(int network_error) override;
-  virtual void RecordConnectionResetSignaled(
+  void RecordCheckinInitiated(uint64 android_id) override;
+  void RecordCheckinDelayedDueToBackoff(int64 delay_msec) override;
+  void RecordCheckinSuccess() override;
+  void RecordCheckinFailure(std::string status, bool will_retry) override;
+  void RecordConnectionInitiated(const std::string& host) override;
+  void RecordConnectionDelayedDueToBackoff(int64 delay_msec) override;
+  void RecordConnectionSuccess() override;
+  void RecordConnectionFailure(int network_error) override;
+  void RecordConnectionResetSignaled(
       ConnectionFactory::ConnectionResetReason reason) override;
-  virtual void RecordRegistrationSent(const std::string& app_id,
-                                      const std::string& sender_ids) override;
-  virtual void RecordRegistrationResponse(
-      const std::string& app_id,
-      const std::vector<std::string>& sender_ids,
-      RegistrationRequest::Status status) override;
-  virtual void RecordRegistrationRetryRequested(
+  void RecordRegistrationSent(const std::string& app_id,
+                              const std::string& sender_ids) override;
+  void RecordRegistrationResponse(const std::string& app_id,
+                                  const std::vector<std::string>& sender_ids,
+                                  RegistrationRequest::Status status) override;
+  void RecordRegistrationRetryRequested(
       const std::string& app_id,
       const std::vector<std::string>& sender_ids,
       int retries_left) override;
-  virtual void RecordUnregistrationSent(const std::string& app_id) override;
-  virtual void RecordUnregistrationResponse(
+  void RecordUnregistrationSent(const std::string& app_id) override;
+  void RecordUnregistrationResponse(
       const std::string& app_id,
       UnregistrationRequest::Status status) override;
-  virtual void RecordUnregistrationRetryDelayed(const std::string& app_id,
-                                                int64 delay_msec) override;
-  virtual void RecordDataMessageReceived(
-      const std::string& app_id,
-      const std::string& from,
-      int message_byte_size,
-      bool to_registered_app,
-      ReceivedMessageType message_type) override;
-  virtual void RecordDataSentToWire(const std::string& app_id,
-                                    const std::string& receiver_id,
-                                    const std::string& message_id,
-                                    int queued) override;
-  virtual void RecordNotifySendStatus(const std::string& app_id,
-                                      const std::string& receiver_id,
-                                      const std::string& message_id,
-                                      MCSClient::MessageSendStatus status,
-                                      int byte_size,
-                                      int ttl) override;
-  virtual void RecordIncomingSendError(const std::string& app_id,
-                                       const std::string& receiver_id,
-                                       const std::string& message_id) override;
+  void RecordUnregistrationRetryDelayed(const std::string& app_id,
+                                        int64 delay_msec) override;
+  void RecordDataMessageReceived(const std::string& app_id,
+                                 const std::string& from,
+                                 int message_byte_size,
+                                 bool to_registered_app,
+                                 ReceivedMessageType message_type) override;
+  void RecordDataSentToWire(const std::string& app_id,
+                            const std::string& receiver_id,
+                            const std::string& message_id,
+                            int queued) override;
+  void RecordNotifySendStatus(const std::string& app_id,
+                              const std::string& receiver_id,
+                              const std::string& message_id,
+                              MCSClient::MessageSendStatus status,
+                              int byte_size,
+                              int ttl) override;
+  void RecordIncomingSendError(const std::string& app_id,
+                               const std::string& receiver_id,
+                               const std::string& message_id) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FakeGCMStatsRecorder);
diff --git a/google_apis/gcm/tools/mcs_probe.cc b/google_apis/gcm/tools/mcs_probe.cc
index 7c83afc..cbee95f 100644
--- a/google_apis/gcm/tools/mcs_probe.cc
+++ b/google_apis/gcm/tools/mcs_probe.cc
@@ -139,7 +139,7 @@
     Init();
   }
 
-  virtual ~MyTestURLRequestContext() {}
+  ~MyTestURLRequestContext() override {}
 };
 
 class MyTestURLRequestContextGetter : public net::TestURLRequestContextGetter {
@@ -148,7 +148,7 @@
       const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy)
       : TestURLRequestContextGetter(io_message_loop_proxy) {}
 
-  virtual net::TestURLRequestContext* GetURLRequestContext() override {
+  net::TestURLRequestContext* GetURLRequestContext() override {
     // Construct |context_| lazily so it gets constructed on the right
     // thread (the IO thread).
     if (!context_)
@@ -157,7 +157,7 @@
   }
 
  private:
-  virtual ~MyTestURLRequestContextGetter() {}
+  ~MyTestURLRequestContextGetter() override {}
 
   scoped_ptr<MyTestURLRequestContext> context_;
 };
@@ -166,20 +166,20 @@
 class MyTestCertVerifier : public net::CertVerifier {
  public:
   MyTestCertVerifier() {}
-  virtual ~MyTestCertVerifier() {}
+  ~MyTestCertVerifier() override {}
 
-  virtual int Verify(net::X509Certificate* cert,
-                     const std::string& hostname,
-                     int flags,
-                     net::CRLSet* crl_set,
-                     net::CertVerifyResult* verify_result,
-                     const net::CompletionCallback& callback,
-                     RequestHandle* out_req,
-                     const net::BoundNetLog& net_log) override {
+  int Verify(net::X509Certificate* cert,
+             const std::string& hostname,
+             int flags,
+             net::CRLSet* crl_set,
+             net::CertVerifyResult* verify_result,
+             const net::CompletionCallback& callback,
+             RequestHandle* out_req,
+             const net::BoundNetLog& net_log) override {
     return net::OK;
   }
 
-  virtual void CancelRequest(RequestHandle req) override {
+  void CancelRequest(RequestHandle req) override {
     // Do nothing.
   }
 };
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index 843cb311..c6a39198 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -237,5 +237,6 @@
   GLES2_GET_FUN(ScheduleOverlayPlaneCHROMIUM)
 #define glMatrixLoadfCHROMIUM GLES2_GET_FUN(MatrixLoadfCHROMIUM)
 #define glMatrixLoadIdentityCHROMIUM GLES2_GET_FUN(MatrixLoadIdentityCHROMIUM)
+#define glBlendBarrierKHR GLES2_GET_FUN(BlendBarrierKHR)
 
 #endif  // GPU_GLES2_GL2CHROMIUM_AUTOGEN_H_
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 14191f2..94c3b34 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1546,6 +1546,12 @@
     'type': 'StateSet',
     'state': 'BlendFunc',
   },
+  'BlendBarrierKHR': {
+    'gl_test_func': 'glBlendBarrierKHR',
+    'extension': True,
+    'extension_flag': 'blend_equation_advanced',
+    'client_test': False,
+  },
   'SampleCoverage': {'decoder_func': 'DoSampleCoverage'},
   'StencilFunc': {
     'type': 'StateSetFrontBack',
@@ -3139,7 +3145,7 @@
     """Writes the GLES2 Implemention declaration."""
     impl_decl = func.GetInfo('impl_decl')
     if impl_decl == None or impl_decl == True:
-      file.Write("virtual %s %s(%s) override;\n" %
+      file.Write("%s %s(%s) override;\n" %
                  (func.return_type, func.original_name,
                   func.MakeTypedOriginalArgString("")))
       file.Write("\n")
@@ -3180,7 +3186,7 @@
 
   def WriteGLES2TraceImplementationHeader(self, func, file):
     """Writes the GLES2 Trace Implemention header."""
-    file.Write("virtual %s %s(%s) override;\n" %
+    file.Write("%s %s(%s) override;\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
 
@@ -3231,7 +3237,7 @@
 
   def WriteGLES2InterfaceStub(self, func, file):
     """Writes the GLES2 Interface stub declaration."""
-    file.Write("virtual %s %s(%s) override;\n" %
+    file.Write("%s %s(%s) override;\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
 
@@ -3828,7 +3834,7 @@
 
   def WriteGLES2ImplementationHeader(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("virtual %s %s(%s) override;\n" %
+    file.Write("%s %s(%s) override;\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
     file.Write("\n")
diff --git a/gpu/command_buffer/client/buffer_tracker_unittest.cc b/gpu/command_buffer/client/buffer_tracker_unittest.cc
index 39ff633..a244009 100644
--- a/gpu/command_buffer/client/buffer_tracker_unittest.cc
+++ b/gpu/command_buffer/client/buffer_tracker_unittest.cc
@@ -23,10 +23,10 @@
   MockClientCommandBufferImpl()
       : MockClientCommandBuffer(),
         context_lost_(false) {}
-  virtual ~MockClientCommandBufferImpl() {}
+  ~MockClientCommandBufferImpl() override {}
 
-  virtual scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
-                                                          int32* id) override {
+  scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
+                                                  int32* id) override {
     if (context_lost_) {
       *id = -1;
       return NULL;
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h
index 51c6b6d3..2cf18e6 100644
--- a/gpu/command_buffer/client/client_test_helper.h
+++ b/gpu/command_buffer/client/client_test_helper.h
@@ -26,21 +26,21 @@
   static const int32 kMaxTransferBuffers = 6;
 
   MockCommandBufferBase();
-  virtual ~MockCommandBufferBase();
+  ~MockCommandBufferBase() override;
 
-  virtual bool Initialize() override;
-  virtual State GetLastState() override;
-  virtual int32 GetLastToken() override;
-  virtual void WaitForTokenInRange(int32 start, int32 end) override;
-  virtual void WaitForGetOffsetInRange(int32 start, int32 end) override;
-  virtual void SetGetBuffer(int transfer_buffer_id) override;
-  virtual void SetGetOffset(int32 get_offset) override;
-  virtual scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
-                                                          int32* id) override;
-  virtual scoped_refptr<gpu::Buffer> GetTransferBuffer(int32 id) override;
-  virtual void SetToken(int32 token) override;
-  virtual void SetParseError(error::Error error) override;
-  virtual void SetContextLostReason(error::ContextLostReason reason) override;
+  bool Initialize() override;
+  State GetLastState() override;
+  int32 GetLastToken() override;
+  void WaitForTokenInRange(int32 start, int32 end) override;
+  void WaitForGetOffsetInRange(int32 start, int32 end) override;
+  void SetGetBuffer(int transfer_buffer_id) override;
+  void SetGetOffset(int32 get_offset) override;
+  scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
+                                                  int32* id) override;
+  scoped_refptr<gpu::Buffer> GetTransferBuffer(int32 id) override;
+  void SetToken(int32 token) override;
+  void SetParseError(error::Error error) override;
+  void SetContextLostReason(error::ContextLostReason reason) override;
 
   // Get's the Id of the next transfer buffer that will be returned
   // by CreateTransferBuffer. This is useful for testing expected ids.
diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
index 2d367acda..3ff9d3a 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc
@@ -46,9 +46,9 @@
         flush_locked_(false),
         last_flush_(-1),
         flush_count_(0) {}
-  virtual ~CommandBufferServiceLocked() {}
+  ~CommandBufferServiceLocked() override {}
 
-  virtual void Flush(int32 put_offset) override {
+  void Flush(int32 put_offset) override {
     flush_count_++;
     if (!flush_locked_) {
       last_flush_ = -1;
@@ -64,7 +64,7 @@
 
   int FlushCount() { return flush_count_; }
 
-  virtual void WaitForGetOffsetInRange(int32 start, int32 end) override {
+  void WaitForGetOffsetInRange(int32 start, int32 end) override {
     if (last_flush_ != -1) {
       CommandBufferService::Flush(last_flush_);
       last_flush_ = -1;
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc
index e8771191..7f24bd6 100644
--- a/gpu/command_buffer/client/gl_in_process_context.cc
+++ b/gpu/command_buffer/client/gl_in_process_context.cc
@@ -48,7 +48,7 @@
  public:
   explicit GLInProcessContextImpl(
       const GLInProcessContextSharedMemoryLimits& mem_limits);
-  virtual ~GLInProcessContextImpl();
+  ~GLInProcessContextImpl() override;
 
   bool Initialize(
       scoped_refptr<gfx::GLSurface> surface,
@@ -62,9 +62,9 @@
       const scoped_refptr<InProcessCommandBuffer::Service>& service);
 
   // GLInProcessContext implementation:
-  virtual void SetContextLostCallback(const base::Closure& callback) override;
-  virtual gles2::GLES2Implementation* GetImplementation() override;
-  virtual size_t GetMappedMemoryLimit() override;
+  void SetContextLostCallback(const base::Closure& callback) override;
+  gles2::GLES2Implementation* GetImplementation() override;
+  size_t GetMappedMemoryLimit() override;
 
 #if defined(OS_ANDROID)
   virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture(
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 71e3c82c..392bb22f 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -958,6 +958,9 @@
 void GLES2MatrixLoadIdentityCHROMIUM(GLenum matrixMode) {
   gles2::GetGLContext()->MatrixLoadIdentityCHROMIUM(matrixMode);
 }
+void GLES2BlendBarrierKHR() {
+  gles2::GetGLContext()->BlendBarrierKHR();
+}
 
 namespace gles2 {
 
@@ -1817,6 +1820,10 @@
      reinterpret_cast<GLES2FunctionPointer>(glMatrixLoadIdentityCHROMIUM),
     },
     {
+     "glBlendBarrierKHR",
+     reinterpret_cast<GLES2FunctionPointer>(glBlendBarrierKHR),
+    },
+    {
      NULL,
      NULL,
     },
diff --git a/gpu/command_buffer/client/gles2_cmd_helper.h b/gpu/command_buffer/client/gles2_cmd_helper.h
index af6cc5d..8a5cde1 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper.h
@@ -16,7 +16,7 @@
 class GPU_EXPORT GLES2CmdHelper : public CommandBufferHelper {
  public:
   explicit GLES2CmdHelper(CommandBuffer* command_buffer);
-  virtual ~GLES2CmdHelper();
+  ~GLES2CmdHelper() override;
 
   // Include the auto-generated part of this class. We split this because it
   // means we can easily edit the non-auto generated parts right here in this
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index c8432dab..24d8be2 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1929,4 +1929,11 @@
   }
 }
 
+void BlendBarrierKHR() {
+  gles2::cmds::BlendBarrierKHR* c = GetCmdSpace<gles2::cmds::BlendBarrierKHR>();
+  if (c) {
+    c->Init();
+  }
+}
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 1025a3e..972291e 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -191,7 +191,7 @@
                       bool lose_context_when_out_of_memory,
                       GpuControl* gpu_control);
 
-  virtual ~GLES2Implementation();
+  ~GLES2Implementation() override;
 
   bool Initialize(
       unsigned int starting_transfer_buffer_size,
@@ -211,23 +211,21 @@
   // this file instead of having to edit some template or the code generator.
   #include "gpu/command_buffer/client/gles2_implementation_autogen.h"
 
-  virtual void DisableVertexAttribArray(GLuint index) override;
-  virtual void EnableVertexAttribArray(GLuint index) override;
-  virtual void GetVertexAttribfv(
-      GLuint index, GLenum pname, GLfloat* params) override;
-  virtual void GetVertexAttribiv(
-      GLuint index, GLenum pname, GLint* params) override;
+  void DisableVertexAttribArray(GLuint index) override;
+  void EnableVertexAttribArray(GLuint index) override;
+  void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) override;
+  void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) override;
 
   // ContextSupport implementation.
-  virtual void Swap() override;
-  virtual void PartialSwapBuffers(const gfx::Rect& sub_buffer) override;
-  virtual void ScheduleOverlayPlane(int plane_z_order,
-                                    gfx::OverlayTransform plane_transform,
-                                    unsigned overlay_texture_id,
-                                    const gfx::Rect& display_bounds,
-                                    const gfx::RectF& uv_rect) override;
-  virtual GLuint InsertFutureSyncPointCHROMIUM() override;
-  virtual void RetireSyncPointCHROMIUM(GLuint sync_point) override;
+  void Swap() override;
+  void PartialSwapBuffers(const gfx::Rect& sub_buffer) override;
+  void ScheduleOverlayPlane(int plane_z_order,
+                            gfx::OverlayTransform plane_transform,
+                            unsigned overlay_texture_id,
+                            const gfx::Rect& display_bounds,
+                            const gfx::RectF& uv_rect) override;
+  GLuint InsertFutureSyncPointCHROMIUM() override;
+  void RetireSyncPointCHROMIUM(GLuint sync_point) override;
 
   void GetProgramInfoCHROMIUMHelper(GLuint program, std::vector<int8>* result);
   GLint GetAttribLocationHelper(GLuint program, const char* name);
@@ -243,11 +241,10 @@
   void FreeEverything();
 
   // ContextSupport implementation.
-  virtual void SignalSyncPoint(uint32 sync_point,
-                               const base::Closure& callback) override;
-  virtual void SignalQuery(uint32 query,
-                           const base::Closure& callback) override;
-  virtual void SetSurfaceVisible(bool visible) override;
+  void SignalSyncPoint(uint32 sync_point,
+                       const base::Closure& callback) override;
+  void SignalQuery(uint32 query, const base::Closure& callback) override;
+  void SetSurfaceVisible(bool visible) override;
 
   void SetErrorMessageCallback(
       GLES2ImplementationErrorMessageCallback* callback) {
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 5465fc7..3ef98dd 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -13,720 +13,684 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
 #define GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
 
-virtual void ActiveTexture(GLenum texture) override;
+void ActiveTexture(GLenum texture) override;
 
-virtual void AttachShader(GLuint program, GLuint shader) override;
+void AttachShader(GLuint program, GLuint shader) override;
 
-virtual void BindAttribLocation(GLuint program,
-                                GLuint index,
-                                const char* name) override;
+void BindAttribLocation(GLuint program,
+                        GLuint index,
+                        const char* name) override;
 
-virtual void BindBuffer(GLenum target, GLuint buffer) override;
+void BindBuffer(GLenum target, GLuint buffer) override;
 
-virtual void BindFramebuffer(GLenum target, GLuint framebuffer) override;
+void BindFramebuffer(GLenum target, GLuint framebuffer) override;
 
-virtual void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
+void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
 
-virtual void BindTexture(GLenum target, GLuint texture) override;
+void BindTexture(GLenum target, GLuint texture) override;
 
-virtual void BlendColor(GLclampf red,
-                        GLclampf green,
-                        GLclampf blue,
-                        GLclampf alpha) override;
+void BlendColor(GLclampf red,
+                GLclampf green,
+                GLclampf blue,
+                GLclampf alpha) override;
 
-virtual void BlendEquation(GLenum mode) override;
+void BlendEquation(GLenum mode) override;
 
-virtual void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) override;
+void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) override;
 
-virtual void BlendFunc(GLenum sfactor, GLenum dfactor) override;
+void BlendFunc(GLenum sfactor, GLenum dfactor) override;
 
-virtual void BlendFuncSeparate(GLenum srcRGB,
-                               GLenum dstRGB,
-                               GLenum srcAlpha,
-                               GLenum dstAlpha) override;
+void BlendFuncSeparate(GLenum srcRGB,
+                       GLenum dstRGB,
+                       GLenum srcAlpha,
+                       GLenum dstAlpha) override;
 
-virtual void BufferData(GLenum target,
-                        GLsizeiptr size,
-                        const void* data,
-                        GLenum usage) override;
+void BufferData(GLenum target,
+                GLsizeiptr size,
+                const void* data,
+                GLenum usage) override;
 
-virtual void BufferSubData(GLenum target,
-                           GLintptr offset,
-                           GLsizeiptr size,
-                           const void* data) override;
+void BufferSubData(GLenum target,
+                   GLintptr offset,
+                   GLsizeiptr size,
+                   const void* data) override;
 
-virtual GLenum CheckFramebufferStatus(GLenum target) override;
+GLenum CheckFramebufferStatus(GLenum target) override;
 
-virtual void Clear(GLbitfield mask) override;
+void Clear(GLbitfield mask) override;
 
-virtual void ClearColor(GLclampf red,
-                        GLclampf green,
-                        GLclampf blue,
-                        GLclampf alpha) override;
+void ClearColor(GLclampf red,
+                GLclampf green,
+                GLclampf blue,
+                GLclampf alpha) override;
 
-virtual void ClearDepthf(GLclampf depth) override;
+void ClearDepthf(GLclampf depth) override;
 
-virtual void ClearStencil(GLint s) override;
+void ClearStencil(GLint s) override;
 
-virtual void ColorMask(GLboolean red,
-                       GLboolean green,
-                       GLboolean blue,
-                       GLboolean alpha) override;
+void ColorMask(GLboolean red,
+               GLboolean green,
+               GLboolean blue,
+               GLboolean alpha) override;
 
-virtual void CompileShader(GLuint shader) override;
+void CompileShader(GLuint shader) override;
 
-virtual void CompressedTexImage2D(GLenum target,
-                                  GLint level,
-                                  GLenum internalformat,
-                                  GLsizei width,
-                                  GLsizei height,
-                                  GLint border,
-                                  GLsizei imageSize,
-                                  const void* data) override;
+void CompressedTexImage2D(GLenum target,
+                          GLint level,
+                          GLenum internalformat,
+                          GLsizei width,
+                          GLsizei height,
+                          GLint border,
+                          GLsizei imageSize,
+                          const void* data) override;
 
-virtual void CompressedTexSubImage2D(GLenum target,
-                                     GLint level,
-                                     GLint xoffset,
-                                     GLint yoffset,
-                                     GLsizei width,
-                                     GLsizei height,
-                                     GLenum format,
-                                     GLsizei imageSize,
-                                     const void* data) override;
+void CompressedTexSubImage2D(GLenum target,
+                             GLint level,
+                             GLint xoffset,
+                             GLint yoffset,
+                             GLsizei width,
+                             GLsizei height,
+                             GLenum format,
+                             GLsizei imageSize,
+                             const void* data) override;
 
-virtual void CopyTexImage2D(GLenum target,
-                            GLint level,
-                            GLenum internalformat,
-                            GLint x,
-                            GLint y,
-                            GLsizei width,
-                            GLsizei height,
-                            GLint border) override;
+void CopyTexImage2D(GLenum target,
+                    GLint level,
+                    GLenum internalformat,
+                    GLint x,
+                    GLint y,
+                    GLsizei width,
+                    GLsizei height,
+                    GLint border) override;
 
-virtual void CopyTexSubImage2D(GLenum target,
+void CopyTexSubImage2D(GLenum target,
+                       GLint level,
+                       GLint xoffset,
+                       GLint yoffset,
+                       GLint x,
+                       GLint y,
+                       GLsizei width,
+                       GLsizei height) override;
+
+GLuint CreateProgram() override;
+
+GLuint CreateShader(GLenum type) override;
+
+void CullFace(GLenum mode) override;
+
+void DeleteBuffers(GLsizei n, const GLuint* buffers) override;
+
+void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
+
+void DeleteProgram(GLuint program) override;
+
+void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override;
+
+void DeleteShader(GLuint shader) override;
+
+void DeleteTextures(GLsizei n, const GLuint* textures) override;
+
+void DepthFunc(GLenum func) override;
+
+void DepthMask(GLboolean flag) override;
+
+void DepthRangef(GLclampf zNear, GLclampf zFar) override;
+
+void DetachShader(GLuint program, GLuint shader) override;
+
+void Disable(GLenum cap) override;
+
+void DrawArrays(GLenum mode, GLint first, GLsizei count) override;
+
+void DrawElements(GLenum mode,
+                  GLsizei count,
+                  GLenum type,
+                  const void* indices) override;
+
+void Enable(GLenum cap) override;
+
+void Finish() override;
+
+void Flush() override;
+
+void FramebufferRenderbuffer(GLenum target,
+                             GLenum attachment,
+                             GLenum renderbuffertarget,
+                             GLuint renderbuffer) override;
+
+void FramebufferTexture2D(GLenum target,
+                          GLenum attachment,
+                          GLenum textarget,
+                          GLuint texture,
+                          GLint level) override;
+
+void FrontFace(GLenum mode) override;
+
+void GenBuffers(GLsizei n, GLuint* buffers) override;
+
+void GenerateMipmap(GLenum target) override;
+
+void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
+
+void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
+
+void GenTextures(GLsizei n, GLuint* textures) override;
+
+void GetActiveAttrib(GLuint program,
+                     GLuint index,
+                     GLsizei bufsize,
+                     GLsizei* length,
+                     GLint* size,
+                     GLenum* type,
+                     char* name) override;
+
+void GetActiveUniform(GLuint program,
+                      GLuint index,
+                      GLsizei bufsize,
+                      GLsizei* length,
+                      GLint* size,
+                      GLenum* type,
+                      char* name) override;
+
+void GetAttachedShaders(GLuint program,
+                        GLsizei maxcount,
+                        GLsizei* count,
+                        GLuint* shaders) override;
+
+GLint GetAttribLocation(GLuint program, const char* name) override;
+
+void GetBooleanv(GLenum pname, GLboolean* params) override;
+
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) override;
+
+GLenum GetError() override;
+
+void GetFloatv(GLenum pname, GLfloat* params) override;
+
+void GetFramebufferAttachmentParameteriv(GLenum target,
+                                         GLenum attachment,
+                                         GLenum pname,
+                                         GLint* params) override;
+
+void GetIntegerv(GLenum pname, GLint* params) override;
+
+void GetProgramiv(GLuint program, GLenum pname, GLint* params) override;
+
+void GetProgramInfoLog(GLuint program,
+                       GLsizei bufsize,
+                       GLsizei* length,
+                       char* infolog) override;
+
+void GetRenderbufferParameteriv(GLenum target,
+                                GLenum pname,
+                                GLint* params) override;
+
+void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
+
+void GetShaderInfoLog(GLuint shader,
+                      GLsizei bufsize,
+                      GLsizei* length,
+                      char* infolog) override;
+
+void GetShaderPrecisionFormat(GLenum shadertype,
+                              GLenum precisiontype,
+                              GLint* range,
+                              GLint* precision) override;
+
+void GetShaderSource(GLuint shader,
+                     GLsizei bufsize,
+                     GLsizei* length,
+                     char* source) override;
+
+const GLubyte* GetString(GLenum name) override;
+
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override;
+
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override;
+
+void GetUniformfv(GLuint program, GLint location, GLfloat* params) override;
+
+void GetUniformiv(GLuint program, GLint location, GLint* params) override;
+
+GLint GetUniformLocation(GLuint program, const char* name) override;
+
+void GetVertexAttribPointerv(GLuint index,
+                             GLenum pname,
+                             void** pointer) override;
+
+void Hint(GLenum target, GLenum mode) override;
+
+GLboolean IsBuffer(GLuint buffer) override;
+
+GLboolean IsEnabled(GLenum cap) override;
+
+GLboolean IsFramebuffer(GLuint framebuffer) override;
+
+GLboolean IsProgram(GLuint program) override;
+
+GLboolean IsRenderbuffer(GLuint renderbuffer) override;
+
+GLboolean IsShader(GLuint shader) override;
+
+GLboolean IsTexture(GLuint texture) override;
+
+void LineWidth(GLfloat width) override;
+
+void LinkProgram(GLuint program) override;
+
+void PixelStorei(GLenum pname, GLint param) override;
+
+void PolygonOffset(GLfloat factor, GLfloat units) override;
+
+void ReadPixels(GLint x,
+                GLint y,
+                GLsizei width,
+                GLsizei height,
+                GLenum format,
+                GLenum type,
+                void* pixels) override;
+
+void ReleaseShaderCompiler() override;
+
+void RenderbufferStorage(GLenum target,
+                         GLenum internalformat,
+                         GLsizei width,
+                         GLsizei height) override;
+
+void SampleCoverage(GLclampf value, GLboolean invert) override;
+
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
+
+void ShaderBinary(GLsizei n,
+                  const GLuint* shaders,
+                  GLenum binaryformat,
+                  const void* binary,
+                  GLsizei length) override;
+
+void ShaderSource(GLuint shader,
+                  GLsizei count,
+                  const GLchar* const* str,
+                  const GLint* length) override;
+
+void ShallowFinishCHROMIUM() override;
+
+void ShallowFlushCHROMIUM() override;
+
+void StencilFunc(GLenum func, GLint ref, GLuint mask) override;
+
+void StencilFuncSeparate(GLenum face,
+                         GLenum func,
+                         GLint ref,
+                         GLuint mask) override;
+
+void StencilMask(GLuint mask) override;
+
+void StencilMaskSeparate(GLenum face, GLuint mask) override;
+
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) override;
+
+void StencilOpSeparate(GLenum face,
+                       GLenum fail,
+                       GLenum zfail,
+                       GLenum zpass) override;
+
+void TexImage2D(GLenum target,
+                GLint level,
+                GLint internalformat,
+                GLsizei width,
+                GLsizei height,
+                GLint border,
+                GLenum format,
+                GLenum type,
+                const void* pixels) override;
+
+void TexParameterf(GLenum target, GLenum pname, GLfloat param) override;
+
+void TexParameterfv(GLenum target,
+                    GLenum pname,
+                    const GLfloat* params) override;
+
+void TexParameteri(GLenum target, GLenum pname, GLint param) override;
+
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override;
+
+void TexSubImage2D(GLenum target,
+                   GLint level,
+                   GLint xoffset,
+                   GLint yoffset,
+                   GLsizei width,
+                   GLsizei height,
+                   GLenum format,
+                   GLenum type,
+                   const void* pixels) override;
+
+void Uniform1f(GLint location, GLfloat x) override;
+
+void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) override;
+
+void Uniform1i(GLint location, GLint x) override;
+
+void Uniform1iv(GLint location, GLsizei count, const GLint* v) override;
+
+void Uniform2f(GLint location, GLfloat x, GLfloat y) override;
+
+void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override;
+
+void Uniform2i(GLint location, GLint x, GLint y) override;
+
+void Uniform2iv(GLint location, GLsizei count, const GLint* v) override;
+
+void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override;
+
+void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override;
+
+void Uniform3i(GLint location, GLint x, GLint y, GLint z) override;
+
+void Uniform3iv(GLint location, GLsizei count, const GLint* v) override;
+
+void Uniform4f(GLint location,
+               GLfloat x,
+               GLfloat y,
+               GLfloat z,
+               GLfloat w) override;
+
+void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) override;
+
+void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override;
+
+void Uniform4iv(GLint location, GLsizei count, const GLint* v) override;
+
+void UniformMatrix2fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+
+void UniformMatrix3fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+
+void UniformMatrix4fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+
+void UseProgram(GLuint program) override;
+
+void ValidateProgram(GLuint program) override;
+
+void VertexAttrib1f(GLuint indx, GLfloat x) override;
+
+void VertexAttrib1fv(GLuint indx, const GLfloat* values) override;
+
+void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) override;
+
+void VertexAttrib2fv(GLuint indx, const GLfloat* values) override;
+
+void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) override;
+
+void VertexAttrib3fv(GLuint indx, const GLfloat* values) override;
+
+void VertexAttrib4f(GLuint indx,
+                    GLfloat x,
+                    GLfloat y,
+                    GLfloat z,
+                    GLfloat w) override;
+
+void VertexAttrib4fv(GLuint indx, const GLfloat* values) override;
+
+void VertexAttribPointer(GLuint indx,
+                         GLint size,
+                         GLenum type,
+                         GLboolean normalized,
+                         GLsizei stride,
+                         const void* ptr) override;
+
+void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override;
+
+void BlitFramebufferCHROMIUM(GLint srcX0,
+                             GLint srcY0,
+                             GLint srcX1,
+                             GLint srcY1,
+                             GLint dstX0,
+                             GLint dstY0,
+                             GLint dstX1,
+                             GLint dstY1,
+                             GLbitfield mask,
+                             GLenum filter) override;
+
+void RenderbufferStorageMultisampleCHROMIUM(GLenum target,
+                                            GLsizei samples,
+                                            GLenum internalformat,
+                                            GLsizei width,
+                                            GLsizei height) override;
+
+void RenderbufferStorageMultisampleEXT(GLenum target,
+                                       GLsizei samples,
+                                       GLenum internalformat,
+                                       GLsizei width,
+                                       GLsizei height) override;
+
+void FramebufferTexture2DMultisampleEXT(GLenum target,
+                                        GLenum attachment,
+                                        GLenum textarget,
+                                        GLuint texture,
+                                        GLint level,
+                                        GLsizei samples) override;
+
+void TexStorage2DEXT(GLenum target,
+                     GLsizei levels,
+                     GLenum internalFormat,
+                     GLsizei width,
+                     GLsizei height) override;
+
+void GenQueriesEXT(GLsizei n, GLuint* queries) override;
+
+void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
+
+GLboolean IsQueryEXT(GLuint id) override;
+
+void BeginQueryEXT(GLenum target, GLuint id) override;
+
+void EndQueryEXT(GLenum target) override;
+
+void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
+
+void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override;
+
+void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) override;
+
+void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) override;
+
+void PopGroupMarkerEXT() override;
+
+void GenVertexArraysOES(GLsizei n, GLuint* arrays) override;
+
+void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) override;
+
+GLboolean IsVertexArrayOES(GLuint array) override;
+
+void BindVertexArrayOES(GLuint array) override;
+
+void SwapBuffers() override;
+
+GLuint GetMaxValueInBufferCHROMIUM(GLuint buffer_id,
+                                   GLsizei count,
+                                   GLenum type,
+                                   GLuint offset) override;
+
+GLboolean EnableFeatureCHROMIUM(const char* feature) override;
+
+void* MapBufferCHROMIUM(GLuint target, GLenum access) override;
+
+GLboolean UnmapBufferCHROMIUM(GLuint target) override;
+
+void* MapBufferSubDataCHROMIUM(GLuint target,
+                               GLintptr offset,
+                               GLsizeiptr size,
+                               GLenum access) override;
+
+void UnmapBufferSubDataCHROMIUM(const void* mem) override;
+
+void* MapTexSubImage2DCHROMIUM(GLenum target,
                                GLint level,
                                GLint xoffset,
                                GLint yoffset,
-                               GLint x,
-                               GLint y,
                                GLsizei width,
-                               GLsizei height) override;
+                               GLsizei height,
+                               GLenum format,
+                               GLenum type,
+                               GLenum access) override;
 
-virtual GLuint CreateProgram() override;
+void UnmapTexSubImage2DCHROMIUM(const void* mem) override;
 
-virtual GLuint CreateShader(GLenum type) override;
+void ResizeCHROMIUM(GLuint width, GLuint height, GLfloat scale_factor) override;
 
-virtual void CullFace(GLenum mode) override;
+const GLchar* GetRequestableExtensionsCHROMIUM() override;
 
-virtual void DeleteBuffers(GLsizei n, const GLuint* buffers) override;
+void RequestExtensionCHROMIUM(const char* extension) override;
 
-virtual void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
+void RateLimitOffscreenContextCHROMIUM() override;
 
-virtual void DeleteProgram(GLuint program) override;
+void GetMultipleIntegervCHROMIUM(const GLenum* pnames,
+                                 GLuint count,
+                                 GLint* results,
+                                 GLsizeiptr size) override;
 
-virtual void DeleteRenderbuffers(GLsizei n,
-                                 const GLuint* renderbuffers) override;
+void GetProgramInfoCHROMIUM(GLuint program,
+                            GLsizei bufsize,
+                            GLsizei* size,
+                            void* info) override;
 
-virtual void DeleteShader(GLuint shader) override;
+GLuint CreateStreamTextureCHROMIUM(GLuint texture) override;
 
-virtual void DeleteTextures(GLsizei n, const GLuint* textures) override;
-
-virtual void DepthFunc(GLenum func) override;
-
-virtual void DepthMask(GLboolean flag) override;
-
-virtual void DepthRangef(GLclampf zNear, GLclampf zFar) override;
-
-virtual void DetachShader(GLuint program, GLuint shader) override;
-
-virtual void Disable(GLenum cap) override;
-
-virtual void DrawArrays(GLenum mode, GLint first, GLsizei count) override;
-
-virtual void DrawElements(GLenum mode,
-                          GLsizei count,
-                          GLenum type,
-                          const void* indices) override;
-
-virtual void Enable(GLenum cap) override;
-
-virtual void Finish() override;
-
-virtual void Flush() override;
-
-virtual void FramebufferRenderbuffer(GLenum target,
-                                     GLenum attachment,
-                                     GLenum renderbuffertarget,
-                                     GLuint renderbuffer) override;
-
-virtual void FramebufferTexture2D(GLenum target,
-                                  GLenum attachment,
-                                  GLenum textarget,
-                                  GLuint texture,
-                                  GLint level) override;
-
-virtual void FrontFace(GLenum mode) override;
-
-virtual void GenBuffers(GLsizei n, GLuint* buffers) override;
-
-virtual void GenerateMipmap(GLenum target) override;
-
-virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
-
-virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
-
-virtual void GenTextures(GLsizei n, GLuint* textures) override;
-
-virtual void GetActiveAttrib(GLuint program,
-                             GLuint index,
-                             GLsizei bufsize,
-                             GLsizei* length,
-                             GLint* size,
-                             GLenum* type,
-                             char* name) override;
-
-virtual void GetActiveUniform(GLuint program,
-                              GLuint index,
-                              GLsizei bufsize,
-                              GLsizei* length,
-                              GLint* size,
-                              GLenum* type,
-                              char* name) override;
-
-virtual void GetAttachedShaders(GLuint program,
-                                GLsizei maxcount,
-                                GLsizei* count,
-                                GLuint* shaders) override;
-
-virtual GLint GetAttribLocation(GLuint program, const char* name) override;
-
-virtual void GetBooleanv(GLenum pname, GLboolean* params) override;
-
-virtual void GetBufferParameteriv(GLenum target,
-                                  GLenum pname,
-                                  GLint* params) override;
-
-virtual GLenum GetError() override;
-
-virtual void GetFloatv(GLenum pname, GLfloat* params) override;
-
-virtual void GetFramebufferAttachmentParameteriv(GLenum target,
-                                                 GLenum attachment,
-                                                 GLenum pname,
-                                                 GLint* params) override;
-
-virtual void GetIntegerv(GLenum pname, GLint* params) override;
-
-virtual void GetProgramiv(GLuint program, GLenum pname, GLint* params) override;
-
-virtual void GetProgramInfoLog(GLuint program,
-                               GLsizei bufsize,
-                               GLsizei* length,
-                               char* infolog) override;
-
-virtual void GetRenderbufferParameteriv(GLenum target,
-                                        GLenum pname,
-                                        GLint* params) override;
-
-virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
-
-virtual void GetShaderInfoLog(GLuint shader,
-                              GLsizei bufsize,
-                              GLsizei* length,
-                              char* infolog) override;
-
-virtual void GetShaderPrecisionFormat(GLenum shadertype,
-                                      GLenum precisiontype,
-                                      GLint* range,
-                                      GLint* precision) override;
-
-virtual void GetShaderSource(GLuint shader,
-                             GLsizei bufsize,
-                             GLsizei* length,
-                             char* source) override;
-
-virtual const GLubyte* GetString(GLenum name) override;
-
-virtual void GetTexParameterfv(GLenum target,
-                               GLenum pname,
-                               GLfloat* params) override;
-
-virtual void GetTexParameteriv(GLenum target,
-                               GLenum pname,
-                               GLint* params) override;
-
-virtual void GetUniformfv(GLuint program,
-                          GLint location,
-                          GLfloat* params) override;
-
-virtual void GetUniformiv(GLuint program,
-                          GLint location,
-                          GLint* params) override;
-
-virtual GLint GetUniformLocation(GLuint program, const char* name) override;
-
-virtual void GetVertexAttribPointerv(GLuint index,
-                                     GLenum pname,
-                                     void** pointer) override;
-
-virtual void Hint(GLenum target, GLenum mode) override;
-
-virtual GLboolean IsBuffer(GLuint buffer) override;
-
-virtual GLboolean IsEnabled(GLenum cap) override;
-
-virtual GLboolean IsFramebuffer(GLuint framebuffer) override;
-
-virtual GLboolean IsProgram(GLuint program) override;
-
-virtual GLboolean IsRenderbuffer(GLuint renderbuffer) override;
-
-virtual GLboolean IsShader(GLuint shader) override;
-
-virtual GLboolean IsTexture(GLuint texture) override;
-
-virtual void LineWidth(GLfloat width) override;
-
-virtual void LinkProgram(GLuint program) override;
-
-virtual void PixelStorei(GLenum pname, GLint param) override;
-
-virtual void PolygonOffset(GLfloat factor, GLfloat units) override;
-
-virtual void ReadPixels(GLint x,
-                        GLint y,
-                        GLsizei width,
-                        GLsizei height,
-                        GLenum format,
-                        GLenum type,
-                        void* pixels) override;
-
-virtual void ReleaseShaderCompiler() override;
-
-virtual void RenderbufferStorage(GLenum target,
-                                 GLenum internalformat,
-                                 GLsizei width,
-                                 GLsizei height) override;
-
-virtual void SampleCoverage(GLclampf value, GLboolean invert) override;
-
-virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
-
-virtual void ShaderBinary(GLsizei n,
-                          const GLuint* shaders,
-                          GLenum binaryformat,
-                          const void* binary,
-                          GLsizei length) override;
-
-virtual void ShaderSource(GLuint shader,
-                          GLsizei count,
-                          const GLchar* const* str,
-                          const GLint* length) override;
-
-virtual void ShallowFinishCHROMIUM() override;
-
-virtual void ShallowFlushCHROMIUM() override;
-
-virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) override;
-
-virtual void StencilFuncSeparate(GLenum face,
-                                 GLenum func,
-                                 GLint ref,
-                                 GLuint mask) override;
-
-virtual void StencilMask(GLuint mask) override;
-
-virtual void StencilMaskSeparate(GLenum face, GLuint mask) override;
-
-virtual void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) override;
-
-virtual void StencilOpSeparate(GLenum face,
-                               GLenum fail,
-                               GLenum zfail,
-                               GLenum zpass) override;
-
-virtual void TexImage2D(GLenum target,
-                        GLint level,
-                        GLint internalformat,
-                        GLsizei width,
-                        GLsizei height,
-                        GLint border,
-                        GLenum format,
-                        GLenum type,
-                        const void* pixels) override;
-
-virtual void TexParameterf(GLenum target, GLenum pname, GLfloat param) override;
-
-virtual void TexParameterfv(GLenum target,
-                            GLenum pname,
-                            const GLfloat* params) override;
-
-virtual void TexParameteri(GLenum target, GLenum pname, GLint param) override;
-
-virtual void TexParameteriv(GLenum target,
-                            GLenum pname,
-                            const GLint* params) override;
-
-virtual void TexSubImage2D(GLenum target,
-                           GLint level,
-                           GLint xoffset,
-                           GLint yoffset,
+GLuint CreateImageCHROMIUM(ClientBuffer buffer,
                            GLsizei width,
                            GLsizei height,
-                           GLenum format,
-                           GLenum type,
-                           const void* pixels) override;
+                           GLenum internalformat) override;
 
-virtual void Uniform1f(GLint location, GLfloat x) override;
+void DestroyImageCHROMIUM(GLuint image_id) override;
 
-virtual void Uniform1fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
+GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width,
+                                          GLsizei height,
+                                          GLenum internalformat,
+                                          GLenum usage) override;
 
-virtual void Uniform1i(GLint location, GLint x) override;
-
-virtual void Uniform1iv(GLint location, GLsizei count, const GLint* v) override;
-
-virtual void Uniform2f(GLint location, GLfloat x, GLfloat y) override;
-
-virtual void Uniform2fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-
-virtual void Uniform2i(GLint location, GLint x, GLint y) override;
-
-virtual void Uniform2iv(GLint location, GLsizei count, const GLint* v) override;
-
-virtual void Uniform3f(GLint location,
-                       GLfloat x,
-                       GLfloat y,
-                       GLfloat z) override;
-
-virtual void Uniform3fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-
-virtual void Uniform3i(GLint location, GLint x, GLint y, GLint z) override;
-
-virtual void Uniform3iv(GLint location, GLsizei count, const GLint* v) override;
-
-virtual void Uniform4f(GLint location,
-                       GLfloat x,
-                       GLfloat y,
-                       GLfloat z,
-                       GLfloat w) override;
-
-virtual void Uniform4fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-
-virtual void Uniform4i(GLint location,
-                       GLint x,
-                       GLint y,
-                       GLint z,
-                       GLint w) override;
-
-virtual void Uniform4iv(GLint location, GLsizei count, const GLint* v) override;
-
-virtual void UniformMatrix2fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-
-virtual void UniformMatrix3fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-
-virtual void UniformMatrix4fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-
-virtual void UseProgram(GLuint program) override;
-
-virtual void ValidateProgram(GLuint program) override;
-
-virtual void VertexAttrib1f(GLuint indx, GLfloat x) override;
-
-virtual void VertexAttrib1fv(GLuint indx, const GLfloat* values) override;
-
-virtual void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) override;
-
-virtual void VertexAttrib2fv(GLuint indx, const GLfloat* values) override;
-
-virtual void VertexAttrib3f(GLuint indx,
-                            GLfloat x,
-                            GLfloat y,
-                            GLfloat z) override;
-
-virtual void VertexAttrib3fv(GLuint indx, const GLfloat* values) override;
-
-virtual void VertexAttrib4f(GLuint indx,
-                            GLfloat x,
-                            GLfloat y,
-                            GLfloat z,
-                            GLfloat w) override;
-
-virtual void VertexAttrib4fv(GLuint indx, const GLfloat* values) override;
-
-virtual void VertexAttribPointer(GLuint indx,
-                                 GLint size,
-                                 GLenum type,
-                                 GLboolean normalized,
-                                 GLsizei stride,
-                                 const void* ptr) override;
-
-virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override;
-
-virtual void BlitFramebufferCHROMIUM(GLint srcX0,
-                                     GLint srcY0,
-                                     GLint srcX1,
-                                     GLint srcY1,
-                                     GLint dstX0,
-                                     GLint dstY0,
-                                     GLint dstX1,
-                                     GLint dstY1,
-                                     GLbitfield mask,
-                                     GLenum filter) override;
-
-virtual void RenderbufferStorageMultisampleCHROMIUM(GLenum target,
-                                                    GLsizei samples,
-                                                    GLenum internalformat,
-                                                    GLsizei width,
-                                                    GLsizei height) override;
-
-virtual void RenderbufferStorageMultisampleEXT(GLenum target,
-                                               GLsizei samples,
-                                               GLenum internalformat,
-                                               GLsizei width,
-                                               GLsizei height) override;
-
-virtual void FramebufferTexture2DMultisampleEXT(GLenum target,
-                                                GLenum attachment,
-                                                GLenum textarget,
-                                                GLuint texture,
-                                                GLint level,
-                                                GLsizei samples) override;
-
-virtual void TexStorage2DEXT(GLenum target,
-                             GLsizei levels,
-                             GLenum internalFormat,
-                             GLsizei width,
-                             GLsizei height) override;
-
-virtual void GenQueriesEXT(GLsizei n, GLuint* queries) override;
-
-virtual void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
-
-virtual GLboolean IsQueryEXT(GLuint id) override;
-
-virtual void BeginQueryEXT(GLenum target, GLuint id) override;
-
-virtual void EndQueryEXT(GLenum target) override;
-
-virtual void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
-
-virtual void GetQueryObjectuivEXT(GLuint id,
-                                  GLenum pname,
-                                  GLuint* params) override;
-
-virtual void InsertEventMarkerEXT(GLsizei length,
-                                  const GLchar* marker) override;
-
-virtual void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) override;
-
-virtual void PopGroupMarkerEXT() override;
-
-virtual void GenVertexArraysOES(GLsizei n, GLuint* arrays) override;
-
-virtual void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) override;
-
-virtual GLboolean IsVertexArrayOES(GLuint array) override;
-
-virtual void BindVertexArrayOES(GLuint array) override;
-
-virtual void SwapBuffers() override;
-
-virtual GLuint GetMaxValueInBufferCHROMIUM(GLuint buffer_id,
-                                           GLsizei count,
-                                           GLenum type,
-                                           GLuint offset) override;
-
-virtual GLboolean EnableFeatureCHROMIUM(const char* feature) override;
-
-virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) override;
-
-virtual GLboolean UnmapBufferCHROMIUM(GLuint target) override;
-
-virtual void* MapBufferSubDataCHROMIUM(GLuint target,
-                                       GLintptr offset,
-                                       GLsizeiptr size,
-                                       GLenum access) override;
-
-virtual void UnmapBufferSubDataCHROMIUM(const void* mem) override;
-
-virtual void* MapTexSubImage2DCHROMIUM(GLenum target,
-                                       GLint level,
-                                       GLint xoffset,
-                                       GLint yoffset,
-                                       GLsizei width,
-                                       GLsizei height,
-                                       GLenum format,
-                                       GLenum type,
-                                       GLenum access) override;
-
-virtual void UnmapTexSubImage2DCHROMIUM(const void* mem) override;
-
-virtual void ResizeCHROMIUM(GLuint width,
-                            GLuint height,
-                            GLfloat scale_factor) override;
-
-virtual const GLchar* GetRequestableExtensionsCHROMIUM() override;
-
-virtual void RequestExtensionCHROMIUM(const char* extension) override;
-
-virtual void RateLimitOffscreenContextCHROMIUM() override;
-
-virtual void GetMultipleIntegervCHROMIUM(const GLenum* pnames,
-                                         GLuint count,
-                                         GLint* results,
-                                         GLsizeiptr size) override;
-
-virtual void GetProgramInfoCHROMIUM(GLuint program,
+void GetTranslatedShaderSourceANGLE(GLuint shader,
                                     GLsizei bufsize,
-                                    GLsizei* size,
-                                    void* info) override;
+                                    GLsizei* length,
+                                    char* source) override;
 
-virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) override;
+void PostSubBufferCHROMIUM(GLint x,
+                           GLint y,
+                           GLint width,
+                           GLint height) override;
 
-virtual GLuint CreateImageCHROMIUM(ClientBuffer buffer,
-                                   GLsizei width,
-                                   GLsizei height,
-                                   GLenum internalformat) override;
+void TexImageIOSurface2DCHROMIUM(GLenum target,
+                                 GLsizei width,
+                                 GLsizei height,
+                                 GLuint ioSurfaceId,
+                                 GLuint plane) override;
 
-virtual void DestroyImageCHROMIUM(GLuint image_id) override;
+void CopyTextureCHROMIUM(GLenum target,
+                         GLenum source_id,
+                         GLenum dest_id,
+                         GLint level,
+                         GLint internalformat,
+                         GLenum dest_type) override;
 
-virtual GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width,
-                                                  GLsizei height,
-                                                  GLenum internalformat,
-                                                  GLenum usage) override;
+void DrawArraysInstancedANGLE(GLenum mode,
+                              GLint first,
+                              GLsizei count,
+                              GLsizei primcount) override;
 
-virtual void GetTranslatedShaderSourceANGLE(GLuint shader,
-                                            GLsizei bufsize,
-                                            GLsizei* length,
-                                            char* source) override;
+void DrawElementsInstancedANGLE(GLenum mode,
+                                GLsizei count,
+                                GLenum type,
+                                const void* indices,
+                                GLsizei primcount) override;
 
-virtual void PostSubBufferCHROMIUM(GLint x,
-                                   GLint y,
-                                   GLint width,
-                                   GLint height) override;
+void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) override;
 
-virtual void TexImageIOSurface2DCHROMIUM(GLenum target,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLuint ioSurfaceId,
-                                         GLuint plane) override;
+void GenMailboxCHROMIUM(GLbyte* mailbox) override;
 
-virtual void CopyTextureCHROMIUM(GLenum target,
-                                 GLenum source_id,
-                                 GLenum dest_id,
-                                 GLint level,
-                                 GLint internalformat,
-                                 GLenum dest_type) override;
+void ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) override;
 
-virtual void DrawArraysInstancedANGLE(GLenum mode,
-                                      GLint first,
-                                      GLsizei count,
-                                      GLsizei primcount) override;
+void ProduceTextureDirectCHROMIUM(GLuint texture,
+                                  GLenum target,
+                                  const GLbyte* mailbox) override;
 
-virtual void DrawElementsInstancedANGLE(GLenum mode,
-                                        GLsizei count,
-                                        GLenum type,
-                                        const void* indices,
-                                        GLsizei primcount) override;
+void ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) override;
 
-virtual void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) override;
+GLuint CreateAndConsumeTextureCHROMIUM(GLenum target,
+                                       const GLbyte* mailbox) override;
 
-virtual void GenMailboxCHROMIUM(GLbyte* mailbox) override;
+void BindUniformLocationCHROMIUM(GLuint program,
+                                 GLint location,
+                                 const char* name) override;
 
-virtual void ProduceTextureCHROMIUM(GLenum target,
-                                    const GLbyte* mailbox) override;
+void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
 
-virtual void ProduceTextureDirectCHROMIUM(GLuint texture,
-                                          GLenum target,
-                                          const GLbyte* mailbox) override;
+void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
 
-virtual void ConsumeTextureCHROMIUM(GLenum target,
-                                    const GLbyte* mailbox) override;
+void TraceBeginCHROMIUM(const char* name) override;
 
-virtual GLuint CreateAndConsumeTextureCHROMIUM(GLenum target,
-                                               const GLbyte* mailbox) override;
+void TraceEndCHROMIUM() override;
 
-virtual void BindUniformLocationCHROMIUM(GLuint program,
-                                         GLint location,
-                                         const char* name) override;
+void AsyncTexSubImage2DCHROMIUM(GLenum target,
+                                GLint level,
+                                GLint xoffset,
+                                GLint yoffset,
+                                GLsizei width,
+                                GLsizei height,
+                                GLenum format,
+                                GLenum type,
+                                const void* data) override;
 
-virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+void AsyncTexImage2DCHROMIUM(GLenum target,
+                             GLint level,
+                             GLenum internalformat,
+                             GLsizei width,
+                             GLsizei height,
+                             GLint border,
+                             GLenum format,
+                             GLenum type,
+                             const void* pixels) override;
 
-virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+void WaitAsyncTexImage2DCHROMIUM(GLenum target) override;
 
-virtual void TraceBeginCHROMIUM(const char* name) override;
+void WaitAllAsyncTexImage2DCHROMIUM() override;
 
-virtual void TraceEndCHROMIUM() override;
+void DiscardFramebufferEXT(GLenum target,
+                           GLsizei count,
+                           const GLenum* attachments) override;
 
-virtual void AsyncTexSubImage2DCHROMIUM(GLenum target,
-                                        GLint level,
-                                        GLint xoffset,
-                                        GLint yoffset,
-                                        GLsizei width,
-                                        GLsizei height,
-                                        GLenum format,
-                                        GLenum type,
-                                        const void* data) override;
+void LoseContextCHROMIUM(GLenum current, GLenum other) override;
 
-virtual void AsyncTexImage2DCHROMIUM(GLenum target,
-                                     GLint level,
-                                     GLenum internalformat,
-                                     GLsizei width,
-                                     GLsizei height,
-                                     GLint border,
-                                     GLenum format,
-                                     GLenum type,
-                                     const void* pixels) override;
+GLuint InsertSyncPointCHROMIUM() override;
 
-virtual void WaitAsyncTexImage2DCHROMIUM(GLenum target) override;
+void WaitSyncPointCHROMIUM(GLuint sync_point) override;
 
-virtual void WaitAllAsyncTexImage2DCHROMIUM() override;
+void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
 
-virtual void DiscardFramebufferEXT(GLenum target,
-                                   GLsizei count,
-                                   const GLenum* attachments) override;
+void DiscardBackbufferCHROMIUM() override;
 
-virtual void LoseContextCHROMIUM(GLenum current, GLenum other) override;
+void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
+                                  GLenum plane_transform,
+                                  GLuint overlay_texture_id,
+                                  GLint bounds_x,
+                                  GLint bounds_y,
+                                  GLint bounds_width,
+                                  GLint bounds_height,
+                                  GLfloat uv_x,
+                                  GLfloat uv_y,
+                                  GLfloat uv_width,
+                                  GLfloat uv_height) override;
 
-virtual GLuint InsertSyncPointCHROMIUM() override;
+void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override;
 
-virtual void WaitSyncPointCHROMIUM(GLuint sync_point) override;
+void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override;
 
-virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
-
-virtual void DiscardBackbufferCHROMIUM() override;
-
-virtual void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
-                                          GLenum plane_transform,
-                                          GLuint overlay_texture_id,
-                                          GLint bounds_x,
-                                          GLint bounds_y,
-                                          GLint bounds_width,
-                                          GLint bounds_height,
-                                          GLfloat uv_x,
-                                          GLfloat uv_y,
-                                          GLfloat uv_width,
-                                          GLfloat uv_height) override;
-
-virtual void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override;
-
-virtual void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override;
+virtual void BlendBarrierKHR() override;
 
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 50d7f821..32b13476 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -2162,4 +2162,12 @@
   CheckGLError();
 }
 
+void GLES2Implementation::BlendBarrierKHR() {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendBarrierKHR("
+                     << ")");
+  helper_->BlendBarrierKHR();
+  CheckGLError();
+}
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index b4e2667..7b3ec2db 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -114,25 +114,23 @@
     }
   }
 
-  virtual ~MockTransferBuffer() { }
+  ~MockTransferBuffer() override {}
 
-  virtual bool Initialize(
-      unsigned int starting_buffer_size,
-      unsigned int result_size,
-      unsigned int /* min_buffer_size */,
-      unsigned int /* max_buffer_size */,
-      unsigned int alignment,
-      unsigned int size_to_flush) override;
-  virtual int GetShmId() override;
-  virtual void* GetResultBuffer() override;
-  virtual int GetResultOffset() override;
-  virtual void Free() override;
-  virtual bool HaveBuffer() const override;
-  virtual void* AllocUpTo(
-      unsigned int size, unsigned int* size_allocated) override;
-  virtual void* Alloc(unsigned int size) override;
-  virtual RingBuffer::Offset GetOffset(void* pointer) const override;
-  virtual void FreePendingToken(void* p, unsigned int /* token */) override;
+  bool Initialize(unsigned int starting_buffer_size,
+                  unsigned int result_size,
+                  unsigned int /* min_buffer_size */,
+                  unsigned int /* max_buffer_size */,
+                  unsigned int alignment,
+                  unsigned int size_to_flush) override;
+  int GetShmId() override;
+  void* GetResultBuffer() override;
+  int GetResultOffset() override;
+  void Free() override;
+  bool HaveBuffer() const override;
+  void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
+  void* Alloc(unsigned int size) override;
+  RingBuffer::Offset GetOffset(void* pointer) const override;
+  void FreePendingToken(void* p, unsigned int /* token */) override;
 
   size_t MaxTransferBufferSize() {
     return size_ - result_size_;
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index 595bde1e..d840804 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -495,4 +495,5 @@
                                           GLfloat uv_height) = 0;
 virtual void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) = 0;
 virtual void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) = 0;
+virtual void BlendBarrierKHR() = 0;
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_stub.h b/gpu/command_buffer/client/gles2_interface_stub.h
index cf3fb41d..589a79c 100644
--- a/gpu/command_buffer/client/gles2_interface_stub.h
+++ b/gpu/command_buffer/client/gles2_interface_stub.h
@@ -14,7 +14,7 @@
 class GLES2InterfaceStub : public GLES2Interface {
  public:
   GLES2InterfaceStub();
-  virtual ~GLES2InterfaceStub();
+  ~GLES2InterfaceStub() override;
 
   // Include the auto-generated part of this class. We split this because
   // it means we can easily edit the non-auto generated parts right here in
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index b021b56..687ff48 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -12,520 +12,479 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_
 #define GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_
 
-virtual void ActiveTexture(GLenum texture) override;
-virtual void AttachShader(GLuint program, GLuint shader) override;
-virtual void BindAttribLocation(GLuint program,
-                                GLuint index,
-                                const char* name) override;
-virtual void BindBuffer(GLenum target, GLuint buffer) override;
-virtual void BindFramebuffer(GLenum target, GLuint framebuffer) override;
-virtual void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
-virtual void BindTexture(GLenum target, GLuint texture) override;
-virtual void BlendColor(GLclampf red,
-                        GLclampf green,
-                        GLclampf blue,
-                        GLclampf alpha) override;
-virtual void BlendEquation(GLenum mode) override;
-virtual void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) override;
-virtual void BlendFunc(GLenum sfactor, GLenum dfactor) override;
-virtual void BlendFuncSeparate(GLenum srcRGB,
-                               GLenum dstRGB,
-                               GLenum srcAlpha,
-                               GLenum dstAlpha) override;
-virtual void BufferData(GLenum target,
-                        GLsizeiptr size,
-                        const void* data,
-                        GLenum usage) override;
-virtual void BufferSubData(GLenum target,
-                           GLintptr offset,
-                           GLsizeiptr size,
-                           const void* data) override;
-virtual GLenum CheckFramebufferStatus(GLenum target) override;
-virtual void Clear(GLbitfield mask) override;
-virtual void ClearColor(GLclampf red,
-                        GLclampf green,
-                        GLclampf blue,
-                        GLclampf alpha) override;
-virtual void ClearDepthf(GLclampf depth) override;
-virtual void ClearStencil(GLint s) override;
-virtual void ColorMask(GLboolean red,
-                       GLboolean green,
-                       GLboolean blue,
-                       GLboolean alpha) override;
-virtual void CompileShader(GLuint shader) override;
-virtual void CompressedTexImage2D(GLenum target,
-                                  GLint level,
-                                  GLenum internalformat,
-                                  GLsizei width,
-                                  GLsizei height,
-                                  GLint border,
-                                  GLsizei imageSize,
-                                  const void* data) override;
-virtual void CompressedTexSubImage2D(GLenum target,
-                                     GLint level,
-                                     GLint xoffset,
-                                     GLint yoffset,
-                                     GLsizei width,
-                                     GLsizei height,
-                                     GLenum format,
-                                     GLsizei imageSize,
-                                     const void* data) override;
-virtual void CopyTexImage2D(GLenum target,
-                            GLint level,
-                            GLenum internalformat,
-                            GLint x,
-                            GLint y,
-                            GLsizei width,
-                            GLsizei height,
-                            GLint border) override;
-virtual void CopyTexSubImage2D(GLenum target,
+void ActiveTexture(GLenum texture) override;
+void AttachShader(GLuint program, GLuint shader) override;
+void BindAttribLocation(GLuint program,
+                        GLuint index,
+                        const char* name) override;
+void BindBuffer(GLenum target, GLuint buffer) override;
+void BindFramebuffer(GLenum target, GLuint framebuffer) override;
+void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
+void BindTexture(GLenum target, GLuint texture) override;
+void BlendColor(GLclampf red,
+                GLclampf green,
+                GLclampf blue,
+                GLclampf alpha) override;
+void BlendEquation(GLenum mode) override;
+void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) override;
+void BlendFunc(GLenum sfactor, GLenum dfactor) override;
+void BlendFuncSeparate(GLenum srcRGB,
+                       GLenum dstRGB,
+                       GLenum srcAlpha,
+                       GLenum dstAlpha) override;
+void BufferData(GLenum target,
+                GLsizeiptr size,
+                const void* data,
+                GLenum usage) override;
+void BufferSubData(GLenum target,
+                   GLintptr offset,
+                   GLsizeiptr size,
+                   const void* data) override;
+GLenum CheckFramebufferStatus(GLenum target) override;
+void Clear(GLbitfield mask) override;
+void ClearColor(GLclampf red,
+                GLclampf green,
+                GLclampf blue,
+                GLclampf alpha) override;
+void ClearDepthf(GLclampf depth) override;
+void ClearStencil(GLint s) override;
+void ColorMask(GLboolean red,
+               GLboolean green,
+               GLboolean blue,
+               GLboolean alpha) override;
+void CompileShader(GLuint shader) override;
+void CompressedTexImage2D(GLenum target,
+                          GLint level,
+                          GLenum internalformat,
+                          GLsizei width,
+                          GLsizei height,
+                          GLint border,
+                          GLsizei imageSize,
+                          const void* data) override;
+void CompressedTexSubImage2D(GLenum target,
+                             GLint level,
+                             GLint xoffset,
+                             GLint yoffset,
+                             GLsizei width,
+                             GLsizei height,
+                             GLenum format,
+                             GLsizei imageSize,
+                             const void* data) override;
+void CopyTexImage2D(GLenum target,
+                    GLint level,
+                    GLenum internalformat,
+                    GLint x,
+                    GLint y,
+                    GLsizei width,
+                    GLsizei height,
+                    GLint border) override;
+void CopyTexSubImage2D(GLenum target,
+                       GLint level,
+                       GLint xoffset,
+                       GLint yoffset,
+                       GLint x,
+                       GLint y,
+                       GLsizei width,
+                       GLsizei height) override;
+GLuint CreateProgram() override;
+GLuint CreateShader(GLenum type) override;
+void CullFace(GLenum mode) override;
+void DeleteBuffers(GLsizei n, const GLuint* buffers) override;
+void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
+void DeleteProgram(GLuint program) override;
+void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override;
+void DeleteShader(GLuint shader) override;
+void DeleteTextures(GLsizei n, const GLuint* textures) override;
+void DepthFunc(GLenum func) override;
+void DepthMask(GLboolean flag) override;
+void DepthRangef(GLclampf zNear, GLclampf zFar) override;
+void DetachShader(GLuint program, GLuint shader) override;
+void Disable(GLenum cap) override;
+void DisableVertexAttribArray(GLuint index) override;
+void DrawArrays(GLenum mode, GLint first, GLsizei count) override;
+void DrawElements(GLenum mode,
+                  GLsizei count,
+                  GLenum type,
+                  const void* indices) override;
+void Enable(GLenum cap) override;
+void EnableVertexAttribArray(GLuint index) override;
+void Finish() override;
+void Flush() override;
+void FramebufferRenderbuffer(GLenum target,
+                             GLenum attachment,
+                             GLenum renderbuffertarget,
+                             GLuint renderbuffer) override;
+void FramebufferTexture2D(GLenum target,
+                          GLenum attachment,
+                          GLenum textarget,
+                          GLuint texture,
+                          GLint level) override;
+void FrontFace(GLenum mode) override;
+void GenBuffers(GLsizei n, GLuint* buffers) override;
+void GenerateMipmap(GLenum target) override;
+void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
+void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
+void GenTextures(GLsizei n, GLuint* textures) override;
+void GetActiveAttrib(GLuint program,
+                     GLuint index,
+                     GLsizei bufsize,
+                     GLsizei* length,
+                     GLint* size,
+                     GLenum* type,
+                     char* name) override;
+void GetActiveUniform(GLuint program,
+                      GLuint index,
+                      GLsizei bufsize,
+                      GLsizei* length,
+                      GLint* size,
+                      GLenum* type,
+                      char* name) override;
+void GetAttachedShaders(GLuint program,
+                        GLsizei maxcount,
+                        GLsizei* count,
+                        GLuint* shaders) override;
+GLint GetAttribLocation(GLuint program, const char* name) override;
+void GetBooleanv(GLenum pname, GLboolean* params) override;
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) override;
+GLenum GetError() override;
+void GetFloatv(GLenum pname, GLfloat* params) override;
+void GetFramebufferAttachmentParameteriv(GLenum target,
+                                         GLenum attachment,
+                                         GLenum pname,
+                                         GLint* params) override;
+void GetIntegerv(GLenum pname, GLint* params) override;
+void GetProgramiv(GLuint program, GLenum pname, GLint* params) override;
+void GetProgramInfoLog(GLuint program,
+                       GLsizei bufsize,
+                       GLsizei* length,
+                       char* infolog) override;
+void GetRenderbufferParameteriv(GLenum target,
+                                GLenum pname,
+                                GLint* params) override;
+void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
+void GetShaderInfoLog(GLuint shader,
+                      GLsizei bufsize,
+                      GLsizei* length,
+                      char* infolog) override;
+void GetShaderPrecisionFormat(GLenum shadertype,
+                              GLenum precisiontype,
+                              GLint* range,
+                              GLint* precision) override;
+void GetShaderSource(GLuint shader,
+                     GLsizei bufsize,
+                     GLsizei* length,
+                     char* source) override;
+const GLubyte* GetString(GLenum name) override;
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override;
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override;
+void GetUniformfv(GLuint program, GLint location, GLfloat* params) override;
+void GetUniformiv(GLuint program, GLint location, GLint* params) override;
+GLint GetUniformLocation(GLuint program, const char* name) override;
+void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) override;
+void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) override;
+void GetVertexAttribPointerv(GLuint index,
+                             GLenum pname,
+                             void** pointer) override;
+void Hint(GLenum target, GLenum mode) override;
+GLboolean IsBuffer(GLuint buffer) override;
+GLboolean IsEnabled(GLenum cap) override;
+GLboolean IsFramebuffer(GLuint framebuffer) override;
+GLboolean IsProgram(GLuint program) override;
+GLboolean IsRenderbuffer(GLuint renderbuffer) override;
+GLboolean IsShader(GLuint shader) override;
+GLboolean IsTexture(GLuint texture) override;
+void LineWidth(GLfloat width) override;
+void LinkProgram(GLuint program) override;
+void PixelStorei(GLenum pname, GLint param) override;
+void PolygonOffset(GLfloat factor, GLfloat units) override;
+void ReadPixels(GLint x,
+                GLint y,
+                GLsizei width,
+                GLsizei height,
+                GLenum format,
+                GLenum type,
+                void* pixels) override;
+void ReleaseShaderCompiler() override;
+void RenderbufferStorage(GLenum target,
+                         GLenum internalformat,
+                         GLsizei width,
+                         GLsizei height) override;
+void SampleCoverage(GLclampf value, GLboolean invert) override;
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
+void ShaderBinary(GLsizei n,
+                  const GLuint* shaders,
+                  GLenum binaryformat,
+                  const void* binary,
+                  GLsizei length) override;
+void ShaderSource(GLuint shader,
+                  GLsizei count,
+                  const GLchar* const* str,
+                  const GLint* length) override;
+void ShallowFinishCHROMIUM() override;
+void ShallowFlushCHROMIUM() override;
+void StencilFunc(GLenum func, GLint ref, GLuint mask) override;
+void StencilFuncSeparate(GLenum face,
+                         GLenum func,
+                         GLint ref,
+                         GLuint mask) override;
+void StencilMask(GLuint mask) override;
+void StencilMaskSeparate(GLenum face, GLuint mask) override;
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) override;
+void StencilOpSeparate(GLenum face,
+                       GLenum fail,
+                       GLenum zfail,
+                       GLenum zpass) override;
+void TexImage2D(GLenum target,
+                GLint level,
+                GLint internalformat,
+                GLsizei width,
+                GLsizei height,
+                GLint border,
+                GLenum format,
+                GLenum type,
+                const void* pixels) override;
+void TexParameterf(GLenum target, GLenum pname, GLfloat param) override;
+void TexParameterfv(GLenum target,
+                    GLenum pname,
+                    const GLfloat* params) override;
+void TexParameteri(GLenum target, GLenum pname, GLint param) override;
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override;
+void TexSubImage2D(GLenum target,
+                   GLint level,
+                   GLint xoffset,
+                   GLint yoffset,
+                   GLsizei width,
+                   GLsizei height,
+                   GLenum format,
+                   GLenum type,
+                   const void* pixels) override;
+void Uniform1f(GLint location, GLfloat x) override;
+void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) override;
+void Uniform1i(GLint location, GLint x) override;
+void Uniform1iv(GLint location, GLsizei count, const GLint* v) override;
+void Uniform2f(GLint location, GLfloat x, GLfloat y) override;
+void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override;
+void Uniform2i(GLint location, GLint x, GLint y) override;
+void Uniform2iv(GLint location, GLsizei count, const GLint* v) override;
+void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override;
+void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override;
+void Uniform3i(GLint location, GLint x, GLint y, GLint z) override;
+void Uniform3iv(GLint location, GLsizei count, const GLint* v) override;
+void Uniform4f(GLint location,
+               GLfloat x,
+               GLfloat y,
+               GLfloat z,
+               GLfloat w) override;
+void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) override;
+void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override;
+void Uniform4iv(GLint location, GLsizei count, const GLint* v) override;
+void UniformMatrix2fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+void UniformMatrix3fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+void UniformMatrix4fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+void UseProgram(GLuint program) override;
+void ValidateProgram(GLuint program) override;
+void VertexAttrib1f(GLuint indx, GLfloat x) override;
+void VertexAttrib1fv(GLuint indx, const GLfloat* values) override;
+void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) override;
+void VertexAttrib2fv(GLuint indx, const GLfloat* values) override;
+void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) override;
+void VertexAttrib3fv(GLuint indx, const GLfloat* values) override;
+void VertexAttrib4f(GLuint indx,
+                    GLfloat x,
+                    GLfloat y,
+                    GLfloat z,
+                    GLfloat w) override;
+void VertexAttrib4fv(GLuint indx, const GLfloat* values) override;
+void VertexAttribPointer(GLuint indx,
+                         GLint size,
+                         GLenum type,
+                         GLboolean normalized,
+                         GLsizei stride,
+                         const void* ptr) override;
+void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override;
+void BlitFramebufferCHROMIUM(GLint srcX0,
+                             GLint srcY0,
+                             GLint srcX1,
+                             GLint srcY1,
+                             GLint dstX0,
+                             GLint dstY0,
+                             GLint dstX1,
+                             GLint dstY1,
+                             GLbitfield mask,
+                             GLenum filter) override;
+void RenderbufferStorageMultisampleCHROMIUM(GLenum target,
+                                            GLsizei samples,
+                                            GLenum internalformat,
+                                            GLsizei width,
+                                            GLsizei height) override;
+void RenderbufferStorageMultisampleEXT(GLenum target,
+                                       GLsizei samples,
+                                       GLenum internalformat,
+                                       GLsizei width,
+                                       GLsizei height) override;
+void FramebufferTexture2DMultisampleEXT(GLenum target,
+                                        GLenum attachment,
+                                        GLenum textarget,
+                                        GLuint texture,
+                                        GLint level,
+                                        GLsizei samples) override;
+void TexStorage2DEXT(GLenum target,
+                     GLsizei levels,
+                     GLenum internalFormat,
+                     GLsizei width,
+                     GLsizei height) override;
+void GenQueriesEXT(GLsizei n, GLuint* queries) override;
+void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
+GLboolean IsQueryEXT(GLuint id) override;
+void BeginQueryEXT(GLenum target, GLuint id) override;
+void EndQueryEXT(GLenum target) override;
+void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
+void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override;
+void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) override;
+void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) override;
+void PopGroupMarkerEXT() override;
+void GenVertexArraysOES(GLsizei n, GLuint* arrays) override;
+void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) override;
+GLboolean IsVertexArrayOES(GLuint array) override;
+void BindVertexArrayOES(GLuint array) override;
+void SwapBuffers() override;
+GLuint GetMaxValueInBufferCHROMIUM(GLuint buffer_id,
+                                   GLsizei count,
+                                   GLenum type,
+                                   GLuint offset) override;
+GLboolean EnableFeatureCHROMIUM(const char* feature) override;
+void* MapBufferCHROMIUM(GLuint target, GLenum access) override;
+GLboolean UnmapBufferCHROMIUM(GLuint target) override;
+void* MapBufferSubDataCHROMIUM(GLuint target,
+                               GLintptr offset,
+                               GLsizeiptr size,
+                               GLenum access) override;
+void UnmapBufferSubDataCHROMIUM(const void* mem) override;
+void* MapTexSubImage2DCHROMIUM(GLenum target,
                                GLint level,
                                GLint xoffset,
                                GLint yoffset,
-                               GLint x,
-                               GLint y,
                                GLsizei width,
-                               GLsizei height) override;
-virtual GLuint CreateProgram() override;
-virtual GLuint CreateShader(GLenum type) override;
-virtual void CullFace(GLenum mode) override;
-virtual void DeleteBuffers(GLsizei n, const GLuint* buffers) override;
-virtual void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
-virtual void DeleteProgram(GLuint program) override;
-virtual void DeleteRenderbuffers(GLsizei n,
-                                 const GLuint* renderbuffers) override;
-virtual void DeleteShader(GLuint shader) override;
-virtual void DeleteTextures(GLsizei n, const GLuint* textures) override;
-virtual void DepthFunc(GLenum func) override;
-virtual void DepthMask(GLboolean flag) override;
-virtual void DepthRangef(GLclampf zNear, GLclampf zFar) override;
-virtual void DetachShader(GLuint program, GLuint shader) override;
-virtual void Disable(GLenum cap) override;
-virtual void DisableVertexAttribArray(GLuint index) override;
-virtual void DrawArrays(GLenum mode, GLint first, GLsizei count) override;
-virtual void DrawElements(GLenum mode,
-                          GLsizei count,
-                          GLenum type,
-                          const void* indices) override;
-virtual void Enable(GLenum cap) override;
-virtual void EnableVertexAttribArray(GLuint index) override;
-virtual void Finish() override;
-virtual void Flush() override;
-virtual void FramebufferRenderbuffer(GLenum target,
-                                     GLenum attachment,
-                                     GLenum renderbuffertarget,
-                                     GLuint renderbuffer) override;
-virtual void FramebufferTexture2D(GLenum target,
-                                  GLenum attachment,
-                                  GLenum textarget,
-                                  GLuint texture,
-                                  GLint level) override;
-virtual void FrontFace(GLenum mode) override;
-virtual void GenBuffers(GLsizei n, GLuint* buffers) override;
-virtual void GenerateMipmap(GLenum target) override;
-virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
-virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
-virtual void GenTextures(GLsizei n, GLuint* textures) override;
-virtual void GetActiveAttrib(GLuint program,
-                             GLuint index,
-                             GLsizei bufsize,
-                             GLsizei* length,
-                             GLint* size,
-                             GLenum* type,
-                             char* name) override;
-virtual void GetActiveUniform(GLuint program,
-                              GLuint index,
-                              GLsizei bufsize,
-                              GLsizei* length,
-                              GLint* size,
-                              GLenum* type,
-                              char* name) override;
-virtual void GetAttachedShaders(GLuint program,
-                                GLsizei maxcount,
-                                GLsizei* count,
-                                GLuint* shaders) override;
-virtual GLint GetAttribLocation(GLuint program, const char* name) override;
-virtual void GetBooleanv(GLenum pname, GLboolean* params) override;
-virtual void GetBufferParameteriv(GLenum target,
-                                  GLenum pname,
-                                  GLint* params) override;
-virtual GLenum GetError() override;
-virtual void GetFloatv(GLenum pname, GLfloat* params) override;
-virtual void GetFramebufferAttachmentParameteriv(GLenum target,
-                                                 GLenum attachment,
-                                                 GLenum pname,
-                                                 GLint* params) override;
-virtual void GetIntegerv(GLenum pname, GLint* params) override;
-virtual void GetProgramiv(GLuint program, GLenum pname, GLint* params) override;
-virtual void GetProgramInfoLog(GLuint program,
-                               GLsizei bufsize,
-                               GLsizei* length,
-                               char* infolog) override;
-virtual void GetRenderbufferParameteriv(GLenum target,
-                                        GLenum pname,
-                                        GLint* params) override;
-virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
-virtual void GetShaderInfoLog(GLuint shader,
-                              GLsizei bufsize,
-                              GLsizei* length,
-                              char* infolog) override;
-virtual void GetShaderPrecisionFormat(GLenum shadertype,
-                                      GLenum precisiontype,
-                                      GLint* range,
-                                      GLint* precision) override;
-virtual void GetShaderSource(GLuint shader,
-                             GLsizei bufsize,
-                             GLsizei* length,
-                             char* source) override;
-virtual const GLubyte* GetString(GLenum name) override;
-virtual void GetTexParameterfv(GLenum target,
-                               GLenum pname,
-                               GLfloat* params) override;
-virtual void GetTexParameteriv(GLenum target,
-                               GLenum pname,
-                               GLint* params) override;
-virtual void GetUniformfv(GLuint program,
-                          GLint location,
-                          GLfloat* params) override;
-virtual void GetUniformiv(GLuint program,
-                          GLint location,
-                          GLint* params) override;
-virtual GLint GetUniformLocation(GLuint program, const char* name) override;
-virtual void GetVertexAttribfv(GLuint index,
-                               GLenum pname,
-                               GLfloat* params) override;
-virtual void GetVertexAttribiv(GLuint index,
-                               GLenum pname,
-                               GLint* params) override;
-virtual void GetVertexAttribPointerv(GLuint index,
-                                     GLenum pname,
-                                     void** pointer) override;
-virtual void Hint(GLenum target, GLenum mode) override;
-virtual GLboolean IsBuffer(GLuint buffer) override;
-virtual GLboolean IsEnabled(GLenum cap) override;
-virtual GLboolean IsFramebuffer(GLuint framebuffer) override;
-virtual GLboolean IsProgram(GLuint program) override;
-virtual GLboolean IsRenderbuffer(GLuint renderbuffer) override;
-virtual GLboolean IsShader(GLuint shader) override;
-virtual GLboolean IsTexture(GLuint texture) override;
-virtual void LineWidth(GLfloat width) override;
-virtual void LinkProgram(GLuint program) override;
-virtual void PixelStorei(GLenum pname, GLint param) override;
-virtual void PolygonOffset(GLfloat factor, GLfloat units) override;
-virtual void ReadPixels(GLint x,
-                        GLint y,
-                        GLsizei width,
-                        GLsizei height,
-                        GLenum format,
-                        GLenum type,
-                        void* pixels) override;
-virtual void ReleaseShaderCompiler() override;
-virtual void RenderbufferStorage(GLenum target,
-                                 GLenum internalformat,
-                                 GLsizei width,
-                                 GLsizei height) override;
-virtual void SampleCoverage(GLclampf value, GLboolean invert) override;
-virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
-virtual void ShaderBinary(GLsizei n,
-                          const GLuint* shaders,
-                          GLenum binaryformat,
-                          const void* binary,
-                          GLsizei length) override;
-virtual void ShaderSource(GLuint shader,
-                          GLsizei count,
-                          const GLchar* const* str,
-                          const GLint* length) override;
-virtual void ShallowFinishCHROMIUM() override;
-virtual void ShallowFlushCHROMIUM() override;
-virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) override;
-virtual void StencilFuncSeparate(GLenum face,
-                                 GLenum func,
-                                 GLint ref,
-                                 GLuint mask) override;
-virtual void StencilMask(GLuint mask) override;
-virtual void StencilMaskSeparate(GLenum face, GLuint mask) override;
-virtual void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) override;
-virtual void StencilOpSeparate(GLenum face,
-                               GLenum fail,
-                               GLenum zfail,
-                               GLenum zpass) override;
-virtual void TexImage2D(GLenum target,
-                        GLint level,
-                        GLint internalformat,
-                        GLsizei width,
-                        GLsizei height,
-                        GLint border,
-                        GLenum format,
-                        GLenum type,
-                        const void* pixels) override;
-virtual void TexParameterf(GLenum target, GLenum pname, GLfloat param) override;
-virtual void TexParameterfv(GLenum target,
-                            GLenum pname,
-                            const GLfloat* params) override;
-virtual void TexParameteri(GLenum target, GLenum pname, GLint param) override;
-virtual void TexParameteriv(GLenum target,
-                            GLenum pname,
-                            const GLint* params) override;
-virtual void TexSubImage2D(GLenum target,
-                           GLint level,
-                           GLint xoffset,
-                           GLint yoffset,
+                               GLsizei height,
+                               GLenum format,
+                               GLenum type,
+                               GLenum access) override;
+void UnmapTexSubImage2DCHROMIUM(const void* mem) override;
+void ResizeCHROMIUM(GLuint width, GLuint height, GLfloat scale_factor) override;
+const GLchar* GetRequestableExtensionsCHROMIUM() override;
+void RequestExtensionCHROMIUM(const char* extension) override;
+void RateLimitOffscreenContextCHROMIUM() override;
+void GetMultipleIntegervCHROMIUM(const GLenum* pnames,
+                                 GLuint count,
+                                 GLint* results,
+                                 GLsizeiptr size) override;
+void GetProgramInfoCHROMIUM(GLuint program,
+                            GLsizei bufsize,
+                            GLsizei* size,
+                            void* info) override;
+GLuint CreateStreamTextureCHROMIUM(GLuint texture) override;
+GLuint CreateImageCHROMIUM(ClientBuffer buffer,
                            GLsizei width,
                            GLsizei height,
-                           GLenum format,
-                           GLenum type,
-                           const void* pixels) override;
-virtual void Uniform1f(GLint location, GLfloat x) override;
-virtual void Uniform1fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-virtual void Uniform1i(GLint location, GLint x) override;
-virtual void Uniform1iv(GLint location, GLsizei count, const GLint* v) override;
-virtual void Uniform2f(GLint location, GLfloat x, GLfloat y) override;
-virtual void Uniform2fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-virtual void Uniform2i(GLint location, GLint x, GLint y) override;
-virtual void Uniform2iv(GLint location, GLsizei count, const GLint* v) override;
-virtual void Uniform3f(GLint location,
-                       GLfloat x,
-                       GLfloat y,
-                       GLfloat z) override;
-virtual void Uniform3fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-virtual void Uniform3i(GLint location, GLint x, GLint y, GLint z) override;
-virtual void Uniform3iv(GLint location, GLsizei count, const GLint* v) override;
-virtual void Uniform4f(GLint location,
-                       GLfloat x,
-                       GLfloat y,
-                       GLfloat z,
-                       GLfloat w) override;
-virtual void Uniform4fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-virtual void Uniform4i(GLint location,
-                       GLint x,
-                       GLint y,
-                       GLint z,
-                       GLint w) override;
-virtual void Uniform4iv(GLint location, GLsizei count, const GLint* v) override;
-virtual void UniformMatrix2fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-virtual void UniformMatrix3fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-virtual void UniformMatrix4fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-virtual void UseProgram(GLuint program) override;
-virtual void ValidateProgram(GLuint program) override;
-virtual void VertexAttrib1f(GLuint indx, GLfloat x) override;
-virtual void VertexAttrib1fv(GLuint indx, const GLfloat* values) override;
-virtual void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) override;
-virtual void VertexAttrib2fv(GLuint indx, const GLfloat* values) override;
-virtual void VertexAttrib3f(GLuint indx,
-                            GLfloat x,
-                            GLfloat y,
-                            GLfloat z) override;
-virtual void VertexAttrib3fv(GLuint indx, const GLfloat* values) override;
-virtual void VertexAttrib4f(GLuint indx,
-                            GLfloat x,
-                            GLfloat y,
-                            GLfloat z,
-                            GLfloat w) override;
-virtual void VertexAttrib4fv(GLuint indx, const GLfloat* values) override;
-virtual void VertexAttribPointer(GLuint indx,
-                                 GLint size,
-                                 GLenum type,
-                                 GLboolean normalized,
-                                 GLsizei stride,
-                                 const void* ptr) override;
-virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override;
-virtual void BlitFramebufferCHROMIUM(GLint srcX0,
-                                     GLint srcY0,
-                                     GLint srcX1,
-                                     GLint srcY1,
-                                     GLint dstX0,
-                                     GLint dstY0,
-                                     GLint dstX1,
-                                     GLint dstY1,
-                                     GLbitfield mask,
-                                     GLenum filter) override;
-virtual void RenderbufferStorageMultisampleCHROMIUM(GLenum target,
-                                                    GLsizei samples,
-                                                    GLenum internalformat,
-                                                    GLsizei width,
-                                                    GLsizei height) override;
-virtual void RenderbufferStorageMultisampleEXT(GLenum target,
-                                               GLsizei samples,
-                                               GLenum internalformat,
-                                               GLsizei width,
-                                               GLsizei height) override;
-virtual void FramebufferTexture2DMultisampleEXT(GLenum target,
-                                                GLenum attachment,
-                                                GLenum textarget,
-                                                GLuint texture,
-                                                GLint level,
-                                                GLsizei samples) override;
-virtual void TexStorage2DEXT(GLenum target,
-                             GLsizei levels,
-                             GLenum internalFormat,
-                             GLsizei width,
-                             GLsizei height) override;
-virtual void GenQueriesEXT(GLsizei n, GLuint* queries) override;
-virtual void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
-virtual GLboolean IsQueryEXT(GLuint id) override;
-virtual void BeginQueryEXT(GLenum target, GLuint id) override;
-virtual void EndQueryEXT(GLenum target) override;
-virtual void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
-virtual void GetQueryObjectuivEXT(GLuint id,
-                                  GLenum pname,
-                                  GLuint* params) override;
-virtual void InsertEventMarkerEXT(GLsizei length,
-                                  const GLchar* marker) override;
-virtual void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) override;
-virtual void PopGroupMarkerEXT() override;
-virtual void GenVertexArraysOES(GLsizei n, GLuint* arrays) override;
-virtual void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) override;
-virtual GLboolean IsVertexArrayOES(GLuint array) override;
-virtual void BindVertexArrayOES(GLuint array) override;
-virtual void SwapBuffers() override;
-virtual GLuint GetMaxValueInBufferCHROMIUM(GLuint buffer_id,
-                                           GLsizei count,
-                                           GLenum type,
-                                           GLuint offset) override;
-virtual GLboolean EnableFeatureCHROMIUM(const char* feature) override;
-virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) override;
-virtual GLboolean UnmapBufferCHROMIUM(GLuint target) override;
-virtual void* MapBufferSubDataCHROMIUM(GLuint target,
-                                       GLintptr offset,
-                                       GLsizeiptr size,
-                                       GLenum access) override;
-virtual void UnmapBufferSubDataCHROMIUM(const void* mem) override;
-virtual void* MapTexSubImage2DCHROMIUM(GLenum target,
-                                       GLint level,
-                                       GLint xoffset,
-                                       GLint yoffset,
-                                       GLsizei width,
-                                       GLsizei height,
-                                       GLenum format,
-                                       GLenum type,
-                                       GLenum access) override;
-virtual void UnmapTexSubImage2DCHROMIUM(const void* mem) override;
-virtual void ResizeCHROMIUM(GLuint width,
-                            GLuint height,
-                            GLfloat scale_factor) override;
-virtual const GLchar* GetRequestableExtensionsCHROMIUM() override;
-virtual void RequestExtensionCHROMIUM(const char* extension) override;
-virtual void RateLimitOffscreenContextCHROMIUM() override;
-virtual void GetMultipleIntegervCHROMIUM(const GLenum* pnames,
-                                         GLuint count,
-                                         GLint* results,
-                                         GLsizeiptr size) override;
-virtual void GetProgramInfoCHROMIUM(GLuint program,
+                           GLenum internalformat) override;
+void DestroyImageCHROMIUM(GLuint image_id) override;
+GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width,
+                                          GLsizei height,
+                                          GLenum internalformat,
+                                          GLenum usage) override;
+void GetTranslatedShaderSourceANGLE(GLuint shader,
                                     GLsizei bufsize,
-                                    GLsizei* size,
-                                    void* info) override;
-virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) override;
-virtual GLuint CreateImageCHROMIUM(ClientBuffer buffer,
-                                   GLsizei width,
-                                   GLsizei height,
-                                   GLenum internalformat) override;
-virtual void DestroyImageCHROMIUM(GLuint image_id) override;
-virtual GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width,
-                                                  GLsizei height,
-                                                  GLenum internalformat,
-                                                  GLenum usage) override;
-virtual void GetTranslatedShaderSourceANGLE(GLuint shader,
-                                            GLsizei bufsize,
-                                            GLsizei* length,
-                                            char* source) override;
-virtual void PostSubBufferCHROMIUM(GLint x,
-                                   GLint y,
-                                   GLint width,
-                                   GLint height) override;
-virtual void TexImageIOSurface2DCHROMIUM(GLenum target,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLuint ioSurfaceId,
-                                         GLuint plane) override;
-virtual void CopyTextureCHROMIUM(GLenum target,
-                                 GLenum source_id,
-                                 GLenum dest_id,
-                                 GLint level,
-                                 GLint internalformat,
-                                 GLenum dest_type) override;
-virtual void DrawArraysInstancedANGLE(GLenum mode,
-                                      GLint first,
-                                      GLsizei count,
-                                      GLsizei primcount) override;
-virtual void DrawElementsInstancedANGLE(GLenum mode,
-                                        GLsizei count,
-                                        GLenum type,
-                                        const void* indices,
-                                        GLsizei primcount) override;
-virtual void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) override;
-virtual void GenMailboxCHROMIUM(GLbyte* mailbox) override;
-virtual void ProduceTextureCHROMIUM(GLenum target,
-                                    const GLbyte* mailbox) override;
-virtual void ProduceTextureDirectCHROMIUM(GLuint texture,
-                                          GLenum target,
-                                          const GLbyte* mailbox) override;
-virtual void ConsumeTextureCHROMIUM(GLenum target,
-                                    const GLbyte* mailbox) override;
-virtual GLuint CreateAndConsumeTextureCHROMIUM(GLenum target,
-                                               const GLbyte* mailbox) override;
-virtual void BindUniformLocationCHROMIUM(GLuint program,
-                                         GLint location,
-                                         const char* name) override;
-virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
-virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
-virtual void TraceBeginCHROMIUM(const char* name) override;
-virtual void TraceEndCHROMIUM() override;
-virtual void AsyncTexSubImage2DCHROMIUM(GLenum target,
-                                        GLint level,
-                                        GLint xoffset,
-                                        GLint yoffset,
-                                        GLsizei width,
-                                        GLsizei height,
-                                        GLenum format,
-                                        GLenum type,
-                                        const void* data) override;
-virtual void AsyncTexImage2DCHROMIUM(GLenum target,
-                                     GLint level,
-                                     GLenum internalformat,
-                                     GLsizei width,
-                                     GLsizei height,
-                                     GLint border,
-                                     GLenum format,
-                                     GLenum type,
-                                     const void* pixels) override;
-virtual void WaitAsyncTexImage2DCHROMIUM(GLenum target) override;
-virtual void WaitAllAsyncTexImage2DCHROMIUM() override;
-virtual void DiscardFramebufferEXT(GLenum target,
-                                   GLsizei count,
-                                   const GLenum* attachments) override;
-virtual void LoseContextCHROMIUM(GLenum current, GLenum other) override;
-virtual GLuint InsertSyncPointCHROMIUM() override;
-virtual void WaitSyncPointCHROMIUM(GLuint sync_point) override;
-virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
-virtual void DiscardBackbufferCHROMIUM() override;
-virtual void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
-                                          GLenum plane_transform,
-                                          GLuint overlay_texture_id,
-                                          GLint bounds_x,
-                                          GLint bounds_y,
-                                          GLint bounds_width,
-                                          GLint bounds_height,
-                                          GLfloat uv_x,
-                                          GLfloat uv_y,
-                                          GLfloat uv_width,
-                                          GLfloat uv_height) override;
-virtual void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override;
-virtual void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override;
+                                    GLsizei* length,
+                                    char* source) override;
+void PostSubBufferCHROMIUM(GLint x,
+                           GLint y,
+                           GLint width,
+                           GLint height) override;
+void TexImageIOSurface2DCHROMIUM(GLenum target,
+                                 GLsizei width,
+                                 GLsizei height,
+                                 GLuint ioSurfaceId,
+                                 GLuint plane) override;
+void CopyTextureCHROMIUM(GLenum target,
+                         GLenum source_id,
+                         GLenum dest_id,
+                         GLint level,
+                         GLint internalformat,
+                         GLenum dest_type) override;
+void DrawArraysInstancedANGLE(GLenum mode,
+                              GLint first,
+                              GLsizei count,
+                              GLsizei primcount) override;
+void DrawElementsInstancedANGLE(GLenum mode,
+                                GLsizei count,
+                                GLenum type,
+                                const void* indices,
+                                GLsizei primcount) override;
+void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) override;
+void GenMailboxCHROMIUM(GLbyte* mailbox) override;
+void ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) override;
+void ProduceTextureDirectCHROMIUM(GLuint texture,
+                                  GLenum target,
+                                  const GLbyte* mailbox) override;
+void ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) override;
+GLuint CreateAndConsumeTextureCHROMIUM(GLenum target,
+                                       const GLbyte* mailbox) override;
+void BindUniformLocationCHROMIUM(GLuint program,
+                                 GLint location,
+                                 const char* name) override;
+void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+void TraceBeginCHROMIUM(const char* name) override;
+void TraceEndCHROMIUM() override;
+void AsyncTexSubImage2DCHROMIUM(GLenum target,
+                                GLint level,
+                                GLint xoffset,
+                                GLint yoffset,
+                                GLsizei width,
+                                GLsizei height,
+                                GLenum format,
+                                GLenum type,
+                                const void* data) override;
+void AsyncTexImage2DCHROMIUM(GLenum target,
+                             GLint level,
+                             GLenum internalformat,
+                             GLsizei width,
+                             GLsizei height,
+                             GLint border,
+                             GLenum format,
+                             GLenum type,
+                             const void* pixels) override;
+void WaitAsyncTexImage2DCHROMIUM(GLenum target) override;
+void WaitAllAsyncTexImage2DCHROMIUM() override;
+void DiscardFramebufferEXT(GLenum target,
+                           GLsizei count,
+                           const GLenum* attachments) override;
+void LoseContextCHROMIUM(GLenum current, GLenum other) override;
+GLuint InsertSyncPointCHROMIUM() override;
+void WaitSyncPointCHROMIUM(GLuint sync_point) override;
+void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
+void DiscardBackbufferCHROMIUM() override;
+void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
+                                  GLenum plane_transform,
+                                  GLuint overlay_texture_id,
+                                  GLint bounds_x,
+                                  GLint bounds_y,
+                                  GLint bounds_width,
+                                  GLint bounds_height,
+                                  GLfloat uv_x,
+                                  GLfloat uv_y,
+                                  GLfloat uv_width,
+                                  GLfloat uv_height) override;
+void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override;
+void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override;
+void BlendBarrierKHR() override;
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index 09360860..e78b07c 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -851,4 +851,6 @@
 }
 void GLES2InterfaceStub::MatrixLoadIdentityCHROMIUM(GLenum /* matrixMode */) {
 }
+void GLES2InterfaceStub::BlendBarrierKHR() {
+}
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_trace_implementation.h b/gpu/command_buffer/client/gles2_trace_implementation.h
index c215231..780a608 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation.h
@@ -17,7 +17,7 @@
     : NON_EXPORTED_BASE(public GLES2Interface) {
  public:
   explicit GLES2TraceImplementation(GLES2Interface* gl);
-  virtual ~GLES2TraceImplementation();
+  ~GLES2TraceImplementation() override;
 
   // Include the auto-generated part of this class. We split this because
   // it means we can easily edit the non-auto generated parts right here in
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index aa0c96fd..a599eb4 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -12,520 +12,479 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_AUTOGEN_H_
 #define GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_AUTOGEN_H_
 
-virtual void ActiveTexture(GLenum texture) override;
-virtual void AttachShader(GLuint program, GLuint shader) override;
-virtual void BindAttribLocation(GLuint program,
-                                GLuint index,
-                                const char* name) override;
-virtual void BindBuffer(GLenum target, GLuint buffer) override;
-virtual void BindFramebuffer(GLenum target, GLuint framebuffer) override;
-virtual void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
-virtual void BindTexture(GLenum target, GLuint texture) override;
-virtual void BlendColor(GLclampf red,
-                        GLclampf green,
-                        GLclampf blue,
-                        GLclampf alpha) override;
-virtual void BlendEquation(GLenum mode) override;
-virtual void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) override;
-virtual void BlendFunc(GLenum sfactor, GLenum dfactor) override;
-virtual void BlendFuncSeparate(GLenum srcRGB,
-                               GLenum dstRGB,
-                               GLenum srcAlpha,
-                               GLenum dstAlpha) override;
-virtual void BufferData(GLenum target,
-                        GLsizeiptr size,
-                        const void* data,
-                        GLenum usage) override;
-virtual void BufferSubData(GLenum target,
-                           GLintptr offset,
-                           GLsizeiptr size,
-                           const void* data) override;
-virtual GLenum CheckFramebufferStatus(GLenum target) override;
-virtual void Clear(GLbitfield mask) override;
-virtual void ClearColor(GLclampf red,
-                        GLclampf green,
-                        GLclampf blue,
-                        GLclampf alpha) override;
-virtual void ClearDepthf(GLclampf depth) override;
-virtual void ClearStencil(GLint s) override;
-virtual void ColorMask(GLboolean red,
-                       GLboolean green,
-                       GLboolean blue,
-                       GLboolean alpha) override;
-virtual void CompileShader(GLuint shader) override;
-virtual void CompressedTexImage2D(GLenum target,
-                                  GLint level,
-                                  GLenum internalformat,
-                                  GLsizei width,
-                                  GLsizei height,
-                                  GLint border,
-                                  GLsizei imageSize,
-                                  const void* data) override;
-virtual void CompressedTexSubImage2D(GLenum target,
-                                     GLint level,
-                                     GLint xoffset,
-                                     GLint yoffset,
-                                     GLsizei width,
-                                     GLsizei height,
-                                     GLenum format,
-                                     GLsizei imageSize,
-                                     const void* data) override;
-virtual void CopyTexImage2D(GLenum target,
-                            GLint level,
-                            GLenum internalformat,
-                            GLint x,
-                            GLint y,
-                            GLsizei width,
-                            GLsizei height,
-                            GLint border) override;
-virtual void CopyTexSubImage2D(GLenum target,
+void ActiveTexture(GLenum texture) override;
+void AttachShader(GLuint program, GLuint shader) override;
+void BindAttribLocation(GLuint program,
+                        GLuint index,
+                        const char* name) override;
+void BindBuffer(GLenum target, GLuint buffer) override;
+void BindFramebuffer(GLenum target, GLuint framebuffer) override;
+void BindRenderbuffer(GLenum target, GLuint renderbuffer) override;
+void BindTexture(GLenum target, GLuint texture) override;
+void BlendColor(GLclampf red,
+                GLclampf green,
+                GLclampf blue,
+                GLclampf alpha) override;
+void BlendEquation(GLenum mode) override;
+void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) override;
+void BlendFunc(GLenum sfactor, GLenum dfactor) override;
+void BlendFuncSeparate(GLenum srcRGB,
+                       GLenum dstRGB,
+                       GLenum srcAlpha,
+                       GLenum dstAlpha) override;
+void BufferData(GLenum target,
+                GLsizeiptr size,
+                const void* data,
+                GLenum usage) override;
+void BufferSubData(GLenum target,
+                   GLintptr offset,
+                   GLsizeiptr size,
+                   const void* data) override;
+GLenum CheckFramebufferStatus(GLenum target) override;
+void Clear(GLbitfield mask) override;
+void ClearColor(GLclampf red,
+                GLclampf green,
+                GLclampf blue,
+                GLclampf alpha) override;
+void ClearDepthf(GLclampf depth) override;
+void ClearStencil(GLint s) override;
+void ColorMask(GLboolean red,
+               GLboolean green,
+               GLboolean blue,
+               GLboolean alpha) override;
+void CompileShader(GLuint shader) override;
+void CompressedTexImage2D(GLenum target,
+                          GLint level,
+                          GLenum internalformat,
+                          GLsizei width,
+                          GLsizei height,
+                          GLint border,
+                          GLsizei imageSize,
+                          const void* data) override;
+void CompressedTexSubImage2D(GLenum target,
+                             GLint level,
+                             GLint xoffset,
+                             GLint yoffset,
+                             GLsizei width,
+                             GLsizei height,
+                             GLenum format,
+                             GLsizei imageSize,
+                             const void* data) override;
+void CopyTexImage2D(GLenum target,
+                    GLint level,
+                    GLenum internalformat,
+                    GLint x,
+                    GLint y,
+                    GLsizei width,
+                    GLsizei height,
+                    GLint border) override;
+void CopyTexSubImage2D(GLenum target,
+                       GLint level,
+                       GLint xoffset,
+                       GLint yoffset,
+                       GLint x,
+                       GLint y,
+                       GLsizei width,
+                       GLsizei height) override;
+GLuint CreateProgram() override;
+GLuint CreateShader(GLenum type) override;
+void CullFace(GLenum mode) override;
+void DeleteBuffers(GLsizei n, const GLuint* buffers) override;
+void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
+void DeleteProgram(GLuint program) override;
+void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override;
+void DeleteShader(GLuint shader) override;
+void DeleteTextures(GLsizei n, const GLuint* textures) override;
+void DepthFunc(GLenum func) override;
+void DepthMask(GLboolean flag) override;
+void DepthRangef(GLclampf zNear, GLclampf zFar) override;
+void DetachShader(GLuint program, GLuint shader) override;
+void Disable(GLenum cap) override;
+void DisableVertexAttribArray(GLuint index) override;
+void DrawArrays(GLenum mode, GLint first, GLsizei count) override;
+void DrawElements(GLenum mode,
+                  GLsizei count,
+                  GLenum type,
+                  const void* indices) override;
+void Enable(GLenum cap) override;
+void EnableVertexAttribArray(GLuint index) override;
+void Finish() override;
+void Flush() override;
+void FramebufferRenderbuffer(GLenum target,
+                             GLenum attachment,
+                             GLenum renderbuffertarget,
+                             GLuint renderbuffer) override;
+void FramebufferTexture2D(GLenum target,
+                          GLenum attachment,
+                          GLenum textarget,
+                          GLuint texture,
+                          GLint level) override;
+void FrontFace(GLenum mode) override;
+void GenBuffers(GLsizei n, GLuint* buffers) override;
+void GenerateMipmap(GLenum target) override;
+void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
+void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
+void GenTextures(GLsizei n, GLuint* textures) override;
+void GetActiveAttrib(GLuint program,
+                     GLuint index,
+                     GLsizei bufsize,
+                     GLsizei* length,
+                     GLint* size,
+                     GLenum* type,
+                     char* name) override;
+void GetActiveUniform(GLuint program,
+                      GLuint index,
+                      GLsizei bufsize,
+                      GLsizei* length,
+                      GLint* size,
+                      GLenum* type,
+                      char* name) override;
+void GetAttachedShaders(GLuint program,
+                        GLsizei maxcount,
+                        GLsizei* count,
+                        GLuint* shaders) override;
+GLint GetAttribLocation(GLuint program, const char* name) override;
+void GetBooleanv(GLenum pname, GLboolean* params) override;
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) override;
+GLenum GetError() override;
+void GetFloatv(GLenum pname, GLfloat* params) override;
+void GetFramebufferAttachmentParameteriv(GLenum target,
+                                         GLenum attachment,
+                                         GLenum pname,
+                                         GLint* params) override;
+void GetIntegerv(GLenum pname, GLint* params) override;
+void GetProgramiv(GLuint program, GLenum pname, GLint* params) override;
+void GetProgramInfoLog(GLuint program,
+                       GLsizei bufsize,
+                       GLsizei* length,
+                       char* infolog) override;
+void GetRenderbufferParameteriv(GLenum target,
+                                GLenum pname,
+                                GLint* params) override;
+void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
+void GetShaderInfoLog(GLuint shader,
+                      GLsizei bufsize,
+                      GLsizei* length,
+                      char* infolog) override;
+void GetShaderPrecisionFormat(GLenum shadertype,
+                              GLenum precisiontype,
+                              GLint* range,
+                              GLint* precision) override;
+void GetShaderSource(GLuint shader,
+                     GLsizei bufsize,
+                     GLsizei* length,
+                     char* source) override;
+const GLubyte* GetString(GLenum name) override;
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) override;
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) override;
+void GetUniformfv(GLuint program, GLint location, GLfloat* params) override;
+void GetUniformiv(GLuint program, GLint location, GLint* params) override;
+GLint GetUniformLocation(GLuint program, const char* name) override;
+void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) override;
+void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) override;
+void GetVertexAttribPointerv(GLuint index,
+                             GLenum pname,
+                             void** pointer) override;
+void Hint(GLenum target, GLenum mode) override;
+GLboolean IsBuffer(GLuint buffer) override;
+GLboolean IsEnabled(GLenum cap) override;
+GLboolean IsFramebuffer(GLuint framebuffer) override;
+GLboolean IsProgram(GLuint program) override;
+GLboolean IsRenderbuffer(GLuint renderbuffer) override;
+GLboolean IsShader(GLuint shader) override;
+GLboolean IsTexture(GLuint texture) override;
+void LineWidth(GLfloat width) override;
+void LinkProgram(GLuint program) override;
+void PixelStorei(GLenum pname, GLint param) override;
+void PolygonOffset(GLfloat factor, GLfloat units) override;
+void ReadPixels(GLint x,
+                GLint y,
+                GLsizei width,
+                GLsizei height,
+                GLenum format,
+                GLenum type,
+                void* pixels) override;
+void ReleaseShaderCompiler() override;
+void RenderbufferStorage(GLenum target,
+                         GLenum internalformat,
+                         GLsizei width,
+                         GLsizei height) override;
+void SampleCoverage(GLclampf value, GLboolean invert) override;
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
+void ShaderBinary(GLsizei n,
+                  const GLuint* shaders,
+                  GLenum binaryformat,
+                  const void* binary,
+                  GLsizei length) override;
+void ShaderSource(GLuint shader,
+                  GLsizei count,
+                  const GLchar* const* str,
+                  const GLint* length) override;
+void ShallowFinishCHROMIUM() override;
+void ShallowFlushCHROMIUM() override;
+void StencilFunc(GLenum func, GLint ref, GLuint mask) override;
+void StencilFuncSeparate(GLenum face,
+                         GLenum func,
+                         GLint ref,
+                         GLuint mask) override;
+void StencilMask(GLuint mask) override;
+void StencilMaskSeparate(GLenum face, GLuint mask) override;
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) override;
+void StencilOpSeparate(GLenum face,
+                       GLenum fail,
+                       GLenum zfail,
+                       GLenum zpass) override;
+void TexImage2D(GLenum target,
+                GLint level,
+                GLint internalformat,
+                GLsizei width,
+                GLsizei height,
+                GLint border,
+                GLenum format,
+                GLenum type,
+                const void* pixels) override;
+void TexParameterf(GLenum target, GLenum pname, GLfloat param) override;
+void TexParameterfv(GLenum target,
+                    GLenum pname,
+                    const GLfloat* params) override;
+void TexParameteri(GLenum target, GLenum pname, GLint param) override;
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override;
+void TexSubImage2D(GLenum target,
+                   GLint level,
+                   GLint xoffset,
+                   GLint yoffset,
+                   GLsizei width,
+                   GLsizei height,
+                   GLenum format,
+                   GLenum type,
+                   const void* pixels) override;
+void Uniform1f(GLint location, GLfloat x) override;
+void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) override;
+void Uniform1i(GLint location, GLint x) override;
+void Uniform1iv(GLint location, GLsizei count, const GLint* v) override;
+void Uniform2f(GLint location, GLfloat x, GLfloat y) override;
+void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override;
+void Uniform2i(GLint location, GLint x, GLint y) override;
+void Uniform2iv(GLint location, GLsizei count, const GLint* v) override;
+void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override;
+void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override;
+void Uniform3i(GLint location, GLint x, GLint y, GLint z) override;
+void Uniform3iv(GLint location, GLsizei count, const GLint* v) override;
+void Uniform4f(GLint location,
+               GLfloat x,
+               GLfloat y,
+               GLfloat z,
+               GLfloat w) override;
+void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) override;
+void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override;
+void Uniform4iv(GLint location, GLsizei count, const GLint* v) override;
+void UniformMatrix2fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+void UniformMatrix3fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+void UniformMatrix4fv(GLint location,
+                      GLsizei count,
+                      GLboolean transpose,
+                      const GLfloat* value) override;
+void UseProgram(GLuint program) override;
+void ValidateProgram(GLuint program) override;
+void VertexAttrib1f(GLuint indx, GLfloat x) override;
+void VertexAttrib1fv(GLuint indx, const GLfloat* values) override;
+void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) override;
+void VertexAttrib2fv(GLuint indx, const GLfloat* values) override;
+void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) override;
+void VertexAttrib3fv(GLuint indx, const GLfloat* values) override;
+void VertexAttrib4f(GLuint indx,
+                    GLfloat x,
+                    GLfloat y,
+                    GLfloat z,
+                    GLfloat w) override;
+void VertexAttrib4fv(GLuint indx, const GLfloat* values) override;
+void VertexAttribPointer(GLuint indx,
+                         GLint size,
+                         GLenum type,
+                         GLboolean normalized,
+                         GLsizei stride,
+                         const void* ptr) override;
+void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override;
+void BlitFramebufferCHROMIUM(GLint srcX0,
+                             GLint srcY0,
+                             GLint srcX1,
+                             GLint srcY1,
+                             GLint dstX0,
+                             GLint dstY0,
+                             GLint dstX1,
+                             GLint dstY1,
+                             GLbitfield mask,
+                             GLenum filter) override;
+void RenderbufferStorageMultisampleCHROMIUM(GLenum target,
+                                            GLsizei samples,
+                                            GLenum internalformat,
+                                            GLsizei width,
+                                            GLsizei height) override;
+void RenderbufferStorageMultisampleEXT(GLenum target,
+                                       GLsizei samples,
+                                       GLenum internalformat,
+                                       GLsizei width,
+                                       GLsizei height) override;
+void FramebufferTexture2DMultisampleEXT(GLenum target,
+                                        GLenum attachment,
+                                        GLenum textarget,
+                                        GLuint texture,
+                                        GLint level,
+                                        GLsizei samples) override;
+void TexStorage2DEXT(GLenum target,
+                     GLsizei levels,
+                     GLenum internalFormat,
+                     GLsizei width,
+                     GLsizei height) override;
+void GenQueriesEXT(GLsizei n, GLuint* queries) override;
+void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
+GLboolean IsQueryEXT(GLuint id) override;
+void BeginQueryEXT(GLenum target, GLuint id) override;
+void EndQueryEXT(GLenum target) override;
+void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
+void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override;
+void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) override;
+void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) override;
+void PopGroupMarkerEXT() override;
+void GenVertexArraysOES(GLsizei n, GLuint* arrays) override;
+void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) override;
+GLboolean IsVertexArrayOES(GLuint array) override;
+void BindVertexArrayOES(GLuint array) override;
+void SwapBuffers() override;
+GLuint GetMaxValueInBufferCHROMIUM(GLuint buffer_id,
+                                   GLsizei count,
+                                   GLenum type,
+                                   GLuint offset) override;
+GLboolean EnableFeatureCHROMIUM(const char* feature) override;
+void* MapBufferCHROMIUM(GLuint target, GLenum access) override;
+GLboolean UnmapBufferCHROMIUM(GLuint target) override;
+void* MapBufferSubDataCHROMIUM(GLuint target,
+                               GLintptr offset,
+                               GLsizeiptr size,
+                               GLenum access) override;
+void UnmapBufferSubDataCHROMIUM(const void* mem) override;
+void* MapTexSubImage2DCHROMIUM(GLenum target,
                                GLint level,
                                GLint xoffset,
                                GLint yoffset,
-                               GLint x,
-                               GLint y,
                                GLsizei width,
-                               GLsizei height) override;
-virtual GLuint CreateProgram() override;
-virtual GLuint CreateShader(GLenum type) override;
-virtual void CullFace(GLenum mode) override;
-virtual void DeleteBuffers(GLsizei n, const GLuint* buffers) override;
-virtual void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
-virtual void DeleteProgram(GLuint program) override;
-virtual void DeleteRenderbuffers(GLsizei n,
-                                 const GLuint* renderbuffers) override;
-virtual void DeleteShader(GLuint shader) override;
-virtual void DeleteTextures(GLsizei n, const GLuint* textures) override;
-virtual void DepthFunc(GLenum func) override;
-virtual void DepthMask(GLboolean flag) override;
-virtual void DepthRangef(GLclampf zNear, GLclampf zFar) override;
-virtual void DetachShader(GLuint program, GLuint shader) override;
-virtual void Disable(GLenum cap) override;
-virtual void DisableVertexAttribArray(GLuint index) override;
-virtual void DrawArrays(GLenum mode, GLint first, GLsizei count) override;
-virtual void DrawElements(GLenum mode,
-                          GLsizei count,
-                          GLenum type,
-                          const void* indices) override;
-virtual void Enable(GLenum cap) override;
-virtual void EnableVertexAttribArray(GLuint index) override;
-virtual void Finish() override;
-virtual void Flush() override;
-virtual void FramebufferRenderbuffer(GLenum target,
-                                     GLenum attachment,
-                                     GLenum renderbuffertarget,
-                                     GLuint renderbuffer) override;
-virtual void FramebufferTexture2D(GLenum target,
-                                  GLenum attachment,
-                                  GLenum textarget,
-                                  GLuint texture,
-                                  GLint level) override;
-virtual void FrontFace(GLenum mode) override;
-virtual void GenBuffers(GLsizei n, GLuint* buffers) override;
-virtual void GenerateMipmap(GLenum target) override;
-virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
-virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
-virtual void GenTextures(GLsizei n, GLuint* textures) override;
-virtual void GetActiveAttrib(GLuint program,
-                             GLuint index,
-                             GLsizei bufsize,
-                             GLsizei* length,
-                             GLint* size,
-                             GLenum* type,
-                             char* name) override;
-virtual void GetActiveUniform(GLuint program,
-                              GLuint index,
-                              GLsizei bufsize,
-                              GLsizei* length,
-                              GLint* size,
-                              GLenum* type,
-                              char* name) override;
-virtual void GetAttachedShaders(GLuint program,
-                                GLsizei maxcount,
-                                GLsizei* count,
-                                GLuint* shaders) override;
-virtual GLint GetAttribLocation(GLuint program, const char* name) override;
-virtual void GetBooleanv(GLenum pname, GLboolean* params) override;
-virtual void GetBufferParameteriv(GLenum target,
-                                  GLenum pname,
-                                  GLint* params) override;
-virtual GLenum GetError() override;
-virtual void GetFloatv(GLenum pname, GLfloat* params) override;
-virtual void GetFramebufferAttachmentParameteriv(GLenum target,
-                                                 GLenum attachment,
-                                                 GLenum pname,
-                                                 GLint* params) override;
-virtual void GetIntegerv(GLenum pname, GLint* params) override;
-virtual void GetProgramiv(GLuint program, GLenum pname, GLint* params) override;
-virtual void GetProgramInfoLog(GLuint program,
-                               GLsizei bufsize,
-                               GLsizei* length,
-                               char* infolog) override;
-virtual void GetRenderbufferParameteriv(GLenum target,
-                                        GLenum pname,
-                                        GLint* params) override;
-virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
-virtual void GetShaderInfoLog(GLuint shader,
-                              GLsizei bufsize,
-                              GLsizei* length,
-                              char* infolog) override;
-virtual void GetShaderPrecisionFormat(GLenum shadertype,
-                                      GLenum precisiontype,
-                                      GLint* range,
-                                      GLint* precision) override;
-virtual void GetShaderSource(GLuint shader,
-                             GLsizei bufsize,
-                             GLsizei* length,
-                             char* source) override;
-virtual const GLubyte* GetString(GLenum name) override;
-virtual void GetTexParameterfv(GLenum target,
-                               GLenum pname,
-                               GLfloat* params) override;
-virtual void GetTexParameteriv(GLenum target,
-                               GLenum pname,
-                               GLint* params) override;
-virtual void GetUniformfv(GLuint program,
-                          GLint location,
-                          GLfloat* params) override;
-virtual void GetUniformiv(GLuint program,
-                          GLint location,
-                          GLint* params) override;
-virtual GLint GetUniformLocation(GLuint program, const char* name) override;
-virtual void GetVertexAttribfv(GLuint index,
-                               GLenum pname,
-                               GLfloat* params) override;
-virtual void GetVertexAttribiv(GLuint index,
-                               GLenum pname,
-                               GLint* params) override;
-virtual void GetVertexAttribPointerv(GLuint index,
-                                     GLenum pname,
-                                     void** pointer) override;
-virtual void Hint(GLenum target, GLenum mode) override;
-virtual GLboolean IsBuffer(GLuint buffer) override;
-virtual GLboolean IsEnabled(GLenum cap) override;
-virtual GLboolean IsFramebuffer(GLuint framebuffer) override;
-virtual GLboolean IsProgram(GLuint program) override;
-virtual GLboolean IsRenderbuffer(GLuint renderbuffer) override;
-virtual GLboolean IsShader(GLuint shader) override;
-virtual GLboolean IsTexture(GLuint texture) override;
-virtual void LineWidth(GLfloat width) override;
-virtual void LinkProgram(GLuint program) override;
-virtual void PixelStorei(GLenum pname, GLint param) override;
-virtual void PolygonOffset(GLfloat factor, GLfloat units) override;
-virtual void ReadPixels(GLint x,
-                        GLint y,
-                        GLsizei width,
-                        GLsizei height,
-                        GLenum format,
-                        GLenum type,
-                        void* pixels) override;
-virtual void ReleaseShaderCompiler() override;
-virtual void RenderbufferStorage(GLenum target,
-                                 GLenum internalformat,
-                                 GLsizei width,
-                                 GLsizei height) override;
-virtual void SampleCoverage(GLclampf value, GLboolean invert) override;
-virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
-virtual void ShaderBinary(GLsizei n,
-                          const GLuint* shaders,
-                          GLenum binaryformat,
-                          const void* binary,
-                          GLsizei length) override;
-virtual void ShaderSource(GLuint shader,
-                          GLsizei count,
-                          const GLchar* const* str,
-                          const GLint* length) override;
-virtual void ShallowFinishCHROMIUM() override;
-virtual void ShallowFlushCHROMIUM() override;
-virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) override;
-virtual void StencilFuncSeparate(GLenum face,
-                                 GLenum func,
-                                 GLint ref,
-                                 GLuint mask) override;
-virtual void StencilMask(GLuint mask) override;
-virtual void StencilMaskSeparate(GLenum face, GLuint mask) override;
-virtual void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) override;
-virtual void StencilOpSeparate(GLenum face,
-                               GLenum fail,
-                               GLenum zfail,
-                               GLenum zpass) override;
-virtual void TexImage2D(GLenum target,
-                        GLint level,
-                        GLint internalformat,
-                        GLsizei width,
-                        GLsizei height,
-                        GLint border,
-                        GLenum format,
-                        GLenum type,
-                        const void* pixels) override;
-virtual void TexParameterf(GLenum target, GLenum pname, GLfloat param) override;
-virtual void TexParameterfv(GLenum target,
-                            GLenum pname,
-                            const GLfloat* params) override;
-virtual void TexParameteri(GLenum target, GLenum pname, GLint param) override;
-virtual void TexParameteriv(GLenum target,
-                            GLenum pname,
-                            const GLint* params) override;
-virtual void TexSubImage2D(GLenum target,
-                           GLint level,
-                           GLint xoffset,
-                           GLint yoffset,
+                               GLsizei height,
+                               GLenum format,
+                               GLenum type,
+                               GLenum access) override;
+void UnmapTexSubImage2DCHROMIUM(const void* mem) override;
+void ResizeCHROMIUM(GLuint width, GLuint height, GLfloat scale_factor) override;
+const GLchar* GetRequestableExtensionsCHROMIUM() override;
+void RequestExtensionCHROMIUM(const char* extension) override;
+void RateLimitOffscreenContextCHROMIUM() override;
+void GetMultipleIntegervCHROMIUM(const GLenum* pnames,
+                                 GLuint count,
+                                 GLint* results,
+                                 GLsizeiptr size) override;
+void GetProgramInfoCHROMIUM(GLuint program,
+                            GLsizei bufsize,
+                            GLsizei* size,
+                            void* info) override;
+GLuint CreateStreamTextureCHROMIUM(GLuint texture) override;
+GLuint CreateImageCHROMIUM(ClientBuffer buffer,
                            GLsizei width,
                            GLsizei height,
-                           GLenum format,
-                           GLenum type,
-                           const void* pixels) override;
-virtual void Uniform1f(GLint location, GLfloat x) override;
-virtual void Uniform1fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-virtual void Uniform1i(GLint location, GLint x) override;
-virtual void Uniform1iv(GLint location, GLsizei count, const GLint* v) override;
-virtual void Uniform2f(GLint location, GLfloat x, GLfloat y) override;
-virtual void Uniform2fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-virtual void Uniform2i(GLint location, GLint x, GLint y) override;
-virtual void Uniform2iv(GLint location, GLsizei count, const GLint* v) override;
-virtual void Uniform3f(GLint location,
-                       GLfloat x,
-                       GLfloat y,
-                       GLfloat z) override;
-virtual void Uniform3fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-virtual void Uniform3i(GLint location, GLint x, GLint y, GLint z) override;
-virtual void Uniform3iv(GLint location, GLsizei count, const GLint* v) override;
-virtual void Uniform4f(GLint location,
-                       GLfloat x,
-                       GLfloat y,
-                       GLfloat z,
-                       GLfloat w) override;
-virtual void Uniform4fv(GLint location,
-                        GLsizei count,
-                        const GLfloat* v) override;
-virtual void Uniform4i(GLint location,
-                       GLint x,
-                       GLint y,
-                       GLint z,
-                       GLint w) override;
-virtual void Uniform4iv(GLint location, GLsizei count, const GLint* v) override;
-virtual void UniformMatrix2fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-virtual void UniformMatrix3fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-virtual void UniformMatrix4fv(GLint location,
-                              GLsizei count,
-                              GLboolean transpose,
-                              const GLfloat* value) override;
-virtual void UseProgram(GLuint program) override;
-virtual void ValidateProgram(GLuint program) override;
-virtual void VertexAttrib1f(GLuint indx, GLfloat x) override;
-virtual void VertexAttrib1fv(GLuint indx, const GLfloat* values) override;
-virtual void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) override;
-virtual void VertexAttrib2fv(GLuint indx, const GLfloat* values) override;
-virtual void VertexAttrib3f(GLuint indx,
-                            GLfloat x,
-                            GLfloat y,
-                            GLfloat z) override;
-virtual void VertexAttrib3fv(GLuint indx, const GLfloat* values) override;
-virtual void VertexAttrib4f(GLuint indx,
-                            GLfloat x,
-                            GLfloat y,
-                            GLfloat z,
-                            GLfloat w) override;
-virtual void VertexAttrib4fv(GLuint indx, const GLfloat* values) override;
-virtual void VertexAttribPointer(GLuint indx,
-                                 GLint size,
-                                 GLenum type,
-                                 GLboolean normalized,
-                                 GLsizei stride,
-                                 const void* ptr) override;
-virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override;
-virtual void BlitFramebufferCHROMIUM(GLint srcX0,
-                                     GLint srcY0,
-                                     GLint srcX1,
-                                     GLint srcY1,
-                                     GLint dstX0,
-                                     GLint dstY0,
-                                     GLint dstX1,
-                                     GLint dstY1,
-                                     GLbitfield mask,
-                                     GLenum filter) override;
-virtual void RenderbufferStorageMultisampleCHROMIUM(GLenum target,
-                                                    GLsizei samples,
-                                                    GLenum internalformat,
-                                                    GLsizei width,
-                                                    GLsizei height) override;
-virtual void RenderbufferStorageMultisampleEXT(GLenum target,
-                                               GLsizei samples,
-                                               GLenum internalformat,
-                                               GLsizei width,
-                                               GLsizei height) override;
-virtual void FramebufferTexture2DMultisampleEXT(GLenum target,
-                                                GLenum attachment,
-                                                GLenum textarget,
-                                                GLuint texture,
-                                                GLint level,
-                                                GLsizei samples) override;
-virtual void TexStorage2DEXT(GLenum target,
-                             GLsizei levels,
-                             GLenum internalFormat,
-                             GLsizei width,
-                             GLsizei height) override;
-virtual void GenQueriesEXT(GLsizei n, GLuint* queries) override;
-virtual void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
-virtual GLboolean IsQueryEXT(GLuint id) override;
-virtual void BeginQueryEXT(GLenum target, GLuint id) override;
-virtual void EndQueryEXT(GLenum target) override;
-virtual void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) override;
-virtual void GetQueryObjectuivEXT(GLuint id,
-                                  GLenum pname,
-                                  GLuint* params) override;
-virtual void InsertEventMarkerEXT(GLsizei length,
-                                  const GLchar* marker) override;
-virtual void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) override;
-virtual void PopGroupMarkerEXT() override;
-virtual void GenVertexArraysOES(GLsizei n, GLuint* arrays) override;
-virtual void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) override;
-virtual GLboolean IsVertexArrayOES(GLuint array) override;
-virtual void BindVertexArrayOES(GLuint array) override;
-virtual void SwapBuffers() override;
-virtual GLuint GetMaxValueInBufferCHROMIUM(GLuint buffer_id,
-                                           GLsizei count,
-                                           GLenum type,
-                                           GLuint offset) override;
-virtual GLboolean EnableFeatureCHROMIUM(const char* feature) override;
-virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) override;
-virtual GLboolean UnmapBufferCHROMIUM(GLuint target) override;
-virtual void* MapBufferSubDataCHROMIUM(GLuint target,
-                                       GLintptr offset,
-                                       GLsizeiptr size,
-                                       GLenum access) override;
-virtual void UnmapBufferSubDataCHROMIUM(const void* mem) override;
-virtual void* MapTexSubImage2DCHROMIUM(GLenum target,
-                                       GLint level,
-                                       GLint xoffset,
-                                       GLint yoffset,
-                                       GLsizei width,
-                                       GLsizei height,
-                                       GLenum format,
-                                       GLenum type,
-                                       GLenum access) override;
-virtual void UnmapTexSubImage2DCHROMIUM(const void* mem) override;
-virtual void ResizeCHROMIUM(GLuint width,
-                            GLuint height,
-                            GLfloat scale_factor) override;
-virtual const GLchar* GetRequestableExtensionsCHROMIUM() override;
-virtual void RequestExtensionCHROMIUM(const char* extension) override;
-virtual void RateLimitOffscreenContextCHROMIUM() override;
-virtual void GetMultipleIntegervCHROMIUM(const GLenum* pnames,
-                                         GLuint count,
-                                         GLint* results,
-                                         GLsizeiptr size) override;
-virtual void GetProgramInfoCHROMIUM(GLuint program,
+                           GLenum internalformat) override;
+void DestroyImageCHROMIUM(GLuint image_id) override;
+GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width,
+                                          GLsizei height,
+                                          GLenum internalformat,
+                                          GLenum usage) override;
+void GetTranslatedShaderSourceANGLE(GLuint shader,
                                     GLsizei bufsize,
-                                    GLsizei* size,
-                                    void* info) override;
-virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) override;
-virtual GLuint CreateImageCHROMIUM(ClientBuffer buffer,
-                                   GLsizei width,
-                                   GLsizei height,
-                                   GLenum internalformat) override;
-virtual void DestroyImageCHROMIUM(GLuint image_id) override;
-virtual GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width,
-                                                  GLsizei height,
-                                                  GLenum internalformat,
-                                                  GLenum usage) override;
-virtual void GetTranslatedShaderSourceANGLE(GLuint shader,
-                                            GLsizei bufsize,
-                                            GLsizei* length,
-                                            char* source) override;
-virtual void PostSubBufferCHROMIUM(GLint x,
-                                   GLint y,
-                                   GLint width,
-                                   GLint height) override;
-virtual void TexImageIOSurface2DCHROMIUM(GLenum target,
-                                         GLsizei width,
-                                         GLsizei height,
-                                         GLuint ioSurfaceId,
-                                         GLuint plane) override;
-virtual void CopyTextureCHROMIUM(GLenum target,
-                                 GLenum source_id,
-                                 GLenum dest_id,
-                                 GLint level,
-                                 GLint internalformat,
-                                 GLenum dest_type) override;
-virtual void DrawArraysInstancedANGLE(GLenum mode,
-                                      GLint first,
-                                      GLsizei count,
-                                      GLsizei primcount) override;
-virtual void DrawElementsInstancedANGLE(GLenum mode,
-                                        GLsizei count,
-                                        GLenum type,
-                                        const void* indices,
-                                        GLsizei primcount) override;
-virtual void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) override;
-virtual void GenMailboxCHROMIUM(GLbyte* mailbox) override;
-virtual void ProduceTextureCHROMIUM(GLenum target,
-                                    const GLbyte* mailbox) override;
-virtual void ProduceTextureDirectCHROMIUM(GLuint texture,
-                                          GLenum target,
-                                          const GLbyte* mailbox) override;
-virtual void ConsumeTextureCHROMIUM(GLenum target,
-                                    const GLbyte* mailbox) override;
-virtual GLuint CreateAndConsumeTextureCHROMIUM(GLenum target,
-                                               const GLbyte* mailbox) override;
-virtual void BindUniformLocationCHROMIUM(GLuint program,
-                                         GLint location,
-                                         const char* name) override;
-virtual void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
-virtual void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
-virtual void TraceBeginCHROMIUM(const char* name) override;
-virtual void TraceEndCHROMIUM() override;
-virtual void AsyncTexSubImage2DCHROMIUM(GLenum target,
-                                        GLint level,
-                                        GLint xoffset,
-                                        GLint yoffset,
-                                        GLsizei width,
-                                        GLsizei height,
-                                        GLenum format,
-                                        GLenum type,
-                                        const void* data) override;
-virtual void AsyncTexImage2DCHROMIUM(GLenum target,
-                                     GLint level,
-                                     GLenum internalformat,
-                                     GLsizei width,
-                                     GLsizei height,
-                                     GLint border,
-                                     GLenum format,
-                                     GLenum type,
-                                     const void* pixels) override;
-virtual void WaitAsyncTexImage2DCHROMIUM(GLenum target) override;
-virtual void WaitAllAsyncTexImage2DCHROMIUM() override;
-virtual void DiscardFramebufferEXT(GLenum target,
-                                   GLsizei count,
-                                   const GLenum* attachments) override;
-virtual void LoseContextCHROMIUM(GLenum current, GLenum other) override;
-virtual GLuint InsertSyncPointCHROMIUM() override;
-virtual void WaitSyncPointCHROMIUM(GLuint sync_point) override;
-virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
-virtual void DiscardBackbufferCHROMIUM() override;
-virtual void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
-                                          GLenum plane_transform,
-                                          GLuint overlay_texture_id,
-                                          GLint bounds_x,
-                                          GLint bounds_y,
-                                          GLint bounds_width,
-                                          GLint bounds_height,
-                                          GLfloat uv_x,
-                                          GLfloat uv_y,
-                                          GLfloat uv_width,
-                                          GLfloat uv_height) override;
-virtual void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override;
-virtual void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override;
+                                    GLsizei* length,
+                                    char* source) override;
+void PostSubBufferCHROMIUM(GLint x,
+                           GLint y,
+                           GLint width,
+                           GLint height) override;
+void TexImageIOSurface2DCHROMIUM(GLenum target,
+                                 GLsizei width,
+                                 GLsizei height,
+                                 GLuint ioSurfaceId,
+                                 GLuint plane) override;
+void CopyTextureCHROMIUM(GLenum target,
+                         GLenum source_id,
+                         GLenum dest_id,
+                         GLint level,
+                         GLint internalformat,
+                         GLenum dest_type) override;
+void DrawArraysInstancedANGLE(GLenum mode,
+                              GLint first,
+                              GLsizei count,
+                              GLsizei primcount) override;
+void DrawElementsInstancedANGLE(GLenum mode,
+                                GLsizei count,
+                                GLenum type,
+                                const void* indices,
+                                GLsizei primcount) override;
+void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) override;
+void GenMailboxCHROMIUM(GLbyte* mailbox) override;
+void ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) override;
+void ProduceTextureDirectCHROMIUM(GLuint texture,
+                                  GLenum target,
+                                  const GLbyte* mailbox) override;
+void ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) override;
+GLuint CreateAndConsumeTextureCHROMIUM(GLenum target,
+                                       const GLbyte* mailbox) override;
+void BindUniformLocationCHROMIUM(GLuint program,
+                                 GLint location,
+                                 const char* name) override;
+void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) override;
+void TraceBeginCHROMIUM(const char* name) override;
+void TraceEndCHROMIUM() override;
+void AsyncTexSubImage2DCHROMIUM(GLenum target,
+                                GLint level,
+                                GLint xoffset,
+                                GLint yoffset,
+                                GLsizei width,
+                                GLsizei height,
+                                GLenum format,
+                                GLenum type,
+                                const void* data) override;
+void AsyncTexImage2DCHROMIUM(GLenum target,
+                             GLint level,
+                             GLenum internalformat,
+                             GLsizei width,
+                             GLsizei height,
+                             GLint border,
+                             GLenum format,
+                             GLenum type,
+                             const void* pixels) override;
+void WaitAsyncTexImage2DCHROMIUM(GLenum target) override;
+void WaitAllAsyncTexImage2DCHROMIUM() override;
+void DiscardFramebufferEXT(GLenum target,
+                           GLsizei count,
+                           const GLenum* attachments) override;
+void LoseContextCHROMIUM(GLenum current, GLenum other) override;
+GLuint InsertSyncPointCHROMIUM() override;
+void WaitSyncPointCHROMIUM(GLuint sync_point) override;
+void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
+void DiscardBackbufferCHROMIUM() override;
+void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
+                                  GLenum plane_transform,
+                                  GLuint overlay_texture_id,
+                                  GLint bounds_x,
+                                  GLint bounds_y,
+                                  GLint bounds_width,
+                                  GLint bounds_height,
+                                  GLfloat uv_x,
+                                  GLfloat uv_y,
+                                  GLfloat uv_width,
+                                  GLfloat uv_height) override;
+void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override;
+void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override;
+void BlendBarrierKHR() override;
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index d1b5fce..3173a25 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -1509,4 +1509,9 @@
   gl_->MatrixLoadIdentityCHROMIUM(matrixMode);
 }
 
+void GLES2TraceImplementation::BlendBarrierKHR() {
+  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::BlendBarrierKHR");
+  gl_->BlendBarrierKHR();
+}
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/program_info_manager.cc b/gpu/command_buffer/client/program_info_manager.cc
index a74b4f03..c0f8600 100644
--- a/gpu/command_buffer/client/program_info_manager.cc
+++ b/gpu/command_buffer/client/program_info_manager.cc
@@ -17,43 +17,42 @@
 class NonCachedProgramInfoManager : public ProgramInfoManager {
  public:
   NonCachedProgramInfoManager();
-  virtual ~NonCachedProgramInfoManager();
+  ~NonCachedProgramInfoManager() override;
 
-  virtual void CreateInfo(GLuint program) override;
+  void CreateInfo(GLuint program) override;
 
-  virtual void DeleteInfo(GLuint program) override;
+  void DeleteInfo(GLuint program) override;
 
-  virtual bool GetProgramiv(GLES2Implementation* gl,
-                            GLuint program,
-                            GLenum pname,
-                            GLint* params) override;
+  bool GetProgramiv(GLES2Implementation* gl,
+                    GLuint program,
+                    GLenum pname,
+                    GLint* params) override;
 
-  virtual GLint GetAttribLocation(GLES2Implementation* gl,
-                                  GLuint program,
-                                  const char* name) override;
+  GLint GetAttribLocation(GLES2Implementation* gl,
+                          GLuint program,
+                          const char* name) override;
 
-  virtual GLint GetUniformLocation(GLES2Implementation* gl,
-                                   GLuint program,
-                                   const char* name) override;
+  GLint GetUniformLocation(GLES2Implementation* gl,
+                           GLuint program,
+                           const char* name) override;
 
-  virtual bool GetActiveAttrib(GLES2Implementation* gl,
-                               GLuint program,
-                               GLuint index,
-                               GLsizei bufsize,
-                               GLsizei* length,
-                               GLint* size,
-                               GLenum* type,
-                               char* name) override;
+  bool GetActiveAttrib(GLES2Implementation* gl,
+                       GLuint program,
+                       GLuint index,
+                       GLsizei bufsize,
+                       GLsizei* length,
+                       GLint* size,
+                       GLenum* type,
+                       char* name) override;
 
-  virtual bool GetActiveUniform(GLES2Implementation* gl,
-                                GLuint program,
-                                GLuint index,
-                                GLsizei bufsize,
-                                GLsizei* length,
-                                GLint* size,
-                                GLenum* type,
-                                char* name) override;
-
+  bool GetActiveUniform(GLES2Implementation* gl,
+                        GLuint program,
+                        GLuint index,
+                        GLsizei bufsize,
+                        GLsizei* length,
+                        GLint* size,
+                        GLenum* type,
+                        char* name) override;
 };
 
 NonCachedProgramInfoManager::NonCachedProgramInfoManager() {
@@ -105,42 +104,42 @@
 class CachedProgramInfoManager : public ProgramInfoManager {
  public:
   CachedProgramInfoManager();
-  virtual ~CachedProgramInfoManager();
+  ~CachedProgramInfoManager() override;
 
-  virtual void CreateInfo(GLuint program) override;
+  void CreateInfo(GLuint program) override;
 
-  virtual void DeleteInfo(GLuint program) override;
+  void DeleteInfo(GLuint program) override;
 
-  virtual bool GetProgramiv(GLES2Implementation* gl,
-                            GLuint program,
-                            GLenum pname,
-                            GLint* params) override;
+  bool GetProgramiv(GLES2Implementation* gl,
+                    GLuint program,
+                    GLenum pname,
+                    GLint* params) override;
 
-  virtual GLint GetAttribLocation(GLES2Implementation* gl,
-                                  GLuint program,
-                                  const char* name) override;
+  GLint GetAttribLocation(GLES2Implementation* gl,
+                          GLuint program,
+                          const char* name) override;
 
-  virtual GLint GetUniformLocation(GLES2Implementation* gl,
-                                   GLuint program,
-                                   const char* name) override;
+  GLint GetUniformLocation(GLES2Implementation* gl,
+                           GLuint program,
+                           const char* name) override;
 
-  virtual bool GetActiveAttrib(GLES2Implementation* gl,
-                               GLuint program,
-                               GLuint index,
-                               GLsizei bufsize,
-                               GLsizei* length,
-                               GLint* size,
-                               GLenum* type,
-                               char* name) override;
+  bool GetActiveAttrib(GLES2Implementation* gl,
+                       GLuint program,
+                       GLuint index,
+                       GLsizei bufsize,
+                       GLsizei* length,
+                       GLint* size,
+                       GLenum* type,
+                       char* name) override;
 
-  virtual bool GetActiveUniform(GLES2Implementation* gl,
-                                GLuint program,
-                                GLuint index,
-                                GLsizei bufsize,
-                                GLsizei* length,
-                                GLint* size,
-                                GLenum* type,
-                                char* name) override;
+  bool GetActiveUniform(GLES2Implementation* gl,
+                        GLuint program,
+                        GLuint index,
+                        GLsizei bufsize,
+                        GLsizei* length,
+                        GLint* size,
+                        GLenum* type,
+                        char* name) override;
 
  private:
   class Program {
diff --git a/gpu/command_buffer/client/share_group.cc b/gpu/command_buffer/client/share_group.cc
index b99ad1e0..c7e3845 100644
--- a/gpu/command_buffer/client/share_group.cc
+++ b/gpu/command_buffer/client/share_group.cc
@@ -26,12 +26,13 @@
 class IdHandler : public IdHandlerInterface {
  public:
   IdHandler() { }
-  virtual ~IdHandler() { }
+  ~IdHandler() override {}
 
   // Overridden from IdHandlerInterface.
-  virtual void MakeIds(
-      GLES2Implementation* /* gl_impl */,
-      GLuint id_offset, GLsizei n, GLuint* ids) override {
+  void MakeIds(GLES2Implementation* /* gl_impl */,
+               GLuint id_offset,
+               GLsizei n,
+               GLuint* ids) override {
     base::AutoLock auto_lock(lock_);
     if (id_offset == 0) {
       for (GLsizei ii = 0; ii < n; ++ii) {
@@ -46,9 +47,10 @@
   }
 
   // Overridden from IdHandlerInterface.
-  virtual bool FreeIds(
-      GLES2Implementation* gl_impl,
-      GLsizei n, const GLuint* ids, DeleteFn delete_fn) override {
+  bool FreeIds(GLES2Implementation* gl_impl,
+               GLsizei n,
+               const GLuint* ids,
+               DeleteFn delete_fn) override {
     base::AutoLock auto_lock(lock_);
 
     for (GLsizei ii = 0; ii < n; ++ii) {
@@ -65,14 +67,14 @@
   }
 
   // Overridden from IdHandlerInterface.
-  virtual bool MarkAsUsedForBind(GLuint id) override {
+  bool MarkAsUsedForBind(GLuint id) override {
     if (id == 0)
       return true;
     base::AutoLock auto_lock(lock_);
     return id_allocator_.MarkAsUsed(id);
   }
 
-  virtual void FreeContext(GLES2Implementation* gl_impl) override {}
+  void FreeContext(GLES2Implementation* gl_impl) override {}
 
  private:
   base::Lock lock_;
@@ -83,13 +85,13 @@
 class StrictIdHandler : public IdHandlerInterface {
  public:
   explicit StrictIdHandler(int id_namespace) : id_namespace_(id_namespace) {}
-  virtual ~StrictIdHandler() {}
+  ~StrictIdHandler() override {}
 
   // Overridden from IdHandler.
-  virtual void MakeIds(GLES2Implementation* gl_impl,
-                       GLuint /* id_offset */,
-                       GLsizei n,
-                       GLuint* ids) override {
+  void MakeIds(GLES2Implementation* gl_impl,
+               GLuint /* id_offset */,
+               GLsizei n,
+               GLuint* ids) override {
     base::AutoLock auto_lock(lock_);
 
     // Collect pending FreeIds from other flush_generation.
@@ -113,11 +115,10 @@
   }
 
   // Overridden from IdHandler.
-  virtual bool FreeIds(GLES2Implementation* gl_impl,
-                       GLsizei n,
-                       const GLuint* ids,
-                       DeleteFn delete_fn) override {
-
+  bool FreeIds(GLES2Implementation* gl_impl,
+               GLsizei n,
+               const GLuint* ids,
+               DeleteFn delete_fn) override {
     // Delete stub must run before CollectPendingFreeIds.
     (gl_impl->*delete_fn)(n, ids);
 
@@ -146,7 +147,7 @@
   }
 
   // Overridden from IdHandler.
-  virtual bool MarkAsUsedForBind(GLuint id) override {
+  bool MarkAsUsedForBind(GLuint id) override {
 #ifndef NDEBUG
     if (id != 0) {
       base::AutoLock auto_lock(lock_);
@@ -157,7 +158,7 @@
   }
 
   // Overridden from IdHandlerInterface.
-  virtual void FreeContext(GLES2Implementation* gl_impl) override {
+  void FreeContext(GLES2Implementation* gl_impl) override {
     base::AutoLock auto_lock(lock_);
     CollectPendingFreeIds(gl_impl);
   }
@@ -193,12 +194,13 @@
 class NonReusedIdHandler : public IdHandlerInterface {
  public:
   NonReusedIdHandler() : last_id_(0) {}
-  virtual ~NonReusedIdHandler() {}
+  ~NonReusedIdHandler() override {}
 
   // Overridden from IdHandlerInterface.
-  virtual void MakeIds(
-      GLES2Implementation* /* gl_impl */,
-      GLuint id_offset, GLsizei n, GLuint* ids) override {
+  void MakeIds(GLES2Implementation* /* gl_impl */,
+               GLuint id_offset,
+               GLsizei n,
+               GLuint* ids) override {
     base::AutoLock auto_lock(lock_);
     for (GLsizei ii = 0; ii < n; ++ii) {
       ids[ii] = ++last_id_ + id_offset;
@@ -206,21 +208,22 @@
   }
 
   // Overridden from IdHandlerInterface.
-  virtual bool FreeIds(
-      GLES2Implementation* gl_impl,
-      GLsizei n, const GLuint* ids, DeleteFn delete_fn) override {
+  bool FreeIds(GLES2Implementation* gl_impl,
+               GLsizei n,
+               const GLuint* ids,
+               DeleteFn delete_fn) override {
     // Ids are never freed.
     (gl_impl->*delete_fn)(n, ids);
     return true;
   }
 
   // Overridden from IdHandlerInterface.
-  virtual bool MarkAsUsedForBind(GLuint /* id */) override {
+  bool MarkAsUsedForBind(GLuint /* id */) override {
     // This is only used for Shaders and Programs which have no bind.
     return false;
   }
 
-  virtual void FreeContext(GLES2Implementation* gl_impl) override {}
+  void FreeContext(GLES2Implementation* gl_impl) override {}
 
  private:
   base::Lock lock_;
diff --git a/gpu/command_buffer/client/transfer_buffer.h b/gpu/command_buffer/client/transfer_buffer.h
index c27dd21c..39e62a6 100644
--- a/gpu/command_buffer/client/transfer_buffer.h
+++ b/gpu/command_buffer/client/transfer_buffer.h
@@ -54,26 +54,24 @@
 class GPU_EXPORT TransferBuffer : public TransferBufferInterface {
  public:
   TransferBuffer(CommandBufferHelper* helper);
-  virtual ~TransferBuffer();
+  ~TransferBuffer() override;
 
   // Overridden from TransferBufferInterface.
-  virtual bool Initialize(
-      unsigned int default_buffer_size,
-      unsigned int result_size,
-      unsigned int min_buffer_size,
-      unsigned int max_buffer_size,
-      unsigned int alignment,
-      unsigned int size_to_flush) override;
-  virtual int GetShmId() override;
-  virtual void* GetResultBuffer() override;
-  virtual int GetResultOffset() override;
-  virtual void Free() override;
-  virtual bool HaveBuffer() const override;
-  virtual void* AllocUpTo(
-      unsigned int size, unsigned int* size_allocated) override;
-  virtual void* Alloc(unsigned int size) override;
-  virtual RingBuffer::Offset GetOffset(void* pointer) const override;
-  virtual void FreePendingToken(void* p, unsigned int token) override;
+  bool Initialize(unsigned int default_buffer_size,
+                  unsigned int result_size,
+                  unsigned int min_buffer_size,
+                  unsigned int max_buffer_size,
+                  unsigned int alignment,
+                  unsigned int size_to_flush) override;
+  int GetShmId() override;
+  void* GetResultBuffer() override;
+  int GetResultOffset() override;
+  void Free() override;
+  bool HaveBuffer() const override;
+  void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
+  void* Alloc(unsigned int size) override;
+  RingBuffer::Offset GetOffset(void* pointer) const override;
+  void FreePendingToken(void* p, unsigned int token) override;
 
   // These are for testing.
   unsigned int GetCurrentMaxAllocationWithoutRealloc() const;
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index 49cb4339..37c33be0 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -222,3 +222,5 @@
 GL_APICALL void         GL_APIENTRY glMatrixLoadfCHROMIUM (GLenumMatrixMode matrixMode, const GLfloat* m);
 GL_APICALL void         GL_APIENTRY glMatrixLoadIdentityCHROMIUM (GLenumMatrixMode matrixMode);
 
+// Extension KHR_blend_equation_advanced
+GL_APICALL void GL_APIENTRY glBlendBarrierKHR (void);
diff --git a/gpu/command_buffer/command_buffer_nacl.gyp b/gpu/command_buffer/command_buffer_nacl.gyp
index aabd1c8..319fc67 100644
--- a/gpu/command_buffer/command_buffer_nacl.gyp
+++ b/gpu/command_buffer/command_buffer_nacl.gyp
@@ -23,10 +23,13 @@
             'build_glibc': 0,
             'build_newlib': 0,
             'build_irt': 1,
+            'build_pnacl_newlib': 0,
+            'build_nonsfi_helper': 1,
           },
           'dependencies': [
             '../../native_client/tools.gyp:prep_toolchain',
             '../../base/base_nacl.gyp:base_nacl',
+            '../../base/base_nacl.gyp:base_nacl_nonsfi',
             '../../third_party/khronos/khronos.gyp:khronos_headers',
           ],
         },
diff --git a/gpu/command_buffer/common/buffer.h b/gpu/command_buffer/common/buffer.h
index 6685ac5..5942f7f 100644
--- a/gpu/command_buffer/common/buffer.h
+++ b/gpu/command_buffer/common/buffer.h
@@ -28,9 +28,9 @@
  public:
   SharedMemoryBufferBacking(scoped_ptr<base::SharedMemory> shared_memory,
                             size_t size);
-  virtual ~SharedMemoryBufferBacking();
-  virtual void* GetMemory() const override;
-  virtual size_t GetSize() const override;
+  ~SharedMemoryBufferBacking() override;
+  void* GetMemory() const override;
+  size_t GetSize() const override;
   base::SharedMemory* shared_memory() { return shared_memory_.get(); }
 
  private:
diff --git a/gpu/command_buffer/common/capabilities.cc b/gpu/command_buffer/common/capabilities.cc
index f51071a..eacf10c 100644
--- a/gpu/command_buffer/common/capabilities.cc
+++ b/gpu/command_buffer/common/capabilities.cc
@@ -20,7 +20,9 @@
       sync_query(false),
       image(false),
       future_sync_points(false),
-      blend_minmax(false) {
+      blend_minmax(false),
+      blend_equation_advanced(false),
+      blend_equation_advanced_coherent(false) {
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/common/capabilities.h b/gpu/command_buffer/common/capabilities.h
index df97d1f..9de6023 100644
--- a/gpu/command_buffer/common/capabilities.h
+++ b/gpu/command_buffer/common/capabilities.h
@@ -24,6 +24,8 @@
   bool image;
   bool future_sync_points;
   bool blend_minmax;
+  bool blend_equation_advanced;
+  bool blend_equation_advanced_coherent;
 
   Capabilities();
 };
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index ccdc040a..487e8b7 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -9014,4 +9014,30 @@
 COMPILE_ASSERT(offsetof(MatrixLoadIdentityCHROMIUM, matrixMode) == 4,
                OffsetOf_MatrixLoadIdentityCHROMIUM_matrixMode_not_4);
 
+struct BlendBarrierKHR {
+  typedef BlendBarrierKHR ValueType;
+  static const CommandId kCmdId = kBlendBarrierKHR;
+  static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+  static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
+  }
+
+  void SetHeader() { header.SetCmd<ValueType>(); }
+
+  void Init() { SetHeader(); }
+
+  void* Set(void* cmd) {
+    static_cast<ValueType*>(cmd)->Init();
+    return NextCmdAddress<ValueType>(cmd);
+  }
+
+  gpu::CommandHeader header;
+};
+
+COMPILE_ASSERT(sizeof(BlendBarrierKHR) == 4, Sizeof_BlendBarrierKHR_is_not_4);
+COMPILE_ASSERT(offsetof(BlendBarrierKHR, header) == 0,
+               OffsetOf_BlendBarrierKHR_header_not_0);
+
 #endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 7b7845b..b26afb1 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -3432,4 +3432,13 @@
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
+TEST_F(GLES2FormatTest, BlendBarrierKHR) {
+  cmds::BlendBarrierKHR& cmd = *GetBufferAs<cmds::BlendBarrierKHR>();
+  void* next_cmd = cmd.Set(&cmd);
+  EXPECT_EQ(static_cast<uint32_t>(cmds::BlendBarrierKHR::kCmdId),
+            cmd.header.command);
+  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+  CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
 #endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 030ada2..8bd5c0a 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -209,7 +209,8 @@
   OP(DiscardBackbufferCHROMIUM)                /* 450 */ \
   OP(ScheduleOverlayPlaneCHROMIUM)             /* 451 */ \
   OP(MatrixLoadfCHROMIUMImmediate)             /* 452 */ \
-  OP(MatrixLoadIdentityCHROMIUM)               /* 453 */
+  OP(MatrixLoadIdentityCHROMIUM)               /* 453 */ \
+  OP(BlendBarrierKHR)                          /* 454 */
 
 enum CommandId {
   kStartPoint = cmd::kLastCommonId,  // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager.h b/gpu/command_buffer/service/async_pixel_transfer_manager.h
index 66b8bf7..3f52e1e 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager.h
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager.h
@@ -45,7 +45,7 @@
  public:
   static AsyncPixelTransferManager* Create(gfx::GLContext* context);
 
-  virtual ~AsyncPixelTransferManager();
+  ~AsyncPixelTransferManager() override;
 
   void Initialize(gles2::TextureManager* texture_manager);
 
@@ -82,9 +82,8 @@
   bool AsyncTransferIsInProgress(gles2::TextureRef* ref);
 
   // gles2::TextureRef::DestructionObserver implementation:
-  virtual void OnTextureManagerDestroying(gles2::TextureManager* manager)
-      override;
-  virtual void OnTextureRefDestroying(gles2::TextureRef* texture) override;
+  void OnTextureManagerDestroying(gles2::TextureManager* manager) override;
+  void OnTextureRefDestroying(gles2::TextureRef* texture) override;
 
  protected:
   AsyncPixelTransferManager();
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
index c43491d3..61db3b68 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.cc
@@ -36,18 +36,16 @@
       AsyncPixelTransferManagerIdle::SharedState* state,
       GLuint texture_id,
       const AsyncTexImage2DParams& define_params);
-  virtual ~AsyncPixelTransferDelegateIdle();
+  ~AsyncPixelTransferDelegateIdle() override;
 
   // Implement AsyncPixelTransferDelegate:
-  virtual void AsyncTexImage2D(
-      const AsyncTexImage2DParams& tex_params,
-      const AsyncMemoryParams& mem_params,
-      const base::Closure& bind_callback) override;
-  virtual void AsyncTexSubImage2D(
-      const AsyncTexSubImage2DParams& tex_params,
-      const AsyncMemoryParams& mem_params) override;
-  virtual bool TransferIsInProgress() override;
-  virtual void WaitForTransferCompletion() override;
+  void AsyncTexImage2D(const AsyncTexImage2DParams& tex_params,
+                       const AsyncMemoryParams& mem_params,
+                       const base::Closure& bind_callback) override;
+  void AsyncTexSubImage2D(const AsyncTexSubImage2DParams& tex_params,
+                          const AsyncMemoryParams& mem_params) override;
+  bool TransferIsInProgress() override;
+  void WaitForTransferCompletion() override;
 
  private:
   void PerformAsyncTexImage2D(AsyncTexImage2DParams tex_params,
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h
index 0ec950c..8aba7ff 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_idle.h
@@ -14,18 +14,18 @@
 class AsyncPixelTransferManagerIdle : public AsyncPixelTransferManager {
  public:
   AsyncPixelTransferManagerIdle();
-  virtual ~AsyncPixelTransferManagerIdle();
+  ~AsyncPixelTransferManagerIdle() override;
 
   // AsyncPixelTransferManager implementation:
-  virtual void BindCompletedAsyncTransfers() override;
-  virtual void AsyncNotifyCompletion(
+  void BindCompletedAsyncTransfers() override;
+  void AsyncNotifyCompletion(
       const AsyncMemoryParams& mem_params,
       AsyncPixelTransferCompletionObserver* observer) override;
-  virtual uint32 GetTextureUploadCount() override;
-  virtual base::TimeDelta GetTotalTextureUploadTime() override;
-  virtual void ProcessMorePendingTransfers() override;
-  virtual bool NeedsProcessMorePendingTransfers() override;
-  virtual void WaitAllAsyncTexImage2D() override;
+  uint32 GetTextureUploadCount() override;
+  base::TimeDelta GetTotalTextureUploadTime() override;
+  void ProcessMorePendingTransfers() override;
+  bool NeedsProcessMorePendingTransfers() override;
+  void WaitAllAsyncTexImage2D() override;
 
   struct Task {
     Task(uint64 transfer_id,
@@ -54,7 +54,7 @@
 
  private:
   // AsyncPixelTransferManager implementation:
-  virtual AsyncPixelTransferDelegate* CreatePixelTransferDelegateImpl(
+  AsyncPixelTransferDelegate* CreatePixelTransferDelegateImpl(
       gles2::TextureRef* ref,
       const AsyncTexImage2DParams& define_params) override;
 
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc
index e28ff82a..b6506bfb 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc
@@ -51,7 +51,7 @@
 #endif
   }
 
-  virtual ~TransferThread() {
+  ~TransferThread() override {
     // The only instance of this class was declared leaky.
     NOTREACHED();
   }
@@ -71,7 +71,7 @@
     wait_for_init.Wait();
   }
 
-  virtual void CleanUp() override {
+  void CleanUp() override {
     surface_ = NULL;
     context_ = NULL;
   }
@@ -377,20 +377,18 @@
       AsyncPixelTransferManagerShareGroup::SharedState* shared_state,
       GLuint texture_id,
       const AsyncTexImage2DParams& define_params);
-  virtual ~AsyncPixelTransferDelegateShareGroup();
+  ~AsyncPixelTransferDelegateShareGroup() override;
 
   void BindTransfer() { state_->BindTransfer(); }
 
   // Implement AsyncPixelTransferDelegate:
-  virtual void AsyncTexImage2D(
-      const AsyncTexImage2DParams& tex_params,
-      const AsyncMemoryParams& mem_params,
-      const base::Closure& bind_callback) override;
-  virtual void AsyncTexSubImage2D(
-      const AsyncTexSubImage2DParams& tex_params,
-      const AsyncMemoryParams& mem_params) override;
-  virtual bool TransferIsInProgress() override;
-  virtual void WaitForTransferCompletion() override;
+  void AsyncTexImage2D(const AsyncTexImage2DParams& tex_params,
+                       const AsyncMemoryParams& mem_params,
+                       const base::Closure& bind_callback) override;
+  void AsyncTexSubImage2D(const AsyncTexSubImage2DParams& tex_params,
+                          const AsyncMemoryParams& mem_params) override;
+  bool TransferIsInProgress() override;
+  void WaitForTransferCompletion() override;
 
  private:
   // A raw pointer is safe because the SharedState is owned by the Manager,
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.h b/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.h
index 9f9f04e..081fcc4 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.h
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.h
@@ -20,18 +20,18 @@
 class AsyncPixelTransferManagerShareGroup : public AsyncPixelTransferManager {
  public:
   explicit AsyncPixelTransferManagerShareGroup(gfx::GLContext* context);
-  virtual ~AsyncPixelTransferManagerShareGroup();
+  ~AsyncPixelTransferManagerShareGroup() override;
 
   // AsyncPixelTransferManager implementation:
-  virtual void BindCompletedAsyncTransfers() override;
-  virtual void AsyncNotifyCompletion(
+  void BindCompletedAsyncTransfers() override;
+  void AsyncNotifyCompletion(
       const AsyncMemoryParams& mem_params,
       AsyncPixelTransferCompletionObserver* observer) override;
-  virtual uint32 GetTextureUploadCount() override;
-  virtual base::TimeDelta GetTotalTextureUploadTime() override;
-  virtual void ProcessMorePendingTransfers() override;
-  virtual bool NeedsProcessMorePendingTransfers() override;
-  virtual void WaitAllAsyncTexImage2D() override;
+  uint32 GetTextureUploadCount() override;
+  base::TimeDelta GetTotalTextureUploadTime() override;
+  void ProcessMorePendingTransfers() override;
+  bool NeedsProcessMorePendingTransfers() override;
+  void WaitAllAsyncTexImage2D() override;
 
   // State shared between Managers and Delegates.
   struct SharedState {
@@ -46,7 +46,7 @@
 
  private:
   // AsyncPixelTransferManager implementation:
-  virtual AsyncPixelTransferDelegate* CreatePixelTransferDelegateImpl(
+  AsyncPixelTransferDelegate* CreatePixelTransferDelegateImpl(
       gles2::TextureRef* ref,
       const AsyncTexImage2DParams& define_params) override;
 
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_stub.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_stub.cc
index 4b8ce1d..a2fbc8e 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_stub.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_stub.cc
@@ -11,18 +11,16 @@
 class AsyncPixelTransferDelegateStub : public AsyncPixelTransferDelegate {
  public:
   AsyncPixelTransferDelegateStub();
-  virtual ~AsyncPixelTransferDelegateStub();
+  ~AsyncPixelTransferDelegateStub() override;
 
   // Implement AsyncPixelTransferDelegate:
-  virtual void AsyncTexImage2D(
-      const AsyncTexImage2DParams& tex_params,
-      const AsyncMemoryParams& mem_params,
-      const base::Closure& bind_callback) override;
-  virtual void AsyncTexSubImage2D(
-      const AsyncTexSubImage2DParams& tex_params,
-      const AsyncMemoryParams& mem_params) override;
-  virtual bool TransferIsInProgress() override;
-  virtual void WaitForTransferCompletion() override;
+  void AsyncTexImage2D(const AsyncTexImage2DParams& tex_params,
+                       const AsyncMemoryParams& mem_params,
+                       const base::Closure& bind_callback) override;
+  void AsyncTexSubImage2D(const AsyncTexSubImage2DParams& tex_params,
+                          const AsyncMemoryParams& mem_params) override;
+  bool TransferIsInProgress() override;
+  void WaitForTransferCompletion() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateStub);
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_stub.h b/gpu/command_buffer/service/async_pixel_transfer_manager_stub.h
index c2fa3eb..f8ced57 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_stub.h
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_stub.h
@@ -12,22 +12,22 @@
 class AsyncPixelTransferManagerStub : public AsyncPixelTransferManager {
  public:
   AsyncPixelTransferManagerStub();
-  virtual ~AsyncPixelTransferManagerStub();
+  ~AsyncPixelTransferManagerStub() override;
 
   // AsyncPixelTransferManager implementation:
-  virtual void BindCompletedAsyncTransfers() override;
-  virtual void AsyncNotifyCompletion(
+  void BindCompletedAsyncTransfers() override;
+  void AsyncNotifyCompletion(
       const AsyncMemoryParams& mem_params,
       AsyncPixelTransferCompletionObserver* observer) override;
-  virtual uint32 GetTextureUploadCount() override;
-  virtual base::TimeDelta GetTotalTextureUploadTime() override;
-  virtual void ProcessMorePendingTransfers() override;
-  virtual bool NeedsProcessMorePendingTransfers() override;
-  virtual void WaitAllAsyncTexImage2D() override;
+  uint32 GetTextureUploadCount() override;
+  base::TimeDelta GetTotalTextureUploadTime() override;
+  void ProcessMorePendingTransfers() override;
+  bool NeedsProcessMorePendingTransfers() override;
+  void WaitAllAsyncTexImage2D() override;
 
  private:
   // AsyncPixelTransferManager implementation:
-  virtual AsyncPixelTransferDelegate* CreatePixelTransferDelegateImpl(
+  AsyncPixelTransferDelegate* CreatePixelTransferDelegateImpl(
       gles2::TextureRef* ref,
       const AsyncTexImage2DParams& define_params) override;
 
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc
index b5851d2..4bc2ba2 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_sync.cc
@@ -13,18 +13,16 @@
  public:
   explicit AsyncPixelTransferDelegateSync(
       AsyncPixelTransferManagerSync::SharedState* shared_state);
-  virtual ~AsyncPixelTransferDelegateSync();
+  ~AsyncPixelTransferDelegateSync() override;
 
   // Implement AsyncPixelTransferDelegate:
-  virtual void AsyncTexImage2D(
-      const AsyncTexImage2DParams& tex_params,
-      const AsyncMemoryParams& mem_params,
-      const base::Closure& bind_callback) override;
-  virtual void AsyncTexSubImage2D(
-      const AsyncTexSubImage2DParams& tex_params,
-      const AsyncMemoryParams& mem_params) override;
-  virtual bool TransferIsInProgress() override;
-  virtual void WaitForTransferCompletion() override;
+  void AsyncTexImage2D(const AsyncTexImage2DParams& tex_params,
+                       const AsyncMemoryParams& mem_params,
+                       const base::Closure& bind_callback) override;
+  void AsyncTexSubImage2D(const AsyncTexSubImage2DParams& tex_params,
+                          const AsyncMemoryParams& mem_params) override;
+  bool TransferIsInProgress() override;
+  void WaitForTransferCompletion() override;
 
  private:
   // Safe to hold a raw pointer because SharedState is owned by the Manager
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_sync.h b/gpu/command_buffer/service/async_pixel_transfer_manager_sync.h
index a08e915..b965d6f4 100644
--- a/gpu/command_buffer/service/async_pixel_transfer_manager_sync.h
+++ b/gpu/command_buffer/service/async_pixel_transfer_manager_sync.h
@@ -12,18 +12,18 @@
 class AsyncPixelTransferManagerSync : public AsyncPixelTransferManager {
  public:
   AsyncPixelTransferManagerSync();
-  virtual ~AsyncPixelTransferManagerSync();
+  ~AsyncPixelTransferManagerSync() override;
 
   // AsyncPixelTransferManager implementation:
-  virtual void BindCompletedAsyncTransfers() override;
-  virtual void AsyncNotifyCompletion(
+  void BindCompletedAsyncTransfers() override;
+  void AsyncNotifyCompletion(
       const AsyncMemoryParams& mem_params,
       AsyncPixelTransferCompletionObserver* observer) override;
-  virtual uint32 GetTextureUploadCount() override;
-  virtual base::TimeDelta GetTotalTextureUploadTime() override;
-  virtual void ProcessMorePendingTransfers() override;
-  virtual bool NeedsProcessMorePendingTransfers() override;
-  virtual void WaitAllAsyncTexImage2D() override;
+  uint32 GetTextureUploadCount() override;
+  base::TimeDelta GetTotalTextureUploadTime() override;
+  void ProcessMorePendingTransfers() override;
+  bool NeedsProcessMorePendingTransfers() override;
+  void WaitAllAsyncTexImage2D() override;
 
   // State shared between Managers and Delegates.
   struct SharedState {
@@ -36,7 +36,7 @@
 
  private:
   // AsyncPixelTransferManager implementation:
-  virtual AsyncPixelTransferDelegate* CreatePixelTransferDelegateImpl(
+  AsyncPixelTransferDelegate* CreatePixelTransferDelegateImpl(
       gles2::TextureRef* ref,
       const AsyncTexImage2DParams& define_params) override;
 
diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h
index e3e2ebd..15f865f 100644
--- a/gpu/command_buffer/service/command_buffer_service.h
+++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -42,26 +42,25 @@
   typedef base::Callback<bool(int32)> GetBufferChangedCallback;
   explicit CommandBufferService(
       TransferBufferManagerInterface* transfer_buffer_manager);
-  virtual ~CommandBufferService();
+  ~CommandBufferService() override;
 
   // CommandBuffer implementation:
-  virtual bool Initialize() override;
-  virtual State GetLastState() override;
-  virtual int32 GetLastToken() override;
-  virtual void Flush(int32 put_offset) override;
-  virtual void WaitForTokenInRange(int32 start, int32 end) override;
-  virtual void WaitForGetOffsetInRange(int32 start, int32 end) override;
-  virtual void SetGetBuffer(int32 transfer_buffer_id) override;
-  virtual scoped_refptr<Buffer> CreateTransferBuffer(size_t size,
-                                                     int32* id) override;
-  virtual void DestroyTransferBuffer(int32 id) override;
+  bool Initialize() override;
+  State GetLastState() override;
+  int32 GetLastToken() override;
+  void Flush(int32 put_offset) override;
+  void WaitForTokenInRange(int32 start, int32 end) override;
+  void WaitForGetOffsetInRange(int32 start, int32 end) override;
+  void SetGetBuffer(int32 transfer_buffer_id) override;
+  scoped_refptr<Buffer> CreateTransferBuffer(size_t size, int32* id) override;
+  void DestroyTransferBuffer(int32 id) override;
 
   // CommandBufferServiceBase implementation:
-  virtual void SetGetOffset(int32 get_offset) override;
-  virtual scoped_refptr<Buffer> GetTransferBuffer(int32 id) override;
-  virtual void SetToken(int32 token) override;
-  virtual void SetParseError(error::Error error) override;
-  virtual void SetContextLostReason(error::ContextLostReason) override;
+  void SetGetOffset(int32 get_offset) override;
+  scoped_refptr<Buffer> GetTransferBuffer(int32 id) override;
+  void SetToken(int32 token) override;
+  void SetParseError(error::Error error) override;
+  void SetContextLostReason(error::ContextLostReason) override;
 
   // Sets a callback that is called whenever the put offset is changed. When
   // called with sync==true, the callback must not return until some progress
diff --git a/gpu/command_buffer/service/common_decoder.h b/gpu/command_buffer/service/common_decoder.h
index 2132afbf..aaf860f 100644
--- a/gpu/command_buffer/service/common_decoder.h
+++ b/gpu/command_buffer/service/common_decoder.h
@@ -95,7 +95,7 @@
   };
 
   CommonDecoder();
-  virtual ~CommonDecoder();
+  ~CommonDecoder() override;
 
   // Sets the engine, to get shared memory buffers from, and to set the token
   // to.
diff --git a/gpu/command_buffer/service/common_decoder_unittest.cc b/gpu/command_buffer/service/common_decoder_unittest.cc
index cc965cd9..aa1ed1bc 100644
--- a/gpu/command_buffer/service/common_decoder_unittest.cc
+++ b/gpu/command_buffer/service/common_decoder_unittest.cc
@@ -51,15 +51,14 @@
 class TestCommonDecoder : public CommonDecoder {
  public:
   // Overridden from AsyncAPIInterface
-  virtual const char* GetCommandName(unsigned int command_id) const override {
+  const char* GetCommandName(unsigned int command_id) const override {
     return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
   }
 
   // Overridden from AsyncAPIInterface
-  virtual error::Error DoCommand(
-      unsigned int command,
-      unsigned int arg_count,
-      const void* cmd_data) override {
+  error::Error DoCommand(unsigned int command,
+                         unsigned int arg_count,
+                         const void* cmd_data) override {
     return DoCommonCommand(command, arg_count, cmd_data);
   }
 
@@ -87,8 +86,7 @@
   }
 
   // Overridden from CommandBufferEngine.
-  virtual scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id)
-      override {
+  scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id) override {
     if (IsValidSharedMemoryId(shm_id))
       return buffer_;
     return NULL;
@@ -110,22 +108,20 @@
   }
 
   // Overridden from CommandBufferEngine.
-  virtual void set_token(int32 token) override {
-    token_ = token;
-  }
+  void set_token(int32 token) override { token_ = token; }
 
   int32 token() const {
     return token_;
   }
 
   // Overridden from CommandBufferEngine.
-  virtual bool SetGetBuffer(int32 transfer_buffer_id) override {
+  bool SetGetBuffer(int32 transfer_buffer_id) override {
     NOTREACHED();
     return false;
   }
 
   // Overridden from CommandBufferEngine.
-  virtual bool SetGetOffset(int32 offset) override {
+  bool SetGetOffset(int32 offset) override {
     if (static_cast<size_t>(offset) < kBufferSize) {
       get_offset_ = offset;
       return true;
@@ -134,9 +130,7 @@
   }
 
   // Overridden from CommandBufferEngine.
-  virtual int32 GetGetOffset() override {
-    return get_offset_;
-  }
+  int32 GetGetOffset() override { return get_offset_; }
 
  private:
   bool IsValidSharedMemoryId(int32 shm_id) {
diff --git a/gpu/command_buffer/service/error_state.cc b/gpu/command_buffer/service/error_state.cc
index c71a159..42131aa 100644
--- a/gpu/command_buffer/service/error_state.cc
+++ b/gpu/command_buffer/service/error_state.cc
@@ -17,45 +17,44 @@
 class ErrorStateImpl : public ErrorState {
  public:
   explicit ErrorStateImpl(ErrorStateClient* client, Logger* logger);
-  virtual ~ErrorStateImpl();
+  ~ErrorStateImpl() override;
 
-  virtual uint32 GetGLError() override;
+  uint32 GetGLError() override;
 
-  virtual void SetGLError(
-      const char* filename,
-      int line,
-      unsigned int error,
-      const char* function_name,
-      const char* msg) override;
-  virtual void SetGLErrorInvalidEnum(
-      const char* filename,
-      int line,
-      const char* function_name,
-      unsigned int value,
-      const char* label) override;
-  virtual void SetGLErrorInvalidParami(
-      const char* filename,
-      int line,
-      unsigned int error,
-      const char* function_name,
-      unsigned int pname,
-      int param) override;
-  virtual void SetGLErrorInvalidParamf(
-      const char* filename,
-      int line,
-      unsigned int error,
-      const char* function_name,
-      unsigned int pname,
-      float param) override;
+  void SetGLError(const char* filename,
+                  int line,
+                  unsigned int error,
+                  const char* function_name,
+                  const char* msg) override;
+  void SetGLErrorInvalidEnum(const char* filename,
+                             int line,
+                             const char* function_name,
+                             unsigned int value,
+                             const char* label) override;
+  void SetGLErrorInvalidParami(const char* filename,
+                               int line,
+                               unsigned int error,
+                               const char* function_name,
+                               unsigned int pname,
+                               int param) override;
+  void SetGLErrorInvalidParamf(const char* filename,
+                               int line,
+                               unsigned int error,
+                               const char* function_name,
+                               unsigned int pname,
+                               float param) override;
 
-  virtual unsigned int PeekGLError(
-      const char* filename, int line, const char* function_name) override;
+  unsigned int PeekGLError(const char* filename,
+                           int line,
+                           const char* function_name) override;
 
-  virtual void CopyRealGLErrorsToWrapper(
-      const char* filename, int line, const char* function_name) override;
+  void CopyRealGLErrorsToWrapper(const char* filename,
+                                 int line,
+                                 const char* function_name) override;
 
-  virtual void ClearRealGLErrors(
-      const char* filename, int line, const char* function_name) override;
+  void ClearRealGLErrors(const char* filename,
+                         int line,
+                         const char* function_name) override;
 
  private:
   // The last error message set.
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index bda7a820..a21f630 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -144,7 +144,9 @@
       angle_texture_usage(false),
       ext_texture_storage(false),
       chromium_path_rendering(false),
-      ext_blend_minmax(false) {
+      ext_blend_minmax(false),
+      blend_equation_advanced(false),
+      blend_equation_advanced_coherent(false) {
 }
 
 FeatureInfo::Workarounds::Workarounds() :
@@ -880,6 +882,40 @@
     feature_flags_.chromium_sync_query = true;
   }
 
+  bool blend_equation_advanced_coherent =
+    extensions.Contains("GL_NV_blend_equation_advanced_coherent") ||
+    extensions.Contains("GL_KHR_blend_equation_advanced_coherent");
+
+  if (blend_equation_advanced_coherent ||
+      extensions.Contains("GL_NV_blend_equation_advanced") ||
+      extensions.Contains("GL_KHR_blend_equation_advanced")) {
+    const GLenum equations[] = {GL_MULTIPLY_KHR,
+                                GL_SCREEN_KHR,
+                                GL_OVERLAY_KHR,
+                                GL_DARKEN_KHR,
+                                GL_LIGHTEN_KHR,
+                                GL_COLORDODGE_KHR,
+                                GL_COLORBURN_KHR,
+                                GL_HARDLIGHT_KHR,
+                                GL_SOFTLIGHT_KHR,
+                                GL_DIFFERENCE_KHR,
+                                GL_EXCLUSION_KHR,
+                                GL_HSL_HUE_KHR,
+                                GL_HSL_SATURATION_KHR,
+                                GL_HSL_COLOR_KHR,
+                                GL_HSL_LUMINOSITY_KHR};
+
+    for (GLenum equation : equations)
+      validators_.equation.AddValue(equation);
+    if (blend_equation_advanced_coherent)
+      AddExtensionString("GL_KHR_blend_equation_advanced_coherent");
+
+    AddExtensionString("GL_KHR_blend_equation_advanced");
+    feature_flags_.blend_equation_advanced = true;
+    feature_flags_.blend_equation_advanced_coherent =
+      blend_equation_advanced_coherent;
+  }
+
   if (extensions.Contains("GL_NV_path_rendering")) {
     if (extensions.Contains("GL_EXT_direct_state_access") || is_es3) {
       AddExtensionString("GL_CHROMIUM_path_rendering");
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index a30581a..0bc00a0 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -72,6 +72,8 @@
     bool ext_texture_storage;
     bool chromium_path_rendering;
     bool ext_blend_minmax;
+    bool blend_equation_advanced;
+    bool blend_equation_advanced_coherent;
   };
 
   struct Workarounds {
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index 004eeeee..a97188f 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -1347,5 +1347,39 @@
               Not(HasSubstr("GL_CHROMIUM_path_rendering")));
 }
 
+TEST_F(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced) {
+  SetupInitExpectationsWithGLVersion("", "", "4.3");
+  EXPECT_FALSE(info_->feature_flags().blend_equation_advanced);
+  EXPECT_THAT(info_->extensions(),
+              Not(HasSubstr("GL_KHR_blend_equation_advanced")));
+}
+
+TEST_F(FeatureInfoTest, InitializeKHR_blend_equations_advanced) {
+  SetupInitExpectations("GL_KHR_blend_equation_advanced");
+  EXPECT_THAT(info_->extensions(), HasSubstr("GL_KHR_blend_equation_advanced"));
+  EXPECT_TRUE(info_->feature_flags().blend_equation_advanced);
+}
+
+TEST_F(FeatureInfoTest, InitializeNV_blend_equations_advanced) {
+  SetupInitExpectations("GL_NV_blend_equation_advanced");
+  EXPECT_THAT(info_->extensions(), HasSubstr("GL_KHR_blend_equation_advanced"));
+  EXPECT_TRUE(info_->feature_flags().blend_equation_advanced);
+}
+
+TEST_F(FeatureInfoTest, InitializeNoKHR_blend_equation_advanced_coherent) {
+  SetupInitExpectationsWithGLVersion("", "", "4.3");
+  EXPECT_FALSE(info_->feature_flags().blend_equation_advanced_coherent);
+  EXPECT_THAT(info_->extensions(),
+              Not(HasSubstr("GL_KHR_blend_equation_advanced_coherent")));
+}
+
+TEST_F(FeatureInfoTest, InitializeKHR_blend_equations_advanced_coherent) {
+  SetupInitExpectations("GL_KHR_blend_equation_advanced_coherent");
+  EXPECT_THAT(info_->extensions(),
+              HasSubstr("GL_KHR_blend_equation_advanced_coherent"));
+  EXPECT_TRUE(info_->feature_flags().blend_equation_advanced);
+  EXPECT_TRUE(info_->feature_flags().blend_equation_advanced_coherent);
+}
+
 }  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc
index 60f3ac9..d766abb 100644
--- a/gpu/command_buffer/service/framebuffer_manager.cc
+++ b/gpu/command_buffer/service/framebuffer_manager.cc
@@ -48,61 +48,42 @@
       : renderbuffer_(renderbuffer) {
   }
 
-  virtual GLsizei width() const override {
-    return renderbuffer_->width();
-  }
+  GLsizei width() const override { return renderbuffer_->width(); }
 
-  virtual GLsizei height() const override {
-    return renderbuffer_->height();
-  }
+  GLsizei height() const override { return renderbuffer_->height(); }
 
-  virtual GLenum internal_format() const override {
+  GLenum internal_format() const override {
     return renderbuffer_->internal_format();
   }
 
-  virtual GLenum texture_type() const override {
-    return 0;
-  }
+  GLenum texture_type() const override { return 0; }
 
-  virtual GLsizei samples() const override {
-    return renderbuffer_->samples();
-  }
+  GLsizei samples() const override { return renderbuffer_->samples(); }
 
-  virtual GLuint object_name() const override {
-    return renderbuffer_->client_id();
-  }
+  GLuint object_name() const override { return renderbuffer_->client_id(); }
 
-  virtual bool cleared() const override {
-    return renderbuffer_->cleared();
-  }
+  bool cleared() const override { return renderbuffer_->cleared(); }
 
-  virtual void SetCleared(
-      RenderbufferManager* renderbuffer_manager,
-      TextureManager* /* texture_manager */,
-      bool cleared) override {
+  void SetCleared(RenderbufferManager* renderbuffer_manager,
+                  TextureManager* /* texture_manager */,
+                  bool cleared) override {
     renderbuffer_manager->SetCleared(renderbuffer_.get(), cleared);
   }
 
-  virtual bool IsTexture(
-      TextureRef* /* texture */) const override {
-    return false;
-  }
+  bool IsTexture(TextureRef* /* texture */) const override { return false; }
 
-  virtual bool IsRenderbuffer(
-       Renderbuffer* renderbuffer) const override {
+  bool IsRenderbuffer(Renderbuffer* renderbuffer) const override {
     return renderbuffer_.get() == renderbuffer;
   }
 
-  virtual bool CanRenderTo() const override {
-    return true;
-  }
+  bool CanRenderTo() const override { return true; }
 
-  virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const override {
+  void DetachFromFramebuffer(Framebuffer* framebuffer) const override {
     // Nothing to do for renderbuffers.
   }
 
-  virtual bool ValidForAttachmentType(
-      GLenum attachment_type, uint32 max_color_attachments) override {
+  bool ValidForAttachmentType(GLenum attachment_type,
+                              uint32 max_color_attachments) override {
     uint32 need = GLES2Util::GetChannelsNeededForAttachmentType(
         attachment_type, max_color_attachments);
     uint32 have = GLES2Util::GetChannelsForFormat(internal_format());
@@ -113,26 +94,25 @@
     return renderbuffer_.get();
   }
 
-  virtual size_t GetSignatureSize(
-      TextureManager* texture_manager) const override {
+  size_t GetSignatureSize(TextureManager* texture_manager) const override {
     return renderbuffer_->GetSignatureSize();
   }
 
-  virtual void AddToSignature(
-      TextureManager* texture_manager, std::string* signature) const override {
+  void AddToSignature(TextureManager* texture_manager,
+                      std::string* signature) const override {
     DCHECK(signature);
     renderbuffer_->AddToSignature(signature);
   }
 
-  virtual void OnWillRenderTo() const override {}
-  virtual void OnDidRenderTo() const override {}
-  virtual bool FormsFeedbackLoop(
-      TextureRef* /* texture */, GLint /*level */) const override {
+  void OnWillRenderTo() const override {}
+  void OnDidRenderTo() const override {}
+  bool FormsFeedbackLoop(TextureRef* /* texture */,
+                         GLint /*level */) const override {
     return false;
   }
 
  protected:
-  virtual ~RenderbufferAttachment() { }
+  ~RenderbufferAttachment() override {}
 
  private:
   scoped_refptr<Renderbuffer> renderbuffer_;
@@ -151,7 +131,7 @@
         samples_(samples) {
   }
 
-  virtual GLsizei width() const override {
+  GLsizei width() const override {
     GLsizei temp_width = 0;
     GLsizei temp_height = 0;
     texture_ref_->texture()->GetLevelSize(
@@ -159,7 +139,7 @@
     return temp_width;
   }
 
-  virtual GLsizei height() const override {
+  GLsizei height() const override {
     GLsizei temp_width = 0;
     GLsizei temp_height = 0;
     texture_ref_->texture()->GetLevelSize(
@@ -167,7 +147,7 @@
     return temp_height;
   }
 
-  virtual GLenum internal_format() const override {
+  GLenum internal_format() const override {
     GLenum temp_type = 0;
     GLenum temp_internal_format = 0;
     texture_ref_->texture()->GetLevelType(
@@ -175,7 +155,7 @@
     return temp_internal_format;
   }
 
-  virtual GLenum texture_type() const override {
+  GLenum texture_type() const override {
     GLenum temp_type = 0;
     GLenum temp_internal_format = 0;
     texture_ref_->texture()->GetLevelType(
@@ -183,33 +163,26 @@
     return temp_type;
   }
 
-  virtual GLsizei samples() const override {
-    return samples_;
-  }
+  GLsizei samples() const override { return samples_; }
 
-  virtual GLuint object_name() const override {
-    return texture_ref_->client_id();
-  }
+  GLuint object_name() const override { return texture_ref_->client_id(); }
 
-  virtual bool cleared() const override {
+  bool cleared() const override {
     return texture_ref_->texture()->IsLevelCleared(target_, level_);
   }
 
-  virtual void SetCleared(
-      RenderbufferManager* /* renderbuffer_manager */,
-      TextureManager* texture_manager,
-      bool cleared) override {
+  void SetCleared(RenderbufferManager* /* renderbuffer_manager */,
+                  TextureManager* texture_manager,
+                  bool cleared) override {
     texture_manager->SetLevelCleared(
         texture_ref_.get(), target_, level_, cleared);
   }
 
-  virtual bool IsTexture(TextureRef* texture) const override {
+  bool IsTexture(TextureRef* texture) const override {
     return texture == texture_ref_.get();
   }
 
-  virtual bool IsRenderbuffer(
-       Renderbuffer* /* renderbuffer */)
-          const override {
+  bool IsRenderbuffer(Renderbuffer* /* renderbuffer */) const override {
     return false;
   }
 
@@ -217,18 +190,17 @@
     return texture_ref_.get();
   }
 
-  virtual bool CanRenderTo() const override {
+  bool CanRenderTo() const override {
     return texture_ref_->texture()->CanRenderTo();
   }
 
-  virtual void DetachFromFramebuffer(Framebuffer* framebuffer)
-      const override {
+  void DetachFromFramebuffer(Framebuffer* framebuffer) const override {
     texture_ref_->texture()->DetachFromFramebuffer();
     framebuffer->OnTextureRefDetached(texture_ref_.get());
   }
 
-  virtual bool ValidForAttachmentType(
-      GLenum attachment_type, uint32 max_color_attachments) override {
+  bool ValidForAttachmentType(GLenum attachment_type,
+                              uint32 max_color_attachments) override {
     GLenum type = 0;
     GLenum internal_format = 0;
     if (!texture_ref_->texture()->GetLevelType(
@@ -248,33 +220,31 @@
     return (need & have) != 0;
   }
 
-  virtual size_t GetSignatureSize(
-      TextureManager* texture_manager) const override {
+  size_t GetSignatureSize(TextureManager* texture_manager) const override {
     return texture_manager->GetSignatureSize();
   }
 
-  virtual void AddToSignature(
-      TextureManager* texture_manager, std::string* signature) const override {
+  void AddToSignature(TextureManager* texture_manager,
+                      std::string* signature) const override {
     DCHECK(signature);
     texture_manager->AddToSignature(
         texture_ref_.get(), target_, level_, signature);
   }
 
-  virtual void OnWillRenderTo() const override {
+  void OnWillRenderTo() const override {
     texture_ref_->texture()->OnWillModifyPixels();
   }
 
-  virtual void OnDidRenderTo() const override {
+  void OnDidRenderTo() const override {
     texture_ref_->texture()->OnDidModifyPixels();
   }
 
-  virtual bool FormsFeedbackLoop(
-      TextureRef* texture, GLint level) const override {
+  bool FormsFeedbackLoop(TextureRef* texture, GLint level) const override {
     return texture == texture_ref_.get() && level == level_;
   }
 
  protected:
-  virtual ~TextureAttachment() {}
+  ~TextureAttachment() override {}
 
  private:
   scoped_refptr<TextureRef> texture_ref_;
diff --git a/gpu/command_buffer/service/gl_context_virtual.h b/gpu/command_buffer/service/gl_context_virtual.h
index 76f4021..ed61016 100644
--- a/gpu/command_buffer/service/gl_context_virtual.h
+++ b/gpu/command_buffer/service/gl_context_virtual.h
@@ -34,23 +34,22 @@
   gfx::Display* display();
 
   // Implement GLContext.
-  virtual bool Initialize(
-      gfx::GLSurface* compatible_surface,
-      gfx::GpuPreference gpu_preference) override;
-  virtual void Destroy() override;
-  virtual bool MakeCurrent(gfx::GLSurface* surface) override;
-  virtual void ReleaseCurrent(gfx::GLSurface* surface) override;
-  virtual bool IsCurrent(gfx::GLSurface* surface) override;
-  virtual void* GetHandle() override;
-  virtual void SetSwapInterval(int interval) override;
-  virtual std::string GetExtensions() override;
-  virtual bool GetTotalGpuMemory(size_t* bytes) override;
-  virtual void SetSafeToForceGpuSwitch() override;
-  virtual bool WasAllocatedUsingRobustnessExtension() override;
-  virtual void SetUnbindFboOnMakeCurrent() override;
+  bool Initialize(gfx::GLSurface* compatible_surface,
+                  gfx::GpuPreference gpu_preference) override;
+  void Destroy() override;
+  bool MakeCurrent(gfx::GLSurface* surface) override;
+  void ReleaseCurrent(gfx::GLSurface* surface) override;
+  bool IsCurrent(gfx::GLSurface* surface) override;
+  void* GetHandle() override;
+  void SetSwapInterval(int interval) override;
+  std::string GetExtensions() override;
+  bool GetTotalGpuMemory(size_t* bytes) override;
+  void SetSafeToForceGpuSwitch() override;
+  bool WasAllocatedUsingRobustnessExtension() override;
+  void SetUnbindFboOnMakeCurrent() override;
 
  protected:
-  virtual ~GLContextVirtual();
+  ~GLContextVirtual() override;
 
  private:
   scoped_refptr<gfx::GLContext> shared_context_;
diff --git a/gpu/command_buffer/service/gl_state_restorer_impl.h b/gpu/command_buffer/service/gl_state_restorer_impl.h
index b8ccc44..91d3408 100644
--- a/gpu/command_buffer/service/gl_state_restorer_impl.h
+++ b/gpu/command_buffer/service/gl_state_restorer_impl.h
@@ -22,13 +22,13 @@
 class GPU_EXPORT GLStateRestorerImpl : public gfx::GLStateRestorer {
  public:
    explicit GLStateRestorerImpl(base::WeakPtr<gles2::GLES2Decoder> decoder);
-   virtual ~GLStateRestorerImpl();
+   ~GLStateRestorerImpl() override;
 
-   virtual bool IsInitialized() override;
-   virtual void RestoreState(const gfx::GLStateRestorer* prev_state) override;
-   virtual void RestoreAllTextureUnitBindings() override;
-   virtual void RestoreActiveTextureUnitBinding(unsigned int target) override;
-   virtual void RestoreFramebufferBindings() override;
+   bool IsInitialized() override;
+   void RestoreState(const gfx::GLStateRestorer* prev_state) override;
+   void RestoreAllTextureUnitBindings() override;
+   void RestoreActiveTextureUnitBinding(unsigned int target) override;
+   void RestoreFramebufferBindings() override;
 
  private:
    const gles2::ContextState* GetContextState() const;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 6253cc8..01d20c7f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -511,7 +511,7 @@
       : async_upload_token_(async_upload_token) {
   }
 
-  virtual void DidComplete(const AsyncMemoryParams& mem_params) override {
+  void DidComplete(const AsyncMemoryParams& mem_params) override {
     DCHECK(mem_params.buffer().get());
     void* data = mem_params.GetDataAddress();
     AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
@@ -519,8 +519,7 @@
   }
 
  private:
-  virtual ~AsyncUploadTokenCompletionObserver() {
-  }
+  ~AsyncUploadTokenCompletionObserver() override {}
 
   uint32 async_upload_token_;
 
@@ -558,17 +557,17 @@
                          public ErrorStateClient {
  public:
   explicit GLES2DecoderImpl(ContextGroup* group);
-  virtual ~GLES2DecoderImpl();
+  ~GLES2DecoderImpl() override;
 
   // Overridden from AsyncAPIInterface.
-  virtual Error DoCommand(unsigned int command,
-                          unsigned int arg_count,
-                          const void* args) override;
+  Error DoCommand(unsigned int command,
+                  unsigned int arg_count,
+                  const void* args) override;
 
-  virtual error::Error DoCommands(unsigned int num_commands,
-                                  const void* buffer,
-                                  int num_entries,
-                                  int* entries_processed) override;
+  error::Error DoCommands(unsigned int num_commands,
+                          const void* buffer,
+                          int num_entries,
+                          int* entries_processed) override;
 
   template <bool DebugImpl>
   error::Error DoCommandsImpl(unsigned int num_commands,
@@ -577,104 +576,91 @@
                               int* entries_processed);
 
   // Overridden from AsyncAPIInterface.
-  virtual const char* GetCommandName(unsigned int command_id) const override;
+  const char* GetCommandName(unsigned int command_id) const override;
 
   // Overridden from GLES2Decoder.
-  virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
-                          const scoped_refptr<gfx::GLContext>& context,
-                          bool offscreen,
-                          const gfx::Size& size,
-                          const DisallowedFeatures& disallowed_features,
-                          const std::vector<int32>& attribs) override;
-  virtual void Destroy(bool have_context) override;
-  virtual void SetSurface(
-      const scoped_refptr<gfx::GLSurface>& surface) override;
-  virtual void ProduceFrontBuffer(const Mailbox& mailbox) override;
-  virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
+  bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
+                  const scoped_refptr<gfx::GLContext>& context,
+                  bool offscreen,
+                  const gfx::Size& size,
+                  const DisallowedFeatures& disallowed_features,
+                  const std::vector<int32>& attribs) override;
+  void Destroy(bool have_context) override;
+  void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
+  void ProduceFrontBuffer(const Mailbox& mailbox) override;
+  bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
   void UpdateParentTextureInfo();
-  virtual bool MakeCurrent() override;
-  virtual GLES2Util* GetGLES2Util() override { return &util_; }
-  virtual gfx::GLContext* GetGLContext() override { return context_.get(); }
-  virtual ContextGroup* GetContextGroup() override { return group_.get(); }
-  virtual Capabilities GetCapabilities() override;
-  virtual void RestoreState(const ContextState* prev_state) override;
+  bool MakeCurrent() override;
+  GLES2Util* GetGLES2Util() override { return &util_; }
+  gfx::GLContext* GetGLContext() override { return context_.get(); }
+  ContextGroup* GetContextGroup() override { return group_.get(); }
+  Capabilities GetCapabilities() override;
+  void RestoreState(const ContextState* prev_state) override;
 
-  virtual void RestoreActiveTexture() const override {
-    state_.RestoreActiveTexture();
-  }
-  virtual void RestoreAllTextureUnitBindings(
+  void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
+  void RestoreAllTextureUnitBindings(
       const ContextState* prev_state) const override {
     state_.RestoreAllTextureUnitBindings(prev_state);
   }
-  virtual void RestoreActiveTextureUnitBinding(
-      unsigned int target) const override {
+  void RestoreActiveTextureUnitBinding(unsigned int target) const override {
     state_.RestoreActiveTextureUnitBinding(target);
   }
-  virtual void RestoreBufferBindings() const override {
+  void RestoreBufferBindings() const override {
     state_.RestoreBufferBindings();
   }
-  virtual void RestoreGlobalState() const override {
-    state_.RestoreGlobalState(NULL);
-  }
-  virtual void RestoreProgramBindings() const override {
+  void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
+  void RestoreProgramBindings() const override {
     state_.RestoreProgramBindings();
   }
-  virtual void RestoreTextureUnitBindings(unsigned unit) const override {
+  void RestoreTextureUnitBindings(unsigned unit) const override {
     state_.RestoreTextureUnitBindings(unit, NULL);
   }
-  virtual void RestoreFramebufferBindings() const override;
-  virtual void RestoreRenderbufferBindings() override;
-  virtual void RestoreTextureState(unsigned service_id) const override;
+  void RestoreFramebufferBindings() const override;
+  void RestoreRenderbufferBindings() override;
+  void RestoreTextureState(unsigned service_id) const override;
 
-  virtual void ClearAllAttributes() const override;
-  virtual void RestoreAllAttributes() const override;
+  void ClearAllAttributes() const override;
+  void RestoreAllAttributes() const override;
 
-  virtual QueryManager* GetQueryManager() override {
-    return query_manager_.get();
-  }
-  virtual VertexArrayManager* GetVertexArrayManager() override {
+  QueryManager* GetQueryManager() override { return query_manager_.get(); }
+  VertexArrayManager* GetVertexArrayManager() override {
     return vertex_array_manager_.get();
   }
-  virtual ImageManager* GetImageManager() override {
-    return image_manager_.get();
-  }
-  virtual bool ProcessPendingQueries() override;
-  virtual bool HasMoreIdleWork() override;
-  virtual void PerformIdleWork() override;
+  ImageManager* GetImageManager() override { return image_manager_.get(); }
+  bool ProcessPendingQueries() override;
+  bool HasMoreIdleWork() override;
+  void PerformIdleWork() override;
 
-  virtual void WaitForReadPixels(base::Closure callback) override;
+  void WaitForReadPixels(base::Closure callback) override;
 
-  virtual void SetResizeCallback(
+  void SetResizeCallback(
       const base::Callback<void(gfx::Size, float)>& callback) override;
 
-  virtual Logger* GetLogger() override;
+  Logger* GetLogger() override;
 
-  virtual void BeginDecoding() override;
-  virtual void EndDecoding() override;
+  void BeginDecoding() override;
+  void EndDecoding() override;
 
-  virtual ErrorState* GetErrorState() override;
-  virtual const ContextState* GetContextState() override { return &state_; }
+  ErrorState* GetErrorState() override;
+  const ContextState* GetContextState() override { return &state_; }
 
-  virtual void SetShaderCacheCallback(
-      const ShaderCacheCallback& callback) override;
-  virtual void SetWaitSyncPointCallback(
-      const WaitSyncPointCallback& callback) override;
+  void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
+  void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
 
-  virtual AsyncPixelTransferManager*
-      GetAsyncPixelTransferManager() override;
-  virtual void ResetAsyncPixelTransferManagerForTest() override;
-  virtual void SetAsyncPixelTransferManagerForTest(
+  AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
+  void ResetAsyncPixelTransferManagerForTest() override;
+  void SetAsyncPixelTransferManagerForTest(
       AsyncPixelTransferManager* manager) override;
-  virtual void SetIgnoreCachedStateForTest(bool ignore) override;
+  void SetIgnoreCachedStateForTest(bool ignore) override;
   void ProcessFinishedAsyncTransfers();
 
-  virtual bool GetServiceTextureId(uint32 client_texture_id,
-                                   uint32* service_texture_id) override;
+  bool GetServiceTextureId(uint32 client_texture_id,
+                           uint32* service_texture_id) override;
 
-  virtual uint32 GetTextureUploadCount() override;
-  virtual base::TimeDelta GetTotalTextureUploadTime() override;
-  virtual base::TimeDelta GetTotalProcessingCommandsTime() override;
-  virtual void AddProcessingCommandsTime(base::TimeDelta) override;
+  uint32 GetTextureUploadCount() override;
+  base::TimeDelta GetTotalTextureUploadTime() override;
+  base::TimeDelta GetTotalProcessingCommandsTime() override;
+  void AddProcessingCommandsTime(base::TimeDelta) override;
 
   // Restores the current state to the user's settings.
   void RestoreCurrentFramebufferBindings();
@@ -690,14 +676,13 @@
   bool BoundFramebufferHasDepthAttachment();
   bool BoundFramebufferHasStencilAttachment();
 
-  virtual error::ContextLostReason GetContextLostReason() override;
+  error::ContextLostReason GetContextLostReason() override;
 
   // Overridden from FramebufferManager::TextureDetachObserver:
-  virtual void OnTextureRefDetachedFromFramebuffer(
-      TextureRef* texture) override;
+  void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
 
   // Overriden from ErrorStateClient.
-  virtual void OnOutOfMemoryError() override;
+  void OnOutOfMemoryError() override;
 
   // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
   void EnsureRenderbufferBound();
@@ -1155,16 +1140,16 @@
   void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
 
   // overridden from GLES2Decoder
-  virtual bool ClearLevel(unsigned service_id,
-                          unsigned bind_target,
-                          unsigned target,
-                          int level,
-                          unsigned internal_format,
-                          unsigned format,
-                          unsigned type,
-                          int width,
-                          int height,
-                          bool is_texture_immutable) override;
+  bool ClearLevel(unsigned service_id,
+                  unsigned bind_target,
+                  unsigned target,
+                  int level,
+                  unsigned internal_format,
+                  unsigned format,
+                  unsigned type,
+                  int width,
+                  int height,
+                  bool is_texture_immutable) override;
 
   // Restore all GL state that affects clearing.
   void RestoreClearState();
@@ -1577,9 +1562,9 @@
       void** result, GLenum* result_type);
 
   void MaybeExitOnContextLost();
-  virtual bool WasContextLost() override;
-  virtual bool WasContextLostByRobustnessExtension() override;
-  virtual void LoseContext(uint32 reset_status) override;
+  bool WasContextLost() override;
+  bool WasContextLostByRobustnessExtension() override;
+  void LoseContext(uint32 reset_status) override;
 
 #if defined(OS_MACOSX)
   void ReleaseIOSurfaceForTexture(GLuint texture_id);
@@ -2757,6 +2742,10 @@
   caps.image = true;
 
   caps.blend_minmax = feature_info_->feature_flags().ext_blend_minmax;
+  caps.blend_equation_advanced =
+      feature_info_->feature_flags().blend_equation_advanced;
+  caps.blend_equation_advanced_coherent =
+      feature_info_->feature_flags().blend_equation_advanced_coherent;
   return caps;
 }
 
@@ -9761,11 +9750,11 @@
     const void* cmd_data) {
   const gles2::cmds::WaitSyncPointCHROMIUM& c =
       *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
-  group_->mailbox_manager()->PullTextureUpdates();
+  uint32 sync_point = c.sync_point;
   if (wait_sync_point_callback_.is_null())
     return error::kNoError;
 
-  return wait_sync_point_callback_.Run(c.sync_point) ?
+  return wait_sync_point_callback_.Run(sync_point) ?
       error::kNoError : error::kDeferCommandUntilLater;
 }
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 5c94b93..8d72335f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -68,7 +68,7 @@
   // Creates a decoder.
   static GLES2Decoder* Create(ContextGroup* group);
 
-  virtual ~GLES2Decoder();
+  ~GLES2Decoder() override;
 
   bool initialized() const {
     return initialized_;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index dade363..02d914f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -3302,6 +3302,22 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderImpl::HandleBlendBarrierKHR(
+    uint32_t immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::BlendBarrierKHR& c =
+      *static_cast<const gles2::cmds::BlendBarrierKHR*>(cmd_data);
+  (void)c;
+  if (!features().blend_equation_advanced) {
+    LOCAL_SET_GL_ERROR(
+        GL_INVALID_OPERATION, "glBlendBarrierKHR", "function not available");
+    return error::kNoError;
+  }
+
+  glBlendBarrierKHR();
+  return error::kNoError;
+}
+
 bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
   switch (cap) {
     case GL_BLEND:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index d510946..1e7db3f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -554,24 +554,23 @@
    public:
     MockCommandBufferEngine();
 
-    virtual ~MockCommandBufferEngine();
+    ~MockCommandBufferEngine() override;
 
-    virtual scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id)
-        override;
+    scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id) override;
 
     void ClearSharedMemory() {
       memset(valid_buffer_->memory(), kInitialMemoryValue, kSharedBufferSize);
     }
 
-    virtual void set_token(int32 token) override;
+    void set_token(int32 token) override;
 
-    virtual bool SetGetBuffer(int32 /* transfer_buffer_id */) override;
+    bool SetGetBuffer(int32 /* transfer_buffer_id */) override;
 
     // Overridden from CommandBufferEngine.
-    virtual bool SetGetOffset(int32 offset) override;
+    bool SetGetOffset(int32 offset) override;
 
     // Overridden from CommandBufferEngine.
-    virtual int32 GetGetOffset() override;
+    int32 GetGetOffset() override;
 
    private:
     scoped_refptr<gpu::Buffer> valid_buffer_;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc
index 311e798..ac80190 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc
@@ -35,6 +35,27 @@
 INSTANTIATE_TEST_CASE_P(Service,
                         GLES2DecoderTestWithCHROMIUMPathRendering,
                         ::testing::Bool());
+
+class GLES2DecoderTestWithBlendEquationAdvanced : public GLES2DecoderTest {
+ public:
+  GLES2DecoderTestWithBlendEquationAdvanced() {}
+  virtual void SetUp() override {
+    InitState init;
+    init.gl_version = "opengl es 2.0";
+    init.has_alpha = true;
+    init.has_depth = true;
+    init.request_alpha = true;
+    init.request_depth = true;
+    init.bind_generates_resource = true;
+    init.extensions = "GL_KHR_blend_equation_advanced";
+    InitDecoder(init);
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(Service,
+                        GLES2DecoderTestWithBlendEquationAdvanced,
+                        ::testing::Bool());
+
 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h"
 
 }  // namespace gles2
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h
index a81be2f..57db672 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h
@@ -44,4 +44,13 @@
   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
+
+TEST_P(GLES2DecoderTestWithBlendEquationAdvanced, BlendBarrierKHRValidArgs) {
+  EXPECT_CALL(*gl_, BlendBarrierKHR());
+  SpecializedSetup<cmds::BlendBarrierKHR, 0>(true);
+  cmds::BlendBarrierKHR cmd;
+  cmd.Init();
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
 #endif  // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_EXTENSIONS_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h
index fed0ce4..5e47d4a 100644
--- a/gpu/command_buffer/service/gpu_scheduler.h
+++ b/gpu/command_buffer/service/gpu_scheduler.h
@@ -56,7 +56,7 @@
                AsyncAPIInterface* handler,
                gles2::GLES2Decoder* decoder);
 
-  virtual ~GpuScheduler();
+  ~GpuScheduler() override;
 
   void PutChanged();
 
@@ -83,11 +83,11 @@
   void SetSchedulingChangedCallback(const SchedulingChangedCallback& callback);
 
   // Implementation of CommandBufferEngine.
-  virtual scoped_refptr<Buffer> GetSharedMemoryBuffer(int32 shm_id) override;
-  virtual void set_token(int32 token) override;
-  virtual bool SetGetBuffer(int32 transfer_buffer_id) override;
-  virtual bool SetGetOffset(int32 offset) override;
-  virtual int32 GetGetOffset() override;
+  scoped_refptr<Buffer> GetSharedMemoryBuffer(int32 shm_id) override;
+  void set_token(int32 token) override;
+  bool SetGetBuffer(int32 transfer_buffer_id) override;
+  bool SetGetOffset(int32 offset) override;
+  int32 GetGetOffset() override;
 
   void SetCommandProcessedCallback(const base::Closure& callback);
 
diff --git a/gpu/command_buffer/service/gpu_state_tracer.cc b/gpu/command_buffer/service/gpu_state_tracer.cc
index 5311e9cc..51b0eba1 100644
--- a/gpu/command_buffer/service/gpu_state_tracer.cc
+++ b/gpu/command_buffer/service/gpu_state_tracer.cc
@@ -24,11 +24,11 @@
   bool SaveScreenshot(const gfx::Size& size);
 
   // base::debug::ConvertableToTraceFormat implementation.
-  virtual void AppendAsTraceFormat(std::string* out) const override;
+  void AppendAsTraceFormat(std::string* out) const override;
 
  private:
   explicit Snapshot(const ContextState* state);
-  virtual ~Snapshot() {}
+  ~Snapshot() override {}
 
   const ContextState* state_;
 
diff --git a/gpu/command_buffer/service/gpu_tracer.h b/gpu/command_buffer/service/gpu_tracer.h
index 8099230..2e81b4eb3 100644
--- a/gpu/command_buffer/service/gpu_tracer.h
+++ b/gpu/command_buffer/service/gpu_tracer.h
@@ -115,14 +115,14 @@
 class TraceOutputter : public Outputter {
  public:
   static scoped_refptr<TraceOutputter> Create(const std::string& name);
-  virtual void Trace(const std::string& name,
-                     int64 start_time,
-                     int64 end_time) override;
+  void Trace(const std::string& name,
+             int64 start_time,
+             int64 end_time) override;
 
  protected:
   friend class base::RefCounted<Outputter>;
   explicit TraceOutputter(const std::string& name);
-  virtual ~TraceOutputter();
+  ~TraceOutputter() override;
 
   base::Thread named_thread_;
   uint64 local_trace_id_;
diff --git a/gpu/command_buffer/service/gpu_tracer_unittest.cc b/gpu/command_buffer/service/gpu_tracer_unittest.cc
index 6be4d5b..fe353c3f 100644
--- a/gpu/command_buffer/service/gpu_tracer_unittest.cc
+++ b/gpu/command_buffer/service/gpu_tracer_unittest.cc
@@ -207,16 +207,12 @@
 
 class GpuARBTimerTracerTest : public BaseGpuTracerTest {
  protected:
-  virtual GpuTracerType GetTracerType() override {
-    return kTracerTypeARBTimer;
-  }
+  GpuTracerType GetTracerType() override { return kTracerTypeARBTimer; }
 };
 
 class GpuDisjointTimerTracerTest : public BaseGpuTracerTest {
  protected:
-  virtual GpuTracerType GetTracerType() override {
-    return kTracerTypeDisjointTimer;
-  }
+  GpuTracerType GetTracerType() override { return kTracerTypeDisjointTimer; }
 };
 
 TEST_F(GpuARBTimerTracerTest, GPUTrace) {
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index 310fced..1e7cc1f 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -62,21 +62,21 @@
  public:
   GpuInProcessThread();
 
-  virtual void AddRef() const override {
+  void AddRef() const override {
     base::RefCountedThreadSafe<GpuInProcessThread>::AddRef();
   }
-  virtual void Release() const override {
+  void Release() const override {
     base::RefCountedThreadSafe<GpuInProcessThread>::Release();
   }
 
-  virtual void ScheduleTask(const base::Closure& task) override;
-  virtual void ScheduleIdleWork(const base::Closure& callback) override;
-  virtual bool UseVirtualizedGLContexts() override { return false; }
-  virtual scoped_refptr<gles2::ShaderTranslatorCache> shader_translator_cache()
+  void ScheduleTask(const base::Closure& task) override;
+  void ScheduleIdleWork(const base::Closure& callback) override;
+  bool UseVirtualizedGLContexts() override { return false; }
+  scoped_refptr<gles2::ShaderTranslatorCache> shader_translator_cache()
       override;
 
  private:
-  virtual ~GpuInProcessThread();
+  ~GpuInProcessThread() override;
   friend class base::RefCountedThreadSafe<GpuInProcessThread>;
 
   scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_;
@@ -177,11 +177,6 @@
 base::LazyInstance<SyncPointManager> g_sync_point_manager =
     LAZY_INSTANCE_INITIALIZER;
 
-bool WaitSyncPoint(uint32 sync_point) {
-  g_sync_point_manager.Get().WaitSyncPoint(sync_point);
-  return true;
-}
-
 }  // anonyous namespace
 
 InProcessCommandBuffer::Service::Service() {}
@@ -422,7 +417,9 @@
     decoder_->SetResizeCallback(base::Bind(
         &InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_));
   }
-  decoder_->SetWaitSyncPointCallback(base::Bind(&WaitSyncPoint));
+  decoder_->SetWaitSyncPointCallback(
+      base::Bind(&InProcessCommandBuffer::WaitSyncPointOnGpuThread,
+                 base::Unretained(this)));
 
   return true;
 }
@@ -658,7 +655,7 @@
       make_current_success = MakeCurrent();
     }
     if (make_current_success)
-      mailbox_manager->PushTextureUpdates();
+      mailbox_manager->PushTextureUpdates(sync_point);
   }
   g_sync_point_manager.Get().RetireSyncPoint(sync_point);
 }
@@ -672,6 +669,14 @@
                        WrapCallback(callback)));
 }
 
+bool InProcessCommandBuffer::WaitSyncPointOnGpuThread(unsigned sync_point) {
+  g_sync_point_manager.Get().WaitSyncPoint(sync_point);
+  gles2::MailboxManager* mailbox_manager =
+      decoder_->GetContextGroup()->mailbox_manager();
+  mailbox_manager->PullTextureUpdates(sync_point);
+  return true;
+}
+
 void InProcessCommandBuffer::SignalSyncPointOnGpuThread(
     unsigned sync_point,
     const base::Closure& callback) {
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index 65cf1ec..e7b22602 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -64,7 +64,7 @@
  public:
   class Service;
   explicit InProcessCommandBuffer(const scoped_refptr<Service>& service);
-  virtual ~InProcessCommandBuffer();
+  ~InProcessCommandBuffer() override;
 
   // If |surface| is not NULL, use it directly; in this case, the command
   // buffer gpu thread must be the same as the client thread. Otherwise create
@@ -80,38 +80,37 @@
   void Destroy();
 
   // CommandBuffer implementation:
-  virtual bool Initialize() override;
-  virtual State GetLastState() override;
-  virtual int32 GetLastToken() override;
-  virtual void Flush(int32 put_offset) override;
-  virtual void WaitForTokenInRange(int32 start, int32 end) override;
-  virtual void WaitForGetOffsetInRange(int32 start, int32 end) override;
-  virtual void SetGetBuffer(int32 shm_id) override;
-  virtual scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
-                                                          int32* id) override;
-  virtual void DestroyTransferBuffer(int32 id) override;
-  virtual gpu::error::Error GetLastError() override;
+  bool Initialize() override;
+  State GetLastState() override;
+  int32 GetLastToken() override;
+  void Flush(int32 put_offset) override;
+  void WaitForTokenInRange(int32 start, int32 end) override;
+  void WaitForGetOffsetInRange(int32 start, int32 end) override;
+  void SetGetBuffer(int32 shm_id) override;
+  scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
+                                                  int32* id) override;
+  void DestroyTransferBuffer(int32 id) override;
+  gpu::error::Error GetLastError() override;
 
   // GpuControl implementation:
-  virtual gpu::Capabilities GetCapabilities() override;
-  virtual int32 CreateImage(ClientBuffer buffer,
-                            size_t width,
-                            size_t height,
-                            unsigned internalformat) override;
-  virtual void DestroyImage(int32 id) override;
-  virtual int32 CreateGpuMemoryBufferImage(size_t width,
-                                           size_t height,
-                                           unsigned internalformat,
-                                           unsigned usage) override;
-  virtual uint32 InsertSyncPoint() override;
-  virtual uint32 InsertFutureSyncPoint() override;
-  virtual void RetireSyncPoint(uint32 sync_point) override;
-  virtual void SignalSyncPoint(uint32 sync_point,
-                               const base::Closure& callback) override;
-  virtual void SignalQuery(uint32 query_id,
-                           const base::Closure& callback) override;
-  virtual void SetSurfaceVisible(bool visible) override;
-  virtual uint32 CreateStreamTexture(uint32 texture_id) override;
+  gpu::Capabilities GetCapabilities() override;
+  int32 CreateImage(ClientBuffer buffer,
+                    size_t width,
+                    size_t height,
+                    unsigned internalformat) override;
+  void DestroyImage(int32 id) override;
+  int32 CreateGpuMemoryBufferImage(size_t width,
+                                   size_t height,
+                                   unsigned internalformat,
+                                   unsigned usage) override;
+  uint32 InsertSyncPoint() override;
+  uint32 InsertFutureSyncPoint() override;
+  void RetireSyncPoint(uint32 sync_point) override;
+  void SignalSyncPoint(uint32 sync_point,
+                       const base::Closure& callback) override;
+  void SignalQuery(uint32 query_id, const base::Closure& callback) override;
+  void SetSurfaceVisible(bool visible) override;
+  uint32 CreateStreamTexture(uint32 texture_id) override;
 
   // The serializer interface to the GPU service (i.e. thread).
   class Service {
@@ -182,6 +181,7 @@
   void RetireSyncPointOnGpuThread(uint32 sync_point);
   void SignalSyncPointOnGpuThread(uint32 sync_point,
                                   const base::Closure& callback);
+  bool WaitSyncPointOnGpuThread(uint32 sync_point);
   void SignalQueryOnGpuThread(unsigned query_id, const base::Closure& callback);
   void DestroyTransferBufferOnGpuThread(int32 id);
 
diff --git a/gpu/command_buffer/service/mailbox_manager.cc b/gpu/command_buffer/service/mailbox_manager.cc
index e6962df5..b4d6e79 100644
--- a/gpu/command_buffer/service/mailbox_manager.cc
+++ b/gpu/command_buffer/service/mailbox_manager.cc
@@ -84,14 +84,14 @@
     sync_->TextureDeleted(texture);
 }
 
-void MailboxManager::PushTextureUpdates() {
+void MailboxManager::PushTextureUpdates(uint32 sync_point) {
   if (sync_)
-    sync_->PushTextureUpdates(this);
+    sync_->PushTextureUpdates(this, sync_point);
 }
 
-void MailboxManager::PullTextureUpdates() {
+void MailboxManager::PullTextureUpdates(uint32 sync_point) {
   if (sync_)
-    sync_->PullTextureUpdates(this);
+    sync_->PullTextureUpdates(this, sync_point);
 }
 
 MailboxManager::TargetName::TargetName(unsigned target, const Mailbox& mailbox)
diff --git a/gpu/command_buffer/service/mailbox_manager.h b/gpu/command_buffer/service/mailbox_manager.h
index e1b36cb9..a00b965 100644
--- a/gpu/command_buffer/service/mailbox_manager.h
+++ b/gpu/command_buffer/service/mailbox_manager.h
@@ -41,8 +41,8 @@
 
   // Used with the MailboxSynchronizer to push/pull texture state to/from
   // other manager instances.
-  void PushTextureUpdates();
-  void PullTextureUpdates();
+  void PushTextureUpdates(uint32 sync_point);
+  void PullTextureUpdates(uint32 sync_point);
 
   // Destroy any mailbox that reference the given texture.
   void TextureDeleted(Texture* texture);
diff --git a/gpu/command_buffer/service/mailbox_manager_unittest.cc b/gpu/command_buffer/service/mailbox_manager_unittest.cc
index df1cd4e..63ffc6d6 100644
--- a/gpu/command_buffer/service/mailbox_manager_unittest.cc
+++ b/gpu/command_buffer/service/mailbox_manager_unittest.cc
@@ -300,8 +300,8 @@
   EXPECT_EQ(texture, manager_->ConsumeTexture(GL_TEXTURE_2D, name));
 
   // Synchronize
-  manager_->PushTextureUpdates();
-  manager2_->PullTextureUpdates();
+  manager_->PushTextureUpdates(0);
+  manager2_->PullTextureUpdates(0);
 
   DestroyTexture(texture);
   EXPECT_EQ(NULL, manager_->ConsumeTexture(GL_TEXTURE_2D, name));
@@ -321,8 +321,8 @@
   EXPECT_EQ(texture, manager_->ConsumeTexture(GL_TEXTURE_2D, name));
 
   // Synchronize
-  manager_->PushTextureUpdates();
-  manager2_->PullTextureUpdates();
+  manager_->PushTextureUpdates(0);
+  manager2_->PullTextureUpdates(0);
 
   EXPECT_CALL(*gl_, GenTextures(1, _))
       .WillOnce(SetArgPointee<1>(kNewTextureId));
@@ -349,10 +349,10 @@
   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
 
   // Synchronize again
-  manager_->PushTextureUpdates();
+  manager_->PushTextureUpdates(0);
   SetupUpdateTexParamExpectations(
       kNewTextureId, GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT);
-  manager2_->PullTextureUpdates();
+  manager2_->PullTextureUpdates(0);
   GLsizei width, height;
   new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height);
   EXPECT_EQ(16, width);
@@ -382,7 +382,7 @@
 
   // The last change to the texture should be visible without a sync point (i.e.
   // push).
-  manager2_->PullTextureUpdates();
+  manager2_->PullTextureUpdates(0);
   new_texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height);
   EXPECT_EQ(64, width);
   EXPECT_EQ(64, height);
@@ -410,8 +410,8 @@
   manager2_->ProduceTexture(GL_TEXTURE_2D, name2, texture2);
 
   // Make visible.
-  manager_->PushTextureUpdates();
-  manager2_->PushTextureUpdates();
+  manager_->PushTextureUpdates(0);
+  manager2_->PushTextureUpdates(0);
 
   // Create textures in the other manager instances for texture1 and texture2,
   // respectively to create a real sharing scenario. Otherwise, there would
@@ -438,7 +438,7 @@
             SetParameter(texture1, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
 
   // Make sure this does not clobber it with the previous version we pushed.
-  manager_->PullTextureUpdates();
+  manager_->PullTextureUpdates(0);
 
   // Make a change to texture2
   DCHECK_EQ(static_cast<GLuint>(GL_LINEAR), texture2->mag_filter());
@@ -448,16 +448,16 @@
   Mock::VerifyAndClearExpectations(gl_.get());
 
   // Synchronize in both directions
-  manager_->PushTextureUpdates();
-  manager2_->PushTextureUpdates();
+  manager_->PushTextureUpdates(0);
+  manager2_->PushTextureUpdates(0);
   // manager1 should see the change to texture2 mag_filter being applied.
   SetupUpdateTexParamExpectations(
       new_texture2->service_id(), GL_LINEAR, GL_NEAREST, GL_REPEAT, GL_REPEAT);
-  manager_->PullTextureUpdates();
+  manager_->PullTextureUpdates(0);
   // manager2 should see the change to texture1 min_filter being applied.
   SetupUpdateTexParamExpectations(
       new_texture1->service_id(), GL_NEAREST, GL_LINEAR, GL_REPEAT, GL_REPEAT);
-  manager2_->PullTextureUpdates();
+  manager2_->PullTextureUpdates(0);
 
   DestroyTexture(texture1);
   DestroyTexture(texture2);
diff --git a/gpu/command_buffer/service/mailbox_synchronizer.cc b/gpu/command_buffer/service/mailbox_synchronizer.cc
index eac31f95..81a2793 100644
--- a/gpu/command_buffer/service/mailbox_synchronizer.cc
+++ b/gpu/command_buffer/service/mailbox_synchronizer.cc
@@ -7,8 +7,13 @@
 #include "base/bind.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/texture_manager.h"
+#include "ui/gl/gl_fence.h"
 #include "ui/gl/gl_implementation.h"
 
+#if !defined(OS_MACOSX)
+#include "ui/gl/gl_fence_egl.h"
+#endif
+
 namespace gpu {
 namespace gles2 {
 
@@ -136,7 +141,8 @@
   }
 }
 
-void MailboxSynchronizer::PushTextureUpdates(MailboxManager* manager) {
+void MailboxSynchronizer::PushTextureUpdates(MailboxManager* manager,
+                                             uint32 sync_point) {
   base::AutoLock lock(lock_);
   for (MailboxManager::MailboxToTextureMap::const_iterator texture_it =
            manager->mailbox_to_textures_.begin();
@@ -179,6 +185,33 @@
       textures_.insert(std::make_pair(texture, TextureVersion(group)));
     }
   }
+
+  CreateFenceLocked(sync_point);
+}
+
+void MailboxSynchronizer::CreateFenceLocked(uint32 sync_point) {
+  lock_.AssertAcquired();
+  if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL)
+    return;
+
+#if !defined(OS_MACOSX)
+  if (sync_point) {
+    while (!sync_points_.empty() &&
+           sync_points_.front()->second->HasCompleted()) {
+      sync_point_to_fence_.erase(sync_points_.front());
+      sync_points_.pop();
+    }
+    // Need to use EGL fences since we are likely not in a single share group.
+    linked_ptr<gfx::GLFence> fence(make_linked_ptr(new gfx::GLFenceEGL(true)));
+    if (fence.get()) {
+      std::pair<SyncPointToFenceMap::iterator, bool> result =
+          sync_point_to_fence_.insert(std::make_pair(sync_point, fence));
+      DCHECK(result.second);
+      sync_points_.push(result.first);
+    }
+    DCHECK(sync_points_.size() == sync_point_to_fence_.size());
+  }
+#endif
 }
 
 void MailboxSynchronizer::UpdateTextureLocked(Texture* texture,
@@ -208,8 +241,20 @@
                                         gl_image ? image_buffer : NULL);
 }
 
-void MailboxSynchronizer::PullTextureUpdates(MailboxManager* manager) {
+void MailboxSynchronizer::AcquireFenceLocked(uint32 sync_point) {
+  lock_.AssertAcquired();
+  SyncPointToFenceMap::iterator fence_it =
+      sync_point_to_fence_.find(sync_point);
+  if (fence_it != sync_point_to_fence_.end()) {
+    fence_it->second->ServerWait();
+  }
+}
+
+void MailboxSynchronizer::PullTextureUpdates(MailboxManager* manager,
+                                             uint32 sync_point) {
   base::AutoLock lock(lock_);
+  AcquireFenceLocked(sync_point);
+
   for (MailboxManager::MailboxToTextureMap::const_iterator texture_it =
            manager->mailbox_to_textures_.begin();
        texture_it != manager->mailbox_to_textures_.end();
diff --git a/gpu/command_buffer/service/mailbox_synchronizer.h b/gpu/command_buffer/service/mailbox_synchronizer.h
index a845963..3ddb9d0 100644
--- a/gpu/command_buffer/service/mailbox_synchronizer.h
+++ b/gpu/command_buffer/service/mailbox_synchronizer.h
@@ -8,6 +8,7 @@
 #include "gpu/command_buffer/common/mailbox.h"
 
 #include <map>
+#include <queue>
 #include <set>
 
 #include "base/memory/linked_ptr.h"
@@ -15,6 +16,10 @@
 #include "gpu/command_buffer/service/texture_definition.h"
 #include "gpu/gpu_export.h"
 
+namespace gfx {
+class GLFence;
+}
+
 namespace gpu {
 namespace gles2 {
 
@@ -34,8 +39,8 @@
   // Create a texture from a globally visible mailbox.
   Texture* CreateTextureFromMailbox(unsigned target, const Mailbox& mailbox);
 
-  void PushTextureUpdates(MailboxManager* manager);
-  void PullTextureUpdates(MailboxManager* manager);
+  void PushTextureUpdates(MailboxManager* manager, uint32 sync_point);
+  void PullTextureUpdates(MailboxManager* manager, uint32 sync_point);
 
   void TextureDeleted(Texture* texture);
 
@@ -85,6 +90,12 @@
       const TargetName& target_name,
       TextureGroup* group);
   void UpdateTextureLocked(Texture* texture, TextureVersion& texture_version);
+  void CreateFenceLocked(uint32 sync_point);
+  void AcquireFenceLocked(uint32 sync_point);
+
+  typedef std::map<uint32, linked_ptr<gfx::GLFence> > SyncPointToFenceMap;
+  SyncPointToFenceMap sync_point_to_fence_;
+  std::queue<SyncPointToFenceMap::iterator> sync_points_;
 
   DISALLOW_COPY_AND_ASSIGN(MailboxSynchronizer);
 };
diff --git a/gpu/command_buffer/service/memory_program_cache.h b/gpu/command_buffer/service/memory_program_cache.h
index 804547ea..7560d01b 100644
--- a/gpu/command_buffer/service/memory_program_cache.h
+++ b/gpu/command_buffer/service/memory_program_cache.h
@@ -24,9 +24,9 @@
  public:
   MemoryProgramCache();
   explicit MemoryProgramCache(const size_t max_cache_size_bytes);
-  virtual ~MemoryProgramCache();
+  ~MemoryProgramCache() override;
 
-  virtual ProgramLoadResult LoadLinkedProgram(
+  ProgramLoadResult LoadLinkedProgram(
       GLuint program,
       Shader* shader_a,
       const ShaderTranslatorInterface* translator_a,
@@ -34,19 +34,18 @@
       const ShaderTranslatorInterface* translator_b,
       const LocationMap* bind_attrib_location_map,
       const ShaderCacheCallback& shader_callback) override;
-  virtual void SaveLinkedProgram(
-      GLuint program,
-      const Shader* shader_a,
-      const ShaderTranslatorInterface* translator_a,
-      const Shader* shader_b,
-      const ShaderTranslatorInterface* translator_b,
-      const LocationMap* bind_attrib_location_map,
-      const ShaderCacheCallback& shader_callback) override;
+  void SaveLinkedProgram(GLuint program,
+                         const Shader* shader_a,
+                         const ShaderTranslatorInterface* translator_a,
+                         const Shader* shader_b,
+                         const ShaderTranslatorInterface* translator_b,
+                         const LocationMap* bind_attrib_location_map,
+                         const ShaderCacheCallback& shader_callback) override;
 
-  virtual void LoadProgram(const std::string& program) override;
+  void LoadProgram(const std::string& program) override;
 
  private:
-  virtual void ClearBackend() override;
+  void ClearBackend() override;
 
   class ProgramCacheValue : public base::RefCounted<ProgramCacheValue> {
    public:
diff --git a/gpu/command_buffer/service/program_cache_unittest.cc b/gpu/command_buffer/service/program_cache_unittest.cc
index 37597d33..525fea1 100644
--- a/gpu/command_buffer/service/program_cache_unittest.cc
+++ b/gpu/command_buffer/service/program_cache_unittest.cc
@@ -15,7 +15,7 @@
 
 class NoBackendProgramCache : public ProgramCache {
  public:
-  virtual ProgramLoadResult LoadLinkedProgram(
+  ProgramLoadResult LoadLinkedProgram(
       GLuint /* program */,
       Shader* /* shader_a */,
       const ShaderTranslatorInterface* /* translator_a */,
@@ -25,18 +25,17 @@
       const ShaderCacheCallback& /* callback */) override {
     return PROGRAM_LOAD_SUCCESS;
   }
-  virtual void SaveLinkedProgram(
-      GLuint /* program */,
-      const Shader* /* shader_a */,
-      const ShaderTranslatorInterface* /* translator_b */,
-      const Shader* /* shader_b */,
-      const ShaderTranslatorInterface* /* translator_b */,
-      const LocationMap* /* bind_attrib_location_map */,
-      const ShaderCacheCallback& /* callback */) override { }
+  void SaveLinkedProgram(GLuint /* program */,
+                         const Shader* /* shader_a */,
+                         const ShaderTranslatorInterface* /* translator_b */,
+                         const Shader* /* shader_b */,
+                         const ShaderTranslatorInterface* /* translator_b */,
+                         const LocationMap* /* bind_attrib_location_map */,
+                         const ShaderCacheCallback& /* callback */) override {}
 
-  virtual void LoadProgram(const std::string& /* program */) override {}
+  void LoadProgram(const std::string& /* program */) override {}
 
-  virtual void ClearBackend() override {}
+  void ClearBackend() override {}
 
   void SaySuccessfullyCached(const std::string& shader1,
                              const ShaderTranslatorInterface* translator_1,
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
index 63a64b7..ac7021ad 100644
--- a/gpu/command_buffer/service/program_manager.cc
+++ b/gpu/command_buffer/service/program_manager.cc
@@ -81,8 +81,8 @@
   return true;
 }
 
-bool IsBuiltInVarying(const std::string& name) {
-  // Built-in variables.
+bool IsBuiltInFragmentVarying(const std::string& name) {
+  // Built-in variables for fragment shaders.
   const char* kBuiltInVaryings[] = {
       "gl_FragCoord",
       "gl_FrontFacing",
@@ -95,6 +95,14 @@
   return false;
 }
 
+bool IsBuiltInInvariant(
+    const VaryingMap& varyings, const std::string& name) {
+  VaryingMap::const_iterator hit = varyings.find(name);
+  if (hit == varyings.end())
+    return false;
+  return hit->second.isInvariant;
+}
+
 }  // anonymous namespace.
 
 Program::UniformInfo::UniformInfo()
@@ -526,6 +534,11 @@
     set_log_info(ProcessLogInfo(info_log).c_str());
     return false;
   }
+  if (DetectBuiltInInvariantConflicts()) {
+    set_log_info("Invariant settings for certain built-in varyings "
+                 "have to match");
+    return false;
+  }
   if (DetectGlobalNameConflicts(&conflicting_name)) {
     std::string info_log = "Name conflicts between an uniform and an "
                            "attribute: " + conflicting_name;
@@ -1071,7 +1084,7 @@
   for (VaryingMap::const_iterator iter = fragment_varyings->begin();
        iter != fragment_varyings->end(); ++iter) {
     const std::string& name = iter->first;
-    if (IsBuiltInVarying(name))
+    if (IsBuiltInFragmentVarying(name))
       continue;
 
     VaryingMap::const_iterator hit = vertex_varyings->find(name);
@@ -1092,6 +1105,28 @@
   return false;
 }
 
+bool Program::DetectBuiltInInvariantConflicts() const {
+  DCHECK(attached_shaders_[0].get() &&
+         attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER &&
+         attached_shaders_[1].get() &&
+         attached_shaders_[1]->shader_type() == GL_FRAGMENT_SHADER);
+  const VaryingMap& vertex_varyings = attached_shaders_[0]->varying_map();
+  const VaryingMap& fragment_varyings = attached_shaders_[1]->varying_map();
+
+  bool gl_position_invariant = IsBuiltInInvariant(
+      vertex_varyings, "gl_Position");
+  bool gl_point_size_invariant = IsBuiltInInvariant(
+      vertex_varyings, "gl_PointSize");
+
+  bool gl_frag_coord_invariant = IsBuiltInInvariant(
+      fragment_varyings, "gl_FragCoord");
+  bool gl_point_coord_invariant = IsBuiltInInvariant(
+      fragment_varyings, "gl_PointCoord");
+
+  return ((gl_frag_coord_invariant && !gl_position_invariant) ||
+          (gl_point_coord_invariant && !gl_point_size_invariant));
+}
+
 bool Program::DetectGlobalNameConflicts(std::string* conflicting_name) const {
   DCHECK(attached_shaders_[0].get() &&
          attached_shaders_[0]->shader_type() == GL_VERTEX_SHADER &&
@@ -1130,7 +1165,7 @@
        iter != fragment_varyings->end(); ++iter) {
     if (!iter->second.staticUse && option == kCountOnlyStaticallyUsed)
       continue;
-    if (!IsBuiltInVarying(iter->first)) {
+    if (!IsBuiltInFragmentVarying(iter->first)) {
       VaryingMap::const_iterator vertex_iter =
           vertex_varyings->find(iter->first);
       if (vertex_iter == vertex_varyings->end() ||
diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h
index 9698fc1..dbe9c14 100644
--- a/gpu/command_buffer/service/program_manager.h
+++ b/gpu/command_buffer/service/program_manager.h
@@ -215,6 +215,10 @@
   // is not declared in vertex shader.
   bool DetectVaryingsMismatch(std::string* conflicting_name) const;
 
+  // Return true if any built-in invariant matching rules are broken as in
+  // GLSL ES spec 1.00.17, section 4.6.4, Invariance and Linkage.
+  bool DetectBuiltInInvariantConflicts() const;
+
   // Return true if an uniform and an attribute share the same name.
   bool DetectGlobalNameConflicts(std::string* conflicting_name) const;
 
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index fdc7d0a..5f518eca 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -34,7 +34,7 @@
     cancelled_ = true;
   }
 
-  virtual void DidComplete(const AsyncMemoryParams& mem_params) override {
+  void DidComplete(const AsyncMemoryParams& mem_params) override {
     base::AutoLock locked(lock_);
     if (!cancelled_) {
       DCHECK(mem_params.buffer().get());
@@ -45,7 +45,7 @@
   }
 
  private:
-  virtual ~AsyncPixelTransferCompletionObserverImpl() {}
+  ~AsyncPixelTransferCompletionObserverImpl() override {}
 
   base::subtle::Atomic32 submit_count_;
 
@@ -62,13 +62,13 @@
   AsyncPixelTransfersCompletedQuery(
       QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
 
-  virtual bool Begin() override;
-  virtual bool End(base::subtle::Atomic32 submit_count) override;
-  virtual bool Process() override;
-  virtual void Destroy(bool have_context) override;
+  bool Begin() override;
+  bool End(base::subtle::Atomic32 submit_count) override;
+  bool Process() override;
+  void Destroy(bool have_context) override;
 
  protected:
-  virtual ~AsyncPixelTransfersCompletedQuery();
+  ~AsyncPixelTransfersCompletedQuery() override;
 
   scoped_refptr<AsyncPixelTransferCompletionObserverImpl> observer_;
 };
@@ -139,13 +139,13 @@
   AllSamplesPassedQuery(
       QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
       GLuint service_id);
-  virtual bool Begin() override;
-  virtual bool End(base::subtle::Atomic32 submit_count) override;
-  virtual bool Process() override;
-  virtual void Destroy(bool have_context) override;
+  bool Begin() override;
+  bool End(base::subtle::Atomic32 submit_count) override;
+  bool Process() override;
+  void Destroy(bool have_context) override;
 
  protected:
-  virtual ~AllSamplesPassedQuery();
+  ~AllSamplesPassedQuery() override;
 
  private:
   // Service side query id.
@@ -198,13 +198,13 @@
   CommandsIssuedQuery(
       QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
 
-  virtual bool Begin() override;
-  virtual bool End(base::subtle::Atomic32 submit_count) override;
-  virtual bool Process() override;
-  virtual void Destroy(bool have_context) override;
+  bool Begin() override;
+  bool End(base::subtle::Atomic32 submit_count) override;
+  bool Process() override;
+  void Destroy(bool have_context) override;
 
  protected:
-  virtual ~CommandsIssuedQuery();
+  ~CommandsIssuedQuery() override;
 
  private:
   base::TimeTicks begin_time_;
@@ -245,13 +245,13 @@
   CommandLatencyQuery(
       QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
 
-  virtual bool Begin() override;
-  virtual bool End(base::subtle::Atomic32 submit_count) override;
-  virtual bool Process() override;
-  virtual void Destroy(bool have_context) override;
+  bool Begin() override;
+  bool End(base::subtle::Atomic32 submit_count) override;
+  bool Process() override;
+  void Destroy(bool have_context) override;
 
  protected:
-  virtual ~CommandLatencyQuery();
+  ~CommandLatencyQuery() override;
 };
 
 CommandLatencyQuery::CommandLatencyQuery(
@@ -291,14 +291,14 @@
   AsyncReadPixelsCompletedQuery(
       QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
 
-  virtual bool Begin() override;
-  virtual bool End(base::subtle::Atomic32 submit_count) override;
-  virtual bool Process() override;
-  virtual void Destroy(bool have_context) override;
+  bool Begin() override;
+  bool End(base::subtle::Atomic32 submit_count) override;
+  bool Process() override;
+  void Destroy(bool have_context) override;
 
  protected:
   void Complete();
-  virtual ~AsyncReadPixelsCompletedQuery();
+  ~AsyncReadPixelsCompletedQuery() override;
 
  private:
   bool completed_;
@@ -351,13 +351,13 @@
   GetErrorQuery(
       QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
 
-  virtual bool Begin() override;
-  virtual bool End(base::subtle::Atomic32 submit_count) override;
-  virtual bool Process() override;
-  virtual void Destroy(bool have_context) override;
+  bool Begin() override;
+  bool End(base::subtle::Atomic32 submit_count) override;
+  bool Process() override;
+  void Destroy(bool have_context) override;
 
  protected:
-  virtual ~GetErrorQuery();
+  ~GetErrorQuery() override;
 
  private:
 };
@@ -398,13 +398,13 @@
                          uint32 shm_offset);
 
   // Overridden from QueryManager::Query:
-  virtual bool Begin() override;
-  virtual bool End(base::subtle::Atomic32 submit_count) override;
-  virtual bool Process() override;
-  virtual void Destroy(bool have_context) override;
+  bool Begin() override;
+  bool End(base::subtle::Atomic32 submit_count) override;
+  bool Process() override;
+  void Destroy(bool have_context) override;
 
  protected:
-  virtual ~CommandsCompletedQuery();
+  ~CommandsCompletedQuery() override;
 
  private:
   scoped_ptr<gfx::GLFence> fence_;
diff --git a/gpu/command_buffer/service/query_manager_unittest.cc b/gpu/command_buffer/service/query_manager_unittest.cc
index f6335e8..b4f1653d5 100644
--- a/gpu/command_buffer/service/query_manager_unittest.cc
+++ b/gpu/command_buffer/service/query_manager_unittest.cc
@@ -96,11 +96,9 @@
       ClearSharedMemory();
     }
 
-    virtual ~MockCommandBufferEngine() {
-    }
+    ~MockCommandBufferEngine() override {}
 
-    virtual scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id)
-        override {
+    scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id) override {
       return shm_id == kSharedMemoryId ? valid_buffer_ : invalid_buffer_;
     }
 
@@ -108,23 +106,21 @@
       memset(data_, kInitialMemoryValue, kSharedBufferSize);
     }
 
-    virtual void set_token(int32 token) override {
-      DCHECK(false);
-    }
+    void set_token(int32 token) override { DCHECK(false); }
 
-    virtual bool SetGetBuffer(int32 /* transfer_buffer_id */) override {
+    bool SetGetBuffer(int32 /* transfer_buffer_id */) override {
       DCHECK(false);
       return false;
     }
 
     // Overridden from CommandBufferEngine.
-    virtual bool SetGetOffset(int32 offset) override {
+    bool SetGetOffset(int32 offset) override {
       DCHECK(false);
       return false;
     }
 
     // Overridden from CommandBufferEngine.
-    virtual int32 GetGetOffset() override {
+    int32 GetGetOffset() override {
       DCHECK(false);
       return 0;
     }
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h
index ff9d741..6075896 100644
--- a/gpu/command_buffer/service/shader_translator.h
+++ b/gpu/command_buffer/service/shader_translator.h
@@ -83,24 +83,22 @@
   ShaderTranslator();
 
   // Overridden from ShaderTranslatorInterface.
-  virtual bool Init(
-      sh::GLenum shader_type,
-      ShShaderSpec shader_spec,
-      const ShBuiltInResources* resources,
-      GlslImplementationType glsl_implementation_type,
-      ShCompileOptions driver_bug_workarounds) override;
+  bool Init(sh::GLenum shader_type,
+            ShShaderSpec shader_spec,
+            const ShBuiltInResources* resources,
+            GlslImplementationType glsl_implementation_type,
+            ShCompileOptions driver_bug_workarounds) override;
 
   // Overridden from ShaderTranslatorInterface.
-  virtual bool Translate(const std::string& shader_source,
-                         std::string* info_log,
-                         std::string* translated_source,
-                         AttributeMap* attrib_map,
-                         UniformMap* uniform_map,
-                         VaryingMap* varying_map,
-                         NameMap* name_map) const override;
+  bool Translate(const std::string& shader_source,
+                 std::string* info_log,
+                 std::string* translated_source,
+                 AttributeMap* attrib_map,
+                 UniformMap* uniform_map,
+                 VaryingMap* varying_map,
+                 NameMap* name_map) const override;
 
-  virtual std::string GetStringForOptionsThatWouldAffectCompilation() const
-      override;
+  std::string GetStringForOptionsThatWouldAffectCompilation() const override;
 
   void AddDestructionObserver(DestructionObserver* observer);
   void RemoveDestructionObserver(DestructionObserver* observer);
@@ -108,7 +106,7 @@
  private:
   friend class base::RefCounted<ShaderTranslator>;
 
-  virtual ~ShaderTranslator();
+  ~ShaderTranslator() override;
   int GetCompileOptions() const;
 
   ShHandle compiler_;
diff --git a/gpu/command_buffer/service/shader_translator_cache.h b/gpu/command_buffer/service/shader_translator_cache.h
index 02f5829..e804ef2 100644
--- a/gpu/command_buffer/service/shader_translator_cache.h
+++ b/gpu/command_buffer/service/shader_translator_cache.h
@@ -29,7 +29,7 @@
   ShaderTranslatorCache();
 
   // ShaderTranslator::DestructionObserver implementation
-  virtual void OnDestruct(ShaderTranslator* translator) override;
+  void OnDestruct(ShaderTranslator* translator) override;
 
   scoped_refptr<ShaderTranslator> GetTranslator(
       sh::GLenum shader_type,
@@ -41,7 +41,7 @@
 
  private:
   friend class base::RefCounted<ShaderTranslatorCache>;
-  virtual ~ShaderTranslatorCache();
+  ~ShaderTranslatorCache() override;
 
   // Parameters passed into ShaderTranslator::Init
   struct ShaderTranslatorInitParams {
diff --git a/gpu/command_buffer/service/shader_translator_unittest.cc b/gpu/command_buffer/service/shader_translator_unittest.cc
index 198ea827..40d5be7 100644
--- a/gpu/command_buffer/service/shader_translator_unittest.cc
+++ b/gpu/command_buffer/service/shader_translator_unittest.cc
@@ -69,10 +69,11 @@
   EXPECT_TRUE(info_log.empty());
   // Translated shader must be valid and non-empty.
   ASSERT_FALSE(translated_source.empty());
-  // There should be no attributes, uniforms, varyings.
+  // There should be no attributes, uniforms, and only one built-in
+  // varying: gl_Position.
   EXPECT_TRUE(attrib_map.empty());
   EXPECT_TRUE(uniform_map.empty());
-  EXPECT_TRUE(varying_map.empty());
+  EXPECT_EQ(1u, varying_map.size());
   // There should be no name mapping.
   EXPECT_TRUE(name_map.empty());
 }
diff --git a/gpu/command_buffer/service/texture_definition.cc b/gpu/command_buffer/service/texture_definition.cc
index 6255a1c0..abde56a 100644
--- a/gpu/command_buffer/service/texture_definition.cc
+++ b/gpu/command_buffer/service/texture_definition.cc
@@ -15,7 +15,6 @@
 #include "ui/gl/scoped_binders.h"
 
 #if !defined(OS_MACOSX)
-#include "ui/gl/gl_fence_egl.h"
 #include "ui/gl/gl_surface_egl.h"
 #endif
 
@@ -30,23 +29,23 @@
                        const gfx::Size& size);
 
   // Implement GLImage.
-  virtual void Destroy(bool have_context) override;
-  virtual gfx::Size GetSize() override;
-  virtual bool BindTexImage(unsigned target) override;
-  virtual void ReleaseTexImage(unsigned target) override;
-  virtual bool CopyTexImage(unsigned target) override;
-  virtual void WillUseTexImage() override;
-  virtual void WillModifyTexImage() override;
-  virtual void DidModifyTexImage() override;
-  virtual void DidUseTexImage() override;
-  virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
-                                    int z_order,
-                                    gfx::OverlayTransform transform,
-                                    const gfx::Rect& bounds_rect,
-                                    const gfx::RectF& crop_rect) override;
+  void Destroy(bool have_context) override;
+  gfx::Size GetSize() override;
+  bool BindTexImage(unsigned target) override;
+  void ReleaseTexImage(unsigned target) override;
+  bool CopyTexImage(unsigned target) override;
+  void WillUseTexImage() override;
+  void WillModifyTexImage() override;
+  void DidModifyTexImage() override;
+  void DidUseTexImage() override;
+  bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
+                            int z_order,
+                            gfx::OverlayTransform transform,
+                            const gfx::Rect& bounds_rect,
+                            const gfx::RectF& crop_rect) override;
 
  protected:
-  virtual ~GLImageSync();
+  ~GLImageSync() override;
 
  private:
   scoped_refptr<NativeImageBuffer> buffer_;
@@ -88,23 +87,15 @@
 }
 
 void GLImageSync::WillUseTexImage() {
-  if (buffer_.get())
-    buffer_->WillRead(this);
 }
 
 void GLImageSync::DidUseTexImage() {
-  if (buffer_.get())
-    buffer_->DidRead(this);
 }
 
 void GLImageSync::WillModifyTexImage() {
-  if (buffer_.get())
-    buffer_->WillWrite(this);
 }
 
 void GLImageSync::DidModifyTexImage() {
-  if (buffer_.get())
-    buffer_->DidWrite(this);
 }
 
 bool GLImageSync::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
@@ -128,10 +119,6 @@
   virtual void RemoveClient(gfx::GLImage* client) override;
   virtual bool IsClient(gfx::GLImage* client) override;
   virtual void BindToTexture(GLenum target) override;
-  virtual void WillRead(gfx::GLImage* client) override;
-  virtual void WillWrite(gfx::GLImage* client) override;
-  virtual void DidRead(gfx::GLImage* client) override;
-  virtual void DidWrite(gfx::GLImage* client) override;
 
   EGLDisplay egl_display_;
   EGLImageKHR egl_image_;
@@ -144,10 +131,8 @@
 
     gfx::GLImage* client;
     bool needs_wait_before_read;
-    linked_ptr<gfx::GLFence> read_fence;
   };
   std::list<ClientInfo> client_infos_;
-  scoped_ptr<gfx::GLFence> write_fence_;
   gfx::GLImage* write_client_;
 
   DISALLOW_COPY_AND_ASSIGN(NativeImageBufferEGL);
@@ -164,8 +149,7 @@
 
   DCHECK(gfx::g_driver_egl.ext.b_EGL_KHR_image_base &&
          gfx::g_driver_egl.ext.b_EGL_KHR_gl_texture_2D_image &&
-         gfx::g_driver_gl.ext.b_GL_OES_EGL_image &&
-         gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync);
+         gfx::g_driver_gl.ext.b_GL_OES_EGL_image);
 
   const EGLint egl_attrib_list[] = {
       EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
@@ -191,7 +175,6 @@
     : NativeImageBuffer(),
       egl_display_(display),
       egl_image_(image),
-      write_fence_(new gfx::GLFenceEGL(true)),
       write_client_(NULL) {
   DCHECK(egl_display_ != EGL_NO_DISPLAY);
   DCHECK(egl_image_ != EGL_NO_IMAGE_KHR);
@@ -241,64 +224,6 @@
   DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
 }
 
-void NativeImageBufferEGL::WillRead(gfx::GLImage* client) {
-  base::AutoLock lock(lock_);
-  if (!write_fence_.get() || write_client_ == client)
-    return;
-
-  for (std::list<ClientInfo>::iterator it = client_infos_.begin();
-       it != client_infos_.end();
-       it++) {
-    if (it->client == client) {
-      if (it->needs_wait_before_read) {
-        it->needs_wait_before_read = false;
-        write_fence_->ServerWait();
-      }
-      return;
-    }
-  }
-  NOTREACHED();
-}
-
-void NativeImageBufferEGL::WillWrite(gfx::GLImage* client) {
-  base::AutoLock lock(lock_);
-  if (write_client_ != client)
-    write_fence_->ServerWait();
-
-  for (std::list<ClientInfo>::iterator it = client_infos_.begin();
-       it != client_infos_.end();
-       it++) {
-    if (it->read_fence.get() && it->client != client)
-      it->read_fence->ServerWait();
-  }
-}
-
-void NativeImageBufferEGL::DidRead(gfx::GLImage* client) {
-  base::AutoLock lock(lock_);
-  for (std::list<ClientInfo>::iterator it = client_infos_.begin();
-       it != client_infos_.end();
-       it++) {
-    if (it->client == client) {
-      it->read_fence = make_linked_ptr(new gfx::GLFenceEGL(true));
-      return;
-    }
-  }
-  NOTREACHED();
-}
-
-void NativeImageBufferEGL::DidWrite(gfx::GLImage* client) {
-  base::AutoLock lock(lock_);
-  // Sharing semantics require the client to flush in order to make changes
-  // visible to other clients.
-  write_fence_.reset(new gfx::GLFenceEGL(false));
-  write_client_ = client;
-  for (std::list<ClientInfo>::iterator it = client_infos_.begin();
-       it != client_infos_.end();
-       it++) {
-    it->needs_wait_before_read = true;
-  }
-}
-
 #endif
 
 class NativeImageBufferStub : public NativeImageBuffer {
@@ -306,15 +231,11 @@
   NativeImageBufferStub() : NativeImageBuffer() {}
 
  private:
-  virtual ~NativeImageBufferStub() {}
-  virtual void AddClient(gfx::GLImage* client) override {}
-  virtual void RemoveClient(gfx::GLImage* client) override {}
-  virtual bool IsClient(gfx::GLImage* client) override { return true; }
-  virtual void BindToTexture(GLenum target) override {}
-  virtual void WillRead(gfx::GLImage* client) override {}
-  virtual void WillWrite(gfx::GLImage* client) override {}
-  virtual void DidRead(gfx::GLImage* client) override {}
-  virtual void DidWrite(gfx::GLImage* client) override {}
+  ~NativeImageBufferStub() override {}
+  void AddClient(gfx::GLImage* client) override {}
+  void RemoveClient(gfx::GLImage* client) override {}
+  bool IsClient(gfx::GLImage* client) override { return true; }
+  void BindToTexture(GLenum target) override {}
 
   DISALLOW_COPY_AND_ASSIGN(NativeImageBufferStub);
 };
diff --git a/gpu/command_buffer/service/texture_definition.h b/gpu/command_buffer/service/texture_definition.h
index 6df4b86..cb21abd 100644
--- a/gpu/command_buffer/service/texture_definition.h
+++ b/gpu/command_buffer/service/texture_definition.h
@@ -27,10 +27,6 @@
   virtual void RemoveClient(gfx::GLImage* client) = 0;
   virtual bool IsClient(gfx::GLImage* client) = 0;
   virtual void BindToTexture(GLenum target) = 0;
-  virtual void WillRead(gfx::GLImage* client) = 0;
-  virtual void WillWrite(gfx::GLImage* client) = 0;
-  virtual void DidRead(gfx::GLImage* client) = 0;
-  virtual void DidWrite(gfx::GLImage* client) = 0;
 
  protected:
   friend class base::RefCountedThreadSafe<NativeImageBuffer>;
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 9604cb1c..157138f 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -2167,16 +2167,14 @@
     current_size_[1] = 0;
   }
 
-  virtual void TrackMemoryAllocatedChange(size_t old_size,
-                                          size_t new_size,
-                                          Pool pool)  override {
+  void TrackMemoryAllocatedChange(size_t old_size,
+                                  size_t new_size,
+                                  Pool pool) override {
     DCHECK_LT(static_cast<size_t>(pool), arraysize(current_size_));
     current_size_[pool] += new_size - old_size;
   }
 
-  virtual bool EnsureGPUMemoryAvailable(size_t size_needed) override {
-    return true;
-  }
+  bool EnsureGPUMemoryAvailable(size_t size_needed) override { return true; }
 
   size_t GetSize(Pool pool) {
     DCHECK_LT(static_cast<size_t>(pool), arraysize(current_size_));
@@ -2184,7 +2182,7 @@
   }
 
  private:
-  virtual ~CountingMemoryTracker() {}
+  ~CountingMemoryTracker() override {}
 
   size_t current_size_[2];
   DISALLOW_COPY_AND_ASSIGN(CountingMemoryTracker);
diff --git a/gpu/command_buffer/service/transfer_buffer_manager.h b/gpu/command_buffer/service/transfer_buffer_manager.h
index 40cd168a..f867790 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager.h
+++ b/gpu/command_buffer/service/transfer_buffer_manager.h
@@ -32,14 +32,14 @@
   TransferBufferManager();
 
   bool Initialize();
-  virtual bool RegisterTransferBuffer(int32 id,
-                                      scoped_ptr<BufferBacking> buffer_backing)
-      override;
-  virtual void DestroyTransferBuffer(int32 id) override;
-  virtual scoped_refptr<Buffer> GetTransferBuffer(int32 id) override;
+  bool RegisterTransferBuffer(
+      int32 id,
+      scoped_ptr<BufferBacking> buffer_backing) override;
+  void DestroyTransferBuffer(int32 id) override;
+  scoped_refptr<Buffer> GetTransferBuffer(int32 id) override;
 
  private:
-  virtual ~TransferBufferManager();
+  ~TransferBufferManager() override;
 
   typedef base::hash_map<int32, scoped_refptr<Buffer> > BufferMap;
   BufferMap registered_buffers_;
diff --git a/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc b/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
index 44d0840..563b6cb7 100644
--- a/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/transfer_buffer_manager_unittest.cc
@@ -57,10 +57,10 @@
 
 class FakeBufferBacking : public BufferBacking {
  public:
-  virtual void* GetMemory() const override {
+  void* GetMemory() const override {
     return reinterpret_cast<void*>(0xBADF00D0);
   }
-  virtual size_t GetSize() const override { return 42; }
+  size_t GetSize() const override { return 42; }
   static scoped_ptr<BufferBacking> Make() {
     return scoped_ptr<BufferBacking>(new FakeBufferBacking);
   }
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 56787789..bb2acbd 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -62,21 +62,21 @@
   }
 
   // Overridden from gfx::GpuMemoryBuffer:
-  virtual void* Map() override {
+  void* Map() override {
     mapped_ = true;
     return &bytes_->data().front();
   }
-  virtual void Unmap() override { mapped_ = false; }
-  virtual bool IsMapped() const override { return mapped_; }
-  virtual Format GetFormat() const override { return format_; }
-  virtual uint32 GetStride() const override {
+  void Unmap() override { mapped_ = false; }
+  bool IsMapped() const override { return mapped_; }
+  Format GetFormat() const override { return format_; }
+  uint32 GetStride() const override {
     return size_.width() * BytesPerPixel(format_);
   }
-  virtual gfx::GpuMemoryBufferHandle GetHandle() const override {
+  gfx::GpuMemoryBufferHandle GetHandle() const override {
     NOTREACHED();
     return gfx::GpuMemoryBufferHandle();
   }
-  virtual ClientBuffer AsClientBuffer() override {
+  ClientBuffer AsClientBuffer() override {
     return reinterpret_cast<ClientBuffer>(this);
   }
 
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h
index d76ca5b5..03ed6a1 100644
--- a/gpu/command_buffer/tests/gl_manager.h
+++ b/gpu/command_buffer/tests/gl_manager.h
@@ -59,7 +59,7 @@
     bool context_lost_allowed;
   };
   GLManager();
-  virtual ~GLManager();
+  ~GLManager() override;
 
   static scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer(
       const gfx::Size& size,
@@ -95,25 +95,24 @@
   const gpu::gles2::FeatureInfo::Workarounds& workarounds() const;
 
   // GpuControl implementation.
-  virtual Capabilities GetCapabilities() override;
-  virtual int32 CreateImage(ClientBuffer buffer,
-                            size_t width,
-                            size_t height,
-                            unsigned internalformat) override;
-  virtual void DestroyImage(int32 id) override;
-  virtual int32 CreateGpuMemoryBufferImage(size_t width,
-                                           size_t height,
-                                           unsigned internalformat,
-                                           unsigned usage) override;
-  virtual uint32 InsertSyncPoint() override;
-  virtual uint32 InsertFutureSyncPoint() override;
-  virtual void RetireSyncPoint(uint32 sync_point) override;
-  virtual void SignalSyncPoint(uint32 sync_point,
-                               const base::Closure& callback) override;
-  virtual void SignalQuery(uint32 query,
-                           const base::Closure& callback) override;
-  virtual void SetSurfaceVisible(bool visible) override;
-  virtual uint32 CreateStreamTexture(uint32 texture_id) override;
+  Capabilities GetCapabilities() override;
+  int32 CreateImage(ClientBuffer buffer,
+                    size_t width,
+                    size_t height,
+                    unsigned internalformat) override;
+  void DestroyImage(int32 id) override;
+  int32 CreateGpuMemoryBufferImage(size_t width,
+                                   size_t height,
+                                   unsigned internalformat,
+                                   unsigned usage) override;
+  uint32 InsertSyncPoint() override;
+  uint32 InsertFutureSyncPoint() override;
+  void RetireSyncPoint(uint32 sync_point) override;
+  void SignalSyncPoint(uint32 sync_point,
+                       const base::Closure& callback) override;
+  void SignalQuery(uint32 query, const base::Closure& callback) override;
+  void SetSurfaceVisible(bool visible) override;
+  uint32 CreateStreamTexture(uint32 texture_id) override;
 
  private:
   void PumpCommands();
diff --git a/gpu/config/DEPS b/gpu/config/DEPS
index 7c0ee4b..39b325a 100644
--- a/gpu/config/DEPS
+++ b/gpu/config/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
   "+third_party/libxml",  # For parsing WinSAT results files.
   "+third_party/libXNVCtrl",  # For NV driver version query.
-  "+media/video",  # For VideoEncodeAccelerator::SupportedProfile.
 ]
diff --git a/gpu/config/gpu_blacklist.h b/gpu/config/gpu_blacklist.h
index 4311212e..6b2138a 100644
--- a/gpu/config/gpu_blacklist.h
+++ b/gpu/config/gpu_blacklist.h
@@ -13,7 +13,7 @@
 
 class GPU_EXPORT GpuBlacklist : public GpuControlList {
  public:
-  virtual ~GpuBlacklist();
+  ~GpuBlacklist() override;
 
   static GpuBlacklist* Create();
 
diff --git a/gpu/config/gpu_driver_bug_list.h b/gpu/config/gpu_driver_bug_list.h
index a4bd3bb..8830cac 100644
--- a/gpu/config/gpu_driver_bug_list.h
+++ b/gpu/config/gpu_driver_bug_list.h
@@ -17,7 +17,7 @@
 
 class GPU_EXPORT GpuDriverBugList : public GpuControlList {
  public:
-  virtual ~GpuDriverBugList();
+  ~GpuDriverBugList() override;
 
   static GpuDriverBugList* Create();
 
diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc
index c7951f9..f1f67ce 100644
--- a/gpu/config/gpu_info.cc
+++ b/gpu/config/gpu_info.cc
@@ -19,7 +19,7 @@
 
 void EnumerateVideoEncodeAcceleratorSupportedProfile(
     gpu::GPUInfo::Enumerator* enumerator,
-    const media::VideoEncodeAccelerator::SupportedProfile profile) {
+    const gpu::VideoEncodeAcceleratorSupportedProfile profile) {
   enumerator->BeginVideoEncodeAcceleratorSupportedProfile();
   enumerator->AddInt("profile", profile.profile);
   enumerator->AddInt("maxResolutionWidth", profile.max_resolution.width());
@@ -101,7 +101,7 @@
     CollectInfoResult dx_diagnostics_info_state;
     DxDiagNode dx_diagnostics;
 #endif
-    std::vector<media::VideoEncodeAccelerator::SupportedProfile>
+    std::vector<VideoEncodeAcceleratorSupportedProfile>
         video_encode_accelerator_supported_profiles;
   };
 
diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h
index bdbb205..7c92d3a 100644
--- a/gpu/config/gpu_info.h
+++ b/gpu/config/gpu_info.h
@@ -18,7 +18,7 @@
 #include "gpu/config/dx_diag_node.h"
 #include "gpu/config/gpu_performance_stats.h"
 #include "gpu/gpu_export.h"
-#include "media/video/video_encode_accelerator.h"
+#include "ui/gfx/geometry/size.h"
 
 namespace gpu {
 
@@ -35,6 +35,34 @@
   kCollectInfoFatalFailure = 3
 };
 
+// Video profile.  This *must* match media::VideoCodecProfile.
+enum VideoCodecProfile {
+  VIDEO_CODEC_PROFILE_UNKNOWN = -1,
+  VIDEO_CODEC_PROFILE_MIN = VIDEO_CODEC_PROFILE_UNKNOWN,
+  H264PROFILE_BASELINE = 0,
+  H264PROFILE_MAIN = 1,
+  H264PROFILE_EXTENDED = 2,
+  H264PROFILE_HIGH = 3,
+  H264PROFILE_HIGH10PROFILE = 4,
+  H264PROFILE_HIGH422PROFILE = 5,
+  H264PROFILE_HIGH444PREDICTIVEPROFILE = 6,
+  H264PROFILE_SCALABLEBASELINE = 7,
+  H264PROFILE_SCALABLEHIGH = 8,
+  H264PROFILE_STEREOHIGH = 9,
+  H264PROFILE_MULTIVIEWHIGH = 10,
+  VP8PROFILE_ANY = 11,
+  VP9PROFILE_ANY = 12,
+  VIDEO_CODEC_PROFILE_MAX = VP9PROFILE_ANY,
+};
+
+// Specification of an encoding profile supported by a hardware encoder.
+struct GPU_EXPORT VideoEncodeAcceleratorSupportedProfile {
+  VideoCodecProfile profile;
+  gfx::Size max_resolution;
+  uint32 max_framerate_numerator;
+  uint32 max_framerate_denominator;
+};
+
 struct GPU_EXPORT GPUInfo {
   struct GPU_EXPORT GPUDevice {
     GPUDevice();
@@ -178,7 +206,7 @@
   DxDiagNode dx_diagnostics;
 #endif
 
-  std::vector<media::VideoEncodeAccelerator::SupportedProfile>
+  std::vector<VideoEncodeAcceleratorSupportedProfile>
       video_encode_accelerator_supported_profiles;
   // Note: when adding new members, please remember to update EnumerateFields
   // in gpu_info.cc.
@@ -204,7 +232,7 @@
     virtual void BeginGPUDevice() = 0;
     virtual void EndGPUDevice() = 0;
 
-    // Markers indicating that a VideoEncodeAccelerator::SupportedProfile is
+    // Markers indicating that a VideoEncodeAcceleratorSupportedProfile is
     // being described.
     virtual void BeginVideoEncodeAcceleratorSupportedProfile() = 0;
     virtual void EndVideoEncodeAcceleratorSupportedProfile() = 0;
diff --git a/gpu/config/gpu_test_config.h b/gpu/config/gpu_test_config.h
index 8600a4a..b83e027 100644
--- a/gpu/config/gpu_test_config.h
+++ b/gpu/config/gpu_test_config.h
@@ -92,10 +92,10 @@
 class GPU_EXPORT GPUTestBotConfig : public GPUTestConfig {
  public:
   GPUTestBotConfig() { }
-  virtual ~GPUTestBotConfig();
+  ~GPUTestBotConfig() override;
 
   // This should only be called when no gpu_vendor is added.
-  virtual void AddGPUVendor(uint32 gpu_vendor) override;
+  void AddGPUVendor(uint32 gpu_vendor) override;
 
   // Return false if gpu_info does not have valid vendor_id and device_id.
   bool SetGPUInfo(const GPUInfo& gpu_info);
@@ -103,7 +103,7 @@
   // Check if the bot config is valid, i.e., if it is one valid test-bot
   // environment. For example, if a field is unknown, or if OS is not one
   // fully defined OS, then it's valid.
-  virtual bool IsValid() const override;
+  bool IsValid() const override;
 
   // Check if a bot config matches a test config, i.e., the test config is a
   // superset of the bot config.
diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h
index a1e82fe..651ab1a 100644
--- a/gpu/gles2_conform_support/egl/display.h
+++ b/gpu/gles2_conform_support/egl/display.h
@@ -38,7 +38,7 @@
 class Display : private gpu::GpuControl {
  public:
   explicit Display(EGLNativeDisplayType display_id);
-  virtual ~Display();
+  ~Display() override;
 
   void SetCreateOffscreen(int width, int height) {
     create_offscreen_ = true;
@@ -74,25 +74,24 @@
   bool MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx);
 
   // GpuControl implementation.
-  virtual gpu::Capabilities GetCapabilities() override;
-  virtual int32_t CreateImage(ClientBuffer buffer,
-                              size_t width,
-                              size_t height,
-                              unsigned internalformat) override;
-  virtual void DestroyImage(int32_t id) override;
-  virtual int32_t CreateGpuMemoryBufferImage(size_t width,
-                                             size_t height,
-                                             unsigned internalformat,
-                                             unsigned usage) override;
-  virtual uint32 InsertSyncPoint() override;
-  virtual uint32 InsertFutureSyncPoint() override;
-  virtual void RetireSyncPoint(uint32 sync_point) override;
-  virtual void SignalSyncPoint(uint32 sync_point,
-                               const base::Closure& callback) override;
-  virtual void SignalQuery(uint32 query,
-                           const base::Closure& callback) override;
-  virtual void SetSurfaceVisible(bool visible) override;
-  virtual uint32 CreateStreamTexture(uint32 texture_id) override;
+  gpu::Capabilities GetCapabilities() override;
+  int32_t CreateImage(ClientBuffer buffer,
+                      size_t width,
+                      size_t height,
+                      unsigned internalformat) override;
+  void DestroyImage(int32_t id) override;
+  int32_t CreateGpuMemoryBufferImage(size_t width,
+                                     size_t height,
+                                     unsigned internalformat,
+                                     unsigned usage) override;
+  uint32 InsertSyncPoint() override;
+  uint32 InsertFutureSyncPoint() override;
+  void RetireSyncPoint(uint32 sync_point) override;
+  void SignalSyncPoint(uint32 sync_point,
+                       const base::Closure& callback) override;
+  void SignalQuery(uint32 query, const base::Closure& callback) override;
+  void SetSurfaceVisible(bool visible) override;
+  uint32 CreateStreamTexture(uint32 texture_id) override;
 
  private:
   EGLNativeDisplayType display_id_;
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index c152baf..5968dab1 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -29,6 +29,11 @@
       'sources': [
         '<@(gles2_implementation_source_files)',
       ],
+      'includes': [
+        # Disable LTO due to ELF section name out of range
+        # crbug.com/422251
+        '../build/android/disable_lto.gypi',
+      ],
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
       'msvs_disabled_warnings': [4267, ],
     },
@@ -479,6 +484,9 @@
           'includes': [
             'command_buffer_service.gypi',
             '../build/android/increase_size_for_speed.gypi',
+            # Disable LTO due to ELF section name out of range
+            # crbug.com/422251
+            '../build/android/disable_lto.gypi',
           ],
           'dependencies': [
             'command_buffer_common',
diff --git a/gpu/gpu_nacl.gyp b/gpu/gpu_nacl.gyp
index 3d8a1c1..003f0af 100644
--- a/gpu/gpu_nacl.gyp
+++ b/gpu/gpu_nacl.gyp
@@ -24,6 +24,8 @@
             'build_glibc': 0,
             'build_newlib': 0,
             'build_irt': 1,
+            'build_pnacl_newlib': 0,
+            'build_nonsfi_helper': 1,
           },
           'defines': [
             'GLES2_IMPL_IMPLEMENTATION',
@@ -32,8 +34,9 @@
             '<@(gles2_implementation_source_files)',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../base/base_nacl.gyp:base_nacl',
+            '../base/base_nacl.gyp:base_nacl_nonsfi',
+            '../native_client/tools.gyp:prep_toolchain',
             '../third_party/khronos/khronos.gyp:khronos_headers',
             'command_buffer/command_buffer_nacl.gyp:gles2_utils_nacl',
             'gles2_cmd_helper_nacl',
@@ -48,13 +51,16 @@
             'build_glibc': 0,
             'build_newlib': 0,
             'build_irt': 1,
+            'build_pnacl_newlib': 0,
+            'build_nonsfi_helper': 1,
           },
           'includes': [
             'command_buffer_common.gypi',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../base/base_nacl.gyp:base_nacl',
+            '../base/base_nacl.gyp:base_nacl_nonsfi',
+            '../native_client/tools.gyp:prep_toolchain',
             'command_buffer/command_buffer_nacl.gyp:gles2_utils_nacl',
           ],
         },
@@ -67,13 +73,16 @@
             'build_glibc': 0,
             'build_newlib': 0,
             'build_irt': 1,
+            'build_pnacl_newlib': 0,
+            'build_nonsfi_helper': 1,
           },
           'includes': [
             'gles2_cmd_helper.gypi',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../base/base_nacl.gyp:base_nacl',
+            '../base/base_nacl.gyp:base_nacl_nonsfi',
+            '../native_client/tools.gyp:prep_toolchain',
             'command_buffer_client_nacl',
           ],
         },
@@ -86,13 +95,16 @@
             'build_glibc': 0,
             'build_newlib': 0,
             'build_irt': 1,
+            'build_pnacl_newlib': 0,
+            'build_nonsfi_helper': 1,
           },
           'includes': [
             'command_buffer_client.gypi',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../base/base_nacl.gyp:base_nacl',
+            '../base/base_nacl.gyp:base_nacl_nonsfi',
+            '../native_client/tools.gyp:prep_toolchain',
             'command_buffer_common_nacl',
           ],
         },
@@ -105,13 +117,16 @@
             'build_glibc': 0,
             'build_newlib': 0,
             'build_irt': 1,
+            'build_pnacl_newlib': 0,
+            'build_nonsfi_helper': 1,
           },
           'includes': [
             'gpu_ipc.gypi',
           ],
           'dependencies': [
-            '../native_client/tools.gyp:prep_toolchain',
             '../base/base_nacl.gyp:base_nacl',
+            '../base/base_nacl.gyp:base_nacl_nonsfi',
+            '../native_client/tools.gyp:prep_toolchain',
             'command_buffer_common_nacl',
           ],
         },
diff --git a/ios/ios_tests_unit.gyp b/ios/ios_tests_unit.gyp
index 5b76f89..a9549aa 100644
--- a/ios/ios_tests_unit.gyp
+++ b/ios/ios_tests_unit.gyp
@@ -16,9 +16,11 @@
         '../testing/gmock.gyp:gmock',
         '../testing/gtest.gyp:gtest',
         'ios_base.gyp:ios_consumer_base',
+        'web/ios_web.gyp:ios_web',
       ],
       'sources': [
         'consumer/base/supports_user_data_unittest.cc',
+        'web/navigation/navigation_item_impl_unittest.mm',
       ],
     },
   ],
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp
index 1742121..7522981 100644
--- a/ios/web/ios_web.gyp
+++ b/ios/web/ios_web.gyp
@@ -15,11 +15,17 @@
       ],
       'dependencies': [
         '../../base/base.gyp:base',
+        '../../net/net.gyp:net',
+        '../../ui/base/ui_base.gyp:ui_base',
+        '../../ui/gfx/gfx.gyp:gfx',
       ],
       'sources': [
+        'navigation/navigation_item_impl.h',
+        'navigation/navigation_item_impl.mm',
         'public/favicon_status.cc',
         'public/favicon_status.h',
         'public/navigation_item.h',
+        'public/referrer.h',
         'public/security_style.h',
         'public/ssl_status.cc',
         'public/ssl_status.h',
diff --git a/ios/web/navigation/navigation_item_impl.h b/ios/web/navigation/navigation_item_impl.h
new file mode 100644
index 0000000..1e4707f
--- /dev/null
+++ b/ios/web/navigation/navigation_item_impl.h
@@ -0,0 +1,70 @@
+// 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 IOS_WEB_NAVIGATION_NAVIGATION_ITEM_IMPL_H_
+#define IOS_WEB_NAVIGATION_NAVIGATION_ITEM_IMPL_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
+#include "ios/web/public/favicon_status.h"
+#include "ios/web/public/navigation_item.h"
+#include "ios/web/public/referrer.h"
+#include "ios/web/public/ssl_status.h"
+#include "url/gurl.h"
+
+namespace web {
+
+// Implementation of NavigationItem.
+class NavigationItemImpl : public web::NavigationItem {
+ public:
+  // Creates a default NavigationItemImpl.
+  NavigationItemImpl();
+  virtual ~NavigationItemImpl();
+
+  // NavigationItem implementation:
+  virtual int GetUniqueID() const override;
+  virtual void SetURL(const GURL& url) override;
+  virtual const GURL& GetURL() const override;
+  virtual void SetReferrer(const web::Referrer& referrer) override;
+  virtual const web::Referrer& GetReferrer() const override;
+  virtual void SetVirtualURL(const GURL& url) override;
+  virtual const GURL& GetVirtualURL() const override;
+  virtual void SetTitle(const base::string16& title) override;
+  virtual const base::string16& GetTitle() const override;
+  virtual void SetPageID(int page_id) override;
+  virtual int32 GetPageID() const override;
+  virtual const base::string16& GetTitleForDisplay(
+      const std::string& languages) const override;
+  virtual void SetTransitionType(ui::PageTransition transition_type) override;
+  virtual ui::PageTransition GetTransitionType() const override;
+  virtual const FaviconStatus& GetFavicon() const override;
+  virtual FaviconStatus& GetFavicon() override;
+  virtual const SSLStatus& GetSSL() const override;
+  virtual SSLStatus& GetSSL() override;
+  virtual void SetTimestamp(base::Time timestamp) override;
+  virtual base::Time GetTimestamp() const override;
+
+ private:
+  int unique_id_;
+  GURL url_;
+  Referrer referrer_;
+  GURL virtual_url_;
+  base::string16 title_;
+  int32 page_id_;
+  ui::PageTransition transition_type_;
+  FaviconStatus favicon_;
+  SSLStatus ssl_;
+  base::Time timestamp_;
+
+  // This is a cached version of the result of GetTitleForDisplay. When the URL,
+  // virtual URL, or title is set, this should be cleared to force a refresh.
+  mutable base::string16 cached_display_title_;
+
+  // Copy and assignment is explicitly allowed for this class.
+};
+
+}  // namespace web
+
+#endif  // IOS_WEB_NAVIGATION_NAVIGATION_ITEM_IMPL_H_
diff --git a/ios/web/navigation/navigation_item_impl.mm b/ios/web/navigation/navigation_item_impl.mm
new file mode 100644
index 0000000..1f86d72b
--- /dev/null
+++ b/ios/web/navigation/navigation_item_impl.mm
@@ -0,0 +1,151 @@
+// 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 "ios/web/navigation/navigation_item_impl.h"
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/net_util.h"
+#include "ui/base/page_transition_types.h"
+#include "ui/gfx/text_elider.h"
+
+namespace {
+
+// Returns a new unique ID for use in NavigationItem during construction.  The
+// returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
+static int GetUniqueIDInConstructor() {
+  static int unique_id_counter = 0;
+  return ++unique_id_counter;
+}
+
+}  // namespace
+
+namespace web {
+
+// static
+scoped_ptr<NavigationItem> NavigationItem::Create() {
+  return scoped_ptr<NavigationItem>(new NavigationItemImpl());
+}
+
+NavigationItemImpl::NavigationItemImpl()
+    : unique_id_(GetUniqueIDInConstructor()),
+      page_id_(-1),
+      transition_type_(ui::PAGE_TRANSITION_LINK) {
+}
+
+NavigationItemImpl::~NavigationItemImpl() {
+}
+
+int NavigationItemImpl::GetUniqueID() const {
+  return unique_id_;
+}
+
+void NavigationItemImpl::SetURL(const GURL& url) {
+  url_ = url;
+  cached_display_title_.clear();
+}
+
+const GURL& NavigationItemImpl::GetURL() const {
+  return url_;
+}
+
+void NavigationItemImpl::SetReferrer(const web::Referrer& referrer) {
+  referrer_ = referrer;
+}
+
+const web::Referrer& NavigationItemImpl::GetReferrer() const {
+  return referrer_;
+}
+
+void NavigationItemImpl::SetVirtualURL(const GURL& url) {
+  virtual_url_ = (url == url_) ? GURL() : url;
+  cached_display_title_.clear();
+}
+
+const GURL& NavigationItemImpl::GetVirtualURL() const {
+  return virtual_url_.is_empty() ? url_ : virtual_url_;
+}
+
+void NavigationItemImpl::SetTitle(const base::string16& title) {
+  title_ = title;
+  cached_display_title_.clear();
+}
+
+const base::string16& NavigationItemImpl::GetTitle() const {
+  return title_;
+}
+
+void NavigationItemImpl::SetPageID(int page_id) {
+  page_id_ = page_id;
+}
+
+int32 NavigationItemImpl::GetPageID() const {
+  return page_id_;
+}
+
+const base::string16& NavigationItemImpl::GetTitleForDisplay(
+    const std::string& languages) const {
+  // Most pages have real titles. Don't even bother caching anything if this is
+  // the case.
+  if (!title_.empty())
+    return title_;
+
+  // More complicated cases will use the URLs as the title. This result we will
+  // cache since it's more complicated to compute.
+  if (!cached_display_title_.empty())
+    return cached_display_title_;
+
+  // Use the virtual URL first if any, and fall back on using the real URL.
+  base::string16 title;
+  if (!virtual_url_.is_empty()) {
+    title = net::FormatUrl(virtual_url_, languages);
+  } else if (!url_.is_empty()) {
+    title = net::FormatUrl(url_, languages);
+  }
+
+  // For file:// URLs use the filename as the title, not the full path.
+  if (url_.SchemeIsFile()) {
+    base::string16::size_type slashpos = title.rfind('/');
+    if (slashpos != base::string16::npos)
+      title = title.substr(slashpos + 1);
+  }
+
+  const int kMaxTitleChars = 4 * 1024;
+  gfx::ElideString(title, kMaxTitleChars, &cached_display_title_);
+  return cached_display_title_;
+}
+
+void NavigationItemImpl::SetTransitionType(ui::PageTransition transition_type) {
+  transition_type_ = transition_type;
+}
+
+ui::PageTransition NavigationItemImpl::GetTransitionType() const {
+  return transition_type_;
+}
+
+const FaviconStatus& NavigationItemImpl::GetFavicon() const {
+  return favicon_;
+}
+
+FaviconStatus& NavigationItemImpl::GetFavicon() {
+  return favicon_;
+}
+
+const SSLStatus& NavigationItemImpl::GetSSL() const {
+  return ssl_;
+}
+
+SSLStatus& NavigationItemImpl::GetSSL() {
+  return ssl_;
+}
+
+void NavigationItemImpl::SetTimestamp(base::Time timestamp) {
+  timestamp_ = timestamp;
+}
+
+base::Time NavigationItemImpl::GetTimestamp() const {
+  return timestamp_;
+}
+
+}  // namespace web
diff --git a/ios/web/navigation/navigation_item_impl_unittest.mm b/ios/web/navigation/navigation_item_impl_unittest.mm
new file mode 100644
index 0000000..4c64221a
--- /dev/null
+++ b/ios/web/navigation/navigation_item_impl_unittest.mm
@@ -0,0 +1,33 @@
+// 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 "base/logging.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
+#include "ios/web/navigation/navigation_item_impl.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
+#include "testing/platform_test.h"
+
+namespace web {
+namespace {
+
+class NavigationItemTest : public PlatformTest {
+ protected:
+  virtual void SetUp() {
+    item_.reset(new NavigationItemImpl());
+  }
+
+  scoped_ptr<NavigationItemImpl> item_;
+};
+
+// TODO(rohitrao): Add and adapt tests from NavigationEntryImpl.
+TEST_F(NavigationItemTest, Dummy) {
+  const GURL url("http://init.test");
+  item_->SetURL(url);
+  EXPECT_TRUE(item_->GetURL().is_valid());
+}
+
+}  // namespace
+}  // namespace web
diff --git a/ios/web/public/navigation_item.h b/ios/web/public/navigation_item.h
index 8b2af55..a17a7e44 100644
--- a/ios/web/public/navigation_item.h
+++ b/ios/web/public/navigation_item.h
@@ -5,6 +5,7 @@
 #ifndef IOS_WEB_PUBLIC_NAVIGATION_ITEM_H_
 #define IOS_WEB_PUBLIC_NAVIGATION_ITEM_H_
 
+#include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
 #include "base/time/time.h"
 #include "ui/base/page_transition_types.h"
@@ -23,6 +24,9 @@
  public:
   virtual ~NavigationItem() {}
 
+  // Creates a new NavigationItem.
+  static scoped_ptr<NavigationItem> Create();
+
   // Page-related stuff --------------------------------------------------------
 
   // A unique ID is preserved across commits and redirects, which means that
diff --git a/ios/web/public/referrer.h b/ios/web/public/referrer.h
new file mode 100644
index 0000000..3110c892
--- /dev/null
+++ b/ios/web/public/referrer.h
@@ -0,0 +1,34 @@
+// 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 IOS_WEB_PUBLIC_REFERRER_H_
+#define IOS_WEB_PUBLIC_REFERRER_H_
+
+#include "base/logging.h"
+#include "url/gurl.h"
+
+namespace web {
+
+enum ReferrerPolicy {
+  ReferrerPolicyAlways,
+  ReferrerPolicyDefault,
+  ReferrerPolicyNever,
+  ReferrerPolicyOrigin,
+  ReferrerPolicyLast = ReferrerPolicyOrigin
+};
+
+// This struct holds a referrer URL, as well as the referrer policy to be
+// applied to this URL. When passing around referrers that will eventually end
+// up being used for URL requests, always use this struct.
+struct Referrer {
+  Referrer(const GURL& url, ReferrerPolicy policy) : url(url), policy(policy) {}
+  Referrer() : policy(ReferrerPolicyDefault) {}
+
+  GURL url;
+  ReferrerPolicy policy;
+};
+
+}  // namespace web
+
+#endif  // IOS_WEB_PUBLIC_REFERRER_H_
diff --git a/ipc/ipc_channel.cc b/ipc/ipc_channel.cc
index a6ee14c..4a4e40d 100644
--- a/ipc/ipc_channel.cc
+++ b/ipc/ipc_channel.cc
@@ -10,14 +10,12 @@
 #include "base/rand_util.h"
 #include "base/strings/stringprintf.h"
 
-#if !defined(OS_NACL)
 namespace {
 
 // Global atomic used to guarantee channel IDs are unique.
 base::StaticAtomicSequenceNumber g_last_id;
 
 }  // namespace
-#endif
 
 namespace IPC {
 
@@ -39,4 +37,3 @@
 }
 
 }  // namespace IPC
-
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h
index 2d8d449..3ed5e6a 100644
--- a/ipc/ipc_channel.h
+++ b/ipc/ipc_channel.h
@@ -179,7 +179,11 @@
   // deleted once the contents of the Message have been sent.
   virtual bool Send(Message* message) = 0;
 
-#if defined(OS_POSIX) && !defined(OS_NACL)
+  // NaCl in Non-SFI mode runs on Linux directly, and the following functions
+  // compiled on Linux are also needed. Please see also comments in
+  // components/nacl_nonsfi.gyp for more details.
+#if defined(OS_POSIX) && \
+    (!defined(OS_NACL) || defined(__native_client_nonsfi__))
   // On POSIX an IPC::Channel wraps a socketpair(), this method returns the
   // FD # for the client end of the socket.
   // This method may only be called on the server side of a channel.
@@ -190,13 +194,13 @@
   // file descriptor to the caller.
   // This method can be called on any thread.
   virtual base::ScopedFD TakeClientFileDescriptor() = 0;
-#endif  // defined(OS_POSIX) && !defined(OS_NACL)
+#endif
 
   // Returns true if a named server channel is initialized on the given channel
   // ID. Even if true, the server may have already accepted a connection.
   static bool IsNamedServerInitialized(const std::string& channel_id);
 
-#if !defined(OS_NACL)
+#if !defined(OS_NACL) || defined(__native_client_nonsfi__)
   // Generates a channel ID that's non-predictable and unique.
   static std::string GenerateUniqueRandomChannelID();
 
diff --git a/ipc/ipc_channel_factory.cc b/ipc/ipc_channel_factory.cc
index 9bcaa75..c8431c0 100644
--- a/ipc/ipc_channel_factory.cc
+++ b/ipc/ipc_channel_factory.cc
@@ -15,7 +15,9 @@
       : handle_(handle), mode_(mode) {
   }
 
-  std::string GetName() const override { return handle_.name; }
+  std::string GetName() const override {
+    return handle_.name;
+  }
 
   scoped_ptr<Channel> BuildChannel(Listener* listener) override {
     return Channel::Create(handle_, mode_, listener);
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc
index c864db23..8e74c3a 100644
--- a/ipc/ipc_channel_posix.cc
+++ b/ipc/ipc_channel_posix.cc
@@ -10,13 +10,16 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/un.h>
 #include <unistd.h>
 
 #if defined(OS_OPENBSD)
 #include <sys/uio.h>
 #endif
 
+#if !defined(__native_client_nonsfi__)
+#include <sys/un.h>
+#endif
+
 #include <map>
 #include <string>
 
@@ -255,6 +258,10 @@
     }
 #endif   // IPC_USES_READWRITE
   } else if (mode_ & MODE_NAMED_FLAG) {
+#if defined(__native_client_nonsfi__)
+    LOG(FATAL)
+        << "IPC channels in nacl_helper_nonsfi should not be in NAMED mode.";
+#else
     // Case 2 from comment above.
     int local_pipe_fd = -1;
 
@@ -276,6 +283,7 @@
     }
 
     local_pipe.reset(local_pipe_fd);
+#endif  // !defined(__native_client_nonsfi__)
   } else {
     local_pipe.reset(PipeMap::GetInstance()->Lookup(pipe_name_));
     if (mode_ & MODE_CLIENT_FLAG) {
@@ -336,10 +344,16 @@
   }
 #endif  // IPC_USES_READWRITE
 
-  if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG))
+  if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) {
+#if defined(__native_client_nonsfi__)
+    LOG(FATAL) << "IPC channels in nacl_helper_nonsfi "
+               << "should not be in NAMED or SERVER mode.";
+#else
     server_listen_pipe_.reset(local_pipe.release());
-  else
+#endif
+  } else {
     pipe_.reset(local_pipe.release());
+  }
   return true;
 }
 
@@ -351,6 +365,10 @@
 
   bool did_connect = true;
   if (server_listen_pipe_.is_valid()) {
+#if defined(__native_client_nonsfi__)
+    LOG(FATAL) << "IPC channels in nacl_helper_nonsfi "
+               << "should always be in client mode.";
+#else
     // Watch the pipe for connections, and turn any connections into
     // active sockets.
     base::MessageLoopForIO::current()->WatchFileDescriptor(
@@ -359,6 +377,7 @@
         base::MessageLoopForIO::WATCH_READ,
         &server_listen_connection_watcher_,
         this);
+#endif
   } else {
     did_connect = AcceptConnection();
   }
@@ -581,10 +600,13 @@
   return AcceptsConnections() && pipe_.is_valid();
 }
 
+#if !defined(__native_client_nonsfi__)
+// GetPeerEuid is not supported in nacl_helper_nonsfi.
 bool ChannelPosix::GetPeerEuid(uid_t* peer_euid) const {
   DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection());
   return IPC::GetPeerEuid(pipe_.get(), peer_euid);
 }
+#endif
 
 void ChannelPosix::ResetToAcceptingConnectionState() {
   // Unregister libevent for the unix domain socket and close it.
@@ -633,6 +655,10 @@
 // Called by libevent when we can read from the pipe without blocking.
 void ChannelPosix::OnFileCanReadWithoutBlocking(int fd) {
   if (fd == server_listen_pipe_.get()) {
+#if defined(__native_client_nonsfi__)
+    LOG(FATAL)
+        << "IPC channels in nacl_helper_nonsfi should not be SERVER mode.";
+#else
     int new_pipe = 0;
     if (!ServerAcceptConnection(server_listen_pipe_.get(), &new_pipe) ||
         new_pipe < 0) {
@@ -671,6 +697,7 @@
       NOTREACHED() << "AcceptConnection should not fail on server";
     }
     waiting_connect_ = false;
+#endif
   } else if (fd == pipe_) {
     if (waiting_connect_ && (mode_ & MODE_SERVER_FLAG)) {
       waiting_connect_ = false;
@@ -923,11 +950,15 @@
                         file_descriptors,
                         file_descriptors + num_file_descriptors);
 
+#if !defined(__native_client_nonsfi__)
+      // The PNaCl toolchain for Non-SFI binary build does not support
+      // MSG_CTRUNC.
       // Check this after adding the FDs so we don't leak them.
       if (msg->msg_flags & MSG_CTRUNC) {
         ClearInputFDs();
         return false;
       }
+#endif
 
       return true;
     }
@@ -1032,9 +1063,14 @@
   }
 
   if (server_listen_pipe_.is_valid()) {
+#if defined(__native_client_nonsfi__)
+    LOG(FATAL)
+        << "IPC channels in nacl_helper_nonsfi should not be SERVER mode.";
+#else
     server_listen_pipe_.reset();
     // Unregister libevent for the listening socket and close it.
     server_listen_connection_watcher_.StopWatchingFileDescriptor();
+#endif
   }
 
   CloseClientFileDescriptor();
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc
index e2d7ad4..07f9552 100644
--- a/ipc/ipc_channel_proxy.cc
+++ b/ipc/ipc_channel_proxy.cc
@@ -434,7 +434,8 @@
   context()->ClearIPCTaskRunner();
 }
 
-#if defined(OS_POSIX) && !defined(OS_NACL)
+#if defined(OS_POSIX) && \
+    (!defined(OS_NACL) || defined(__native_client_nonsfi__))
 // See the TODO regarding lazy initialization of the channel in
 // ChannelProxy::Init().
 int ChannelProxy::GetClientFileDescriptor() {
diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h
index 71a014b..e2ad4a94 100644
--- a/ipc/ipc_channel_proxy.h
+++ b/ipc/ipc_channel_proxy.h
@@ -119,11 +119,12 @@
   // Returns base::kNullProcessId if the peer is not connected yet.
   base::ProcessId GetPeerPID() const { return context_->peer_pid_; }
 
-#if defined(OS_POSIX) && !defined(OS_NACL)
+#if defined(OS_POSIX) && \
+    (!defined(OS_NACL) || defined(__native_client_nonsfi__))
   // Calls through to the underlying channel's methods.
   int GetClientFileDescriptor();
   base::ScopedFD TakeClientFileDescriptor();
-#endif  // defined(OS_POSIX)
+#endif
 
  protected:
   class Context;
diff --git a/ipc/ipc_channel_unittest.cc b/ipc/ipc_channel_unittest.cc
index 1b28376..dd31e9e 100644
--- a/ipc/ipc_channel_unittest.cc
+++ b/ipc/ipc_channel_unittest.cc
@@ -148,7 +148,9 @@
   ChannelListenerWithOnConnectedSend() {}
   ~ChannelListenerWithOnConnectedSend() override {}
 
-  void OnChannelConnected(int32 peer_pid) override { SendNextMessage(); }
+  void OnChannelConnected(int32 peer_pid) override {
+    SendNextMessage();
+  }
 };
 
 #if defined(OS_WIN)
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h
index 6004155..96cc20b 100644
--- a/ipc/ipc_message_macros.h
+++ b/ipc/ipc_message_macros.h
@@ -606,57 +606,60 @@
     IPC_ASYNC_MESSAGE_METHODS_##in_cnt                                        \
   };
 
-#define IPC_ASYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \
-  class IPC_MESSAGE_EXPORT msg_class : public IPC::Message {                 \
-   public:                                                                   \
-    typedef IPC::MessageSchema<IPC_TUPLE_IN_##in_cnt in_list> Schema;        \
-    typedef Schema::Param Param;                                             \
-    enum { ID = IPC_MESSAGE_ID() };                                          \
-    msg_class(int32 routing_id                                               \
-                  IPC_COMMA_##in_cnt IPC_TYPE_IN_##in_cnt in_list);          \
-    ~msg_class() override;                                                   \
-    static bool Read(const Message* msg, Schema::Param* p);                  \
-    static void Log(std::string* name, const Message* msg, std::string* l);  \
-    IPC_ASYNC_MESSAGE_METHODS_##in_cnt                                       \
+#define IPC_ASYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list)  \
+  class IPC_MESSAGE_EXPORT msg_class : public IPC::Message {                  \
+   public:                                                                    \
+    typedef IPC::MessageSchema<IPC_TUPLE_IN_##in_cnt in_list> Schema;         \
+    typedef Schema::Param Param;                                              \
+    enum { ID = IPC_MESSAGE_ID() };                                           \
+    msg_class(int32 routing_id IPC_COMMA_##in_cnt                             \
+              IPC_TYPE_IN_##in_cnt in_list);                                  \
+    ~msg_class() override;                                                    \
+    static bool Read(const Message* msg, Schema::Param* p);                   \
+    static void Log(std::string* name, const Message* msg, std::string* l);   \
+    IPC_ASYNC_MESSAGE_METHODS_##in_cnt                                        \
   };
 
-#define IPC_SYNC_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list) \
-  class IPC_MESSAGE_EXPORT msg_class : public IPC::SyncMessage {             \
-   public:                                                                   \
-    typedef IPC::SyncMessageSchema<IPC_TUPLE_IN_##in_cnt in_list,            \
-                                   IPC_TUPLE_OUT_##out_cnt out_list> Schema; \
-    typedef Schema::ReplyParam ReplyParam;                                   \
-    typedef Schema::SendParam SendParam;                                     \
-    enum { ID = IPC_MESSAGE_ID() };                                          \
-    msg_class(IPC_TYPE_IN_##in_cnt in_list                                   \
-                  IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt)                \
-                      IPC_TYPE_OUT_##out_cnt out_list);                      \
-    ~msg_class() override;                                                   \
-    static bool ReadSendParam(const Message* msg, Schema::SendParam* p);     \
-    static bool ReadReplyParam(const Message* msg,                           \
-                               TupleTypes<ReplyParam>::ValueTuple* p);       \
-    static void Log(std::string* name, const Message* msg, std::string* l);  \
-    IPC_SYNC_MESSAGE_METHODS_##out_cnt                                       \
+#define IPC_SYNC_CONTROL_DECL(msg_class, in_cnt, out_cnt, in_list, out_list)  \
+  class IPC_MESSAGE_EXPORT msg_class : public IPC::SyncMessage {              \
+   public:                                                                    \
+    typedef IPC::SyncMessageSchema<IPC_TUPLE_IN_##in_cnt in_list,             \
+                                   IPC_TUPLE_OUT_##out_cnt out_list> Schema;  \
+    typedef Schema::ReplyParam ReplyParam;                                    \
+    typedef Schema::SendParam SendParam;                                      \
+    enum { ID = IPC_MESSAGE_ID() };                                           \
+    msg_class(IPC_TYPE_IN_##in_cnt in_list                                    \
+              IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt)                     \
+              IPC_TYPE_OUT_##out_cnt out_list);                               \
+    ~msg_class() override;                                                    \
+    static bool ReadSendParam(const Message* msg, Schema::SendParam* p);      \
+    static bool ReadReplyParam(                                               \
+        const Message* msg,                                                   \
+        TupleTypes<ReplyParam>::ValueTuple* p);                               \
+    static void Log(std::string* name, const Message* msg, std::string* l);   \
+    IPC_SYNC_MESSAGE_METHODS_##out_cnt                                        \
   };
 
-#define IPC_SYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list)  \
-  class IPC_MESSAGE_EXPORT msg_class : public IPC::SyncMessage {             \
-   public:                                                                   \
-    typedef IPC::SyncMessageSchema<IPC_TUPLE_IN_##in_cnt in_list,            \
-                                   IPC_TUPLE_OUT_##out_cnt out_list> Schema; \
-    typedef Schema::ReplyParam ReplyParam;                                   \
-    typedef Schema::SendParam SendParam;                                     \
-    enum { ID = IPC_MESSAGE_ID() };                                          \
-    msg_class(int32 routing_id IPC_COMMA_OR_##in_cnt(IPC_COMMA_##out_cnt)    \
-                  IPC_TYPE_IN_##in_cnt in_list                               \
-                      IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt)            \
-                          IPC_TYPE_OUT_##out_cnt out_list);                  \
-    ~msg_class() override;                                                   \
-    static bool ReadSendParam(const Message* msg, Schema::SendParam* p);     \
-    static bool ReadReplyParam(const Message* msg,                           \
-                               TupleTypes<ReplyParam>::ValueTuple* p);       \
-    static void Log(std::string* name, const Message* msg, std::string* l);  \
-    IPC_SYNC_MESSAGE_METHODS_##out_cnt                                       \
+#define IPC_SYNC_ROUTED_DECL(msg_class, in_cnt, out_cnt, in_list, out_list)   \
+  class IPC_MESSAGE_EXPORT msg_class : public IPC::SyncMessage {              \
+   public:                                                                    \
+    typedef IPC::SyncMessageSchema<IPC_TUPLE_IN_##in_cnt in_list,             \
+                                   IPC_TUPLE_OUT_##out_cnt out_list> Schema;  \
+    typedef Schema::ReplyParam ReplyParam;                                    \
+    typedef Schema::SendParam SendParam;                                      \
+    enum { ID = IPC_MESSAGE_ID() };                                           \
+    msg_class(int32 routing_id                                                \
+              IPC_COMMA_OR_##in_cnt(IPC_COMMA_##out_cnt)                      \
+              IPC_TYPE_IN_##in_cnt in_list                                    \
+              IPC_COMMA_AND_##in_cnt(IPC_COMMA_##out_cnt)                     \
+              IPC_TYPE_OUT_##out_cnt out_list);                               \
+    ~msg_class() override;                                                    \
+    static bool ReadSendParam(const Message* msg, Schema::SendParam* p);      \
+    static bool ReadReplyParam(                                               \
+        const Message* msg,                                                   \
+        TupleTypes<ReplyParam>::ValueTuple* p);                               \
+    static void Log(std::string* name, const Message* msg, std::string* l);   \
+    IPC_SYNC_MESSAGE_METHODS_##out_cnt                                        \
   };
 
 #if defined(IPC_MESSAGE_IMPL)
diff --git a/ipc/ipc_nacl.gyp b/ipc/ipc_nacl.gyp
index 3119f46c..6f0d522d 100644
--- a/ipc/ipc_nacl.gyp
+++ b/ipc/ipc_nacl.gyp
@@ -25,8 +25,38 @@
             'build_irt': 1,
           },
           'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
             '../base/base_nacl.gyp:base_nacl',
+            '../native_client/tools.gyp:prep_toolchain',
+          ],
+        },
+        {
+          'target_name': 'ipc_nacl_nonsfi',
+          'type': 'none',
+          'variables': {
+            'ipc_target': 1,
+            'nacl_untrusted_build': 1,
+            'nlib_target': 'libipc_nacl_nonsfi.a',
+            'build_glibc': 0,
+            'build_newlib': 0,
+            'build_irt': 0,
+            'build_pnacl_newlib': 0,
+            'build_nonsfi_helper': 1,
+
+            # Use linux IPC channel implementation for nacl_helper_nonsfi,
+            # instead of NaCl's IPC implementation (ipc_channel_nacl.cc),
+            # because nacl_helper_nonsfi will be running directly on Linux.
+            # ipc_channel_nacl.cc is excluded below.
+            'sources': [
+              'ipc_channel.cc',
+              'ipc_channel_posix.cc',
+            ],
+          },
+          'sources!': [
+            'ipc_channel_nacl.cc',
+          ],
+          'dependencies': [
+            '../base/base_nacl.gyp:base_nacl_nonsfi',
+            '../native_client/tools.gyp:prep_toolchain',
           ],
         },
       ],
diff --git a/ipc/ipc_perftest_support.cc b/ipc/ipc_perftest_support.cc
index ab06ed61b..d0cbe5e 100644
--- a/ipc/ipc_perftest_support.cc
+++ b/ipc/ipc_perftest_support.cc
@@ -142,7 +142,9 @@
     VLOG(1) << "Server listener up";
   }
 
-  ~PerformanceChannelListener() override { VLOG(1) << "Server listener down"; }
+  ~PerformanceChannelListener() override {
+    VLOG(1) << "Server listener down";
+  }
 
   void Init(Sender* sender) {
     DCHECK(!sender_);
diff --git a/ipc/ipc_send_fds_test.cc b/ipc/ipc_send_fds_test.cc
index 332a6310..cf2c680 100644
--- a/ipc/ipc_send_fds_test.cc
+++ b/ipc/ipc_send_fds_test.cc
@@ -60,7 +60,9 @@
     return num_fds_received_ == kNumFDsToSend;
   }
 
-  void OnChannelError() override { base::MessageLoop::current()->Quit(); }
+  void OnChannelError() override {
+    base::MessageLoop::current()->Quit();
+  }
 
  protected:
   void HandleFD(int fd) override {
diff --git a/ipc/ipc_sync_channel_unittest.cc b/ipc/ipc_sync_channel_unittest.cc
index 9ad0e58c..f834ec3 100644
--- a/ipc/ipc_sync_channel_unittest.cc
+++ b/ipc/ipc_sync_channel_unittest.cc
@@ -969,7 +969,9 @@
                                         thread_.message_loop_proxy());
   }
 
-  void Run() override { channel()->AddFilter(filter_.get()); }
+  void Run() override {
+    channel()->AddFilter(filter_.get());
+  }
 
   base::Thread thread_;
   scoped_refptr<TestSyncMessageFilter> filter_;
@@ -1327,7 +1329,9 @@
         received_noarg_reply_(false),
         done_issued_(false) {}
 
-  void Run() override { server_ready_event_->Wait(); }
+  void Run() override {
+    server_ready_event_->Wait();
+  }
 
   void OnDoClient2Task() {
     events_[3]->Wait();
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc
index a93adf1..bd3ceb58 100644
--- a/ipc/mojo/ipc_channel_mojo.cc
+++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -27,7 +27,9 @@
                      Channel::Mode mode)
       : delegate_(delegate), channel_handle_(channel_handle), mode_(mode) {}
 
-  std::string GetName() const override { return channel_handle_.name; }
+  std::string GetName() const override {
+    return channel_handle_.name;
+  }
 
   scoped_ptr<Channel> BuildChannel(Listener* listener) override {
     return ChannelMojo::Create(delegate_, channel_handle_, mode_, listener);
diff --git a/ipc/mojo/ipc_channel_mojo_unittest.cc b/ipc/mojo/ipc_channel_mojo_unittest.cc
index 1697ff70..07218c69 100644
--- a/ipc/mojo/ipc_channel_mojo_unittest.cc
+++ b/ipc/mojo/ipc_channel_mojo_unittest.cc
@@ -209,7 +209,9 @@
   ListenerThatQuits() {
   }
 
-  bool OnMessageReceived(const IPC::Message& message) override { return true; }
+  bool OnMessageReceived(const IPC::Message& message) override {
+    return true;
+  }
 
   void OnChannelConnected(int32 peer_pid) override {
     base::MessageLoop::current()->Quit();
@@ -336,7 +338,9 @@
     return true;
   }
 
-  void OnChannelError() override { NOTREACHED(); }
+  void OnChannelError() override {
+    NOTREACHED();
+  }
 
   static std::string GetSendingFileContent() {
     return "Hello";
diff --git a/ipc/mojo/ipc_mojo_bootstrap.cc b/ipc/mojo/ipc_mojo_bootstrap.cc
index 74582658..4af4e503 100644
--- a/ipc/mojo/ipc_mojo_bootstrap.cc
+++ b/ipc/mojo/ipc_mojo_bootstrap.cc
@@ -84,6 +84,9 @@
 }
 
 void MojoServerBootstrap::OnClientLaunched(base::ProcessHandle process) {
+  if (HasFailed())
+    return;
+
   DCHECK_EQ(state(), STATE_INITIALIZED);
   DCHECK_NE(process, base::kNullProcessHandle);
   client_process_ = process;
@@ -202,6 +205,10 @@
   delegate()->OnBootstrapError();
 }
 
+bool MojoBootstrap::HasFailed() const {
+  return state() == STATE_ERROR;
+}
+
 bool MojoBootstrap::Send(Message* message) {
   return channel_->Send(message);
 }
diff --git a/ipc/mojo/ipc_mojo_bootstrap.h b/ipc/mojo/ipc_mojo_bootstrap.h
index 0d007dd..ad5283d9 100644
--- a/ipc/mojo/ipc_mojo_bootstrap.h
+++ b/ipc/mojo/ipc_mojo_bootstrap.h
@@ -60,6 +60,7 @@
   Delegate* delegate() const { return delegate_; }
   bool Send(Message* message);
   void Fail();
+  bool HasFailed() const;
 
   State state() const { return state_; }
   void set_state(State state) { state_ = state; }
diff --git a/ipc/param_traits_macros.h b/ipc/param_traits_macros.h
index ad87a939..f4248df 100644
--- a/ipc/param_traits_macros.h
+++ b/ipc/param_traits_macros.h
@@ -39,8 +39,11 @@
 // Convenience macro for defining enumerated type traits for types which are
 // range-checked by the IPC system to be in the range of minvalue..maxvalue
 // inclusive. This macro should not need to be subsequently redefined.
+// TODO(tsepez): Cast to std::underlying_type<>::type once that is permitted.
 #define IPC_ENUM_TRAITS_MIN_MAX_VALUE(type, minvalue, maxvalue)  \
-  IPC_ENUM_TRAITS_VALIDATE(type, (value >= (minvalue) && value <= (maxvalue)))
+  IPC_ENUM_TRAITS_VALIDATE( \
+      type, (static_cast<int>(value) >= static_cast<int>(minvalue) && \
+             static_cast<int>(value) <= static_cast<int>(maxvalue)))
 
 // Traits generation for enums. This macro may be redefined later.
 #define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \
diff --git a/ipc/unix_domain_socket_util_unittest.cc b/ipc/unix_domain_socket_util_unittest.cc
index 90c2ada..813d4979 100644
--- a/ipc/unix_domain_socket_util_unittest.cc
+++ b/ipc/unix_domain_socket_util_unittest.cc
@@ -27,7 +27,9 @@
         base::Bind(&SocketAcceptor::StartWatching, base::Unretained(this), fd));
   }
 
-  ~SocketAcceptor() override { Close(); }
+  ~SocketAcceptor() override {
+    Close();
+  }
 
   int server_fd() const { return server_fd_; }
 
diff --git a/jingle/PRESUBMIT.py b/jingle/PRESUBMIT.py
index 9e62e23..ae8a5ba 100644
--- a/jingle/PRESUBMIT.py
+++ b/jingle/PRESUBMIT.py
@@ -11,12 +11,12 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_rel_swarming': set(['defaulttests']),
+      'linux_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.mac': {
-      'mac_chromium_rel_swarming': set(['defaulttests']),
+      'mac_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.win': {
-      'win_chromium_rel_swarming': set(['defaulttests']),
+      'win_chromium_rel': set(['defaulttests']),
     }
   }
diff --git a/jingle/glue/channel_socket_adapter.h b/jingle/glue/channel_socket_adapter.h
index 48c4097c..d3ba419 100644
--- a/jingle/glue/channel_socket_adapter.h
+++ b/jingle/glue/channel_socket_adapter.h
@@ -30,7 +30,7 @@
  public:
   // TransportChannel object is always owned by the corresponding session.
   explicit TransportChannelSocketAdapter(cricket::TransportChannel* channel);
-  virtual ~TransportChannelSocketAdapter();
+  ~TransportChannelSocketAdapter() override;
 
   // Sets callback that should be called when the adapter is being
   // destroyed. The callback is not allowed to touch the adapter, but
@@ -43,13 +43,15 @@
   void Close(int error_code);
 
   // Socket implementation.
-  virtual int Read(net::IOBuffer* buf, int buf_len,
-                   const net::CompletionCallback& callback) override;
-  virtual int Write(net::IOBuffer* buf, int buf_len,
-                    const net::CompletionCallback& callback) override;
+  int Read(net::IOBuffer* buf,
+           int buf_len,
+           const net::CompletionCallback& callback) override;
+  int Write(net::IOBuffer* buf,
+            int buf_len,
+            const net::CompletionCallback& callback) override;
 
-  virtual int SetReceiveBufferSize(int32 size) override;
-  virtual int SetSendBufferSize(int32 size) override;
+  int SetReceiveBufferSize(int32 size) override;
+  int SetSendBufferSize(int32 size) override;
 
  private:
   void OnNewPacket(cricket::TransportChannel* channel,
diff --git a/jingle/glue/chrome_async_socket.h b/jingle/glue/chrome_async_socket.h
index e05f9c6..af6a8fc 100644
--- a/jingle/glue/chrome_async_socket.h
+++ b/jingle/glue/chrome_async_socket.h
@@ -41,22 +41,22 @@
       size_t write_buf_size);
 
   // Does not raise any signals.
-  virtual ~ChromeAsyncSocket();
+  ~ChromeAsyncSocket() override;
 
   // buzz::AsyncSocket implementation.
 
   // The current state (see buzz::AsyncSocket::State; all but
   // STATE_CLOSING is used).
-  virtual State state() override;
+  State state() override;
 
   // The last generated error.  Errors are generated when the main
   // functions below return false or when SignalClosed is raised due
   // to an asynchronous error.
-  virtual Error error() override;
+  Error error() override;
 
   // GetError() (which is of type net::Error) != net::OK only when
   // error() == ERROR_WINSOCK.
-  virtual int GetError() override;
+  int GetError() override;
 
   // Tries to connect to the given address.
   //
@@ -72,7 +72,7 @@
   // Otherwise, starts the connection process and returns true.
   // SignalConnected will be raised when the connection is successful;
   // otherwise, SignalClosed will be raised with a net error set.
-  virtual bool Connect(const rtc::SocketAddress& address) override;
+  bool Connect(const rtc::SocketAddress& address) override;
 
   // Tries to read at most |len| bytes into |data|.
   //
@@ -85,7 +85,7 @@
   // case because StartTls() is called during a slot connected to
   // SignalRead after parsing the final non-TLS reply from the server
   // [see XmppClient::Private::OnSocketRead()].)
-  virtual bool Read(char* data, size_t len, size_t* len_read) override;
+  bool Read(char* data, size_t len, size_t* len_read) override;
 
   // Queues up |len| bytes of |data| for writing.
   //
@@ -104,11 +104,11 @@
   // Note that there's no guarantee that the data will actually be
   // sent; however, it is guaranteed that the any data sent will be
   // sent in FIFO order.
-  virtual bool Write(const char* data, size_t len) override;
+  bool Write(const char* data, size_t len) override;
 
   // If the socket is not already closed, closes the socket and raises
   // SignalClosed.  Always returns true.
-  virtual bool Close() override;
+  bool Close() override;
 
   // Tries to change to a TLS connection with the given domain name.
   //
@@ -121,7 +121,7 @@
   // SignalSSLConnected will be raised when the connection is
   // successful; otherwise, SignalClosed will be raised with a net
   // error set.
-  virtual bool StartTls(const std::string& domain_name) override;
+  bool StartTls(const std::string& domain_name) override;
 
   // Signal behavior:
   //
diff --git a/jingle/glue/chrome_async_socket_unittest.cc b/jingle/glue/chrome_async_socket_unittest.cc
index e04b608..4449d382 100644
--- a/jingle/glue/chrome_async_socket_unittest.cc
+++ b/jingle/glue/chrome_async_socket_unittest.cc
@@ -36,14 +36,14 @@
  public:
   AsyncSocketDataProvider() : has_pending_read_(false) {}
 
-  virtual ~AsyncSocketDataProvider() {
+  ~AsyncSocketDataProvider() override {
     EXPECT_TRUE(writes_.empty());
     EXPECT_TRUE(reads_.empty());
   }
 
   // If there's no read, sets the "has pending read" flag.  Otherwise,
   // pops the next read.
-  virtual net::MockRead GetNextRead() override {
+  net::MockRead GetNextRead() override {
     if (reads_.empty()) {
       DCHECK(!has_pending_read_);
       has_pending_read_ = true;
@@ -57,7 +57,7 @@
 
   // Simply pops the next write and, if applicable, compares it to
   // |data|.
-  virtual net::MockWriteResult OnWrite(const std::string& data) override {
+  net::MockWriteResult OnWrite(const std::string& data) override {
     DCHECK(!writes_.empty());
     net::MockWrite mock_write = writes_.front();
     writes_.pop_front();
@@ -74,7 +74,7 @@
 
   // We ignore resets so we can pre-load the socket data provider with
   // read/write events.
-  virtual void Reset() override {}
+  void Reset() override {}
 
   // If there is a pending read, completes it with the given read.
   // Otherwise, queues up the given read.
@@ -114,13 +114,13 @@
   }
 
   // ResolvingClientSocketFactory implementation.
-  virtual scoped_ptr<net::StreamSocket> CreateTransportClientSocket(
+  scoped_ptr<net::StreamSocket> CreateTransportClientSocket(
       const net::HostPortPair& host_and_port) override {
     return mock_client_socket_factory_->CreateTransportClientSocket(
         address_list_, NULL, net::NetLog::Source());
   }
 
-  virtual scoped_ptr<net::SSLClientSocket> CreateSSLClientSocket(
+  scoped_ptr<net::SSLClientSocket> CreateSSLClientSocket(
       scoped_ptr<net::ClientSocketHandle> transport_socket,
       const net::HostPortPair& host_and_port) override {
     net::SSLClientSocketContext context;
diff --git a/jingle/glue/fake_ssl_client_socket.h b/jingle/glue/fake_ssl_client_socket.h
index a27caa7..bf951d6d 100644
--- a/jingle/glue/fake_ssl_client_socket.h
+++ b/jingle/glue/fake_ssl_client_socket.h
@@ -38,33 +38,35 @@
  public:
   explicit FakeSSLClientSocket(scoped_ptr<net::StreamSocket> transport_socket);
 
-  virtual ~FakeSSLClientSocket();
+  ~FakeSSLClientSocket() override;
 
   // Exposed for testing.
   static base::StringPiece GetSslClientHello();
   static base::StringPiece GetSslServerHello();
 
   // net::StreamSocket implementation.
-  virtual int Read(net::IOBuffer* buf, int buf_len,
-                   const net::CompletionCallback& callback) override;
-  virtual int Write(net::IOBuffer* buf, int buf_len,
-                    const net::CompletionCallback& callback) override;
-  virtual int SetReceiveBufferSize(int32 size) override;
-  virtual int SetSendBufferSize(int32 size) override;
-  virtual int Connect(const net::CompletionCallback& callback) override;
-  virtual void Disconnect() override;
-  virtual bool IsConnected() const override;
-  virtual bool IsConnectedAndIdle() const override;
-  virtual int GetPeerAddress(net::IPEndPoint* address) const override;
-  virtual int GetLocalAddress(net::IPEndPoint* address) const override;
-  virtual const net::BoundNetLog& NetLog() const override;
-  virtual void SetSubresourceSpeculation() override;
-  virtual void SetOmniboxSpeculation() override;
-  virtual bool WasEverUsed() const override;
-  virtual bool UsingTCPFastOpen() const override;
-  virtual bool WasNpnNegotiated() const override;
-  virtual net::NextProto GetNegotiatedProtocol() const override;
-  virtual bool GetSSLInfo(net::SSLInfo* ssl_info) override;
+  int Read(net::IOBuffer* buf,
+           int buf_len,
+           const net::CompletionCallback& callback) override;
+  int Write(net::IOBuffer* buf,
+            int buf_len,
+            const net::CompletionCallback& callback) override;
+  int SetReceiveBufferSize(int32 size) override;
+  int SetSendBufferSize(int32 size) override;
+  int Connect(const net::CompletionCallback& callback) override;
+  void Disconnect() override;
+  bool IsConnected() const override;
+  bool IsConnectedAndIdle() const override;
+  int GetPeerAddress(net::IPEndPoint* address) const override;
+  int GetLocalAddress(net::IPEndPoint* address) const override;
+  const net::BoundNetLog& NetLog() const override;
+  void SetSubresourceSpeculation() override;
+  void SetOmniboxSpeculation() override;
+  bool WasEverUsed() const override;
+  bool UsingTCPFastOpen() const override;
+  bool WasNpnNegotiated() const override;
+  net::NextProto GetNegotiatedProtocol() const override;
+  bool GetSSLInfo(net::SSLInfo* ssl_info) override;
 
  private:
   enum HandshakeState {
diff --git a/jingle/glue/proxy_resolving_client_socket.h b/jingle/glue/proxy_resolving_client_socket.h
index 27a01c3..86b21a5 100644
--- a/jingle/glue/proxy_resolving_client_socket.h
+++ b/jingle/glue/proxy_resolving_client_socket.h
@@ -45,29 +45,31 @@
       const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
       const net::SSLConfig& ssl_config,
       const net::HostPortPair& dest_host_port_pair);
-  virtual ~ProxyResolvingClientSocket();
+  ~ProxyResolvingClientSocket() override;
 
   // net::StreamSocket implementation.
-  virtual int Read(net::IOBuffer* buf, int buf_len,
-                   const net::CompletionCallback& callback) override;
-  virtual int Write(net::IOBuffer* buf, int buf_len,
-                    const net::CompletionCallback& callback) override;
-  virtual int SetReceiveBufferSize(int32 size) override;
-  virtual int SetSendBufferSize(int32 size) override;
-  virtual int Connect(const net::CompletionCallback& callback) override;
-  virtual void Disconnect() override;
-  virtual bool IsConnected() const override;
-  virtual bool IsConnectedAndIdle() const override;
-  virtual int GetPeerAddress(net::IPEndPoint* address) const override;
-  virtual int GetLocalAddress(net::IPEndPoint* address) const override;
-  virtual const net::BoundNetLog& NetLog() const override;
-  virtual void SetSubresourceSpeculation() override;
-  virtual void SetOmniboxSpeculation() override;
-  virtual bool WasEverUsed() const override;
-  virtual bool UsingTCPFastOpen() const override;
-  virtual bool WasNpnNegotiated() const override;
-  virtual net::NextProto GetNegotiatedProtocol() const override;
-  virtual bool GetSSLInfo(net::SSLInfo* ssl_info) override;
+  int Read(net::IOBuffer* buf,
+           int buf_len,
+           const net::CompletionCallback& callback) override;
+  int Write(net::IOBuffer* buf,
+            int buf_len,
+            const net::CompletionCallback& callback) override;
+  int SetReceiveBufferSize(int32 size) override;
+  int SetSendBufferSize(int32 size) override;
+  int Connect(const net::CompletionCallback& callback) override;
+  void Disconnect() override;
+  bool IsConnected() const override;
+  bool IsConnectedAndIdle() const override;
+  int GetPeerAddress(net::IPEndPoint* address) const override;
+  int GetLocalAddress(net::IPEndPoint* address) const override;
+  const net::BoundNetLog& NetLog() const override;
+  void SetSubresourceSpeculation() override;
+  void SetOmniboxSpeculation() override;
+  bool WasEverUsed() const override;
+  bool UsingTCPFastOpen() const override;
+  bool WasNpnNegotiated() const override;
+  net::NextProto GetNegotiatedProtocol() const override;
+  bool GetSSLInfo(net::SSLInfo* ssl_info) override;
 
  private:
   // Proxy resolution and connection functions.
diff --git a/jingle/glue/proxy_resolving_client_socket_unittest.cc b/jingle/glue/proxy_resolving_client_socket_unittest.cc
index cdcbc56f..0fda0ff4 100644
--- a/jingle/glue/proxy_resolving_client_socket_unittest.cc
+++ b/jingle/glue/proxy_resolving_client_socket_unittest.cc
@@ -25,7 +25,7 @@
             "PROXY bad:99; PROXY maybe:80; DIRECT"));
     Init();
   }
-  virtual ~MyTestURLRequestContext() {}
+  ~MyTestURLRequestContext() override {}
 };
 
 }  // namespace
diff --git a/jingle/glue/pseudotcp_adapter.cc b/jingle/glue/pseudotcp_adapter.cc
index 74f3f18..756dbd54 100644
--- a/jingle/glue/pseudotcp_adapter.cc
+++ b/jingle/glue/pseudotcp_adapter.cc
@@ -38,14 +38,15 @@
 
   // cricket::IPseudoTcpNotify interface.
   // These notifications are triggered from NotifyPacket.
-  virtual void OnTcpOpen(cricket::PseudoTcp* tcp) override;
-  virtual void OnTcpReadable(cricket::PseudoTcp* tcp) override;
-  virtual void OnTcpWriteable(cricket::PseudoTcp* tcp) override;
+  void OnTcpOpen(cricket::PseudoTcp* tcp) override;
+  void OnTcpReadable(cricket::PseudoTcp* tcp) override;
+  void OnTcpWriteable(cricket::PseudoTcp* tcp) override;
   // This is triggered by NotifyClock or NotifyPacket.
-  virtual void OnTcpClosed(cricket::PseudoTcp* tcp, uint32 error) override;
+  void OnTcpClosed(cricket::PseudoTcp* tcp, uint32 error) override;
   // This is triggered by NotifyClock, NotifyPacket, Recv and Send.
-  virtual WriteResult TcpWritePacket(cricket::PseudoTcp* tcp,
-                                     const char* buffer, size_t len) override;
+  WriteResult TcpWritePacket(cricket::PseudoTcp* tcp,
+                             const char* buffer,
+                             size_t len) override;
 
   void SetAckDelay(int delay_ms);
   void SetNoDelay(bool no_delay);
@@ -57,7 +58,7 @@
 
  private:
   friend class base::RefCounted<Core>;
-  virtual ~Core();
+  ~Core() override;
 
   // These are invoked by the underlying Socket, and may trigger callbacks.
   // They hold a reference to |this| while running, to protect from deletion.
diff --git a/jingle/glue/pseudotcp_adapter.h b/jingle/glue/pseudotcp_adapter.h
index 88ebfc9f..36c3fd0 100644
--- a/jingle/glue/pseudotcp_adapter.h
+++ b/jingle/glue/pseudotcp_adapter.h
@@ -27,31 +27,33 @@
   // Creates an adapter for the supplied Socket.  |socket| should already
   // be ready for use, and ownership of it will be assumed by the adapter.
   PseudoTcpAdapter(net::Socket* socket);
-  virtual ~PseudoTcpAdapter();
+  ~PseudoTcpAdapter() override;
 
   // net::Socket implementation.
-  virtual int Read(net::IOBuffer* buffer, int buffer_size,
-                   const net::CompletionCallback& callback) override;
-  virtual int Write(net::IOBuffer* buffer, int buffer_size,
-                    const net::CompletionCallback& callback) override;
-  virtual int SetReceiveBufferSize(int32 size) override;
-  virtual int SetSendBufferSize(int32 size) override;
+  int Read(net::IOBuffer* buffer,
+           int buffer_size,
+           const net::CompletionCallback& callback) override;
+  int Write(net::IOBuffer* buffer,
+            int buffer_size,
+            const net::CompletionCallback& callback) override;
+  int SetReceiveBufferSize(int32 size) override;
+  int SetSendBufferSize(int32 size) override;
 
   // net::StreamSocket implementation.
-  virtual int Connect(const net::CompletionCallback& callback) override;
-  virtual void Disconnect() override;
-  virtual bool IsConnected() const override;
-  virtual bool IsConnectedAndIdle() const override;
-  virtual int GetPeerAddress(net::IPEndPoint* address) const override;
-  virtual int GetLocalAddress(net::IPEndPoint* address) const override;
-  virtual const net::BoundNetLog& NetLog() const override;
-  virtual void SetSubresourceSpeculation() override;
-  virtual void SetOmniboxSpeculation() override;
-  virtual bool WasEverUsed() const override;
-  virtual bool UsingTCPFastOpen() const override;
-  virtual bool WasNpnNegotiated() const override;
-  virtual net::NextProto GetNegotiatedProtocol() const override;
-  virtual bool GetSSLInfo(net::SSLInfo* ssl_info) override;
+  int Connect(const net::CompletionCallback& callback) override;
+  void Disconnect() override;
+  bool IsConnected() const override;
+  bool IsConnectedAndIdle() const override;
+  int GetPeerAddress(net::IPEndPoint* address) const override;
+  int GetLocalAddress(net::IPEndPoint* address) const override;
+  const net::BoundNetLog& NetLog() const override;
+  void SetSubresourceSpeculation() override;
+  void SetOmniboxSpeculation() override;
+  bool WasEverUsed() const override;
+  bool UsingTCPFastOpen() const override;
+  bool WasNpnNegotiated() const override;
+  net::NextProto GetNegotiatedProtocol() const override;
+  bool GetSSLInfo(net::SSLInfo* ssl_info) override;
 
   // Set the delay for sending ACK.
   void SetAckDelay(int delay_ms);
diff --git a/jingle/glue/pseudotcp_adapter_unittest.cc b/jingle/glue/pseudotcp_adapter_unittest.cc
index 00070ef5..1b2674f6 100644
--- a/jingle/glue/pseudotcp_adapter_unittest.cc
+++ b/jingle/glue/pseudotcp_adapter_unittest.cc
@@ -49,9 +49,9 @@
         last_update_(base::TimeTicks::HighResNow()) {
   }
 
-  virtual ~LeakyBucket() { }
+  ~LeakyBucket() override {}
 
-  virtual bool DropNextPacket() override {
+  bool DropNextPacket() override {
     base::TimeTicks now = base::TimeTicks::HighResNow();
     double interval = (now - last_update_).InSecondsF();
     last_update_ = now;
@@ -78,7 +78,7 @@
       : rate_limiter_(NULL),
         latency_ms_(0) {
   }
-  virtual ~FakeSocket() { }
+  ~FakeSocket() override {}
 
   void AppendInputPacket(const std::vector<char>& data) {
     if (rate_limiter_ && rate_limiter_->DropNextPacket())
@@ -107,8 +107,9 @@
   void set_latency(int latency_ms) { latency_ms_ = latency_ms; };
 
   // net::Socket interface.
-  virtual int Read(net::IOBuffer* buf, int buf_len,
-                   const net::CompletionCallback& callback) override {
+  int Read(net::IOBuffer* buf,
+           int buf_len,
+           const net::CompletionCallback& callback) override {
     CHECK(read_callback_.is_null());
     CHECK(buf);
 
@@ -127,8 +128,9 @@
     }
   }
 
-  virtual int Write(net::IOBuffer* buf, int buf_len,
-                    const net::CompletionCallback& callback) override {
+  int Write(net::IOBuffer* buf,
+            int buf_len,
+            const net::CompletionCallback& callback) override {
     DCHECK(buf);
     if (peer_socket_) {
       base::MessageLoop::current()->PostDelayedTask(
@@ -142,11 +144,11 @@
     return buf_len;
   }
 
-  virtual int SetReceiveBufferSize(int32 size) override {
+  int SetReceiveBufferSize(int32 size) override {
     NOTIMPLEMENTED();
     return net::ERR_NOT_IMPLEMENTED;
   }
-  virtual int SetSendBufferSize(int32 size) override {
+  int SetSendBufferSize(int32 size) override {
     NOTIMPLEMENTED();
     return net::ERR_NOT_IMPLEMENTED;
   }
diff --git a/jingle/glue/task_pump.h b/jingle/glue/task_pump.h
index 0b86707..b102605c 100644
--- a/jingle/glue/task_pump.h
+++ b/jingle/glue/task_pump.h
@@ -17,11 +17,11 @@
  public:
   TaskPump();
 
-  virtual ~TaskPump();
+  ~TaskPump() override;
 
   // rtc::TaskRunner implementation.
-  virtual void WakeTasks() override;
-  virtual int64 CurrentTime() override;
+  void WakeTasks() override;
+  int64 CurrentTime() override;
 
   // No tasks will be processed after this is called, even if
   // WakeTasks() is called.
diff --git a/jingle/glue/thread_wrapper.h b/jingle/glue/thread_wrapper.h
index 0313bfb..6a045bf 100644
--- a/jingle/glue/thread_wrapper.h
+++ b/jingle/glue/thread_wrapper.h
@@ -42,7 +42,7 @@
 
   explicit JingleThreadWrapper(
      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-  virtual ~JingleThreadWrapper();
+  ~JingleThreadWrapper() override;
 
   // Sets whether the thread can be used to send messages
   // synchronously to another thread using Send() method. Set to false
@@ -52,47 +52,44 @@
   void set_send_allowed(bool allowed) { send_allowed_ = allowed; }
 
   // MessageLoop::DestructionObserver implementation.
-  virtual void WillDestroyCurrentMessageLoop() override;
+  void WillDestroyCurrentMessageLoop() override;
 
   // rtc::MessageQueue overrides.
-  virtual void Post(rtc::MessageHandler *phandler,
-                    uint32 id,
-                    rtc::MessageData *pdata,
-                    bool time_sensitive) override;
-  virtual void PostDelayed(int delay_ms,
-                           rtc::MessageHandler* handler,
-                           uint32 id,
-                           rtc::MessageData* data) override;
-  virtual void Clear(rtc::MessageHandler* handler,
-                     uint32 id,
-                     rtc::MessageList* removed) override;
-  virtual void Send(rtc::MessageHandler *handler,
-                    uint32 id,
-                    rtc::MessageData *data) override;
+  void Post(rtc::MessageHandler* phandler,
+            uint32 id,
+            rtc::MessageData* pdata,
+            bool time_sensitive) override;
+  void PostDelayed(int delay_ms,
+                   rtc::MessageHandler* handler,
+                   uint32 id,
+                   rtc::MessageData* data) override;
+  void Clear(rtc::MessageHandler* handler,
+             uint32 id,
+             rtc::MessageList* removed) override;
+  void Send(rtc::MessageHandler* handler,
+            uint32 id,
+            rtc::MessageData* data) override;
 
   // Following methods are not supported.They are overriden just to
   // ensure that they are not called (each of them contain NOTREACHED
   // in the body). Some of this methods can be implemented if it
   // becomes neccessary to use libjingle code that calls them.
-  virtual void Quit() override;
-  virtual bool IsQuitting() override;
-  virtual void Restart() override;
-  virtual bool Get(rtc::Message* message,
-                   int delay_ms,
-                   bool process_io) override;
-  virtual bool Peek(rtc::Message* message,
-                    int delay_ms) override;
-  virtual void PostAt(uint32 timestamp,
-                      rtc::MessageHandler* handler,
-                      uint32 id,
-                      rtc::MessageData* data) override;
-  virtual void Dispatch(rtc::Message* message) override;
-  virtual void ReceiveSends() override;
-  virtual int GetDelay() override;
+  void Quit() override;
+  bool IsQuitting() override;
+  void Restart() override;
+  bool Get(rtc::Message* message, int delay_ms, bool process_io) override;
+  bool Peek(rtc::Message* message, int delay_ms) override;
+  void PostAt(uint32 timestamp,
+              rtc::MessageHandler* handler,
+              uint32 id,
+              rtc::MessageData* data) override;
+  void Dispatch(rtc::Message* message) override;
+  void ReceiveSends() override;
+  int GetDelay() override;
 
   // rtc::Thread overrides.
-  virtual void Stop() override;
-  virtual void Run() override;
+  void Stop() override;
+  void Run() override;
 
  private:
   typedef std::map<int, rtc::Message> MessagesQueue;
diff --git a/jingle/glue/xmpp_client_socket_factory.h b/jingle/glue/xmpp_client_socket_factory.h
index 03b2b14..db46afdd 100644
--- a/jingle/glue/xmpp_client_socket_factory.h
+++ b/jingle/glue/xmpp_client_socket_factory.h
@@ -32,13 +32,13 @@
       const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
       bool use_fake_ssl_client_socket);
 
-  virtual ~XmppClientSocketFactory();
+  ~XmppClientSocketFactory() override;
 
   // ResolvingClientSocketFactory implementation.
-  virtual scoped_ptr<net::StreamSocket> CreateTransportClientSocket(
+  scoped_ptr<net::StreamSocket> CreateTransportClientSocket(
       const net::HostPortPair& host_and_port) override;
 
-  virtual scoped_ptr<net::SSLClientSocket> CreateSSLClientSocket(
+  scoped_ptr<net::SSLClientSocket> CreateSSLClientSocket(
       scoped_ptr<net::ClientSocketHandle> transport_socket,
       const net::HostPortPair& host_and_port) override;
 
diff --git a/jingle/notifier/base/fake_base_task.cc b/jingle/notifier/base/fake_base_task.cc
index 510293c8..c1805b42 100644
--- a/jingle/notifier/base/fake_base_task.cc
+++ b/jingle/notifier/base/fake_base_task.cc
@@ -39,11 +39,9 @@
       : notifier::WeakXmppClient(parent),
         jid_("test@example.com/testresource") {}
 
-  virtual ~FakeWeakXmppClient() {}
+  ~FakeWeakXmppClient() override {}
 
-  virtual const buzz::Jid& jid() const override {
-    return jid_;
-  }
+  const buzz::Jid& jid() const override { return jid_; }
 
  private:
   buzz::Jid jid_;
diff --git a/jingle/notifier/base/gaia_token_pre_xmpp_auth.cc b/jingle/notifier/base/gaia_token_pre_xmpp_auth.cc
index 74ff87d..b213095f 100644
--- a/jingle/notifier/base/gaia_token_pre_xmpp_auth.cc
+++ b/jingle/notifier/base/gaia_token_pre_xmpp_auth.cc
@@ -25,9 +25,9 @@
       : buzz::SaslCookieMechanism(
           mechanism, username, cookie, token_service) {}
 
-  virtual ~GaiaCookieMechanism() {}
+  ~GaiaCookieMechanism() override {}
 
-  virtual buzz::XmlElement* StartSaslAuth() override {
+  buzz::XmlElement* StartSaslAuth() override {
     buzz::XmlElement* auth = buzz::SaslCookieMechanism::StartSaslAuth();
     // These attributes are necessary for working with non-gmail gaia
     // accounts.
diff --git a/jingle/notifier/base/gaia_token_pre_xmpp_auth.h b/jingle/notifier/base/gaia_token_pre_xmpp_auth.h
index 529b4e02..0ff49ff2 100644
--- a/jingle/notifier/base/gaia_token_pre_xmpp_auth.h
+++ b/jingle/notifier/base/gaia_token_pre_xmpp_auth.h
@@ -22,37 +22,38 @@
                        const std::string& token_service,
                        const std::string& auth_mechanism);
 
-  virtual ~GaiaTokenPreXmppAuth();
+  ~GaiaTokenPreXmppAuth() override;
 
   // buzz::PreXmppAuth (-buzz::SaslHandler) implementation.  We stub
   // all the methods out as we don't actually do any authentication at
   // this point.
-  virtual void StartPreXmppAuth(const buzz::Jid& jid,
-                                const rtc::SocketAddress& server,
-                                const rtc::CryptString& pass,
-                                const std::string& auth_mechanism,
-                                const std::string& auth_token) override;
+  void StartPreXmppAuth(const buzz::Jid& jid,
+                        const rtc::SocketAddress& server,
+                        const rtc::CryptString& pass,
+                        const std::string& auth_mechanism,
+                        const std::string& auth_token) override;
 
-  virtual bool IsAuthDone() const override;
+  bool IsAuthDone() const override;
 
-  virtual bool IsAuthorized() const override;
+  bool IsAuthorized() const override;
 
-  virtual bool HadError() const override;
+  bool HadError() const override;
 
-  virtual int GetError() const override;
+  int GetError() const override;
 
-  virtual buzz::CaptchaChallenge GetCaptchaChallenge() const override;
+  buzz::CaptchaChallenge GetCaptchaChallenge() const override;
 
-  virtual std::string GetAuthToken() const override;
+  std::string GetAuthToken() const override;
 
-  virtual std::string GetAuthMechanism() const override;
+  std::string GetAuthMechanism() const override;
 
   // buzz::SaslHandler implementation.
 
-  virtual std::string ChooseBestSaslMechanism(
-      const std::vector<std::string>& mechanisms, bool encrypted) override;
+  std::string ChooseBestSaslMechanism(
+      const std::vector<std::string>& mechanisms,
+      bool encrypted) override;
 
-  virtual buzz::SaslMechanism* CreateSaslMechanism(
+  buzz::SaslMechanism* CreateSaslMechanism(
       const std::string& mechanism) override;
 
  private:
diff --git a/jingle/notifier/base/weak_xmpp_client.h b/jingle/notifier/base/weak_xmpp_client.h
index 47c5587..d77903c6 100644
--- a/jingle/notifier/base/weak_xmpp_client.h
+++ b/jingle/notifier/base/weak_xmpp_client.h
@@ -28,7 +28,7 @@
  public:
   explicit WeakXmppClient(rtc::TaskParent* parent);
 
-  virtual ~WeakXmppClient();
+  ~WeakXmppClient() override;
 
   // Returns a weak pointer that is invalidated when the XmppClient
   // becomes invalid to use.
@@ -40,7 +40,7 @@
   void Invalidate();
 
  protected:
-  virtual void Stop() override;
+  void Stop() override;
 
  private:
   // We use our own WeakPtrFactory instead of inheriting from
diff --git a/jingle/notifier/base/xmpp_connection.h b/jingle/notifier/base/xmpp_connection.h
index 52102345..bc75605 100644
--- a/jingle/notifier/base/xmpp_connection.h
+++ b/jingle/notifier/base/xmpp_connection.h
@@ -77,7 +77,7 @@
   // Invalidates any weak pointers passed to the delegate by
   // OnConnect(), but does not trigger a call to the delegate's
   // OnError() function.
-  virtual ~XmppConnection();
+  ~XmppConnection() override;
 
  private:
   void OnStateChange(buzz::XmppEngine::State state);
diff --git a/jingle/notifier/communicator/login.h b/jingle/notifier/communicator/login.h
index df02cc0..a8646f6 100644
--- a/jingle/notifier/communicator/login.h
+++ b/jingle/notifier/communicator/login.h
@@ -72,7 +72,7 @@
         const ServerList& servers,
         bool try_ssltcp_first,
         const std::string& auth_mechanism);
-  virtual ~Login();
+  ~Login() override;
 
   // Starts connecting (or forces a reconnection if we're backed off).
   void StartConnection();
@@ -83,21 +83,21 @@
   void UpdateXmppSettings(const buzz::XmppClientSettings& user_settings);
 
   // net::NetworkChangeNotifier::IPAddressObserver implementation.
-  virtual void OnIPAddressChanged() override;
+  void OnIPAddressChanged() override;
 
   // net::NetworkChangeNotifier::ConnectionTypeObserver implementation.
-  virtual void OnConnectionTypeChanged(
+  void OnConnectionTypeChanged(
       net::NetworkChangeNotifier::ConnectionType type) override;
 
   // net::NetworkChangeNotifier::DNSObserver implementation.
-  virtual void OnDNSChanged() override;
+  void OnDNSChanged() override;
 
   // SingleLoginAttempt::Delegate implementation.
-  virtual void OnConnect(
+  void OnConnect(
       base::WeakPtr<buzz::XmppTaskParentInterface> base_task) override;
-  virtual void OnRedirect(const ServerInformation& redirect_server) override;
-  virtual void OnCredentialsRejected() override;
-  virtual void OnSettingsExhausted() override;
+  void OnRedirect(const ServerInformation& redirect_server) override;
+  void OnCredentialsRejected() override;
+  void OnSettingsExhausted() override;
 
  private:
   // Called by the various network notifications.
diff --git a/jingle/notifier/communicator/single_login_attempt.h b/jingle/notifier/communicator/single_login_attempt.h
index 7c877cb..5480e3c1 100644
--- a/jingle/notifier/communicator/single_login_attempt.h
+++ b/jingle/notifier/communicator/single_login_attempt.h
@@ -57,14 +57,13 @@
   // Does not take ownership of |delegate|, which must not be NULL.
   SingleLoginAttempt(const LoginSettings& login_settings, Delegate* delegate);
 
-  virtual ~SingleLoginAttempt();
+  ~SingleLoginAttempt() override;
 
   // XmppConnection::Delegate implementation.
-  virtual void OnConnect(
-      base::WeakPtr<buzz::XmppTaskParentInterface> parent) override;
-  virtual void OnError(buzz::XmppEngine::Error error,
-                       int error_subcode,
-                       const buzz::XmlElement* stream_error) override;
+  void OnConnect(base::WeakPtr<buzz::XmppTaskParentInterface> parent) override;
+  void OnError(buzz::XmppEngine::Error error,
+               int error_subcode,
+               const buzz::XmlElement* stream_error) override;
 
  private:
   void TryConnect(const ConnectionSettings& new_settings);
diff --git a/jingle/notifier/communicator/single_login_attempt_unittest.cc b/jingle/notifier/communicator/single_login_attempt_unittest.cc
index 281ae0d..2a9b5af 100644
--- a/jingle/notifier/communicator/single_login_attempt_unittest.cc
+++ b/jingle/notifier/communicator/single_login_attempt_unittest.cc
@@ -35,24 +35,20 @@
  public:
   FakeDelegate() : state_(IDLE) {}
 
-  virtual void OnConnect(
+  void OnConnect(
       base::WeakPtr<buzz::XmppTaskParentInterface> base_task) override {
     state_ = CONNECTED;
     base_task_ = base_task;
   }
 
-  virtual void OnRedirect(const ServerInformation& redirect_server) override {
+  void OnRedirect(const ServerInformation& redirect_server) override {
     state_ = REDIRECTED;
     redirect_server_ = redirect_server;
   }
 
-  virtual void OnCredentialsRejected() override {
-    state_ = CREDENTIALS_REJECTED;
-  }
+  void OnCredentialsRejected() override { state_ = CREDENTIALS_REJECTED; }
 
-  virtual void OnSettingsExhausted() override {
-    state_ = SETTINGS_EXHAUSTED;
-  }
+  void OnSettingsExhausted() override { state_ = SETTINGS_EXHAUSTED; }
 
   DelegateState state() const { return state_; }
 
@@ -77,7 +73,7 @@
         scoped_ptr<net::HostResolver>(new net::HangingHostResolver()));
     Init();
   }
-  virtual ~MyTestURLRequestContext() {}
+  ~MyTestURLRequestContext() override {}
 };
 
 class SingleLoginAttemptTest : public ::testing::Test {
diff --git a/jingle/notifier/listener/fake_push_client.h b/jingle/notifier/listener/fake_push_client.h
index c97d397..3c12f51 100644
--- a/jingle/notifier/listener/fake_push_client.h
+++ b/jingle/notifier/listener/fake_push_client.h
@@ -19,17 +19,16 @@
 class FakePushClient : public PushClient {
  public:
   FakePushClient();
-  virtual ~FakePushClient();
+  ~FakePushClient() override;
 
   // PushClient implementation.
-  virtual void AddObserver(PushClientObserver* observer) override;
-  virtual void RemoveObserver(PushClientObserver* observer) override;
-  virtual void UpdateSubscriptions(
-      const SubscriptionList& subscriptions) override;
-  virtual void UpdateCredentials(
-      const std::string& email, const std::string& token) override;
-  virtual void SendNotification(const Notification& notification) override;
-  virtual void SendPing() override;
+  void AddObserver(PushClientObserver* observer) override;
+  void RemoveObserver(PushClientObserver* observer) override;
+  void UpdateSubscriptions(const SubscriptionList& subscriptions) override;
+  void UpdateCredentials(const std::string& email,
+                         const std::string& token) override;
+  void SendNotification(const Notification& notification) override;
+  void SendPing() override;
 
   // Triggers OnNotificationsEnabled on all observers.
   void EnableNotifications();
diff --git a/jingle/notifier/listener/fake_push_client_observer.h b/jingle/notifier/listener/fake_push_client_observer.h
index 2460e37..eba26117 100644
--- a/jingle/notifier/listener/fake_push_client_observer.h
+++ b/jingle/notifier/listener/fake_push_client_observer.h
@@ -14,14 +14,12 @@
 class FakePushClientObserver : public PushClientObserver {
  public:
   FakePushClientObserver();
-  virtual ~FakePushClientObserver();
+  ~FakePushClientObserver() override;
 
   // PushClientObserver implementation.
-  virtual void OnNotificationsEnabled() override;
-  virtual void OnNotificationsDisabled(
-      NotificationsDisabledReason reason) override;
-  virtual void OnIncomingNotification(
-      const Notification& notification) override;
+  void OnNotificationsEnabled() override;
+  void OnNotificationsDisabled(NotificationsDisabledReason reason) override;
+  void OnIncomingNotification(const Notification& notification) override;
 
   NotificationsDisabledReason last_notifications_disabled_reason() const;
   const Notification& last_incoming_notification() const;
diff --git a/jingle/notifier/listener/non_blocking_push_client.cc b/jingle/notifier/listener/non_blocking_push_client.cc
index e2a10b76..97b0cca 100644
--- a/jingle/notifier/listener/non_blocking_push_client.cc
+++ b/jingle/notifier/listener/non_blocking_push_client.cc
@@ -40,18 +40,16 @@
   void SendNotification(const Notification& data);
   void SendPing();
 
-  virtual void OnNotificationsEnabled() override;
-  virtual void OnNotificationsDisabled(
-      NotificationsDisabledReason reason) override;
-  virtual void OnIncomingNotification(
-      const Notification& notification) override;
-  virtual void OnPingResponse() override;
+  void OnNotificationsEnabled() override;
+  void OnNotificationsDisabled(NotificationsDisabledReason reason) override;
+  void OnIncomingNotification(const Notification& notification) override;
+  void OnPingResponse() override;
 
  private:
   friend class base::RefCountedThreadSafe<NonBlockingPushClient::Core>;
 
   // Called on either the parent thread or the delegate thread.
-  virtual ~Core();
+  ~Core() override;
 
   const scoped_refptr<base::SingleThreadTaskRunner> parent_task_runner_;
   const scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner_;
diff --git a/jingle/notifier/listener/non_blocking_push_client.h b/jingle/notifier/listener/non_blocking_push_client.h
index 17dba05d..27e07fb 100644
--- a/jingle/notifier/listener/non_blocking_push_client.h
+++ b/jingle/notifier/listener/non_blocking_push_client.h
@@ -39,17 +39,16 @@
       const scoped_refptr<base::SingleThreadTaskRunner>& delegate_task_runner,
       const CreateBlockingPushClientCallback&
           create_blocking_push_client_callback);
-  virtual ~NonBlockingPushClient();
+  ~NonBlockingPushClient() override;
 
   // PushClient implementation.
-  virtual void AddObserver(PushClientObserver* observer) override;
-  virtual void RemoveObserver(PushClientObserver* observer) override;
-  virtual void UpdateSubscriptions(
-      const SubscriptionList& subscriptions) override;
-  virtual void UpdateCredentials(
-      const std::string& email, const std::string& token) override;
-  virtual void SendNotification(const Notification& notification) override;
-  virtual void SendPing() override;
+  void AddObserver(PushClientObserver* observer) override;
+  void RemoveObserver(PushClientObserver* observer) override;
+  void UpdateSubscriptions(const SubscriptionList& subscriptions) override;
+  void UpdateCredentials(const std::string& email,
+                         const std::string& token) override;
+  void SendNotification(const Notification& notification) override;
+  void SendPing() override;
 
  private:
   class Core;
diff --git a/jingle/notifier/listener/push_notifications_listen_task.h b/jingle/notifier/listener/push_notifications_listen_task.h
index 659a946..7efd95c 100644
--- a/jingle/notifier/listener/push_notifications_listen_task.h
+++ b/jingle/notifier/listener/push_notifications_listen_task.h
@@ -36,12 +36,12 @@
 
   PushNotificationsListenTask(buzz::XmppTaskParentInterface* parent,
                               Delegate* delegate);
-  virtual ~PushNotificationsListenTask();
+  ~PushNotificationsListenTask() override;
 
   // Overriden from buzz::XmppTask.
-  virtual int ProcessStart() override;
-  virtual int ProcessResponse() override;
-  virtual bool HandleStanza(const buzz::XmlElement* stanza) override;
+  int ProcessStart() override;
+  int ProcessResponse() override;
+  bool HandleStanza(const buzz::XmlElement* stanza) override;
 
  private:
   bool IsValidNotification(const buzz::XmlElement* stanza);
diff --git a/jingle/notifier/listener/push_notifications_send_update_task.h b/jingle/notifier/listener/push_notifications_send_update_task.h
index 287705b5..773e2bc9 100644
--- a/jingle/notifier/listener/push_notifications_send_update_task.h
+++ b/jingle/notifier/listener/push_notifications_send_update_task.h
@@ -24,10 +24,10 @@
  public:
   PushNotificationsSendUpdateTask(
       buzz::XmppTaskParentInterface* parent, const Notification& notification);
-  virtual ~PushNotificationsSendUpdateTask();
+  ~PushNotificationsSendUpdateTask() override;
 
   // Overridden from buzz::XmppTask.
-  virtual int ProcessStart() override;
+  int ProcessStart() override;
 
  private:
   // Allocates and constructs an buzz::XmlElement containing the update stanza.
diff --git a/jingle/notifier/listener/push_notifications_subscribe_task.h b/jingle/notifier/listener/push_notifications_subscribe_task.h
index 7580124..75ee9e13 100644
--- a/jingle/notifier/listener/push_notifications_subscribe_task.h
+++ b/jingle/notifier/listener/push_notifications_subscribe_task.h
@@ -29,12 +29,12 @@
   PushNotificationsSubscribeTask(buzz::XmppTaskParentInterface* parent,
                                  const SubscriptionList& subscriptions,
                                  Delegate* delegate);
-  virtual ~PushNotificationsSubscribeTask();
+  ~PushNotificationsSubscribeTask() override;
 
   // Overridden from XmppTask.
-  virtual int ProcessStart() override;
-  virtual int ProcessResponse() override;
-  virtual bool HandleStanza(const buzz::XmlElement* stanza) override;
+  int ProcessStart() override;
+  int ProcessResponse() override;
+  bool HandleStanza(const buzz::XmlElement* stanza) override;
 
  private:
   // Assembles an Xmpp stanza which can be sent to subscribe to notifications.
diff --git a/jingle/notifier/listener/send_ping_task.h b/jingle/notifier/listener/send_ping_task.h
index ac4fa20..feccb17 100644
--- a/jingle/notifier/listener/send_ping_task.h
+++ b/jingle/notifier/listener/send_ping_task.h
@@ -29,12 +29,12 @@
   };
 
   SendPingTask(buzz::XmppTaskParentInterface* parent, Delegate* delegate);
-  virtual ~SendPingTask();
+  ~SendPingTask() override;
 
   // Overridden from buzz::XmppTask.
-  virtual int ProcessStart() override;
-  virtual int ProcessResponse() override;
-  virtual bool HandleStanza(const buzz::XmlElement* stanza) override;
+  int ProcessStart() override;
+  int ProcessResponse() override;
+  bool HandleStanza(const buzz::XmlElement* stanza) override;
 
  private:
   static buzz::XmlElement* MakePingStanza(const std::string& task_id);
diff --git a/jingle/notifier/listener/xmpp_push_client.h b/jingle/notifier/listener/xmpp_push_client.h
index 4c6fea5..dbbd468 100644
--- a/jingle/notifier/listener/xmpp_push_client.h
+++ b/jingle/notifier/listener/xmpp_push_client.h
@@ -41,34 +41,32 @@
       public SendPingTaskDelegate {
  public:
   explicit XmppPushClient(const NotifierOptions& notifier_options);
-  virtual ~XmppPushClient();
+  ~XmppPushClient() override;
 
   // PushClient implementation.
-  virtual void AddObserver(PushClientObserver* observer) override;
-  virtual void RemoveObserver(PushClientObserver* observer) override;
-  virtual void UpdateSubscriptions(
-      const SubscriptionList& subscriptions) override;
-  virtual void UpdateCredentials(
-      const std::string& email, const std::string& token) override;
-  virtual void SendNotification(const Notification& notification) override;
-  virtual void SendPing() override;
+  void AddObserver(PushClientObserver* observer) override;
+  void RemoveObserver(PushClientObserver* observer) override;
+  void UpdateSubscriptions(const SubscriptionList& subscriptions) override;
+  void UpdateCredentials(const std::string& email,
+                         const std::string& token) override;
+  void SendNotification(const Notification& notification) override;
+  void SendPing() override;
 
   // Login::Delegate implementation.
-  virtual void OnConnect(
+  void OnConnect(
       base::WeakPtr<buzz::XmppTaskParentInterface> base_task) override;
-  virtual void OnTransientDisconnection() override;
-  virtual void OnCredentialsRejected() override;
+  void OnTransientDisconnection() override;
+  void OnCredentialsRejected() override;
 
   // PushNotificationsListenTaskDelegate implementation.
-  virtual void OnNotificationReceived(
-      const Notification& notification) override;
+  void OnNotificationReceived(const Notification& notification) override;
 
   // PushNotificationsSubscribeTaskDelegate implementation.
-  virtual void OnSubscribed() override;
-  virtual void OnSubscriptionError() override;
+  void OnSubscribed() override;
+  void OnSubscriptionError() override;
 
   // SendPingTaskDelegate implementation.
-  virtual void OnPingResponseReceived() override;
+  void OnPingResponseReceived() override;
 
  private:
   base::ThreadChecker thread_checker_;
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 0f1291f1..280dc3d8 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -4,8 +4,9 @@
 
 import("//build/config/android/config.gni")
 import("//build/config/arm.gni")
-import("//build/config/ui.gni")
+import("//build/config/features.gni")
 import("//build/config/linux/pkg_config.gni")
+import("//build/config/ui.gni")
 import("//media/media_options.gni")
 
 # Common configuration for targets in the media directory.
@@ -27,8 +28,9 @@
 }
 
 config("media_dependent_config") {
+  defines = []
   if (!media_use_libvpx) {
-    defines = [ "MEDIA_DISABLE_LIBVPX" ]
+    defines += [ "MEDIA_DISABLE_LIBVPX" ]
   }
   if (is_win) {
     ldflags = [
@@ -375,6 +377,8 @@
 
   if (proprietary_codecs) {
     sources += [
+      "filters/h264_to_annex_b_bitstream_converter.cc",
+      "filters/h264_to_annex_b_bitstream_converter.h",
       "formats/mp2t/es_adapter_video.cc",
       "formats/mp2t/es_adapter_video.h",
       "formats/mp2t/es_parser.cc",
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index 5b473e8..d89881e 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -65,6 +65,8 @@
     "audio_output_proxy.h",
     "audio_output_resampler.cc",
     "audio_output_resampler.h",
+    "audio_output_stream_sink.cc",
+    "audio_output_stream_sink.h",
     "audio_power_monitor.cc",
     "audio_power_monitor.h",
     "audio_source_diverter.h",
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index 3bd14f1..44ecb29 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -117,7 +117,8 @@
 
 AudioInputController::AudioInputController(EventHandler* handler,
                                            SyncWriter* sync_writer,
-                                           UserInputMonitor* user_input_monitor)
+                                           UserInputMonitor* user_input_monitor,
+                                           const bool agc_is_enabled)
     : creator_task_runner_(base::MessageLoopProxy::current()),
       handler_(handler),
       stream_(NULL),
@@ -126,6 +127,7 @@
       sync_writer_(sync_writer),
       max_volume_(0.0),
       user_input_monitor_(user_input_monitor),
+      agc_is_enabled_(agc_is_enabled),
 #if defined(AUDIO_POWER_MONITORING)
       power_measurement_is_enabled_(false),
       log_silence_state_(false),
@@ -156,7 +158,7 @@
         audio_manager, event_handler, params, user_input_monitor);
   }
   scoped_refptr<AudioInputController> controller(
-      new AudioInputController(event_handler, NULL, user_input_monitor));
+      new AudioInputController(event_handler, NULL, user_input_monitor, false));
 
   controller->task_runner_ = audio_manager->GetTaskRunner();
 
@@ -182,7 +184,8 @@
     const AudioParameters& params,
     const std::string& device_id,
     SyncWriter* sync_writer,
-    UserInputMonitor* user_input_monitor) {
+    UserInputMonitor* user_input_monitor,
+    const bool agc_is_enabled) {
   DCHECK(audio_manager);
   DCHECK(sync_writer);
 
@@ -191,8 +194,8 @@
 
   // Create the AudioInputController object and ensure that it runs on
   // the audio-manager thread.
-  scoped_refptr<AudioInputController> controller(
-      new AudioInputController(event_handler, sync_writer, user_input_monitor));
+  scoped_refptr<AudioInputController> controller(new AudioInputController(
+      event_handler, sync_writer, user_input_monitor, agc_is_enabled));
   controller->task_runner_ = audio_manager->GetTaskRunner();
 
   // Create and open a new audio input stream from the existing
@@ -222,8 +225,8 @@
 
   // Create the AudioInputController object and ensure that it runs on
   // the audio-manager thread.
-  scoped_refptr<AudioInputController> controller(
-      new AudioInputController(event_handler, sync_writer, user_input_monitor));
+  scoped_refptr<AudioInputController> controller(new AudioInputController(
+      event_handler, sync_writer, user_input_monitor, false));
   controller->task_runner_ = task_runner;
 
   // TODO(miu): See TODO at top of file.  Until that's resolved, we need to
@@ -260,11 +263,6 @@
       &AudioInputController::DoSetVolume, this, volume));
 }
 
-void AudioInputController::SetAutomaticGainControl(bool enabled) {
-  task_runner_->PostTask(FROM_HERE, base::Bind(
-      &AudioInputController::DoSetAutomaticGainControl, this, enabled));
-}
-
 void AudioInputController::DoCreate(AudioManager* audio_manager,
                                     const AudioParameters& params,
                                     const std::string& device_id) {
@@ -274,7 +272,9 @@
     handler_->OnLog(this, "AIC::DoCreate");
 
 #if defined(AUDIO_POWER_MONITORING)
-  power_measurement_is_enabled_ = true;
+  // Disable power monitoring for streams that run without AGC enabled to
+  // avoid adding logs and UMA for non-WebRTC clients.
+  power_measurement_is_enabled_ = agc_is_enabled_;
   last_audio_level_log_time_ = base::TimeTicks::Now();
   silence_state_ = SILENCE_STATE_NO_MEASUREMENT;
 #endif
@@ -327,6 +327,10 @@
 
   DCHECK(!no_data_timer_.get());
 
+  // Set AGC state using mode in |agc_is_enabled_| which can only be enabled in
+  // CreateLowLatency().
+  stream_->SetAutomaticGainControl(agc_is_enabled_);
+
   // Create the data timer which will call FirstCheckForNoData(). The timer
   // is started in DoRecord() and restarted in each DoCheckForNoData()
   // callback.
@@ -449,17 +453,6 @@
   stream_->SetVolume(max_volume_ * volume);
 }
 
-void AudioInputController::DoSetAutomaticGainControl(bool enabled) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK_NE(state_, RECORDING);
-
-  // Ensure that the AGC state only can be modified before streaming starts.
-  if (state_ != CREATED)
-    return;
-
-  stream_->SetAutomaticGainControl(enabled);
-}
-
 void AudioInputController::FirstCheckForNoData() {
   DCHECK(task_runner_->BelongsToCurrentThread());
   LogCaptureStartupResult(GetDataIsActive() ?
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h
index 4bacaa54..19d04ec 100644
--- a/media/audio/audio_input_controller.h
+++ b/media/audio/audio_input_controller.h
@@ -188,7 +188,8 @@
       const std::string& device_id,
       // External synchronous writer for audio controller.
       SyncWriter* sync_writer,
-      UserInputMonitor* user_input_monitor);
+      UserInputMonitor* user_input_monitor,
+      const bool agc_is_enabled);
 
   // Factory method for creating an AudioInputController with an existing
   // |stream| for low-latency mode, taking ownership of |stream|. The stream
@@ -221,10 +222,6 @@
   // to muted and 1.0 to maximum volume.
   virtual void SetVolume(double volume);
 
-  // Sets the Automatic Gain Control (AGC) state of the input stream.
-  // Changing the AGC state is not supported while recording is active.
-  virtual void SetAutomaticGainControl(bool enabled);
-
   // AudioInputCallback implementation. Threading details depends on the
   // device-specific implementation.
   void OnData(AudioInputStream* stream,
@@ -267,8 +264,9 @@
 
   AudioInputController(EventHandler* handler,
                        SyncWriter* sync_writer,
-                       UserInputMonitor* user_input_monitor);
-  ~AudioInputController() override;
+                       UserInputMonitor* user_input_monitor,
+                       const bool agc_is_enabled);
+  virtual ~AudioInputController();
 
   // Methods called on the audio thread (owned by the AudioManager).
   void DoCreate(AudioManager* audio_manager,
@@ -282,7 +280,6 @@
   void DoClose();
   void DoReportError();
   void DoSetVolume(double volume);
-  void DoSetAutomaticGainControl(bool enabled);
   void DoOnData(scoped_ptr<AudioBus> data);
   void DoLogAudioLevels(float level_dbfs, int microphone_volume_percent);
 
@@ -351,6 +348,8 @@
 
   UserInputMonitor* user_input_monitor_;
 
+  const bool agc_is_enabled_;
+
 #if defined(AUDIO_POWER_MONITORING)
   // Enabled in DoCrete() but not in DoCreateForStream().
   bool power_measurement_is_enabled_;
diff --git a/media/audio/audio_output_stream_sink.cc b/media/audio/audio_output_stream_sink.cc
new file mode 100644
index 0000000..e233e994
--- /dev/null
+++ b/media/audio/audio_output_stream_sink.cc
@@ -0,0 +1,126 @@
+// 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 "media/audio/audio_output_stream_sink.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "media/audio/audio_manager.h"
+
+namespace media {
+
+AudioOutputStreamSink::AudioOutputStreamSink()
+    : render_callback_(NULL),
+      audio_task_runner_(AudioManager::Get()->GetTaskRunner()),
+      stream_(NULL),
+      active_render_callback_(NULL) {
+}
+
+AudioOutputStreamSink::~AudioOutputStreamSink() {
+}
+
+void AudioOutputStreamSink::Initialize(const AudioParameters& params,
+                                       RenderCallback* callback) {
+  DCHECK(callback);
+  DCHECK(!render_callback_);
+  params_ = params;
+  render_callback_ = callback;
+}
+
+void AudioOutputStreamSink::Start() {
+  audio_task_runner_->PostTask(
+      FROM_HERE, base::Bind(&AudioOutputStreamSink::DoStart, this));
+}
+
+void AudioOutputStreamSink::Stop() {
+  ClearCallback();
+  audio_task_runner_->PostTask(
+      FROM_HERE, base::Bind(&AudioOutputStreamSink::DoStop, this));
+}
+
+void AudioOutputStreamSink::Pause() {
+  ClearCallback();
+  audio_task_runner_->PostTask(
+      FROM_HERE, base::Bind(&AudioOutputStreamSink::DoPause, this));
+}
+
+void AudioOutputStreamSink::Play() {
+  base::AutoLock al(callback_lock_);
+  active_render_callback_ = render_callback_;
+  audio_task_runner_->PostTask(
+      FROM_HERE, base::Bind(&AudioOutputStreamSink::DoPlay, this));
+}
+
+bool AudioOutputStreamSink::SetVolume(double volume) {
+  audio_task_runner_->PostTask(
+      FROM_HERE, base::Bind(&AudioOutputStreamSink::DoSetVolume, this, volume));
+  return true;
+};
+
+int AudioOutputStreamSink::OnMoreData(AudioBus* dest,
+                                      uint32 total_bytes_delay) {
+  // Note: Runs on the audio thread created by the OS.
+  base::AutoLock al(callback_lock_);
+  if (!active_render_callback_)
+    return 0;
+
+  return active_render_callback_->Render(
+      dest, total_bytes_delay * 1000.0 / params_.GetBytesPerSecond());
+}
+
+void AudioOutputStreamSink::OnError(AudioOutputStream* stream) {
+  // Note: Runs on the audio thread created by the OS.
+  base::AutoLock al(callback_lock_);
+  if (active_render_callback_)
+    active_render_callback_->OnRenderError();
+}
+
+void AudioOutputStreamSink::DoStart() {
+  DCHECK(audio_task_runner_->BelongsToCurrentThread());
+
+  // Create an AudioOutputStreamProxy which will handle any and all resampling
+  // necessary to generate a low latency output stream.
+  stream_ =
+      AudioManager::Get()->MakeAudioOutputStreamProxy(params_, std::string());
+  if (!stream_ || !stream_->Open()) {
+    render_callback_->OnRenderError();
+    if (stream_)
+      stream_->Close();
+    stream_ = NULL;
+  }
+}
+
+void AudioOutputStreamSink::DoStop() {
+  DCHECK(audio_task_runner_->BelongsToCurrentThread());
+
+  if (!stream_)
+    return;
+
+  DoPause();
+  stream_->Close();
+  stream_ = NULL;
+}
+
+void AudioOutputStreamSink::DoPause() {
+  DCHECK(audio_task_runner_->BelongsToCurrentThread());
+  stream_->Stop();
+}
+
+void AudioOutputStreamSink::DoPlay() {
+  DCHECK(audio_task_runner_->BelongsToCurrentThread());
+  stream_->Start(this);
+}
+
+void AudioOutputStreamSink::DoSetVolume(double volume) {
+  DCHECK(audio_task_runner_->BelongsToCurrentThread());
+  stream_->SetVolume(volume);
+}
+
+void AudioOutputStreamSink::ClearCallback() {
+  base::AutoLock al(callback_lock_);
+  active_render_callback_ = NULL;
+}
+
+}  // namepace media
diff --git a/media/audio/audio_output_stream_sink.h b/media/audio/audio_output_stream_sink.h
new file mode 100644
index 0000000..c6f04a7d
--- /dev/null
+++ b/media/audio/audio_output_stream_sink.h
@@ -0,0 +1,80 @@
+// 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 MEDIA_AUDIO_AUDIO_OUTPUT_STREAM_SINK_H_
+#define MEDIA_AUDIO_AUDIO_OUTPUT_STREAM_SINK_H_
+
+#include "base/compiler_specific.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/lock.h"
+#include "media/audio/audio_io.h"
+#include "media/base/audio_renderer_sink.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+// Wrapper which exposes the browser side audio interface (AudioOutputStream) as
+// if it were a renderer side audio interface (AudioRendererSink). Note: This
+// will not work for sandboxed renderers.
+//
+// TODO(dalecurtis): Delete this class once we have a proper mojo audio service;
+// tracked by http://crbug.com/425368
+class MEDIA_EXPORT AudioOutputStreamSink
+    : NON_EXPORTED_BASE(public AudioRendererSink),
+      public AudioOutputStream::AudioSourceCallback {
+ public:
+  AudioOutputStreamSink();
+
+  // AudioRendererSink implementation.
+  void Initialize(const AudioParameters& params,
+                  RenderCallback* callback) override;
+  void Start() override;
+  void Stop() override;
+  void Pause() override;
+  void Play() override;
+  bool SetVolume(double volume) override;
+
+  // AudioSourceCallback implementation.
+  int OnMoreData(AudioBus* dest, uint32 total_bytes_delay) override;
+  void OnError(AudioOutputStream* stream) override;
+
+ private:
+  ~AudioOutputStreamSink() override;
+
+  // Helper methods for running AudioManager methods on the audio thread.
+  void DoStart();
+  void DoStop();
+  void DoPause();
+  void DoPlay();
+  void DoSetVolume(double volume);
+
+  // Clears |active_render_callback_| under lock, synchronously stopping render
+  // callbacks from any thread.  Must be called before Pause() and Stop()
+  // trampoline to their helper methods on the audio thread.
+  void ClearCallback();
+
+  // Parameters provided by Initialize(), cached for use on other threads.
+  AudioParameters params_;
+
+  // Since Initialize() is only called once for AudioRenderSinks, save the
+  // callback both here and under |active_render_callback_| which will be
+  // cleared during Pause() and Stop() to achieve "synchronous" stoppage.
+  RenderCallback* render_callback_;
+
+  // The task runner for the audio thread.
+  const scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_;
+
+  // The actual AudioOutputStream, must only be accessed on the audio thread.
+  AudioOutputStream* stream_;
+
+  // Lock and callback for forwarding OnMoreData() calls into Render() calls.
+  base::Lock callback_lock_;
+  RenderCallback* active_render_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioOutputStreamSink);
+};
+
+}  // namepace media
+
+#endif  // MEDIA_AUDIO_AUDIO_OUTPUT_STREAM_SINK_H_
diff --git a/media/audio/audio_parameters.cc b/media/audio/audio_parameters.cc
index 3265450..7dd26e1ba 100644
--- a/media/audio/audio_parameters.cc
+++ b/media/audio/audio_parameters.cc
@@ -87,6 +87,17 @@
          (frames_per_buffer_ <= media::limits::kMaxSamplesPerPacket);
 }
 
+std::string AudioParameters::AsHumanReadableString() const {
+  std::ostringstream s;
+  s << "format: " << format()
+    << " channels: " << channels()
+    << " channel_layout: " << channel_layout()
+    << " sample_rate: " << sample_rate()
+    << " bits_per_sample: " << bits_per_sample()
+    << " frames_per_buffer: " << frames_per_buffer();
+  return s.str();
+}
+
 int AudioParameters::GetBytesPerBuffer() const {
   return frames_per_buffer_ * GetBytesPerFrame();
 }
@@ -100,9 +111,9 @@
 }
 
 base::TimeDelta AudioParameters::GetBufferDuration() const {
-  return base::TimeDelta::FromMicroseconds(
+  return base::TimeDelta::FromMicroseconds(static_cast<int64>(
       frames_per_buffer_ * base::Time::kMicrosecondsPerSecond /
-      static_cast<float>(sample_rate_));
+      static_cast<float>(sample_rate_)));
 }
 
 bool AudioParameters::Equals(const AudioParameters& other) const {
diff --git a/media/audio/audio_parameters.h b/media/audio/audio_parameters.h
index 222132ef..b5ac71d 100644
--- a/media/audio/audio_parameters.h
+++ b/media/audio/audio_parameters.h
@@ -5,6 +5,8 @@
 #ifndef MEDIA_AUDIO_AUDIO_PARAMETERS_H_
 #define MEDIA_AUDIO_AUDIO_PARAMETERS_H_
 
+#include <string>
+
 #include "base/basictypes.h"
 #include "base/time/time.h"
 #include "media/base/channel_layout.h"
@@ -72,6 +74,10 @@
   // in media::Limits.
   bool IsValid() const;
 
+  // Returns a human-readable string describing |*this|.  For debugging & test
+  // output only.
+  std::string AsHumanReadableString() const;
+
   // Returns size of audio buffer in bytes.
   int GetBytesPerBuffer() const;
 
diff --git a/media/audio/test_audio_input_controller_factory.cc b/media/audio/test_audio_input_controller_factory.cc
index 4490dc9..cd07e20 100644
--- a/media/audio/test_audio_input_controller_factory.cc
+++ b/media/audio/test_audio_input_controller_factory.cc
@@ -14,7 +14,10 @@
     EventHandler* event_handler,
     SyncWriter* sync_writer,
     UserInputMonitor* user_input_monitor)
-    : AudioInputController(event_handler, sync_writer, user_input_monitor),
+    : AudioInputController(event_handler,
+                           sync_writer,
+                           user_input_monitor,
+                           false),
       audio_parameters_(audio_parameters),
       factory_(factory),
       event_handler_(event_handler) {
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn
index 5e0f8d0..61fc291 100644
--- a/media/base/BUILD.gn
+++ b/media/base/BUILD.gn
@@ -64,6 +64,8 @@
     "cdm_promise.h",
     "channel_mixer.cc",
     "channel_mixer.h",
+    "channel_mixing_matrix.cc",
+    "channel_mixing_matrix.h",
     "clock.h",
     "data_buffer.cc",
     "data_buffer.h",
@@ -85,6 +87,9 @@
     "demuxer_stream_provider.h",
     "djb2.cc",
     "djb2.h",
+    "eme_constants.h",
+    "key_system_info.cc",
+    "key_system_info.h",
     "media.cc",
     "media.h",
     "media_keys.cc",
@@ -291,6 +296,7 @@
     "callback_holder.h",
     "callback_holder_unittest.cc",
     "channel_mixer_unittest.cc",
+    "channel_mixing_matrix_unittest.cc",
     "data_buffer_unittest.cc",
     "decoder_buffer_queue_unittest.cc",
     "decoder_buffer_unittest.cc",
diff --git a/media/base/android/BUILD.gn b/media/base/android/BUILD.gn
index b2d7bbc..9e4db09 100644
--- a/media/base/android/BUILD.gn
+++ b/media/base/android/BUILD.gn
@@ -91,13 +91,12 @@
   jni_package = "media"
 }
 
-java_cpp_template("media_android_imageformat_list") {
-  package_name = "org/chromium/media"
+java_cpp_enum("media_java_enums_srcjar") {
   sources = [
-    "java/src/org/chromium/media/AndroidImageFormat.template",
+    "//media/video/capture/android/video_capture_device_android.h",
   ]
-  inputs = [
-    "//media/video/capture/android/imageformat_list.h"
+  outputs = [
+    "org/chromium/media/AndroidImageFormat.java",
   ]
 }
 
@@ -107,7 +106,7 @@
   ]
 
   srcjar_deps = [
-    ":media_android_imageformat_list",
+    ":media_java_enums_srcjar",
   ]
 
   DEPRECATED_java_in_dir = "java/src"
diff --git a/media/base/android/OWNERS b/media/base/android/OWNERS
index fead260..4a94f86 100644
--- a/media/base/android/OWNERS
+++ b/media/base/android/OWNERS
@@ -1,5 +1,2 @@
 # Preferred reviewers.
 qinmin@chromium.org
-
-# VideoCapture classes under Android java/src/org/chromium/media/
-per-file VideoCapture*.java=mcasas@chromium.org
diff --git a/media/base/android/java/src/org/chromium/media/AndroidImageFormat.template b/media/base/android/java/src/org/chromium/media/AndroidImageFormat.template
deleted file mode 100644
index c7879aa..0000000
--- a/media/base/android/java/src/org/chromium/media/AndroidImageFormat.template
+++ /dev/null
@@ -1,12 +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.media;
-
-class AndroidImageFormat {
-#define DEFINE_ANDROID_IMAGEFORMAT(name, value) \
-    static final int name = value;
-#include "media/video/capture/android/imageformat_list.h"
-#undef DEFINE_ANDROID_IMAGEFORMAT
-}
\ No newline at end of file
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
index 4595bf00..28d20ffd 100644
--- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
+++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
@@ -228,6 +228,30 @@
         return codecName;
     }
 
+    /**
+     * Get a list of encoder supported color formats for specified mime type.
+     */
+    @CalledByNative
+    private static int[] getEncoderColorFormatsForMime(String mime) {
+        int count = MediaCodecList.getCodecCount();
+        for (int i = 0; i < count; ++i) {
+            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+            if (!info.isEncoder())
+                continue;
+
+            String[] supportedTypes = info.getSupportedTypes();
+            for (int j = 0; j < supportedTypes.length; ++j) {
+                if (!supportedTypes[j].equalsIgnoreCase(mime))
+                    continue;
+
+                MediaCodecInfo.CodecCapabilities capabilities =
+                    info.getCapabilitiesForType(mime);
+                return capabilities.colorFormats;
+            }
+        }
+        return null;
+    }
+
     @SuppressWarnings("deprecation")
     private static String getDecoderNameForMime(String mime) {
         int count = MediaCodecList.getCodecCount();
diff --git a/media/base/android/java/src/org/chromium/media/OWNERS b/media/base/android/java/src/org/chromium/media/OWNERS
new file mode 100644
index 0000000..85e4365
--- /dev/null
+++ b/media/base/android/java/src/org/chromium/media/OWNERS
@@ -0,0 +1,2 @@
+# VideoCapture classes under Android
+per-file VideoCapture*.java=mcasas@chromium.org
diff --git a/media/base/android/java/src/org/chromium/media/VideoCapture.java b/media/base/android/java/src/org/chromium/media/VideoCapture.java
index e024ec4..06eae1d 100644
--- a/media/base/android/java/src/org/chromium/media/VideoCapture.java
+++ b/media/base/android/java/src/org/chromium/media/VideoCapture.java
@@ -6,25 +6,17 @@
 
 import android.content.Context;
 import android.graphics.ImageFormat;
-import android.graphics.SurfaceTexture;
-import android.opengl.GLES20;
-import android.util.Log;
-import android.view.Surface;
-import android.view.WindowManager;
 
 import org.chromium.base.CalledByNative;
 import org.chromium.base.JNINamespace;
 
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.locks.ReentrantLock;
-
 /**
- * Video Capture Device base class to interface to native Chromium.
+ * Video Capture Device base class, defines a set of methods that native code
+ * needs to use to configure, start capture, and to be reached by callbacks and
+ * provides some neccesary data type(s) with accessors.
  **/
 @JNINamespace("media")
-@SuppressWarnings("deprecation")
-public abstract class VideoCapture implements android.hardware.Camera.PreviewCallback {
+public abstract class VideoCapture {
 
     protected static class CaptureFormat {
         int mWidth;
@@ -57,37 +49,11 @@
         }
     }
 
-    protected android.hardware.Camera mCamera;
     protected CaptureFormat mCaptureFormat = null;
-    // Lock to mutually exclude execution of OnPreviewFrame {start/stop}Capture.
-    protected ReentrantLock mPreviewBufferLock = new ReentrantLock();
-    protected Context mContext = null;
-    // True when native code has started capture.
-    protected boolean mIsRunning = false;
-
-    protected int mId;
+    protected final Context mContext;
+    protected final int mId;
     // Native callback context variable.
-    protected long mNativeVideoCaptureDeviceAndroid;
-    protected int[] mGlTextures = null;
-    protected SurfaceTexture mSurfaceTexture = null;
-    protected static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
-
-    protected int mCameraOrientation;
-    protected int mCameraFacing;
-    protected int mDeviceOrientation;
-    private static final String TAG = "VideoCapture";
-
-    static android.hardware.Camera.CameraInfo getCameraInfo(int id) {
-        android.hardware.Camera.CameraInfo cameraInfo =
-                new android.hardware.Camera.CameraInfo();
-        try {
-            android.hardware.Camera.getCameraInfo(id, cameraInfo);
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "getCameraInfo: Camera.getCameraInfo: " + ex);
-            return null;
-        }
-        return cameraInfo;
-    }
+    protected final long mNativeVideoCaptureDeviceAndroid;
 
     VideoCapture(Context context,
                  int id,
@@ -98,289 +64,53 @@
     }
 
     @CalledByNative
-    boolean allocate(int width, int height, int frameRate) {
-        Log.d(TAG, "allocate: requested (" + width + "x" + height + ")@" +
-                frameRate + "fps");
-        try {
-            mCamera = android.hardware.Camera.open(mId);
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "allocate: Camera.open: " + ex);
-            return false;
-        }
-
-        android.hardware.Camera.CameraInfo cameraInfo = VideoCapture.getCameraInfo(mId);
-        if (cameraInfo == null) {
-            mCamera.release();
-            mCamera = null;
-            return false;
-        }
-
-        mCameraOrientation = cameraInfo.orientation;
-        mCameraFacing = cameraInfo.facing;
-        mDeviceOrientation = getDeviceOrientation();
-        Log.d(TAG, "allocate: orientation dev=" + mDeviceOrientation +
-                  ", cam=" + mCameraOrientation + ", facing=" + mCameraFacing);
-
-        android.hardware.Camera.Parameters parameters = getCameraParameters(mCamera);
-        if (parameters == null) {
-            mCamera = null;
-            return false;
-        }
-
-        // getSupportedPreviewFpsRange() returns a List with at least one
-        // element, but when camera is in bad state, it can return null pointer.
-        List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange();
-        if (listFpsRange == null || listFpsRange.size() == 0) {
-            Log.e(TAG, "allocate: no fps range found");
-            return false;
-        }
-        // Use the first range as the default chosen range.
-        int[] chosenFpsRange = listFpsRange.get(0);
-        int chosenFrameRate = (chosenFpsRange[0] + 999) / 1000;
-        int fpsRangeSize = Integer.MAX_VALUE;
-        // API fps ranges are scaled up x1000 to avoid floating point.
-        int frameRateScaled = frameRate * 1000;
-        for (int[] fpsRange : listFpsRange) {
-            if (fpsRange[0] <= frameRateScaled && frameRateScaled <= fpsRange[1] &&
-                    (fpsRange[1] - fpsRange[0]) <= fpsRangeSize) {
-                chosenFpsRange = fpsRange;
-                chosenFrameRate = frameRate;
-                fpsRangeSize = fpsRange[1] - fpsRange[0];
-            }
-        }
-        Log.d(TAG, "allocate: fps set to " + chosenFrameRate + ", [" +
-                chosenFpsRange[0] + "-" + chosenFpsRange[1] + "]");
-
-        // Calculate size.
-        List<android.hardware.Camera.Size> listCameraSize =
-                parameters.getSupportedPreviewSizes();
-        int minDiff = Integer.MAX_VALUE;
-        int matchedWidth = width;
-        int matchedHeight = height;
-        for (android.hardware.Camera.Size size : listCameraSize) {
-            int diff = Math.abs(size.width - width) +
-                       Math.abs(size.height - height);
-            Log.d(TAG, "allocate: supported (" +
-                    size.width + ", " + size.height + "), diff=" + diff);
-            // TODO(wjia): Remove this hack (forcing width to be multiple
-            // of 32) by supporting stride in video frame buffer.
-            // Right now, VideoCaptureController requires compact YV12
-            // (i.e., with no padding).
-            if (diff < minDiff && (size.width % 32 == 0)) {
-                minDiff = diff;
-                matchedWidth = size.width;
-                matchedHeight = size.height;
-            }
-        }
-        if (minDiff == Integer.MAX_VALUE) {
-            Log.e(TAG, "allocate: can not find a multiple-of-32 resolution");
-            return false;
-        }
-        Log.d(TAG, "allocate: matched (" + matchedWidth + "x" + matchedHeight + ")");
-
-        if (parameters.isVideoStabilizationSupported()) {
-            Log.d(TAG, "Image stabilization supported, currently: " +
-                    parameters.getVideoStabilization() + ", setting it.");
-            parameters.setVideoStabilization(true);
-        } else {
-            Log.d(TAG, "Image stabilization not supported.");
-        }
-
-        setCaptureParameters(matchedWidth, matchedHeight, chosenFrameRate, parameters);
-        parameters.setPreviewSize(mCaptureFormat.mWidth,
-                                  mCaptureFormat.mHeight);
-        parameters.setPreviewFpsRange(chosenFpsRange[0], chosenFpsRange[1]);
-        parameters.setPreviewFormat(mCaptureFormat.mPixelFormat);
-        try {
-            mCamera.setParameters(parameters);
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "setParameters: " + ex);
-            return false;
-        }
-
-        // Set SurfaceTexture. Android Capture needs a SurfaceTexture even if
-        // it is not going to be used.
-        mGlTextures = new int[1];
-        // Generate one texture pointer and bind it as an external texture.
-        GLES20.glGenTextures(1, mGlTextures, 0);
-        GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mGlTextures[0]);
-        // No mip-mapping with camera source.
-        GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
-                GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
-        GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
-                GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
-        // Clamp to edge is only option.
-        GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
-                GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
-        GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
-                GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
-
-        mSurfaceTexture = new SurfaceTexture(mGlTextures[0]);
-        mSurfaceTexture.setOnFrameAvailableListener(null);
-        try {
-            mCamera.setPreviewTexture(mSurfaceTexture);
-        } catch (IOException ex) {
-            Log.e(TAG, "allocate: " + ex);
-            return false;
-        }
-
-        allocateBuffers();
-        return true;
-    }
+    abstract boolean allocate(int width, int height, int frameRate);
 
     @CalledByNative
-    public int startCapture() {
-        if (mCamera == null) {
-            Log.e(TAG, "startCapture: camera is null");
-            return -1;
-        }
-
-        mPreviewBufferLock.lock();
-        try {
-            if (mIsRunning) {
-                return 0;
-            }
-            mIsRunning = true;
-        } finally {
-            mPreviewBufferLock.unlock();
-        }
-        setPreviewCallback(this);
-        try {
-            mCamera.startPreview();
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "startCapture: Camera.startPreview: " + ex);
-            return -1;
-        }
-        return 0;
-    }
+    abstract int startCapture();
 
     @CalledByNative
-    public int stopCapture() {
-        if (mCamera == null) {
-            Log.e(TAG, "stopCapture: camera is null");
-            return 0;
-        }
-
-        mPreviewBufferLock.lock();
-        try {
-            if (!mIsRunning) {
-                return 0;
-            }
-            mIsRunning = false;
-        } finally {
-            mPreviewBufferLock.unlock();
-        }
-
-        mCamera.stopPreview();
-        setPreviewCallback(null);
-        return 0;
-    }
+    abstract int stopCapture();
 
     @CalledByNative
-    public void deallocate() {
-        if (mCamera == null)
-            return;
-
-        stopCapture();
-        try {
-            mCamera.setPreviewTexture(null);
-            if (mGlTextures != null)
-                GLES20.glDeleteTextures(1, mGlTextures, 0);
-            mCaptureFormat = null;
-            mCamera.release();
-            mCamera = null;
-        } catch (IOException ex) {
-            Log.e(TAG, "deallocate: failed to deallocate camera, " + ex);
-            return;
-        }
-    }
-
-    // Local hook to allow derived classes to fill capture format and modify
-    // camera parameters as they see fit.
-    abstract void setCaptureParameters(
-            int width,
-            int height,
-            int frameRate,
-            android.hardware.Camera.Parameters cameraParameters);
+    abstract void deallocate();
 
     // Local hook to allow derived classes to configure and plug capture
     // buffers if needed.
     abstract void allocateBuffers();
 
-    // Local method to be overriden with the particular setPreviewCallback to be
-    // used in the implementations.
-    abstract void setPreviewCallback(android.hardware.Camera.PreviewCallback cb);
-
     @CalledByNative
-    public int queryWidth() {
+    public final int queryWidth() {
         return mCaptureFormat.mWidth;
     }
 
     @CalledByNative
-    public int queryHeight() {
+    public final int queryHeight() {
         return mCaptureFormat.mHeight;
     }
 
     @CalledByNative
-    public int queryFrameRate() {
+    public final int queryFrameRate() {
         return mCaptureFormat.mFramerate;
     }
 
     @CalledByNative
-    public int getColorspace() {
+    public final int getColorspace() {
         switch (mCaptureFormat.mPixelFormat) {
             case ImageFormat.YV12:
-                return AndroidImageFormat.ANDROID_IMAGEFORMAT_YV12;
+                return AndroidImageFormat.YV12;
             case ImageFormat.NV21:
-                return AndroidImageFormat.ANDROID_IMAGEFORMAT_NV21;
+                return AndroidImageFormat.NV21;
             case ImageFormat.UNKNOWN:
             default:
-                return AndroidImageFormat.ANDROID_IMAGEFORMAT_UNKNOWN;
+                return AndroidImageFormat.UNKNOWN;
         }
     }
 
-    protected int getDeviceOrientation() {
-        int orientation = 0;
-        if (mContext != null) {
-            WindowManager wm = (WindowManager) mContext.getSystemService(
-                    Context.WINDOW_SERVICE);
-            switch(wm.getDefaultDisplay().getRotation()) {
-                case Surface.ROTATION_90:
-                    orientation = 90;
-                    break;
-                case Surface.ROTATION_180:
-                    orientation = 180;
-                    break;
-                case Surface.ROTATION_270:
-                    orientation = 270;
-                    break;
-                case Surface.ROTATION_0:
-                default:
-                    orientation = 0;
-                    break;
-            }
-        }
-        return orientation;
-    }
-
     // Method for VideoCapture implementations to call back native code.
     public native void nativeOnFrameAvailable(
             long nativeVideoCaptureDeviceAndroid,
             byte[] data,
             int length,
             int rotation);
-
-    protected static android.hardware.Camera.Parameters getCameraParameters(
-            android.hardware.Camera camera) {
-        android.hardware.Camera.Parameters parameters;
-        try {
-            parameters = camera.getParameters();
-        } catch (RuntimeException ex) {
-            Log.e(TAG, "getCameraParameters: android.hardware.Camera.getParameters: " + ex);
-            camera.release();
-            return null;
-        }
-        return parameters;
-    }
-
 }
diff --git a/media/base/android/java/src/org/chromium/media/VideoCaptureAndroid.java b/media/base/android/java/src/org/chromium/media/VideoCaptureAndroid.java
index e431ada..169758fb 100644
--- a/media/base/android/java/src/org/chromium/media/VideoCaptureAndroid.java
+++ b/media/base/android/java/src/org/chromium/media/VideoCaptureAndroid.java
@@ -12,13 +12,13 @@
 import java.util.List;
 
 /**
- * This class extends the VideoCapture base class for manipulating normal video
- * capture devices in Android, including receiving copies of preview frames via
- * Java-allocated buffers. It also includes class BuggyDeviceHack to deal with
- * troublesome devices.
+ * This class extends the VideoCaptureCamera base class for manipulating normal
+ * video capture devices in Android, including receiving copies of preview
+ * frames via Java-allocated buffers. It also includes class BuggyDeviceHack to
+ * deal with troublesome devices.
  **/
 @SuppressWarnings("deprecation")
-public class VideoCaptureAndroid extends VideoCapture {
+public class VideoCaptureAndroid extends VideoCaptureCamera {
 
     // Some devices don't support YV12 format correctly, even with JELLY_BEAN or
     // newer OS. To work around the issues on those devices, we have to request
@@ -51,8 +51,8 @@
         static void applyMinDimensions(CaptureFormat format) {
             // NOTE: this can discard requested aspect ratio considerations.
             for (IdAndSizes buggyDevice : CAPTURESIZE_BUGGY_DEVICE_LIST) {
-                if (buggyDevice.mModel.contentEquals(android.os.Build.MODEL) &&
-                        buggyDevice.mDevice.contentEquals(android.os.Build.DEVICE)) {
+                if (buggyDevice.mModel.contentEquals(android.os.Build.MODEL)
+                        && buggyDevice.mDevice.contentEquals(android.os.Build.DEVICE)) {
                     format.mWidth = (buggyDevice.mMinWidth > format.mWidth)
                             ? buggyDevice.mMinWidth : format.mWidth;
                     format.mHeight = (buggyDevice.mMinHeight > format.mHeight)
@@ -84,9 +84,10 @@
     }
 
     static String getName(int id) {
-        android.hardware.Camera.CameraInfo cameraInfo = VideoCapture.getCameraInfo(id);
-        return "camera " + id + ", facing " + (cameraInfo.facing ==
-                android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" : "back");
+        android.hardware.Camera.CameraInfo cameraInfo = VideoCaptureCamera.getCameraInfo(id);
+        if (cameraInfo == null) return null;
+        return "camera " + id + ", facing " + (cameraInfo.facing
+                == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" : "back");
     }
 
     static CaptureFormat[] getDeviceSupportedFormats(int id) {
@@ -115,9 +116,9 @@
             pixelFormats.add(ImageFormat.UNKNOWN);
         }
         for (Integer previewFormat : pixelFormats) {
-            int pixelFormat = AndroidImageFormat.ANDROID_IMAGEFORMAT_UNKNOWN;
+            int pixelFormat = AndroidImageFormat.UNKNOWN;
             if (previewFormat == ImageFormat.YV12) {
-                pixelFormat = AndroidImageFormat.ANDROID_IMAGEFORMAT_YV12;
+                pixelFormat = AndroidImageFormat.YV12;
             } else if (previewFormat == ImageFormat.NV21) {
                 continue;
             }
@@ -171,8 +172,8 @@
 
     @Override
     protected void allocateBuffers() {
-        mExpectedFrameSize = mCaptureFormat.mWidth * mCaptureFormat.mHeight *
-                ImageFormat.getBitsPerPixel(mCaptureFormat.mPixelFormat) / 8;
+        mExpectedFrameSize = mCaptureFormat.mWidth * mCaptureFormat.mHeight
+                * ImageFormat.getBitsPerPixel(mCaptureFormat.mPixelFormat) / 8;
         for (int i = 0; i < NUM_CAPTURE_BUFFERS; i++) {
             byte[] buffer = new byte[mExpectedFrameSize];
             mCamera.addCallbackBuffer(buffer);
diff --git a/media/base/android/java/src/org/chromium/media/VideoCaptureCamera.java b/media/base/android/java/src/org/chromium/media/VideoCaptureCamera.java
new file mode 100644
index 0000000..dd1632b0
--- /dev/null
+++ b/media/base/android/java/src/org/chromium/media/VideoCaptureCamera.java
@@ -0,0 +1,308 @@
+// 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.
+
+package org.chromium.media;
+
+import android.content.Context;
+import android.graphics.SurfaceTexture;
+import android.opengl.GLES20;
+import android.util.Log;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import org.chromium.base.JNINamespace;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Video Capture Device extension of VideoCapture to provide common functionality
+ * for capture using android.hardware.Camera API (deprecated in API 21). Normal
+ * Android and Tango devices are extensions of this class.
+ **/
+@JNINamespace("media")
+@SuppressWarnings("deprecation")
+public abstract class VideoCaptureCamera extends VideoCapture
+        implements android.hardware.Camera.PreviewCallback {
+
+    protected android.hardware.Camera mCamera;
+    // Lock to mutually exclude execution of OnPreviewFrame() and {start/stop}Capture().
+    protected ReentrantLock mPreviewBufferLock = new ReentrantLock();
+    // True when native code has started capture.
+    protected boolean mIsRunning = false;
+
+    protected int[] mGlTextures = null;
+    protected SurfaceTexture mSurfaceTexture = null;
+    protected static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
+
+    protected int mCameraOrientation;
+    protected int mCameraFacing;
+    protected int mDeviceOrientation;
+    private static final String TAG = "VideoCaptureCamera";
+
+    protected static android.hardware.Camera.CameraInfo getCameraInfo(int id) {
+        android.hardware.Camera.CameraInfo cameraInfo =
+                new android.hardware.Camera.CameraInfo();
+        try {
+            android.hardware.Camera.getCameraInfo(id, cameraInfo);
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "getCameraInfo: Camera.getCameraInfo: " + ex);
+            return null;
+        }
+        return cameraInfo;
+    }
+
+    protected static android.hardware.Camera.Parameters getCameraParameters(
+            android.hardware.Camera camera) {
+        android.hardware.Camera.Parameters parameters;
+        try {
+            parameters = camera.getParameters();
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "getCameraParameters: android.hardware.Camera.getParameters: " + ex);
+            camera.release();
+            return null;
+        }
+        return parameters;
+    }
+
+    VideoCaptureCamera(Context context,
+                       int id,
+                       long nativeVideoCaptureDeviceAndroid) {
+        super(context, id, nativeVideoCaptureDeviceAndroid);
+    }
+
+    @Override
+    public boolean allocate(int width, int height, int frameRate) {
+        Log.d(TAG, "allocate: requested (" + width + "x" + height + ")@"
+                + frameRate + "fps");
+        try {
+            mCamera = android.hardware.Camera.open(mId);
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "allocate: Camera.open: " + ex);
+            return false;
+        }
+
+        android.hardware.Camera.CameraInfo cameraInfo = VideoCaptureCamera.getCameraInfo(mId);
+        if (cameraInfo == null) {
+            mCamera.release();
+            mCamera = null;
+            return false;
+        }
+
+        mCameraOrientation = cameraInfo.orientation;
+        mCameraFacing = cameraInfo.facing;
+        mDeviceOrientation = getDeviceOrientation();
+        Log.d(TAG, "allocate: orientation dev=" + mDeviceOrientation
+                  + ", cam=" + mCameraOrientation + ", facing=" + mCameraFacing);
+
+        android.hardware.Camera.Parameters parameters = getCameraParameters(mCamera);
+        if (parameters == null) {
+            mCamera = null;
+            return false;
+        }
+
+        // getSupportedPreviewFpsRange() returns a List with at least one
+        // element, but when camera is in bad state, it can return null pointer.
+        List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange();
+        if (listFpsRange == null || listFpsRange.size() == 0) {
+            Log.e(TAG, "allocate: no fps range found");
+            return false;
+        }
+        // Use the first range as the default chosen range.
+        int[] chosenFpsRange = listFpsRange.get(0);
+        int chosenFrameRate = (chosenFpsRange[0] + 999) / 1000;
+        int fpsRangeSize = Integer.MAX_VALUE;
+        // API fps ranges are scaled up x1000 to avoid floating point.
+        int frameRateScaled = frameRate * 1000;
+        for (int[] fpsRange : listFpsRange) {
+            if (fpsRange[0] <= frameRateScaled && frameRateScaled <= fpsRange[1]
+                    && (fpsRange[1] - fpsRange[0]) <= fpsRangeSize) {
+                chosenFpsRange = fpsRange;
+                chosenFrameRate = frameRate;
+                fpsRangeSize = fpsRange[1] - fpsRange[0];
+            }
+        }
+        Log.d(TAG, "allocate: fps set to " + chosenFrameRate + ", ["
+                + chosenFpsRange[0] + "-" + chosenFpsRange[1] + "]");
+
+        // Calculate size.
+        List<android.hardware.Camera.Size> listCameraSize =
+                parameters.getSupportedPreviewSizes();
+        int minDiff = Integer.MAX_VALUE;
+        int matchedWidth = width;
+        int matchedHeight = height;
+        for (android.hardware.Camera.Size size : listCameraSize) {
+            int diff = Math.abs(size.width - width)
+                       + Math.abs(size.height - height);
+            Log.d(TAG, "allocate: supported ("
+                    + size.width + ", " + size.height + "), diff=" + diff);
+            // TODO(wjia): Remove this hack (forcing width to be multiple
+            // of 32) by supporting stride in video frame buffer.
+            // Right now, VideoCaptureController requires compact YV12
+            // (i.e., with no padding).
+            if (diff < minDiff && (size.width % 32 == 0)) {
+                minDiff = diff;
+                matchedWidth = size.width;
+                matchedHeight = size.height;
+            }
+        }
+        if (minDiff == Integer.MAX_VALUE) {
+            Log.e(TAG, "allocate: can not find a multiple-of-32 resolution");
+            return false;
+        }
+        Log.d(TAG, "allocate: matched (" + matchedWidth + "x" + matchedHeight + ")");
+
+        if (parameters.isVideoStabilizationSupported()) {
+            Log.d(TAG, "Image stabilization supported, currently: "
+                    + parameters.getVideoStabilization() + ", setting it.");
+            parameters.setVideoStabilization(true);
+        } else {
+            Log.d(TAG, "Image stabilization not supported.");
+        }
+
+        setCaptureParameters(matchedWidth, matchedHeight, chosenFrameRate, parameters);
+        parameters.setPreviewSize(mCaptureFormat.mWidth,
+                                  mCaptureFormat.mHeight);
+        parameters.setPreviewFpsRange(chosenFpsRange[0], chosenFpsRange[1]);
+        parameters.setPreviewFormat(mCaptureFormat.mPixelFormat);
+        try {
+            mCamera.setParameters(parameters);
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "setParameters: " + ex);
+            return false;
+        }
+
+        // Set SurfaceTexture. Android Capture needs a SurfaceTexture even if
+        // it is not going to be used.
+        mGlTextures = new int[1];
+        // Generate one texture pointer and bind it as an external texture.
+        GLES20.glGenTextures(1, mGlTextures, 0);
+        GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mGlTextures[0]);
+        // No mip-mapping with camera source.
+        GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
+                GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+        GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES,
+                GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
+        // Clamp to edge is only option.
+        GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
+                GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
+        GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
+                GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
+
+        mSurfaceTexture = new SurfaceTexture(mGlTextures[0]);
+        mSurfaceTexture.setOnFrameAvailableListener(null);
+        try {
+            mCamera.setPreviewTexture(mSurfaceTexture);
+        } catch (IOException ex) {
+            Log.e(TAG, "allocate: " + ex);
+            return false;
+        }
+
+        allocateBuffers();
+        return true;
+    }
+
+    @Override
+    public int startCapture() {
+        if (mCamera == null) {
+            Log.e(TAG, "startCapture: camera is null");
+            return -1;
+        }
+
+        mPreviewBufferLock.lock();
+        try {
+            if (mIsRunning) {
+                return 0;
+            }
+            mIsRunning = true;
+        } finally {
+            mPreviewBufferLock.unlock();
+        }
+        setPreviewCallback(this);
+        try {
+            mCamera.startPreview();
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "startCapture: Camera.startPreview: " + ex);
+            return -1;
+        }
+        return 0;
+    }
+
+    @Override
+    public int stopCapture() {
+        if (mCamera == null) {
+            Log.e(TAG, "stopCapture: camera is null");
+            return 0;
+        }
+
+        mPreviewBufferLock.lock();
+        try {
+            if (!mIsRunning) {
+                return 0;
+            }
+            mIsRunning = false;
+        } finally {
+            mPreviewBufferLock.unlock();
+        }
+
+        mCamera.stopPreview();
+        setPreviewCallback(null);
+        return 0;
+    }
+
+    @Override
+    public void deallocate() {
+        if (mCamera == null) return;
+
+        stopCapture();
+        try {
+            mCamera.setPreviewTexture(null);
+            if (mGlTextures != null)
+                GLES20.glDeleteTextures(1, mGlTextures, 0);
+            mCaptureFormat = null;
+            mCamera.release();
+            mCamera = null;
+        } catch (IOException ex) {
+            Log.e(TAG, "deallocate: failed to deallocate camera, " + ex);
+            return;
+        }
+    }
+
+    // Local hook to allow derived classes to fill capture format and modify
+    // camera parameters as they see fit.
+    abstract void setCaptureParameters(
+            int width,
+            int height,
+            int frameRate,
+            android.hardware.Camera.Parameters cameraParameters);
+
+    // Local method to be overriden with the particular setPreviewCallback to be
+    // used in the implementations.
+    abstract void setPreviewCallback(android.hardware.Camera.PreviewCallback cb);
+
+    protected int getDeviceOrientation() {
+        int orientation = 0;
+        if (mContext != null) {
+            WindowManager wm = (WindowManager) mContext.getSystemService(
+                    Context.WINDOW_SERVICE);
+            switch(wm.getDefaultDisplay().getRotation()) {
+                case Surface.ROTATION_90:
+                    orientation = 90;
+                    break;
+                case Surface.ROTATION_180:
+                    orientation = 180;
+                    break;
+                case Surface.ROTATION_270:
+                    orientation = 270;
+                    break;
+                case Surface.ROTATION_0:
+                default:
+                    orientation = 0;
+                    break;
+            }
+        }
+        return orientation;
+    }
+}
diff --git a/media/base/android/java/src/org/chromium/media/VideoCaptureFactory.java b/media/base/android/java/src/org/chromium/media/VideoCaptureFactory.java
index 3d262f2..15433dea 100644
--- a/media/base/android/java/src/org/chromium/media/VideoCaptureFactory.java
+++ b/media/base/android/java/src/org/chromium/media/VideoCaptureFactory.java
@@ -108,11 +108,6 @@
     }
 
     @CalledByNative
-    static String getDeviceId(int id) {
-        return Integer.toString(id);
-    }
-
-    @CalledByNative
     static VideoCapture.CaptureFormat[] getDeviceSupportedFormats(int id) {
         return ChromiumCameraInfo.isSpecialCamera(id) ?
                 VideoCaptureTango.getDeviceSupportedFormats(
diff --git a/media/base/android/java/src/org/chromium/media/VideoCaptureTango.java b/media/base/android/java/src/org/chromium/media/VideoCaptureTango.java
index c005b11..67d9ca5 100644
--- a/media/base/android/java/src/org/chromium/media/VideoCaptureTango.java
+++ b/media/base/android/java/src/org/chromium/media/VideoCaptureTango.java
@@ -20,9 +20,9 @@
  * |s_CAM_PARAMS|; all devices |id| are index 0 towards the parent VideoCapture.
  **/
 @SuppressWarnings("deprecation")
-public class VideoCaptureTango extends VideoCapture {
+public class VideoCaptureTango extends VideoCaptureCamera {
 
-    static class CamParams {
+    private static class CamParams {
         final int mId;
         final String mName;
         final int mWidth;
@@ -161,8 +161,8 @@
                     // them explicitly since they're filled to 128 on creation.
                     ByteBuffer.wrap(data, startY, sizeY).get(mFrameBuffer.array(), 0, sizeY);
                 } else if (mTangoCameraId == FOURMP_CAMERA_ID) {
-                    int startY = SF_WIDTH * (SF_LINES_HEADER + SF_LINES_FISHEYE +
-                                    SF_LINES_RESERVED + SF_LINES_DEPTH_PADDED);
+                    int startY = SF_WIDTH * (SF_LINES_HEADER + SF_LINES_FISHEYE
+                                    + SF_LINES_RESERVED + SF_LINES_DEPTH_PADDED);
                     int sizeY = SF_WIDTH * SF_LINES_BIGIMAGE;
 
                     // The spec is completely inaccurate on the location, sizes
diff --git a/media/base/android/media_codec_bridge.cc b/media/base/android/media_codec_bridge.cc
index eb30f28..27d931e3 100644
--- a/media/base/android/media_codec_bridge.cc
+++ b/media/base/android/media_codec_bridge.cc
@@ -24,6 +24,7 @@
 using base::android::AttachCurrentThread;
 using base::android::ConvertJavaStringToUTF8;
 using base::android::ConvertUTF8ToJavaString;
+using base::android::JavaIntArrayToIntVector;
 using base::android::ScopedJavaLocalRef;
 
 namespace media {
@@ -171,6 +172,27 @@
 }
 
 // static
+std::set<int> MediaCodecBridge::GetEncoderColorFormats(
+    const std::string& mime_type) {
+  std::set<int> color_formats;
+  if (!IsAvailable())
+    return color_formats;
+
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime_type);
+  ScopedJavaLocalRef<jintArray> j_color_format_array =
+      Java_MediaCodecBridge_getEncoderColorFormatsForMime(env, j_mime.obj());
+
+  if (j_color_format_array.obj()) {
+    std::vector<int> formats;
+    JavaIntArrayToIntVector(env, j_color_format_array.obj(), &formats);
+    color_formats = std::set<int>(formats.begin(), formats.end());
+  }
+
+  return color_formats;
+}
+
+// static
 bool MediaCodecBridge::CanDecode(const std::string& codec, bool is_secure) {
   if (!IsAvailable())
     return false;
diff --git a/media/base/android/media_codec_bridge.h b/media/base/android/media_codec_bridge.h
index da2348f..f7c9e2b 100644
--- a/media/base/android/media_codec_bridge.h
+++ b/media/base/android/media_codec_bridge.h
@@ -81,6 +81,11 @@
   static std::string GetDefaultCodecName(const std::string& mime_type,
                                          MediaCodecDirection direction);
 
+  // Get a list of encoder supported color formats for |mime_type|.
+  // The mapping of color format name and its value refers to
+  // MediaCodecInfo.CodecCapabilities.
+  static std::set<int> GetEncoderColorFormats(const std::string& mime_type);
+
   virtual ~MediaCodecBridge();
 
   // Resets both input and output, all indices previously returned in calls to
diff --git a/media/base/channel_layout.cc b/media/base/channel_layout.cc
index d0b02a90..ffabfdf 100644
--- a/media/base/channel_layout.cc
+++ b/media/base/channel_layout.cc
@@ -48,7 +48,7 @@
 // channel at that index is not used for that layout. For example, the left side
 // surround sound channel in FFmpeg's 5.1 layout is in the 5th position (because
 // the order is L, R, C, LFE, LS, RS), so
-// kChannelOrderings[CHANNEL_LAYOUT_5POINT1][SIDE_LEFT] = 4;
+// kChannelOrderings[CHANNEL_LAYOUT_5_1][SIDE_LEFT] = 4;
 static const int kChannelOrderings[CHANNEL_LAYOUT_MAX + 1][CHANNELS_MAX + 1] = {
     // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
 
diff --git a/media/base/channel_layout.h b/media/base/channel_layout.h
index 12319ecb..323368a 100644
--- a/media/base/channel_layout.h
+++ b/media/base/channel_layout.h
@@ -126,7 +126,7 @@
 
 // Returns the expected channel position in an interleaved stream.  Values of -1
 // mean the channel at that index is not used for that layout.  Values range
-// from 0 to CHANNELS_MAX - 1.
+// from 0 to ChannelLayoutToChannelCount(layout) - 1.
 MEDIA_EXPORT int ChannelOrder(ChannelLayout layout, Channels channel);
 
 // Returns the number of channels in a given ChannelLayout.
diff --git a/media/base/channel_mixer.cc b/media/base/channel_mixer.cc
index 4c5179b..54b59a8 100644
--- a/media/base/channel_mixer.cc
+++ b/media/base/channel_mixer.cc
@@ -2,117 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// MSVC++ requires this to be set before any other includes to get M_SQRT1_2.
-#define _USE_MATH_DEFINES
-
 #include "media/base/channel_mixer.h"
 
-#include <algorithm>
-#include <cmath>
-
 #include "base/logging.h"
 #include "media/audio/audio_parameters.h"
 #include "media/base/audio_bus.h"
+#include "media/base/channel_mixing_matrix.h"
 #include "media/base/vector_math.h"
 
 namespace media {
 
-// Default scale factor for mixing two channels together.  We use a different
-// value for stereo -> mono and mono -> stereo mixes.
-static const float kEqualPowerScale = static_cast<float>(M_SQRT1_2);
-
-static void ValidateLayout(ChannelLayout layout) {
-  CHECK_NE(layout, CHANNEL_LAYOUT_NONE);
-  CHECK_LE(layout, CHANNEL_LAYOUT_MAX);
-  CHECK_NE(layout, CHANNEL_LAYOUT_UNSUPPORTED);
-  CHECK_NE(layout, CHANNEL_LAYOUT_DISCRETE);
-  CHECK_NE(layout, CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC);
-
-  // Verify there's at least one channel.  Should always be true here by virtue
-  // of not being one of the invalid layouts, but lets double check to be sure.
-  int channel_count = ChannelLayoutToChannelCount(layout);
-  DCHECK_GT(channel_count, 0);
-
-  // If we have more than one channel, verify a symmetric layout for sanity.
-  // The unit test will verify all possible layouts, so this can be a DCHECK.
-  // Symmetry allows simplifying the matrix building code by allowing us to
-  // assume that if one channel of a pair exists, the other will too.
-  if (channel_count > 1) {
-    DCHECK((ChannelOrder(layout, LEFT) >= 0 &&
-            ChannelOrder(layout, RIGHT) >= 0) ||
-           (ChannelOrder(layout, SIDE_LEFT) >= 0 &&
-            ChannelOrder(layout, SIDE_RIGHT) >= 0) ||
-           (ChannelOrder(layout, BACK_LEFT) >= 0 &&
-            ChannelOrder(layout, BACK_RIGHT) >= 0) ||
-           (ChannelOrder(layout, LEFT_OF_CENTER) >= 0 &&
-            ChannelOrder(layout, RIGHT_OF_CENTER) >= 0))
-        << "Non-symmetric channel layout encountered.";
-  } else {
-    DCHECK_EQ(layout, CHANNEL_LAYOUT_MONO);
-  }
-
-  return;
-}
-
-class MatrixBuilder {
- public:
-  MatrixBuilder(ChannelLayout input_layout, int input_channels,
-                ChannelLayout output_layout, int output_channels)
-      : input_layout_(input_layout),
-        input_channels_(input_channels),
-        output_layout_(output_layout),
-        output_channels_(output_channels) {
-    // Special case for 5.0, 5.1 with back channels when upmixed to 7.0, 7.1,
-    // which should map the back LR to side LR.
-    if (input_layout_ == CHANNEL_LAYOUT_5_0_BACK &&
-        output_layout_ == CHANNEL_LAYOUT_7_0) {
-      input_layout_ = CHANNEL_LAYOUT_5_0;
-    } else if (input_layout_ == CHANNEL_LAYOUT_5_1_BACK &&
-               output_layout_ == CHANNEL_LAYOUT_7_1) {
-      input_layout_ = CHANNEL_LAYOUT_5_1;
-    }
-  }
-
-  ~MatrixBuilder() { }
-
-  // Create the transformation matrix of input channels to output channels.
-  // Updates the empty matrix with the transformation, and returns true
-  // if the transformation is just a remapping of channels (no mixing).
-  bool CreateTransformationMatrix(std::vector< std::vector<float> >* matrix);
-
- private:
-  // Result transformation of input channels to output channels
-  std::vector< std::vector<float> >* matrix_;
-
-  // Input and output channel layout provided during construction.
-  ChannelLayout input_layout_;
-  int input_channels_;
-  ChannelLayout output_layout_;
-  int output_channels_;
-
-  // Helper variable for tracking which inputs are currently unaccounted,
-  // should be empty after construction completes.
-  std::vector<Channels> unaccounted_inputs_;
-
-  // Helper methods for managing unaccounted input channels.
-  void AccountFor(Channels ch);
-  bool IsUnaccounted(Channels ch);
-
-  // Helper methods for checking if |ch| exists in either |input_layout_| or
-  // |output_layout_| respectively.
-  bool HasInputChannel(Channels ch);
-  bool HasOutputChannel(Channels ch);
-
-  // Helper methods for updating |matrix_| with the proper value for
-  // mixing |input_ch| into |output_ch|.  MixWithoutAccounting() does not
-  // remove the channel from |unaccounted_inputs_|.
-  void Mix(Channels input_ch, Channels output_ch, float scale);
-  void MixWithoutAccounting(Channels input_ch, Channels output_ch,
-                                          float scale);
-
-  DISALLOW_COPY_AND_ASSIGN(MatrixBuilder);
-};
-
 ChannelMixer::ChannelMixer(ChannelLayout input_layout,
                            ChannelLayout output_layout) {
   Initialize(input_layout,
@@ -132,203 +31,12 @@
 void ChannelMixer::Initialize(
     ChannelLayout input_layout, int input_channels,
     ChannelLayout output_layout, int output_channels) {
-  // Stereo down mix should never be the output layout.
-  CHECK_NE(output_layout, CHANNEL_LAYOUT_STEREO_DOWNMIX);
-
-  // Verify that the layouts are supported
-  if (input_layout != CHANNEL_LAYOUT_DISCRETE)
-    ValidateLayout(input_layout);
-  if (output_layout != CHANNEL_LAYOUT_DISCRETE)
-    ValidateLayout(output_layout);
-
   // Create the transformation matrix
-  MatrixBuilder matrix_builder(input_layout, input_channels,
-                               output_layout, output_channels);
+  ChannelMixingMatrix matrix_builder(input_layout, input_channels,
+                                     output_layout, output_channels);
   remapping_ = matrix_builder.CreateTransformationMatrix(&matrix_);
 }
 
-bool MatrixBuilder::CreateTransformationMatrix(
-    std::vector< std::vector<float> >* matrix) {
-  matrix_ = matrix;
-
-  // Size out the initial matrix.
-  matrix_->reserve(output_channels_);
-  for (int output_ch = 0; output_ch < output_channels_; ++output_ch)
-    matrix_->push_back(std::vector<float>(input_channels_, 0));
-
-  // First check for discrete case.
-  if (input_layout_ == CHANNEL_LAYOUT_DISCRETE ||
-      output_layout_ == CHANNEL_LAYOUT_DISCRETE) {
-    // If the number of input channels is more than output channels, then
-    // copy as many as we can then drop the remaining input channels.
-    // If the number of input channels is less than output channels, then
-    // copy them all, then zero out the remaining output channels.
-    int passthrough_channels = std::min(input_channels_, output_channels_);
-    for (int i = 0; i < passthrough_channels; ++i)
-      (*matrix_)[i][i] = 1;
-
-    return true;
-  }
-
-  // Route matching channels and figure out which ones aren't accounted for.
-  for (Channels ch = LEFT; ch < CHANNELS_MAX + 1;
-       ch = static_cast<Channels>(ch + 1)) {
-    int input_ch_index = ChannelOrder(input_layout_, ch);
-    if (input_ch_index < 0)
-      continue;
-
-    int output_ch_index = ChannelOrder(output_layout_, ch);
-    if (output_ch_index < 0) {
-      unaccounted_inputs_.push_back(ch);
-      continue;
-    }
-
-    DCHECK_LT(static_cast<size_t>(output_ch_index), matrix_->size());
-    DCHECK_LT(static_cast<size_t>(input_ch_index),
-              (*matrix_)[output_ch_index].size());
-    (*matrix_)[output_ch_index][input_ch_index] = 1;
-  }
-
-  // If all input channels are accounted for, there's nothing left to do.
-  if (unaccounted_inputs_.empty()) {
-    // Since all output channels map directly to inputs we can optimize.
-    return true;
-  }
-
-  // Mix front LR into center.
-  if (IsUnaccounted(LEFT)) {
-    // When down mixing to mono from stereo, we need to be careful of full scale
-    // stereo mixes.  Scaling by 1 / sqrt(2) here will likely lead to clipping
-    // so we use 1 / 2 instead.
-    float scale =
-        (output_layout_ == CHANNEL_LAYOUT_MONO && input_channels_ == 2) ?
-        0.5 : kEqualPowerScale;
-    Mix(LEFT, CENTER, scale);
-    Mix(RIGHT, CENTER, scale);
-  }
-
-  // Mix center into front LR.
-  if (IsUnaccounted(CENTER)) {
-    // When up mixing from mono, just do a copy to front LR.
-    float scale =
-        (input_layout_ == CHANNEL_LAYOUT_MONO) ? 1 : kEqualPowerScale;
-    MixWithoutAccounting(CENTER, LEFT, scale);
-    Mix(CENTER, RIGHT, scale);
-  }
-
-  // Mix back LR into: side LR || back center || front LR || front center.
-  if (IsUnaccounted(BACK_LEFT)) {
-    if (HasOutputChannel(SIDE_LEFT)) {
-      // If we have side LR, mix back LR into side LR, but instead if the input
-      // doesn't have side LR (but output does) copy back LR to side LR.
-      float scale = HasInputChannel(SIDE_LEFT) ? kEqualPowerScale : 1;
-      Mix(BACK_LEFT, SIDE_LEFT, scale);
-      Mix(BACK_RIGHT, SIDE_RIGHT, scale);
-    } else if (HasOutputChannel(BACK_CENTER)) {
-      // Mix back LR into back center.
-      Mix(BACK_LEFT, BACK_CENTER, kEqualPowerScale);
-      Mix(BACK_RIGHT, BACK_CENTER, kEqualPowerScale);
-    } else if (output_layout_ > CHANNEL_LAYOUT_MONO) {
-      // Mix back LR into front LR.
-      Mix(BACK_LEFT, LEFT, kEqualPowerScale);
-      Mix(BACK_RIGHT, RIGHT, kEqualPowerScale);
-    } else {
-      // Mix back LR into front center.
-      Mix(BACK_LEFT, CENTER, kEqualPowerScale);
-      Mix(BACK_RIGHT, CENTER, kEqualPowerScale);
-    }
-  }
-
-  // Mix side LR into: back LR || back center || front LR || front center.
-  if (IsUnaccounted(SIDE_LEFT)) {
-    if (HasOutputChannel(BACK_LEFT)) {
-      // If we have back LR, mix side LR into back LR, but instead if the input
-      // doesn't have back LR (but output does) copy side LR to back LR.
-      float scale = HasInputChannel(BACK_LEFT) ? kEqualPowerScale : 1;
-      Mix(SIDE_LEFT, BACK_LEFT, scale);
-      Mix(SIDE_RIGHT, BACK_RIGHT, scale);
-    } else if (HasOutputChannel(BACK_CENTER)) {
-      // Mix side LR into back center.
-      Mix(SIDE_LEFT, BACK_CENTER, kEqualPowerScale);
-      Mix(SIDE_RIGHT, BACK_CENTER, kEqualPowerScale);
-    } else if (output_layout_ > CHANNEL_LAYOUT_MONO) {
-      // Mix side LR into front LR.
-      Mix(SIDE_LEFT, LEFT, kEqualPowerScale);
-      Mix(SIDE_RIGHT, RIGHT, kEqualPowerScale);
-    } else {
-      // Mix side LR into front center.
-      Mix(SIDE_LEFT, CENTER, kEqualPowerScale);
-      Mix(SIDE_RIGHT, CENTER, kEqualPowerScale);
-    }
-  }
-
-  // Mix back center into: back LR || side LR || front LR || front center.
-  if (IsUnaccounted(BACK_CENTER)) {
-    if (HasOutputChannel(BACK_LEFT)) {
-      // Mix back center into back LR.
-      MixWithoutAccounting(BACK_CENTER, BACK_LEFT, kEqualPowerScale);
-      Mix(BACK_CENTER, BACK_RIGHT, kEqualPowerScale);
-    } else if (HasOutputChannel(SIDE_LEFT)) {
-      // Mix back center into side LR.
-      MixWithoutAccounting(BACK_CENTER, SIDE_LEFT, kEqualPowerScale);
-      Mix(BACK_CENTER, SIDE_RIGHT, kEqualPowerScale);
-    } else if (output_layout_ > CHANNEL_LAYOUT_MONO) {
-      // Mix back center into front LR.
-      // TODO(dalecurtis): Not sure about these values?
-      MixWithoutAccounting(BACK_CENTER, LEFT, kEqualPowerScale);
-      Mix(BACK_CENTER, RIGHT, kEqualPowerScale);
-    } else {
-      // Mix back center into front center.
-      // TODO(dalecurtis): Not sure about these values?
-      Mix(BACK_CENTER, CENTER, kEqualPowerScale);
-    }
-  }
-
-  // Mix LR of center into: front center || front LR.
-  if (IsUnaccounted(LEFT_OF_CENTER)) {
-    if (HasOutputChannel(LEFT)) {
-      // Mix LR of center into front LR.
-      Mix(LEFT_OF_CENTER, LEFT, kEqualPowerScale);
-      Mix(RIGHT_OF_CENTER, RIGHT, kEqualPowerScale);
-    } else {
-      // Mix LR of center into front center.
-      Mix(LEFT_OF_CENTER, CENTER, kEqualPowerScale);
-      Mix(RIGHT_OF_CENTER, CENTER, kEqualPowerScale);
-    }
-  }
-
-  // Mix LFE into: front LR || front center.
-  if (IsUnaccounted(LFE)) {
-    if (!HasOutputChannel(CENTER)) {
-      // Mix LFE into front LR.
-      MixWithoutAccounting(LFE, LEFT, kEqualPowerScale);
-      Mix(LFE, RIGHT, kEqualPowerScale);
-    } else {
-      // Mix LFE into front center.
-      Mix(LFE, CENTER, kEqualPowerScale);
-    }
-  }
-
-  // All channels should now be accounted for.
-  DCHECK(unaccounted_inputs_.empty());
-
-  // See if the output |matrix_| is simply a remapping matrix.  If each input
-  // channel maps to a single output channel we can simply remap.  Doing this
-  // programmatically is less fragile than logic checks on channel mappings.
-  for (int output_ch = 0; output_ch < output_channels_; ++output_ch) {
-    int input_mappings = 0;
-    for (int input_ch = 0; input_ch < input_channels_; ++input_ch) {
-      // We can only remap if each row contains a single scale of 1.  I.e., each
-      // output channel is mapped from a single unscaled input channel.
-      if ((*matrix_)[output_ch][input_ch] != 1 || ++input_mappings > 1)
-        return false;
-    }
-  }
-
-  // If we've gotten here, |matrix_| is simply a remapping.
-  return true;
-}
-
 ChannelMixer::~ChannelMixer() {}
 
 void ChannelMixer::Transform(const AudioBus* input, AudioBus* output) {
@@ -368,40 +76,4 @@
   }
 }
 
-void MatrixBuilder::AccountFor(Channels ch) {
-  unaccounted_inputs_.erase(std::find(
-      unaccounted_inputs_.begin(), unaccounted_inputs_.end(), ch));
-}
-
-bool MatrixBuilder::IsUnaccounted(Channels ch) {
-  return std::find(unaccounted_inputs_.begin(), unaccounted_inputs_.end(),
-                   ch) != unaccounted_inputs_.end();
-}
-
-bool MatrixBuilder::HasInputChannel(Channels ch) {
-  return ChannelOrder(input_layout_, ch) >= 0;
-}
-
-bool MatrixBuilder::HasOutputChannel(Channels ch) {
-  return ChannelOrder(output_layout_, ch) >= 0;
-}
-
-void MatrixBuilder::Mix(Channels input_ch, Channels output_ch, float scale) {
-  MixWithoutAccounting(input_ch, output_ch, scale);
-  AccountFor(input_ch);
-}
-
-void MatrixBuilder::MixWithoutAccounting(Channels input_ch, Channels output_ch,
-                                         float scale) {
-  int input_ch_index = ChannelOrder(input_layout_, input_ch);
-  int output_ch_index = ChannelOrder(output_layout_, output_ch);
-
-  DCHECK(IsUnaccounted(input_ch));
-  DCHECK_GE(input_ch_index, 0);
-  DCHECK_GE(output_ch_index, 0);
-
-  DCHECK_EQ((*matrix_)[output_ch_index][input_ch_index], 0);
-  (*matrix_)[output_ch_index][input_ch_index] = scale;
-}
-
 }  // namespace media
diff --git a/media/base/channel_mixer.h b/media/base/channel_mixer.h
index ea3cbf81..ef11a2ed 100644
--- a/media/base/channel_mixer.h
+++ b/media/base/channel_mixer.h
@@ -7,7 +7,7 @@
 
 #include <vector>
 
-#include "base/basictypes.h"
+#include "base/macros.h"
 #include "media/base/channel_layout.h"
 #include "media/base/media_export.h"
 
diff --git a/media/base/channel_mixer_unittest.cc b/media/base/channel_mixer_unittest.cc
index ac228e66..07d64eb 100644
--- a/media/base/channel_mixer_unittest.cc
+++ b/media/base/channel_mixer_unittest.cc
@@ -24,14 +24,16 @@
        input_layout <= CHANNEL_LAYOUT_MAX;
        input_layout = static_cast<ChannelLayout>(input_layout + 1)) {
     for (ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
-         output_layout < CHANNEL_LAYOUT_STEREO_DOWNMIX;
+         output_layout <= CHANNEL_LAYOUT_MAX;
          output_layout = static_cast<ChannelLayout>(output_layout + 1)) {
       // DISCRETE can't be tested here based on the current approach.
       // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC is not mixable.
+      // Stereo down mix should never be the output layout.
       if (input_layout == CHANNEL_LAYOUT_DISCRETE ||
           input_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
           output_layout == CHANNEL_LAYOUT_DISCRETE ||
-          output_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) {
+          output_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
+          output_layout == CHANNEL_LAYOUT_STEREO_DOWNMIX) {
         continue;
       }
 
@@ -141,7 +143,7 @@
   if (input_layout != CHANNEL_LAYOUT_DISCRETE) {
     for (int ch = 0; ch < output_bus->channels(); ++ch) {
       for (int frame = 0; frame < output_bus->frames(); ++frame) {
-        ASSERT_FLOAT_EQ(output_bus->channel(ch)[frame], expected_value);
+        ASSERT_FLOAT_EQ(expected_value, output_bus->channel(ch)[frame]);
       }
     }
   } else {
@@ -151,7 +153,7 @@
     for (int ch = 0; ch < output_bus->channels(); ++ch) {
       expected_value = (ch < input_channels) ? channel_values[ch] : 0;
       for (int frame = 0; frame < output_bus->frames(); ++frame) {
-        ASSERT_FLOAT_EQ(output_bus->channel(ch)[frame], expected_value);
+        ASSERT_FLOAT_EQ(expected_value, output_bus->channel(ch)[frame]);
       }
     }
   }
diff --git a/media/base/channel_mixing_matrix.cc b/media/base/channel_mixing_matrix.cc
new file mode 100644
index 0000000..eee0efd0
--- /dev/null
+++ b/media/base/channel_mixing_matrix.cc
@@ -0,0 +1,304 @@
+// Copyright (c) 2012 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.
+
+// MSVC++ requires this to be set before any other includes to get M_SQRT1_2.
+#define _USE_MATH_DEFINES
+
+#include "media/base/channel_mixing_matrix.h"
+
+#include <algorithm>
+#include <cmath>
+
+#include "base/logging.h"
+
+namespace media {
+
+// Default scale factor for mixing two channels together.  We use a different
+// value for stereo -> mono and mono -> stereo mixes.
+static const float kEqualPowerScale = static_cast<float>(M_SQRT1_2);
+
+static void ValidateLayout(ChannelLayout layout) {
+  CHECK_NE(layout, CHANNEL_LAYOUT_NONE);
+  CHECK_LE(layout, CHANNEL_LAYOUT_MAX);
+  CHECK_NE(layout, CHANNEL_LAYOUT_UNSUPPORTED);
+  CHECK_NE(layout, CHANNEL_LAYOUT_DISCRETE);
+  CHECK_NE(layout, CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC);
+
+  // Verify there's at least one channel.  Should always be true here by virtue
+  // of not being one of the invalid layouts, but lets double check to be sure.
+  int channel_count = ChannelLayoutToChannelCount(layout);
+  DCHECK_GT(channel_count, 0);
+
+  // If we have more than one channel, verify a symmetric layout for sanity.
+  // The unit test will verify all possible layouts, so this can be a DCHECK.
+  // Symmetry allows simplifying the matrix building code by allowing us to
+  // assume that if one channel of a pair exists, the other will too.
+  if (channel_count > 1) {
+    // Assert that LEFT exists if and only if RIGHT exists, and so on.
+    DCHECK_EQ(ChannelOrder(layout, LEFT) >= 0,
+              ChannelOrder(layout, RIGHT) >= 0);
+    DCHECK_EQ(ChannelOrder(layout, SIDE_LEFT) >= 0,
+              ChannelOrder(layout, SIDE_RIGHT) >= 0);
+    DCHECK_EQ(ChannelOrder(layout, BACK_LEFT) >= 0,
+              ChannelOrder(layout, BACK_RIGHT) >= 0);
+    DCHECK_EQ(ChannelOrder(layout, LEFT_OF_CENTER) >= 0,
+              ChannelOrder(layout, RIGHT_OF_CENTER) >= 0);
+  } else {
+    DCHECK_EQ(layout, CHANNEL_LAYOUT_MONO);
+  }
+}
+
+ChannelMixingMatrix::ChannelMixingMatrix(ChannelLayout input_layout,
+                                         int input_channels,
+                                         ChannelLayout output_layout,
+                                         int output_channels)
+    : input_layout_(input_layout),
+      input_channels_(input_channels),
+      output_layout_(output_layout),
+      output_channels_(output_channels) {
+  // Stereo down mix should never be the output layout.
+  CHECK_NE(output_layout, CHANNEL_LAYOUT_STEREO_DOWNMIX);
+
+  // Verify that the layouts are supported
+  if (input_layout != CHANNEL_LAYOUT_DISCRETE)
+    ValidateLayout(input_layout);
+  if (output_layout != CHANNEL_LAYOUT_DISCRETE)
+    ValidateLayout(output_layout);
+
+  // Special case for 5.0, 5.1 with back channels when upmixed to 7.0, 7.1,
+  // which should map the back LR to side LR.
+  if (input_layout_ == CHANNEL_LAYOUT_5_0_BACK &&
+      output_layout_ == CHANNEL_LAYOUT_7_0) {
+    input_layout_ = CHANNEL_LAYOUT_5_0;
+  } else if (input_layout_ == CHANNEL_LAYOUT_5_1_BACK &&
+             output_layout_ == CHANNEL_LAYOUT_7_1) {
+    input_layout_ = CHANNEL_LAYOUT_5_1;
+  }
+}
+
+ChannelMixingMatrix::~ChannelMixingMatrix() {
+}
+
+bool ChannelMixingMatrix::CreateTransformationMatrix(
+    std::vector<std::vector<float>>* matrix) {
+  matrix_ = matrix;
+
+  // Size out the initial matrix.
+  matrix_->reserve(output_channels_);
+  for (int output_ch = 0; output_ch < output_channels_; ++output_ch)
+    matrix_->push_back(std::vector<float>(input_channels_, 0));
+
+  // First check for discrete case.
+  if (input_layout_ == CHANNEL_LAYOUT_DISCRETE ||
+      output_layout_ == CHANNEL_LAYOUT_DISCRETE) {
+    // If the number of input channels is more than output channels, then
+    // copy as many as we can then drop the remaining input channels.
+    // If the number of input channels is less than output channels, then
+    // copy them all, then zero out the remaining output channels.
+    int passthrough_channels = std::min(input_channels_, output_channels_);
+    for (int i = 0; i < passthrough_channels; ++i)
+      (*matrix_)[i][i] = 1;
+
+    return true;
+  }
+
+  // Route matching channels and figure out which ones aren't accounted for.
+  for (Channels ch = LEFT; ch < CHANNELS_MAX + 1;
+       ch = static_cast<Channels>(ch + 1)) {
+    int input_ch_index = ChannelOrder(input_layout_, ch);
+    if (input_ch_index < 0)
+      continue;
+
+    int output_ch_index = ChannelOrder(output_layout_, ch);
+    if (output_ch_index < 0) {
+      unaccounted_inputs_.push_back(ch);
+      continue;
+    }
+
+    DCHECK_LT(static_cast<size_t>(output_ch_index), matrix_->size());
+    DCHECK_LT(static_cast<size_t>(input_ch_index),
+              (*matrix_)[output_ch_index].size());
+    (*matrix_)[output_ch_index][input_ch_index] = 1;
+  }
+
+  // If all input channels are accounted for, there's nothing left to do.
+  if (unaccounted_inputs_.empty()) {
+    // Since all output channels map directly to inputs we can optimize.
+    return true;
+  }
+
+  // Mix front LR into center.
+  if (IsUnaccounted(LEFT)) {
+    // When down mixing to mono from stereo, we need to be careful of full scale
+    // stereo mixes.  Scaling by 1 / sqrt(2) here will likely lead to clipping
+    // so we use 1 / 2 instead.
+    float scale =
+        (output_layout_ == CHANNEL_LAYOUT_MONO && input_channels_ == 2) ?
+        0.5 : kEqualPowerScale;
+    Mix(LEFT, CENTER, scale);
+    Mix(RIGHT, CENTER, scale);
+  }
+
+  // Mix center into front LR.
+  if (IsUnaccounted(CENTER)) {
+    // When up mixing from mono, just do a copy to front LR.
+    float scale =
+        (input_layout_ == CHANNEL_LAYOUT_MONO) ? 1 : kEqualPowerScale;
+    MixWithoutAccounting(CENTER, LEFT, scale);
+    Mix(CENTER, RIGHT, scale);
+  }
+
+  // Mix back LR into: side LR || back center || front LR || front center.
+  if (IsUnaccounted(BACK_LEFT)) {
+    if (HasOutputChannel(SIDE_LEFT)) {
+      // If the input has side LR, mix back LR into side LR, but instead if the
+      // input doesn't have side LR (but output does) copy back LR to side LR.
+      float scale = HasInputChannel(SIDE_LEFT) ? kEqualPowerScale : 1;
+      Mix(BACK_LEFT, SIDE_LEFT, scale);
+      Mix(BACK_RIGHT, SIDE_RIGHT, scale);
+    } else if (HasOutputChannel(BACK_CENTER)) {
+      // Mix back LR into back center.
+      Mix(BACK_LEFT, BACK_CENTER, kEqualPowerScale);
+      Mix(BACK_RIGHT, BACK_CENTER, kEqualPowerScale);
+    } else if (output_layout_ > CHANNEL_LAYOUT_MONO) {
+      // Mix back LR into front LR.
+      Mix(BACK_LEFT, LEFT, kEqualPowerScale);
+      Mix(BACK_RIGHT, RIGHT, kEqualPowerScale);
+    } else {
+      // Mix back LR into front center.
+      Mix(BACK_LEFT, CENTER, kEqualPowerScale);
+      Mix(BACK_RIGHT, CENTER, kEqualPowerScale);
+    }
+  }
+
+  // Mix side LR into: back LR || back center || front LR || front center.
+  if (IsUnaccounted(SIDE_LEFT)) {
+    if (HasOutputChannel(BACK_LEFT)) {
+      // If the input has back LR, mix side LR into back LR, but instead if the
+      // input doesn't have back LR (but output does) copy side LR to back LR.
+      float scale = HasInputChannel(BACK_LEFT) ? kEqualPowerScale : 1;
+      Mix(SIDE_LEFT, BACK_LEFT, scale);
+      Mix(SIDE_RIGHT, BACK_RIGHT, scale);
+    } else if (HasOutputChannel(BACK_CENTER)) {
+      // Mix side LR into back center.
+      Mix(SIDE_LEFT, BACK_CENTER, kEqualPowerScale);
+      Mix(SIDE_RIGHT, BACK_CENTER, kEqualPowerScale);
+    } else if (output_layout_ > CHANNEL_LAYOUT_MONO) {
+      // Mix side LR into front LR.
+      Mix(SIDE_LEFT, LEFT, kEqualPowerScale);
+      Mix(SIDE_RIGHT, RIGHT, kEqualPowerScale);
+    } else {
+      // Mix side LR into front center.
+      Mix(SIDE_LEFT, CENTER, kEqualPowerScale);
+      Mix(SIDE_RIGHT, CENTER, kEqualPowerScale);
+    }
+  }
+
+  // Mix back center into: back LR || side LR || front LR || front center.
+  if (IsUnaccounted(BACK_CENTER)) {
+    if (HasOutputChannel(BACK_LEFT)) {
+      // Mix back center into back LR.
+      MixWithoutAccounting(BACK_CENTER, BACK_LEFT, kEqualPowerScale);
+      Mix(BACK_CENTER, BACK_RIGHT, kEqualPowerScale);
+    } else if (HasOutputChannel(SIDE_LEFT)) {
+      // Mix back center into side LR.
+      MixWithoutAccounting(BACK_CENTER, SIDE_LEFT, kEqualPowerScale);
+      Mix(BACK_CENTER, SIDE_RIGHT, kEqualPowerScale);
+    } else if (output_layout_ > CHANNEL_LAYOUT_MONO) {
+      // Mix back center into front LR.
+      // TODO(dalecurtis): Not sure about these values?
+      MixWithoutAccounting(BACK_CENTER, LEFT, kEqualPowerScale);
+      Mix(BACK_CENTER, RIGHT, kEqualPowerScale);
+    } else {
+      // Mix back center into front center.
+      // TODO(dalecurtis): Not sure about these values?
+      Mix(BACK_CENTER, CENTER, kEqualPowerScale);
+    }
+  }
+
+  // Mix LR of center into: front LR || front center.
+  if (IsUnaccounted(LEFT_OF_CENTER)) {
+    if (HasOutputChannel(LEFT)) {
+      // Mix LR of center into front LR.
+      Mix(LEFT_OF_CENTER, LEFT, kEqualPowerScale);
+      Mix(RIGHT_OF_CENTER, RIGHT, kEqualPowerScale);
+    } else {
+      // Mix LR of center into front center.
+      Mix(LEFT_OF_CENTER, CENTER, kEqualPowerScale);
+      Mix(RIGHT_OF_CENTER, CENTER, kEqualPowerScale);
+    }
+  }
+
+  // Mix LFE into: front center || front LR.
+  if (IsUnaccounted(LFE)) {
+    if (!HasOutputChannel(CENTER)) {
+      // Mix LFE into front LR.
+      MixWithoutAccounting(LFE, LEFT, kEqualPowerScale);
+      Mix(LFE, RIGHT, kEqualPowerScale);
+    } else {
+      // Mix LFE into front center.
+      Mix(LFE, CENTER, kEqualPowerScale);
+    }
+  }
+
+  // All channels should now be accounted for.
+  DCHECK(unaccounted_inputs_.empty());
+
+  // See if the output |matrix_| is simply a remapping matrix.  If each input
+  // channel maps to a single output channel we can simply remap.  Doing this
+  // programmatically is less fragile than logic checks on channel mappings.
+  for (int output_ch = 0; output_ch < output_channels_; ++output_ch) {
+    int input_mappings = 0;
+    for (int input_ch = 0; input_ch < input_channels_; ++input_ch) {
+      // We can only remap if each row contains a single scale of 1.  I.e., each
+      // output channel is mapped from a single unscaled input channel.
+      if ((*matrix_)[output_ch][input_ch] != 1 || ++input_mappings > 1)
+        return false;
+    }
+  }
+
+  // If we've gotten here, |matrix_| is simply a remapping.
+  return true;
+}
+
+void ChannelMixingMatrix::AccountFor(Channels ch) {
+  unaccounted_inputs_.erase(std::find(
+      unaccounted_inputs_.begin(), unaccounted_inputs_.end(), ch));
+}
+
+bool ChannelMixingMatrix::IsUnaccounted(Channels ch) const {
+  return std::find(unaccounted_inputs_.begin(), unaccounted_inputs_.end(),
+                   ch) != unaccounted_inputs_.end();
+}
+
+bool ChannelMixingMatrix::HasInputChannel(Channels ch) const {
+  return ChannelOrder(input_layout_, ch) >= 0;
+}
+
+bool ChannelMixingMatrix::HasOutputChannel(Channels ch) const {
+  return ChannelOrder(output_layout_, ch) >= 0;
+}
+
+void ChannelMixingMatrix::Mix(Channels input_ch,
+                              Channels output_ch,
+                              float scale) {
+  MixWithoutAccounting(input_ch, output_ch, scale);
+  AccountFor(input_ch);
+}
+
+void ChannelMixingMatrix::MixWithoutAccounting(Channels input_ch,
+                                               Channels output_ch,
+                                               float scale) {
+  int input_ch_index = ChannelOrder(input_layout_, input_ch);
+  int output_ch_index = ChannelOrder(output_layout_, output_ch);
+
+  DCHECK(IsUnaccounted(input_ch));
+  DCHECK_GE(input_ch_index, 0);
+  DCHECK_GE(output_ch_index, 0);
+
+  DCHECK_EQ((*matrix_)[output_ch_index][input_ch_index], 0);
+  (*matrix_)[output_ch_index][input_ch_index] = scale;
+}
+
+}  // namespace media
diff --git a/media/base/channel_mixing_matrix.h b/media/base/channel_mixing_matrix.h
new file mode 100644
index 0000000..64fcdb9
--- /dev/null
+++ b/media/base/channel_mixing_matrix.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2012 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 MEDIA_BASE_CHANNEL_MIXING_MATRIX_H_
+#define MEDIA_BASE_CHANNEL_MIXING_MATRIX_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "media/base/channel_layout.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+class MEDIA_EXPORT ChannelMixingMatrix {
+ public:
+  ChannelMixingMatrix(ChannelLayout input_layout,
+                      int input_channels,
+                      ChannelLayout output_layout,
+                      int output_channels);
+
+  ~ChannelMixingMatrix();
+
+  // Create the transformation matrix of input channels to output channels.
+  // Updates the empty matrix with the transformation, and returns true
+  // if the transformation is just a remapping of channels (no mixing).
+  bool CreateTransformationMatrix(std::vector<std::vector<float>>* matrix);
+
+ private:
+  // Result transformation of input channels to output channels
+  std::vector<std::vector<float>>* matrix_;
+
+  // Input and output channel layout provided during construction.
+  ChannelLayout input_layout_;
+  int input_channels_;
+  ChannelLayout output_layout_;
+  int output_channels_;
+
+  // Helper variable for tracking which inputs are currently unaccounted,
+  // should be empty after construction completes.
+  std::vector<Channels> unaccounted_inputs_;
+
+  // Helper methods for managing unaccounted input channels.
+  void AccountFor(Channels ch);
+  bool IsUnaccounted(Channels ch) const;
+
+  // Helper methods for checking if |ch| exists in either |input_layout_| or
+  // |output_layout_| respectively.
+  bool HasInputChannel(Channels ch) const;
+  bool HasOutputChannel(Channels ch) const;
+
+  // Helper methods for updating |matrix_| with the proper value for
+  // mixing |input_ch| into |output_ch|.  MixWithoutAccounting() does not
+  // remove the channel from |unaccounted_inputs_|.
+  void Mix(Channels input_ch, Channels output_ch, float scale);
+  void MixWithoutAccounting(Channels input_ch, Channels output_ch, float scale);
+
+  DISALLOW_COPY_AND_ASSIGN(ChannelMixingMatrix);
+};
+
+}  // namespace media
+
+#endif  // MEDIA_BASE_CHANNEL_MIXING_MATRIX_H_
diff --git a/media/base/channel_mixing_matrix_unittest.cc b/media/base/channel_mixing_matrix_unittest.cc
new file mode 100644
index 0000000..dcba54f9
--- /dev/null
+++ b/media/base/channel_mixing_matrix_unittest.cc
@@ -0,0 +1,157 @@
+// Copyright (c) 2012 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.
+
+// MSVC++ requires this to be set before any other includes to get M_SQRT1_2.
+#define _USE_MATH_DEFINES
+
+#include "media/base/channel_mixing_matrix.h"
+
+#include <cmath>
+
+#include "base/strings/stringprintf.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+// Test all possible layout conversions can be constructed and mixed.
+TEST(ChannelMixingMatrixTest, ConstructAllPossibleLayouts) {
+  for (ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
+       input_layout <= CHANNEL_LAYOUT_MAX;
+       input_layout = static_cast<ChannelLayout>(input_layout + 1)) {
+    for (ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
+         output_layout <= CHANNEL_LAYOUT_MAX;
+         output_layout = static_cast<ChannelLayout>(output_layout + 1)) {
+      // DISCRETE can't be tested here based on the current approach.
+      // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC is not mixable.
+      // Stereo down mix should never be the output layout.
+      if (input_layout == CHANNEL_LAYOUT_DISCRETE ||
+          input_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
+          output_layout == CHANNEL_LAYOUT_DISCRETE ||
+          output_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
+          output_layout == CHANNEL_LAYOUT_STEREO_DOWNMIX) {
+        continue;
+      }
+
+      SCOPED_TRACE(base::StringPrintf(
+          "Input Layout: %d, Output Layout: %d", input_layout, output_layout));
+      ChannelMixingMatrix matrix_builder(
+          input_layout,
+          ChannelLayoutToChannelCount(input_layout),
+          output_layout,
+          ChannelLayoutToChannelCount(output_layout));
+      std::vector<std::vector<float>> matrix;
+      matrix_builder.CreateTransformationMatrix(&matrix);
+    }
+  }
+}
+
+// Verify channels are mixed and scaled correctly.
+TEST(ChannelMixingMatrixTest, StereoToMono) {
+  ChannelLayout input_layout = CHANNEL_LAYOUT_STEREO;
+  ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
+  ChannelMixingMatrix matrix_builder(
+      input_layout,
+      ChannelLayoutToChannelCount(input_layout),
+      output_layout,
+      ChannelLayoutToChannelCount(output_layout));
+  std::vector<std::vector<float>> matrix;
+  bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
+
+  //                      Input: stereo
+  //                      LEFT  RIGHT
+  // Output: mono CENTER  0.5   0.5
+  //
+  EXPECT_FALSE(remapping);
+  EXPECT_EQ(1u, matrix.size());
+  EXPECT_EQ(2u, matrix[0].size());
+  EXPECT_EQ(0.5f, matrix[0][0]);
+  EXPECT_EQ(0.5f, matrix[0][1]);
+}
+
+TEST(ChannelMixingMatrixTest, MonoToStereo) {
+  ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
+  ChannelLayout output_layout = CHANNEL_LAYOUT_STEREO;
+  ChannelMixingMatrix matrix_builder(
+      input_layout,
+      ChannelLayoutToChannelCount(input_layout),
+      output_layout,
+      ChannelLayoutToChannelCount(output_layout));
+  std::vector<std::vector<float>> matrix;
+  bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
+
+  //                       Input: mono
+  //                       CENTER
+  // Output: stereo LEFT   1
+  //                RIGHT  1
+  //
+  EXPECT_TRUE(remapping);
+  EXPECT_EQ(2u, matrix.size());
+  EXPECT_EQ(1u, matrix[0].size());
+  EXPECT_EQ(1.0f, matrix[0][0]);
+  EXPECT_EQ(1u, matrix[1].size());
+  EXPECT_EQ(1.0f, matrix[1][0]);
+}
+
+TEST(ChannelMixingMatrixTest, FiveOneToMono) {
+  ChannelLayout input_layout = CHANNEL_LAYOUT_5_1;
+  ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
+  ChannelMixingMatrix matrix_builder(
+      input_layout,
+      ChannelLayoutToChannelCount(input_layout),
+      output_layout,
+      ChannelLayoutToChannelCount(output_layout));
+  std::vector<std::vector<float>> matrix;
+  bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
+
+  // Note: 1/sqrt(2) is shown as 0.707.
+  //
+  //                      Input: 5.1
+  //                      LEFT   RIGHT  CENTER  LFE    SIDE_LEFT  SIDE_RIGHT
+  // Output: mono CENTER  0.707  0.707  1       0.707  0.707      0.707
+  //
+  EXPECT_FALSE(remapping);
+  EXPECT_EQ(1u, matrix.size());
+  EXPECT_EQ(6u, matrix[0].size());
+  EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][0]);
+  EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][1]);
+  // The center channel will be mixed at scale 1.
+  EXPECT_EQ(1.0f, matrix[0][2]);
+  EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][3]);
+  EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][4]);
+  EXPECT_FLOAT_EQ(static_cast<float>(M_SQRT1_2), matrix[0][5]);
+}
+
+TEST(ChannelMixingMatrixTest, DiscreteToDiscrete) {
+  const struct {
+    int input_channels;
+    int output_channels;
+  } test_case[] = {
+    {2, 2}, {2, 5}, {5, 2},
+  };
+
+  for (size_t n = 0; n < arraysize(test_case); n++) {
+    int input_channels = test_case[n].input_channels;
+    int output_channels = test_case[n].output_channels;
+    ChannelMixingMatrix matrix_builder(CHANNEL_LAYOUT_DISCRETE,
+                                       input_channels,
+                                       CHANNEL_LAYOUT_DISCRETE,
+                                       output_channels);
+    std::vector<std::vector<float>> matrix;
+    bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
+    EXPECT_TRUE(remapping);
+    EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
+    for (int i = 0; i < output_channels; i++) {
+      EXPECT_EQ(static_cast<size_t>(input_channels), matrix[i].size());
+      for (int j = 0; j < input_channels; j++) {
+        if (i == j) {
+          EXPECT_EQ(1.0f, matrix[i][j]);
+        } else {
+          EXPECT_EQ(0.0f, matrix[i][j]);
+        }
+      }
+    }
+  }
+}
+
+}  // namespace media
diff --git a/content/public/common/eme_constants.h b/media/base/eme_constants.h
similarity index 89%
rename from content/public/common/eme_constants.h
rename to media/base/eme_constants.h
index aaf183e..27ebfff 100644
--- a/content/public/common/eme_constants.h
+++ b/media/base/eme_constants.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_PUBLIC_COMMON_EME_CONSTANTS_H_
-#define CONTENT_PUBLIC_COMMON_EME_CONSTANTS_H_
+#ifndef MEDIA_BASE_EME_CONSTANTS_H_
+#define MEDIA_BASE_EME_CONSTANTS_H_
 
 #include <stdint.h>
 
-namespace content {
+namespace media {
 
 // Defines bitmask values that specify registered initialization data types used
 // in Encrypted Media Extensions (EME).
@@ -48,6 +48,6 @@
 typedef uint32_t SupportedInitDataTypes;
 typedef uint32_t SupportedCodecs;
 
-}  // namespace content
+}  // namespace media
 
-#endif  // CONTENT_PUBLIC_COMMON_EME_CONSTANTS_H_
+#endif  // MEDIA_BASE_EME_CONSTANTS_H_
diff --git a/content/public/renderer/key_system_info.cc b/media/base/key_system_info.cc
similarity index 81%
rename from content/public/renderer/key_system_info.cc
rename to media/base/key_system_info.cc
index 9578ebf..f436912 100644
--- a/content/public/renderer/key_system_info.cc
+++ b/media/base/key_system_info.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/public/renderer/key_system_info.h"
+#include "media/base/key_system_info.h"
 
-namespace content {
+namespace media {
 
 KeySystemInfo::KeySystemInfo(const std::string& key_system)
     : key_system(key_system),
@@ -16,4 +16,4 @@
 KeySystemInfo::~KeySystemInfo() {
 }
 
-}  // namespace content
+}  // namespace media
diff --git a/content/public/renderer/key_system_info.h b/media/base/key_system_info.h
similarity index 80%
rename from content/public/renderer/key_system_info.h
rename to media/base/key_system_info.h
index 9ec317d4..e259c00d 100644
--- a/content/public/renderer/key_system_info.h
+++ b/media/base/key_system_info.h
@@ -2,16 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_PUBLIC_RENDERER_KEY_SYSTEM_INFO_H_
-#define CONTENT_PUBLIC_RENDERER_KEY_SYSTEM_INFO_H_
+#ifndef MEDIA_BASE_KEY_SYSTEM_INFO_H_
+#define MEDIA_BASE_KEY_SYSTEM_INFO_H_
 
-#include <map>
 #include <string>
 
-#include "base/basictypes.h"
-#include "base/containers/hash_tables.h"
-#include "content/common/content_export.h"
-#include "content/public/common/eme_constants.h"
+#include "media/base/eme_constants.h"
+#include "media/base/media_export.h"
 
 // Definitions:
 // * Key system
@@ -28,11 +25,11 @@
 //    be an abstract key system.
 //    As an example, "com.example" is the parent of "com.example.foo".
 
-namespace content {
+namespace media {
 
 // Contains information about an EME key system as well as how to instantiate
 // the corresponding CDM.
-struct CONTENT_EXPORT KeySystemInfo {
+struct MEDIA_EXPORT KeySystemInfo {
   explicit KeySystemInfo(const std::string& key_system);
   ~KeySystemInfo();
 
@@ -56,6 +53,6 @@
 #endif
 };
 
-}  // namespace content
+}  // namespace media
 
-#endif  // CONTENT_PUBLIC_RENDERER_KEY_SYSTEM_INFO_H_
+#endif  // MEDIA_BASE_KEY_SYSTEM_INFO_H_
diff --git a/media/base/sinc_resampler.cc b/media/base/sinc_resampler.cc
index 900648e..280cd68 100644
--- a/media/base/sinc_resampler.cc
+++ b/media/base/sinc_resampler.cc
@@ -178,23 +178,22 @@
 
     for (int i = 0; i < kKernelSize; ++i) {
       const int idx = i + offset_idx * kKernelSize;
-      const float pre_sinc = M_PI * (i - kKernelSize / 2 - subsample_offset);
+      const float pre_sinc =
+          static_cast<float>(M_PI * (i - kKernelSize / 2 - subsample_offset));
       kernel_pre_sinc_storage_[idx] = pre_sinc;
 
       // Compute Blackman window, matching the offset of the sinc().
       const float x = (i - subsample_offset) / kKernelSize;
-      const float window =
-          kA0 - kA1 * cos(2.0 * M_PI * x) + kA2 * cos(4.0 * M_PI * x);
+      const float window = static_cast<float>(kA0 - kA1 * cos(2.0 * M_PI * x) +
+          kA2 * cos(4.0 * M_PI * x));
       kernel_window_storage_[idx] = window;
 
       // Compute the sinc with offset, then window the sinc() function and store
       // at the correct offset.
-      if (pre_sinc == 0) {
-        kernel_storage_[idx] = sinc_scale_factor * window;
-      } else {
-        kernel_storage_[idx] =
-            window * sin(sinc_scale_factor * pre_sinc) / pre_sinc;
-      }
+      kernel_storage_[idx] = static_cast<float>(window *
+          ((pre_sinc == 0) ?
+              sinc_scale_factor :
+              (sin(sinc_scale_factor * pre_sinc) / pre_sinc)));
     }
   }
 }
@@ -216,12 +215,10 @@
       const float window = kernel_window_storage_[idx];
       const float pre_sinc = kernel_pre_sinc_storage_[idx];
 
-      if (pre_sinc == 0) {
-        kernel_storage_[idx] = sinc_scale_factor * window;
-      } else {
-        kernel_storage_[idx] =
-            window * sin(sinc_scale_factor * pre_sinc) / pre_sinc;
-      }
+      kernel_storage_[idx] = static_cast<float>(window *
+          ((pre_sinc == 0) ?
+              sinc_scale_factor :
+              (sin(sinc_scale_factor * pre_sinc) / pre_sinc)));
     }
   }
 }
@@ -242,7 +239,7 @@
   while (remaining_frames) {
     // Note: The loop construct here can severely impact performance on ARM
     // or when built with clang.  See https://codereview.chromium.org/18566009/
-    int source_idx = virtual_source_idx_;
+    int source_idx = static_cast<int>(virtual_source_idx_);
     while (source_idx < block_size_) {
       // |virtual_source_idx_| lies in between two kernel offsets so figure out
       // what they are.
@@ -250,7 +247,7 @@
 
       const double virtual_offset_idx =
           subsample_remainder * kKernelOffsetCount;
-      const int offset_idx = virtual_offset_idx;
+      const int offset_idx = static_cast<int>(virtual_offset_idx);
 
       // We'll compute "convolutions" for the two kernels which straddle
       // |virtual_source_idx_|.
@@ -273,7 +270,7 @@
 
       // Advance the virtual index.
       virtual_source_idx_ += current_io_ratio;
-      source_idx = virtual_source_idx_;
+      source_idx = static_cast<int>(virtual_source_idx_);
 
       if (!--remaining_frames)
         return;
@@ -297,7 +294,7 @@
 }
 
 int SincResampler::ChunkSize() const {
-  return block_size_ / io_sample_rate_ratio_;
+  return static_cast<int>(block_size_ / io_sample_rate_ratio_);
 }
 
 void SincResampler::Flush() {
@@ -323,8 +320,8 @@
   }
 
   // Linearly interpolate the two "convolutions".
-  return (1.0 - kernel_interpolation_factor) * sum1
-      + kernel_interpolation_factor * sum2;
+  return static_cast<float>((1.0 - kernel_interpolation_factor) * sum1 +
+      kernel_interpolation_factor * sum2);
 }
 
 #if defined(ARCH_CPU_X86_FAMILY)
@@ -352,8 +349,10 @@
   }
 
   // Linearly interpolate the two "convolutions".
-  m_sums1 = _mm_mul_ps(m_sums1, _mm_set_ps1(1.0 - kernel_interpolation_factor));
-  m_sums2 = _mm_mul_ps(m_sums2, _mm_set_ps1(kernel_interpolation_factor));
+  m_sums1 = _mm_mul_ps(m_sums1, _mm_set_ps1(
+      static_cast<float>(1.0 - kernel_interpolation_factor)));
+  m_sums2 = _mm_mul_ps(m_sums2, _mm_set_ps1(
+      static_cast<float>(kernel_interpolation_factor)));
   m_sums1 = _mm_add_ps(m_sums1, m_sums2);
 
   // Sum components together.
diff --git a/media/base/video_decoder_config.h b/media/base/video_decoder_config.h
index 0954e05f..5d01d08 100644
--- a/media/base/video_decoder_config.h
+++ b/media/base/video_decoder_config.h
@@ -37,7 +37,8 @@
 };
 
 // Video stream profile.  This *must* match PP_VideoDecoder_Profile.
-// (enforced in webkit/plugins/ppapi/ppb_video_decoder_impl.cc)
+// (enforced in webkit/plugins/ppapi/ppb_video_decoder_impl.cc) and
+// gpu::VideoCodecProfile.
 enum VideoCodecProfile {
   // Keep the values in this enum unique, as they imply format (h.264 vs. VP8,
   // for example), and keep the values for a particular format grouped
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 5f0d728..abea883 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -14,6 +14,7 @@
 #include "gpu/command_buffer/common/mailbox_holder.h"
 #include "media/base/limits.h"
 #include "media/base/video_util.h"
+#include "ui/gfx/point.h"
 
 #if !defined(MEDIA_FOR_CAST_IOS)
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -21,30 +22,84 @@
 
 namespace media {
 
+static bool IsPowerOfTwo(size_t x) {
+  return x != 0 && (x & (x - 1)) == 0;
+}
+
 static inline size_t RoundUp(size_t value, size_t alignment) {
-  // Check that |alignment| is a power of 2.
-  DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1)));
+  DCHECK(IsPowerOfTwo(alignment));
   return ((value + (alignment - 1)) & ~(alignment - 1));
 }
 
+static inline size_t RoundDown(size_t value, size_t alignment) {
+  DCHECK(IsPowerOfTwo(alignment));
+  return value & ~(alignment - 1);
+}
+
+// Returns the pixel size per element for given |plane| and |format|. E.g. 2x2
+// for the U-plane in I420.
+static gfx::Size SampleSize(VideoFrame::Format format, size_t plane) {
+  DCHECK(VideoFrame::IsValidPlane(plane, format));
+
+  switch (plane) {
+    case VideoFrame::kYPlane:
+    case VideoFrame::kAPlane:
+      return gfx::Size(1, 1);
+
+    case VideoFrame::kUPlane:  // and VideoFrame::kUVPlane:
+    case VideoFrame::kVPlane:
+      switch (format) {
+        case VideoFrame::YV24:
+          return gfx::Size(1, 1);
+
+        case VideoFrame::YV16:
+          return gfx::Size(2, 1);
+
+        case VideoFrame::YV12:
+        case VideoFrame::YV12J:
+        case VideoFrame::I420:
+        case VideoFrame::YV12A:
+        case VideoFrame::NV12:
+          return gfx::Size(2, 2);
+
+        case VideoFrame::UNKNOWN:
+#if defined(VIDEO_HOLE)
+        case VideoFrame::HOLE:
+#endif  // defined(VIDEO_HOLE)
+        case VideoFrame::NATIVE_TEXTURE:
+          break;
+      }
+  }
+  NOTREACHED();
+  return gfx::Size();
+}
+
+// Return the alignment for the whole frame, calculated as the max of the
+// alignment for each individual plane.
+static gfx::Size CommonAlignment(VideoFrame::Format format) {
+  int max_sample_width = 0;
+  int max_sample_height = 0;
+  for (size_t plane = 0; plane < VideoFrame::NumPlanes(format); ++plane) {
+    const gfx::Size sample_size = SampleSize(format, plane);
+    max_sample_width = std::max(max_sample_width, sample_size.width());
+    max_sample_height = std::max(max_sample_height, sample_size.height());
+  }
+  return gfx::Size(max_sample_width, max_sample_height);
+}
+
+// Returns the number of bytes per element for given |plane| and |format|. E.g.
+// 2 for the UV plane in NV12.
+static int BytesPerElement(VideoFrame::Format format, size_t plane) {
+  DCHECK(VideoFrame::IsValidPlane(plane, format));
+  return (format == VideoFrame::NV12 && plane == VideoFrame::kUVPlane) ? 2 : 1;
+}
+
 // Rounds up |coded_size| if necessary for |format|.
 static gfx::Size AdjustCodedSize(VideoFrame::Format format,
                                  const gfx::Size& coded_size) {
-  gfx::Size new_coded_size(coded_size);
-  switch (format) {
-    case VideoFrame::YV12:
-    case VideoFrame::YV12A:
-    case VideoFrame::I420:
-    case VideoFrame::YV12J:
-      new_coded_size.set_height(RoundUp(new_coded_size.height(), 2));
-    // Fallthrough.
-    case VideoFrame::YV16:
-      new_coded_size.set_width(RoundUp(new_coded_size.width(), 2));
-      break;
-    default:
-      break;
-  }
-  return new_coded_size;
+  const gfx::Size alignment = CommonAlignment(format);
+  return gfx::Size(RoundUp(coded_size.width(), alignment.width()),
+                   RoundUp(coded_size.height(), alignment.height()));
 }
 
 // static
@@ -64,7 +119,7 @@
   // Since we're creating a new YUV frame (and allocating memory for it
   // ourselves), we can pad the requested |coded_size| if necessary if the
   // request does not line up on sample boundaries.
-  gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
+  const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
   DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
 
   scoped_refptr<VideoFrame> frame(
@@ -131,35 +186,35 @@
     case VideoFrame::UNKNOWN:
       return (coded_size.IsEmpty() && visible_rect.IsEmpty() &&
               natural_size.IsEmpty());
+
+    // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are
+    // allowed to skip the below check.
+    case VideoFrame::NATIVE_TEXTURE:
+#if defined(VIDEO_HOLE)
+    case VideoFrame::HOLE:
+#endif  // defined(VIDEO_HOLE)
+      return true;
+
     case VideoFrame::YV24:
-      break;
     case VideoFrame::YV12:
     case VideoFrame::YV12J:
     case VideoFrame::I420:
     case VideoFrame::YV12A:
     case VideoFrame::NV12:
-      // Subsampled YUV formats have width/height requirements.
-      if (static_cast<size_t>(coded_size.height()) <
-          RoundUp(visible_rect.bottom(), 2))
-        return false;
-    // Fallthrough.
     case VideoFrame::YV16:
-      if (static_cast<size_t>(coded_size.width()) <
-          RoundUp(visible_rect.right(), 2))
-        return false;
-      break;
-    case VideoFrame::NATIVE_TEXTURE:
-#if defined(VIDEO_HOLE)
-    case VideoFrame::HOLE:
-#endif  // defined(VIDEO_HOLE)
-      // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are
-      // allowed to skip the below check and be empty.
-      return true;
+      // Check that software-allocated buffer formats are aligned correctly and
+      // not empty.
+      const gfx::Size alignment = CommonAlignment(format);
+      return RoundUp(visible_rect.right(), alignment.width()) <=
+                 static_cast<size_t>(coded_size.width()) &&
+             RoundUp(visible_rect.bottom(), alignment.height()) <=
+                 static_cast<size_t>(coded_size.height()) &&
+             !coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
+             !natural_size.IsEmpty();
   }
 
-  // Check that software-allocated buffer formats are not empty.
-  return (!coded_size.IsEmpty() && !visible_rect.IsEmpty() &&
-          !natural_size.IsEmpty());
+  NOTREACHED();
+  return false;
 }
 
 // static
@@ -203,7 +258,7 @@
     base::SharedMemoryHandle handle,
     base::TimeDelta timestamp,
     const base::Closure& no_longer_needed_cb) {
-  gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
+  const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
 
   if (!IsValidConfig(format, new_coded_size, visible_rect, natural_size))
     return NULL;
@@ -291,7 +346,7 @@
   DCHECK(cv_pixel_buffer);
   DCHECK(CFGetTypeID(cv_pixel_buffer) == CVPixelBufferGetTypeID());
 
-  OSType cv_format = CVPixelBufferGetPixelFormatType(cv_pixel_buffer);
+  const OSType cv_format = CVPixelBufferGetPixelFormatType(cv_pixel_buffer);
   Format format;
   // There are very few compatible CV pixel formats, so just check each.
   if (cv_format == kCVPixelFormatType_420YpCbCr8Planar) {
@@ -307,9 +362,9 @@
     return NULL;
   }
 
-  gfx::Size coded_size(CVImageBufferGetEncodedSize(cv_pixel_buffer));
-  gfx::Rect visible_rect(CVImageBufferGetCleanRect(cv_pixel_buffer));
-  gfx::Size natural_size(CVImageBufferGetDisplaySize(cv_pixel_buffer));
+  const gfx::Size coded_size(CVImageBufferGetEncodedSize(cv_pixel_buffer));
+  const gfx::Rect visible_rect(CVImageBufferGetCleanRect(cv_pixel_buffer));
+  const gfx::Size natural_size(CVImageBufferGetDisplaySize(cv_pixel_buffer));
 
   if (!IsValidConfig(format, coded_size, visible_rect, natural_size))
     return NULL;
@@ -342,7 +397,7 @@
     uint8* v_data,
     base::TimeDelta timestamp,
     const base::Closure& no_longer_needed_cb) {
-  gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
+  const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size);
   CHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size));
 
   scoped_refptr<VideoFrame> frame(
@@ -497,78 +552,19 @@
 gfx::Size VideoFrame::PlaneSize(Format format,
                                 size_t plane,
                                 const gfx::Size& coded_size) {
+  DCHECK(IsValidPlane(plane, format));
+
   // Align to multiple-of-two size overall. This ensures that non-subsampled
   // planes can be addressed by pixel with the same scaling as the subsampled
   // planes.
   const int width = RoundUp(coded_size.width(), 2);
   const int height = RoundUp(coded_size.height(), 2);
-  switch (format) {
-    case VideoFrame::YV24:
-      switch (plane) {
-        case VideoFrame::kYPlane:
-        case VideoFrame::kUPlane:
-        case VideoFrame::kVPlane:
-          return gfx::Size(width, height);
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV12:
-    case VideoFrame::YV12J:
-    case VideoFrame::I420:
-      switch (plane) {
-        case VideoFrame::kYPlane:
-          return gfx::Size(width, height);
-        case VideoFrame::kUPlane:
-        case VideoFrame::kVPlane:
-          return gfx::Size(width / 2, height / 2);
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV12A:
-      switch (plane) {
-        case VideoFrame::kYPlane:
-        case VideoFrame::kAPlane:
-          return gfx::Size(width, height);
-        case VideoFrame::kUPlane:
-        case VideoFrame::kVPlane:
-          return gfx::Size(width / 2, height / 2);
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV16:
-      switch (plane) {
-        case VideoFrame::kYPlane:
-          return gfx::Size(width, height);
-        case VideoFrame::kUPlane:
-        case VideoFrame::kVPlane:
-          return gfx::Size(width / 2, height);
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::NV12:
-      switch (plane) {
-        case VideoFrame::kYPlane:
-          return gfx::Size(width, height);
-        case VideoFrame::kUVPlane:
-          return gfx::Size(width, height / 2);
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::UNKNOWN:
-    case VideoFrame::NATIVE_TEXTURE:
-#if defined(VIDEO_HOLE)
-    case VideoFrame::HOLE:
-#endif  // defined(VIDEO_HOLE)
-      break;
-  }
-  NOTREACHED() << "Unsupported video frame format/plane: "
-               << format << "/" << plane;
-  return gfx::Size();
+
+  const gfx::Size subsample = SampleSize(format, plane);
+  DCHECK(width % subsample.width() == 0);
+  DCHECK(height % subsample.height() == 0);
+  return gfx::Size(BytesPerElement(format, plane) * width / subsample.width(),
+                   height / subsample.height());
 }
 
 size_t VideoFrame::PlaneAllocationSize(Format format,
@@ -580,63 +576,11 @@
 
 // static
 int VideoFrame::PlaneHorizontalBitsPerPixel(Format format, size_t plane) {
-  switch (format) {
-    case VideoFrame::YV24:
-      switch (plane) {
-        case kYPlane:
-        case kUPlane:
-        case kVPlane:
-          return 8;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV12:
-    case VideoFrame::YV16:
-    case VideoFrame::I420:
-    case VideoFrame::YV12J:
-      switch (plane) {
-        case kYPlane:
-          return 8;
-        case kUPlane:
-        case kVPlane:
-          return 2;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV12A:
-      switch (plane) {
-        case kYPlane:
-        case kAPlane:
-          return 8;
-        case kUPlane:
-        case kVPlane:
-          return 2;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::NV12:
-      switch (plane) {
-        case kYPlane:
-          return 8;
-        case kUVPlane:
-          return 4;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::UNKNOWN:
-#if defined(VIDEO_HOLE)
-    case VideoFrame::HOLE:
-#endif  // defined(VIDEO_HOLE)
-    case VideoFrame::NATIVE_TEXTURE:
-      break;
-  }
-  NOTREACHED() << "Unsupported video frame format/plane: "
-               << format << "/" << plane;
-  return 0;
+  DCHECK(IsValidPlane(plane, format));
+  const int bits_per_element = 8 * BytesPerElement(format, plane);
+  const int pixels_per_element = SampleSize(format, plane).GetArea();
+  DCHECK(bits_per_element % pixels_per_element == 0);
+  return bits_per_element / pixels_per_element;
 }
 
 // Release data allocated by AllocateYUV().
@@ -646,60 +590,40 @@
 }
 
 void VideoFrame::AllocateYUV() {
-  DCHECK(format_ == VideoFrame::YV12 || format_ == VideoFrame::YV16 ||
-         format_ == VideoFrame::YV12A || format_ == VideoFrame::I420 ||
-         format_ == VideoFrame::YV12J || format_ == VideoFrame::YV24);
-  // Align Y rows at least at 16 byte boundaries.  The stride for both
-  // YV12 and YV16 is 1/2 of the stride of Y.  For YV12, every row of bytes for
-  // U and V applies to two rows of Y (one byte of UV for 4 bytes of Y), so in
-  // the case of YV12 the strides are identical for the same width surface, but
-  // the number of bytes allocated for YV12 is 1/2 the amount for U & V as
-  // YV16. We also round the height of the surface allocated to be an even
-  // number to avoid any potential of faulting by code that attempts to access
-  // the Y values of the final row, but assumes that the last row of U & V
-  // applies to a full two rows of Y. YV12A is the same as YV12, but with an
-  // additional alpha plane that has the same size and alignment as the Y plane.
-  size_t y_stride = RoundUp(row_bytes(VideoFrame::kYPlane),
-                            kFrameSizeAlignment);
-  size_t uv_stride = RoundUp(row_bytes(VideoFrame::kUPlane),
-                             kFrameSizeAlignment);
+  DCHECK(format_ == YV12 || format_ == YV16 || format_ == YV12A ||
+         format_ == I420 || format_ == YV12J || format_ == YV24);
+  COMPILE_ASSERT(0 == kYPlane, y_plane_data_must_be_index_0);
 
-  // The *2 here is because some formats (e.g. h264) allow interlaced coding,
-  // and then the size needs to be a multiple of two macroblocks (vertically).
-  // See libavcodec/utils.c:avcodec_align_dimensions2().
-  size_t y_height = RoundUp(coded_size_.height(), kFrameSizeAlignment * 2);
-  size_t uv_height =
-      (format_ == VideoFrame::YV12 || format_ == VideoFrame::YV12A ||
-       format_ == VideoFrame::I420)
-          ? y_height / 2
-          : y_height;
-  size_t y_bytes = y_height * y_stride;
-  size_t uv_bytes = uv_height * uv_stride;
-  size_t a_bytes = format_ == VideoFrame::YV12A ? y_bytes : 0;
+  size_t data_size = 0;
+  size_t offset[kMaxPlanes];
+  for (size_t plane = 0; plane < VideoFrame::NumPlanes(format_); ++plane) {
+    // The *2 in alignment for height is because some formats (e.g. h264) allow
+    // interlaced coding, and then the size needs to be a multiple of two
+    // macroblocks (vertically). See
+    // libavcodec/utils.c:avcodec_align_dimensions2().
+    const size_t height = RoundUp(rows(plane), kFrameSizeAlignment * 2);
+    strides_[plane] = RoundUp(row_bytes(plane), kFrameSizeAlignment);
+    offset[plane] = data_size;
+    data_size += height * strides_[plane];
+  }
 
   // The extra line of UV being allocated is because h264 chroma MC
   // overreads by one line in some cases, see libavcodec/utils.c:
   // avcodec_align_dimensions2() and libavcodec/x86/h264_chromamc.asm:
   // put_h264_chroma_mc4_ssse3().
-  const size_t data_size =
-      y_bytes + (uv_bytes * 2 + uv_stride) + a_bytes + kFrameSizePadding;
-  uint8* data = reinterpret_cast<uint8*>(
-      base::AlignedAlloc(data_size, kFrameAddressAlignment));
+  DCHECK(IsValidPlane(kUPlane, format_));
+  data_size += strides_[kUPlane] + kFrameSizePadding;
+
   // FFmpeg expects the initialize allocation to be zero-initialized.  Failure
   // to do so can lead to unitialized value usage.  See http://crbug.com/390941
+  uint8* data = reinterpret_cast<uint8*>(
+      base::AlignedAlloc(data_size, kFrameAddressAlignment));
   memset(data, 0, data_size);
+
+  for (size_t plane = 0; plane < VideoFrame::NumPlanes(format_); ++plane)
+    data_[plane] = data + offset[plane];
+
   no_longer_needed_cb_ = base::Bind(&ReleaseData, data);
-  COMPILE_ASSERT(0 == VideoFrame::kYPlane, y_plane_data_must_be_index_0);
-  data_[VideoFrame::kYPlane] = data;
-  data_[VideoFrame::kUPlane] = data + y_bytes;
-  data_[VideoFrame::kVPlane] = data + y_bytes + uv_bytes;
-  strides_[VideoFrame::kYPlane] = y_stride;
-  strides_[VideoFrame::kUPlane] = uv_stride;
-  strides_[VideoFrame::kVPlane] = uv_stride;
-  if (format_ == YV12A) {
-    data_[VideoFrame::kAPlane] = data + y_bytes + (2 * uv_bytes);
-    strides_[VideoFrame::kAPlane] = y_stride;
-  }
 }
 
 VideoFrame::VideoFrame(VideoFrame::Format format,
@@ -750,65 +674,11 @@
 }
 
 // static
-size_t VideoFrame::RowBytes(size_t plane, VideoFrame::Format format,
+size_t VideoFrame::RowBytes(size_t plane,
+                            VideoFrame::Format format,
                             int width) {
   DCHECK(IsValidPlane(plane, format));
-  switch (format) {
-    case VideoFrame::YV24:
-      switch (plane) {
-        case kYPlane:
-        case kUPlane:
-        case kVPlane:
-          return width;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV12:
-    case VideoFrame::YV16:
-    case VideoFrame::I420:
-    case VideoFrame::YV12J:
-      switch (plane) {
-        case kYPlane:
-          return width;
-        case kUPlane:
-        case kVPlane:
-          return RoundUp(width, 2) / 2;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV12A:
-      switch (plane) {
-        case kYPlane:
-        case kAPlane:
-          return width;
-        case kUPlane:
-        case kVPlane:
-          return RoundUp(width, 2) / 2;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::NV12:
-      switch (plane) {
-        case kYPlane:
-        case kUVPlane:
-          return width;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::UNKNOWN:
-#if defined(VIDEO_HOLE)
-    case VideoFrame::HOLE:
-#endif  // defined(VIDEO_HOLE)
-    case VideoFrame::NATIVE_TEXTURE:
-      break;
-  }
-  NOTREACHED() << "Unsupported video frame format/plane: " << format << "/"
-               << plane;
-  return 0;
+  return BytesPerElement(format, plane) * Columns(plane, format, width);
 }
 
 int VideoFrame::row_bytes(size_t plane) const {
@@ -818,74 +688,53 @@
 // static
 size_t VideoFrame::Rows(size_t plane, VideoFrame::Format format, int height) {
   DCHECK(IsValidPlane(plane, format));
-  switch (format) {
-    case VideoFrame::YV24:
-    case VideoFrame::YV16:
-      switch (plane) {
-        case kYPlane:
-        case kUPlane:
-        case kVPlane:
-          return height;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV12:
-    case VideoFrame::YV12J:
-    case VideoFrame::I420:
-      switch (plane) {
-        case kYPlane:
-          return height;
-        case kUPlane:
-        case kVPlane:
-          return RoundUp(height, 2) / 2;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::YV12A:
-      switch (plane) {
-        case kYPlane:
-        case kAPlane:
-          return height;
-        case kUPlane:
-        case kVPlane:
-          return RoundUp(height, 2) / 2;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::NV12:
-      switch (plane) {
-        case kYPlane:
-          return height;
-        case kUVPlane:
-          return RoundUp(height, 2) / 2;
-        default:
-          break;
-      }
-      break;
-    case VideoFrame::UNKNOWN:
-#if defined(VIDEO_HOLE)
-    case VideoFrame::HOLE:
-#endif  // defined(VIDEO_HOLE)
-    case VideoFrame::NATIVE_TEXTURE:
-      break;
-  }
-  NOTREACHED() << "Unsupported video frame format/plane: " << format << "/"
-               << plane;
-  return 0;
+  const int sample_height = SampleSize(format, plane).height();
+  return RoundUp(height, sample_height) / sample_height;
+}
+
+// static
+size_t VideoFrame::Columns(size_t plane, Format format, int width) {
+  DCHECK(IsValidPlane(plane, format));
+  const int sample_width = SampleSize(format, plane).width();
+  return RoundUp(width, sample_width) / sample_width;
 }
 
 int VideoFrame::rows(size_t plane) const {
   return Rows(plane, format_, coded_size_.height());
 }
 
-uint8* VideoFrame::data(size_t plane) const {
+const uint8* VideoFrame::data(size_t plane) const {
   DCHECK(IsValidPlane(plane, format_));
   return data_[plane];
 }
 
+uint8* VideoFrame::data(size_t plane) {
+  DCHECK(IsValidPlane(plane, format_));
+  return data_[plane];
+}
+
+const uint8* VideoFrame::visible_data(size_t plane) const {
+  DCHECK(IsValidPlane(plane, format_));
+
+  // Calculate an offset that is properly aligned for all planes.
+  const gfx::Size alignment = CommonAlignment(format_);
+  const gfx::Point offset(RoundDown(visible_rect_.x(), alignment.width()),
+                          RoundDown(visible_rect_.y(), alignment.height()));
+
+  const gfx::Size subsample = SampleSize(format_, plane);
+  DCHECK(offset.x() % subsample.width() == 0);
+  DCHECK(offset.y() % subsample.height() == 0);
+  return data(plane) +
+         stride(plane) * (offset.y() / subsample.height()) +  // Row offset.
+         BytesPerElement(format_, plane) *                    // Column offset.
+             (offset.x() / subsample.width());
+}
+
+uint8* VideoFrame::visible_data(size_t plane) {
+  return const_cast<uint8*>(
+      static_cast<const VideoFrame*>(this)->visible_data(plane));
+}
+
 const gpu::MailboxHolder* VideoFrame::mailbox_holder() const {
   DCHECK_EQ(format_, NATIVE_TEXTURE);
   return mailbox_holder_.get();
@@ -919,9 +768,7 @@
 #endif
 
 void VideoFrame::HashFrameForTesting(base::MD5Context* context) {
-  for (int plane = 0; plane < kMaxPlanes; ++plane) {
-    if (!IsValidPlane(plane, format_))
-      break;
+  for (size_t plane = 0; plane < NumPlanes(format_); ++plane) {
     for (int row = 0; row < rows(plane); ++row) {
       base::MD5Update(context, base::StringPiece(
           reinterpret_cast<char*>(data(plane) + stride(plane) * row),
diff --git a/media/base/video_frame.h b/media/base/video_frame.h
index 928550c..ca2a2e2 100644
--- a/media/base/video_frame.h
+++ b/media/base/video_frame.h
@@ -78,6 +78,10 @@
       const gfx::Size& natural_size,
       base::TimeDelta timestamp);
 
+  // Returns true if |plane| is a valid plane number for the given format. This
+  // can be used to DCHECK() plane parameters.
+  static bool IsValidPlane(size_t plane, VideoFrame::Format format);
+
   // Call prior to CreateFrame to ensure validity of frame configuration. Called
   // automatically by VideoDecoderConfig::IsValidConfig().
   // TODO(scherkus): VideoDecoderConfig shouldn't call this method
@@ -226,7 +230,8 @@
   // given coded size and format.
   static size_t AllocationSize(Format format, const gfx::Size& coded_size);
 
-  // Returns the plane size for a plane of the given coded size and format.
+  // Returns the plane size (in bytes) for a plane of the given coded size and
+  // format.
   static gfx::Size PlaneSize(Format format,
                              size_t plane,
                              const gfx::Size& coded_size);
@@ -248,6 +253,10 @@
   // The height may be aligned to format requirements.
   static size_t Rows(size_t plane, Format format, int height);
 
+  // Returns the number of columns for the given plane, format, and width.
+  // The width may be aligned to format requirements.
+  static size_t Columns(size_t plane, Format format, int width);
+
   Format format() const { return format_; }
 
   const gfx::Size& coded_size() const { return coded_size_; }
@@ -265,7 +274,15 @@
 
   // Returns pointer to the buffer for a given plane. The memory is owned by
   // VideoFrame object and must not be freed by the caller.
-  uint8* data(size_t plane) const;
+  const uint8* data(size_t plane) const;
+  uint8* data(size_t plane);
+
+  // Returns pointer to the data in the visible region of the frame. I.e. the
+  // returned pointer is offsetted into the plane buffer specified by
+  // visible_rect().origin(). Memory is owned by VideoFrame object and must not
+  // be freed by the caller.
+  const uint8* visible_data(size_t plane) const;
+  uint8* visible_data(size_t plane);
 
   // Returns the mailbox holder of the native texture wrapped by this frame.
   // Only valid to call if this is a NATIVE_TEXTURE frame. Before using the
@@ -319,10 +336,6 @@
  private:
   friend class base::RefCountedThreadSafe<VideoFrame>;
 
-  // Returns true if |plane| is a valid plane number for the given format. This
-  // can be used to DCHECK() plane parameters.
-  static bool IsValidPlane(size_t plane, VideoFrame::Format format);
-
   // Clients must use the static CreateFrame() method to create a new frame.
   VideoFrame(Format format,
              const gfx::Size& coded_size,
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index a4e829d..b1744bd 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -137,6 +137,7 @@
     blink::WebLocalFrame* frame,
     blink::WebMediaPlayerClient* client,
     base::WeakPtr<WebMediaPlayerDelegate> delegate,
+    scoped_ptr<Renderer> renderer,
     const WebMediaPlayerParams& params)
     : frame_(frame),
       network_state_(WebMediaPlayer::NetworkStateEmpty),
@@ -168,7 +169,8 @@
       text_track_index_(0),
       encrypted_media_support_(
           params.CreateEncryptedMediaPlayerSupport(client)),
-      audio_hardware_config_(params.audio_hardware_config()) {
+      audio_hardware_config_(params.audio_hardware_config()),
+      renderer_(renderer.Pass()) {
   DCHECK(encrypted_media_support_);
 
   // Threaded compositing isn't enabled universally yet.
@@ -178,6 +180,11 @@
   media_log_->AddEvent(
       media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED));
 
+  // TODO(xhwang): When we use an external Renderer, many methods won't work,
+  // e.g. GetCurrentFrameFromCompositor(). Fix this in a future CL.
+  if (renderer_)
+    return;
+
   // |gpu_factories_| requires that its entry points be called on its
   // |GetTaskRunner()|.  Since |pipeline_| will own decoders created from the
   // factories, require that their message loops are identical.
@@ -907,9 +914,13 @@
 
   // ... and we're ready to go!
   seeking_ = true;
+
+  if (!renderer_)
+    renderer_ = CreateRenderer();
+
   pipeline_.Start(
       demuxer_.get(),
-      CreateRenderer(),
+      renderer_.Pass(),
       BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded),
       BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError),
       BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false),
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index a237a40..bec5747e 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -16,9 +16,8 @@
 #include "base/threading/thread.h"
 #include "media/base/audio_renderer_sink.h"
 #include "media/base/media_export.h"
-// TODO(xhwang): Remove when we remove prefixed EME implementation.
-#include "media/base/media_keys.h"
 #include "media/base/pipeline.h"
+#include "media/base/renderer.h"
 #include "media/base/text_track.h"
 #include "media/blink/buffered_data_source.h"
 #include "media/blink/buffered_data_source_host_impl.h"
@@ -44,6 +43,7 @@
 }
 
 namespace media {
+
 class AudioHardwareConfig;
 class ChunkDemuxer;
 class EncryptedMediaPlayerSupport;
@@ -63,10 +63,14 @@
       public base::SupportsWeakPtr<WebMediaPlayerImpl> {
  public:
   // Constructs a WebMediaPlayer implementation using Chromium's media stack.
-  // |delegate| may be null.
+  // |delegate| may be null. |renderer| may also be null, in which case an
+  // internal renderer will be created.
+  // TODO(xhwang): Drop the internal renderer path and always pass in a renderer
+  // here.
   WebMediaPlayerImpl(blink::WebLocalFrame* frame,
                      blink::WebMediaPlayerClient* client,
                      base::WeakPtr<WebMediaPlayerDelegate> delegate,
+                     scoped_ptr<Renderer> renderer,
                      const WebMediaPlayerParams& params);
   virtual ~WebMediaPlayerImpl();
 
@@ -305,6 +309,8 @@
 
   const AudioHardwareConfig& audio_hardware_config_;
 
+  scoped_ptr<Renderer> renderer_;
+
   DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl);
 };
 
diff --git a/media/cast/cast_defines.h b/media/cast/cast_defines.h
index 76e2527..661c095 100644
--- a/media/cast/cast_defines.h
+++ b/media/cast/cast_defines.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <cmath>
 #include <map>
 #include <set>
 
@@ -178,9 +179,10 @@
 
 inline base::TimeTicks ConvertNtpToTimeTicks(uint32 ntp_seconds,
                                              uint32 ntp_fractions) {
-  int64 ntp_time_us =
-      static_cast<int64>(ntp_seconds) * base::Time::kMicrosecondsPerSecond +
-      static_cast<int64>(ntp_fractions) / kMagicFractionalUnit;
+  // We need to ceil() here because the calculation of |fractions| in
+  // ConvertTimeToFractions() effectively does a floor().
+  int64 ntp_time_us = ntp_seconds * base::Time::kMicrosecondsPerSecond +
+      static_cast<int64>(std::ceil(ntp_fractions / kMagicFractionalUnit));
 
   base::TimeDelta elapsed_since_unix_epoch = base::TimeDelta::FromMicroseconds(
       ntp_time_us -
diff --git a/media/cast/common/clock_drift_smoother.cc b/media/cast/common/clock_drift_smoother.cc
index aff9a396..df3ffdb 100644
--- a/media/cast/common/clock_drift_smoother.cc
+++ b/media/cast/common/clock_drift_smoother.cc
@@ -27,7 +27,7 @@
                                base::TimeDelta measured_offset) {
   DCHECK(!now.is_null());
   last_update_time_ = now;
-  estimate_us_ = measured_offset.InMicroseconds();
+  estimate_us_ = static_cast<double>(measured_offset.InMicroseconds());
 }
 
 void ClockDriftSmoother::Update(base::TimeTicks now,
@@ -39,7 +39,8 @@
     // |now| is not monotonically non-decreasing.
     NOTREACHED();
   } else {
-    const double elapsed_us = (now - last_update_time_).InMicroseconds();
+    const double elapsed_us =
+        static_cast<double>((now - last_update_time_).InMicroseconds());
     last_update_time_ = now;
     const double weight =
         elapsed_us / (elapsed_us + time_constant_.InMicroseconds());
diff --git a/media/cast/logging/log_serializer.cc b/media/cast/logging/log_serializer.cc
index afcf770..c5cb252 100644
--- a/media/cast/logging/log_serializer.cc
+++ b/media/cast/logging/log_serializer.cc
@@ -47,7 +47,7 @@
 
   int proto_size = metadata.ByteSize();
   DCHECK(proto_size <= kMaxSerializedProtoBytes);
-  if (!writer.WriteU16(proto_size))
+  if (!writer.WriteU16(static_cast<uint16>(proto_size)))
     return false;
   if (!metadata.SerializeToArray(writer.ptr(), writer.remaining()))
     return false;
@@ -73,7 +73,7 @@
     DCHECK(proto_size <= kMaxSerializedProtoBytes);
 
     // Write size of the proto, then write the proto.
-    if (!writer.WriteU16(proto_size))
+    if (!writer.WriteU16(static_cast<uint16>(proto_size)))
       return false;
     if (!frame_event.SerializeToArray(writer.ptr(), writer.remaining()))
       return false;
@@ -97,7 +97,7 @@
     DCHECK(proto_size <= kMaxSerializedProtoBytes);
 
     // Write size of the proto, then write the proto.
-    if (!writer.WriteU16(proto_size))
+    if (!writer.WriteU16(static_cast<uint16>(proto_size)))
       return false;
     if (!packet_event.SerializeToArray(writer.ptr(), writer.remaining()))
       return false;
diff --git a/media/cast/net/cast_transport_config.h b/media/cast/net/cast_transport_config.h
index c5da103..0f101d8 100644
--- a/media/cast/net/cast_transport_config.h
+++ b/media/cast/net/cast_transport_config.h
@@ -22,6 +22,7 @@
   CODEC_UNKNOWN,
   CODEC_AUDIO_OPUS,
   CODEC_AUDIO_PCM16,
+  CODEC_AUDIO_AAC,
   CODEC_VIDEO_FAKE,
   CODEC_VIDEO_VP8,
   CODEC_VIDEO_H264,
diff --git a/media/cast/sender/audio_encoder.cc b/media/cast/sender/audio_encoder.cc
index bf1d3ac..273151f2 100644
--- a/media/cast/sender/audio_encoder.cc
+++ b/media/cast/sender/audio_encoder.cc
@@ -5,6 +5,8 @@
 #include "media/cast/sender/audio_encoder.h"
 
 #include <algorithm>
+#include <limits>
+#include <string>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -15,25 +17,25 @@
 #include "media/base/audio_bus.h"
 #include "media/cast/cast_defines.h"
 #include "media/cast/cast_environment.h"
+
+#if !defined(OS_IOS)
 #include "third_party/opus/src/include/opus.h"
+#endif
+
+#if defined(OS_MACOSX)
+#include <AudioToolbox/AudioToolbox.h>
+#endif
 
 namespace media {
 namespace cast {
 
 namespace {
 
-// The fixed number of audio frames per second and, inversely, the duration of
-// one frame's worth of samples.
-const int kFramesPerSecond = 100;
-const int kFrameDurationMillis = 1000 / kFramesPerSecond;  // No remainder!
-
-// Threshold used to decide whether audio being delivered to the encoder is
-// coming in too slow with respect to the capture timestamps.
-const int kUnderrunThresholdMillis = 3 * kFrameDurationMillis;
+const int kUnderrunSkipThreshold = 3;
+const int kDefaultFramesPerSecond = 100;
 
 }  // namespace
 
-
 // Base class that handles the common problem of feeding one or more AudioBus'
 // data into a buffer and then, once the buffer is full, encoding the signal and
 // emitting an EncodedFrame via the FrameEncodedCallback.
@@ -47,13 +49,17 @@
            Codec codec,
            int num_channels,
            int sampling_rate,
+           int samples_per_frame,
            const FrameEncodedCallback& callback)
       : cast_environment_(cast_environment),
         codec_(codec),
         num_channels_(num_channels),
-        samples_per_frame_(sampling_rate / kFramesPerSecond),
+        samples_per_frame_(samples_per_frame),
         callback_(callback),
         cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED),
+        frame_duration_(base::TimeDelta::FromMicroseconds(
+            base::Time::kMicrosecondsPerSecond * samples_per_frame_ /
+            sampling_rate)),
         buffer_fill_end_(0),
         frame_id_(0),
         frame_rtp_timestamp_(0),
@@ -61,7 +67,7 @@
     // Support for max sampling rate of 48KHz, 2 channels, 100 ms duration.
     const int kMaxSamplesTimesChannelsPerFrame = 48 * 2 * 100;
     if (num_channels_ <= 0 || samples_per_frame_ <= 0 ||
-        sampling_rate % kFramesPerSecond != 0 ||
+        frame_duration_ == base::TimeDelta() ||
         samples_per_frame_ * num_channels_ > kMaxSamplesTimesChannelsPerFrame) {
       cast_initialization_status_ = STATUS_INVALID_AUDIO_CONFIGURATION;
     }
@@ -75,6 +81,8 @@
     return samples_per_frame_;
   }
 
+  base::TimeDelta frame_duration() const { return frame_duration_; }
+
   void EncodeAudio(scoped_ptr<AudioBus> audio_bus,
                    const base::TimeTicks& recorded_time) {
     DCHECK_EQ(cast_initialization_status_, STATUS_AUDIO_INITIALIZED);
@@ -86,20 +94,16 @@
     // frame's RTP timestamp by the estimated number of frames missed.  On the
     // other hand, don't attempt to resolve overruns: A receiver should
     // gracefully deal with an excess of audio data.
-    const base::TimeDelta frame_duration =
-        base::TimeDelta::FromMilliseconds(kFrameDurationMillis);
     base::TimeDelta buffer_fill_duration =
-        buffer_fill_end_ * frame_duration / samples_per_frame_;
+        buffer_fill_end_ * frame_duration_ / samples_per_frame_;
     if (!frame_capture_time_.is_null()) {
       const base::TimeDelta amount_ahead_by =
           recorded_time - (frame_capture_time_ + buffer_fill_duration);
-      if (amount_ahead_by >
-              base::TimeDelta::FromMilliseconds(kUnderrunThresholdMillis)) {
+      const int64 num_frames_missed = amount_ahead_by / frame_duration_;
+      if (num_frames_missed > kUnderrunSkipThreshold) {
         samples_dropped_from_buffer_ += buffer_fill_end_;
         buffer_fill_end_ = 0;
         buffer_fill_duration = base::TimeDelta();
-        const int64 num_frames_missed = amount_ahead_by /
-            base::TimeDelta::FromMilliseconds(kFrameDurationMillis);
         frame_rtp_timestamp_ +=
             static_cast<uint32>(num_frames_missed * samples_per_frame_);
         DVLOG(1) << "Skipping RTP timestamp ahead to account for "
@@ -145,7 +149,7 @@
       buffer_fill_end_ = 0;
       ++frame_id_;
       frame_rtp_timestamp_ += samples_per_frame_;
-      frame_capture_time_ += frame_duration;
+      frame_capture_time_ += frame_duration_;
     }
   }
 
@@ -168,6 +172,10 @@
   // Subclass' ctor is expected to set this to STATUS_AUDIO_INITIALIZED.
   CastInitializationStatus cast_initialization_status_;
 
+  // The duration of one frame of encoded audio samples. Derived from
+  // |samples_per_frame_| and the sampling rate.
+  const base::TimeDelta frame_duration_;
+
  private:
   // 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
@@ -198,6 +206,7 @@
   DISALLOW_COPY_AND_ASSIGN(ImplBase);
 };
 
+#if !defined(OS_IOS)
 class AudioEncoder::OpusImpl : public AudioEncoder::ImplBase {
  public:
   OpusImpl(const scoped_refptr<CastEnvironment>& cast_environment,
@@ -209,12 +218,16 @@
                  CODEC_AUDIO_OPUS,
                  num_channels,
                  sampling_rate,
+                 sampling_rate / kDefaultFramesPerSecond, /* 10 ms frames */
                  callback),
         encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]),
         opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())),
         buffer_(new float[num_channels * samples_per_frame_]) {
-    if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED)
+    if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED ||
+        sampling_rate % samples_per_frame_ != 0 ||
+        !IsValidFrameDuration(frame_duration_)) {
       return;
+    }
     if (opus_encoder_init(opus_encoder_,
                           sampling_rate,
                           num_channels,
@@ -274,6 +287,16 @@
     }
   }
 
+  static bool IsValidFrameDuration(base::TimeDelta duration) {
+    // See https://tools.ietf.org/html/rfc6716#section-2.1.4
+    return duration == base::TimeDelta::FromMicroseconds(2500) ||
+           duration == base::TimeDelta::FromMilliseconds(5) ||
+           duration == base::TimeDelta::FromMilliseconds(10) ||
+           duration == base::TimeDelta::FromMilliseconds(20) ||
+           duration == base::TimeDelta::FromMilliseconds(40) ||
+           duration == base::TimeDelta::FromMilliseconds(60);
+  }
+
   const scoped_ptr<uint8[]> encoder_memory_;
   OpusEncoder* const opus_encoder_;
   const scoped_ptr<float[]> buffer_;
@@ -288,6 +311,388 @@
 
   DISALLOW_COPY_AND_ASSIGN(OpusImpl);
 };
+#endif
+
+#if defined(OS_MACOSX)
+class AudioEncoder::AppleAacImpl : public AudioEncoder::ImplBase {
+  // AAC-LC has two access unit sizes (960 and 1024). The Apple encoder only
+  // supports the latter.
+  static const int kAccessUnitSamples = 1024;
+
+  // Size of an ADTS header (w/o checksum). See
+  // http://wiki.multimedia.cx/index.php?title=ADTS
+  static const int kAdtsHeaderSize = 7;
+
+ public:
+  AppleAacImpl(const scoped_refptr<CastEnvironment>& cast_environment,
+               int num_channels,
+               int sampling_rate,
+               int bitrate,
+               const FrameEncodedCallback& callback)
+      : ImplBase(cast_environment,
+                 CODEC_AUDIO_AAC,
+                 num_channels,
+                 sampling_rate,
+                 kAccessUnitSamples,
+                 callback),
+        input_buffer_(AudioBus::Create(num_channels, kAccessUnitSamples)),
+        input_bus_(AudioBus::CreateWrapper(num_channels)),
+        max_access_unit_size_(0),
+        output_buffer_(nullptr),
+        converter_(nullptr),
+        file_(nullptr),
+        num_access_units_(0),
+        can_resume_(true) {
+    if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED) {
+      return;
+    }
+    if (!Initialize(sampling_rate, bitrate)) {
+      ImplBase::cast_initialization_status_ =
+          STATUS_INVALID_AUDIO_CONFIGURATION;
+      return;
+    }
+    ImplBase::cast_initialization_status_ = STATUS_AUDIO_INITIALIZED;
+  }
+
+ private:
+  virtual ~AppleAacImpl() { Teardown(); }
+
+  // Destroys the existing audio converter and file, if any.
+  void Teardown() {
+    if (converter_) {
+      AudioConverterDispose(converter_);
+      converter_ = nullptr;
+    }
+    if (file_) {
+      AudioFileClose(file_);
+      file_ = nullptr;
+    }
+  }
+
+  // Initializes the audio converter and file. Calls Teardown to destroy any
+  // existing state. This is so that Initialize() may be called to setup another
+  // converter after a non-resumable interruption.
+  bool Initialize(int sampling_rate, int bitrate) {
+    // Teardown previous audio converter and file.
+    Teardown();
+
+    // Input data comes from AudioBus objects, which carry non-interleaved
+    // packed native-endian float samples. Note that in Core Audio, a frame is
+    // one sample across all channels at a given point in time. When describing
+    // a non-interleaved samples format, the "per frame" fields mean "per
+    // channel" or "per stream", with the exception of |mChannelsPerFrame|. For
+    // uncompressed formats, one packet contains one frame.
+    AudioStreamBasicDescription in_asbd;
+    in_asbd.mSampleRate = sampling_rate;
+    in_asbd.mFormatID = kAudioFormatLinearPCM;
+    in_asbd.mFormatFlags =
+        kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
+    in_asbd.mChannelsPerFrame = num_channels_;
+    in_asbd.mBitsPerChannel = sizeof(float) * 8;
+    in_asbd.mFramesPerPacket = 1;
+    in_asbd.mBytesPerPacket = in_asbd.mBytesPerFrame = sizeof(float);
+    in_asbd.mReserved = 0;
+
+    // Request AAC-LC encoding, with no downmixing or downsampling.
+    AudioStreamBasicDescription out_asbd;
+    memset(&out_asbd, 0, sizeof(AudioStreamBasicDescription));
+    out_asbd.mSampleRate = sampling_rate;
+    out_asbd.mFormatID = kAudioFormatMPEG4AAC;
+    out_asbd.mChannelsPerFrame = num_channels_;
+    UInt32 prop_size = sizeof(out_asbd);
+    if (AudioFormatGetProperty(kAudioFormatProperty_FormatInfo,
+                               0,
+                               nullptr,
+                               &prop_size,
+                               &out_asbd) != noErr) {
+      return false;
+    }
+
+    if (AudioConverterNew(&in_asbd, &out_asbd, &converter_) != noErr) {
+      return false;
+    }
+
+    // The converter will fully specify the output format and update the
+    // relevant fields of the structure, which we can now query.
+    prop_size = sizeof(out_asbd);
+    if (AudioConverterGetProperty(converter_,
+                                  kAudioConverterCurrentOutputStreamDescription,
+                                  &prop_size,
+                                  &out_asbd) != noErr) {
+      return false;
+    }
+
+    // If bitrate is <= 0, allow the encoder to pick a suitable value.
+    // Otherwise, set the bitrate (which can fail if the value is not suitable
+    // or compatible with the output sampling rate or channels).
+    if (bitrate > 0) {
+      prop_size = sizeof(int);
+      if (AudioConverterSetProperty(
+              converter_, kAudioConverterEncodeBitRate, prop_size, &bitrate) !=
+          noErr) {
+        return false;
+      }
+    }
+
+#if defined(OS_IOS)
+    // See the comment next to |can_resume_| for details on resumption. Some
+    // converters can return kAudioConverterErr_PropertyNotSupported, in which
+    // case resumption is implicitly supported. This is the only location where
+    // the implementation modifies |can_resume_|.
+    uint32_t can_resume;
+    prop_size = sizeof(can_resume);
+    OSStatus oserr = AudioConverterGetProperty(
+        converter_,
+        kAudioConverterPropertyCanResumeFromInterruption,
+        &prop_size,
+        &can_resume);
+    if (oserr == noErr) {
+      const_cast<bool&>(can_resume_) = can_resume != 0;
+    }
+#endif
+
+    // Figure out the maximum size of an access unit that the encoder can
+    // produce. |mBytesPerPacket| will be 0 for variable size configurations,
+    // in which case we must query the value.
+    uint32_t max_access_unit_size = out_asbd.mBytesPerPacket;
+    if (max_access_unit_size == 0) {
+      prop_size = sizeof(max_access_unit_size);
+      if (AudioConverterGetProperty(
+              converter_,
+              kAudioConverterPropertyMaximumOutputPacketSize,
+              &prop_size,
+              &max_access_unit_size) != noErr) {
+        return false;
+      }
+    }
+
+    // This is the only location where the implementation modifies
+    // |max_access_unit_size_|.
+    const_cast<uint32_t&>(max_access_unit_size_) = max_access_unit_size;
+
+    // Allocate a buffer to store one access unit. This is the only location
+    // where the implementation modifies |access_unit_buffer_|.
+    const_cast<scoped_ptr<uint8[]>&>(access_unit_buffer_)
+        .reset(new uint8[max_access_unit_size]);
+
+    // Initialize the converter ABL. Note that the buffer size has to be set
+    // before every encode operation, since the field is modified to indicate
+    // the size of the output data (on input it indicates the buffer capacity).
+    converter_abl_.mNumberBuffers = 1;
+    converter_abl_.mBuffers[0].mNumberChannels = num_channels_;
+    converter_abl_.mBuffers[0].mData = access_unit_buffer_.get();
+
+    // The "magic cookie" is an encoder state vector required for decoding and
+    // packetization. It is queried now from |converter_| then set on |file_|
+    // after initialization.
+    UInt32 cookie_size;
+    if (AudioConverterGetPropertyInfo(converter_,
+                                      kAudioConverterCompressionMagicCookie,
+                                      &cookie_size,
+                                      nullptr) != noErr) {
+      return false;
+    }
+    scoped_ptr<uint8[]> cookie_data(new uint8[cookie_size]);
+    if (AudioConverterGetProperty(converter_,
+                                  kAudioConverterCompressionMagicCookie,
+                                  &cookie_size,
+                                  cookie_data.get()) != noErr) {
+      return false;
+    }
+
+    if (AudioFileInitializeWithCallbacks(this,
+                                         nullptr,
+                                         &FileWriteCallback,
+                                         nullptr,
+                                         nullptr,
+                                         kAudioFileAAC_ADTSType,
+                                         &out_asbd,
+                                         0,
+                                         &file_) != noErr) {
+      return false;
+    }
+
+    if (AudioFileSetProperty(file_,
+                             kAudioFilePropertyMagicCookieData,
+                             cookie_size,
+                             cookie_data.get()) != noErr) {
+      return false;
+    }
+
+    // Initially the input bus points to the input buffer. See the comment on
+    // |input_bus_| for more on this optimization.
+    input_bus_->set_frames(kAccessUnitSamples);
+    for (int ch = 0; ch < input_buffer_->channels(); ++ch) {
+      input_bus_->SetChannelData(ch, input_buffer_->channel(ch));
+    }
+
+    return true;
+  }
+
+  void TransferSamplesIntoBuffer(const AudioBus* audio_bus,
+                                 int source_offset,
+                                 int buffer_fill_offset,
+                                 int num_samples) override {
+    DCHECK_EQ(audio_bus->channels(), input_buffer_->channels());
+
+    // See the comment on |input_bus_| for more on this optimization. Note that
+    // we cannot elide the copy if the source offset would result in an
+    // unaligned pointer.
+    if (num_samples == kAccessUnitSamples &&
+        source_offset * sizeof(float) % AudioBus::kChannelAlignment == 0) {
+      DCHECK_EQ(buffer_fill_offset, 0);
+      for (int ch = 0; ch < audio_bus->channels(); ++ch) {
+        auto samples = const_cast<float*>(audio_bus->channel(ch));
+        input_bus_->SetChannelData(ch, samples + source_offset);
+      }
+      return;
+    }
+
+    // Copy the samples into the input buffer.
+    DCHECK_EQ(input_bus_->channel(0), input_buffer_->channel(0));
+    audio_bus->CopyPartialFramesTo(
+        source_offset, num_samples, buffer_fill_offset, input_buffer_.get());
+  }
+
+  bool EncodeFromFilledBuffer(std::string* out) override {
+    // Reset the buffer size field to the buffer capacity.
+    converter_abl_.mBuffers[0].mDataByteSize = max_access_unit_size_;
+
+    // Encode the current input buffer. This is a sychronous call.
+    OSStatus oserr;
+    UInt32 io_num_packets = 1;
+    AudioStreamPacketDescription packet_description;
+    oserr = AudioConverterFillComplexBuffer(converter_,
+                                            &ConverterFillDataCallback,
+                                            this,
+                                            &io_num_packets,
+                                            &converter_abl_,
+                                            &packet_description);
+    if (oserr != noErr || io_num_packets == 0) {
+      return false;
+    }
+
+    // Reserve space in the output buffer to write the packet.
+    out->reserve(packet_description.mDataByteSize + kAdtsHeaderSize);
+
+    // Set the current output buffer and emit an ADTS-wrapped AAC access unit.
+    // This is a synchronous call. After it returns, reset the output buffer.
+    output_buffer_ = out;
+    oserr = AudioFileWritePackets(file_,
+                                  false,
+                                  converter_abl_.mBuffers[0].mDataByteSize,
+                                  &packet_description,
+                                  num_access_units_,
+                                  &io_num_packets,
+                                  converter_abl_.mBuffers[0].mData);
+    output_buffer_ = nullptr;
+    if (oserr != noErr || io_num_packets == 0) {
+      return false;
+    }
+    num_access_units_ += io_num_packets;
+    return true;
+  }
+
+  // The |AudioConverterFillComplexBuffer| input callback function. Configures
+  // the provided |AudioBufferList| to alias |input_bus_|. The implementation
+  // can only supply |kAccessUnitSamples| samples as a result of not copying
+  // samples or tracking read and write positions. Note that this function is
+  // called synchronously by |AudioConverterFillComplexBuffer|.
+  static OSStatus ConverterFillDataCallback(
+      AudioConverterRef in_converter,
+      UInt32* io_num_packets,
+      AudioBufferList* io_data,
+      AudioStreamPacketDescription** out_packet_desc,
+      void* in_encoder) {
+    DCHECK(in_encoder);
+    auto encoder = reinterpret_cast<AppleAacImpl*>(in_encoder);
+    auto input_buffer = encoder->input_buffer_.get();
+    auto input_bus = encoder->input_bus_.get();
+
+    DCHECK_EQ(static_cast<int>(*io_num_packets), kAccessUnitSamples);
+    DCHECK_EQ(io_data->mNumberBuffers,
+              static_cast<unsigned>(input_bus->channels()));
+    for (int i_buf = 0, end = io_data->mNumberBuffers; i_buf < end; ++i_buf) {
+      io_data->mBuffers[i_buf].mNumberChannels = 1;
+      io_data->mBuffers[i_buf].mDataByteSize = sizeof(float) * *io_num_packets;
+      io_data->mBuffers[i_buf].mData = input_bus->channel(i_buf);
+
+      // Reset the input bus back to the input buffer. See the comment on
+      // |input_bus_| for more on this optimization.
+      input_bus->SetChannelData(i_buf, input_buffer->channel(i_buf));
+    }
+    return noErr;
+  }
+
+  // The AudioFile write callback function. Appends the data to the encoder's
+  // current |output_buffer_|.
+  static OSStatus FileWriteCallback(void* in_encoder,
+                                    SInt64 in_position,
+                                    UInt32 in_size,
+                                    const void* in_buffer,
+                                    UInt32* out_size) {
+    DCHECK(in_encoder);
+    DCHECK(in_buffer);
+    auto encoder = reinterpret_cast<const AppleAacImpl*>(in_encoder);
+    auto buffer = reinterpret_cast<const std::string::value_type*>(in_buffer);
+
+    std::string* const output_buffer = encoder->output_buffer_;
+    DCHECK(output_buffer);
+
+    output_buffer->append(buffer, in_size);
+    *out_size = in_size;
+    return noErr;
+  }
+
+  // Buffer that holds one AAC access unit worth of samples. The input callback
+  // function provides samples from this buffer via |input_bus_| to the encoder.
+  const scoped_ptr<AudioBus> input_buffer_;
+
+  // Wrapper AudioBus used by the input callback function. Normally it wraps
+  // |input_buffer_|. However, as an optimization when the client submits a
+  // buffer containing exactly one access unit worth of samples, the bus is
+  // redirected to the client buffer temporarily. We know that the base
+  // implementation will call us right after to encode the buffer and thus we
+  // can eliminate the copy into |input_buffer_|.
+  const scoped_ptr<AudioBus> input_bus_;
+
+  // A buffer that holds one AAC access unit. Initialized in |Initialize| once
+  // the maximum access unit size is known.
+  const scoped_ptr<uint8[]> access_unit_buffer_;
+
+  // The maximum size of an access unit that the encoder can emit.
+  const uint32_t max_access_unit_size_;
+
+  // A temporary pointer to the current output buffer. Only non-null when
+  // writing an access unit. Accessed by the AudioFile write callback function.
+  std::string* output_buffer_;
+
+  // The |AudioConverter| is responsible for AAC encoding. This is a Core Audio
+  // object, not to be confused with |media::AudioConverter|.
+  AudioConverterRef converter_;
+
+  // The |AudioFile| is responsible for ADTS packetization.
+  AudioFileID file_;
+
+  // An |AudioBufferList| passed to the converter to store encoded samples.
+  AudioBufferList converter_abl_;
+
+  // The number of access units emitted so far by the encoder.
+  uint64_t num_access_units_;
+
+  // On iOS, audio codecs can be interrupted by other services (such as an
+  // audio alert or phone call). Depending on the underlying hardware and
+  // configuration, the codec may have to be thrown away and re-initialized
+  // after such an interruption. This flag tracks if we can resume or not from
+  // such an interruption. It is initialized to true, which is the only possible
+  // value on OS X and on most modern iOS hardware.
+  // TODO(jfroy): Implement encoder re-initialization after interruption.
+  //              https://crbug.com/424787
+  const bool can_resume_;
+
+  DISALLOW_COPY_AND_ASSIGN(AppleAacImpl);
+};
+#endif  // defined(OS_MACOSX)
 
 class AudioEncoder::Pcm16Impl : public AudioEncoder::ImplBase {
  public:
@@ -299,6 +704,7 @@
                  CODEC_AUDIO_PCM16,
                  num_channels,
                  sampling_rate,
+                 sampling_rate / kDefaultFramesPerSecond, /* 10 ms frames */
                  callback),
         buffer_(new int16[num_channels * samples_per_frame_]) {
     if (ImplBase::cast_initialization_status_ != STATUS_AUDIO_UNINITIALIZED)
@@ -349,6 +755,7 @@
   // as all calls to InsertAudio() are by the same thread.
   insert_thread_checker_.DetachFromThread();
   switch (codec) {
+#if !defined(OS_IOS)
     case CODEC_AUDIO_OPUS:
       impl_ = new OpusImpl(cast_environment,
                            num_channels,
@@ -356,6 +763,16 @@
                            bitrate,
                            frame_encoded_callback);
       break;
+#endif
+#if defined(OS_MACOSX)
+    case CODEC_AUDIO_AAC:
+      impl_ = new AppleAacImpl(cast_environment,
+                               num_channels,
+                               sampling_rate,
+                               bitrate,
+                               frame_encoded_callback);
+      break;
+#endif  // defined(OS_MACOSX)
     case CODEC_AUDIO_PCM16:
       impl_ = new Pcm16Impl(cast_environment,
                             num_channels,
@@ -387,6 +804,15 @@
   return impl_->samples_per_frame();
 }
 
+base::TimeDelta AudioEncoder::GetFrameDuration() const {
+  DCHECK(insert_thread_checker_.CalledOnValidThread());
+  if (InitializationResult() != STATUS_AUDIO_INITIALIZED) {
+    NOTREACHED();
+    return base::TimeDelta();
+  }
+  return impl_->frame_duration();
+}
+
 void AudioEncoder::InsertAudio(scoped_ptr<AudioBus> audio_bus,
                                const base::TimeTicks& recorded_time) {
   DCHECK(insert_thread_checker_.CalledOnValidThread());
diff --git a/media/cast/sender/audio_encoder.h b/media/cast/sender/audio_encoder.h
index e0a3d8a..8c5bafa 100644
--- a/media/cast/sender/audio_encoder.h
+++ b/media/cast/sender/audio_encoder.h
@@ -36,6 +36,7 @@
   CastInitializationStatus InitializationResult() const;
 
   int GetSamplesPerFrame() const;
+  base::TimeDelta GetFrameDuration() const;
 
   void InsertAudio(scoped_ptr<AudioBus> audio_bus,
                    const base::TimeTicks& recorded_time);
@@ -44,6 +45,7 @@
   class ImplBase;
   class OpusImpl;
   class Pcm16Impl;
+  class AppleAacImpl;
 
   const scoped_refptr<CastEnvironment> cast_environment_;
   scoped_refptr<ImplBase> impl_;
diff --git a/media/cast/sender/audio_encoder_unittest.cc b/media/cast/sender/audio_encoder_unittest.cc
index a33ed3b..795ab725 100644
--- a/media/cast/sender/audio_encoder_unittest.cc
+++ b/media/cast/sender/audio_encoder_unittest.cc
@@ -39,6 +39,10 @@
     upper_bound_ = upper_bound;
   }
 
+  void SetSamplesPerFrame(int samples_per_frame) {
+    samples_per_frame_ = samples_per_frame;
+  }
+
   void FrameEncoded(scoped_ptr<EncodedFrame> encoded_frame,
                     int samples_skipped) {
     EXPECT_EQ(encoded_frame->dependency, EncodedFrame::KEY);
@@ -49,9 +53,7 @@
     // of the fixed frame size.
     EXPECT_LE(rtp_lower_bound_, encoded_frame->rtp_timestamp);
     rtp_lower_bound_ = encoded_frame->rtp_timestamp;
-    // Note: In audio_encoder.cc, 100 is the fixed audio frame rate.
-    const int kSamplesPerFrame = kDefaultAudioSamplingRate / 100;
-    EXPECT_EQ(0u, encoded_frame->rtp_timestamp % kSamplesPerFrame);
+    EXPECT_EQ(0u, encoded_frame->rtp_timestamp % samples_per_frame_);
     EXPECT_TRUE(!encoded_frame->data.empty());
 
     EXPECT_LE(lower_bound_, encoded_frame->reference_time);
@@ -65,6 +67,7 @@
   const Codec codec_;
   int frames_received_;
   uint32 rtp_lower_bound_;
+  int samples_per_frame_;
   base::TimeTicks lower_bound_;
   base::TimeTicks upper_bound_;
 
@@ -116,9 +119,7 @@
 
     CreateObjectsForCodec(codec);
 
-    // Note: In audio_encoder.cc, 10 ms is the fixed frame duration.
-    const base::TimeDelta frame_duration =
-        base::TimeDelta::FromMilliseconds(10);
+    const base::TimeDelta frame_duration = audio_encoder_->GetFrameDuration();
 
     for (size_t i = 0; i < scenario.num_durations; ++i) {
       const bool simulate_missing_data = scenario.durations_in_ms[i] < 0;
@@ -160,6 +161,8 @@
         codec,
         base::Bind(&TestEncodedAudioFrameReceiver::FrameEncoded,
                    base::Unretained(receiver_.get()))));
+
+    receiver_->SetSamplesPerFrame(audio_encoder_->GetSamplesPerFrame());
   }
 
   base::SimpleTestTickClock* testing_clock_;  // Owned by CastEnvironment.
@@ -180,6 +183,12 @@
   RunTestForCodec(CODEC_AUDIO_PCM16);
 }
 
+#if defined(OS_MACOSX)
+TEST_P(AudioEncoderTest, EncodeAac) {
+  RunTestForCodec(CODEC_AUDIO_AAC);
+}
+#endif
+
 static const int64 kOneCall_3Millis[] = {3};
 static const int64 kOneCall_10Millis[] = {10};
 static const int64 kOneCall_13Millis[] = {13};
diff --git a/media/cast/sender/audio_sender.cc b/media/cast/sender/audio_sender.cc
index 8916a17..4748218c 100644
--- a/media/cast/sender/audio_sender.cc
+++ b/media/cast/sender/audio_sender.cc
@@ -13,29 +13,20 @@
 
 namespace media {
 namespace cast {
-namespace {
-
-// TODO(miu): This should be specified in AudioSenderConfig, but currently it is
-// fixed to 100 FPS (i.e., 10 ms per frame), and AudioEncoder assumes this as
-// well.
-const int kAudioFrameRate = 100;
-
-}  // namespace
 
 AudioSender::AudioSender(scoped_refptr<CastEnvironment> cast_environment,
                          const AudioSenderConfig& audio_config,
                          CastTransportSender* const transport_sender)
-    : FrameSender(
-        cast_environment,
-        true,
-        transport_sender,
-        base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval),
-        audio_config.frequency,
-        audio_config.ssrc,
-        kAudioFrameRate,
-        audio_config.min_playout_delay,
-        audio_config.max_playout_delay,
-        NewFixedCongestionControl(audio_config.bitrate)),
+    : FrameSender(cast_environment,
+                  true,
+                  transport_sender,
+                  base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval),
+                  audio_config.frequency,
+                  audio_config.ssrc,
+                  0,  // |max_frame_rate_| is set after encoder initialization.
+                  audio_config.min_playout_delay,
+                  audio_config.max_playout_delay,
+                  NewFixedCongestionControl(audio_config.bitrate)),
       samples_in_encoder_(0),
       weak_factory_(this) {
   cast_initialization_status_ = STATUS_AUDIO_UNINITIALIZED;
@@ -56,6 +47,12 @@
     cast_initialization_status_ = STATUS_AUDIO_UNINITIALIZED;
   }
 
+  // The number of samples per encoded audio frame depends on the codec and its
+  // initialization parameters. Now that we have an encoder, we can calculate
+  // the maximum frame rate.
+  max_frame_rate_ =
+      audio_config.frequency / audio_encoder_->GetSamplesPerFrame();
+
   media::cast::CastTransportRtpConfig transport_config;
   transport_config.ssrc = audio_config.ssrc;
   transport_config.feedback_ssrc = audio_config.incoming_feedback_ssrc;
diff --git a/media/cast/sender/vp8_encoder.cc b/media/cast/sender/vp8_encoder.cc
index 54a579d..bf430c1 100644
--- a/media/cast/sender/vp8_encoder.cc
+++ b/media/cast/sender/vp8_encoder.cc
@@ -13,7 +13,15 @@
 namespace media {
 namespace cast {
 
-static const uint32 kMinIntra = 300;
+namespace {
+
+// After a pause in the video stream, what is the maximum duration amount to
+// pass to the encoder for the next frame (in terms of 1/max_fps sized periods)?
+// This essentially controls the encoded size of the first frame that follows a
+// pause in the video stream.
+const int kRestartFramePeriods = 3;
+
+}  // namespace
 
 Vp8Encoder::Vp8Encoder(const VideoSenderConfig& video_config)
     : cast_config_(video_config),
@@ -22,10 +30,8 @@
           kNumberOfVp8VideoBuffers),
       raw_image_(nullptr),
       key_frame_requested_(true),
-      first_frame_received_(false),
       last_encoded_frame_id_(kStartFrameId),
       last_acked_frame_id_(kStartFrameId),
-      frame_id_to_reference_(kStartFrameId - 1),
       undroppable_frames_(0) {
   config_.g_timebase.den = 0;  // Not initialized.
 
@@ -75,8 +81,9 @@
   config_.g_threads = cast_config_.number_of_encode_threads;
   config_.g_w = cast_config_.width;
   config_.g_h = cast_config_.height;
+  // Set the timebase to match that of base::TimeDelta.
   config_.g_timebase.num = 1;
-  config_.g_timebase.den = kVideoFrequency;
+  config_.g_timebase.den = base::Time::kMicrosecondsPerSecond;
   if (use_multiple_video_buffers_) {
     // We must enable error resilience when we use multiple buffers, due to
     // codec requirements.
@@ -92,27 +99,38 @@
   config_.rc_target_bitrate = cast_config_.start_bitrate / 1000;  // In kbit/s.
   config_.rc_min_quantizer = cast_config_.min_qp;
   config_.rc_max_quantizer = cast_config_.max_qp;
+  // TODO(miu): Revisit these now that the encoder is being successfully
+  // micro-managed.
   config_.rc_undershoot_pct = 100;
   config_.rc_overshoot_pct = 15;
+  // TODO(miu): Document why these rc_buf_*_sz values were chosen and/or
+  // research for better values.  Should they be computed from the target
+  // playout delay?
   config_.rc_buf_initial_sz = 500;
   config_.rc_buf_optimal_sz = 600;
-  config_.rc_buf_sz = 1000;  // TODO(miu): Adjust relative to playout delay?
+  config_.rc_buf_sz = 1000;
 
   config_.kf_mode = VPX_KF_DISABLED;
 
-  // set the maximum target size of any key-frame.
-  uint32 rc_max_intra_target = MaxIntraTarget(config_.rc_buf_optimal_sz);
   vpx_codec_flags_t flags = 0;
   if (vpx_codec_enc_init(&encoder_, vpx_codec_vp8_cx(), &config_, flags)) {
     NOTREACHED() << "vpx_codec_enc_init() failed.";
     config_.g_timebase.den = 0;  // Do not call vpx_codec_destroy() in dtor.
     return;
   }
+
+  // Raise the threshold for considering macroblocks as static.  The default is
+  // zero, so this setting makes the encoder less sensitive to motion.  This
+  // lowers the probability of needing to utilize more CPU to search for motion
+  // vectors.
   vpx_codec_control(&encoder_, VP8E_SET_STATIC_THRESHOLD, 1);
-  vpx_codec_control(&encoder_, VP8E_SET_NOISE_SENSITIVITY, 0);
+
+  // Improve quality by enabling sets of codec features that utilize more CPU.
+  // The default is zero, with increasingly more CPU to be used as the value is
+  // more negative.
+  // TODO(miu): Document why this value was chosen and expected behaviors.
+  // Should this be dynamic w.r.t. hardware performance?
   vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, -6);
-  vpx_codec_control(
-      &encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT, rc_max_intra_target);
 }
 
 void Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame,
@@ -153,28 +171,33 @@
     GetCodecUpdateFlags(buffer_to_update, &flags);
   }
 
-  // Note: The duration does not reflect the real time between frames. This is
-  // done to keep the encoder happy.
-  //
-  // TODO(miu): This is a semi-hack.  We should consider using
-  // |video_frame->timestamp()| instead.
-  uint32 duration = kVideoFrequency / cast_config_.max_frame_rate;
+  // The frame duration given to the VP8 codec affects a number of important
+  // behaviors, including: per-frame bandwidth, CPU time spent encoding,
+  // temporal quality trade-offs, and key/golden/alt-ref frame generation
+  // intervals.  Use the actual amount of time between the current and previous
+  // frames as a prediction for the next frame's duration, but bound the
+  // prediction to account for the fact that the frame rate can be highly
+  // variable, including long pauses in the video stream.
+  const base::TimeDelta minimum_frame_duration =
+      base::TimeDelta::FromSecondsD(1.0 / cast_config_.max_frame_rate);
+  const base::TimeDelta maximum_frame_duration =
+      base::TimeDelta::FromSecondsD(static_cast<double>(kRestartFramePeriods) /
+                                        cast_config_.max_frame_rate);
+  const base::TimeDelta last_frame_duration =
+      video_frame->timestamp() - last_frame_timestamp_;
+  const base::TimeDelta predicted_frame_duration =
+      std::max(minimum_frame_duration,
+               std::min(maximum_frame_duration, last_frame_duration));
+  last_frame_timestamp_ = video_frame->timestamp();
 
-  // Note: Timestamp here is used for bitrate calculation. The absolute value
-  // is not important.
-  if (!first_frame_received_) {
-    first_frame_received_ = true;
-    first_frame_timestamp_ = video_frame->timestamp();
-  }
-
-  vpx_codec_pts_t timestamp =
-      (video_frame->timestamp() - first_frame_timestamp_).InMicroseconds() *
-      kVideoFrequency / base::Time::kMicrosecondsPerSecond;
-
+  // Encode the frame.  The presentation time stamp argument here is fixed to
+  // zero to force the encoder to base its single-frame bandwidth calculations
+  // entirely on |predicted_frame_duration| and the target bitrate setting being
+  // micro-managed via calls to UpdateRates().
   CHECK_EQ(vpx_codec_encode(&encoder_,
                             raw_image_,
-                            timestamp,
-                            duration,
+                            0,
+                            predicted_frame_duration.InMicroseconds(),
                             flags,
                             VPX_DL_REALTIME),
            VPX_CODEC_OK)
@@ -198,7 +221,8 @@
       // flag never seems to be set.
       encoded_frame->referenced_frame_id = latest_frame_id_to_reference;
     }
-    encoded_frame->rtp_timestamp = timestamp;
+    encoded_frame->rtp_timestamp =
+        TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency);
     encoded_frame->reference_time = reference_time;
     encoded_frame->data.assign(
         static_cast<const uint8*>(pkt->data.frame.buf),
@@ -208,7 +232,7 @@
   DCHECK(!encoded_frame->data.empty())
       << "BUG: Encoder must provide data since lagged encoding is disabled.";
 
-  DVLOG(1) << "VP8 encoded frame_id " << encoded_frame->frame_id
+  DVLOG(2) << "VP8 encoded frame_id " << encoded_frame->frame_id
            << ", sized:" << encoded_frame->data.size();
 
   if (encoded_frame->dependency == EncodedFrame::KEY) {
@@ -384,6 +408,8 @@
   if (vpx_codec_enc_config_set(&encoder_, &config_)) {
     NOTREACHED() << "Invalid return value";
   }
+
+  VLOG(1) << "VP8 new rc_target_bitrate: " << new_bitrate_kbit << " kbps";
 }
 
 void Vp8Encoder::LatestFrameIdToReference(uint32 frame_id) {
@@ -391,7 +417,7 @@
   if (!use_multiple_video_buffers_)
     return;
 
-  VLOG(1) << "VP8 ok to reference frame:" << static_cast<int>(frame_id);
+  VLOG(2) << "VP8 ok to reference frame:" << static_cast<int>(frame_id);
   for (int i = 0; i < kNumberOfVp8VideoBuffers; ++i) {
     if (frame_id == buffer_state_[i].frame_id) {
       buffer_state_[i].state = kBufferAcked;
@@ -408,22 +434,5 @@
   key_frame_requested_ = true;
 }
 
-// Calculate the max size of the key frame relative to a normal delta frame.
-uint32 Vp8Encoder::MaxIntraTarget(uint32 optimal_buffer_size_ms) const {
-  // Set max to the optimal buffer level (normalized by target BR),
-  // and scaled by a scale_parameter.
-  // Max target size = scalePar * optimalBufferSize * targetBR[Kbps].
-  // This values is presented in percentage of perFrameBw:
-  // perFrameBw = targetBR[Kbps] * 1000 / frameRate.
-  // The target in % is as follows:
-
-  float scale_parameter = 0.5;
-  uint32 target_pct = optimal_buffer_size_ms * scale_parameter *
-                      cast_config_.max_frame_rate / 10;
-
-  // Don't go below 3 times the per frame bandwidth.
-  return std::max(target_pct, kMinIntra);
-}
-
 }  // namespace cast
 }  // namespace media
diff --git a/media/cast/sender/vp8_encoder.h b/media/cast/sender/vp8_encoder.h
index bf678bcd..387dbf2 100644
--- a/media/cast/sender/vp8_encoder.h
+++ b/media/cast/sender/vp8_encoder.h
@@ -61,9 +61,6 @@
     return config_.g_timebase.den != 0;
   }
 
-  // Calculate the max target in % for a keyframe.
-  uint32 MaxIntraTarget(uint32 optimal_buffer_size) const;
-
   // Calculate which next Vp8 buffers to update with the next frame.
   Vp8Buffers GetNextBufferToUpdate();
 
@@ -86,13 +83,24 @@
   // Wrapper for access to YUV data planes in a media::VideoFrame.
   vpx_image_t* raw_image_;
 
+  // Set to true to request the next frame emitted by Vp8Encoder be a key frame.
   bool key_frame_requested_;
-  bool first_frame_received_;
-  base::TimeDelta first_frame_timestamp_;
+
+  // The |VideoFrame::timestamp()| of the last encoded frame.  This is used to
+  // predict the duration of the next frame.
+  base::TimeDelta last_frame_timestamp_;
+
+  // The last encoded frame's ID.
   uint32 last_encoded_frame_id_;
+
+  // Used to track which buffers are old enough to be re-used.
   uint32 last_acked_frame_id_;
-  uint32 frame_id_to_reference_;
-  uint32 undroppable_frames_;
+
+  // Used by GetNextBufferToUpdate() to track how many consecutive times the
+  // newest buffer had to be overwritten.
+  int undroppable_frames_;
+
+  // Tracks the lifecycle and dependency state of each of the three buffers.
   BufferState buffer_state_[kNumberOfVp8VideoBuffers];
 
   // This is bound to the thread where Initialize() is called.
diff --git a/media/cast/test/fake_media_source.cc b/media/cast/test/fake_media_source.cc
index 096d576..d687ef3 100644
--- a/media/cast/test/fake_media_source.cc
+++ b/media/cast/test/fake_media_source.cc
@@ -41,6 +41,16 @@
   av_frame_free(&frame);
 }
 
+base::TimeDelta PtsToTimeDelta(int64 pts, const AVRational& time_base) {
+  return pts * base::TimeDelta::FromSeconds(1) * time_base.num / time_base.den;
+}
+
+int64 TimeDeltaToPts(base::TimeDelta delta, const AVRational& time_base) {
+  return static_cast<int64>(
+      delta.InSecondsF() * time_base.den / time_base.num +
+      0.5 /* rounding */);
+}
+
 }  // namespace
 
 namespace media {
@@ -78,11 +88,6 @@
                                     int override_fps) {
   DCHECK(!video_file.empty());
 
-  if (override_fps) {
-    video_config_.max_frame_rate = override_fps;
-    video_frame_rate_numerator_ = override_fps;
-  }
-
   LOG(INFO) << "Source: " << video_file.value();
   if (!file_data_.Initialize(video_file)) {
     LOG(ERROR) << "Cannot load file.";
@@ -162,18 +167,16 @@
         LOG(WARNING) << "Found multiple video streams.";
       }
       video_stream_index_ = static_cast<int>(i);
-      if (!override_fps) {
-        video_frame_rate_numerator_ = av_stream->r_frame_rate.num;
-        video_frame_rate_denominator_ = av_stream->r_frame_rate.den;
-        // Max frame rate is rounded up.
-        video_config_.max_frame_rate =
-            video_frame_rate_denominator_ +
-            video_frame_rate_numerator_ - 1;
-        video_config_.max_frame_rate /= video_frame_rate_denominator_;
-      } else {
+      if (override_fps > 0) {
         // If video is played at a manual speed audio needs to match.
         playback_rate_ = 1.0 * override_fps *
-            av_stream->r_frame_rate.den /  av_stream->r_frame_rate.num;
+            av_stream->r_frame_rate.den / av_stream->r_frame_rate.num;
+        video_frame_rate_numerator_ = override_fps;
+        video_frame_rate_denominator_ = 1;
+      } else {
+        playback_rate_ = 1.0;
+        video_frame_rate_numerator_ = av_stream->r_frame_rate.num;
+        video_frame_rate_denominator_ = av_stream->r_frame_rate.den;
       }
       LOG(INFO) << "Source file has video.";
     } else {
@@ -190,11 +193,14 @@
   video_frame_input_ = video_frame_input;
 
   LOG(INFO) << "Max Frame rate: " << video_config_.max_frame_rate;
-  LOG(INFO) << "Real Frame rate: "
+  LOG(INFO) << "Source Frame rate: "
             << video_frame_rate_numerator_ << "/"
             << video_frame_rate_denominator_ << " fps.";
   LOG(INFO) << "Audio playback rate: " << playback_rate_;
 
+  if (start_time_.is_null())
+    start_time_ = clock_->NowTicks();
+
   if (!is_transcoding_audio() && !is_transcoding_video()) {
     // Send fake patterns.
     task_runner_->PostTask(
@@ -235,9 +241,7 @@
   PopulateVideoFrame(video_frame.get(), synthetic_count_);
   ++synthetic_count_;
 
-  base::TimeTicks now = clock_->NowTicks();
-  if (start_time_.is_null())
-    start_time_ = now;
+  const base::TimeTicks now = clock_->NowTicks();
 
   base::TimeDelta video_time = VideoFrameTime(++video_frame_count_);
   video_frame->set_timestamp(video_time);
@@ -263,7 +267,7 @@
     audio_time = AudioFrameTime(++audio_frame_count_);
   }
 
-  // This is the time since the stream started.
+  // This is the time since FakeMediaSource was started.
   const base::TimeDelta elapsed_time = now - start_time_;
 
   // Handle the case when frame generation cannot keep up.
@@ -313,11 +317,10 @@
                    decoded_frame->rows(VideoFrame::kVPlane),
                    video_frame.get());
 
-  base::TimeDelta video_time;
   // Use the timestamp from the file if we're transcoding.
-  video_time = ScaleTimestamp(decoded_frame->timestamp());
+  video_frame->set_timestamp(ScaleTimestamp(decoded_frame->timestamp()));
   video_frame_input_->InsertRawVideoFrame(
-      video_frame, start_time_ + video_time);
+      video_frame, start_time_ + video_frame->timestamp());
 
   // Make sure queue is not empty.
   Decode(false);
@@ -347,11 +350,6 @@
 }
 
 void FakeMediaSource::SendNextFrame() {
-  if (start_time_.is_null())
-    start_time_ = clock_->NowTicks();
-  if (start_time_.is_null())
-    start_time_ = clock_->NowTicks();
-
   // Send as much as possible. Audio is sent according to
   // system time.
   while (SendNextTranscodedAudio(clock_->NowTicks() - start_time_));
@@ -364,9 +362,6 @@
     // the end of the stream.
     LOG(INFO) << "Rewind.";
     Rewind();
-    start_time_ = base::TimeTicks();
-    audio_sent_ts_.reset();
-    video_first_pts_set_ = false;
   }
 
   // Send next send.
@@ -384,8 +379,7 @@
 }
 
 base::TimeDelta FakeMediaSource::ScaleTimestamp(base::TimeDelta timestamp) {
-  return base::TimeDelta::FromMicroseconds(
-      timestamp.InMicroseconds() / playback_rate_);
+  return base::TimeDelta::FromSecondsD(timestamp.InSecondsF() / playback_rate_);
 }
 
 base::TimeDelta FakeMediaSource::AudioFrameTime(int frame_number) {
@@ -400,7 +394,7 @@
 ScopedAVPacket FakeMediaSource::DemuxOnePacket(bool* audio) {
   ScopedAVPacket packet(new AVPacket());
   if (av_read_frame(av_format_context_, packet.get()) < 0) {
-    LOG(ERROR) << "Failed to read one AVPacket.";
+    VLOG(1) << "Failed to read one AVPacket.";
     packet.reset();
     return packet.Pass();
   }
@@ -463,8 +457,7 @@
             av_audio_context()->sample_rate,
             frames_read,
             &avframe->data[0],
-            // Note: Not all files have correct values for pkt_pts.
-            base::TimeDelta::FromMilliseconds(avframe->pkt_pts));
+            PtsToTimeDelta(avframe->pkt_pts, av_audio_stream()->time_base));
     audio_algo_.EnqueueBuffer(buffer);
     av_frame_unref(avframe);
   } while (packet_temp.size > 0);
@@ -509,9 +502,6 @@
   // Video.
   int got_picture;
   AVFrame* avframe = av_frame_alloc();
-  // Tell the decoder to reorder for us.
-  avframe->reordered_opaque =
-      av_video_context()->reordered_opaque = packet->pts;
   CHECK(avcodec_decode_video2(
       av_video_context(), avframe, &got_picture, packet.get()) >= 0)
       << "Video decode error.";
@@ -520,12 +510,23 @@
     return;
   }
   gfx::Size size(av_video_context()->width, av_video_context()->height);
-  if (!video_first_pts_set_ ||
-      avframe->reordered_opaque < video_first_pts_) {
+
+  if (!video_first_pts_set_) {
+    video_first_pts_ = avframe->pkt_pts;
     video_first_pts_set_ = true;
-    video_first_pts_ = avframe->reordered_opaque;
   }
-  int64 pts = avframe->reordered_opaque - video_first_pts_;
+  const AVRational& time_base = av_video_stream()->time_base;
+  base::TimeDelta timestamp =
+      PtsToTimeDelta(avframe->pkt_pts - video_first_pts_, time_base);
+  if (timestamp < last_video_frame_timestamp_) {
+    // Stream has rewound.  Rebase |video_first_pts_|.
+    const AVRational& frame_rate = av_video_stream()->r_frame_rate;
+    timestamp = last_video_frame_timestamp_ +
+        (base::TimeDelta::FromSeconds(1) * frame_rate.den / frame_rate.num);
+    const int64 adjustment_pts = TimeDeltaToPts(timestamp, time_base);
+    video_first_pts_ = avframe->pkt_pts - adjustment_pts;
+  }
+
   video_frame_queue_.push(
       VideoFrame::WrapExternalYuvData(
           media::VideoFrame::YV12,
@@ -538,8 +539,9 @@
           avframe->data[0],
           avframe->data[1],
           avframe->data[2],
-          base::TimeDelta::FromMilliseconds(pts),
+          timestamp,
           base::Bind(&AVFreeFrame, avframe)));
+  last_video_frame_timestamp_ = timestamp;
 }
 
 void FakeMediaSource::Decode(bool decode_audio) {
@@ -553,7 +555,7 @@
     bool audio_packet = false;
     ScopedAVPacket packet = DemuxOnePacket(&audio_packet);
     if (!packet) {
-      LOG(INFO) << "End of stream.";
+      VLOG(1) << "End of stream.";
       return;
     }
 
diff --git a/media/cast/test/fake_media_source.h b/media/cast/test/fake_media_source.h
index 835fb95..4e6a4c3 100644
--- a/media/cast/test/fake_media_source.h
+++ b/media/cast/test/fake_media_source.h
@@ -97,8 +97,8 @@
   AVCodecContext* av_audio_context();
   AVCodecContext* av_video_context();
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  VideoSenderConfig video_config_;
+  const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  const VideoSenderConfig video_config_;
   scoped_refptr<AudioFrameInput> audio_frame_input_;
   scoped_refptr<VideoFrameInput> video_frame_input_;
   uint8 synthetic_count_;
@@ -137,6 +137,7 @@
   std::queue<scoped_refptr<VideoFrame> > video_frame_queue_;
   int64 video_first_pts_;
   bool video_first_pts_set_;
+  base::TimeDelta last_video_frame_timestamp_;
 
   std::queue<AudioBus*> audio_bus_queue_;
 
diff --git a/media/cast/test/simulator.cc b/media/cast/test/simulator.cc
index cccc571a..61084386 100644
--- a/media/cast/test/simulator.cc
+++ b/media/cast/test/simulator.cc
@@ -14,6 +14,14 @@
 // --target-delay-ms=
 //   Target playout delay to configure (integer number of milliseconds).
 //   Optional; default is 400.
+// --max-frame-rate=
+//   The maximum frame rate allowed at any time during the Cast session.
+//   Optional; default is 30.
+// --source-frame-rate=
+//   Overrides the playback rate; the source video will play faster/slower.
+// --run-time=
+//   In seconds, how long the Cast session runs for.
+//   Optional; default is 180.
 //
 // Output:
 // - Raw event log of the simulation session tagged with the unique test ID,
@@ -75,16 +83,19 @@
 const char kSimulationId[] = "sim-id";
 const char kLibDir[] = "lib-dir";
 const char kTargetDelay[] = "target-delay-ms";
+const char kMaxFrameRate[] = "max-frame-rate";
+const char kSourceFrameRate[] = "source-frame-rate";
+const char kRunTime[] = "run-time";
 
-base::TimeDelta GetTargetPlayoutDelay() {
-  const std::string delay_str =
-      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kTargetDelay);
-  if (delay_str.empty())
-    return base::TimeDelta::FromMilliseconds(400);
-  int delay_ms;
-  CHECK(base::StringToInt(delay_str, &delay_ms));
-  CHECK_GT(delay_ms, 0);
-  return base::TimeDelta::FromMilliseconds(delay_ms);
+int GetIntegerSwitchValue(const char* switch_name, int default_value) {
+  const std::string as_str =
+      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name);
+  if (as_str.empty())
+    return default_value;
+  int as_int;
+  CHECK(base::StringToInt(as_str, &as_int));
+  CHECK_GT(as_int, 0);
+  return as_int;
 }
 
 void UpdateCastTransportStatus(CastTransportStatus status) {
@@ -234,7 +245,9 @@
 
   // Audio sender config.
   AudioSenderConfig audio_sender_config = GetDefaultAudioSenderConfig();
-  audio_sender_config.max_playout_delay = GetTargetPlayoutDelay();
+  audio_sender_config.min_playout_delay =
+      audio_sender_config.max_playout_delay = base::TimeDelta::FromMilliseconds(
+          GetIntegerSwitchValue(kTargetDelay, 400));
 
   // Audio receiver config.
   FrameReceiverConfig audio_receiver_config =
@@ -247,7 +260,10 @@
   video_sender_config.max_bitrate = 2500000;
   video_sender_config.min_bitrate = 2000000;
   video_sender_config.start_bitrate = 2000000;
-  video_sender_config.max_playout_delay = GetTargetPlayoutDelay();
+  video_sender_config.min_playout_delay =
+      video_sender_config.max_playout_delay =
+          audio_sender_config.max_playout_delay;
+  video_sender_config.max_frame_rate = GetIntegerSwitchValue(kMaxFrameRate, 30);
 
   // Video receiver config.
   FrameReceiverConfig video_receiver_config =
@@ -329,14 +345,17 @@
   // Start sending.
   if (!source_path.empty()) {
     // 0 means using the FPS from the file.
-    media_source.SetSourceFile(source_path, 0);
+    media_source.SetSourceFile(source_path,
+                               GetIntegerSwitchValue(kSourceFrameRate, 0));
   }
   media_source.Start(cast_sender->audio_frame_input(),
                      cast_sender->video_frame_input());
 
   // Run for 3 minutes.
   base::TimeDelta elapsed_time;
-  while (elapsed_time.InMinutes() < 3) {
+  const base::TimeDelta desired_run_time =
+      base::TimeDelta::FromSeconds(GetIntegerSwitchValue(kRunTime, 180));
+  while (elapsed_time < desired_run_time) {
     // Each step is 100us.
     base::TimeDelta step = base::TimeDelta::FromMicroseconds(100);
     task_runner->Sleep(step);
@@ -388,10 +407,15 @@
     }
   }
 
-  double avg_encoded_bitrate =
-      !encoded_video_frames ? 0 :
-      8.0 * encoded_size * video_sender_config.max_frame_rate /
-      encoded_video_frames / 1000;
+  // Subtract fraction of dropped frames from |elapsed_time| before estimating
+  // the average encoded bitrate.
+  const base::TimeDelta elapsed_time_undropped =
+      total_video_frames <= 0 ? base::TimeDelta() :
+      (elapsed_time * (total_video_frames - dropped_video_frames) /
+           total_video_frames);
+  const double avg_encoded_bitrate =
+      elapsed_time_undropped <= base::TimeDelta() ? 0 :
+      8.0 * encoded_size / elapsed_time_undropped.InSecondsF() / 1000;
   double avg_target_bitrate =
       !encoded_video_frames ? 0 : target_bitrate / encoded_video_frames / 1000;
 
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
index 84a6a314..7b6db1b 100644
--- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
+++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -700,6 +700,10 @@
 
 void ClearKeyCdm::OnSessionKeysChange(const std::string& web_session_id,
                                       bool has_additional_usable_key) {
+  // Ignore the message when we are waiting to update the loadable session.
+  if (web_session_id == session_id_for_emulated_loadsession_)
+    return;
+
   host_->OnSessionUsableKeysChange(web_session_id.data(),
                                    web_session_id.length(),
                                    has_additional_usable_key);
@@ -749,6 +753,9 @@
     // |promise_id| is the LoadSession() promise, so resolve appropriately.
     host_->OnResolveNewSessionPromise(
         promise_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId));
+    // Generate the UsableKeys event now that the session is "loaded".
+    host_->OnSessionUsableKeysChange(
+        kLoadableWebSessionId, strlen(kLoadableWebSessionId), true);
     return;
   }
 
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index 5a536998..f61e3af 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -155,13 +155,18 @@
 }
 
 base::TimeDelta AudioRendererImpl::CurrentMediaTime() {
-  DVLOG(2) << __FUNCTION__;
-
   // In practice the Render() method is called with a high enough frequency
   // that returning only the front timestamp is good enough and also prevents
   // returning values that go backwards in time.
-  base::AutoLock auto_lock(lock_);
-  return audio_clock_->front_timestamp();
+  base::TimeDelta current_media_time;
+  {
+    base::AutoLock auto_lock(lock_);
+    current_media_time = audio_clock_->front_timestamp();
+  }
+
+  DVLOG(3) << __FUNCTION__ << ": " << current_media_time.InMilliseconds()
+           << " ms";
+  return current_media_time;
 }
 
 base::TimeDelta AudioRendererImpl::CurrentMediaTimeForSyncingVideo() {
@@ -254,6 +259,7 @@
                                    const BufferingStateCB& buffering_state_cb,
                                    const base::Closure& ended_cb,
                                    const PipelineStatusCB& error_cb) {
+  DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(stream);
   DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
@@ -318,6 +324,7 @@
 }
 
 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
+  DVLOG(1) << __FUNCTION__ << ": " << success;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   base::AutoLock auto_lock(lock_);
@@ -329,6 +336,8 @@
   }
 
   if (!audio_parameters_.IsValid()) {
+    DVLOG(1) << __FUNCTION__ << ": Invalid audio parameters: "
+             << audio_parameters_.AsHumanReadableString();
     ChangeState_Locked(kUninitialized);
     base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
     return;
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
index 8f2deaf9..5a98619 100644
--- a/media/filters/decoder_stream.cc
+++ b/media/filters/decoder_stream.cc
@@ -217,7 +217,9 @@
 void DecoderStream<StreamType>::OnDecoderSelected(
     scoped_ptr<Decoder> selected_decoder,
     scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
-  FUNCTION_DVLOG(2);
+  FUNCTION_DVLOG(2) << ": "
+                    << (selected_decoder ? selected_decoder->GetDisplayName()
+                                         : "No decoder selected.");
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
   DCHECK(!init_cb_.is_null());
@@ -290,7 +292,7 @@
 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size,
                                              bool end_of_stream,
                                              typename Decoder::Status status) {
-  FUNCTION_DVLOG(2) << status;
+  FUNCTION_DVLOG(2) << ": " << status;
   DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
          state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
       << state_;
diff --git a/media/media.gyp b/media/media.gyp
index afc2758..f3b2817 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -121,6 +121,8 @@
         'audio/audio_output_proxy.h',
         'audio/audio_output_resampler.cc',
         'audio/audio_output_resampler.h',
+        'audio/audio_output_stream_sink.cc',
+        'audio/audio_output_stream_sink.h',
         'audio/audio_power_monitor.cc',
         'audio/audio_power_monitor.h',
         'audio/audio_source_diverter.h',
@@ -261,6 +263,8 @@
         'base/cdm_promise.h',
         'base/channel_mixer.cc',
         'base/channel_mixer.h',
+        'base/channel_mixing_matrix.cc',
+        'base/channel_mixing_matrix.h',
         'base/container_names.cc',
         'base/container_names.h',
         'base/data_buffer.cc',
@@ -283,6 +287,9 @@
         'base/demuxer_stream_provider.h',
         'base/djb2.cc',
         'base/djb2.h',
+        'base/eme_constants.h',
+        'base/key_system_info.cc',
+        'base/key_system_info.h',
         'base/keyboard_event_counter.cc',
         'base/keyboard_event_counter.h',
         'base/mac/avfoundation_glue.h',
@@ -1070,7 +1077,7 @@
       ],
     },
     {
-      'target_name': 'media_mojo_renderer_app',
+      'target_name': 'mojo_media_renderer_app',
       'type': 'loadable_module',
       'includes': [
         '../mojo/mojo_variables.gypi',
@@ -1107,7 +1114,7 @@
       ],
     },
     {
-      'target_name': 'media_mojo_renderer_apptest',
+      'target_name': 'mojo_media_renderer_apptest',
       'type': 'loadable_module',
       'includes': [
         '../mojo/mojo_variables.gypi',
@@ -1116,8 +1123,8 @@
         'media',
         'media_mojo_bindings',
         'media_mojo_lib',
-        'media_mojo_renderer_app',
         'media_test_support',
+        'mojo_media_renderer_app',
         '../base/base.gyp:base',
         '../base/base.gyp:test_support_base',
         '../testing/gtest.gyp:gtest',
@@ -1134,8 +1141,8 @@
       'dependencies': [
         'media_mojo_lib',
         'media_mojo_lib_unittests',
-        'media_mojo_renderer_app',
-        'media_mojo_renderer_apptest',
+        'mojo_media_renderer_apptest',
+        'mojo_media_renderer_app',
       ]
     },
     {
@@ -1213,6 +1220,7 @@
         'base/callback_holder.h',
         'base/callback_holder_unittest.cc',
         'base/channel_mixer_unittest.cc',
+        'base/channel_mixing_matrix_unittest.cc',
         'base/container_names_unittest.cc',
         'base/data_buffer_unittest.cc',
         'base/decoder_buffer_queue_unittest.cc',
@@ -1813,7 +1821,7 @@
           'type': 'none',
           'dependencies': [
             '../base/base.gyp:base',
-            'media_android_imageformat_list',
+            'media_android_imageformat',
           ],
           'export_dependent_settings': [
             '../base/base.gyp:base',
@@ -1824,17 +1832,13 @@
           'includes': ['../build/java.gypi'],
         },
         {
-          # GN: //media/base/android:media_android_imageformat_list
-          'target_name': 'media_android_imageformat_list',
+          # GN: //media/base/android:media_android_imageformat
+          'target_name': 'media_android_imageformat',
           'type': 'none',
-          'sources': [
-            'base/android/java/src/org/chromium/media/AndroidImageFormat.template',
-          ],
           'variables': {
-            'package_name': 'org/chromium/media',
-            'template_deps': ['video/capture/android/imageformat_list.h'],
+            'source_file': 'video/capture/android/video_capture_device_android.h',
           },
-          'includes': [ '../build/android/java_cpp_template.gypi' ],
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
       ],
     }],
diff --git a/media/media_options.gni b/media/media_options.gni
index dfc653b..c2b4709 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -3,9 +3,6 @@
 # found in the LICENSE file.
 
 declare_args() {
-  # Enables proprietary codecs and demuxers; e.g. H264, MOV, AAC, and MP3.
-  proprietary_codecs = false
-
   # Allows distributions to link pulseaudio directly (DT_NEEDED) instead of
   # using dlopen. This helps with automated detection of ABI mismatches and
   # prevents silent errors.
diff --git a/media/midi/midi_manager.cc b/media/midi/midi_manager.cc
index c53eef4..d0eb50f 100644
--- a/media/midi/midi_manager.cc
+++ b/media/midi/midi_manager.cc
@@ -26,7 +26,7 @@
 }
 #endif
 
-void MidiManager::StartSession(MidiManagerClient* client, int client_id) {
+void MidiManager::StartSession(MidiManagerClient* client) {
   bool session_is_ready;
   bool session_needs_initialization = false;
   bool too_many_pending_clients_exist = false;
@@ -34,6 +34,12 @@
   {
     base::AutoLock auto_lock(lock_);
     session_is_ready = initialized_;
+    if (clients_.find(client) != clients_.end() ||
+        pending_clients_.find(client) != pending_clients_.end()) {
+      // Should not happen. But just in case the renderer is compromised.
+      NOTREACHED();
+      return;
+    }
     if (!session_is_ready) {
       // Do not accept a new request if the pending client list contains too
       // many clients.
@@ -43,7 +49,7 @@
       if (!too_many_pending_clients_exist) {
         // Call StartInitialization() only for the first request.
         session_needs_initialization = pending_clients_.empty();
-        pending_clients_.insert(std::make_pair(client, client_id));
+        pending_clients_.insert(client);
       }
     }
   }
@@ -58,7 +64,7 @@
     }
     if (too_many_pending_clients_exist) {
       // Return an error immediately if there are too many requests.
-      client->CompleteStartSession(client_id, MIDI_INITIALIZATION_ERROR);
+      client->CompleteStartSession(MIDI_INITIALIZATION_ERROR);
       return;
     }
     // CompleteInitialization() will be called asynchronously when platform
@@ -71,14 +77,18 @@
   MidiResult result;
   {
     base::AutoLock auto_lock(lock_);
-    if (result_ == MIDI_OK)
+    if (result_ == MIDI_OK) {
+      AddInitialPorts(client);
       clients_.insert(client);
+    }
     result = result_;
   }
-  client->CompleteStartSession(client_id, result);
+  client->CompleteStartSession(result);
 }
 
 void MidiManager::EndSession(MidiManagerClient* client) {
+  // At this point, |client| can be in the destruction process, and calling
+  // any method of |client| is dangerous.
   base::AutoLock auto_lock(lock_);
   clients_.erase(client);
   pending_clients_.erase(client);
@@ -107,11 +117,17 @@
 }
 
 void MidiManager::AddInputPort(const MidiPortInfo& info) {
+  base::AutoLock auto_lock(lock_);
   input_ports_.push_back(info);
+  for (auto client : clients_)
+    client->AddInputPort(info);
 }
 
 void MidiManager::AddOutputPort(const MidiPortInfo& info) {
+  base::AutoLock auto_lock(lock_);
   output_ports_.push_back(info);
+  for (auto client : clients_)
+    client->AddOutputPort(info);
 }
 
 void MidiManager::ReceiveMidiData(
@@ -121,8 +137,8 @@
     double timestamp) {
   base::AutoLock auto_lock(lock_);
 
-  for (ClientList::iterator i = clients_.begin(); i != clients_.end(); ++i)
-    (*i)->ReceiveMidiData(port_index, data, length, timestamp);
+  for (auto client : clients_)
+    client->ReceiveMidiData(port_index, data, length, timestamp);
 }
 
 void MidiManager::CompleteInitializationInternal(MidiResult result) {
@@ -134,14 +150,23 @@
   initialized_ = true;
   result_ = result;
 
-  for (PendingClientMap::iterator it = pending_clients_.begin();
-       it != pending_clients_.end();
-       ++it) {
-    if (result_ == MIDI_OK)
-      clients_.insert(it->first);
-    it->first->CompleteStartSession(it->second, result_);
+  for (auto client : pending_clients_) {
+    if (result_ == MIDI_OK) {
+      AddInitialPorts(client);
+      clients_.insert(client);
+    }
+    client->CompleteStartSession(result_);
   }
   pending_clients_.clear();
 }
 
+void MidiManager::AddInitialPorts(MidiManagerClient* client) {
+  lock_.AssertAcquired();
+
+  for (const auto& info : input_ports_)
+    client->AddInputPort(info);
+  for (const auto& info : output_ports_)
+    client->AddOutputPort(info);
+}
+
 }  // namespace media
diff --git a/media/midi/midi_manager.h b/media/midi/midi_manager.h
index 9fd7a21..d7e7e47 100644
--- a/media/midi/midi_manager.h
+++ b/media/midi/midi_manager.h
@@ -5,7 +5,6 @@
 #ifndef MEDIA_MIDI_MIDI_MANAGER_H_
 #define MEDIA_MIDI_MIDI_MANAGER_H_
 
-#include <map>
 #include <set>
 #include <vector>
 
@@ -30,9 +29,20 @@
  public:
   virtual ~MidiManagerClient() {}
 
+  // AddInputPort() and AddOutputPort() are called before CompleteStartSession()
+  // is called to notify existing MIDI ports, and also called after that to
+  // notify new MIDI ports are added.
+  virtual void AddInputPort(const MidiPortInfo& info) = 0;
+  virtual void AddOutputPort(const MidiPortInfo& info) = 0;
+
+  // TODO(toyoshim): DisableInputPort(const MidiPortInfo& info) and
+  // DisableOutputPort(const MidiPortInfo& info) should be added.
+  // On DisableInputPort(), internal states, e.g. received_messages_queues in
+  // MidiHost, should be reset.
+
   // CompleteStartSession() is called when platform dependent preparation is
   // finished.
-  virtual void CompleteStartSession(int client_id, MidiResult result) = 0;
+  virtual void CompleteStartSession(MidiResult result) = 0;
 
   // ReceiveMidiData() is called when MIDI data has been received from the
   // MIDI system.
@@ -71,7 +81,7 @@
   // Otherwise CompleteStartSession() is called with proper MidiResult code.
   // StartSession() and EndSession() can be called on the Chrome_IOThread.
   // CompleteStartSession() will be invoked on the same Chrome_IOThread.
-  void StartSession(MidiManagerClient* client, int client_id);
+  void StartSession(MidiManagerClient* client);
 
   // A client calls EndSession() to stop receiving MIDI data.
   void EndSession(MidiManagerClient* client);
@@ -90,16 +100,6 @@
                                     const std::vector<uint8>& data,
                                     double timestamp);
 
-  // input_ports() is a list of MIDI ports for receiving MIDI data.
-  // Each individual port in this list can be identified by its
-  // integer index into this list.
-  const MidiPortInfoList& input_ports() const { return input_ports_; }
-
-  // output_ports() is a list of MIDI ports for sending MIDI data.
-  // Each individual port in this list can be identified by its
-  // integer index into this list.
-  const MidiPortInfoList& output_ports() const { return output_ports_; }
-
  protected:
   friend class MidiManagerUsb;
 
@@ -146,14 +146,14 @@
 
  private:
   void CompleteInitializationInternal(MidiResult result);
+  void AddInitialPorts(MidiManagerClient* client);
 
   // Keeps track of all clients who wish to receive MIDI data.
-  typedef std::set<MidiManagerClient*> ClientList;
-  ClientList clients_;
+  typedef std::set<MidiManagerClient*> ClientSet;
+  ClientSet clients_;
 
   // Keeps track of all clients who are waiting for CompleteStartSession().
-  typedef std::multimap<MidiManagerClient*, int> PendingClientMap;
-  PendingClientMap pending_clients_;
+  ClientSet pending_clients_;
 
   // Keeps a SingleThreadTaskRunner of the thread that calls StartSession in
   // order to invoke CompleteStartSession() on the thread.
@@ -166,13 +166,14 @@
   // completed. Otherwise keeps MIDI_NOT_SUPPORTED.
   MidiResult result_;
 
-  // Protects access to |clients_|, |pending_clients_|, |initialized_|, and
-  // |result_|.
-  base::Lock lock_;
-
+  // Keeps all MidiPortInfo.
   MidiPortInfoList input_ports_;
   MidiPortInfoList output_ports_;
 
+  // Protects access to |clients_|, |pending_clients_|, |initialized_|,
+  // |result_|, |input_ports_| and |output_ports_|.
+  base::Lock lock_;
+
   DISALLOW_COPY_AND_ASSIGN(MidiManager);
 };
 
diff --git a/media/midi/midi_manager_unittest.cc b/media/midi/midi_manager_unittest.cc
index 846e1bcf..8662adb5 100644
--- a/media/midi/midi_manager_unittest.cc
+++ b/media/midi/midi_manager_unittest.cc
@@ -54,16 +54,17 @@
 
 class FakeMidiManagerClient : public MidiManagerClient {
  public:
-  explicit FakeMidiManagerClient(int client_id)
-      : client_id_(client_id),
-        result_(MIDI_NOT_SUPPORTED),
+  FakeMidiManagerClient()
+      : result_(MIDI_NOT_SUPPORTED),
         wait_for_result_(true) {}
   ~FakeMidiManagerClient() override {}
 
   // MidiManagerClient implementation.
-  void CompleteStartSession(int client_id, MidiResult result) override {
+  void AddInputPort(const MidiPortInfo& info) override {}
+  void AddOutputPort(const MidiPortInfo& info) override {}
+
+  void CompleteStartSession(MidiResult result) override {
     EXPECT_TRUE(wait_for_result_);
-    CHECK_EQ(client_id_, client_id);
     result_ = result;
     wait_for_result_ = false;
   }
@@ -74,7 +75,6 @@
                        double timestamp) override {}
   void AccumulateMidiBytesSent(size_t size) override {}
 
-  int client_id() const { return client_id_; }
   MidiResult result() const { return result_; }
 
   MidiResult WaitForResult() {
@@ -86,7 +86,6 @@
   }
 
  private:
-  int client_id_;
   MidiResult result_;
   bool wait_for_result_;
 
@@ -105,7 +104,7 @@
     EXPECT_FALSE(manager_->start_initialization_is_called_);
     EXPECT_EQ(0U, manager_->GetClientCount());
     EXPECT_EQ(0U, manager_->GetPendingClientCount());
-    manager_->StartSession(client, client->client_id());
+    manager_->StartSession(client);
     EXPECT_EQ(0U, manager_->GetClientCount());
     EXPECT_EQ(1U, manager_->GetPendingClientCount());
     EXPECT_TRUE(manager_->start_initialization_is_called_);
@@ -122,7 +121,7 @@
     // StartInitialization() should not be called for the second and later
     // sessions.
     manager_->start_initialization_is_called_ = false;
-    manager_->StartSession(client, client->client_id());
+    manager_->StartSession(client);
     EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_);
     manager_->start_initialization_is_called_ = true;
   }
@@ -153,7 +152,7 @@
 
 TEST_F(MidiManagerTest, StartAndEndSession) {
   scoped_ptr<FakeMidiManagerClient> client;
-  client.reset(new FakeMidiManagerClient(0));
+  client.reset(new FakeMidiManagerClient);
 
   StartTheFirstSession(client.get());
   CompleteInitialization(MIDI_OK);
@@ -163,7 +162,7 @@
 
 TEST_F(MidiManagerTest, StartAndEndSessionWithError) {
   scoped_ptr<FakeMidiManagerClient> client;
-  client.reset(new FakeMidiManagerClient(1));
+  client.reset(new FakeMidiManagerClient);
 
   StartTheFirstSession(client.get());
   CompleteInitialization(MIDI_INITIALIZATION_ERROR);
@@ -175,9 +174,9 @@
   scoped_ptr<FakeMidiManagerClient> client1;
   scoped_ptr<FakeMidiManagerClient> client2;
   scoped_ptr<FakeMidiManagerClient> client3;
-  client1.reset(new FakeMidiManagerClient(0));
-  client2.reset(new FakeMidiManagerClient(1));
-  client3.reset(new FakeMidiManagerClient(1));
+  client1.reset(new FakeMidiManagerClient);
+  client2.reset(new FakeMidiManagerClient);
+  client3.reset(new FakeMidiManagerClient);
 
   StartTheFirstSession(client1.get());
   StartTheNthSession(client2.get(), 2);
@@ -199,16 +198,15 @@
   ScopedVector<FakeMidiManagerClient> many_existing_clients;
   many_existing_clients.resize(MidiManager::kMaxPendingClientCount);
   for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) {
-    many_existing_clients[i] = new FakeMidiManagerClient(i);
+    many_existing_clients[i] = new FakeMidiManagerClient;
     StartTheNthSession(many_existing_clients[i], i + 1);
   }
 
   // Push the last client that should be rejected for too many pending requests.
   scoped_ptr<FakeMidiManagerClient> additional_client(
-      new FakeMidiManagerClient(MidiManager::kMaxPendingClientCount));
+      new FakeMidiManagerClient);
   manager_->start_initialization_is_called_ = false;
-  manager_->StartSession(additional_client.get(),
-                         additional_client->client_id());
+  manager_->StartSession(additional_client.get());
   EXPECT_FALSE(manager_->start_initialization_is_called_);
   EXPECT_EQ(MIDI_INITIALIZATION_ERROR, additional_client->result());
 
@@ -232,7 +230,7 @@
   // A client starting a session can be destructed while an asynchronous
   // initialization is performed.
   scoped_ptr<FakeMidiManagerClient> client;
-  client.reset(new FakeMidiManagerClient(0));
+  client.reset(new FakeMidiManagerClient);
 
   StartTheFirstSession(client.get());
   EndSession(client.get(), 0, 0);
@@ -246,10 +244,10 @@
 
 TEST_F(MidiManagerTest, CreateMidiManager) {
   scoped_ptr<FakeMidiManagerClient> client;
-  client.reset(new FakeMidiManagerClient(0));
+  client.reset(new FakeMidiManagerClient);
 
   scoped_ptr<MidiManager> manager(MidiManager::Create());
-  manager->StartSession(client.get(), client->client_id());
+  manager->StartSession(client.get());
 
   MidiResult result = client->WaitForResult();
   // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc.
diff --git a/media/midi/midi_manager_usb_unittest.cc b/media/midi/midi_manager_usb_unittest.cc
index b4f939f..5fbaa1b 100644
--- a/media/midi/midi_manager_usb_unittest.cc
+++ b/media/midi/midi_manager_usb_unittest.cc
@@ -78,7 +78,15 @@
         logger_(logger) {}
   ~FakeMidiManagerClient() override {}
 
-  void CompleteStartSession(int client_id, MidiResult result) override {
+  void AddInputPort(const MidiPortInfo& info) override {
+    input_ports_.push_back(info);
+  }
+
+  void AddOutputPort(const MidiPortInfo& info) override {
+    output_ports_.push_back(info);
+  }
+
+  void CompleteStartSession(MidiResult result) override {
     complete_start_session_ = true;
     result_ = result;
   }
@@ -103,6 +111,8 @@
 
   bool complete_start_session_;
   MidiResult result_;
+  MidiPortInfoList input_ports_;
+  MidiPortInfoList output_ports_;
 
  private:
   Logger* logger_;
@@ -159,7 +169,7 @@
  protected:
   void Initialize() {
     client_.reset(new FakeMidiManagerClient(&logger_));
-    manager_->StartSession(client_.get(), 0);
+    manager_->StartSession(client_.get());
   }
 
   void Finalize() {
@@ -183,6 +193,9 @@
     }
   }
 
+  const MidiPortInfoList& input_ports() { return client_->input_ports_; }
+  const MidiPortInfoList& output_ports() { return client_->output_ports_; }
+
   scoped_ptr<MidiManagerUsbForTesting> manager_;
   scoped_ptr<FakeMidiManagerClient> client_;
   // Owned by manager_.
@@ -223,8 +236,8 @@
   RunCallbackUntilCallbackInvoked(true, &devices);
   EXPECT_EQ(MIDI_OK, GetInitializationResult());
 
-  ASSERT_EQ(1u, manager_->input_ports().size());
-  ASSERT_EQ(2u, manager_->output_ports().size());
+  ASSERT_EQ(1u, input_ports().size());
+  ASSERT_EQ(2u, output_ports().size());
   ASSERT_TRUE(manager_->input_stream());
   std::vector<UsbMidiInputStream::JackUniqueKey> keys =
       manager_->input_stream()->RegisteredJackKeysForTesting();
diff --git a/media/midi/midi_manager_win.cc b/media/midi/midi_manager_win.cc
index 54a1db873..439ce93 100644
--- a/media/midi/midi_manager_win.cc
+++ b/media/midi/midi_manager_win.cc
@@ -499,6 +499,7 @@
 void MidiManagerWin::StartInitialization() {
   const UINT num_in_devices = midiInGetNumDevs();
   in_devices_.reserve(num_in_devices);
+  int inport_index = 0;
   for (UINT device_id = 0; device_id < num_in_devices; ++device_id) {
     MIDIINCAPS caps = {};
     MMRESULT result = midiInGetDevCaps(device_id, &caps, sizeof(caps));
@@ -516,7 +517,7 @@
         base::WideToUTF8(caps.szPname),
         base::IntToString(static_cast<int>(caps.vDriverVersion)));
     AddInputPort(info);
-    in_device->set_port_index(input_ports().size() - 1);
+    in_device->set_port_index(inport_index++);
     in_devices_.push_back(in_device.Pass());
   }
 
@@ -548,8 +549,8 @@
 MidiManagerWin::~MidiManagerWin() {
   // Cleanup order is important. |send_thread_| must be stopped before
   // |out_devices_| is cleared.
-  for (size_t i = 0; i < output_ports().size(); ++i)
-    out_devices_[i]->Quit();
+  for (auto& device : out_devices_)
+    device->Quit();
   send_thread_.Stop();
 
   out_devices_.clear();
diff --git a/media/midi/midi_result.h b/media/midi/midi_result.h
index 1e10401..2fb58a4 100644
--- a/media/midi/midi_result.h
+++ b/media/midi/midi_result.h
@@ -9,7 +9,8 @@
 
 // Result codes for MIDI.
 enum MidiResult {
-  MIDI_OK,
+  MIDI_NOT_INITIALIZED = -1,
+  MIDI_OK = 0,
   MIDI_NOT_SUPPORTED,
   MIDI_INITIALIZATION_ERROR,
 
diff --git a/media/mojo/interfaces/media_types.mojom b/media/mojo/interfaces/media_types.mojom
index ec1eb9c..edaf282 100644
--- a/media/mojo/interfaces/media_types.mojom
+++ b/media/mojo/interfaces/media_types.mojom
@@ -107,7 +107,7 @@
 
   // This is backed by an std::vector and results in a few copies.
   // Into the vector, onto and off the MessagePipe, back into a vector.
-  array<uint8> side_data;
+  array<uint8>? side_data;
   uint32 side_data_size;
 
   // These fields indicate the amount of data to discard after decoding.
@@ -117,11 +117,11 @@
   // Indicates this buffer is part of a splice around |splice_timestamp_usec|.
   int64 splice_timestamp_usec;
 
-  // The payload.
+  // The payload. Invalid handle indicates an end-of-stream (EOS) buffer.
   // TODO(tim): This currently results in allocating a new, largeish DataPipe
   // for each buffer. Remove this once framed data pipes exist, but using this
   // for now for prototyping audio.
-  handle<data_pipe_consumer> data;
+  handle<data_pipe_consumer>? data;
 };
 
 }  // module mojo
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn
index 304c6c14..d13e66f 100644
--- a/media/mojo/services/BUILD.gn
+++ b/media/mojo/services/BUILD.gn
@@ -43,9 +43,9 @@
 }
 
 # mojo media::Renderer application.
-# GYP version: media/media.gyp:media_mojo_renderer_app
+# GYP version: media/media.gyp:mojo_media_renderer_app
 shared_library("renderer_app") {
-  output_name = "media_mojo_renderer_app"
+  output_name = "mojo_media_renderer_app"
 
   deps = [
     "//base",
@@ -66,7 +66,7 @@
   ]
 }
 
-test("media_mojo_lib_unittests") {
+test("mojo_media_lib_unittests") {
   sources = [
     "media_type_converters_unittest.cc",
   ]
@@ -84,11 +84,11 @@
   ]
 }
 
-# GYP version: media/media.gyp:media_mojo_renderer_apptest
+# GYP version: media/media.gyp:mojo_media_renderer_apptest
 # Not a 'test' because this is loaded via mojo_shell as an app.
 shared_library("renderer_apptest") {
   testonly = true
-  output_name = "media_mojo_renderer_apptest"
+  output_name = "mojo_media_renderer_apptest"
 
   deps = [
     "//base",
@@ -121,7 +121,7 @@
 group("tests") {
   testonly = true
   deps = [
-    ":media_mojo_lib_unittests",
+    ":mojo_media_lib_unittests",
     ":renderer_apptest",
   ]
 }
diff --git a/media/mojo/services/media_type_converters.cc b/media/mojo/services/media_type_converters.cc
index 2a39b53..07404f7 100644
--- a/media/mojo/services/media_type_converters.cc
+++ b/media/mojo/services/media_type_converters.cc
@@ -129,6 +129,11 @@
     scoped_refptr<media::DecoderBuffer> >::Convert(
         const scoped_refptr<media::DecoderBuffer>& input) {
   MediaDecoderBufferPtr mojo_buffer(MediaDecoderBuffer::New());
+  DCHECK(!mojo_buffer->data.is_valid());
+
+  if (input->end_of_stream())
+    return mojo_buffer.Pass();
+
   mojo_buffer->timestamp_usec = input->timestamp().InMicroseconds();
   mojo_buffer->duration_usec = input->duration().InMicroseconds();
   mojo_buffer->data_size = input->data_size();
@@ -169,6 +174,9 @@
 scoped_refptr<media::DecoderBuffer>  TypeConverter<
     scoped_refptr<media::DecoderBuffer>, MediaDecoderBufferPtr>::Convert(
         const MediaDecoderBufferPtr& input) {
+  if (!input->data.is_valid())
+    return media::DecoderBuffer::CreateEOSBuffer();
+
   uint32_t num_bytes  = 0;
   // TODO(tim): We're assuming that because we always write to the pipe above
   // before sending the MediaDecoderBuffer that the pipe is readable when
@@ -233,16 +241,17 @@
 TypeConverter<media::AudioDecoderConfig, AudioDecoderConfigPtr>::Convert(
     const AudioDecoderConfigPtr& input) {
   media::AudioDecoderConfig config;
-  config.Initialize(static_cast<media::AudioCodec>(input->codec),
-                    static_cast<media::SampleFormat>(input->sample_format),
-                    static_cast<media::ChannelLayout>(input->channel_layout),
-                    input->samples_per_second,
-                    &input->extra_data.front(),
-                    input->extra_data.size(),
-                    false,
-                    false,
-                    base::TimeDelta::FromMicroseconds(input->seek_preroll_usec),
-                    input->codec_delay);
+  config.Initialize(
+      static_cast<media::AudioCodec>(input->codec),
+      static_cast<media::SampleFormat>(input->sample_format),
+      static_cast<media::ChannelLayout>(input->channel_layout),
+      input->samples_per_second,
+      input->extra_data.size() ? &input->extra_data.front() : NULL,
+      input->extra_data.size(),
+      false,
+      false,
+      base::TimeDelta::FromMicroseconds(input->seek_preroll_usec),
+      input->codec_delay);
   return config;
 }
 
diff --git a/media/mojo/services/media_type_converters_unittest.cc b/media/mojo/services/media_type_converters_unittest.cc
index 29049b6..1bf9b85 100644
--- a/media/mojo/services/media_type_converters_unittest.cc
+++ b/media/mojo/services/media_type_converters_unittest.cc
@@ -13,7 +13,7 @@
 namespace mojo {
 namespace test {
 
-TEST(MediaTypeConvertersTest, ConvertDecoderBuffer) {
+TEST(MediaTypeConvertersTest, ConvertDecoderBuffer_Normal) {
   const uint8 kData[] = "hello, world";
   const uint8 kSideData[] = "sideshow bob";
   const int kDataSize = arraysize(kData);
@@ -32,7 +32,7 @@
 
   // Convert from and back.
   MediaDecoderBufferPtr ptr(MediaDecoderBuffer::From(buffer));
-  scoped_refptr<DecoderBuffer> result(ptr.To<scoped_refptr<DecoderBuffer> >());
+  scoped_refptr<DecoderBuffer> result(ptr.To<scoped_refptr<DecoderBuffer>>());
 
   // Compare.
   EXPECT_EQ(kDataSize, result->data_size());
@@ -45,9 +45,21 @@
   EXPECT_EQ(buffer->discard_padding(), result->discard_padding());
 }
 
-// TODO(tim): Handle EOS, check other properties.
+TEST(MediaTypeConvertersTest, ConvertDecoderBuffer_EOS) {
+  // Original.
+  scoped_refptr<DecoderBuffer> buffer(DecoderBuffer::CreateEOSBuffer());
 
-TEST(MediaTypeConvertersTest, ConvertAudioDecoderConfig) {
+  // Convert from and back.
+  MediaDecoderBufferPtr ptr(MediaDecoderBuffer::From(buffer));
+  scoped_refptr<DecoderBuffer> result(ptr.To<scoped_refptr<DecoderBuffer>>());
+
+  // Compare.
+  EXPECT_TRUE(result->end_of_stream());
+}
+
+// TODO(tim): Check other properties.
+
+TEST(MediaTypeConvertersTest, ConvertAudioDecoderConfig_Normal) {
   const uint8 kExtraData[] = "config extra data";
   const int kExtraDataSize = arraysize(kExtraData);
   media::AudioDecoderConfig config;
@@ -66,5 +78,22 @@
   EXPECT_TRUE(result.Matches(config));
 }
 
+TEST(MediaTypeConvertersTest, ConvertAudioDecoderConfig_NullExtraData) {
+  media::AudioDecoderConfig config;
+  config.Initialize(media::kCodecAAC,
+                    media::kSampleFormatU8,
+                    media::CHANNEL_LAYOUT_SURROUND,
+                    48000,
+                    NULL,
+                    0,
+                    false,
+                    false,
+                    base::TimeDelta(),
+                    0);
+  AudioDecoderConfigPtr ptr(AudioDecoderConfig::From(config));
+  media::AudioDecoderConfig result(ptr.To<media::AudioDecoderConfig>());
+  EXPECT_TRUE(result.Matches(config));
+}
+
 }  // namespace test
 }  // namespace mojo
diff --git a/media/mojo/services/mojo_demuxer_stream_adapter.cc b/media/mojo/services/mojo_demuxer_stream_adapter.cc
index fd70732..5b60177 100644
--- a/media/mojo/services/mojo_demuxer_stream_adapter.cc
+++ b/media/mojo/services/mojo_demuxer_stream_adapter.cc
@@ -17,13 +17,16 @@
     : demuxer_stream_(demuxer_stream.Pass()),
       stream_ready_cb_(stream_ready_cb),
       weak_factory_(this) {
+  DVLOG(1) << __FUNCTION__;
   demuxer_stream_.set_client(this);
 }
 
 MojoDemuxerStreamAdapter::~MojoDemuxerStreamAdapter() {
+  DVLOG(1) << __FUNCTION__;
 }
 
 void MojoDemuxerStreamAdapter::Read(const DemuxerStream::ReadCB& read_cb) {
+  DVLOG(3) << __FUNCTION__;
   // We shouldn't be holding on to a previous callback if a new Read() came in.
   DCHECK(read_cb_.is_null());
   read_cb_ = read_cb;
@@ -60,6 +63,7 @@
 
 void MojoDemuxerStreamAdapter::OnStreamReady(
     mojo::ScopedDataPipeConsumerHandle pipe) {
+  DVLOG(1) << __FUNCTION__;
   // TODO(tim): We don't support pipe streaming yet.
   DCHECK(!pipe.is_valid());
   DCHECK(!config_queue_.empty());
@@ -79,6 +83,7 @@
 void MojoDemuxerStreamAdapter::OnBufferReady(
     mojo::DemuxerStream::Status status,
     mojo::MediaDecoderBufferPtr buffer) {
+  DVLOG(3) << __FUNCTION__;
   DCHECK(!read_cb_.is_null());
   DCHECK(!config_queue_.empty());
 
diff --git a/media/mojo/services/mojo_renderer_impl.cc b/media/mojo/services/mojo_renderer_impl.cc
index 1ecd93b..48d28e0 100644
--- a/media/mojo/services/mojo_renderer_impl.cc
+++ b/media/mojo/services/mojo_renderer_impl.cc
@@ -6,7 +6,9 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/location.h"
 #include "base/single_thread_task_runner.h"
+#include "media/base/bind_to_current_loop.h"
 #include "media/base/demuxer_stream_provider.h"
 #include "media/mojo/services/mojo_demuxer_stream_impl.h"
 #include "mojo/public/cpp/application/connect.h"
@@ -20,6 +22,7 @@
     mojo::ServiceProvider* audio_renderer_provider)
     : task_runner_(task_runner),
       weak_factory_(this) {
+  DVLOG(1) << __FUNCTION__;
   // For now we only support audio and there must be a provider.
   DCHECK(audio_renderer_provider);
   mojo::ConnectToService(audio_renderer_provider, &remote_audio_renderer_);
@@ -27,6 +30,7 @@
 }
 
 MojoRendererImpl::~MojoRendererImpl() {
+  DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   // Connection to |remote_audio_renderer_| will error-out here.
 }
@@ -38,10 +42,12 @@
     const base::Closure& ended_cb,
     const PipelineStatusCB& error_cb,
     const BufferingStateCB& buffering_state_cb) {
+  DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(demuxer_stream_provider);
 
   demuxer_stream_provider_ = demuxer_stream_provider;
+  // |init_cb| can be called on other thread.
   init_cb_ = init_cb;
   ended_cb_ = ended_cb;
   error_cb_ = error_cb;
@@ -53,67 +59,121 @@
       new MojoDemuxerStreamImpl(
           demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO)),
       &demuxer_stream);
-  remote_audio_renderer_->Initialize(demuxer_stream.Pass(), init_cb);
+  remote_audio_renderer_->Initialize(
+      demuxer_stream.Pass(),
+      BindToCurrentLoop(base::Bind(&MojoRendererImpl::OnInitialized,
+                                   weak_factory_.GetWeakPtr())));
 }
 
 void MojoRendererImpl::Flush(const base::Closure& flush_cb) {
+  DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   remote_audio_renderer_->Flush(flush_cb);
 }
 
 void MojoRendererImpl::StartPlayingFrom(base::TimeDelta time) {
+  DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
+
+  {
+    base::AutoLock auto_lock(lock_);
+    time_ = time;
+  }
+
   remote_audio_renderer_->StartPlayingFrom(time.InMicroseconds());
 }
 
 void MojoRendererImpl::SetPlaybackRate(float playback_rate) {
+  DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   remote_audio_renderer_->SetPlaybackRate(playback_rate);
 }
 
 void MojoRendererImpl::SetVolume(float volume) {
+  DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   remote_audio_renderer_->SetVolume(volume);
 }
 
 base::TimeDelta MojoRendererImpl::GetMediaTime() {
-  NOTIMPLEMENTED();
-  return base::TimeDelta();
+  base::AutoLock auto_lock(lock_);
+  DVLOG(3) << __FUNCTION__ << ": " << time_.InMilliseconds() << " ms";
+  return time_;
 }
 
 bool MojoRendererImpl::HasAudio() {
+  DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(remote_audio_renderer_.get());  // We always bind the renderer.
   return true;
 }
 
 bool MojoRendererImpl::HasVideo() {
+  DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   return false;
 }
 
 void MojoRendererImpl::SetCdm(MediaKeys* cdm) {
+  DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   NOTIMPLEMENTED();
 }
 
 void MojoRendererImpl::OnTimeUpdate(int64_t time_usec, int64_t max_time_usec) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  NOTIMPLEMENTED();
+  DVLOG(3) << __FUNCTION__ << ": " << time_usec << ", " << max_time_usec;
+
+  if (!task_runner_->BelongsToCurrentThread()) {
+    task_runner_->PostTask(FROM_HERE,
+                           base::Bind(&MojoRendererImpl::OnTimeUpdate,
+                                      weak_factory_.GetWeakPtr(),
+                                      time_usec,
+                                      max_time_usec));
+    return;
+  }
+
+  base::AutoLock auto_lock(lock_);
+  time_ = base::TimeDelta::FromMicroseconds(time_usec);
+  max_time_ = base::TimeDelta::FromMicroseconds(max_time_usec);
 }
 
 void MojoRendererImpl::OnBufferingStateChange(mojo::BufferingState state) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DVLOG(2) << __FUNCTION__;
+
+  if (!task_runner_->BelongsToCurrentThread()) {
+    task_runner_->PostTask(FROM_HERE,
+                           base::Bind(&MojoRendererImpl::OnBufferingStateChange,
+                                      weak_factory_.GetWeakPtr(),
+                                      state));
+    return;
+  }
+
   buffering_state_cb_.Run(static_cast<media::BufferingState>(state));
 }
 
 void MojoRendererImpl::OnEnded() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  ended_cb_.Run();
+  DVLOG(1) << __FUNCTION__;
+
+  if (!task_runner_->BelongsToCurrentThread()) {
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&MojoRendererImpl::OnEnded, weak_factory_.GetWeakPtr()));
+    return;
+  }
+
+  base::ResetAndReturn(&ended_cb_).Run();
 }
 
 void MojoRendererImpl::OnError() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DVLOG(1) << __FUNCTION__;
+
+  if (!task_runner_->BelongsToCurrentThread()) {
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&MojoRendererImpl::OnError, weak_factory_.GetWeakPtr()));
+    return;
+  }
+
   // TODO(tim): Should we plumb error code from remote renderer?
   // http://crbug.com/410451.
   if (init_cb_.is_null())  // We have initialized already.
@@ -123,7 +183,10 @@
 }
 
 void MojoRendererImpl::OnInitialized() {
+  DVLOG(1) << __FUNCTION__;
+  DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(!init_cb_.is_null());
+
   base::ResetAndReturn(&init_cb_).Run();
 }
 
diff --git a/media/mojo/services/mojo_renderer_impl.h b/media/mojo/services/mojo_renderer_impl.h
index f70bb99..24a319b 100644
--- a/media/mojo/services/mojo_renderer_impl.h
+++ b/media/mojo/services/mojo_renderer_impl.h
@@ -78,7 +78,15 @@
   PipelineStatusCB error_cb_;
   BufferingStateCB buffering_state_cb_;
 
+  // Lock used to serialize access for the following data members.
+  mutable base::Lock lock_;
+
+  base::TimeDelta time_;
+  // TODO(xhwang): It seems we don't need |max_time_| now. Drop it!
+  base::TimeDelta max_time_;
+
   base::WeakPtrFactory<MojoRendererImpl> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(MojoRendererImpl);
 };
 
diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc
index 2f1625c..f1a1ac8 100644
--- a/media/mojo/services/mojo_renderer_service.cc
+++ b/media/mojo/services/mojo_renderer_service.cc
@@ -5,7 +5,10 @@
 #include "media/mojo/services/mojo_renderer_service.h"
 
 #include "base/bind.h"
+#include "base/callback_helpers.h"
 #include "base/memory/scoped_vector.h"
+#include "media/audio/audio_manager.h"
+#include "media/audio/audio_manager_base.h"
 #include "media/audio/null_audio_sink.h"
 #include "media/base/audio_decoder.h"
 #include "media/base/audio_renderer.h"
@@ -13,6 +16,8 @@
 #include "media/base/decryptor.h"
 #include "media/base/media_log.h"
 #include "media/filters/audio_renderer_impl.h"
+#include "media/filters/ffmpeg_audio_decoder.h"
+#include "media/filters/opus_audio_decoder.h"
 #include "media/mojo/services/mojo_demuxer_stream_adapter.h"
 #include "mojo/application/application_runner_chromium.h"
 #include "mojo/public/c/system/main.h"
@@ -22,6 +27,20 @@
 
 namespace media {
 
+// Time interval to update media time.
+const int kTimeUpdateIntervalMs = 50;
+
+#if !defined(OS_ANDROID)
+static void LogMediaSourceError(const scoped_refptr<MediaLog>& media_log,
+                                const std::string& error) {
+  media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error));
+}
+#endif
+
+static base::TimeDelta TimeUpdateInterval() {
+  return base::TimeDelta::FromMilliseconds(kTimeUpdateIntervalMs);
+}
+
 class MojoRendererApplication
     : public mojo::ApplicationDelegate,
       public mojo::InterfaceFactory<mojo::MediaRenderer> {
@@ -40,25 +59,54 @@
   }
 };
 
+// TODO(xhwang): This class looks insanely similar to RendererImpl. We should
+// really host a Renderer in this class instead of a AudioRenderer.
+
 MojoRendererService::MojoRendererService(
     mojo::ApplicationConnection* connection)
-    : hardware_config_(AudioParameters(), AudioParameters()),
+    : state_(STATE_UNINITIALIZED),
+      time_source_(NULL),
+      time_ticking_(false),
+      ended_(false),
+      // AudioManager() has been created by WebMediaPlayerFactory. This will
+      // be problematic when MojoRendererService really runs in a separate
+      // process.
+      // TODO(xhwang/dalecurtis): Figure out what config we should use.
+      audio_manager_(
+          media::AudioManager::Get()
+              ? media::AudioManager::Get()
+              : media::AudioManager::Create(&fake_audio_log_factory_)),
+      audio_hardware_config_(
+          audio_manager_->GetInputStreamParameters(
+              media::AudioManagerBase::kDefaultDeviceId),
+          audio_manager_->GetDefaultOutputStreamParameters()),
       weak_factory_(this),
       weak_this_(weak_factory_.GetWeakPtr()) {
+  DVLOG(1) << __FUNCTION__;
+
   scoped_refptr<base::SingleThreadTaskRunner> runner(
       base::MessageLoop::current()->task_runner());
   scoped_refptr<MediaLog> media_log(new MediaLog());
+
+  // TODO(xhwang): Provide a more general way to add new decoders.
+  ScopedVector<AudioDecoder> audio_decoders;
+
+#if !defined(OS_ANDROID)
+  audio_decoders.push_back(new media::FFmpegAudioDecoder(
+      runner, base::Bind(&LogMediaSourceError, media_log)));
+  audio_decoders.push_back(new media::OpusAudioDecoder(runner));
+#endif
+
   audio_renderer_.reset(new AudioRendererImpl(
       runner,
       // TODO(tim): We should use |connection| passed to MojoRendererService
       // to connect to a MojoAudioRendererSink implementation that we would
       // wrap in an AudioRendererSink and pass in here.
       new NullAudioSink(runner),
-      // TODO(tim): Figure out how to select decoders.
-      ScopedVector<AudioDecoder>(),
+      audio_decoders.Pass(),
       // TODO(tim): Not needed for now?
       SetDecryptorReadyCB(),
-      hardware_config_,
+      audio_hardware_config_,
       media_log));
 }
 
@@ -67,30 +115,53 @@
 
 void MojoRendererService::Initialize(mojo::DemuxerStreamPtr stream,
                                      const mojo::Callback<void()>& callback) {
+  DVLOG(1) << __FUNCTION__;
+  DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_;
   DCHECK(client());
+
+  init_cb_ = callback;
+  state_ = STATE_INITIALIZING;
   stream_.reset(new MojoDemuxerStreamAdapter(
       stream.Pass(),
       base::Bind(&MojoRendererService::OnStreamReady, weak_this_)));
-  init_cb_ = callback;
 }
 
 void MojoRendererService::Flush(const mojo::Callback<void()>& callback) {
+  DVLOG(2) << __FUNCTION__;
+  DCHECK_EQ(state_, STATE_PLAYING) << state_;
+
+  state_ = STATE_FLUSHING;
+  if (time_ticking_)
+    PausePlayback();
+
+  // TODO(xhwang): This is not completed. Finish the flushing path.
   NOTIMPLEMENTED();
 }
 
 void MojoRendererService::StartPlayingFrom(int64_t time_delta_usec) {
-  NOTIMPLEMENTED();
+  DVLOG(2) << __FUNCTION__ << ": " << time_delta_usec;
+  base::TimeDelta time = base::TimeDelta::FromMicroseconds(time_delta_usec);
+  time_source_->SetMediaTime(time);
+  audio_renderer_->StartPlaying();
 }
 
 void MojoRendererService::SetPlaybackRate(float playback_rate) {
-  NOTIMPLEMENTED();
+  DVLOG(2) << __FUNCTION__ << ": " << playback_rate;
+
+  // Playback rate changes are only carried out while playing.
+  if (state_ != STATE_PLAYING)
+    return;
+
+  time_source_->SetPlaybackRate(playback_rate);
 }
 
 void MojoRendererService::SetVolume(float volume) {
-  NOTIMPLEMENTED();
+  if (audio_renderer_)
+    audio_renderer_->SetVolume(volume);
 }
 
 void MojoRendererService::OnStreamReady() {
+  DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
   audio_renderer_->Initialize(
       stream_.get(),
       base::Bind(&MojoRendererService::OnAudioRendererInitializeDone,
@@ -102,29 +173,81 @@
 }
 
 void MojoRendererService::OnAudioRendererInitializeDone(PipelineStatus status) {
+  DVLOG(1) << __FUNCTION__ << ": " << status;
+  DCHECK_EQ(state_, STATE_INITIALIZING) << state_;
+
   if (status != PIPELINE_OK) {
+    state_ = STATE_ERROR;
     audio_renderer_.reset();
     client()->OnError();
+    init_cb_.Run();
+    init_cb_.reset();
+    return;
   }
+
+  time_source_ = audio_renderer_->GetTimeSource();
+
+  state_ = STATE_PLAYING;
   init_cb_.Run();
+  init_cb_.reset();
 }
 
 void MojoRendererService::OnUpdateStatistics(const PipelineStatistics& stats) {
   NOTIMPLEMENTED();
 }
 
-void MojoRendererService::OnAudioTimeUpdate(base::TimeDelta time,
-                                            base::TimeDelta max_time) {
-  client()->OnTimeUpdate(time.InMicroseconds(), max_time.InMicroseconds());
+void MojoRendererService::UpdateMediaTime() {
+  uint64_t media_time = time_source_->CurrentMediaTime().InMicroseconds();
+  client()->OnTimeUpdate(media_time, media_time);
+}
+
+void MojoRendererService::SchedulePeriodicMediaTimeUpdates() {
+  // Update media time immediately.
+  UpdateMediaTime();
+
+  // Then setup periodic time update.
+  time_update_timer_.Start(
+      FROM_HERE,
+      TimeUpdateInterval(),
+      base::Bind(&MojoRendererService::UpdateMediaTime, weak_this_));
 }
 
 void MojoRendererService::OnBufferingStateChanged(
     media::BufferingState new_buffering_state) {
-  client()->OnBufferingStateChange(
-      static_cast<mojo::BufferingState>(new_buffering_state));
+  DVLOG(2) << __FUNCTION__ << "(" << buffering_state_ << ", "
+           << new_buffering_state << ") ";
+  bool was_waiting_for_enough_data = WaitingForEnoughData();
+
+  buffering_state_ = new_buffering_state;
+
+  // Renderer underflowed.
+  if (!was_waiting_for_enough_data && WaitingForEnoughData()) {
+    PausePlayback();
+    // TODO(xhwang): Notify client of underflow condition.
+    return;
+  }
+
+  // Renderer prerolled.
+  if (was_waiting_for_enough_data && !WaitingForEnoughData()) {
+    StartPlayback();
+    client()->OnBufferingStateChange(
+        static_cast<mojo::BufferingState>(new_buffering_state));
+    return;
+  }
 }
 
 void MojoRendererService::OnAudioRendererEnded() {
+  DVLOG(1) << __FUNCTION__;
+
+  if (state_ != STATE_PLAYING)
+    return;
+
+  DCHECK(!ended_);
+  ended_ = true;
+
+  if (time_ticking_)
+    PausePlayback();
+
   client()->OnEnded();
 }
 
@@ -132,6 +255,52 @@
   client()->OnError();
 }
 
+bool MojoRendererService::WaitingForEnoughData() const {
+  DCHECK(audio_renderer_);
+
+  return state_ == STATE_PLAYING && buffering_state_ != BUFFERING_HAVE_ENOUGH;
+}
+
+void MojoRendererService::StartPlayback() {
+  DVLOG(1) << __FUNCTION__;
+  DCHECK_EQ(state_, STATE_PLAYING);
+  DCHECK(!time_ticking_);
+  DCHECK(!WaitingForEnoughData());
+
+  time_ticking_ = true;
+  time_source_->StartTicking();
+
+  SchedulePeriodicMediaTimeUpdates();
+}
+
+void MojoRendererService::PausePlayback() {
+  DVLOG(1) << __FUNCTION__;
+  DCHECK(time_ticking_);
+  switch (state_) {
+    case STATE_PLAYING:
+      DCHECK(ended_ || WaitingForEnoughData())
+          << "Playback should only pause due to ending or underflowing";
+      break;
+
+    case STATE_FLUSHING:
+      // It's OK to pause playback when flushing.
+      break;
+
+    case STATE_UNINITIALIZED:
+    case STATE_INITIALIZING:
+    case STATE_ERROR:
+      NOTREACHED() << "Invalid state: " << state_;
+      break;
+  }
+
+  time_ticking_ = false;
+  time_source_->StopTicking();
+
+  // Cancel repeating time update timer and update the current media time.
+  time_update_timer_.Stop();
+  UpdateMediaTime();
+}
+
 }  // namespace media
 
 MojoResult MojoMain(MojoHandle shell_handle) {
diff --git a/media/mojo/services/mojo_renderer_service.h b/media/mojo/services/mojo_renderer_service.h
index 75726b96..e1f2cfd 100644
--- a/media/mojo/services/mojo_renderer_service.h
+++ b/media/mojo/services/mojo_renderer_service.h
@@ -9,6 +9,8 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/timer/timer.h"
+#include "media/audio/fake_audio_log_factory.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/audio_hardware_config.h"
 #include "media/base/buffering_state.h"
@@ -22,8 +24,10 @@
 
 namespace media {
 
+class AudioManager;
 class AudioRenderer;
 class MojoDemuxerStreamAdapter;
+class TimeSource;
 
 // A mojo::MediaRenderer implementation that uses media::AudioRenderer to
 // decode and render audio to a sink obtained from the ApplicationConnection.
@@ -45,6 +49,14 @@
   void SetVolume(float volume) override;
 
  private:
+  enum State {
+    STATE_UNINITIALIZED,
+    STATE_INITIALIZING,
+    STATE_FLUSHING,
+    STATE_PLAYING,
+    STATE_ERROR
+  };
+
   // Called when the MojoDemuxerStreamAdapter is ready to go (has a config,
   // pipe handle, etc) and can be handed off to a renderer for use.
   void OnStreamReady();
@@ -55,8 +67,8 @@
   // Callback executed by filters to update statistics.
   void OnUpdateStatistics(const PipelineStatistics& stats);
 
-  // Callback executed by audio renderer to update clock time.
-  void OnAudioTimeUpdate(base::TimeDelta time, base::TimeDelta max_time);
+  void UpdateMediaTime();
+  void SchedulePeriodicMediaTimeUpdates();
 
   // Callback executed by audio renderer when buffering state changes.
   // TODO(tim): Need old and new.
@@ -68,19 +80,35 @@
   // Callback executed when a runtime error happens.
   void OnError(PipelineStatus error);
 
+  bool WaitingForEnoughData() const;
+  void StartPlayback();
+  void PausePlayback();
+
+  State state_;
+
   scoped_ptr<MojoDemuxerStreamAdapter> stream_;
   scoped_ptr<AudioRenderer> audio_renderer_;
 
+  TimeSource* time_source_;
+  bool time_ticking_;
+
+  BufferingState buffering_state_;
+
   mojo::Callback<void()> init_cb_;
 
-  // TODO(tim): Figure out how to set up hardware config.
-  // NOTE: AudioRendererImpl stores a const& to the config we pass in (hmm..).
-  // Hence stack-allocating one and passing it to Initialize results in
-  // undefined badness (e.g, hangs trying to acquire config_lock_);
-  media::AudioHardwareConfig hardware_config_;
+  bool ended_;
+
+  base::RepeatingTimer<MojoRendererService> time_update_timer_;
+
+  // TODO(xhwang): Currently we are using a default |audio_hardware_config_|.
+  // Do we need different configs on different platforms?
+  media::FakeAudioLogFactory fake_audio_log_factory_;
+  scoped_ptr<media::AudioManager> audio_manager_;
+  media::AudioHardwareConfig audio_hardware_config_;
 
   base::WeakPtrFactory<MojoRendererService> weak_factory_;
   base::WeakPtr<MojoRendererService> weak_this_;
+
   DISALLOW_COPY_AND_ASSIGN(MojoRendererService);
 };
 
diff --git a/media/test/data/eme_player_js/player_utils.js b/media/test/data/eme_player_js/player_utils.js
index 5f524ba..634cc31 100644
--- a/media/test/data/eme_player_js/player_utils.js
+++ b/media/test/data/eme_player_js/player_utils.js
@@ -53,26 +53,23 @@
       });
     }
 
-    Utils.timeLog('Creating new media key session for initDataType: ' +
-                  message.initDataType + ', initData: ' +
-                  Utils.getHexString(new Uint8Array(message.initData)));
     try {
-      if (message.target.mediaKeys.createSession.length == 0) {
-        // FIXME(jrummell): Remove this test (and else branch) once blink
-        // uses the new API.
+      if (player.testConfig.sessionToLoad) {
+        Utils.timeLog('Loading session: ' + player.testConfig.sessionToLoad);
+        var session = message.target.mediaKeys.createSession('persistent');
+        addMediaKeySessionListeners(session);
+        session.load(player.testConfig.sessionToLoad)
+            .catch(function(error) { Utils.failTest(error, KEY_ERROR); });
+      } else {
+        Utils.timeLog('Creating new media key session for initDataType: ' +
+                      message.initDataType + ', initData: ' +
+                      Utils.getHexString(new Uint8Array(message.initData)));
         var session = message.target.mediaKeys.createSession();
         addMediaKeySessionListeners(session);
         session.generateRequest(message.initDataType, message.initData)
           .catch(function(error) {
             Utils.failTest(error, KEY_ERROR);
           });
-      } else {
-        var session = message.target.mediaKeys.createSession(
-            message.initDataType, message.initData);
-        session.then(addMediaKeySessionListeners)
-            .catch(function(error) {
-              Utils.failTest(error, KEY_ERROR);
-            });
       }
     } catch (e) {
       Utils.failTest(e);
diff --git a/media/test/data/eme_player_js/test_config.js b/media/test/data/eme_player_js/test_config.js
index 8be8a9ad..6484eb54 100644
--- a/media/test/data/eme_player_js/test_config.js
+++ b/media/test/data/eme_player_js/test_config.js
@@ -28,6 +28,15 @@
   this.useMSE = this.useMSE == '1' || this.useMSE == 'true';
   this.usePrefixedEME =
       this.usePrefixedEME == '1' || this.usePrefixedEME == 'true';
+
+  // Validate that the prefixed/unprefixed EME is available.
+  if (this.usePrefixedEME) {
+    if (EME_DISABLED_OPTIONS.indexOf(EME_PREFIXED_VERSION) >= 0)
+      Utils.failTest('Prefixed EME not available.')
+  } else {
+    if (EME_DISABLED_OPTIONS.indexOf(EME_UNPREFIXED_VERSION) >= 0)
+      Utils.failTest('Unprefixed EME not available.')
+  }
 };
 
 TestConfig.updateDocument = function() {
diff --git a/media/video/capture/OWNERS b/media/video/capture/OWNERS
index efee8804..4e965f77 100644
--- a/media/video/capture/OWNERS
+++ b/media/video/capture/OWNERS
@@ -1,8 +1,2 @@
 perkj@chromium.org
 tommi@chromium.org
-
-# Android OWNERS, applying to files under android/
-per-file *android.*=mcasas@chromium.org
-
-# Mac OWNERS, applying to files under mac/
-per-file *mac.*=mcasas@chromium.org
diff --git a/media/video/capture/android/OWNERS b/media/video/capture/android/OWNERS
new file mode 100644
index 0000000..ad80981
--- /dev/null
+++ b/media/video/capture/android/OWNERS
@@ -0,0 +1 @@
+mcasas@chromium.org
diff --git a/media/video/capture/android/video_capture_device_android.cc b/media/video/capture/android/video_capture_device_android.cc
index 3817e53..836153d 100644
--- a/media/video/capture/android/video_capture_device_android.cc
+++ b/media/video/capture/android/video_capture_device_android.cc
@@ -179,11 +179,11 @@
   int current_capture_colorspace =
       Java_VideoCapture_getColorspace(env, j_capture_.obj());
   switch (current_capture_colorspace) {
-    case ANDROID_IMAGEFORMAT_YV12:
+    case ANDROID_IMAGE_FORMAT_YV12:
       return media::PIXEL_FORMAT_YV12;
-    case ANDROID_IMAGEFORMAT_NV21:
+    case ANDROID_IMAGE_FORMAT_NV21:
       return media::PIXEL_FORMAT_NV21;
-    case ANDROID_IMAGEFORMAT_UNKNOWN:
+    case ANDROID_IMAGE_FORMAT_UNKNOWN:
     default:
       return media::PIXEL_FORMAT_UNKNOWN;
   }
diff --git a/media/video/capture/android/video_capture_device_android.h b/media/video/capture/android/video_capture_device_android.h
index f3a2e93..e4defa1 100644
--- a/media/video/capture/android/video_capture_device_android.h
+++ b/media/video/capture/android/video_capture_device_android.h
@@ -24,10 +24,15 @@
 class MEDIA_EXPORT VideoCaptureDeviceAndroid : public VideoCaptureDevice {
  public:
   // Automatically generated enum to interface with Java world.
+  //
+  // A Java counterpart will be generated for this enum.
+  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media
   enum AndroidImageFormat {
-#define DEFINE_ANDROID_IMAGEFORMAT(name, value) name = value,
-#include "media/video/capture/android/imageformat_list.h"
-#undef DEFINE_ANDROID_IMAGEFORMAT
+    // Android graphics ImageFormat mapping, see reference in:
+    // http://developer.android.com/reference/android/graphics/ImageFormat.html
+    ANDROID_IMAGE_FORMAT_NV21 = 17,
+    ANDROID_IMAGE_FORMAT_YV12 = 842094169,
+    ANDROID_IMAGE_FORMAT_UNKNOWN = 0,
   };
 
   explicit VideoCaptureDeviceAndroid(const Name& device_name);
diff --git a/media/video/capture/android/video_capture_device_factory_android.cc b/media/video/capture/android/video_capture_device_factory_android.cc
index 38a72c89..010c1949 100644
--- a/media/video/capture/android/video_capture_device_factory_android.cc
+++ b/media/video/capture/android/video_capture_device_factory_android.cc
@@ -65,11 +65,14 @@
     return;
 
   for (int camera_id = num_cameras - 1; camera_id >= 0; --camera_id) {
+    base::android::ScopedJavaLocalRef<jstring> device_name =
+        Java_VideoCaptureFactory_getDeviceName(env, camera_id);
+    if (device_name.obj() == NULL)
+      continue;
+
     VideoCaptureDevice::Name name(
-        base::android::ConvertJavaStringToUTF8(
-            Java_VideoCaptureFactory_getDeviceName(env, camera_id)),
-        base::android::ConvertJavaStringToUTF8(
-            Java_VideoCaptureFactory_getDeviceId(env, camera_id)));
+        base::android::ConvertJavaStringToUTF8(device_name),
+        base::IntToString(camera_id));
     device_names->push_back(name);
 
     DVLOG(1) << "VideoCaptureDeviceFactoryAndroid::GetDeviceNames: camera "
@@ -98,10 +101,10 @@
     VideoPixelFormat pixel_format = media::PIXEL_FORMAT_UNKNOWN;
     switch (media::Java_VideoCaptureFactory_getCaptureFormatPixelFormat(
         env, format.obj())) {
-      case ANDROID_IMAGEFORMAT_YV12:
+      case VideoCaptureDeviceAndroid::ANDROID_IMAGE_FORMAT_YV12:
         pixel_format = media::PIXEL_FORMAT_YV12;
         break;
-      case ANDROID_IMAGEFORMAT_NV21:
+      case VideoCaptureDeviceAndroid::ANDROID_IMAGE_FORMAT_NV21:
         pixel_format = media::PIXEL_FORMAT_NV21;
         break;
       default:
diff --git a/media/video/capture/android/video_capture_device_factory_android.h b/media/video/capture/android/video_capture_device_factory_android.h
index 415b8022..4ea4ad5 100644
--- a/media/video/capture/android/video_capture_device_factory_android.h
+++ b/media/video/capture/android/video_capture_device_factory_android.h
@@ -19,12 +19,6 @@
 class MEDIA_EXPORT VideoCaptureDeviceFactoryAndroid :
   public VideoCaptureDeviceFactory {
  public:
-  // Automatically generated enum to interface with Java world.
-  enum AndroidImageFormat {
-#define DEFINE_ANDROID_IMAGEFORMAT(name, value) name = value,
-#include "media/video/capture/android/imageformat_list.h"
-#undef DEFINE_ANDROID_IMAGEFORMAT
-  };
   static bool RegisterVideoCaptureDeviceFactory(JNIEnv* env);
   static base::android::ScopedJavaLocalRef<jobject> createVideoCaptureAndroid(
       int id,
diff --git a/media/video/capture/mac/OWNERS b/media/video/capture/mac/OWNERS
new file mode 100644
index 0000000..ad80981
--- /dev/null
+++ b/media/video/capture/mac/OWNERS
@@ -0,0 +1 @@
+mcasas@chromium.org
diff --git a/media/video/capture/video_capture_device.cc b/media/video/capture/video_capture_device.cc
index 3b74417..dc62fc9 100644
--- a/media/video/capture/video_capture_device.cc
+++ b/media/video/capture/video_capture_device.cc
@@ -57,6 +57,36 @@
 
 VideoCaptureDevice::Name::~Name() {}
 
+#if defined(OS_WIN)
+const char* VideoCaptureDevice::Name::GetCaptureApiTypeString() const {
+  switch(capture_api_type()) {
+    case MEDIA_FOUNDATION:
+      return "Media Foundation";
+    case DIRECT_SHOW:
+      return "Direct Show";
+    case DIRECT_SHOW_WDM_CROSSBAR:
+      return "Direct Show WDM Crossbar";
+    default:
+      NOTREACHED() << "Unknown Video Capture API type!";
+      return "Unknown API";
+  }
+}
+#elif defined(OS_MACOSX)
+const char* VideoCaptureDevice::Name::GetCaptureApiTypeString() const {
+  switch(capture_api_type()) {
+    case AVFOUNDATION:
+      return "AV Foundation";
+    case QTKIT:
+      return "QTKit";
+    case DECKLINK:
+      return "DeckLink";
+    default:
+      NOTREACHED() << "Unknown Video Capture API type!";
+      return "Unknown API";
+  }
+}
+#endif
+
 VideoCaptureDevice::~VideoCaptureDevice() {}
 
 int VideoCaptureDevice::GetPowerLineFrequencyForLocation() const {
diff --git a/media/video/capture/video_capture_device.h b/media/video/capture/video_capture_device.h
index 187145f..455dc83 100644
--- a/media/video/capture/video_capture_device.h
+++ b/media/video/capture/video_capture_device.h
@@ -106,6 +106,7 @@
     CaptureApiType capture_api_type() const {
       return capture_api_class_.capture_api_type();
     }
+    const char* GetCaptureApiTypeString() const;
 #endif
 #if defined(OS_WIN)
     // Certain devices need an ID different from the |unique_id_| for
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn
index 8f58fc1..1f36443 100644
--- a/mojo/BUILD.gn
+++ b/mojo/BUILD.gn
@@ -7,9 +7,6 @@
 group("mojo") {
   # Meta-target, don't link into production code.
   testonly = true
-  declare_args() {
-    mojo_use_go = false
-  }
   deps = [
     ":tests",
     "//mojo/apps/js:mojo_js_content_handler",
@@ -27,17 +24,6 @@
       "//mojo/android",
     ]
   }
-
-  if (is_linux) {
-    deps += [
-      "//mojo/python",
-    ]
-    if (mojo_use_go) {
-      deps += [
-        "//mojo/go",
-      ]
-    }
-  }
 }
 
 group("tests") {
@@ -65,8 +51,6 @@
   if (use_aura) {
     deps += [
       "//mojo/services/public/cpp/view_manager/tests:mojo_view_manager_lib_unittests",
-      "//mojo/services/view_manager:mojo_view_manager_unittests",
-      "//mojo/services/window_manager:mojo_core_window_manager_unittests",
     ]
   }
 }
diff --git a/mojo/OWNERS b/mojo/OWNERS
index b864087..cd7230f 100644
--- a/mojo/OWNERS
+++ b/mojo/OWNERS
@@ -1,11 +1,6 @@
-aa@chromium.org
-abarth@chromium.org
+# This subdirectory is being canonically developed in the mojo repository,
+# please land changes there or they will be blown away by the next sync.
+# See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nAwEbgCrUio/73AA2fnfcpEJ
+# for more details.
 ben@chromium.org
-darin@chromium.org
-davemoore@chromium.org
 jamesr@chromium.org
-mpcomplete@chromium.org
-qsr@chromium.org
-sky@chromium.org
-viettrungluu@chromium.org
-yzshen@chromium.org
diff --git a/mojo/PRESUBMIT.py b/mojo/PRESUBMIT.py
index 41a8ec6e..2766055 100644
--- a/mojo/PRESUBMIT.py
+++ b/mojo/PRESUBMIT.py
@@ -22,9 +22,6 @@
   # For the python bindings:
   mojo_python_bindings_path = os.path.join(
       input_api.PresubmitLocalPath(), "public", "python")
-  # For the python bindings tests:
-  mojo_python_bindings_tests_path = os.path.join(
-      input_api.PresubmitLocalPath(), "python", "tests")
   # TODO(vtl): Don't lint these files until the (many) problems are fixed
   # (possibly by deleting/rewriting some files).
   temporary_black_list = input_api.DEFAULT_BLACK_LIST + \
@@ -40,7 +37,6 @@
       third_party_path,
       mojo_public_bindings_pylib_path,
       mojo_python_bindings_path,
-      mojo_python_bindings_tests_path,
   ]
   results += input_api.canned_checks.RunPylint(
       input_api, output_api, extra_paths_list=pylint_extra_paths,
diff --git a/mojo/android/javatests/AndroidManifest.xml b/mojo/android/javatests/AndroidManifest.xml
index 290a1de..1b0a9073 100644
--- a/mojo/android/javatests/AndroidManifest.xml
+++ b/mojo/android/javatests/AndroidManifest.xml
@@ -12,7 +12,7 @@
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.mojo.tests"
         android:label="Tests for org.chromium.mojo"/>
diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java
index 8bf5e21..3734a7e4 100644
--- a/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java
+++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/ValidationTest.java
@@ -7,6 +7,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.mojo.HandleMock;
 import org.chromium.mojo.MojoTestCase;
@@ -176,8 +177,9 @@
 
     /**
      * Testing the conformance suite.
+     * Disabled: http://crbug.com/426564
      */
-    @SmallTest
+    @DisabledTest
     public void testConformance() throws FileNotFoundException {
         runTest("conformance_", ConformanceTestInterface.MANAGER.buildStub(null,
                 ConformanceTestInterface.MANAGER.buildProxy(null, new SinkMessageReceiver())));
diff --git a/mojo/aura/screen_mojo.cc b/mojo/aura/screen_mojo.cc
index b07c320..098df39 100644
--- a/mojo/aura/screen_mojo.cc
+++ b/mojo/aura/screen_mojo.cc
@@ -17,11 +17,6 @@
 ScreenMojo::~ScreenMojo() {
 }
 
-bool ScreenMojo::IsDIPEnabled() {
-  NOTIMPLEMENTED();
-  return true;
-}
-
 gfx::Point ScreenMojo::GetCursorScreenPoint() {
   NOTIMPLEMENTED();
   return gfx::Point();
diff --git a/mojo/aura/screen_mojo.h b/mojo/aura/screen_mojo.h
index 184ccff5..b825f9e 100644
--- a/mojo/aura/screen_mojo.h
+++ b/mojo/aura/screen_mojo.h
@@ -20,26 +20,21 @@
 class ScreenMojo : public gfx::Screen {
  public:
   static ScreenMojo* Create();
-  virtual ~ScreenMojo();
+  ~ScreenMojo() override;
 
  protected:
   // gfx::Screen overrides:
-  virtual bool IsDIPEnabled() override;
-  virtual gfx::Point GetCursorScreenPoint() override;
-  virtual gfx::NativeWindow GetWindowUnderCursor() override;
-  virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point)
-      override;
-  virtual int GetNumDisplays() const override;
-  virtual std::vector<gfx::Display> GetAllDisplays() const override;
-  virtual gfx::Display GetDisplayNearestWindow(
-      gfx::NativeView view) const override;
-  virtual gfx::Display GetDisplayNearestPoint(
-      const gfx::Point& point) const override;
-  virtual gfx::Display GetDisplayMatching(
-      const gfx::Rect& match_rect) const override;
-  virtual gfx::Display GetPrimaryDisplay() const override;
-  virtual void AddObserver(gfx::DisplayObserver* observer) override;
-  virtual void RemoveObserver(gfx::DisplayObserver* observer) override;
+  gfx::Point GetCursorScreenPoint() override;
+  gfx::NativeWindow GetWindowUnderCursor() override;
+  gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
+  int GetNumDisplays() const override;
+  std::vector<gfx::Display> GetAllDisplays() const override;
+  gfx::Display GetDisplayNearestWindow(gfx::NativeView view) const override;
+  gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const override;
+  gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
+  gfx::Display GetPrimaryDisplay() const override;
+  void AddObserver(gfx::DisplayObserver* observer) override;
+  void RemoveObserver(gfx::DisplayObserver* observer) override;
 
  private:
   explicit ScreenMojo(const gfx::Rect& screen_bounds);
diff --git a/mojo/aura/surface_binding.cc b/mojo/aura/surface_binding.cc
index fc1d31a..8c1da68 100644
--- a/mojo/aura/surface_binding.cc
+++ b/mojo/aura/surface_binding.cc
@@ -35,10 +35,10 @@
 class SurfaceClientImpl : public SurfaceClient {
  public:
   SurfaceClientImpl() {}
-  virtual ~SurfaceClientImpl() {}
+  ~SurfaceClientImpl() override {}
 
   // SurfaceClient:
-  virtual void ReturnResources(Array<ReturnedResourcePtr> resources) override {
+  void ReturnResources(Array<ReturnedResourcePtr> resources) override {
     // TODO (sky|jamesr): figure out right way to recycle resources.
   }
 
@@ -56,10 +56,10 @@
                     const scoped_refptr<cc::ContextProvider>& context_provider,
                     Surface* surface,
                     cc::SurfaceIdAllocator* id_allocator);
-  virtual ~OutputSurfaceImpl();
+  ~OutputSurfaceImpl() override;
 
   // cc::OutputSurface:
-  virtual void SwapBuffers(cc::CompositorFrame* frame) override;
+  void SwapBuffers(cc::CompositorFrame* frame) override;
 
  private:
   View* view_;
diff --git a/mojo/aura/surface_context_factory.h b/mojo/aura/surface_context_factory.h
index 8dd4721..d60080e 100644
--- a/mojo/aura/surface_context_factory.h
+++ b/mojo/aura/surface_context_factory.h
@@ -15,26 +15,24 @@
 class SurfaceContextFactory : public ui::ContextFactory {
  public:
   SurfaceContextFactory(Shell* shell, View* view);
-  virtual ~SurfaceContextFactory();
+  ~SurfaceContextFactory() override;
 
  private:
   // ContextFactory:
-  virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(
+  scoped_ptr<cc::OutputSurface> CreateOutputSurface(
       ui::Compositor* compositor,
       bool software_fallback) override;
-  virtual scoped_refptr<ui::Reflector> CreateReflector(
+  scoped_refptr<ui::Reflector> CreateReflector(
       ui::Compositor* mirrored_compositor,
       ui::Layer* mirroring_layer) override;
-  virtual void RemoveReflector(scoped_refptr<ui::Reflector> reflector) override;
-  virtual scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider()
-      override;
-  virtual void RemoveCompositor(ui::Compositor* compositor) override;
-  virtual bool DoesCreateTestContexts() override;
-  virtual cc::SharedBitmapManager* GetSharedBitmapManager() override;
-  virtual cc::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
-  virtual base::MessageLoopProxy* GetCompositorMessageLoop() override;
-  virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator()
-      override;
+  void RemoveReflector(scoped_refptr<ui::Reflector> reflector) override;
+  scoped_refptr<cc::ContextProvider> SharedMainThreadContextProvider() override;
+  void RemoveCompositor(ui::Compositor* compositor) override;
+  bool DoesCreateTestContexts() override;
+  cc::SharedBitmapManager* GetSharedBitmapManager() override;
+  cc::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
+  base::MessageLoopProxy* GetCompositorMessageLoop() override;
+  scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() override;
 
   SurfaceBinding surface_binding_;
 
diff --git a/mojo/aura/window_tree_host_mojo.h b/mojo/aura/window_tree_host_mojo.h
index f43e90d..f3f4be91 100644
--- a/mojo/aura/window_tree_host_mojo.h
+++ b/mojo/aura/window_tree_host_mojo.h
@@ -27,7 +27,7 @@
                            public ViewObserver {
  public:
   WindowTreeHostMojo(Shell* shell, View* view);
-  virtual ~WindowTreeHostMojo();
+  ~WindowTreeHostMojo() override;
 
   const gfx::Rect& bounds() const { return bounds_; }
 
@@ -37,27 +37,27 @@
 
  private:
   // WindowTreeHost:
-  virtual ui::EventSource* GetEventSource() override;
-  virtual gfx::AcceleratedWidget GetAcceleratedWidget() override;
-  virtual void Show() override;
-  virtual void Hide() override;
-  virtual gfx::Rect GetBounds() const override;
-  virtual void SetBounds(const gfx::Rect& bounds) override;
-  virtual gfx::Point GetLocationOnNativeScreen() const override;
-  virtual void SetCapture() override;
-  virtual void ReleaseCapture() override;
-  virtual void PostNativeEvent(const base::NativeEvent& native_event) override;
-  virtual void SetCursorNative(gfx::NativeCursor cursor) override;
-  virtual void MoveCursorToNative(const gfx::Point& location) override;
-  virtual void OnCursorVisibilityChangedNative(bool show) override;
+  ui::EventSource* GetEventSource() override;
+  gfx::AcceleratedWidget GetAcceleratedWidget() override;
+  void Show() override;
+  void Hide() override;
+  gfx::Rect GetBounds() const override;
+  void SetBounds(const gfx::Rect& bounds) override;
+  gfx::Point GetLocationOnNativeScreen() const override;
+  void SetCapture() override;
+  void ReleaseCapture() override;
+  void PostNativeEvent(const base::NativeEvent& native_event) override;
+  void SetCursorNative(gfx::NativeCursor cursor) override;
+  void MoveCursorToNative(const gfx::Point& location) override;
+  void OnCursorVisibilityChangedNative(bool show) override;
 
   // ui::EventSource:
-  virtual ui::EventProcessor* GetEventProcessor() override;
+  ui::EventProcessor* GetEventProcessor() override;
 
   // ViewObserver:
-  virtual void OnViewBoundsChanged(View* view,
-                                   const gfx::Rect& old_bounds,
-                                   const gfx::Rect& new_bounds) override;
+  void OnViewBoundsChanged(View* view,
+                           const gfx::Rect& old_bounds,
+                           const gfx::Rect& new_bounds) override;
 
   View* view_;
 
diff --git a/mojo/edk/embedder/embedder_unittest.cc b/mojo/edk/embedder/embedder_unittest.cc
index 551ea272..5c4d0d8 100644
--- a/mojo/edk/embedder/embedder_unittest.cc
+++ b/mojo/edk/embedder/embedder_unittest.cc
@@ -102,7 +102,7 @@
 class EmbedderTest : public testing::Test {
  public:
   EmbedderTest() : test_io_thread_(base::TestIOThread::kAutoStart) {}
-  virtual ~EmbedderTest() {}
+  ~EmbedderTest() override {}
 
  protected:
   base::TestIOThread* test_io_thread() { return &test_io_thread_; }
diff --git a/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc b/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
index 355e573..926bbc5 100644
--- a/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
+++ b/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
@@ -42,16 +42,16 @@
 class PlatformChannelPairPosixTest : public testing::Test {
  public:
   PlatformChannelPairPosixTest() {}
-  virtual ~PlatformChannelPairPosixTest() {}
+  ~PlatformChannelPairPosixTest() override {}
 
-  virtual void SetUp() override {
+  void SetUp() override {
     // Make sure |SIGPIPE| isn't being ignored.
     struct sigaction action = {};
     action.sa_handler = SIG_DFL;
     ASSERT_EQ(0, sigaction(SIGPIPE, &action, &old_action_));
   }
 
-  virtual void TearDown() override {
+  void TearDown() override {
     // Restore the |SIGPIPE| handler.
     ASSERT_EQ(0, sigaction(SIGPIPE, &old_action_, nullptr));
   }
diff --git a/mojo/edk/system/channel_unittest.cc b/mojo/edk/system/channel_unittest.cc
index c85bf92e..7d45f6e 100644
--- a/mojo/edk/system/channel_unittest.cc
+++ b/mojo/edk/system/channel_unittest.cc
@@ -33,9 +33,9 @@
   ChannelTest()
       : io_thread_(base::TestIOThread::kAutoStart),
         init_result_(TRISTATE_UNKNOWN) {}
-  virtual ~ChannelTest() {}
+  ~ChannelTest() override {}
 
-  virtual void SetUp() override {
+  void SetUp() override {
     io_thread_.PostTaskAndWait(
         FROM_HERE,
         base::Bind(&ChannelTest::SetUpOnIOThread, base::Unretained(this)));
diff --git a/mojo/edk/system/core_test_base.h b/mojo/edk/system/core_test_base.h
index 409f7e1b..2881176b 100644
--- a/mojo/edk/system/core_test_base.h
+++ b/mojo/edk/system/core_test_base.h
@@ -25,10 +25,10 @@
   typedef CoreTestBase_MockHandleInfo MockHandleInfo;
 
   CoreTestBase();
-  virtual ~CoreTestBase();
+  ~CoreTestBase() override;
 
-  virtual void SetUp() override;
-  virtual void TearDown() override;
+  void SetUp() override;
+  void TearDown() override;
 
  protected:
   // |info| must remain alive until the returned handle is closed.
diff --git a/mojo/edk/system/message_pipe.h b/mojo/edk/system/message_pipe.h
index e1d9f636..a52743d 100644
--- a/mojo/edk/system/message_pipe.h
+++ b/mojo/edk/system/message_pipe.h
@@ -99,7 +99,7 @@
   MessagePipe();
 
   friend class base::RefCountedThreadSafe<MessagePipe>;
-  virtual ~MessagePipe();
+  ~MessagePipe();
 
   // This is used internally by |WriteMessage()| and by |EnqueueMessage()|.
   // |transports| may be non-null only if it's nonempty and |message| has no
diff --git a/mojo/edk/system/message_pipe_test_utils.h b/mojo/edk/system/message_pipe_test_utils.h
index 9e6a4b7..c9d9c8b 100644
--- a/mojo/edk/system/message_pipe_test_utils.h
+++ b/mojo/edk/system/message_pipe_test_utils.h
@@ -49,7 +49,7 @@
 class MultiprocessMessagePipeTestBase : public testing::Test {
  public:
   MultiprocessMessagePipeTestBase();
-  virtual ~MultiprocessMessagePipeTestBase();
+  ~MultiprocessMessagePipeTestBase() override;
 
  protected:
   void Init(scoped_refptr<ChannelEndpoint> ep);
diff --git a/mojo/edk/system/raw_channel_unittest.cc b/mojo/edk/system/raw_channel_unittest.cc
index 23c2e7fd..9ee937d 100644
--- a/mojo/edk/system/raw_channel_unittest.cc
+++ b/mojo/edk/system/raw_channel_unittest.cc
@@ -73,16 +73,16 @@
 class RawChannelTest : public testing::Test {
  public:
   RawChannelTest() : io_thread_(base::TestIOThread::kManualStart) {}
-  virtual ~RawChannelTest() {}
+  ~RawChannelTest() override {}
 
-  virtual void SetUp() override {
+  void SetUp() override {
     embedder::PlatformChannelPair channel_pair;
     handles[0] = channel_pair.PassServerHandle();
     handles[1] = channel_pair.PassClientHandle();
     io_thread_.Start();
   }
 
-  virtual void TearDown() override {
+  void TearDown() override {
     io_thread_.Stop();
     handles[0].reset();
     handles[1].reset();
diff --git a/mojo/edk/system/raw_channel_win.cc b/mojo/edk/system/raw_channel_win.cc
index 208d5958..98380a9 100644
--- a/mojo/edk/system/raw_channel_win.cc
+++ b/mojo/edk/system/raw_channel_win.cc
@@ -72,10 +72,10 @@
 class RawChannelWin : public RawChannel {
  public:
   RawChannelWin(embedder::ScopedPlatformHandle handle);
-  virtual ~RawChannelWin();
+  ~RawChannelWin() override;
 
   // |RawChannel| public methods:
-  virtual size_t GetSerializedPlatformHandleSize() const override;
+  size_t GetSerializedPlatformHandleSize() const override;
 
  private:
   // RawChannelIOHandler receives OS notifications for I/O completion. It must
@@ -109,9 +109,9 @@
     // |base::MessageLoopForIO::IOHandler| implementation:
     // Must be called on the I/O thread. It could be called before or after
     // detached from the owner.
-    virtual void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
-                               DWORD bytes_transferred,
-                               DWORD error) override;
+    void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
+                       DWORD bytes_transferred,
+                       DWORD error) override;
 
     // Must be called on the I/O thread under |owner_->write_lock()|.
     // After this call, the owner must not make any further calls on this
@@ -121,7 +121,7 @@
                                scoped_ptr<WriteBuffer> write_buffer);
 
    private:
-    virtual ~RawChannelIOHandler();
+    ~RawChannelIOHandler() override;
 
     // Returns true if |owner_| has been reset and there is not pending read or
     // write.
@@ -160,17 +160,17 @@
   };
 
   // |RawChannel| private methods:
-  virtual IOResult Read(size_t* bytes_read) override;
-  virtual IOResult ScheduleRead() override;
-  virtual embedder::ScopedPlatformHandleVectorPtr GetReadPlatformHandles(
+  IOResult Read(size_t* bytes_read) override;
+  IOResult ScheduleRead() override;
+  embedder::ScopedPlatformHandleVectorPtr GetReadPlatformHandles(
       size_t num_platform_handles,
       const void* platform_handle_table) override;
-  virtual IOResult WriteNoLock(size_t* platform_handles_written,
-                               size_t* bytes_written) override;
-  virtual IOResult ScheduleWriteNoLock() override;
-  virtual bool OnInit() override;
-  virtual void OnShutdownNoLock(scoped_ptr<ReadBuffer> read_buffer,
-                                scoped_ptr<WriteBuffer> write_buffer) override;
+  IOResult WriteNoLock(size_t* platform_handles_written,
+                       size_t* bytes_written) override;
+  IOResult ScheduleWriteNoLock() override;
+  bool OnInit() override;
+  void OnShutdownNoLock(scoped_ptr<ReadBuffer> read_buffer,
+                        scoped_ptr<WriteBuffer> write_buffer) override;
 
   // Passed to |io_handler_| during initialization.
   embedder::ScopedPlatformHandle handle_;
diff --git a/mojo/edk/system/remote_message_pipe_unittest.cc b/mojo/edk/system/remote_message_pipe_unittest.cc
index f7095d2f..6e0b991 100644
--- a/mojo/edk/system/remote_message_pipe_unittest.cc
+++ b/mojo/edk/system/remote_message_pipe_unittest.cc
@@ -44,16 +44,16 @@
 class RemoteMessagePipeTest : public testing::Test {
  public:
   RemoteMessagePipeTest() : io_thread_(base::TestIOThread::kAutoStart) {}
-  virtual ~RemoteMessagePipeTest() {}
+  ~RemoteMessagePipeTest() override {}
 
-  virtual void SetUp() override {
+  void SetUp() override {
     io_thread_.PostTaskAndWait(
         FROM_HERE,
         base::Bind(&RemoteMessagePipeTest::SetUpOnIOThread,
                    base::Unretained(this)));
   }
 
-  virtual void TearDown() override {
+  void TearDown() override {
     io_thread_.PostTaskAndWait(
         FROM_HERE,
         base::Bind(&RemoteMessagePipeTest::TearDownOnIOThread,
diff --git a/mojo/edk/system/shared_buffer_dispatcher_unittest.cc b/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
index d46ffe3..a80f71d 100644
--- a/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
+++ b/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
@@ -43,7 +43,7 @@
 class SharedBufferDispatcherTest : public testing::Test {
  public:
   SharedBufferDispatcherTest() {}
-  virtual ~SharedBufferDispatcherTest() {}
+  ~SharedBufferDispatcherTest() override {}
 
   embedder::PlatformSupport* platform_support() { return &platform_support_; }
 
diff --git a/mojo/examples/BUILD.gn b/mojo/examples/BUILD.gn
index bdd09f71..4d0623e6 100644
--- a/mojo/examples/BUILD.gn
+++ b/mojo/examples/BUILD.gn
@@ -22,14 +22,9 @@
   if (use_aura) {
     deps += [
       "//mojo/examples/aura_demo:mojo_aura_demo",
-      "//mojo/examples/browser",
       "//mojo/examples/demo_launcher",
-      "//mojo/examples/embedded_app",
       "//mojo/examples/media_viewer",
-      "//mojo/examples/nesting_app",
       "//mojo/examples/keyboard",
-      "//mojo/examples/window_manager",
-      "//mojo/examples/wm_flow",
     ]
   }
 }
diff --git a/mojo/examples/browser/BUILD.gn b/mojo/examples/browser/BUILD.gn
deleted file mode 100644
index d28a971..0000000
--- a/mojo/examples/browser/BUILD.gn
+++ /dev/null
@@ -1,42 +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.
-
-import("//build/config/ui.gni")
-
-assert(use_aura)
-
-shared_library("browser") {
-  output_name = "mojo_browser"
-
-  sources = [
-    "browser.cc",
-  ]
-
-  deps = [
-    "//base",
-    "//cc",
-    "//mojo/application",
-    "//mojo/aura",
-    "//mojo/common",
-    "//mojo/converters/geometry",
-    "//mojo/converters/input_events",
-    "//mojo/examples/window_manager:bindings",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/public/interfaces/geometry",
-    "//mojo/services/public/interfaces/input_events",
-    "//mojo/services/public/interfaces/navigation",
-    "//mojo/services/public/interfaces/view_manager",
-    "//mojo/views:views",
-    "//third_party/icu",
-    "//ui/aura",
-    "//ui/base",
-    "//ui/compositor",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-    "//ui/resources",
-    "//ui/views",
-    "//url",
-  ]
-}
diff --git a/mojo/examples/browser/DEPS b/mojo/examples/browser/DEPS
deleted file mode 100644
index 02dd6ea..0000000
--- a/mojo/examples/browser/DEPS
+++ /dev/null
@@ -1,11 +0,0 @@
-include_rules = [
-  "+cc",
-  "-cc/blink",
-  "+skia/ext",
-  "+ui/aura",
-  "+ui/base/hit_test.h",
-  "+ui/compositor",
-  "+ui/events",
-  "+ui/gfx",
-  "+ui/views",
-]
diff --git a/mojo/examples/browser/browser.cc b/mojo/examples/browser/browser.cc
deleted file mode 100644
index e5f724e..0000000
--- a/mojo/examples/browser/browser.cc
+++ /dev/null
@@ -1,274 +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 "base/macros.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "mojo/application/application_runner_chromium.h"
-#include "mojo/common/common_type_converters.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/examples/window_manager/window_manager.mojom.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/connect.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
-#include "mojo/views/native_widget_view_manager.h"
-#include "mojo/views/views_init.h"
-#include "ui/aura/client/focus_client.h"
-#include "ui/aura/window.h"
-#include "ui/events/event.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/textfield/textfield.h"
-#include "ui/views/controls/textfield/textfield_controller.h"
-#include "ui/views/focus/focus_manager.h"
-#include "ui/views/layout/layout_manager.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_delegate.h"
-#include "ui/views/widget/widget_observer.h"
-#include "url/gurl.h"
-
-namespace mojo {
-namespace examples {
-
-class BrowserLayoutManager : public views::LayoutManager {
- public:
-  BrowserLayoutManager() {}
-  virtual ~BrowserLayoutManager() {}
-
- private:
-  // Overridden from views::LayoutManager:
-  virtual void Layout(views::View* host) override {
-    // Browser view has one child, a text input field.
-    DCHECK_EQ(1, host->child_count());
-    views::View* text_field = host->child_at(0);
-    gfx::Size ps = text_field->GetPreferredSize();
-    text_field->SetBoundsRect(gfx::Rect(host->width(), ps.height()));
-  }
-  virtual gfx::Size GetPreferredSize(const views::View* host) const override {
-    return gfx::Size();
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(BrowserLayoutManager);
-};
-
-// KeyboardManager handles notifying the windowmanager when views are focused.
-// To use create one and KeyboardManager will take care of all other details.
-//
-// TODO(sky): it would be nice if this were put in NativeWidgetViewManager, but
-// that requires NativeWidgetViewManager to take an IWindowManager. That may be
-// desirable anyway...
-class KeyboardManager
-    : public views::FocusChangeListener,
-      public ui::EventHandler,
-      public views::WidgetObserver {
- public:
-  KeyboardManager(views::Widget* widget,
-                  IWindowManager* window_manager,
-                  View* view)
-      : widget_(widget),
-        window_manager_(window_manager),
-        view_(view),
-        last_view_id_(0),
-        focused_view_(NULL) {
-    widget_->GetFocusManager()->AddFocusChangeListener(this);
-    widget_->AddObserver(this);
-    widget_->GetNativeView()->AddPostTargetHandler(this);
-  }
-
- private:
-  virtual ~KeyboardManager() {
-    widget_->GetFocusManager()->RemoveFocusChangeListener(this);
-    widget_->GetNativeView()->RemovePostTargetHandler(this);
-    widget_->RemoveObserver(this);
-
-    HideKeyboard();
-  }
-
-  void ShowKeyboard(views::View* view) {
-    if (focused_view_ == view)
-      return;
-
-    const gfx::Rect bounds_in_widget =
-        view->ConvertRectToWidget(gfx::Rect(view->bounds().size()));
-    last_view_id_ = view_->id();
-    window_manager_->ShowKeyboard(last_view_id_,
-                                  Rect::From(bounds_in_widget));
-    // TODO(sky): listen for view to be removed.
-    focused_view_ = view;
-  }
-
-  void HideKeyboard() {
-    if (!focused_view_)
-      return;
-
-    window_manager_->HideKeyboard(last_view_id_);
-    last_view_id_ = 0;
-    focused_view_ = NULL;
-  }
-
-  // views::FocusChangeListener:
-  virtual void OnWillChangeFocus(views::View* focused_before,
-                                 views::View* focused_now) override {
-  }
-  virtual void OnDidChangeFocus(views::View* focused_before,
-                                views::View* focused_now) override {
-    if (focused_view_ && focused_now != focused_view_)
-      HideKeyboard();
-  }
-
-  // ui::EventHandler:
-  virtual void OnMouseEvent(ui::MouseEvent* event) override {
-    views::View* focused_now = widget_->GetFocusManager()->GetFocusedView();
-    if (focused_now &&
-        focused_now->GetClassName() == views::Textfield::kViewClassName &&
-        (event->flags() & ui::EF_FROM_TOUCH) != 0) {
-      ShowKeyboard(focused_now);
-    }
-  }
-
-  // views::WidgetObserver:
-  virtual void OnWidgetDestroying(views::Widget* widget) override {
-    delete this;
-  }
-
-  views::Widget* widget_;
-  IWindowManager* window_manager_;
-  View* view_;
-  Id last_view_id_;
-  views::View* focused_view_;
-
-  DISALLOW_COPY_AND_ASSIGN(KeyboardManager);
-};
-
-// This is the basics of creating a views widget with a textfield.
-// TODO: cleanup!
-class Browser : public ApplicationDelegate,
-                public ViewManagerDelegate,
-                public views::TextfieldController,
-                public ViewObserver {
- public:
-  Browser()
-      : shell_(nullptr), view_manager_(NULL), root_(NULL), widget_(NULL) {}
-
-  virtual ~Browser() {
-    if (root_)
-      root_->RemoveObserver(this);
-  }
-
- private:
-  // Overridden from ApplicationDelegate:
-  virtual void Initialize(ApplicationImpl* app) override {
-    shell_ = app->shell();
-    view_manager_client_factory_.reset(
-        new ViewManagerClientFactory(shell_, this));
-    views_init_.reset(new ViewsInit);
-    app->ConnectToService("mojo:window_manager", &window_manager_);
- }
-
- virtual bool ConfigureIncomingConnection(
-     ApplicationConnection* connection) override {
-    connection->AddService(view_manager_client_factory_.get());
-    return true;
-  }
-
-  void CreateWidget(View* view) {
-    views::Textfield* textfield = new views::Textfield;
-    textfield->set_controller(this);
-
-    views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView;
-    widget_delegate->GetContentsView()->set_background(
-        views::Background::CreateSolidBackground(SK_ColorBLUE));
-    widget_delegate->GetContentsView()->AddChildView(textfield);
-    widget_delegate->GetContentsView()->SetLayoutManager(
-        new BrowserLayoutManager);
-
-    widget_ = new views::Widget;
-    views::Widget::InitParams params(
-        views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
-    params.native_widget = new NativeWidgetViewManager(widget_, shell_, view);
-    params.delegate = widget_delegate;
-    params.bounds = gfx::Rect(view->bounds().width(), view->bounds().height());
-    widget_->Init(params);
-    // KeyboardManager handles deleting itself when the widget is destroyed.
-    new KeyboardManager(widget_, window_manager_.get(), view);
-    widget_->Show();
-    textfield->RequestFocus();
-  }
-
-  // ViewManagerDelegate:
-  virtual void OnEmbed(ViewManager* view_manager,
-                       View* root,
-                       ServiceProviderImpl* exported_services,
-                       scoped_ptr<ServiceProvider> imported_services) override {
-    // TODO: deal with OnEmbed() being invoked multiple times.
-    ConnectToService(imported_services.get(), &navigator_host_);
-    view_manager_ = view_manager;
-    root_ = root;
-    root_->AddObserver(this);
-    root_->SetFocus();
-    CreateWidget(root_);
-  }
-  virtual void OnViewManagerDisconnected(
-      ViewManager* view_manager) override {
-    DCHECK_EQ(view_manager_, view_manager);
-    view_manager_ = NULL;
-    base::MessageLoop::current()->Quit();
-  }
-
-  // views::TextfieldController:
-  virtual bool HandleKeyEvent(views::Textfield* sender,
-                              const ui::KeyEvent& key_event) override {
-    if (key_event.key_code() == ui::VKEY_RETURN) {
-      GURL url(sender->text());
-      printf("User entered this URL: %s\n", url.spec().c_str());
-      URLRequestPtr request(URLRequest::New());
-      request->url = String::From(url);
-      navigator_host_->RequestNavigate(TARGET_NEW_NODE, request.Pass());
-    }
-    return false;
-  }
-
-  // ViewObserver:
-  virtual void OnViewFocusChanged(View* gained_focus,
-                                  View* lost_focus) override {
-    aura::client::FocusClient* focus_client =
-        aura::client::GetFocusClient(widget_->GetNativeView());
-    if (lost_focus == root_)
-      focus_client->FocusWindow(NULL);
-    else if (gained_focus == root_)
-      focus_client->FocusWindow(widget_->GetNativeView());
-  }
-  virtual void OnViewDestroyed(View* view) override {
-    DCHECK_EQ(root_, view);
-    view->RemoveObserver(this);
-    root_ = NULL;
-  }
-
-  Shell* shell_;
-
-  scoped_ptr<ViewsInit> views_init_;
-
-  ViewManager* view_manager_;
-  scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
-  View* root_;
-  views::Widget* widget_;
-  NavigatorHostPtr navigator_host_;
-  IWindowManagerPtr window_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(Browser);
-};
-
-}  // namespace examples
-}  // namespace mojo
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new mojo::examples::Browser);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/examples/embedded_app/BUILD.gn b/mojo/examples/embedded_app/BUILD.gn
deleted file mode 100644
index 12cf1b91..0000000
--- a/mojo/examples/embedded_app/BUILD.gn
+++ /dev/null
@@ -1,28 +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.
-
-shared_library("embedded_app") {
-  output_name = "mojo_embedded_app"
-
-  sources = [
-    "embedded_app.cc",
-  ]
-
-  deps = [
-    "//base",
-    "//mojo/application",
-    "//mojo/examples/bitmap_uploader",
-    "//mojo/examples/window_manager:bindings",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/public/cpp/bindings",
-    "//mojo/public/cpp/utility",
-    "//mojo/public/gles2:for_shared_library",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/public/interfaces/geometry",
-    "//mojo/services/public/interfaces/navigation",
-    "//ui/gfx/geometry",
-    "//ui/gl",
-    "//url",
-  ]
-}
diff --git a/mojo/examples/embedded_app/DEPS b/mojo/examples/embedded_app/DEPS
deleted file mode 100644
index fe1d98e..0000000
--- a/mojo/examples/embedded_app/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+ui/events",
-]
diff --git a/mojo/examples/embedded_app/embedded_app.cc b/mojo/examples/embedded_app/embedded_app.cc
deleted file mode 100644
index 98c418e9..0000000
--- a/mojo/examples/embedded_app/embedded_app.cc
+++ /dev/null
@@ -1,122 +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 "base/bind.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "mojo/application/application_runner_chromium.h"
-#include "mojo/examples/bitmap_uploader/bitmap_uploader.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/connect.h"
-#include "mojo/public/cpp/application/interface_factory_impl.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/public/cpp/view_manager/view_observer.h"
-#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
-#include "ui/events/event_constants.h"
-#include "url/gurl.h"
-#include "url/url_util.h"
-
-namespace mojo {
-namespace examples {
-
-const SkColor kColors[] = {SK_ColorYELLOW, SK_ColorRED, SK_ColorGREEN,
-                           SK_ColorMAGENTA};
-
-struct Window {
-  Window(View* root,
-         scoped_ptr<ServiceProvider> embedder_service_provider,
-         Shell* shell)
-      : root(root),
-        embedder_service_provider(embedder_service_provider.Pass()),
-        bitmap_uploader(root) {
-    bitmap_uploader.Init(shell);
-  }
-
-  View* root;
-  scoped_ptr<ServiceProvider> embedder_service_provider;
-  BitmapUploader bitmap_uploader;
-};
-
-class EmbeddedApp
-    : public ApplicationDelegate,
-      public ViewManagerDelegate,
-      public ViewObserver {
- public:
-  EmbeddedApp() : shell_(nullptr) { url::AddStandardScheme("mojo"); }
-  virtual ~EmbeddedApp() {}
-
- private:
-
-  // Overridden from ApplicationDelegate:
-  virtual void Initialize(ApplicationImpl* app) override {
-    shell_ = app->shell();
-    view_manager_client_factory_.reset(
-        new ViewManagerClientFactory(app->shell(), this));
-  }
-
-  virtual bool ConfigureIncomingConnection(
-      ApplicationConnection* connection) override {
-    connection->AddService(view_manager_client_factory_.get());
-    return true;
-  }
-
-  // Overridden from ViewManagerDelegate:
-  virtual void OnEmbed(ViewManager* view_manager,
-                       View* root,
-                       ServiceProviderImpl* exported_services,
-                       scoped_ptr<ServiceProvider> imported_services) override {
-    root->AddObserver(this);
-    Window* window = new Window(root, imported_services.Pass(), shell_);
-    windows_[root->id()] = window;
-    window->bitmap_uploader.SetColor(
-        kColors[next_color_++ % arraysize(kColors)]);
-  }
-  virtual void OnViewManagerDisconnected(ViewManager* view_manager) override {
-    base::MessageLoop::current()->Quit();
-  }
-
-  // Overridden from ViewObserver:
-  virtual void OnViewDestroyed(View* view) override {
-    DCHECK(windows_.find(view->id()) != windows_.end());
-    windows_.erase(view->id());
-  }
-  virtual void OnViewInputEvent(View* view, const EventPtr& event) override {
-    if (event->action == EVENT_TYPE_MOUSE_RELEASED) {
-      if (event->flags & EVENT_FLAGS_LEFT_MOUSE_BUTTON) {
-        URLRequestPtr request(URLRequest::New());
-        request->url = "http://www.aaronboodman.com/z_dropbox/test.html";
-        NavigatorHostPtr navigator_host;
-        ConnectToService(windows_[view->id()]->embedder_service_provider.get(),
-                         &navigator_host);
-        navigator_host->RequestNavigate(TARGET_SOURCE_NODE, request.Pass());
-      }
-    }
-  }
-
-  Shell* shell_;
-  scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
-
-  typedef std::map<Id, Window*> WindowMap;
-  WindowMap windows_;
-
-  int next_color_;
-
-  DISALLOW_COPY_AND_ASSIGN(EmbeddedApp);
-};
-
-}  // namespace examples
-}  // namespace mojo
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new mojo::examples::EmbeddedApp);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/examples/nesting_app/BUILD.gn b/mojo/examples/nesting_app/BUILD.gn
deleted file mode 100644
index 0043517..0000000
--- a/mojo/examples/nesting_app/BUILD.gn
+++ /dev/null
@@ -1,27 +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.
-
-shared_library("nesting_app") {
-  output_name = "mojo_nesting_app"
-
-  sources = [
-    "nesting_app.cc"
-  ]
-
-  deps = [
-    "//base",
-    "//mojo/application",
-    "//mojo/examples/bitmap_uploader",
-    "//mojo/examples/window_manager:bindings",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/public/cpp/bindings",
-    "//mojo/public/cpp/utility",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/public/interfaces/geometry",
-    "//mojo/services/public/interfaces/navigation",
-    "//ui/gfx/geometry",
-    "//ui/gl",
-    "//url",
-  ]
-}
diff --git a/mojo/examples/nesting_app/DEPS b/mojo/examples/nesting_app/DEPS
deleted file mode 100644
index fe1d98e..0000000
--- a/mojo/examples/nesting_app/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+ui/events",
-]
diff --git a/mojo/examples/nesting_app/nesting_app.cc b/mojo/examples/nesting_app/nesting_app.cc
deleted file mode 100644
index 4473d6f..0000000
--- a/mojo/examples/nesting_app/nesting_app.cc
+++ /dev/null
@@ -1,105 +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 "base/bind.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/stringprintf.h"
-#include "mojo/application/application_runner_chromium.h"
-#include "mojo/examples/bitmap_uploader/bitmap_uploader.h"
-#include "mojo/examples/window_manager/window_manager.mojom.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/interface_factory_impl.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/public/cpp/view_manager/view_observer.h"
-#include "ui/events/event_constants.h"
-#include "url/gurl.h"
-
-namespace mojo {
-namespace examples {
-
-namespace {
-const char kEmbeddedAppURL[] = "mojo:embedded_app";
-}
-
-class NestingApp;
-
-// An app that embeds another app.
-// TODO(davemoore): Is this the right name?
-class NestingApp
-    : public ApplicationDelegate,
-      public ViewManagerDelegate,
-      public ViewObserver {
- public:
-  NestingApp() : nested_(nullptr), shell_(nullptr) {}
-  virtual ~NestingApp() {}
-
- private:
-  // Overridden from ApplicationDelegate:
-  virtual void Initialize(ApplicationImpl* app) override {
-    shell_ = app->shell();
-    view_manager_client_factory_.reset(
-        new ViewManagerClientFactory(app->shell(), this));
-  }
-
-  // Overridden from ApplicationImpl:
-  virtual bool ConfigureIncomingConnection(
-      ApplicationConnection* connection) override {
-    connection->ConnectToService(&window_manager_);
-    connection->AddService(view_manager_client_factory_.get());
-    return true;
-  }
-
-  // Overridden from ViewManagerDelegate:
-  virtual void OnEmbed(ViewManager* view_manager,
-                       View* root,
-                       ServiceProviderImpl* exported_services,
-                       scoped_ptr<ServiceProvider> imported_services) override {
-    root->AddObserver(this);
-    bitmap_uploader_.reset(new BitmapUploader(root));
-    bitmap_uploader_->Init(shell_);
-    bitmap_uploader_->SetColor(SK_ColorCYAN);
-
-    nested_ = View::Create(view_manager);
-    root->AddChild(nested_);
-    nested_->SetBounds(gfx::Rect(20, 20, 50, 50));
-    nested_->Embed(kEmbeddedAppURL);
-  }
-  virtual void OnViewManagerDisconnected(ViewManager* view_manager) override {
-    base::MessageLoop::current()->Quit();
-  }
-
-  // Overridden from ViewObserver:
-  virtual void OnViewDestroyed(View* view) override {
-    // TODO(beng): reap views & child Views.
-    nested_ = NULL;
-  }
-  virtual void OnViewInputEvent(View* view, const EventPtr& event) override {
-    if (event->action == EVENT_TYPE_MOUSE_RELEASED)
-      window_manager_->CloseWindow(view->id());
-  }
-
-  scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
-
-  View* nested_;
-  Shell* shell_;
-  IWindowManagerPtr window_manager_;
-  scoped_ptr<BitmapUploader> bitmap_uploader_;
-
-  DISALLOW_COPY_AND_ASSIGN(NestingApp);
-};
-
-}  // namespace examples
-}  // namespace mojo
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new mojo::examples::NestingApp);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/examples/window_manager/BUILD.gn b/mojo/examples/window_manager/BUILD.gn
deleted file mode 100644
index 3f463e5..0000000
--- a/mojo/examples/window_manager/BUILD.gn
+++ /dev/null
@@ -1,56 +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.
-
-import("//build/config/ui.gni")
-import("//mojo/public/tools/bindings/mojom.gni")
-
-assert(use_aura)
-
-shared_library("window_manager") {
-  output_name = "mojo_window_manager"
-
-  sources = [
-    "debug_panel.cc",
-    "debug_panel.h",
-    "window_manager.cc",
-  ]
-
-  deps = [
-    ":bindings",
-    "//base",
-    "//mojo/application",
-    "//mojo/aura",
-    "//mojo/converters/geometry",
-    "//mojo/converters/input_events",
-    "//mojo/examples/keyboard:bindings",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/public/cpp/bindings",
-    "//mojo/public/cpp/utility",
-    "//mojo/public/gles2:for_shared_library",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/public/interfaces/geometry",
-    "//mojo/services/public/interfaces/input_events",
-    "//mojo/services/public/interfaces/navigation",
-    "//mojo/services/window_manager:lib",
-    "//mojo/views:views",
-    "//ui/aura",
-    "//ui/base",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-    "//ui/gl",
-    "//ui/resources",
-    "//ui/views",
-    "//ui/wm",
-  ]
-}
-
-mojom("bindings") {
-  sources = [
-    "window_manager.mojom",
-  ]
-  deps = [
-    "//mojo/services/public/interfaces/geometry",
-  ]
-}
-
diff --git a/mojo/examples/window_manager/DEPS b/mojo/examples/window_manager/DEPS
deleted file mode 100644
index 372b6a8..0000000
--- a/mojo/examples/window_manager/DEPS
+++ /dev/null
@@ -1,7 +0,0 @@
-include_rules = [
-  "+ui/aura",
-  "+ui/events",
-  "+ui/gfx",
-  "+ui/views",
-  "+ui/wm/core",
-]
diff --git a/mojo/examples/window_manager/debug_panel.cc b/mojo/examples/window_manager/debug_panel.cc
deleted file mode 100644
index 4a751344..0000000
--- a/mojo/examples/window_manager/debug_panel.cc
+++ /dev/null
@@ -1,138 +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 "mojo/examples/window_manager/debug_panel.h"
-
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/views/native_widget_view_manager.h"
-#include "ui/gfx/text_constants.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/button/blue_button.h"
-#include "ui/views/controls/button/radio_button.h"
-#include "ui/views/widget/widget.h"
-
-namespace mojo {
-namespace examples {
-
-namespace {
-
-const int kControlBorderInset = 5;
-const int kNavigationTargetGroupId = 1;
-
-}  // namespace
-
-DebugPanel::DebugPanel(Delegate* delegate, Shell* shell, View* view)
-    : delegate_(delegate),
-      view_(view),
-      navigation_target_label_(
-          new views::Label(base::ASCIIToUTF16("Navigation target:"))),
-      navigation_target_new_(
-          new views::RadioButton(base::ASCIIToUTF16("New window"),
-                                 kNavigationTargetGroupId)),
-      navigation_target_source_(
-          new views::RadioButton(base::ASCIIToUTF16("Source window"),
-                                 kNavigationTargetGroupId)),
-      navigation_target_default_(
-          new views::RadioButton(base::ASCIIToUTF16("Default"),
-                                 kNavigationTargetGroupId)),
-      colored_square_(
-          new views::BlueButton(this, base::ASCIIToUTF16("Local nav test"))),
-      close_last_(
-          new views::BlueButton(this, base::ASCIIToUTF16("Close last window"))),
-      cross_app_(
-          new views::BlueButton(this,
-                                base::ASCIIToUTF16("Cross-app nav test"))) {
-  navigation_target_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  navigation_target_default_->SetChecked(true);
-
-  views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView();
-  widget_delegate->GetContentsView()->set_background(
-      views::Background::CreateSolidBackground(0xFFDDDDDD));
-  widget_delegate->GetContentsView()->AddChildView(navigation_target_label_);
-  widget_delegate->GetContentsView()->AddChildView(navigation_target_default_);
-  widget_delegate->GetContentsView()->AddChildView(navigation_target_new_);
-  widget_delegate->GetContentsView()->AddChildView(navigation_target_source_);
-  widget_delegate->GetContentsView()->AddChildView(colored_square_);
-  widget_delegate->GetContentsView()->AddChildView(close_last_);
-  widget_delegate->GetContentsView()->AddChildView(cross_app_);
-  widget_delegate->GetContentsView()->SetLayoutManager(this);
-
-  views::Widget* widget = new views::Widget();
-  views::Widget::InitParams params(
-      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
-  params.native_widget = new NativeWidgetViewManager(widget, shell, view);
-  params.delegate = widget_delegate;
-  params.bounds = gfx::Rect(view->bounds().size());
-  widget->Init(params);
-  widget->Show();
-}
-
-DebugPanel::~DebugPanel() {
-}
-
-gfx::Size DebugPanel::GetPreferredSize(const views::View* view) const {
-  return gfx::Size();
-}
-
-Target DebugPanel::navigation_target() const {
-  if (navigation_target_new_->checked())
-    return TARGET_NEW_NODE;
-  if (navigation_target_source_->checked())
-    return TARGET_SOURCE_NODE;
-  return TARGET_DEFAULT;
-}
-
-void DebugPanel::Layout(views::View* view) {
-  int y = kControlBorderInset;
-  int w = view->width() - kControlBorderInset * 2;
-
-  navigation_target_label_->SetBounds(
-      kControlBorderInset, y, w,
-      navigation_target_label_->GetPreferredSize().height());
-  y += navigation_target_label_->height();
-
-  views::RadioButton* radios[] = {
-    navigation_target_default_,
-    navigation_target_new_,
-    navigation_target_source_,
-  };
-  for (size_t i = 0; i < arraysize(radios); ++i) {
-    radios[i]->SetBounds(kControlBorderInset, y, w,
-                         radios[i]->GetPreferredSize().height());
-    y += radios[i]->height();
-  }
-
-  y += kControlBorderInset;
-  views::Button* buttons[] = {
-    colored_square_,
-    close_last_,
-    cross_app_,
-  };
-  for (size_t i = 0; i < arraysize(buttons); ++i) {
-    buttons[i]->SetBounds(kControlBorderInset, y, w,
-                          buttons[i]->GetPreferredSize().height());
-    y += buttons[i]->height();
-  }
-}
-
-void DebugPanel::ButtonPressed(views::Button* sender, const ui::Event& event) {
-  if (sender == colored_square_) {
-    Navigate("mojo://embedded_app/");
-  } else if (sender == close_last_) {
-    delegate_->CloseTopWindow();
-  } else if (sender == cross_app_) {
-    Navigate("http://www.aaronboodman.com/z_dropbox/test.html");
-  }
-}
-
-void DebugPanel::Navigate(const std::string& url) {
-  URLRequestPtr request(URLRequest::New());
-  request->url = url;
-  delegate_->RequestNavigate(view_->id(), TARGET_NEW_NODE, request.Pass());
-}
-
-}  // namespace examples
-}  // namespace mojo
diff --git a/mojo/examples/window_manager/debug_panel.h b/mojo/examples/window_manager/debug_panel.h
deleted file mode 100644
index eec3067..0000000
--- a/mojo/examples/window_manager/debug_panel.h
+++ /dev/null
@@ -1,76 +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 MOJO_EXAMPLES_WINDOW_MANAGER_DEBUG_PANEL_H_
-#define MOJO_EXAMPLES_WINDOW_MANAGER_DEBUG_PANEL_H_
-
-#include <string>
-
-#include "base/macros.h"
-#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
-#include "ui/views/controls/button/button.h"
-#include "ui/views/layout/layout_manager.h"
-#include "ui/views/widget/widget_delegate.h"
-
-namespace views {
-class Label;
-class RadioButton;
-}
-
-namespace mojo {
-
-class Shell;
-class View;
-
-namespace examples {
-
-// A panel of controls intended to demonstrate the functionality of the window
-// manager.
-class DebugPanel : public views::LayoutManager, public views::ButtonListener {
- public:
-  class Delegate {
-   public:
-    virtual void CloseTopWindow() = 0;
-    virtual void RequestNavigate(uint32 source_view_id,
-                                 Target target,
-                                 URLRequestPtr url_request) = 0;
-
-   protected:
-    virtual ~Delegate(){}
-  };
-
-  DebugPanel(Delegate* delegate, Shell* shell, View* view);
-  virtual ~DebugPanel();
-
-  Target navigation_target() const;
-
- private:
-  // LayoutManager overrides:
-  virtual gfx::Size GetPreferredSize(const views::View* view) const override;
-  virtual void Layout(views::View* host) override;
-  virtual void ButtonPressed(views::Button* sender,
-                             const ui::Event& event) override;
-
-  void Navigate(const std::string& url);
-
-  Delegate* delegate_;
-  Shell* shell_;
-  View* view_;
-
-  views::Label* navigation_target_label_;
-  views::RadioButton* navigation_target_new_;
-  views::RadioButton* navigation_target_source_;
-  views::RadioButton* navigation_target_default_;
-
-  views::Button* colored_square_;
-  views::Button* close_last_;
-  views::Button* cross_app_;
-
-  DISALLOW_COPY_AND_ASSIGN(DebugPanel);
-};
-
-}  // examples
-}  // mojo
-
-#endif  //  MOJO_EXAMPLES_WINDOW_MANAGER_DEBUG_PANEL_H_
diff --git a/mojo/examples/window_manager/window_manager.cc b/mojo/examples/window_manager/window_manager.cc
deleted file mode 100644
index e2bb237..0000000
--- a/mojo/examples/window_manager/window_manager.cc
+++ /dev/null
@@ -1,603 +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 "base/bind.h"
-#include "base/macros.h"
-#include "mojo/application/application_runner_chromium.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/converters/input_events/input_events_type_converters.h"
-#include "mojo/examples/keyboard/keyboard.mojom.h"
-#include "mojo/examples/window_manager/debug_panel.h"
-#include "mojo/examples/window_manager/window_manager.mojom.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/interface_factory_impl.h"
-#include "mojo/public/cpp/application/service_provider_impl.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/public/cpp/view_manager/view_observer.h"
-#include "mojo/services/public/interfaces/input_events/input_events.mojom.h"
-#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
-#include "mojo/services/window_manager/window_manager_app.h"
-#include "mojo/services/window_manager/window_manager_delegate.h"
-#include "mojo/views/views_init.h"
-#include "ui/aura/window.h"
-#include "ui/events/event.h"
-#include "ui/events/event_constants.h"
-#include "ui/gfx/geometry/size_conversions.h"
-#include "ui/wm/core/focus_rules.h"
-
-#if defined CreateWindow
-#undef CreateWindow
-#endif
-
-namespace mojo {
-namespace examples {
-
-class WindowManager;
-
-namespace {
-
-const int kBorderInset = 25;
-const int kControlPanelWidth = 200;
-const int kTextfieldHeight = 25;
-
-class WMFocusRules : public wm::FocusRules {
- public:
-  WMFocusRules(mojo::WindowManagerApp* window_manager_app,
-               mojo::View* window_container)
-      : window_container_(window_container),
-        window_manager_app_(window_manager_app) {}
-  virtual ~WMFocusRules() {}
-
- private:
-  // Overridden from wm::FocusRules:
-  virtual bool IsToplevelWindow(aura::Window* window) const override {
-    return mojo::WindowManagerApp::GetViewForWindow(window)->parent() ==
-        window_container_;
-  }
-  virtual bool CanActivateWindow(aura::Window* window) const override {
-    return mojo::WindowManagerApp::GetViewForWindow(window)->parent() ==
-        window_container_;
-  }
-  virtual bool CanFocusWindow(aura::Window* window) const override {
-    return true;
-  }
-  virtual aura::Window* GetToplevelWindow(aura::Window* window) const override {
-    mojo::View* view = mojo::WindowManagerApp::GetViewForWindow(window);
-    while (view->parent() != window_container_) {
-      view = view->parent();
-      // Unparented hierarchy, there is no "top level" window.
-      if (!view)
-        return NULL;
-    }
-
-    return window_manager_app_->GetWindowForViewId(view->id());
-  }
-  virtual aura::Window* GetActivatableWindow(
-      aura::Window* window) const override {
-    return GetToplevelWindow(window);
-  }
-  virtual aura::Window* GetFocusableWindow(
-      aura::Window* window) const override {
-    return window;
-  }
-  virtual aura::Window* GetNextActivatableWindow(
-      aura::Window* ignore) const override {
-    aura::Window* activatable = GetActivatableWindow(ignore);
-    const aura::Window::Windows& children = activatable->parent()->children();
-    for (aura::Window::Windows::const_reverse_iterator it = children.rbegin();
-         it != children.rend(); ++it) {
-      if (*it != ignore)
-        return *it;
-    }
-    return NULL;
-  }
-
-  mojo::View* window_container_;
-  mojo::WindowManagerApp* window_manager_app_;
-
-  DISALLOW_COPY_AND_ASSIGN(WMFocusRules);
-};
-
-}  // namespace
-
-class WindowManagerConnection : public InterfaceImpl<IWindowManager> {
- public:
-  explicit WindowManagerConnection(WindowManager* window_manager)
-      : window_manager_(window_manager) {}
-  virtual ~WindowManagerConnection() {}
-
- private:
-  // Overridden from IWindowManager:
-  virtual void CloseWindow(Id view_id) override;
-  virtual void ShowKeyboard(Id view_id, RectPtr bounds) override;
-  virtual void HideKeyboard(Id view_id) override;
-
-  WindowManager* window_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection);
-};
-
-class NavigatorHostImpl : public InterfaceImpl<NavigatorHost> {
- public:
-  explicit NavigatorHostImpl(WindowManager* window_manager, Id view_id)
-      : window_manager_(window_manager), view_id_(view_id) {}
-  virtual ~NavigatorHostImpl() {
-  }
-
- private:
-  virtual void DidNavigateLocally(const mojo::String& url) override;
-  virtual void RequestNavigate(Target target, URLRequestPtr request) override;
-
-  WindowManager* window_manager_;
-  Id view_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(NavigatorHostImpl);
-};
-
-class KeyboardManager : public KeyboardClient,
-                        public ViewObserver {
- public:
-  KeyboardManager() : view_manager_(NULL), view_(NULL) {
-  }
-  virtual ~KeyboardManager() {
-    if (view_)
-      view_->parent()->RemoveObserver(this);
-  }
-
-  View* view() { return view_; }
-
-  void Init(ApplicationImpl* application,
-            ViewManager* view_manager,
-            View* parent,
-            const gfx::Rect& bounds) {
-    view_manager_ = view_manager;
-    view_ = View::Create(view_manager);
-    view_->SetBounds(bounds);
-    parent->AddChild(view_);
-    view_->Embed("mojo:keyboard");
-    application->ConnectToService("mojo:keyboard", &keyboard_service_);
-    keyboard_service_.set_client(this);
-    parent->AddObserver(this);
-  }
-
-  void Show(Id view_id, const gfx::Rect& bounds) {
-    keyboard_service_->SetTarget(view_id);
-    view_->SetVisible(true);
-  }
-
-  void Hide(Id view_id) {
-    keyboard_service_->SetTarget(0);
-    view_->SetVisible(false);
-  }
-
- private:
-  // KeyboardClient:
-  virtual void OnKeyboardEvent(Id view_id,
-                               int32_t code,
-                               int32_t flags) override {
-    // TODO(sky): figure this out. Code use to dispatch events, but that's a
-    // hack. Instead strings should be passed through, or maybe a richer text
-    // input interface.
-  }
-
-  // Overridden from ViewObserver:
-  virtual void OnViewBoundsChanged(View* parent,
-                                   const gfx::Rect& old_bounds,
-                                   const gfx::Rect& new_bounds) override {
-    gfx::Rect keyboard_bounds(view_->bounds());
-    keyboard_bounds.set_y(new_bounds.bottom() - keyboard_bounds.height());
-    keyboard_bounds.set_width(keyboard_bounds.width() +
-                              new_bounds.width() - old_bounds.width());
-    view_->SetBounds(keyboard_bounds);
-  }
-  virtual void OnViewDestroyed(View* parent) override {
-    DCHECK_EQ(parent, view_->parent());
-    parent->RemoveObserver(this);
-    view_ = NULL;
-  }
-
-  KeyboardServicePtr keyboard_service_;
-  ViewManager* view_manager_;
-
-  // View the keyboard is attached to.
-  View* view_;
-
-  DISALLOW_COPY_AND_ASSIGN(KeyboardManager);
-};
-
-class RootLayoutManager : public ViewObserver {
- public:
-  RootLayoutManager(ViewManager* view_manager,
-                    View* root,
-                    Id content_view_id,
-                    Id launcher_ui_view_id,
-                    Id control_panel_view_id)
-      : root_(root),
-        view_manager_(view_manager),
-        content_view_id_(content_view_id),
-        launcher_ui_view_id_(launcher_ui_view_id),
-        control_panel_view_id_(control_panel_view_id) {}
-  virtual ~RootLayoutManager() {
-    if (root_)
-      root_->RemoveObserver(this);
-  }
-
- private:
-  // Overridden from ViewObserver:
-  virtual void OnViewBoundsChanged(View* view,
-                                   const gfx::Rect& old_bounds,
-                                   const gfx::Rect& new_bounds) override {
-    DCHECK_EQ(view, root_);
-
-    View* content_view = view_manager_->GetViewById(content_view_id_);
-    content_view->SetBounds(new_bounds);
-
-    int delta_width = new_bounds.width() - old_bounds.width();
-    int delta_height = new_bounds.height() - old_bounds.height();
-
-    View* launcher_ui_view =
-        view_manager_->GetViewById(launcher_ui_view_id_);
-    gfx::Rect launcher_ui_bounds(launcher_ui_view->bounds());
-    launcher_ui_bounds.set_width(launcher_ui_bounds.width() + delta_width);
-    launcher_ui_view->SetBounds(launcher_ui_bounds);
-
-    View* control_panel_view =
-        view_manager_->GetViewById(control_panel_view_id_);
-    gfx::Rect control_panel_bounds(control_panel_view->bounds());
-    control_panel_bounds.set_x(control_panel_bounds.x() + delta_width);
-    control_panel_view->SetBounds(control_panel_bounds);
-
-    const View::Children& content_views = content_view->children();
-    View::Children::const_iterator iter = content_views.begin();
-    for(; iter != content_views.end(); ++iter) {
-      View* view = *iter;
-      if (view->id() == control_panel_view->id() ||
-          view->id() == launcher_ui_view->id())
-        continue;
-      gfx::Rect view_bounds(view->bounds());
-      view_bounds.set_width(view_bounds.width() + delta_width);
-      view_bounds.set_height(view_bounds.height() + delta_height);
-      view->SetBounds(view_bounds);
-    }
-  }
-  virtual void OnViewDestroyed(View* view) override {
-    DCHECK_EQ(view, root_);
-    root_->RemoveObserver(this);
-    root_ = NULL;
-  }
-
-  View* root_;
-  ViewManager* view_manager_;
-  const Id content_view_id_;
-  const Id launcher_ui_view_id_;
-  const Id control_panel_view_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(RootLayoutManager);
-};
-
-class Window : public InterfaceFactory<NavigatorHost> {
- public:
-  Window(WindowManager* window_manager, View* view)
-      : window_manager_(window_manager), view_(view) {}
-
-  virtual ~Window() {}
-
-  View* view() const { return view_; }
-
-  void Embed(const std::string& url) {
-    scoped_ptr<ServiceProviderImpl> service_provider_impl(
-        new ServiceProviderImpl());
-    service_provider_impl->AddService<NavigatorHost>(this);
-    view_->Embed(url, service_provider_impl.Pass());
-  }
-
- private:
-  // InterfaceFactory<NavigatorHost>
-  virtual void Create(ApplicationConnection* connection,
-                      InterfaceRequest<NavigatorHost> request) override {
-    BindToRequest(new NavigatorHostImpl(window_manager_, view_->id()),
-                  &request);
-  }
-
-  WindowManager* window_manager_;
-  View* view_;
-};
-
-class WindowManager
-    : public ApplicationDelegate,
-      public DebugPanel::Delegate,
-      public ViewManagerDelegate,
-      public WindowManagerDelegate,
-      public ui::EventHandler {
- public:
-  WindowManager()
-      : shell_(nullptr),
-        window_manager_factory_(this),
-        launcher_ui_(NULL),
-        view_manager_(NULL),
-        window_manager_app_(new WindowManagerApp(this, this)),
-        app_(NULL) {}
-
-  virtual ~WindowManager() {
-    // host() may be destroyed by the time we get here.
-    // TODO: figure out a way to always cleanly remove handler.
-    if (window_manager_app_->host())
-      window_manager_app_->host()->window()->RemovePreTargetHandler(this);
-  }
-
-  void CloseWindow(Id view_id) {
-    WindowVector::iterator iter = GetWindowByViewId(view_id);
-    DCHECK(iter != windows_.end());
-    Window* window = *iter;
-    windows_.erase(iter);
-    window->view()->Destroy();
-  }
-
-  void ShowKeyboard(Id view_id, const gfx::Rect& bounds) {
-    // TODO: this needs to validate |view_id|. That is, it shouldn't assume
-    // |view_id| is valid and it also needs to make sure the client that sent
-    // this really owns |view_id|.
-    // TODO: honor |bounds|.
-    if (!keyboard_manager_) {
-      keyboard_manager_.reset(new KeyboardManager);
-      View* parent = view_manager_->GetRoots().back();
-      int ideal_height = 200;
-      // TODO(sky): 10 is a bit of a hack here. There is a bug that causes
-      // white strips to appear when 0 is used. Figure this out!
-      const gfx::Rect keyboard_bounds(
-          10, parent->bounds().height() - ideal_height,
-          parent->bounds().width() - 20, ideal_height);
-      keyboard_manager_->Init(app_, view_manager_, parent, keyboard_bounds);
-    }
-    keyboard_manager_->Show(view_id, bounds);
-  }
-
-  void HideKeyboard(Id view_id) {
-    // See comment in ShowKeyboard() about validating args.
-    if (keyboard_manager_)
-      keyboard_manager_->Hide(view_id);
-  }
-
-  void DidNavigateLocally(uint32 source_view_id, const mojo::String& url) {
-    LOG(ERROR) << "DidNavigateLocally: source_view_id: " << source_view_id
-               << " url: " << url.To<std::string>();
-  }
-
-  // Overridden from DebugPanel::Delegate:
-  virtual void CloseTopWindow() override {
-    if (!windows_.empty())
-      CloseWindow(windows_.back()->view()->id());
-  }
-
-  virtual void RequestNavigate(uint32 source_view_id,
-                               Target target,
-                               URLRequestPtr request) override {
-    OnLaunch(source_view_id, target, request->url);
-  }
-
- private:
-  typedef std::vector<Window*> WindowVector;
-
-  // Overridden from ApplicationDelegate:
-  virtual void Initialize(ApplicationImpl* app) override {
-    shell_ = app->shell();
-    app_ = app;
-    views_init_.reset(new ViewsInit);
-    window_manager_app_->Initialize(app);
-  }
-
-  virtual bool ConfigureIncomingConnection(
-      ApplicationConnection* connection) override {
-    connection->AddService(&window_manager_factory_);
-    window_manager_app_->ConfigureIncomingConnection(connection);
-    return true;
-  }
-
-  // Overridden from ViewManagerDelegate:
-  virtual void OnEmbed(ViewManager* view_manager,
-                       View* root,
-                       ServiceProviderImpl* exported_services,
-                       scoped_ptr<ServiceProvider> imported_services) override {
-    DCHECK(!view_manager_);
-    view_manager_ = view_manager;
-
-    View* view = View::Create(view_manager_);
-    root->AddChild(view);
-    view->SetBounds(gfx::Rect(root->bounds().size()));
-    content_view_id_ = view->id();
-
-    Id launcher_ui_id = CreateLauncherUI();
-    Id control_panel_id = CreateControlPanel(view);
-
-    root_layout_manager_.reset(
-        new RootLayoutManager(view_manager, root,
-                              content_view_id_,
-                              launcher_ui_id,
-                              control_panel_id));
-    root->AddObserver(root_layout_manager_.get());
-
-    window_manager_app_->host()->window()->AddPreTargetHandler(this);
-
-    window_manager_app_->InitFocus(new WMFocusRules(window_manager_app_.get(),
-                                                    view));
-  }
-  virtual void OnViewManagerDisconnected(ViewManager* view_manager) override {
-    DCHECK_EQ(view_manager_, view_manager);
-    view_manager_ = NULL;
-    base::MessageLoop::current()->Quit();
-  }
-
-  // Overridden from WindowManagerDelegate:
-  virtual void Embed(
-      const String& url,
-      InterfaceRequest<ServiceProvider> service_provider) override {
-    const Id kInvalidSourceViewId = 0;
-    OnLaunch(kInvalidSourceViewId, TARGET_DEFAULT, url);
-  }
-
-  // Overridden from ui::EventHandler:
-  virtual void OnEvent(ui::Event* event) override {
-    View* view = WindowManagerApp::GetViewForWindow(
-        static_cast<aura::Window*>(event->target()));
-    if (event->type() == ui::ET_MOUSE_PRESSED &&
-        !IsDescendantOfKeyboard(view)) {
-      view->SetFocus();
-    }
-  }
-
-  void OnLaunch(uint32 source_view_id,
-                Target requested_target,
-                const mojo::String& url) {
-    Target target = debug_panel_->navigation_target();
-    if (target == TARGET_DEFAULT) {
-      if (requested_target != TARGET_DEFAULT) {
-        target = requested_target;
-      } else {
-        // TODO(aa): Should be TARGET_NEW_NODE if source origin and dest origin
-        // are different?
-        target = TARGET_SOURCE_NODE;
-      }
-    }
-
-    Window* dest_view = NULL;
-    if (target == TARGET_SOURCE_NODE) {
-      WindowVector::iterator source_view = GetWindowByViewId(source_view_id);
-      bool app_initiated = source_view != windows_.end();
-      if (app_initiated)
-        dest_view = *source_view;
-      else if (!windows_.empty())
-        dest_view = windows_.back();
-    }
-
-    if (!dest_view) {
-      dest_view = CreateWindow();
-      windows_.push_back(dest_view);
-    }
-
-    dest_view->Embed(url);
-  }
-
-  // TODO(beng): proper layout manager!!
-  Id CreateLauncherUI() {
-    View* view = view_manager_->GetViewById(content_view_id_);
-    gfx::Rect bounds = view->bounds();
-    bounds.Inset(kBorderInset, kBorderInset);
-    bounds.set_height(kTextfieldHeight);
-    launcher_ui_ = CreateWindow(bounds);
-    launcher_ui_->Embed("mojo:browser");
-    return launcher_ui_->view()->id();
-  }
-
-  Window* CreateWindow() {
-    View* view = view_manager_->GetViewById(content_view_id_);
-    gfx::Rect bounds(kBorderInset,
-                     2 * kBorderInset + kTextfieldHeight,
-                     view->bounds().width() - 3 * kBorderInset -
-                         kControlPanelWidth,
-                     view->bounds().height() -
-                         (3 * kBorderInset + kTextfieldHeight));
-    if (!windows_.empty()) {
-      gfx::Point position = windows_.back()->view()->bounds().origin();
-      position.Offset(35, 35);
-      bounds.set_origin(position);
-    }
-    return CreateWindow(bounds);
-  }
-
-  Window* CreateWindow(const gfx::Rect& bounds) {
-    View* content = view_manager_->GetViewById(content_view_id_);
-    View* view = View::Create(view_manager_);
-    content->AddChild(view);
-    view->SetBounds(bounds);
-    view->SetFocus();
-    return new Window(this, view);
-  }
-
-  bool IsDescendantOfKeyboard(View* target) {
-    return keyboard_manager_.get() &&
-        keyboard_manager_->view()->Contains(target);
-  }
-
-  Id CreateControlPanel(View* root) {
-    View* view = View::Create(view_manager_);
-    root->AddChild(view);
-
-    gfx::Rect bounds(root->bounds().width() - kControlPanelWidth -
-                         kBorderInset,
-                     kBorderInset * 2 + kTextfieldHeight,
-                     kControlPanelWidth,
-                     root->bounds().height() - kBorderInset * 3 -
-                         kTextfieldHeight);
-    view->SetBounds(bounds);
-
-    debug_panel_ = new DebugPanel(this, shell_, view);
-    return view->id();
-  }
-
-  WindowVector::iterator GetWindowByViewId(Id view_id) {
-    for (std::vector<Window*>::iterator iter = windows_.begin();
-         iter != windows_.end();
-         ++iter) {
-      if ((*iter)->view()->id() == view_id) {
-        return iter;
-      }
-    }
-    return windows_.end();
-  }
-
-  Shell* shell_;
-
-  InterfaceFactoryImplWithContext<WindowManagerConnection, WindowManager>
-      window_manager_factory_;
-
-  scoped_ptr<ViewsInit> views_init_;
-  DebugPanel* debug_panel_;
-  Window* launcher_ui_;
-  WindowVector windows_;
-  ViewManager* view_manager_;
-  scoped_ptr<RootLayoutManager> root_layout_manager_;
-
-  scoped_ptr<WindowManagerApp> window_manager_app_;
-
-  // Id of the view most content is added to. The keyboard is NOT added here.
-  Id content_view_id_;
-
-  scoped_ptr<KeyboardManager> keyboard_manager_;
-  ApplicationImpl* app_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManager);
-};
-
-void WindowManagerConnection::CloseWindow(Id view_id) {
-  window_manager_->CloseWindow(view_id);
-}
-
-void WindowManagerConnection::ShowKeyboard(Id view_id, RectPtr bounds) {
-  window_manager_->ShowKeyboard(view_id, bounds.To<gfx::Rect>());
-}
-
-void WindowManagerConnection::HideKeyboard(Id view_id) {
-  window_manager_->HideKeyboard(view_id);
-}
-
-void NavigatorHostImpl::DidNavigateLocally(const mojo::String& url) {
-  window_manager_->DidNavigateLocally(view_id_, url);
-}
-
-void NavigatorHostImpl::RequestNavigate(Target target, URLRequestPtr request) {
-  window_manager_->RequestNavigate(view_id_, target, request.Pass());
-}
-
-}  // namespace examples
-}  // namespace mojo
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new mojo::examples::WindowManager);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/examples/window_manager/window_manager.mojom b/mojo/examples/window_manager/window_manager.mojom
deleted file mode 100644
index c6b4187e..0000000
--- a/mojo/examples/window_manager/window_manager.mojom
+++ /dev/null
@@ -1,22 +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.
-
-import "mojo/services/public/interfaces/geometry/geometry.mojom"
-
-module mojo {
-
-interface IWindowManager {
-  CloseWindow(uint32 node_id);
-
-  // Shows the keyboard for the specified view. |bounds| is the bounds of the
-  // view that is showing focus. |bounds| is relative to the bounds of the node.
-  // Events from the keyboard are routed to the view with id |view_id|.
-  ShowKeyboard(uint32 view_id, mojo.Rect? bounds);
-
-  // Hides the keyboard. This is ignored if |view_id| is not the view that was
-  // last passed to ShowKeyboard().
-  HideKeyboard(uint32 view_id);
-};
-
-}
diff --git a/mojo/examples/wm_flow/BUILD.gn b/mojo/examples/wm_flow/BUILD.gn
deleted file mode 100644
index 5f70abf..0000000
--- a/mojo/examples/wm_flow/BUILD.gn
+++ /dev/null
@@ -1,111 +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.
-
-import("//build/config/ui.gni")
-import("//mojo/public/tools/bindings/mojom.gni")
-
-assert(use_aura)
-
-group("wm_flow") {
-  deps = [
-    ":app",
-    ":embedded",
-    ":init",
-    ":wm",
-  ]
-}
-
-shared_library("wm") {
-  output_name = "mojo_wm_flow_wm"
-
-  sources = [
-    "wm/wm.cc",
-    "wm/frame_controller.cc",
-    "wm/frame_controller.h",
-  ]
-
-  deps = [
-    "//base",
-    "//skia",
-    "//ui/aura",
-    "//ui/views",
-    "//ui/wm:wm",
-    "//mojo/application",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/public/interfaces/input_events",
-    "//mojo/services/window_manager:lib",
-    "//mojo/views:views",
-  ]
-}
-
-shared_library("init") {
-  output_name = "mojo_wm_flow_init"
-
-  sources = [
-    "init/init.cc",
-  ]
-
-  deps = [
-    "//base",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-    "//mojo/application",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/public/interfaces/application:application",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/public/interfaces/view_manager",
-  ]
-}
-
-shared_library("app") {
-  output_name = "mojo_wm_flow_app"
-
-  sources = [
-    "app/app.cc",
-  ]
-
-  deps = [
-    ":embedder_bindings",
-    ":embeddee_bindings",
-    "//base",
-    "//mojo/application",
-    "//mojo/examples/bitmap_uploader",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/public/interfaces/application:application",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/window_manager:lib",
-  ]
-}
-
-shared_library("embedded") {
-  output_name = "mojo_wm_flow_embedded"
-
-  sources = [
-    "embedded/embedded.cc",
-  ]
-
-  deps = [
-    ":embedder_bindings",
-    ":embeddee_bindings",
-    "//base",
-    "//mojo/application",
-    "//mojo/examples/bitmap_uploader",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/window_manager:lib",
-  ]
-}
-
-mojom("embedder_bindings") {
-  sources = [
-    "app/embedder.mojom",
-  ]
-}
-
-mojom("embeddee_bindings") {
-  sources = [
-    "embedded/embeddee.mojom",
-  ]
-}
diff --git a/mojo/examples/wm_flow/app/app.cc b/mojo/examples/wm_flow/app/app.cc
deleted file mode 100644
index d9a8da2..0000000
--- a/mojo/examples/wm_flow/app/app.cc
+++ /dev/null
@@ -1,154 +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 <map>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/stl_util.h"
-#include "mojo/application/application_runner_chromium.h"
-#include "mojo/examples/bitmap_uploader/bitmap_uploader.h"
-#include "mojo/examples/wm_flow/app/embedder.mojom.h"
-#include "mojo/examples/wm_flow/embedded/embeddee.mojom.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/connect.h"
-#include "mojo/public/cpp/application/interface_factory_impl.h"
-#include "mojo/public/cpp/application/service_provider_impl.h"
-#include "mojo/public/interfaces/application/service_provider.mojom.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_context.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/public/cpp/view_manager/view_observer.h"
-
-namespace examples {
-namespace {
-
-const SkColor kColors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorYELLOW };
-
-class EmbedderImpl : public mojo::InterfaceImpl<Embedder> {
- public:
-  EmbedderImpl() {}
-  virtual ~EmbedderImpl() {}
-
- private:
-  // Overridden from Embedder:
-  virtual void HelloWorld(const mojo::Callback<void()>& callback) override {
-    callback.Run();
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(EmbedderImpl);
-};
-
-}  // namespace
-
-// This app starts its life via Connect() rather than by being embed, so it does
-// not start with a connection to the ViewManager service. It has to obtain a
-// connection by connecting to the ViewManagerInit service and asking to be
-// embed without a view context.
-class WMFlowApp : public mojo::ApplicationDelegate,
-                  public mojo::ViewManagerDelegate,
-                  public mojo::ViewObserver {
- public:
-  WMFlowApp() : shell_(nullptr), embed_count_(0) {}
-  virtual ~WMFlowApp() { STLDeleteValues(&uploaders_); }
-
- private:
-  typedef std::map<mojo::View*, mojo::BitmapUploader*> ViewToUploader;
-
-  // Overridden from Application:
-  virtual void Initialize(mojo::ApplicationImpl* app) override {
-    shell_ = app->shell();
-    view_manager_client_factory_.reset(
-        new mojo::ViewManagerClientFactory(app->shell(), this));
-    view_manager_context_.reset(new mojo::ViewManagerContext(app));
-    OpenNewWindow();
-    OpenNewWindow();
-    OpenNewWindow();
-  }
-  virtual bool ConfigureIncomingConnection(
-      mojo::ApplicationConnection* connection) override {
-    connection->AddService(view_manager_client_factory_.get());
-    return true;
-  }
-
-  void OnConnect(bool success) {}
-
-  // Overridden from mojo::ViewManagerDelegate:
-  virtual void OnEmbed(
-      mojo::ViewManager* view_manager,
-      mojo::View* root,
-      mojo::ServiceProviderImpl* exported_services,
-      scoped_ptr<mojo::ServiceProvider> imported_services) override {
-    root->AddObserver(this);
-    mojo::BitmapUploader* uploader = new mojo::BitmapUploader(root);
-    uploaders_[root] = uploader;
-    uploader->Init(shell_);
-    uploader->SetColor(kColors[embed_count_++ % arraysize(kColors)]);
-
-    mojo::View* embed = mojo::View::Create(view_manager);
-    root->AddChild(embed);
-    gfx::Rect bounds = gfx::Rect(root->bounds().size());
-    bounds.Inset(25, 25);
-    embed->SetBounds(bounds);
-
-    scoped_ptr<mojo::ServiceProviderImpl> registry(
-        new mojo::ServiceProviderImpl);
-    // Expose some services to the embeddee...
-    registry->AddService(&embedder_factory_);
-    scoped_ptr<mojo::ServiceProvider> imported =
-        embed->Embed("mojo:wm_flow_embedded", registry.Pass());
-    mojo::ConnectToService(imported.get(), &embeddee_);
-    embeddee_->HelloBack(base::Bind(&WMFlowApp::HelloBackAck,
-                                    base::Unretained(this)));
-  }
-  virtual void OnViewManagerDisconnected(
-      mojo::ViewManager* view_manager) override {
-    STLDeleteValues(&uploaders_);
-  }
-
-  // Overridden from mojo::ViewObserver:
-  virtual void OnViewInputEvent(mojo::View* view,
-                                const mojo::EventPtr& event) override {
-    if (event->action == mojo::EVENT_TYPE_MOUSE_RELEASED &&
-        event->flags & mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON) {
-      OpenNewWindow();
-    }
-  }
-  virtual void OnViewDestroyed(mojo::View* view) override {
-    if (uploaders_.find(view) != uploaders_.end()) {
-      delete uploaders_[view];
-      uploaders_.erase(view);
-    }
-    --embed_count_;
-    view->RemoveObserver(this);
-  }
-
-  void HelloBackAck() {
-    printf("HelloBack() ack'ed\n");
-  }
-
-  void OpenNewWindow() { view_manager_context_->Embed("mojo:wm_flow_app"); }
-
-  mojo::Shell* shell_;
-  int embed_count_;
-  scoped_ptr<mojo::ViewManagerClientFactory> view_manager_client_factory_;
-  mojo::InterfaceFactoryImpl<EmbedderImpl> embedder_factory_;
-  scoped_ptr<mojo::ViewManagerContext> view_manager_context_;
-  EmbeddeePtr embeddee_;
-  ViewToUploader uploaders_;
-
-  DISALLOW_COPY_AND_ASSIGN(WMFlowApp);
-};
-
-}  // namespace examples
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new examples::WMFlowApp);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/examples/wm_flow/app/embedder.mojom b/mojo/examples/wm_flow/app/embedder.mojom
deleted file mode 100644
index aae78705..0000000
--- a/mojo/examples/wm_flow/app/embedder.mojom
+++ /dev/null
@@ -1,11 +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.
-
-module examples {
-
-interface Embedder {
-  HelloWorld() => ();
-};
-
-}
diff --git a/mojo/examples/wm_flow/embedded/embedded.cc b/mojo/examples/wm_flow/embedded/embedded.cc
deleted file mode 100644
index d328501..0000000
--- a/mojo/examples/wm_flow/embedded/embedded.cc
+++ /dev/null
@@ -1,98 +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 "base/bind.h"
-#include "base/macros.h"
-#include "mojo/application/application_runner_chromium.h"
-#include "mojo/examples/bitmap_uploader/bitmap_uploader.h"
-#include "mojo/examples/wm_flow/app/embedder.mojom.h"
-#include "mojo/examples/wm_flow/embedded/embeddee.mojom.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/connect.h"
-#include "mojo/public/cpp/application/interface_factory_impl.h"
-#include "mojo/public/cpp/application/service_provider_impl.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-
-namespace examples {
-
-namespace {
-
-class EmbeddeeImpl : public mojo::InterfaceImpl<Embeddee> {
- public:
-  EmbeddeeImpl() {}
-  virtual ~EmbeddeeImpl() {}
-
- private:
-  // Overridden from Embeddee:
-  virtual void HelloBack(const mojo::Callback<void()>& callback) override {
-    callback.Run();
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(EmbeddeeImpl);
-};
-
-}  // namespace
-
-class WMFlowEmbedded : public mojo::ApplicationDelegate,
-                       public mojo::ViewManagerDelegate {
- public:
-  WMFlowEmbedded() : shell_(nullptr) {}
-  virtual ~WMFlowEmbedded() {}
-
- private:
-  // Overridden from Application:
-  virtual void Initialize(mojo::ApplicationImpl* app) override {
-    shell_ = app->shell();
-    view_manager_client_factory_.reset(
-        new mojo::ViewManagerClientFactory(app->shell(), this));
-  }
-  virtual bool ConfigureIncomingConnection(
-      mojo::ApplicationConnection* connection) override {
-    connection->AddService(view_manager_client_factory_.get());
-    return true;
-  }
-
-  // Overridden from mojo::ViewManagerDelegate:
-  virtual void OnEmbed(
-      mojo::ViewManager* view_manager,
-      mojo::View* root,
-      mojo::ServiceProviderImpl* exported_services,
-      scoped_ptr<mojo::ServiceProvider> imported_services) override {
-    bitmap_uploader_.reset(new mojo::BitmapUploader(root));
-    bitmap_uploader_->Init(shell_);
-    bitmap_uploader_->SetColor(SK_ColorMAGENTA);
-
-    exported_services->AddService(&embeddee_factory_);
-    mojo::ConnectToService(imported_services.get(), &embedder_);
-    embedder_->HelloWorld(base::Bind(&WMFlowEmbedded::HelloWorldAck,
-                                     base::Unretained(this)));
-  }
-  virtual void OnViewManagerDisconnected(
-      mojo::ViewManager* view_manager) override {}
-
-  void HelloWorldAck() {
-    printf("HelloWorld() ack'ed\n");
-  }
-
-  mojo::Shell* shell_;
-  scoped_ptr<mojo::ViewManagerClientFactory> view_manager_client_factory_;
-  EmbedderPtr embedder_;
-  mojo::InterfaceFactoryImpl<EmbeddeeImpl> embeddee_factory_;
-  scoped_ptr<mojo::BitmapUploader> bitmap_uploader_;
-
-  DISALLOW_COPY_AND_ASSIGN(WMFlowEmbedded);
-};
-
-}  // namespace examples
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new examples::WMFlowEmbedded);
-  return runner.Run(shell_handle);
-}
-
diff --git a/mojo/examples/wm_flow/embedded/embeddee.mojom b/mojo/examples/wm_flow/embedded/embeddee.mojom
deleted file mode 100644
index b989da23..0000000
--- a/mojo/examples/wm_flow/embedded/embeddee.mojom
+++ /dev/null
@@ -1,11 +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.
-
-module examples {
-
-interface Embeddee {
-  HelloBack() => ();
-};
-
-}
diff --git a/mojo/examples/wm_flow/init/init.cc b/mojo/examples/wm_flow/init/init.cc
deleted file mode 100644
index 5738edd..0000000
--- a/mojo/examples/wm_flow/init/init.cc
+++ /dev/null
@@ -1,40 +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 "mojo/application/application_runner_chromium.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_context.h"
-
-namespace examples {
-
-// This application starts the view manager, embeds the window manager and then
-// starts another app (wm_flow_app) which also connects to the view manager and
-// asks to be embedded without context.
-class WMFlowInit : public mojo::ApplicationDelegate {
- public:
-  WMFlowInit() {}
-  virtual ~WMFlowInit() {}
-
- private:
-  // Overridden from Application:
-  virtual void Initialize(mojo::ApplicationImpl* app) override {
-    context_.reset(new mojo::ViewManagerContext(app));
-    context_->Embed("mojo:wm_flow_wm");
-    app->ConnectToApplication("mojo:wm_flow_app");
-  }
-
-  scoped_ptr<mojo::ViewManagerContext> context_;
-
-  DISALLOW_COPY_AND_ASSIGN(WMFlowInit);
-};
-
-}  // namespace examples
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new examples::WMFlowInit);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/examples/wm_flow/wm/DEPS b/mojo/examples/wm_flow/wm/DEPS
deleted file mode 100644
index 1486b9f..0000000
--- a/mojo/examples/wm_flow/wm/DEPS
+++ /dev/null
@@ -1,7 +0,0 @@
-include_rules = [
-  "+ui/aura",
-  "+ui/gfx/geometry",
-  "+ui/views",
-  "+ui/wm/core",
-  "+ui/wm/public",
-]
diff --git a/mojo/examples/wm_flow/wm/frame_controller.cc b/mojo/examples/wm_flow/wm/frame_controller.cc
deleted file mode 100644
index 40ff041..0000000
--- a/mojo/examples/wm_flow/wm/frame_controller.cc
+++ /dev/null
@@ -1,157 +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 "mojo/examples/wm_flow/wm/frame_controller.h"
-
-#include "base/macros.h"
-#include "base/strings/utf_string_conversions.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/window_manager/window_manager_app.h"
-#include "mojo/views/native_widget_view_manager.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/layout/layout_manager.h"
-#include "ui/views/widget/widget.h"
-#include "ui/wm/public/activation_client.h"
-
-class FrameController::LayoutManager : public views::LayoutManager,
-                                       public views::ButtonListener {
- public:
-  explicit LayoutManager(FrameController* controller)
-      : controller_(controller),
-        close_button_(
-            new views::LabelButton(this, base::ASCIIToUTF16("Begone"))),
-        maximize_button_(
-            new views::LabelButton(this, base::ASCIIToUTF16("Embiggen"))) {}
-  virtual ~LayoutManager() {}
-
- private:
-  static const int kButtonFrameMargin = 5;
-  static const int kButtonFrameSpacing = 2;
-  static const int kFrameSize = 10;
-
-  // Overridden from views::LayoutManager:
-  virtual void Installed(views::View* host) override {
-    host->AddChildView(close_button_);
-    host->AddChildView(maximize_button_);
-  }
-  virtual void Layout(views::View* host) override {
-    gfx::Size ps = close_button_->GetPreferredSize();
-    gfx::Rect bounds = host->GetLocalBounds();
-    close_button_->SetBounds(bounds.right() - kButtonFrameMargin - ps.width(),
-                             kButtonFrameMargin, ps.width(), ps.height());
-
-    ps = maximize_button_->GetPreferredSize();
-    maximize_button_->SetBounds(
-        close_button_->x() - kButtonFrameSpacing - ps.width(),
-        kButtonFrameMargin, ps.width(), ps.height());
-
-    bounds.Inset(kFrameSize,
-                 close_button_->bounds().bottom() + kButtonFrameMargin,
-                 kFrameSize, kFrameSize);
-    controller_->app_view_->SetBounds(bounds);
-  }
-  virtual gfx::Size GetPreferredSize(const views::View* host) const override {
-    return gfx::Size();
-  }
-
-  // Overridden from views::ButtonListener:
-  virtual void ButtonPressed(views::Button* sender,
-                             const ui::Event& event) override {
-    if (sender == close_button_)
-      controller_->CloseWindow();
-    else if (sender == maximize_button_)
-      controller_->ToggleMaximize();
-  }
-
-  FrameController* controller_;
-  views::Button* close_button_;
-  views::Button* maximize_button_;
-
-  DISALLOW_COPY_AND_ASSIGN(LayoutManager);
-};
-
-class FrameController::FrameEventHandler : public ui::EventHandler {
- public:
-  explicit FrameEventHandler(FrameController* frame_controller)
-      : frame_controller_(frame_controller) {}
-  virtual ~FrameEventHandler() {}
-
- private:
-
-  // Overriden from ui::EventHandler:
-  virtual void OnMouseEvent(ui::MouseEvent* event) override {
-    if (event->type() == ui::ET_MOUSE_PRESSED)
-      frame_controller_->ActivateWindow();
-  }
-
-  FrameController* frame_controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(FrameEventHandler);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// FrameController, public:
-
-FrameController::FrameController(
-    mojo::Shell* shell,
-    mojo::View* view,
-    mojo::View** app_view,
-    aura::client::ActivationClient* activation_client,
-    mojo::WindowManagerApp* window_manager_app)
-    : view_(view),
-      app_view_(mojo::View::Create(view->view_manager())),
-      frame_view_(new views::View),
-      frame_view_layout_manager_(new LayoutManager(this)),
-      widget_(new views::Widget),
-      maximized_(false),
-      activation_client_(activation_client),
-      window_manager_app_(window_manager_app) {
-  view_->AddChild(app_view_);
-  view_->AddObserver(this);
-  *app_view = app_view_;
-  frame_view_->set_background(
-      views::Background::CreateSolidBackground(SK_ColorBLUE));
-  frame_view_->SetLayoutManager(frame_view_layout_manager_);
-  frame_event_handler_.reset(new FrameEventHandler(this));
-  frame_view_->AddPreTargetHandler(frame_event_handler_.get());
-  views::Widget::InitParams params(
-      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
-  params.native_widget =
-      new mojo::NativeWidgetViewManager(widget_, shell, view_);
-  params.bounds = gfx::Rect(view_->bounds().size());
-  widget_->Init(params);
-  widget_->SetContentsView(frame_view_);
-  widget_->Show();
-}
-
-FrameController::~FrameController() {}
-
-void FrameController::CloseWindow() {
-  app_view_->Destroy();
-  view_->Destroy();
-}
-
-void FrameController::ToggleMaximize() {
-  if (!maximized_)
-    restored_bounds_ = view_->bounds();
-  maximized_ = !maximized_;
-  if (maximized_)
-    view_->SetBounds(view_->parent()->bounds());
-  else
-    view_->SetBounds(restored_bounds_);
-}
-
-void FrameController::ActivateWindow() {
-  aura::Window* window = window_manager_app_->GetWindowForViewId(view_->id());
-  activation_client_->ActivateWindow(window);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// FrameController, mojo::ViewObserver implementation:
-
-void FrameController::OnViewDestroyed(mojo::View* view) {
-  view_->RemoveObserver(this);
-  delete this;
-}
diff --git a/mojo/examples/wm_flow/wm/frame_controller.h b/mojo/examples/wm_flow/wm/frame_controller.h
deleted file mode 100644
index 0add0a1e..0000000
--- a/mojo/examples/wm_flow/wm/frame_controller.h
+++ /dev/null
@@ -1,68 +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 MOJO_EXAMPLES_WM_FLOW_WM_FRAME_CONTROLLER_H_
-#define MOJO_EXAMPLES_WM_FLOW_WM_FRAME_CONTROLLER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "mojo/services/public/cpp/view_manager/view_observer.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace aura {
-namespace client {
-class ActivationClient;
-}
-}
-
-namespace mojo {
-class NativeWidgetViewManager;
-class Shell;
-class View;
-class WindowManagerApp;
-}
-
-namespace views {
-class View;
-class Widget;
-}
-
-// FrameController encapsulates the window manager's frame additions to a window
-// created by an application. It renders the content of the frame and responds
-// to any events targeted at it.
-class FrameController : mojo::ViewObserver {
- public:
-  FrameController(mojo::Shell* shell,
-                  mojo::View* view,
-                  mojo::View** app_view,
-                  aura::client::ActivationClient* activation_client,
-                  mojo::WindowManagerApp* window_manager_app);
-  virtual ~FrameController();
-
-  void CloseWindow();
-  void ToggleMaximize();
-
-  void ActivateWindow();
-
- private:
-  class LayoutManager;
-  friend class LayoutManager;
-  class FrameEventHandler;
-
-  virtual void OnViewDestroyed(mojo::View* view) override;
-
-  mojo::View* view_;
-  mojo::View* app_view_;
-  views::View* frame_view_;
-  LayoutManager* frame_view_layout_manager_;
-  views::Widget* widget_;
-  bool maximized_;
-  gfx::Rect restored_bounds_;
-  aura::client::ActivationClient* activation_client_;
-  mojo::WindowManagerApp* window_manager_app_;
-  scoped_ptr<FrameEventHandler> frame_event_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(FrameController);
-};
-
-#endif  // MOJO_EXAMPLES_WM_FLOW_WM_FRAME_CONTROLLER_H_
diff --git a/mojo/examples/wm_flow/wm/wm.cc b/mojo/examples/wm_flow/wm/wm.cc
deleted file mode 100644
index 228f04f..0000000
--- a/mojo/examples/wm_flow/wm/wm.cc
+++ /dev/null
@@ -1,208 +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 <vector>
-
-#include "mojo/application/application_runner_chromium.h"
-#include "mojo/examples/wm_flow/wm/frame_controller.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/service_provider_impl.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/public/cpp/view_manager/view_observer.h"
-#include "mojo/services/public/interfaces/input_events/input_events.mojom.h"
-#include "mojo/services/window_manager/window_manager_app.h"
-#include "mojo/services/window_manager/window_manager_delegate.h"
-#include "mojo/views/views_init.h"
-#include "ui/aura/window.h"
-#include "ui/wm/core/focus_rules.h"
-#include "ui/wm/public/activation_client.h"
-
-namespace examples {
-
-namespace {
-
-class WMFocusRules : public wm::FocusRules {
- public:
-  WMFocusRules(mojo::WindowManagerApp* window_manager_app,
-               mojo::View* window_container)
-      : window_container_(window_container),
-        window_manager_app_(window_manager_app) {}
-  virtual ~WMFocusRules() {}
-
- private:
-  // Overridden from wm::FocusRules:
-  virtual bool IsToplevelWindow(aura::Window* window) const override {
-    return mojo::WindowManagerApp::GetViewForWindow(window)->parent() ==
-        window_container_;
-  }
-  virtual bool CanActivateWindow(aura::Window* window) const override {
-    return mojo::WindowManagerApp::GetViewForWindow(window)->parent() ==
-        window_container_;
-  }
-  virtual bool CanFocusWindow(aura::Window* window) const override {
-    return true;
-  }
-  virtual aura::Window* GetToplevelWindow(aura::Window* window) const override {
-    mojo::View* view = mojo::WindowManagerApp::GetViewForWindow(window);
-    while (view->parent() != window_container_) {
-      view = view->parent();
-      // Unparented hierarchy, there is no "top level" window.
-      if (!view)
-        return NULL;
-    }
-
-    return window_manager_app_->GetWindowForViewId(view->id());
-  }
-  virtual aura::Window* GetActivatableWindow(
-      aura::Window* window) const override {
-    return GetToplevelWindow(window);
-  }
-  virtual aura::Window* GetFocusableWindow(
-      aura::Window* window) const override {
-    return window;
-  }
-  virtual aura::Window* GetNextActivatableWindow(
-      aura::Window* ignore) const override {
-    aura::Window* activatable = GetActivatableWindow(ignore);
-    const aura::Window::Windows& children = activatable->parent()->children();
-    for (aura::Window::Windows::const_reverse_iterator it = children.rbegin();
-         it != children.rend(); ++it) {
-      if (*it != ignore)
-        return *it;
-    }
-    return NULL;
-  }
-
-  mojo::View* window_container_;
-  mojo::WindowManagerApp* window_manager_app_;
-
-  DISALLOW_COPY_AND_ASSIGN(WMFocusRules);
-};
-
-}  // namespace
-
-class SimpleWM : public mojo::ApplicationDelegate,
-                 public mojo::ViewManagerDelegate,
-                 public mojo::WindowManagerDelegate,
-                 public mojo::ViewObserver {
- public:
-  SimpleWM()
-      : shell_(nullptr),
-        window_manager_app_(new mojo::WindowManagerApp(this, this)),
-        view_manager_(NULL),
-        root_(NULL),
-        window_container_(NULL),
-        next_window_origin_(10, 10) {}
-  virtual ~SimpleWM() {}
-
- private:
-  // Overridden from mojo::ApplicationDelegate:
-  virtual void Initialize(mojo::ApplicationImpl* impl) override {
-    // Create views_init here as we need ApplicationRunnerChromium to install
-    // an AtExitManager and CommandLine.
-    if (!views_init_.get())
-      views_init_.reset(new mojo::ViewsInit);
-    shell_ = impl->shell();
-    window_manager_app_->Initialize(impl);
-  }
-  virtual bool ConfigureIncomingConnection(
-      mojo::ApplicationConnection* connection) override {
-    window_manager_app_->ConfigureIncomingConnection(connection);
-    return true;
-  }
-
-  // Overridden from mojo::ViewManagerDelegate:
-  virtual void OnEmbed(
-      mojo::ViewManager* view_manager,
-      mojo::View* root,
-      mojo::ServiceProviderImpl* exported_services,
-      scoped_ptr<mojo::ServiceProvider> remote_service_provider) override {
-    view_manager_ = view_manager;
-    root_ = root;
-
-    window_container_ = mojo::View::Create(view_manager_);
-    window_container_->SetBounds(root_->bounds());
-    root_->AddChild(window_container_);
-
-    window_manager_app_->InitFocus(new WMFocusRules(window_manager_app_.get(),
-                                                    window_container_));
-  }
-  virtual void OnViewManagerDisconnected(
-      mojo::ViewManager* view_manager) override {
-    view_manager_ = NULL;
-    root_ = NULL;
-  }
-
-  // Overridden from mojo::WindowManagerDelegate:
-  virtual void Embed(
-      const mojo::String& url,
-      mojo::InterfaceRequest<mojo::ServiceProvider> service_provider) override {
-    mojo::View* app_view = NULL;
-    mojo::View* frame_view = CreateTopLevelWindow(&app_view);
-    window_container_->AddChild(frame_view);
-
-    // TODO(beng): We're dropping the |service_provider| passed from the client
-    //             on the floor here and passing our own. Seems like we should
-    //             be sending both. I'm not yet sure how this sould work for
-    //             N levels of proxying.
-    app_view->Embed(url, scoped_ptr<mojo::ServiceProviderImpl>(
-        new mojo::ServiceProviderImpl).Pass());
-  }
-
-  // Overridden from mojo::ViewObserver:
-  virtual void OnViewInputEvent(mojo::View* view,
-                                const mojo::EventPtr& event) override {
-    if (event->action == mojo::EVENT_TYPE_MOUSE_RELEASED &&
-        event->flags & mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON &&
-        view->parent() == window_container_) {
-      CloseWindow(view);
-    }
-  }
-  virtual void OnViewDestroyed(mojo::View* view) override {
-    view->RemoveObserver(this);
-  }
-
-  void CloseWindow(mojo::View* view) {
-    mojo::View* first_child = view->children().front();
-    first_child->Destroy();
-    view->Destroy();
-    next_window_origin_.Offset(-50, -50);
-  }
-
-  mojo::View* CreateTopLevelWindow(mojo::View** app_view) {
-    mojo::View* frame_view = mojo::View::Create(view_manager_);
-    frame_view->SetBounds(gfx::Rect(next_window_origin_, gfx::Size(400, 400)));
-    next_window_origin_.Offset(50, 50);
-
-    aura::client::ActivationClient* client = aura::client::GetActivationClient(
-        window_manager_app_->host()->window());
-    new FrameController(
-        shell_, frame_view, app_view, client, window_manager_app_.get());
-    return frame_view;
-  }
-
-  mojo::Shell* shell_;
-
-  scoped_ptr<mojo::ViewsInit> views_init_;
-
-  scoped_ptr<mojo::WindowManagerApp> window_manager_app_;
-
-  mojo::ViewManager* view_manager_;
-  mojo::View* root_;
-  mojo::View* window_container_;
-
-  gfx::Point next_window_origin_;
-
-  DISALLOW_COPY_AND_ASSIGN(SimpleWM);
-};
-
-}  // namespace examples
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new examples::SimpleWM);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/go/BUILD.gn b/mojo/go/BUILD.gn
deleted file mode 100644
index e190379..0000000
--- a/mojo/go/BUILD.gn
+++ /dev/null
@@ -1,24 +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.
-
-import("//build/go/rules.gni")
-
-group("go") {
-  deps = [
-    ":system_test",
-  ]
-}
-
-go_test_binary("system_test") {
-  sources = [
-    "tests/system_test.go",
-  ]
-  static_library_sources = [
-    "c_embedder/c_embedder.cc",
-    "c_embedder/c_embedder.h",
-  ]
-  deps = [
-    "//mojo/edk/system",
-  ]
-}
diff --git a/mojo/go/c_embedder/c_embedder.cc b/mojo/go/c_embedder/c_embedder.cc
deleted file mode 100644
index 7d6a2e0..0000000
--- a/mojo/go/c_embedder/c_embedder.cc
+++ /dev/null
@@ -1,22 +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 "mojo/go/c_embedder/c_embedder.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "mojo/edk/embedder/simple_platform_support.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void InitializeMojoEmbedder() {
-  mojo::embedder::Init(scoped_ptr<mojo::embedder::PlatformSupport>(
-      new mojo::embedder::SimplePlatformSupport()));
-}
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
diff --git a/mojo/go/c_embedder/c_embedder.h b/mojo/go/c_embedder/c_embedder.h
deleted file mode 100644
index f2961d6..0000000
--- a/mojo/go/c_embedder/c_embedder.h
+++ /dev/null
@@ -1,18 +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 MOJO_GO_C_EMBEDDER_C_EMBEDDER_H_
-#define MOJO_GO_C_EMBEDDER_C_EMBEDDER_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-__attribute__((visibility("default"))) void InitializeMojoEmbedder();
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // MOJO_GO_C_EMBEDDER_C_EMBEDDER_H__
diff --git a/mojo/go/system/embedder/embedder.go b/mojo/go/system/embedder/embedder.go
deleted file mode 100644
index 6f605df..0000000
--- a/mojo/go/system/embedder/embedder.go
+++ /dev/null
@@ -1,14 +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.
-
-package embedder;
-
-/*
-#include "mojo/go/c_embedder/c_embedder.h"
-*/
-import "C"
-
-func InitializeMojoEmbedder() {
-	C.InitializeMojoEmbedder();
-}
diff --git a/mojo/go/system/impl/core_impl.go b/mojo/go/system/impl/core_impl.go
deleted file mode 100644
index 9341a06e..0000000
--- a/mojo/go/system/impl/core_impl.go
+++ /dev/null
@@ -1,27 +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.
-
-package impl
-
-/*
-#include "mojo/public/platform/native/system_thunks.h"
-*/
-import "C"
-import "mojo/public/go/mojo/edk/system"
-
-type CoreImpl struct {
-}
-
-func (c CoreImpl) GetTimeTicksNow() int64 {
-	return (int64)(C.MojoGetTimeTicksNow())
-}
-
-var lazyInstance *CoreImpl = nil
-
-func GetCore() system.Core {
-	if lazyInstance == nil {
-		lazyInstance = new(CoreImpl)
-	}
-	return lazyInstance
-}
diff --git a/mojo/go/tests/system_test.go b/mojo/go/tests/system_test.go
deleted file mode 100644
index 549d01d..0000000
--- a/mojo/go/tests/system_test.go
+++ /dev/null
@@ -1,23 +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.
-
-package tests
-
-import "mojo/go/system/embedder"
-import "mojo/go/system/impl"
-import "mojo/public/go/mojo/edk/system"
-import "testing"
-
-func Init() {
-	embedder.InitializeMojoEmbedder()
-}
-
-func TestGetTimeTicksNow(t *testing.T) {
-	Init()
-	var c system.Core = impl.GetCore()
-	x := c.GetTimeTicksNow()
-	if x < 10 {
-		t.Error("Invalid GetTimeTicksNow return value")
-	}
-}
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index 6fdddf25..6fd87331 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -33,7 +33,6 @@
         'mojo_clipboard',
         'mojo_clipboard_unittests',
         'mojo_geometry_lib',
-        'mojo_html_viewer',
         'mojo_input_events_lib',
         'mojo_js_content_handler',
         'mojo_js_standalone',
@@ -48,32 +47,15 @@
         'mojo_surfaces_service',
         'mojo_test_app',
         'mojo_test_request_tracker_app',
-        'mojo_view_manager_lib_unittests',
         'services/public/mojo_services_public.gyp:mojo_services_public',
         'public/mojo_public.gyp:mojo_public',
       ],
       'conditions': [
-        ['use_aura==1', {
-          'dependencies': [
-            'mojo_core_window_manager',
-            'mojo_core_window_manager_unittests',
-            'mojo_view_manager',
-            'mojo_view_manager_unittests',
-          ],
-        }],
         ['OS == "linux"', {
           'dependencies': [
             'mojo_external_application_tests',
           ],
         }],
-        ['component != "shared_library" and OS == "linux"', {
-          'dependencies': [
-            'mojo_python_bindings',
-            'mojo_python_embedder',
-            'mojo_python_system',
-            'mojo_python',
-          ],
-        }],
       ]
     },
     {
@@ -497,223 +479,6 @@
         },
       ],
     }],
-    ['use_aura==1', {
-      'targets': [
-        {
-          # GN version: //mojo/aura
-          'target_name': 'mojo_aura_support',
-          'type': 'static_library',
-          'dependencies': [
-            '../cc/cc.gyp:cc',
-            '../ui/aura/aura.gyp:aura',
-            '../ui/compositor/compositor.gyp:compositor',
-            '../ui/events/events.gyp:events',
-            '../ui/events/events.gyp:events_base',
-            'mojo_cc_support',
-            'mojo_geometry_lib',
-            'mojo_surfaces_lib',
-            'mojo_view_manager_lib',
-            'public/mojo_public.gyp:mojo_application_base',
-            'public/mojo_public.gyp:mojo_application_bindings',
-            'services/public/mojo_services_public.gyp:mojo_native_viewport_bindings',
-          ],
-          'includes': [
-            'mojo_public_gles2_for_loadable_module.gypi',
-          ],
-          'sources': [
-            'aura/aura_init.cc',
-            'aura/aura_init.h',
-            'aura/screen_mojo.cc',
-            'aura/screen_mojo.h',
-            'aura/surface_binding.cc',
-            'aura/surface_binding.h',
-            'aura/surface_context_factory.cc',
-            'aura/surface_context_factory.h',
-            'aura/window_tree_host_mojo.cc',
-            'aura/window_tree_host_mojo.h',
-          ],
-        },
-        {
-          # GN version: //mojo/views:views
-          'target_name': 'mojo_views_support',
-          'type': 'static_library',
-          'dependencies': [
-            '../base/base.gyp:base',
-            '../base/base.gyp:base_i18n',
-            '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
-            '../skia/skia.gyp:skia',
-            '../third_party/icu/icu.gyp:icui18n',
-            '../third_party/icu/icu.gyp:icuuc',
-            '../ui/aura/aura.gyp:aura',
-            '../ui/base/ui_base.gyp:ui_base',
-            '../ui/gfx/gfx.gyp:gfx',
-            '../ui/views/views.gyp:views',
-            '../ui/wm/wm.gyp:wm',
-            'mojo_aura_support',
-            'mojo_view_manager_lib',
-            'services/public/mojo_services_public.gyp:mojo_view_manager_bindings',
-          ],
-          'sources': [
-            'views/input_method_mojo_linux.cc',
-            'views/input_method_mojo_linux.h',
-            'views/native_widget_view_manager.cc',
-            'views/native_widget_view_manager.h',
-            'views/views_init.cc',
-            'views/views_init.h',
-          ],
-        },
-        {
-          # GN version: //mojo/services/public/cpp/view_manager/lib:run_unittests
-          'target_name': 'mojo_view_manager_run_unittests',
-          'type': 'static_library',
-          'dependencies': [
-            '../base/base.gyp:base',
-            '../base/base.gyp:test_support_base',
-          ],
-          'sources': [
-            'services/public/cpp/view_manager/lib/view_manager_test_suite.cc',
-            'services/public/cpp/view_manager/lib/view_manager_test_suite.h',
-            'services/public/cpp/view_manager/lib/view_manager_unittests.cc',
-          ],
-          'conditions': [
-            ['use_x11==1', {
-              'dependencies': [
-                '../ui/gfx/x/gfx_x11.gyp:gfx_x11',
-              ],
-            }],
-          ],
-        },
-      ],
-    }],
-    ['component!="shared_library" and OS=="linux"', {
-      'targets': [
-        {
-          # GN version: //mojo/public/python:system
-          'target_name': 'mojo_python_system',
-          'variables': {
-            'python_base_module': 'mojo',
-            'python_cython_module': 'system',
-          },
-          'sources': [
-            'public/python/mojo/c_core.pxd',
-            'public/python/mojo/c_environment.pxd',
-            'public/python/mojo/system.pyx',
-            'public/python/src/python_system_helper.cc',
-            'public/python/src/python_system_helper.h',
-          ],
-          'dependencies': [
-            'public/mojo_public.gyp:mojo_environment_standalone',
-            'public/mojo_public.gyp:mojo_system',
-            'public/mojo_public.gyp:mojo_utility',
-          ],
-          'includes': [ '../third_party/cython/cython_compiler.gypi' ],
-        },
-        {
-          # GN version: //mojo/python:embedder
-          'target_name': 'mojo_python_embedder',
-          'type': 'loadable_module',
-          'variables': {
-            'python_base_module': 'mojo',
-            'python_cython_module': 'embedder',
-          },
-          'sources': [
-            'python/system/mojo/embedder.pyx',
-          ],
-          'dependencies': [
-            'edk/mojo_edk.gyp:mojo_system_impl',
-          ],
-          'includes': [ '../third_party/cython/cython_compiler.gypi' ],
-        },
-        {
-          # GN version: //mojo/public/python:bindings
-          'target_name': 'mojo_python_bindings',
-          'type': 'none',
-          'variables': {
-            'python_base_module': 'mojo/bindings',
-          },
-          'sources': [
-            'public/python/mojo/bindings/__init__.py',
-            'public/python/mojo/bindings/descriptor.py',
-            'public/python/mojo/bindings/messaging.py',
-            'public/python/mojo/bindings/promise.py',
-            'public/python/mojo/bindings/reflection.py',
-            'public/python/mojo/bindings/serialization.py',
-          ],
-          'dependencies': [
-            'mojo_python_system',
-          ],
-          'includes': [ '../third_party/cython/python_module.gypi' ],
-        },
-        {
-          # GN version: //mojo/python
-          'target_name': 'mojo_python',
-          'type': 'none',
-          'variables': {
-            'python_base_module': 'mojo',
-          },
-          'sources': [
-            'public/python/mojo/__init__.py',
-          ],
-          'dependencies': [
-            'mojo_python_bindings',
-            'mojo_python_embedder',
-            'mojo_python_system',
-          ],
-          # The python module need to be copied to their destinations
-          'actions': [
-            {
-              'action_name': 'Copy system module.',
-              'inputs': [
-                '<(DEPTH)/build/cp.py',
-                '<(PRODUCT_DIR)/libmojo_python_system.so',
-              ],
-              'outputs': [
-                '<(PRODUCT_DIR)/python/mojo/system.so',
-              ],
-              'action': [
-                'python',
-                '<@(_inputs)',
-                '<@(_outputs)',
-              ]
-            },
-            {
-              'action_name': 'Copy embedder module.',
-              'inputs': [
-                '<(DEPTH)/build/cp.py',
-                '<(PRODUCT_DIR)/libmojo_python_embedder.so',
-              ],
-              'outputs': [
-                '<(PRODUCT_DIR)/python/mojo/embedder.so',
-              ],
-              'action': [
-                'python',
-                '<@(_inputs)',
-                '<@(_outputs)',
-              ]
-            },
-          ],
-          'includes': [ '../third_party/cython/python_module.gypi' ],
-        },
-      ],
-    }],
-    ['component!="shared_library" and OS=="linux" and test_isolation_mode!="noop"', {
-      'targets': [
-        {
-          'target_name': 'mojo_python_unittests_run',
-          'type': 'none',
-          'dependencies': [
-            'mojo_python',
-            'public/mojo_public.gyp:mojo_public_test_interfaces',
-          ],
-          'includes': [
-            '../build/isolate.gypi',
-          ],
-          'sources': [
-            'mojo_python_unittests.isolate',
-          ],
-        },
-      ],
-    }],
     ['test_isolation_mode != "noop"', {
       'targets': [
         {
diff --git a/mojo/mojo_python_unittests.isolate b/mojo/mojo_python_unittests.isolate
deleted file mode 100644
index 4fea84a..0000000
--- a/mojo/mojo_python_unittests.isolate
+++ /dev/null
@@ -1,22 +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.
-{
-  'conditions': [
-    ['OS=="linux"', {
-      'variables': {
-        'command': [
-          'tools/run_mojo_python_bindings_tests.py',
-          '--build-dir=<(PRODUCT_DIR)',
-        ],
-        'files': [
-          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/',
-          '<(PRODUCT_DIR)/python/',
-          'python/tests/',
-          'tools/pylib/mojo_python_tests_runner.py',
-          'tools/run_mojo_python_bindings_tests.py',
-        ],
-      },
-    }],
-  ],
-}
diff --git a/mojo/mojo_services.gypi b/mojo/mojo_services.gypi
index e26b0d3..fefa64aa 100644
--- a/mojo/mojo_services.gypi
+++ b/mojo/mojo_services.gypi
@@ -63,79 +63,6 @@
       ],
     },
     {
-      # GN version: //mojo/services/html_viewer
-      'target_name': 'mojo_html_viewer',
-      'type': 'loadable_module',
-      'dependencies': [
-        '../cc/blink/cc_blink.gyp:cc_blink',
-        '../cc/cc.gyp:cc',
-        '../cc/cc.gyp:cc_surfaces',
-        '../media/blink/media_blink.gyp:media_blink',
-        '../media/media.gyp:media',
-        '../net/net.gyp:net',
-        '../skia/skia.gyp:skia',
-        '../third_party/WebKit/public/blink.gyp:blink',
-        '../ui/native_theme/native_theme.gyp:native_theme',
-        '../url/url.gyp:url_lib',
-        'mojo_base.gyp:mojo_application_chromium',
-        'mojo_base.gyp:mojo_common_lib',
-        'mojo_cc_support',
-        'services/public/mojo_services_public.gyp:mojo_clipboard_bindings',
-        'services/public/mojo_services_public.gyp:mojo_content_handler_bindings',
-        'services/public/mojo_services_public.gyp:mojo_gpu_bindings',
-        'services/public/mojo_services_public.gyp:mojo_navigation_bindings',
-        'services/public/mojo_services_public.gyp:mojo_network_bindings',
-        'services/public/mojo_services_public.gyp:mojo_surfaces_bindings',
-        'mojo_view_manager_lib',
-        'public/mojo_public.gyp:mojo_cpp_bindings',
-        'public/mojo_public.gyp:mojo_utility',
-        '<(mojo_system_for_loadable_module)',
-      ],
-      'include_dirs': [
-        'third_party/WebKit'
-      ],
-      'includes': [
-        'mojo_public_gles2_for_loadable_module.gypi',
-      ],
-      'sources': [
-        'services/html_viewer/blink_basic_type_converters.cc',
-        'services/html_viewer/blink_basic_type_converters.h',
-        'services/html_viewer/blink_input_events_type_converters.cc',
-        'services/html_viewer/blink_input_events_type_converters.h',
-        'services/html_viewer/blink_platform_impl.cc',
-        'services/html_viewer/blink_platform_impl.h',
-        'services/html_viewer/blink_url_request_type_converters.cc',
-        'services/html_viewer/blink_url_request_type_converters.h',
-        'services/html_viewer/html_viewer.cc',
-        'services/html_viewer/html_document_view.cc',
-        'services/html_viewer/html_document_view.h',
-        'services/html_viewer/webclipboard_impl.cc',
-        'services/html_viewer/webclipboard_impl.h',
-        'services/html_viewer/webcookiejar_impl.cc',
-        'services/html_viewer/webcookiejar_impl.h',
-        'services/html_viewer/webmediaplayer_factory.cc',
-        'services/html_viewer/webmediaplayer_factory.h',
-        'services/html_viewer/webmimeregistry_impl.cc',
-        'services/html_viewer/webmimeregistry_impl.h',
-        'services/html_viewer/websockethandle_impl.cc',
-        'services/html_viewer/websockethandle_impl.h',
-        'services/html_viewer/webstoragenamespace_impl.cc',
-        'services/html_viewer/webstoragenamespace_impl.h',
-        'services/html_viewer/webthemeengine_impl.cc',
-        'services/html_viewer/webthemeengine_impl.h',
-        'services/html_viewer/webthread_impl.cc',
-        'services/html_viewer/webthread_impl.h',
-        'services/html_viewer/weburlloader_impl.cc',
-        'services/html_viewer/weburlloader_impl.h',
-        'services/html_viewer/weblayertreeview_impl.cc',
-        'services/html_viewer/weblayertreeview_impl.h',
-        'services/public/cpp/network/web_socket_read_queue.cc',
-        'services/public/cpp/network/web_socket_read_queue.h',
-        'services/public/cpp/network/web_socket_write_queue.cc',
-        'services/public/cpp/network/web_socket_write_queue.h',
-      ],
-    },
-    {
       # GN version: //mojo/services/gles2
       'target_name': 'mojo_gles2_service',
       'type': 'static_library',
@@ -356,81 +283,6 @@
       ],
     },
     {
-      # GN version: //mojo/services/public/cpp/view_manager/tests:mojo_view_manager_lib_unittests
-      'target_name': 'mojo_view_manager_lib_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../base/base.gyp:base',
-        '../base/base.gyp:test_support_base',
-        '../testing/gtest.gyp:gtest',
-        '../ui/gfx/gfx.gyp:gfx',
-        '../ui/gfx/gfx.gyp:gfx_test_support',
-        'mojo.gyp:mojo_shell_test_support',
-        'mojo_base.gyp:mojo_environment_chromium',
-        'mojo_geometry_lib',
-        'mojo_view_manager_lib',
-        'services/public/mojo_services_public.gyp:mojo_geometry_bindings',
-        'services/public/mojo_services_public.gyp:mojo_view_manager_bindings',
-      ],
-      'sources': [
-        'services/public/cpp/view_manager/tests/view_unittest.cc',
-        'services/public/cpp/view_manager/tests/view_manager_unittest.cc',
-      ],
-      'conditions': [
-        ['use_aura==1', {
-          'dependencies': [
-            'mojo_view_manager_run_unittests'
-          ],
-        }, {  # use_aura==0
-          'dependencies': [
-            'edk/mojo_edk.gyp:mojo_run_all_unittests',
-          ],
-        }],
-      ],
-    },
-    {
-      # GN version: //mojo/services/public/cpp/view_manager
-      'target_name': 'mojo_view_manager_lib',
-      'type': 'static_library',
-      'dependencies': [
-        '../base/base.gyp:base',
-        '../ui/gfx/gfx.gyp:gfx_geometry',
-        'mojo_base.gyp:mojo_application_chromium',
-        'mojo_geometry_lib',
-        'public/mojo_public.gyp:mojo_application_base',
-        'public/mojo_public.gyp:mojo_application_bindings',
-        'public/mojo_public.gyp:mojo_cpp_bindings',
-        'services/public/mojo_services_public.gyp:mojo_core_window_manager_bindings',
-        'services/public/mojo_services_public.gyp:mojo_geometry_bindings',
-        'services/public/mojo_services_public.gyp:mojo_input_events_bindings',
-        'services/public/mojo_services_public.gyp:mojo_surface_id_bindings',
-        'services/public/mojo_services_public.gyp:mojo_view_manager_bindings',
-        'services/public/mojo_services_public.gyp:mojo_view_manager_common',
-      ],
-      'includes': [
-        'mojo_public_gles2_for_loadable_module.gypi',
-      ],
-      'sources': [
-        'services/public/cpp/view_manager/lib/view.cc',
-        'services/public/cpp/view_manager/lib/view_manager_client_factory.cc',
-        'services/public/cpp/view_manager/lib/view_manager_client_impl.cc',
-        'services/public/cpp/view_manager/lib/view_manager_client_impl.h',
-        'services/public/cpp/view_manager/lib/view_manager_context.cc',
-        'services/public/cpp/view_manager/lib/view_observer.cc',
-        'services/public/cpp/view_manager/lib/view_private.cc',
-        'services/public/cpp/view_manager/lib/view_private.h',
-        'services/public/cpp/view_manager/view.h',
-        'services/public/cpp/view_manager/view_manager.h',
-        'services/public/cpp/view_manager/view_manager_client_factory.h',
-        'services/public/cpp/view_manager/view_manager_context.h',
-        'services/public/cpp/view_manager/view_manager_delegate.h',
-        'services/public/cpp/view_manager/view_observer.h',
-      ],
-      'export_dependent_settings': [
-        'services/public/mojo_services_public.gyp:mojo_view_manager_bindings',
-      ],
-    },
-    {
       # GN version: //mojo/services/test_service:bindings
       'target_name': 'mojo_test_service_bindings',
       'type': 'static_library',
@@ -504,194 +356,4 @@
       ],
     },
   ],
-  'conditions': [
-    ['use_aura==1', {
-      'targets': [
-        {
-          # GN version: //mojo/services/view_manager
-          'target_name': 'mojo_view_manager',
-          'type': 'loadable_module',
-          'dependencies': [
-            '../base/base.gyp:base',
-            '../cc/cc.gyp:cc_surfaces',
-            '../skia/skia.gyp:skia',
-            '../ui/base/ui_base.gyp:ui_base',
-            '../ui/events/events.gyp:events',
-            '../ui/events/events.gyp:events_base',
-            '../ui/gfx/gfx.gyp:gfx',
-            '../ui/gfx/gfx.gyp:gfx_geometry',
-            'mojo_base.gyp:mojo_application_chromium',
-            'mojo_base.gyp:mojo_common_lib',
-            'mojo_geometry_lib',
-            'mojo_input_events_lib',
-            'mojo_surfaces_lib',
-            'services/public/mojo_services_public.gyp:mojo_geometry_bindings',
-            'services/public/mojo_services_public.gyp:mojo_gpu_bindings',
-            'services/public/mojo_services_public.gyp:mojo_input_events_bindings',
-            'services/public/mojo_services_public.gyp:mojo_native_viewport_bindings',
-            'services/public/mojo_services_public.gyp:mojo_surfaces_bindings',
-            'services/public/mojo_services_public.gyp:mojo_view_manager_bindings',
-            'services/public/mojo_services_public.gyp:mojo_view_manager_common',
-            'services/public/mojo_services_public.gyp:mojo_window_manager_bindings',
-            '<(mojo_system_for_loadable_module)',
-          ],
-          'sources': [
-            'services/view_manager/access_policy.h',
-            'services/view_manager/access_policy_delegate.h',
-            'services/view_manager/connection_manager.cc',
-            'services/view_manager/connection_manager.h',
-            'services/view_manager/default_access_policy.cc',
-            'services/view_manager/default_access_policy.h',
-            'services/view_manager/display_manager.cc',
-            'services/view_manager/display_manager.h',
-            'services/view_manager/ids.h',
-            'services/view_manager/main.cc',
-            'services/view_manager/server_view.cc',
-            'services/view_manager/server_view.h',
-            'services/view_manager/server_view_delegate.h',
-            'services/view_manager/view_manager_export.h',
-            'services/view_manager/view_manager_init_service_context.cc',
-            'services/view_manager/view_manager_init_service_context.h',
-            'services/view_manager/view_manager_init_service_impl.cc',
-            'services/view_manager/view_manager_init_service_impl.h',
-            'services/view_manager/view_manager_service_impl.cc',
-            'services/view_manager/view_manager_service_impl.h',
-            'services/view_manager/window_manager_access_policy.cc',
-            'services/view_manager/window_manager_access_policy.h',
-            'services/view_manager/window_manager_client_impl.cc',
-            'services/view_manager/window_manager_client_impl.h',
-          ],
-          'includes': [
-            'mojo_public_gles2_for_loadable_module.gypi',
-          ],
-          'defines': [
-            'MOJO_VIEW_MANAGER_IMPLEMENTATION',
-          ],
-        },
-        {
-          # GN version: //mojo/services/view_manager:mojo_view_manager_unittests
-          'target_name': 'mojo_view_manager_unittests',
-          'type': 'executable',
-          'dependencies': [
-            '../base/base.gyp:base',
-            '../base/base.gyp:test_support_base',
-            '../skia/skia.gyp:skia',
-            '../testing/gtest.gyp:gtest',
-            '../ui/aura/aura.gyp:aura',
-            '../ui/gfx/gfx.gyp:gfx_geometry',
-            'edk/mojo_edk.gyp:mojo_system_impl',
-            'mojo_application_manager',
-            'mojo_base.gyp:mojo_application_chromium',
-            'mojo_geometry_lib',
-            'mojo_input_events_lib',
-            'mojo_native_viewport_service_args',
-            'mojo_shell_test_support',
-            'mojo_view_manager_run_unittests',
-            'services/public/mojo_services_public.gyp:mojo_geometry_bindings',
-            'services/public/mojo_services_public.gyp:mojo_input_events_bindings',
-            'services/public/mojo_services_public.gyp:mojo_view_manager_bindings',
-            'services/public/mojo_services_public.gyp:mojo_view_manager_common',
-            'services/public/mojo_services_public.gyp:mojo_window_manager_bindings',
-            # Included only to force deps for bots.
-            'mojo_native_viewport_service',
-            'mojo_surfaces_service',
-            'mojo_view_manager',
-          ],
-          'sources': [
-            'services/view_manager/test_change_tracker.cc',
-            'services/view_manager/test_change_tracker.h',
-            'services/view_manager/view_manager_unittest.cc',
-          ],
-          'conditions': [
-             ['OS=="win"', {
-               'dependencies': [
-                 '../ui/gfx/gfx.gyp:gfx',
-               ],
-             }],
-           ],
-        },
-        {
-          'target_name': 'package_mojo_view_manager',
-          'variables': {
-            'app_name': 'mojo_view_manager',
-          },
-          'includes': [ 'build/package_app.gypi' ],
-        },
-        {
-          # GN version: //mojo/services/window_manager:lib
-          'target_name': 'mojo_core_window_manager_lib',
-          'type': 'static_library',
-          'dependencies': [
-            '../base/base.gyp:base',
-            '../ui/base/ui_base.gyp:ui_base',
-            '../ui/gfx/gfx.gyp:gfx',
-            '../ui/gfx/gfx.gyp:gfx_geometry',
-            '../ui/wm/wm.gyp:wm',
-            'mojo_aura_support',
-            'mojo_base.gyp:mojo_application_chromium',
-            'mojo_base.gyp:mojo_common_lib',
-            'mojo_input_events_lib',
-            'mojo_view_manager_lib',
-            'public/mojo_public.gyp:mojo_application_bindings',
-            'services/public/mojo_services_public.gyp:mojo_core_window_manager_bindings',
-            'services/public/mojo_services_public.gyp:mojo_window_manager_bindings',
-          ],
-          'sources': [
-            'services/window_manager/window_manager_app.cc',
-            'services/window_manager/window_manager_app.h',
-            'services/window_manager/window_manager_delegate.h',
-            'services/window_manager/window_manager_service_impl.cc',
-            'services/window_manager/window_manager_service_impl.h',
-            'services/window_manager/window_manager_service2_impl.cc',
-            'services/window_manager/window_manager_service2_impl.h',
-          ],
-        },
-        {
-          # GN version: //mojo/services/window_manager
-          'target_name': 'mojo_core_window_manager',
-          'type': 'loadable_module',
-          'dependencies': [
-            'mojo_core_window_manager_lib',
-            '<(mojo_system_for_loadable_module)',
-          ],
-          'sources': [
-            'services/window_manager/main.cc',
-          ],
-        },
-        {
-          # GN version: //mojo/services/window_manager:mojo_core_window_manager_unittests
-          'target_name': 'mojo_core_window_manager_unittests',
-          'type': 'executable',
-          'dependencies': [
-            '../base/base.gyp:test_support_base',
-            '../testing/gtest.gyp:gtest',
-            'edk/mojo_edk.gyp:mojo_system_impl',
-            'mojo_application_manager',
-            'mojo_base.gyp:mojo_environment_chromium',
-            'services/public/mojo_services_public.gyp:mojo_core_window_manager_bindings',
-            'mojo_shell_test_support',
-            'services/public/mojo_services_public.gyp:mojo_view_manager_bindings',
-            'mojo_view_manager_lib',
-          ],
-          'sources': [
-            'services/window_manager/window_manager_api_unittest.cc',
-            'services/window_manager/window_manager_unittests.cc',
-          ],
-          'conditions': [
-            ['OS=="linux"', {
-              'dependencies': [
-                '../third_party/mesa/mesa.gyp:osmesa',
-                'mojo_native_viewport_service_lib',
-              ],
-            }],
-            ['use_x11==1', {
-              'dependencies': [
-                '../ui/gfx/x/gfx_x11.gyp:gfx_x11',
-              ],
-            }],
-          ],
-        },
-      ],
-    }],
-  ],
 }
diff --git a/mojo/public/VERSION b/mojo/public/VERSION
new file mode 100644
index 0000000..9e33d22
--- /dev/null
+++ b/mojo/public/VERSION
@@ -0,0 +1 @@
+3b54eded8dadb36548934c09c5100e9e645ec328
\ No newline at end of file
diff --git a/mojo/public/c/system/tests/core_perftest.cc b/mojo/public/c/system/tests/core_perftest.cc
index fa90c86..15500ff1 100644
--- a/mojo/public/c/system/tests/core_perftest.cc
+++ b/mojo/public/c/system/tests/core_perftest.cc
@@ -112,7 +112,7 @@
 class CorePerftest : public testing::Test {
  public:
   CorePerftest() : buffer_(NULL), num_bytes_(0) {}
-  virtual ~CorePerftest() {}
+  ~CorePerftest() override {}
 
   static void NoOp(void* /*closure*/) {}
 
diff --git a/mojo/public/cpp/bindings/tests/array_unittest.cc b/mojo/public/cpp/bindings/tests/array_unittest.cc
index 0b083c7..ed9a647 100644
--- a/mojo/public/cpp/bindings/tests/array_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/array_unittest.cc
@@ -23,7 +23,7 @@
 
 class ArrayTest : public testing::Test {
  public:
-  virtual ~ArrayTest() {}
+  ~ArrayTest() override {}
 
  private:
   Environment env_;
diff --git a/mojo/public/cpp/bindings/tests/connector_unittest.cc b/mojo/public/cpp/bindings/tests/connector_unittest.cc
index 1e1c6ef..f8df1a67 100644
--- a/mojo/public/cpp/bindings/tests/connector_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/connector_unittest.cc
@@ -75,11 +75,9 @@
  public:
   ConnectorTest() {}
 
-  virtual void SetUp() override {
-    CreateMessagePipe(nullptr, &handle0_, &handle1_);
-  }
+  void SetUp() override { CreateMessagePipe(nullptr, &handle0_, &handle1_); }
 
-  virtual void TearDown() override {}
+  void TearDown() override {}
 
   void AllocMessage(const char* text, Message* message) {
     size_t payload_size = strlen(text) + 1;  // Plus null terminator.
diff --git a/mojo/public/cpp/bindings/tests/equals_unittest.cc b/mojo/public/cpp/bindings/tests/equals_unittest.cc
index 38c78cb..9196d86 100644
--- a/mojo/public/cpp/bindings/tests/equals_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/equals_unittest.cc
@@ -22,7 +22,7 @@
 
 class EqualsTest : public testing::Test {
  public:
-  virtual ~EqualsTest() {}
+  ~EqualsTest() override {}
 
  private:
   Environment env_;
diff --git a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
index 53652cf..5667f64d 100644
--- a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
@@ -166,7 +166,7 @@
 
 class HandlePassingTest : public testing::Test {
  public:
-  virtual void TearDown() { PumpMessages(); }
+  void TearDown() override { PumpMessages(); }
 
   void PumpMessages() { loop_.RunUntilIdle(); }
 
diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
index 57ec78a..0cd5646 100644
--- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
@@ -152,7 +152,7 @@
 
 class InterfacePtrTest : public testing::Test {
  public:
-  virtual ~InterfacePtrTest() { loop_.RunUntilIdle(); }
+  ~InterfacePtrTest() override { loop_.RunUntilIdle(); }
 
   void PumpMessages() { loop_.RunUntilIdle(); }
 
diff --git a/mojo/public/cpp/bindings/tests/map_unittest.cc b/mojo/public/cpp/bindings/tests/map_unittest.cc
index 6f7db162..bb3c23d 100644
--- a/mojo/public/cpp/bindings/tests/map_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/map_unittest.cc
@@ -32,7 +32,7 @@
 
 class MapTest : public testing::Test {
  public:
-  virtual ~MapTest() {}
+  ~MapTest() override {}
 
  private:
   Environment env_;
diff --git a/mojo/public/cpp/bindings/tests/request_response_unittest.cc b/mojo/public/cpp/bindings/tests/request_response_unittest.cc
index 56d7244..4864e35 100644
--- a/mojo/public/cpp/bindings/tests/request_response_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/request_response_unittest.cc
@@ -75,7 +75,7 @@
 
 class RequestResponseTest : public testing::Test {
  public:
-  virtual ~RequestResponseTest() { loop_.RunUntilIdle(); }
+  ~RequestResponseTest() override { loop_.RunUntilIdle(); }
 
   void PumpMessages() { loop_.RunUntilIdle(); }
 
diff --git a/mojo/public/cpp/bindings/tests/router_unittest.cc b/mojo/public/cpp/bindings/tests/router_unittest.cc
index e680112..e8521e81 100644
--- a/mojo/public/cpp/bindings/tests/router_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/router_unittest.cc
@@ -103,11 +103,9 @@
  public:
   RouterTest() {}
 
-  virtual void SetUp() override {
-    CreateMessagePipe(nullptr, &handle0_, &handle1_);
-  }
+  void SetUp() override { CreateMessagePipe(nullptr, &handle0_, &handle1_); }
 
-  virtual void TearDown() override {}
+  void TearDown() override {}
 
   void PumpMessages() { loop_.RunUntilIdle(); }
 
diff --git a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
index 0bed540..ff047cb 100644
--- a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
@@ -312,7 +312,7 @@
 class BindingsSampleTest : public testing::Test {
  public:
   BindingsSampleTest() {}
-  virtual ~BindingsSampleTest() {}
+  ~BindingsSampleTest() override {}
 
  private:
   mojo::Environment env_;
diff --git a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
index fc0508c..4359be82 100644
--- a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
@@ -40,7 +40,7 @@
 
 class SerializationWarningTest : public testing::Test {
  public:
-  virtual ~SerializationWarningTest() {}
+  ~SerializationWarningTest() override {}
 
  protected:
   template <typename T>
diff --git a/mojo/public/cpp/bindings/tests/struct_unittest.cc b/mojo/public/cpp/bindings/tests/struct_unittest.cc
index c7e7599d..8f7580d 100644
--- a/mojo/public/cpp/bindings/tests/struct_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/struct_unittest.cc
@@ -29,7 +29,7 @@
 
 class StructTest : public testing::Test {
  public:
-  virtual ~StructTest() {}
+  ~StructTest() override {}
 
  private:
   Environment env_;
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
index 8f3adb8..c7edf19e 100644
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -187,7 +187,7 @@
 
 class ValidationTest : public testing::Test {
  public:
-  virtual ~ValidationTest() {}
+  ~ValidationTest() override {}
 
  private:
   Environment env_;
@@ -197,9 +197,9 @@
  public:
   ValidationIntegrationTest() : test_message_receiver_(nullptr) {}
 
-  virtual ~ValidationIntegrationTest() {}
+  ~ValidationIntegrationTest() override {}
 
-  virtual void SetUp() override {
+  void SetUp() override {
     ScopedMessagePipeHandle tester_endpoint;
     ASSERT_EQ(MOJO_RESULT_OK,
               CreateMessagePipe(nullptr, &tester_endpoint, &testee_endpoint_));
@@ -207,7 +207,7 @@
         new TestMessageReceiver(this, tester_endpoint.Pass());
   }
 
-  virtual void TearDown() override {
+  void TearDown() override {
     delete test_message_receiver_;
     test_message_receiver_ = nullptr;
 
diff --git a/mojo/public/cpp/environment/tests/async_waiter_unittest.cc b/mojo/public/cpp/environment/tests/async_waiter_unittest.cc
index 52f1406..c1876b79 100644
--- a/mojo/public/cpp/environment/tests/async_waiter_unittest.cc
+++ b/mojo/public/cpp/environment/tests/async_waiter_unittest.cc
@@ -18,7 +18,7 @@
 class TestAsyncWaitCallback {
  public:
   TestAsyncWaitCallback() : result_count_(0), last_result_(MOJO_RESULT_OK) {}
-  virtual ~TestAsyncWaitCallback() {}
+  ~TestAsyncWaitCallback() {}
 
   int result_count() const { return result_count_; }
 
diff --git a/mojo/public/cpp/environment/tests/logging_unittest.cc b/mojo/public/cpp/environment/tests/logging_unittest.cc
index 609def1..53a1f88 100644
--- a/mojo/public/cpp/environment/tests/logging_unittest.cc
+++ b/mojo/public/cpp/environment/tests/logging_unittest.cc
@@ -35,7 +35,7 @@
     minimum_log_level_ = MOJO_LOG_LEVEL_INFO;
     ResetMockLogger();
   }
-  virtual ~LoggingTest() {}
+  ~LoggingTest() override {}
 
  protected:
   // Note: Does not reset |minimum_log_level_|.
diff --git a/mojo/public/cpp/utility/tests/run_loop_unittest.cc b/mojo/public/cpp/utility/tests/run_loop_unittest.cc
index 870ff92..1e21a13 100644
--- a/mojo/public/cpp/utility/tests/run_loop_unittest.cc
+++ b/mojo/public/cpp/utility/tests/run_loop_unittest.cc
@@ -50,11 +50,11 @@
  public:
   RunLoopTest() {}
 
-  virtual void SetUp() override {
+  void SetUp() override {
     Test::SetUp();
     RunLoop::SetUp();
   }
-  virtual void TearDown() override {
+  void TearDown() override {
     RunLoop::TearDown();
     Test::TearDown();
   }
diff --git a/mojo/public/go/system/core.go b/mojo/public/go/system/core.go
new file mode 100644
index 0000000..d8735ae
--- /dev/null
+++ b/mojo/public/go/system/core.go
@@ -0,0 +1,21 @@
+// 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.
+
+package system
+
+import "mojo/public/go/system/impl"
+
+type Core interface {
+	GetTimeTicksNow() int64
+}
+
+var core *impl.CoreImpl
+
+func init() {
+     core = &impl.CoreImpl{}
+}
+
+func GetCore() Core {
+     return core
+}
\ No newline at end of file
diff --git a/mojo/public/go/system/impl/core_impl.go b/mojo/public/go/system/impl/core_impl.go
new file mode 100644
index 0000000..b269583
--- /dev/null
+++ b/mojo/public/go/system/impl/core_impl.go
@@ -0,0 +1,16 @@
+// 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.
+
+package impl
+
+//#include "mojo/public/platform/native/system_thunks.h"
+//#include "mojo/public/c/system/main.h"
+import "C"
+
+type CoreImpl struct {
+}
+
+func (c *CoreImpl) GetTimeTicksNow() int64 {
+  return (int64)(C.MojoGetTimeTicksNow())
+}
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good.data
new file mode 100644
index 0000000..4ae4fd45c
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good.data
@@ -0,0 +1,46 @@
+[dist4]message_header  // num_bytes
+[u4]2                  // num_fields
+[u4]10                 // name
+[u4]0                  // flags
+[anchr]message_header
+
+[dist4]method10_params  // num_bytes
+[u4]1                   // num_fields
+[dist8]map_data_ptr     // param0
+[anchr]method10_params
+
+[anchr]map_data_ptr
+[dist4]map_data_struct_header  // num_bytes
+[u4]2                          // num_elements
+[dist8]key_array_ptr
+[dist8]value_array_ptr
+[anchr]map_data_struct_header
+
+[anchr]key_array_ptr
+[dist4]key_array_member   // num_bytes
+[u4]2                     // num_elements
+[dist8]key_string_1
+[dist8]key_string_2
+[anchr]key_array_member
+
+[anchr]key_string_1
+[dist4]key_string_1_member  // num_bytes
+[u4]5                       // num_elements
+0 1 2 3 4
+[anchr]key_string_1_member
+
+[u4]0 [u4]0 [u1]0 [u1]0 [u1]0  // manual padding for array alignment
+
+[anchr]key_string_2
+[dist4]key_string_2_member  // num_bytes
+[u4]5                       // num_elements
+5 6 7 8 9
+[anchr]key_string_2_member
+
+[u4]0 [u4]0 [u1]0 [u1]0 [u1]0  // manual padding for array alignment
+
+[anchr]value_array_ptr
+[dist4]value_array_member   // num_bytes
+[u4]2                       // num_elements
+1 2
+[anchr]value_array_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good_non_unique_keys.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good_non_unique_keys.data
new file mode 100644
index 0000000..cc18fee
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good_non_unique_keys.data
@@ -0,0 +1,46 @@
+[dist4]message_header  // num_bytes
+[u4]2                  // num_fields
+[u4]10                 // name
+[u4]0                  // flags
+[anchr]message_header
+
+[dist4]method10_params  // num_bytes
+[u4]1                   // num_fields
+[dist8]map_data_ptr     // param0
+[anchr]method10_params
+
+[anchr]map_data_ptr
+[dist4]map_data_struct_header  // num_bytes
+[u4]2                          // num_elements
+[dist8]key_array_ptr
+[dist8]value_array_ptr
+[anchr]map_data_struct_header
+
+[anchr]key_array_ptr
+[dist4]key_array_member   // num_bytes
+[u4]2                     // num_elements
+[dist8]key_string_1
+[dist8]key_string_2
+[anchr]key_array_member
+
+[anchr]key_string_1
+[dist4]key_string_1_member  // num_bytes
+[u4]5                       // num_elements
+0 1 2 3 4
+[anchr]key_string_1_member
+
+[u4]0 [u4]0 [u1]0 [u1]0 [u1]0  // manual padding for array alignment
+
+[anchr]key_string_2
+[dist4]key_string_2_member  // num_bytes
+[u4]5                       // num_elements
+0 1 2 3 4
+[anchr]key_string_2_member
+
+[u4]0 [u4]0 [u1]0 [u1]0 [u1]0  // manual padding for array alignment
+
+[anchr]value_array_ptr
+[dist4]value_array_member   // num_bytes
+[u4]2                       // num_elements
+1 2
+[anchr]value_array_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good_non_unique_keys.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good_non_unique_keys.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_good_non_unique_keys.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_keys.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_keys.data
new file mode 100644
index 0000000..a296980
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_keys.data
@@ -0,0 +1,23 @@
+[dist4]message_header  // num_bytes
+[u4]2                  // num_fields
+[u4]10                 // name
+[u4]0                  // flags
+[anchr]message_header
+
+[dist4]method10_params  // num_bytes
+[u4]1                   // num_fields
+[dist8]map_data_ptr     // param0
+[anchr]method10_params
+
+[anchr]map_data_ptr
+[dist4]map_data_struct_header  // num_bytes
+[u4]2                          // num_elements
+[u8]0                          // null keys array
+[dist8]value_array_ptr
+[anchr]map_data_struct_header
+
+[anchr]value_array_ptr
+[dist4]value_array_member   // num_bytes
+[u4]2                       // num_elements
+1 2
+[anchr]value_array_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_keys.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_keys.expected
new file mode 100644
index 0000000..95d8db0
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_keys.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_UNEXPECTED_NULL_POINTER
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_values.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_values.data
new file mode 100644
index 0000000..ce135da
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_values.data
@@ -0,0 +1,38 @@
+[dist4]message_header  // num_bytes
+[u4]2                  // num_fields
+[u4]10                 // name
+[u4]0                  // flags
+[anchr]message_header
+
+[dist4]method10_params  // num_bytes
+[u4]1                   // num_fields
+[dist8]map_data_ptr     // param0
+[anchr]method10_params
+
+[anchr]map_data_ptr
+[dist4]map_data_struct_header  // num_bytes
+[u4]2                          // num_elements
+[dist8]key_array_ptr
+[u8]0                          // null values array
+[anchr]map_data_struct_header
+
+[anchr]key_array_ptr
+[dist4]key_array_member   // num_bytes
+[u4]2                     // num_elements
+[dist8]key_string_1
+[dist8]key_string_2
+[anchr]key_array_member
+
+[anchr]key_string_1
+[dist4]key_string_1_member  // num_bytes
+[u4]5                       // num_elements
+0 1 2 3 4
+[anchr]key_string_1_member
+
+[u4]0 [u4]0 [u1]0 [u1]0 [u1]0  // manual padding for array alignment
+
+[anchr]key_string_2
+[dist4]key_string_2_member  // num_bytes
+[u4]5                       // num_elements
+5 6 7 8 9
+[anchr]key_string_2_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_values.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_values.expected
new file mode 100644
index 0000000..95d8db0
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_null_values.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_UNEXPECTED_NULL_POINTER
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_one_null_key.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_one_null_key.data
new file mode 100644
index 0000000..06b55fb
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_one_null_key.data
@@ -0,0 +1,38 @@
+[dist4]message_header  // num_bytes
+[u4]2                  // num_fields
+[u4]10                 // name
+[u4]0                  // flags
+[anchr]message_header
+
+[dist4]method10_params  // num_bytes
+[u4]1                   // num_fields
+[dist8]map_data_ptr     // param0
+[anchr]method10_params
+
+[anchr]map_data_ptr
+[dist4]map_data_struct_header  // num_bytes
+[u4]2                          // num_elements
+[dist8]key_array_ptr
+[dist8]value_array_ptr
+[anchr]map_data_struct_header
+
+[anchr]key_array_ptr
+[dist4]key_array_member   // num_bytes
+[u4]2                     // num_elements
+[dist8]key_string_1
+[u8]0                     // one null key
+[anchr]key_array_member
+
+[anchr]key_string_1
+[dist4]key_string_1_member  // num_bytes
+[u4]5                       // num_elements
+0 1 2 3 4
+[anchr]key_string_1_member
+
+[u4]0 [u4]0 [u1]0 [u1]0 [u1]0  // manual padding for array alignment
+
+[anchr]value_array_ptr
+[dist4]value_array_member   // num_bytes
+[u4]2                       // num_elements
+1 2
+[anchr]value_array_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_one_null_key.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_one_null_key.expected
new file mode 100644
index 0000000..95d8db0
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_one_null_key.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_UNEXPECTED_NULL_POINTER
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_unequal_array_size.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_unequal_array_size.data
new file mode 100644
index 0000000..15c76b3
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_unequal_array_size.data
@@ -0,0 +1,46 @@
+[dist4]message_header  // num_bytes
+[u4]2                  // num_fields
+[u4]10                 // name
+[u4]0                  // flags
+[anchr]message_header
+
+[dist4]method10_params  // num_bytes
+[u4]1                   // num_fields
+[dist8]map_data_ptr     // param0
+[anchr]method10_params
+
+[anchr]map_data_ptr
+[dist4]map_data_struct_header  // num_bytes
+[u4]2                          // num_elements
+[dist8]key_array_ptr
+[dist8]value_array_ptr
+[anchr]map_data_struct_header
+
+[anchr]key_array_ptr
+[dist4]key_array_member   // num_bytes
+[u4]2                     // num_elements
+[dist8]key_string_1
+[dist8]key_string_2
+[anchr]key_array_member
+
+[anchr]key_string_1
+[dist4]key_string_1_member  // num_bytes
+[u4]5                       // num_elements
+0 1 2 3 4
+[anchr]key_string_1_member
+
+[u4]0 [u4]0 [u1]0 [u1]0 [u1]0  // manual padding for array alignment
+
+[anchr]key_string_2
+[dist4]key_string_2_member  // num_bytes
+[u4]5                       // num_elements
+5 6 7 8 9
+[anchr]key_string_2_member
+
+[u4]0 [u4]0 [u1]0 [u1]0 [u1]0  // manual padding for array alignment
+
+[anchr]value_array_ptr
+[dist4]value_array_member   // num_bytes
+[u4]1                       // num_elements
+1                           // unequal size
+[anchr]value_array_member
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_unequal_array_size.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_unequal_array_size.expected
new file mode 100644
index 0000000..2798d48
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd10_unequal_array_size.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP
diff --git a/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom b/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
index 1d0a9ef9..93393b0 100644
--- a/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
+++ b/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
@@ -42,6 +42,7 @@
   Method7(StructF param0, array<array<uint8, 3>?, 2> param1);
   Method8(array<array<string>?> param0);
   Method9(array<array<handle?>>? param0);
+  Method10(map<string, uint8> param0);
 };
 
 struct BasicStruct {
diff --git a/mojo/public/mojo.gni b/mojo/public/mojo.gni
new file mode 100644
index 0000000..5ff2989
--- /dev/null
+++ b/mojo/public/mojo.gni
@@ -0,0 +1,9 @@
+# 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.
+
+declare_args() {
+  # Whether to use a prebuilt mojo_shell binary instead of one built from
+  # source.
+  use_prebuilt_mojo_shell = false
+}
diff --git a/mojo/public/python/src/python_system_helper.cc b/mojo/public/python/src/python_system_helper.cc
index 50b5fb0..22b6bbb 100644
--- a/mojo/public/python/src/python_system_helper.cc
+++ b/mojo/public/python/src/python_system_helper.cc
@@ -57,7 +57,7 @@
     MOJO_DCHECK(callable);
   }
 
-  virtual void Run() const override {
+  void Run() const override {
     ScopedGIL acquire_gil;
     ScopedPyRef empty_tuple(PyTuple_New(0));
     if (!empty_tuple) {
@@ -101,7 +101,7 @@
 
   void set_wait_id(int wait_id) { wait_id_ = wait_id; }
 
-  virtual void Run(MojoResult mojo_result) const override {
+  void Run(MojoResult mojo_result) const override {
     MOJO_DCHECK(wait_id_);
 
     // Remove to reference to this object from PythonAsyncWaiter and ensure this
diff --git a/mojo/public/tools/BUILD.gn b/mojo/public/tools/BUILD.gn
new file mode 100644
index 0000000..6405c54
--- /dev/null
+++ b/mojo/public/tools/BUILD.gn
@@ -0,0 +1,16 @@
+# 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.
+
+import("//mojo/public/mojo.gni")
+
+if (use_prebuilt_mojo_shell) {
+  copy("copy_mojo_shell") {
+    filename = "mojo_shell"
+    if (is_win) {
+      filename += ".exe"
+    }
+    sources = [ "prebuilt/$filename" ]
+    outputs = [ "$root_out_dir/$filename" ]
+  }
+}
diff --git a/mojo/public/tools/download_shell_binary.py b/mojo/public/tools/download_shell_binary.py
new file mode 100755
index 0000000..16180c4f
--- /dev/null
+++ b/mojo/public/tools/download_shell_binary.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# 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.
+
+import os
+import subprocess
+import sys
+import tempfile
+import zipfile
+
+current_path = os.path.dirname(os.path.realpath(__file__))
+sys.path.insert(0, os.path.join(current_path, "..", "..", "..", "tools"))
+# pylint: disable=F0401
+import find_depot_tools
+
+if not sys.platform.startswith("linux"):
+  print "Not supported for your platform"
+  sys.exit(0)
+
+version_path = os.path.join(current_path, "../VERSION")
+with open(version_path) as version_file:
+  version = version_file.read().strip()
+
+prebuilt_file_path = os.path.join(current_path, "prebuilt")
+stamp_path = os.path.join(prebuilt_file_path, "VERSION")
+
+try:
+  with open(stamp_path) as stamp_file:
+    current_version = stamp_file.read().strip()
+    if current_version == version:
+      sys.exit(0)
+except IOError:
+  pass
+
+platform = "linux-x64" # TODO: configurate
+basename = platform + ".zip"
+
+gs_path = "gs://mojo/shell/" + version + "/" + basename
+
+depot_tools_path = find_depot_tools.add_depot_tools_to_path()
+gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil")
+
+with tempfile.NamedTemporaryFile() as temp_zip_file:
+  subprocess.check_call([gsutil_exe, "--bypass_prodaccess",
+                         "cp", gs_path, temp_zip_file.name])
+  with zipfile.ZipFile(temp_zip_file.name) as z:
+    zi = z.getinfo("mojo_shell")
+    mode = zi.external_attr >> 16L
+    z.extract(zi, prebuilt_file_path)
+    os.chmod(os.path.join(prebuilt_file_path, "mojo_shell"), mode)
+
+with open(stamp_path, 'w') as stamp_file:
+  stamp_file.write(version + "\n")
diff --git a/mojo/python/BUILD.gn b/mojo/python/BUILD.gn
deleted file mode 100644
index 7b07f4f..0000000
--- a/mojo/python/BUILD.gn
+++ /dev/null
@@ -1,27 +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.
-
-import("//third_party/cython/rules.gni")
-
-# GYP version: mojo/mojo.gyp:mojo_python
-group("python") {
-  deps = [
-    ":embedder",
-    "//mojo/public/python",
-  ]
-}
-
-# GYP version: mojo/mojo.gyp:mojo_python_embedder
-python_binary_module("embedder") {
-  python_base_module = "mojo"
-  sources = [
-    "system/mojo/embedder.pyx",
-  ]
-  deps = [
-    "//mojo/edk/system",
-  ]
-  datadeps = [
-    "//mojo/public/python:system",
-  ]
-}
diff --git a/mojo/python/system/mojo/embedder.pyx b/mojo/python/system/mojo/embedder.pyx
deleted file mode 100644
index c409999..0000000
--- a/mojo/python/system/mojo/embedder.pyx
+++ /dev/null
@@ -1,41 +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.
-
-# distutils: language = c++
-
-from libc.stdint cimport uintptr_t
-
-from mojo import system
-
-cdef extern from "third_party/cython/python_export.h":
-  pass
-
-cdef extern from "base/memory/scoped_ptr.h":
-  cdef cppclass scoped_ptr[T]:
-    scoped_ptr(T*)
-
-cdef extern from "mojo/edk/embedder/platform_support.h" \
-    namespace "mojo::embedder" nogil:
-  cdef cppclass PlatformSupport:
-    pass
-
-cdef extern from "mojo/edk/embedder/simple_platform_support.h" \
-    namespace "mojo::embedder" nogil:
-  cdef cppclass SimplePlatformSupport(PlatformSupport):
-    SimplePlatformSupport()
-
-cdef extern from "mojo/edk/embedder/embedder.h" nogil:
-  cdef void InitCEmbedder "mojo::embedder::Init"(
-      scoped_ptr[PlatformSupport] platform_support)
-
-cdef extern from "mojo/public/platform/native/system_thunks.h" nogil:
-  cdef struct MojoSystemThunks:
-    pass
-  cdef MojoSystemThunks MojoMakeSystemThunks()
-
-def Init():
-  InitCEmbedder(scoped_ptr[PlatformSupport](
-      new SimplePlatformSupport()))
-  cdef MojoSystemThunks thunks = MojoMakeSystemThunks()
-  system.SetSystemThunks(<uintptr_t>(&thunks))
diff --git a/mojo/python/tests/async_wait_unittest.py b/mojo/python/tests/async_wait_unittest.py
deleted file mode 100644
index 71b7e75..0000000
--- a/mojo/python/tests/async_wait_unittest.py
+++ /dev/null
@@ -1,50 +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.
-
-import mojo_unittest
-
-# pylint: disable=E0611
-from mojo import system
-
-
-class AsyncWaitTest(mojo_unittest.MojoTestCase):
-
-  def setUp(self):
-    super(AsyncWaitTest, self).setUp()
-    self.array = []
-    self.handles = system.MessagePipe()
-    self.cancel = self.handles.handle0.AsyncWait(system.HANDLE_SIGNAL_READABLE,
-                                                 system.DEADLINE_INDEFINITE,
-                                                 self._OnResult)
-
-  def tearDown(self):
-    self.cancel()
-    self.handles = None
-    self.array = None
-    super(AsyncWaitTest, self).tearDown()
-
-  def _OnResult(self, value):
-    self.array.append(value)
-
-  def _WriteToHandle(self):
-    self.handles.handle1.WriteMessage()
-
-  def _PostWriteAndRun(self):
-    self.loop.PostDelayedTask(self._WriteToHandle, 0)
-    self.loop.RunUntilIdle()
-
-  def testAsyncWait(self):
-    self._PostWriteAndRun()
-    self.assertEquals(len(self.array), 1)
-    self.assertEquals(system.RESULT_OK, self.array[0])
-
-  def testAsyncWaitCancel(self):
-    self.loop.PostDelayedTask(self.cancel, 0)
-    self._PostWriteAndRun()
-    self.assertEquals(len(self.array), 0)
-
-  def testAsyncWaitImmediateCancel(self):
-    self.cancel()
-    self._PostWriteAndRun()
-    self.assertEquals(len(self.array), 0)
diff --git a/mojo/python/tests/bindings_constants_unittest.py b/mojo/python/tests/bindings_constants_unittest.py
deleted file mode 100644
index 85e97c6..0000000
--- a/mojo/python/tests/bindings_constants_unittest.py
+++ /dev/null
@@ -1,39 +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.
-
-import math
-import unittest
-
-# Generated files
-# pylint: disable=F0401
-import sample_service_mojom
-
-
-class ConstantBindingsTest(unittest.TestCase):
-
-  def testConstantGeneration(self):
-    self.assertEquals(sample_service_mojom.TWELVE, 12)
-    self.assertEquals(sample_service_mojom.TOO_BIG_FOR_SIGNED_INT64,
-                      9999999999999999999)
-    self.assertEquals(sample_service_mojom.DOUBLE_INFINITY,
-                      float('inf'))
-    self.assertEquals(sample_service_mojom.DOUBLE_NEGATIVE_INFINITY,
-                      float('-inf'))
-    self.assertTrue(math.isnan(sample_service_mojom.DOUBLE_NA_N))
-    self.assertEquals(sample_service_mojom.FLOAT_INFINITY,
-                      float('inf'))
-    self.assertEquals(sample_service_mojom.FLOAT_NEGATIVE_INFINITY,
-                      float('-inf'))
-    self.assertTrue(math.isnan(sample_service_mojom.FLOAT_NA_N))
-
-  def testConstantOnStructGeneration(self):
-    self.assertEquals(sample_service_mojom.Foo.FOOBY, "Fooby")
-
-  def testStructImmutability(self):
-    with self.assertRaises(AttributeError):
-      sample_service_mojom.Foo.FOOBY = 0
-    with self.assertRaises(AttributeError):
-      del sample_service_mojom.Foo.FOOBY
-    with self.assertRaises(AttributeError):
-      sample_service_mojom.Foo.BAR = 1
diff --git a/mojo/python/tests/bindings_enums_unittest.py b/mojo/python/tests/bindings_enums_unittest.py
deleted file mode 100644
index 6ec5d8c..0000000
--- a/mojo/python/tests/bindings_enums_unittest.py
+++ /dev/null
@@ -1,61 +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.
-
-import unittest
-
-# Generated files
-# pylint: disable=F0401
-import sample_import_mojom
-import sample_service_mojom
-
-
-class EnumBindingsTest(unittest.TestCase):
-
-  # Testing enum classes are in the right module.
-  def testModule(self):
-    self.assertEquals(sample_import_mojom.Shape.__module__,
-                      'sample_import_mojom')
-
-  # Testing that enum class have expected constant values.
-  def testTopLevelEnumGeneration(self):
-    self.assertEquals(sample_import_mojom.Shape.RECTANGLE, 1)
-    self.assertEquals(sample_import_mojom.Shape.CIRCLE, 2)
-    self.assertEquals(sample_import_mojom.Shape.TRIANGLE, 3)
-    self.assertEquals(sample_import_mojom.Shape.LAST,
-                      sample_import_mojom.Shape.TRIANGLE)
-
-    self.assertEquals(sample_import_mojom.AnotherShape.RECTANGLE, 10)
-    self.assertEquals(sample_import_mojom.AnotherShape.CIRCLE, 11)
-    self.assertEquals(sample_import_mojom.AnotherShape.TRIANGLE, 12)
-
-    self.assertEquals(sample_import_mojom.YetAnotherShape.RECTANGLE, 20)
-    self.assertEquals(sample_import_mojom.YetAnotherShape.CIRCLE, 21)
-    self.assertEquals(sample_import_mojom.YetAnotherShape.TRIANGLE, 22)
-
-  # Testing that internal enum class have expected constant values.
-  def testInternalEnumGeneration(self):
-    self.assertEquals(sample_service_mojom.Bar.Type.VERTICAL, 1)
-    self.assertEquals(sample_service_mojom.Bar.Type.HORIZONTAL, 2)
-    self.assertEquals(sample_service_mojom.Bar.Type.BOTH, 3)
-    self.assertEquals(sample_service_mojom.Bar.Type.INVALID, 4)
-
-  # Testing an enum class cannot be instantiated.
-  def testNonInstantiableEnum(self):
-    with self.assertRaises(TypeError):
-      sample_import_mojom.Shape()
-
-  # Testing an enum does not contain the VALUES constant.
-  def testNoVALUESConstant(self):
-    with self.assertRaises(AttributeError):
-      # pylint: disable=W0104
-      sample_import_mojom.Shape.VALUES
-
-  # Testing enum values are frozen.
-  def testEnumFrozen(self):
-    with self.assertRaises(AttributeError):
-      sample_import_mojom.Shape.RECTANGLE = 2
-    with self.assertRaises(AttributeError):
-      del sample_import_mojom.Shape.RECTANGLE
-    with self.assertRaises(AttributeError):
-      sample_import_mojom.Shape.NewShape = 4
diff --git a/mojo/python/tests/bindings_serialization_deserialization_unittest.py b/mojo/python/tests/bindings_serialization_deserialization_unittest.py
deleted file mode 100644
index 89599bb..0000000
--- a/mojo/python/tests/bindings_serialization_deserialization_unittest.py
+++ /dev/null
@@ -1,97 +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.
-
-import math
-import unittest
-
-# pylint: disable=E0611,F0401
-import mojo.system
-
-# Generated files
-# pylint: disable=F0401
-import sample_import_mojom
-import sample_import2_mojom
-import sample_service_mojom
-
-
-def _NewHandle():
-  return mojo.system.MessagePipe().handle0
-
-
-def _NewBar():
-  bar_instance = sample_service_mojom.Bar()
-  bar_instance.alpha = 22
-  bar_instance.beta = 87
-  bar_instance.gamma = 122
-  bar_instance.type = sample_service_mojom.Bar.Type.BOTH
-  return bar_instance
-
-
-def _NewFoo():
-  foo_instance = sample_service_mojom.Foo()
-  foo_instance.name = "Foo.name"
-  foo_instance.x = 23
-  foo_instance.y = -23
-  foo_instance.a = False
-  foo_instance.b = True
-  foo_instance.c = True
-  foo_instance.bar = _NewBar()
-  foo_instance.extra_bars = [
-      _NewBar(),
-      _NewBar(),
-  ]
-  foo_instance.data = 'Hello world'
-  foo_instance.source = _NewHandle()
-  foo_instance.input_streams = [ _NewHandle() ]
-  foo_instance.output_streams = [ _NewHandle(), _NewHandle() ]
-  foo_instance.array_of_array_of_bools = [ [ True, False ], [] ]
-  foo_instance.multi_array_of_strings = [
-      [
-          [ "1", "2" ],
-          [],
-          [ "3", "4" ],
-      ],
-      [],
-  ]
-  foo_instance.array_of_bools = [ True, 0, 1, 2, 0, 0, 0, 0, 0, True ]
-  return foo_instance
-
-
-class SerializationDeserializationTest(unittest.TestCase):
-
-  def testFooSerialization(self):
-    (data, _) = _NewFoo().Serialize()
-    self.assertTrue(len(data))
-    self.assertEquals(len(data) % 8, 0)
-
-  def testFooDeserialization(self):
-    (data, handles) = _NewFoo().Serialize()
-    self.assertTrue(
-        sample_service_mojom.Foo.Deserialize(data, handles))
-
-  def testFooSerializationDeserialization(self):
-    foo1 = _NewFoo()
-    (data, handles) = foo1.Serialize()
-    foo2 = sample_service_mojom.Foo.Deserialize(data, handles)
-    self.assertEquals(foo1, foo2)
-
-  def testDefaultsTestSerializationDeserialization(self):
-    v1 = sample_service_mojom.DefaultsTest()
-    v1.a18 = []
-    v1.a19 = ""
-    v1.a21 = sample_import_mojom.Point()
-    v1.a22.location = sample_import_mojom.Point()
-    v1.a22.size = sample_import2_mojom.Size()
-    (data, handles) = v1.Serialize()
-    v2 = sample_service_mojom.DefaultsTest.Deserialize(data, handles)
-    # NaN needs to be a special case.
-    self.assertNotEquals(v1, v2)
-    self.assertTrue(math.isnan(v2.a28))
-    self.assertTrue(math.isnan(v2.a31))
-    v1.a28 = v2.a28 = v1.a31 = v2.a31 = 0
-    self.assertEquals(v1, v2)
-
-  def testFooDeserializationError(self):
-    with self.assertRaises(Exception):
-      sample_service_mojom.Foo.Deserialize("", [])
diff --git a/mojo/python/tests/bindings_structs_unittest.py b/mojo/python/tests/bindings_structs_unittest.py
deleted file mode 100644
index 5a4c064..0000000
--- a/mojo/python/tests/bindings_structs_unittest.py
+++ /dev/null
@@ -1,217 +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.
-
-import math
-import unittest
-
-# pylint: disable=E0611,F0401
-import mojo.system
-
-# Generated files
-# pylint: disable=F0401
-import regression_tests_mojom
-import sample_import_mojom
-import sample_import2_mojom
-import sample_service_mojom
-
-
-class StructBindingsTest(unittest.TestCase):
-
-  def testModule(self):
-    self.assertEquals(sample_service_mojom.DefaultsTest.__module__,
-                      'sample_service_mojom')
-
-  def testDefaultsTest(self):
-    defaults_test = sample_service_mojom.DefaultsTest()
-    self.assertEquals(defaults_test.a0, -12)
-    self.assertEquals(defaults_test.a1, 12)
-    self.assertEquals(defaults_test.a2, 1234)
-    self.assertEquals(defaults_test.a3, 34567)
-    self.assertEquals(defaults_test.a4, 123456)
-    self.assertEquals(defaults_test.a5, 3456789012)
-    self.assertEquals(defaults_test.a6, -111111111111)
-    self.assertEquals(defaults_test.a7, 9999999999999999999)
-    self.assertEquals(defaults_test.a8, 0x12345)
-    self.assertEquals(defaults_test.a9, -0x12345)
-    self.assertEquals(defaults_test.a10, 1234)
-    self.assertEquals(defaults_test.a11, True)
-    self.assertEquals(defaults_test.a12, False)
-    self.assertEquals(defaults_test.a13, 123.25)
-    self.assertEquals(defaults_test.a14, 1234567890.123)
-    self.assertEquals(defaults_test.a15, 1E10)
-    self.assertEquals(defaults_test.a16, -1.2E+20)
-    self.assertEquals(defaults_test.a17, 1.23E-20)
-    self.assertEquals(defaults_test.a18, None)
-    self.assertEquals(defaults_test.a19, None)
-    self.assertEquals(defaults_test.a20, sample_service_mojom.Bar.Type.BOTH)
-    self.assertEquals(defaults_test.a21, None)
-    self.assertTrue(isinstance(defaults_test.a22, sample_import2_mojom.Thing))
-    self.assertEquals(defaults_test.a23, 0xFFFFFFFFFFFFFFFF)
-    self.assertEquals(defaults_test.a24, 0x123456789)
-    self.assertEquals(defaults_test.a25, -0x123456789)
-    self.assertEquals(defaults_test.a26, float('inf'))
-    self.assertEquals(defaults_test.a27, float('-inf'))
-    self.assertTrue(math.isnan(defaults_test.a28))
-    self.assertEquals(defaults_test.a29, float('inf'))
-    self.assertEquals(defaults_test.a30, float('-inf'))
-    self.assertTrue(math.isnan(defaults_test.a31))
-
-  def testNoAliasing(self):
-    foo1 = sample_service_mojom.Foo()
-    foo2 = sample_service_mojom.Foo()
-    foo1.name = "foo1"
-    foo2.name = "foo2"
-    self.assertEquals(foo1.name, "foo1")
-    self.assertEquals(foo2.name, "foo2")
-
-    defaults_test1 = sample_service_mojom.DefaultsTest()
-    defaults_test2 = sample_service_mojom.DefaultsTest()
-    self.assertIsNot(defaults_test1.a22, defaults_test2.a22)
-
-  def testImmutableAttributeSet(self):
-    foo_instance = sample_service_mojom.Foo()
-    with self.assertRaises(AttributeError):
-      foo_instance.new_attribute = None
-    with self.assertRaises(AttributeError):
-      del foo_instance.name
-
-  def _TestIntegerField(self, entity, field_name, bits, signed):
-    if signed:
-      min_value = -(1 << (bits - 1))
-      max_value = (1 << (bits - 1)) - 1
-    else:
-      min_value = 0
-      max_value = (1 << bits) - 1
-    entity.__setattr__(field_name, min_value)
-    entity.__setattr__(field_name, max_value)
-    with self.assertRaises(TypeError):
-      entity.__setattr__(field_name, None)
-    with self.assertRaises(OverflowError):
-      entity.__setattr__(field_name, min_value - 1)
-    with self.assertRaises(OverflowError):
-      entity.__setattr__(field_name, max_value + 1)
-    with self.assertRaises(TypeError):
-      entity.__setattr__(field_name, 'hello world')
-
-  def testTypes(self):
-    defaults_test = sample_service_mojom.DefaultsTest()
-    # Integer types
-    self._TestIntegerField(defaults_test, 'a0', 8, True)
-    self._TestIntegerField(defaults_test, 'a1', 8, False)
-    self._TestIntegerField(defaults_test, 'a2', 16, True)
-    self._TestIntegerField(defaults_test, 'a3', 16, False)
-    self._TestIntegerField(defaults_test, 'a4', 32, True)
-    self._TestIntegerField(defaults_test, 'a5', 32, False)
-    self._TestIntegerField(defaults_test, 'a6', 64, True)
-    self._TestIntegerField(defaults_test, 'a7', 64, False)
-
-    # Boolean types
-    defaults_test.a11 = False
-    self.assertEquals(defaults_test.a11, False)
-    defaults_test.a11 = None
-    self.assertEquals(defaults_test.a11, False)
-    defaults_test.a11 = []
-    self.assertEquals(defaults_test.a11, False)
-    defaults_test.a12 = True
-    self.assertEquals(defaults_test.a12, True)
-    defaults_test.a12 = 1
-    self.assertEquals(defaults_test.a12, True)
-    defaults_test.a12 = [[]]
-    self.assertEquals(defaults_test.a12, True)
-
-    # Floating point types
-    with self.assertRaises(TypeError):
-      defaults_test.a13 = 'hello'
-    with self.assertRaises(TypeError):
-      defaults_test.a14 = 'hello'
-
-    # Array type
-    defaults_test.a18 = None
-    defaults_test.a18 = []
-    defaults_test.a18 = [ 0 ]
-    defaults_test.a18 = [ 255 ]
-    defaults_test.a18 = [ 0, 255 ]
-    with self.assertRaises(TypeError):
-      defaults_test.a18 = [[]]
-    with self.assertRaises(OverflowError):
-      defaults_test.a18 = [ -1 ]
-    with self.assertRaises(OverflowError):
-      defaults_test.a18 = [ 256 ]
-
-    # String type
-    defaults_test.a19 = None
-    defaults_test.a19 = ''
-    defaults_test.a19 = 'hello world'
-    with self.assertRaises(TypeError):
-      defaults_test.a19 = [[]]
-    with self.assertRaises(TypeError):
-      defaults_test.a19 = [ -1 ]
-    with self.assertRaises(TypeError):
-      defaults_test.a19 = [ 256 ]
-
-    # Structs
-    defaults_test.a21 = None
-    defaults_test.a21 = sample_import_mojom.Point()
-    with self.assertRaises(TypeError):
-      defaults_test.a21 = 1
-    with self.assertRaises(TypeError):
-      defaults_test.a21 = sample_import2_mojom.Thing()
-
-    # Handles
-    foo_instance = sample_service_mojom.Foo()
-    foo_instance.source = None
-    foo_instance.source = mojo.system.Handle()
-    with self.assertRaises(TypeError):
-      foo_instance.source = 1
-    with self.assertRaises(TypeError):
-      foo_instance.source = object()
-
-  def testConstructor(self):
-    bar_instance = sample_service_mojom.Bar()
-    foo_instance = sample_service_mojom.Foo(name="Foo",
-                                            x=-1,
-                                            y=5,
-                                            a=False,
-                                            bar=bar_instance)
-    self.assertEquals(foo_instance.name, "Foo")
-    self.assertEquals(foo_instance.x, -1)
-    self.assertEquals(foo_instance.y, 5)
-    self.assertEquals(foo_instance.a, False)
-    self.assertEquals(foo_instance.bar, bar_instance)
-
-  def testPositionalConstructor(self):
-    p = sample_import_mojom.Point()
-    self.assertEquals(p.x, 0)
-    self.assertEquals(p.y, 0)
-
-    p = sample_import_mojom.Point(34)
-    self.assertEquals(p.x, 34)
-    self.assertEquals(p.y, 0)
-
-    p = sample_import_mojom.Point(34, 12)
-    self.assertEquals(p.x, 34)
-    self.assertEquals(p.y, 12)
-
-    p = sample_import_mojom.Point(x=34, y=12)
-    self.assertEquals(p.x, 34)
-    self.assertEquals(p.y, 12)
-
-    p = sample_import_mojom.Point(34, y=12)
-    self.assertEquals(p.x, 34)
-    self.assertEquals(p.y, 12)
-
-    with self.assertRaises(TypeError):
-      p = sample_import_mojom.Point(0, 0, 0)
-    with self.assertRaises(TypeError):
-      p = sample_import_mojom.Point(0, x=0)
-    with self.assertRaises(TypeError):
-      p = sample_import_mojom.Point(c=0)
-
-  def testCyclicDefinition(self):
-    a = regression_tests_mojom.A()
-    b = regression_tests_mojom.B()
-    self.assertIsNone(a.b)
-    self.assertIsNone(b.a)
-    a.b = b
-    self.assertIs(a.b, b)
diff --git a/mojo/python/tests/messaging_unittest.py b/mojo/python/tests/messaging_unittest.py
deleted file mode 100644
index 767ba74..0000000
--- a/mojo/python/tests/messaging_unittest.py
+++ /dev/null
@@ -1,207 +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.
-
-import unittest
-
-import mojo_unittest
-from mojo.bindings import messaging
-
-# pylint: disable=E0611
-from mojo import system
-
-
-class _ForwardingConnectionErrorHandler(messaging.ConnectionErrorHandler):
-
-  def __init__(self, callback):
-    messaging.ConnectionErrorHandler.__init__(self)
-    self._callback = callback
-
-  def OnError(self, result):
-    self._callback(result)
-
-
-class ConnectorTest(mojo_unittest.MojoTestCase):
-
-  def setUp(self):
-    super(ConnectorTest, self).setUp()
-    self.received_messages = []
-    self.received_errors = []
-    def _OnMessage(message):
-      self.received_messages.append(message)
-      return True
-    def _OnError(result):
-      self.received_errors.append(result)
-    handles = system.MessagePipe()
-    self.connector = messaging.Connector(handles.handle1)
-    self.connector.SetIncomingMessageReceiver(
-        messaging.ForwardingMessageReceiver(_OnMessage))
-    self.connector.SetErrorHandler(
-        _ForwardingConnectionErrorHandler(_OnError))
-    self.connector.Start()
-    self.handle = handles.handle0
-
-
-  def tearDown(self):
-    self.connector = None
-    self.handle = None
-    super(ConnectorTest, self).tearDown()
-
-  def testConnectorRead(self):
-    self.handle.WriteMessage()
-    self.loop.RunUntilIdle()
-    self.assertTrue(self.received_messages)
-    self.assertFalse(self.received_errors)
-
-  def testConnectorWrite(self):
-    self.connector.Accept(messaging.Message())
-    (result, _, _) = self.handle.ReadMessage()
-    self.assertEquals(result, system.RESULT_OK)
-    self.assertFalse(self.received_errors)
-
-  def testConnectorCloseRemoteHandle(self):
-    self.handle.Close()
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_messages)
-    self.assertTrue(self.received_errors)
-    self.assertEquals(self.received_errors[0],
-                      system.RESULT_FAILED_PRECONDITION)
-
-  def testConnectorDeleteConnector(self):
-    self.connector = None
-    (result, _, _) = self.handle.ReadMessage()
-    self.assertEquals(result, system.RESULT_FAILED_PRECONDITION)
-
-
-class HeaderTest(unittest.TestCase):
-
-  def testSimpleMessageHeader(self):
-    header = messaging.MessageHeader(0xdeadbeaf, messaging.NO_FLAG)
-    self.assertEqual(header.message_type, 0xdeadbeaf)
-    self.assertFalse(header.has_request_id)
-    self.assertFalse(header.expects_response)
-    self.assertFalse(header.is_response)
-    data = header.Serialize()
-    other_header = messaging.MessageHeader.Deserialize(data)
-    self.assertEqual(other_header.message_type, 0xdeadbeaf)
-    self.assertFalse(other_header.has_request_id)
-    self.assertFalse(other_header.expects_response)
-    self.assertFalse(other_header.is_response)
-
-  def testMessageHeaderWithRequestID(self):
-    # Request message.
-    header = messaging.MessageHeader(0xdeadbeaf,
-                                     messaging.MESSAGE_EXPECTS_RESPONSE_FLAG)
-
-    self.assertEqual(header.message_type, 0xdeadbeaf)
-    self.assertTrue(header.has_request_id)
-    self.assertTrue(header.expects_response)
-    self.assertFalse(header.is_response)
-    self.assertEqual(header.request_id, 0)
-
-    data = header.Serialize()
-    other_header = messaging.MessageHeader.Deserialize(data)
-
-    self.assertEqual(other_header.message_type, 0xdeadbeaf)
-    self.assertTrue(other_header.has_request_id)
-    self.assertTrue(other_header.expects_response)
-    self.assertFalse(other_header.is_response)
-    self.assertEqual(other_header.request_id, 0)
-
-    header.request_id = 0xdeadbeafdeadbeaf
-    data = header.Serialize()
-    other_header = messaging.MessageHeader.Deserialize(data)
-
-    self.assertEqual(other_header.request_id, 0xdeadbeafdeadbeaf)
-
-    # Response message.
-    header = messaging.MessageHeader(0xdeadbeaf,
-                                     messaging.MESSAGE_IS_RESPONSE_FLAG,
-                                     0xdeadbeafdeadbeaf)
-
-    self.assertEqual(header.message_type, 0xdeadbeaf)
-    self.assertTrue(header.has_request_id)
-    self.assertFalse(header.expects_response)
-    self.assertTrue(header.is_response)
-    self.assertEqual(header.request_id, 0xdeadbeafdeadbeaf)
-
-    data = header.Serialize()
-    other_header = messaging.MessageHeader.Deserialize(data)
-
-    self.assertEqual(other_header.message_type, 0xdeadbeaf)
-    self.assertTrue(other_header.has_request_id)
-    self.assertFalse(other_header.expects_response)
-    self.assertTrue(other_header.is_response)
-    self.assertEqual(other_header.request_id, 0xdeadbeafdeadbeaf)
-
-
-class RouterTest(mojo_unittest.MojoTestCase):
-
-  def setUp(self):
-    super(RouterTest, self).setUp()
-    self.received_messages = []
-    self.received_errors = []
-    def _OnMessage(message):
-      self.received_messages.append(message)
-      return True
-    def _OnError(result):
-      self.received_errors.append(result)
-    handles = system.MessagePipe()
-    self.router = messaging.Router(handles.handle1)
-    self.router.SetIncomingMessageReceiver(
-        messaging.ForwardingMessageReceiver(_OnMessage))
-    self.router.SetErrorHandler(
-        _ForwardingConnectionErrorHandler(_OnError))
-    self.router.Start()
-    self.handle = handles.handle0
-
-  def tearDown(self):
-    self.router = None
-    self.handle = None
-    super(RouterTest, self).tearDown()
-
-  def testSimpleMessage(self):
-    header_data = messaging.MessageHeader(0, messaging.NO_FLAG).Serialize()
-    message = messaging.Message(header_data)
-    self.router.Accept(message)
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_errors)
-    self.assertFalse(self.received_messages)
-    (res, data, _) = self.handle.ReadMessage(bytearray(len(header_data)))
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(data[0], header_data)
-
-  def testSimpleReception(self):
-    header_data = messaging.MessageHeader(0, messaging.NO_FLAG).Serialize()
-    self.handle.WriteMessage(header_data)
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_errors)
-    self.assertEquals(len(self.received_messages), 1)
-    self.assertEquals(self.received_messages[0].data, header_data)
-
-  def testRequestResponse(self):
-    header_data = messaging.MessageHeader(
-        0, messaging.MESSAGE_EXPECTS_RESPONSE_FLAG).Serialize()
-    message = messaging.Message(header_data)
-    back_messages = []
-    def OnBackMessage(message):
-      back_messages.append(message)
-    self.router.AcceptWithResponder(message,
-                                    messaging.ForwardingMessageReceiver(
-                                        OnBackMessage))
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_errors)
-    self.assertFalse(self.received_messages)
-    (res, data, _) = self.handle.ReadMessage(bytearray(len(header_data)))
-    self.assertEquals(system.RESULT_OK, res)
-    message_header = messaging.MessageHeader.Deserialize(data[0])
-    self.assertNotEquals(message_header.request_id, 0)
-    response_header_data = messaging.MessageHeader(
-        0,
-        messaging.MESSAGE_IS_RESPONSE_FLAG,
-        message_header.request_id).Serialize()
-    self.handle.WriteMessage(response_header_data)
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_errors)
-    self.assertEquals(len(back_messages), 1)
-    self.assertEquals(back_messages[0].data, response_header_data)
diff --git a/mojo/python/tests/mojo_unittest.py b/mojo/python/tests/mojo_unittest.py
deleted file mode 100644
index e8961ac..0000000
--- a/mojo/python/tests/mojo_unittest.py
+++ /dev/null
@@ -1,19 +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.
-
-import unittest
-
-# pylint: disable=E0611,F0401
-import mojo.embedder
-import mojo.system as system
-
-
-class MojoTestCase(unittest.TestCase):
-
-  def setUp(self):
-    mojo.embedder.Init()
-    self.loop = system.RunLoop()
-
-  def tearDown(self):
-    self.loop = None
diff --git a/mojo/python/tests/promise_unittest.py b/mojo/python/tests/promise_unittest.py
deleted file mode 100644
index 44427ba..0000000
--- a/mojo/python/tests/promise_unittest.py
+++ /dev/null
@@ -1,181 +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.
-
-import unittest
-
-# pylint: disable=F0401
-from mojo.bindings import promise
-
-
-class PromiseTest(unittest.TestCase):
-
-  def setUp(self):
-    self.accumulated = []
-
-  def _AddToAccumulated(self, res):
-    self.accumulated.append(res)
-    return res
-
-  def testResolve(self):
-    p = promise.Promise.Resolve(0)
-    self.assertEquals(p.state, promise.Promise.STATE_FULLFILLED)
-    p.Then(self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [0])
-
-  def testResolveToPromise(self):
-    p = promise.Promise.Resolve(0)
-    self.assertEquals(p.state, promise.Promise.STATE_FULLFILLED)
-    q = promise.Promise.Resolve(p)
-    self.assertEquals(p.state, promise.Promise.STATE_FULLFILLED)
-    q.Then(self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [0])
-
-  def testReject(self):
-    p = promise.Promise.Reject(0)
-    self.assertEquals(p.state, promise.Promise.STATE_REJECTED)
-    p.Then(onRejected=self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [0])
-
-  def testGeneratorFunctionResolve(self):
-    (p, resolve, _) = _GetPromiseAndFunctions()
-    self.assertEquals(p.state, promise.Promise.STATE_PENDING)
-    p.Then(self._AddToAccumulated)
-    resolve(0)
-    self.assertEquals(p.state, promise.Promise.STATE_FULLFILLED)
-    self.assertEquals(self.accumulated, [0])
-
-  def testGeneratorFunctionReject(self):
-    (p, _, reject) = _GetPromiseAndFunctions()
-    self.assertEquals(p.state, promise.Promise.STATE_PENDING)
-    p.Then(None, self._AddToAccumulated)
-    reject(0)
-    self.assertEquals(p.state, promise.Promise.STATE_REJECTED)
-    self.assertEquals(self.accumulated, [0])
-
-  def testGeneratorFunctionResolveToPromise(self):
-    (p1, resolve, _) = _GetPromiseAndFunctions()
-    p2 = promise.Promise(lambda x, y: x(p1))
-    self.assertEquals(p2.state, promise.Promise.STATE_PENDING)
-    p2.Then(self._AddToAccumulated)
-    resolve(promise.Promise.Resolve(0))
-    self.assertEquals(self.accumulated, [0])
-
-  def testComputation(self):
-    (p, resolve, _) = _GetPromiseAndFunctions()
-    p.Then(lambda x: x+1).Then(lambda x: x+2).Then(self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [])
-    resolve(0)
-    self.assertEquals(self.accumulated, [3])
-
-  def testRecoverAfterException(self):
-    (p, resolve, _) = _GetPromiseAndFunctions()
-    p.Then(_ThrowException).Catch(self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [])
-    resolve(0)
-    self.assertEquals(len(self.accumulated), 1)
-    self.assertIsInstance(self.accumulated[0], RuntimeError)
-    self.assertEquals(self.accumulated[0].message, 0)
-
-  def testMultipleRejectResolve(self):
-    (p, resolve, reject) = _GetPromiseAndFunctions()
-    p.Then(self._AddToAccumulated, self._AddToAccumulated)
-    resolve(0)
-    self.assertEquals(self.accumulated, [0])
-    resolve(0)
-    self.assertEquals(self.accumulated, [0])
-    reject(0)
-    self.assertEquals(self.accumulated, [0])
-
-    self.accumulated = []
-    (p, resolve, reject) = _GetPromiseAndFunctions()
-    p.Then(self._AddToAccumulated, self._AddToAccumulated)
-    reject(0)
-    self.assertEquals(self.accumulated, [0])
-    resolve(0)
-    self.assertEquals(self.accumulated, [0])
-    reject(0)
-    self.assertEquals(self.accumulated, [0])
-
-  def testAll(self):
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    all_promise = promise.Promise.All(*promises)
-    res = []
-    def AddToRes(values):
-      res.append(values)
-    all_promise.Then(AddToRes, AddToRes)
-    for i, (_, resolve, _) in enumerate(promises_and_functions):
-      self.assertEquals(len(res), 0)
-      resolve(i)
-    self.assertEquals(len(res), 1)
-    self.assertEquals(res[0], [i for i in xrange(10)])
-    self.assertEquals(all_promise.state, promise.Promise.STATE_FULLFILLED)
-
-  def testAllFailure(self):
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    all_promise = promise.Promise.All(*promises)
-    res = []
-    def AddToRes(values):
-      res.append(values)
-    all_promise.Then(AddToRes, AddToRes)
-    for i in xrange(10):
-      if i <= 5:
-        self.assertEquals(len(res), 0)
-      else:
-        self.assertEquals(len(res), 1)
-      if i != 5:
-        promises_and_functions[i][1](i)
-      else:
-        promises_and_functions[i][2]('error')
-    self.assertEquals(len(res), 1)
-    self.assertEquals(res[0], 'error')
-    self.assertEquals(all_promise.state, promise.Promise.STATE_REJECTED)
-
-  def testRace(self):
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    race_promise = promise.Promise.Race(*promises)
-    res = []
-    def AddToRes(values):
-      res.append(values)
-    race_promise.Then(AddToRes, AddToRes)
-    self.assertEquals(len(res), 0)
-    promises_and_functions[7][1]('success')
-    self.assertEquals(len(res), 1)
-    for i, (f) in enumerate(promises_and_functions):
-      f[1 + (i % 2)](i)
-    self.assertEquals(len(res), 1)
-    self.assertEquals(res[0], 'success')
-    self.assertEquals(race_promise.state, promise.Promise.STATE_FULLFILLED)
-
-  def testRaceFailure(self):
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    race_promise = promise.Promise.Race(*promises)
-    res = []
-    def AddToRes(values):
-      res.append(values)
-    race_promise.Then(AddToRes, AddToRes)
-    self.assertEquals(len(res), 0)
-    promises_and_functions[7][2]('error')
-    self.assertEquals(len(res), 1)
-    for i, (f) in enumerate(promises_and_functions):
-      f[1 + (i % 2)](i)
-    self.assertEquals(len(res), 1)
-    self.assertEquals(res[0], 'error')
-    self.assertEquals(race_promise.state, promise.Promise.STATE_REJECTED)
-
-
-def _GetPromiseAndFunctions():
-  functions = {}
-  def GeneratorFunction(resolve, reject):
-    functions['resolve'] = resolve
-    functions['reject'] = reject
-  p = promise.Promise(GeneratorFunction)
-  return (p, functions['resolve'], functions['reject'])
-
-
-def _ThrowException(x):
-  raise RuntimeError(x)
diff --git a/mojo/python/tests/runloop_unittest.py b/mojo/python/tests/runloop_unittest.py
deleted file mode 100644
index 5c1ca83..0000000
--- a/mojo/python/tests/runloop_unittest.py
+++ /dev/null
@@ -1,41 +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.
-
-import mojo_unittest
-
-# pylint: disable=E0611
-from mojo import system
-
-
-def _Increment(array):
-  def _Closure():
-    array.append(0)
-  return _Closure
-
-
-class RunLoopTest(mojo_unittest.MojoTestCase):
-
-  def testRunLoop(self):
-    array = []
-    for _ in xrange(10):
-      self.loop.PostDelayedTask(_Increment(array))
-    self.loop.RunUntilIdle()
-    self.assertEquals(len(array), 10)
-
-  def testRunLoopWithException(self):
-    def Throw():
-      raise Exception("error")
-    array = []
-    self.loop.PostDelayedTask(Throw)
-    self.loop.PostDelayedTask(_Increment(array))
-    with self.assertRaisesRegexp(Exception, '^error$'):
-      self.loop.Run()
-    self.assertEquals(len(array), 0)
-    self.loop.RunUntilIdle()
-    self.assertEquals(len(array), 1)
-
-  def testCurrent(self):
-    self.assertEquals(system.RunLoop.Current(), self.loop)
-    self.loop = None
-    self.assertIsNone(system.RunLoop.Current())
diff --git a/mojo/python/tests/system_unittest.py b/mojo/python/tests/system_unittest.py
deleted file mode 100644
index e3b7c10..0000000
--- a/mojo/python/tests/system_unittest.py
+++ /dev/null
@@ -1,293 +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.
-
-import random
-import time
-
-import mojo_unittest
-
-# pylint: disable=E0611
-from mojo import system
-
-DATA_SIZE = 1024
-
-
-def _GetRandomBuffer(size):
-  random.seed(size)
-  return bytearray(''.join(chr(random.randint(0, 255)) for i in xrange(size)))
-
-
-class CoreTest(mojo_unittest.MojoTestCase):
-
-  def testResults(self):
-    self.assertEquals(system.RESULT_OK, 0)
-    self.assertLess(system.RESULT_CANCELLED, 0)
-    self.assertLess(system.RESULT_UNKNOWN, 0)
-    self.assertLess(system.RESULT_INVALID_ARGUMENT, 0)
-    self.assertLess(system.RESULT_DEADLINE_EXCEEDED, 0)
-    self.assertLess(system.RESULT_NOT_FOUND, 0)
-    self.assertLess(system.RESULT_ALREADY_EXISTS, 0)
-    self.assertLess(system.RESULT_PERMISSION_DENIED, 0)
-    self.assertLess(system.RESULT_RESOURCE_EXHAUSTED, 0)
-    self.assertLess(system.RESULT_FAILED_PRECONDITION, 0)
-    self.assertLess(system.RESULT_ABORTED, 0)
-    self.assertLess(system.RESULT_OUT_OF_RANGE, 0)
-    self.assertLess(system.RESULT_UNIMPLEMENTED, 0)
-    self.assertLess(system.RESULT_INTERNAL, 0)
-    self.assertLess(system.RESULT_UNAVAILABLE, 0)
-    self.assertLess(system.RESULT_DATA_LOSS, 0)
-    self.assertLess(system.RESULT_BUSY, 0)
-    self.assertLess(system.RESULT_SHOULD_WAIT, 0)
-
-  def testConstants(self):
-    self.assertGreaterEqual(system.DEADLINE_INDEFINITE, 0)
-    self.assertGreaterEqual(system.HANDLE_SIGNAL_NONE, 0)
-    self.assertGreaterEqual(system.HANDLE_SIGNAL_READABLE, 0)
-    self.assertGreaterEqual(system.HANDLE_SIGNAL_WRITABLE, 0)
-    self.assertGreaterEqual(system.WRITE_MESSAGE_FLAG_NONE, 0)
-    self.assertGreaterEqual(system.READ_MESSAGE_FLAG_NONE, 0)
-    self.assertGreaterEqual(system.READ_MESSAGE_FLAG_MAY_DISCARD, 0)
-    self.assertGreaterEqual(system.WRITE_DATA_FLAG_NONE, 0)
-    self.assertGreaterEqual(system.WRITE_DATA_FLAG_ALL_OR_NONE, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_NONE, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_ALL_OR_NONE, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_DISCARD, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_QUERY, 0)
-    self.assertGreaterEqual(system.MAP_BUFFER_FLAG_NONE, 0)
-
-  def testGetTimeTicksNow(self):
-    v1 = system.GetTimeTicksNow()
-    time.sleep(1e-3)
-    v2 = system.GetTimeTicksNow()
-    self.assertGreater(v1, 0)
-    self.assertGreater(v2, v1 + 1e2)
-    self.assertLess(v2, v1 + 1e5)
-
-  def _testHandlesCreation(self, *args):
-    for handle in args:
-      self.assertTrue(handle.IsValid())
-      handle.Close()
-      self.assertFalse(handle.IsValid())
-
-  def _TestMessageHandleCreation(self, handles):
-    self._testHandlesCreation(handles.handle0, handles.handle1)
-
-  def testCreateMessagePipe(self):
-    self._TestMessageHandleCreation(system.MessagePipe())
-
-  def testCreateMessagePipeWithNoneOptions(self):
-    self._TestMessageHandleCreation(system.MessagePipe(None))
-
-  def testCreateMessagePipeWithOptions(self):
-    self._TestMessageHandleCreation(
-        system.MessagePipe(system.CreateMessagePipeOptions()))
-
-  def testWaitOverMessagePipe(self):
-    handles = system.MessagePipe()
-    handle = handles.handle0
-
-    self.assertEquals(system.RESULT_OK, handle.Wait(
-        system.HANDLE_SIGNAL_WRITABLE, system.DEADLINE_INDEFINITE))
-    self.assertEquals(system.RESULT_DEADLINE_EXCEEDED,
-                      handle.Wait(system.HANDLE_SIGNAL_READABLE, 0))
-
-    handles.handle1.WriteMessage()
-
-    self.assertEquals(
-        system.RESULT_OK,
-        handle.Wait(
-            system.HANDLE_SIGNAL_READABLE,
-            system.DEADLINE_INDEFINITE))
-
-  def testWaitOverManyMessagePipe(self):
-    handles = system.MessagePipe()
-    handle0 = handles.handle0
-    handle1 = handles.handle1
-
-    self.assertEquals(
-        0,
-        system.WaitMany(
-            [(handle0, system.HANDLE_SIGNAL_WRITABLE),
-             (handle1, system.HANDLE_SIGNAL_WRITABLE)],
-            system.DEADLINE_INDEFINITE))
-    self.assertEquals(
-        system.RESULT_DEADLINE_EXCEEDED,
-        system.WaitMany(
-            [(handle0, system.HANDLE_SIGNAL_READABLE),
-             (handle1, system.HANDLE_SIGNAL_READABLE)], 0))
-
-    handle0.WriteMessage()
-
-    self.assertEquals(
-        1,
-        system.WaitMany(
-            [(handle0, system.HANDLE_SIGNAL_READABLE),
-             (handle1, system.HANDLE_SIGNAL_READABLE)],
-            system.DEADLINE_INDEFINITE))
-
-  def testSendBytesOverMessagePipe(self):
-    handles = system.MessagePipe()
-    data = _GetRandomBuffer(DATA_SIZE)
-    handles.handle0.WriteMessage(data)
-    (res, buffers, next_message) = handles.handle1.ReadMessage()
-    self.assertEquals(system.RESULT_RESOURCE_EXHAUSTED, res)
-    self.assertEquals(None, buffers)
-    self.assertEquals((DATA_SIZE, 0), next_message)
-    result = bytearray(DATA_SIZE)
-    (res, buffers, next_message) = handles.handle1.ReadMessage(result)
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(None, next_message)
-    self.assertEquals((data, []), buffers)
-
-  def testSendEmptyDataOverMessagePipe(self):
-    handles = system.MessagePipe()
-    handles.handle0.WriteMessage(None)
-    (res, buffers, next_message) = handles.handle1.ReadMessage()
-
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(None, next_message)
-    self.assertEquals((None, []), buffers)
-
-  def testSendHandleOverMessagePipe(self):
-    handles = system.MessagePipe()
-    handles_to_send = system.MessagePipe()
-    handles.handle0.WriteMessage(handles=[handles_to_send.handle0,
-                                           handles_to_send.handle1])
-    (res, buffers, next_message) = handles.handle1.ReadMessage(
-        max_number_of_handles=2)
-
-    self.assertFalse(handles_to_send.handle0.IsValid())
-    self.assertFalse(handles_to_send.handle1.IsValid())
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(None, next_message)
-    self.assertEquals(None, buffers[0])
-    self.assertEquals(2, len(buffers[1]))
-
-    handles = buffers[1]
-    for handle in handles:
-      self.assertTrue(handle.IsValid())
-      (res, buffers, next_message) = handle.ReadMessage()
-      self.assertEquals(system.RESULT_SHOULD_WAIT, res)
-
-    for handle in handles:
-      handle.WriteMessage()
-
-    for handle in handles:
-      (res, buffers, next_message) = handle.ReadMessage()
-      self.assertEquals(system.RESULT_OK, res)
-
-  def _TestDataHandleCreation(self, handles):
-    self._testHandlesCreation(
-        handles.producer_handle, handles.consumer_handle)
-
-  def testCreateDataPipe(self):
-    self._TestDataHandleCreation(system.DataPipe())
-
-  def testCreateDataPipeWithNoneOptions(self):
-    self._TestDataHandleCreation(system.DataPipe(None))
-
-  def testCreateDataPipeWithDefaultOptions(self):
-    self._TestDataHandleCreation(
-        system.DataPipe(system.CreateDataPipeOptions()))
-
-  def testCreateDataPipeWithDiscardFlag(self):
-    options = system.CreateDataPipeOptions()
-    options.flags = system.CreateDataPipeOptions.FLAG_MAY_DISCARD
-    self._TestDataHandleCreation(system.DataPipe(options))
-
-  def testCreateDataPipeWithElementSize(self):
-    options = system.CreateDataPipeOptions()
-    options.element_num_bytes = 5
-    self._TestDataHandleCreation(system.DataPipe(options))
-
-  def testCreateDataPipeWithCapacity(self):
-    options = system.CreateDataPipeOptions()
-    options.element_capacity_num_bytes = DATA_SIZE
-    self._TestDataHandleCreation(system.DataPipe(options))
-
-  def testCreateDataPipeWithIncorrectParameters(self):
-    options = system.CreateDataPipeOptions()
-    options.element_num_bytes = 5
-    options.capacity_num_bytes = DATA_SIZE
-    with self.assertRaises(system.MojoException) as cm:
-      self._TestDataHandleCreation(system.DataPipe(options))
-    self.assertEquals(system.RESULT_INVALID_ARGUMENT, cm.exception.mojo_result)
-
-  def testSendEmptyDataOverDataPipe(self):
-    pipes = system.DataPipe()
-    self.assertEquals((system.RESULT_OK, 0), pipes.producer_handle.WriteData())
-    self.assertEquals(
-        (system.RESULT_OK, None), pipes.consumer_handle.ReadData())
-
-  def testSendDataOverDataPipe(self):
-    pipes = system.DataPipe()
-    data = _GetRandomBuffer(DATA_SIZE)
-    self.assertEquals((system.RESULT_OK, DATA_SIZE),
-                      pipes.producer_handle.WriteData(data))
-    self.assertEquals((system.RESULT_OK, data),
-                      pipes.consumer_handle.ReadData(bytearray(DATA_SIZE)))
-
-  def testTwoPhaseWriteOnDataPipe(self):
-    pipes = system.DataPipe()
-    (res, buf) = pipes.producer_handle.BeginWriteData(DATA_SIZE)
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertGreaterEqual(len(buf.buffer), DATA_SIZE)
-    data = _GetRandomBuffer(DATA_SIZE)
-    buf.buffer[0:DATA_SIZE] = data
-    self.assertEquals(system.RESULT_OK, buf.End(DATA_SIZE))
-    self.assertEquals((system.RESULT_OK, data),
-                      pipes.consumer_handle.ReadData(bytearray(DATA_SIZE)))
-
-  def testTwoPhaseReadOnDataPipe(self):
-    pipes = system.DataPipe()
-    data = _GetRandomBuffer(DATA_SIZE)
-    self.assertEquals((system.RESULT_OK, DATA_SIZE),
-                      pipes.producer_handle.WriteData(data))
-    (res, buf) = pipes.consumer_handle.BeginReadData()
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(DATA_SIZE, len(buf.buffer))
-    self.assertEquals(data, buf.buffer)
-    self.assertEquals(system.RESULT_OK, buf.End(DATA_SIZE))
-
-  def testCreateSharedBuffer(self):
-    self._testHandlesCreation(system.CreateSharedBuffer(DATA_SIZE))
-
-  def testCreateSharedBufferWithNoneOptions(self):
-    self._testHandlesCreation(system.CreateSharedBuffer(DATA_SIZE, None))
-
-  def testCreateSharedBufferWithDefaultOptions(self):
-    self._testHandlesCreation(
-        system.CreateSharedBuffer(
-            DATA_SIZE,
-            system.CreateSharedBufferOptions()))
-
-  def testDuplicateSharedBuffer(self):
-    handle = system.CreateSharedBuffer(DATA_SIZE)
-    self._testHandlesCreation(handle.Duplicate())
-
-  def testDuplicateSharedBufferWithNoneOptions(self):
-    handle = system.CreateSharedBuffer(DATA_SIZE)
-    self._testHandlesCreation(handle.Duplicate(None))
-
-  def testDuplicateSharedBufferWithDefaultOptions(self):
-    handle = system.CreateSharedBuffer(DATA_SIZE)
-    self._testHandlesCreation(
-        handle.Duplicate(system.DuplicateSharedBufferOptions()))
-
-  def testSendBytesOverSharedBuffer(self):
-    handle = system.CreateSharedBuffer(DATA_SIZE)
-    duplicated = handle.Duplicate()
-    data = _GetRandomBuffer(DATA_SIZE)
-    (res1, buf1) = handle.Map(0, DATA_SIZE)
-    (res2, buf2) = duplicated.Map(0, DATA_SIZE)
-    self.assertEquals(system.RESULT_OK, res1)
-    self.assertEquals(system.RESULT_OK, res2)
-    self.assertEquals(DATA_SIZE, len(buf1.buffer))
-    self.assertEquals(DATA_SIZE, len(buf2.buffer))
-    self.assertEquals(buf1.buffer, buf2.buffer)
-
-    buf1.buffer[:] = data
-    self.assertEquals(data, buf1.buffer)
-    self.assertEquals(data, buf2.buffer)
-    self.assertEquals(buf1.buffer, buf2.buffer)
diff --git a/mojo/services/BUILD.gn b/mojo/services/BUILD.gn
index fdddd3d..f4809fd 100644
--- a/mojo/services/BUILD.gn
+++ b/mojo/services/BUILD.gn
@@ -20,16 +20,10 @@
     "//mojo/services/public/interfaces/surfaces",
     "//mojo/services/surfaces",
     "//mojo/services/test_service:bindings",
+    "//mojo/services/public/interfaces/view_manager",
+    "//mojo/services/public/interfaces/window_manager2",
   ]
   if (!is_android) {
     deps += ["//mojo/services/native_viewport"]
   }
-  if (use_aura) {
-    deps += [
-      "//mojo/services/public/interfaces/view_manager",
-      "//mojo/services/public/interfaces/window_manager2",
-      "//mojo/services/view_manager",
-      "//mojo/services/window_manager",
-    ]
-  }
 }
diff --git a/mojo/services/html_viewer/BUILD.gn b/mojo/services/html_viewer/BUILD.gn
index 31bc4d4..07d09f5 100644
--- a/mojo/services/html_viewer/BUILD.gn
+++ b/mojo/services/html_viewer/BUILD.gn
@@ -2,10 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# GYP version: mojo/mojo_services.gypi:mojo_html_viewer
+# GYP version: mojo/mojo_services.gypi:html_viewer
 shared_library("html_viewer") {
-  output_name = "mojo_html_viewer"
-
   sources = [
     "blink_basic_type_converters.cc",
     "blink_basic_type_converters.h",
@@ -52,6 +50,7 @@
     "//media/audio",
     "//media/base",
     "//media/blink",
+    "//media/mojo",
     "//mojo/application",
     "//mojo/cc",
     "//mojo/common",
diff --git a/mojo/services/html_viewer/OWNERS b/mojo/services/html_viewer/OWNERS
new file mode 100644
index 0000000..5562b116
--- /dev/null
+++ b/mojo/services/html_viewer/OWNERS
@@ -0,0 +1 @@
+aa@chromium.org
diff --git a/mojo/services/html_viewer/html_document_view.cc b/mojo/services/html_viewer/html_document_view.cc
index 0ceb101..a7d3c95a 100644
--- a/mojo/services/html_viewer/html_document_view.cc
+++ b/mojo/services/html_viewer/html_document_view.cc
@@ -177,7 +177,8 @@
     blink::WebLocalFrame* frame,
     const blink::WebURL& url,
     blink::WebMediaPlayerClient* client) {
-  return web_media_player_factory_->CreateMediaPlayer(frame, url, client);
+  return web_media_player_factory_->CreateMediaPlayer(
+      frame, url, client, shell_);
 }
 
 blink::WebMediaPlayer* HTMLDocumentView::createMediaPlayer(
diff --git a/mojo/services/html_viewer/html_viewer.cc b/mojo/services/html_viewer/html_viewer.cc
index 967a75a..dc56ddc 100644
--- a/mojo/services/html_viewer/html_viewer.cc
+++ b/mojo/services/html_viewer/html_viewer.cc
@@ -26,6 +26,13 @@
 
 namespace mojo {
 
+// Switches for html_viewer to be used with "--args-for". For example:
+// --args-for='mojo://html_viewer --enable-mojo-media-renderer'
+
+// Enable mojo::MediaRenderer in media pipeline instead of using the internal
+// media::Renderer implementation.
+const char kEnableMojoMediaRenderer[] = "--enable-mojo-media-renderer";
+
 class HTMLViewer;
 
 class ContentHandlerImpl : public InterfaceImpl<ContentHandler> {
@@ -72,18 +79,26 @@
     blink_platform_impl_.reset(new BlinkPlatformImpl(app));
     blink::initialize(blink_platform_impl_.get());
 #if !defined(COMPONENT_BUILD)
-  base::i18n::InitializeICU();
+    base::i18n::InitializeICU();
 
-  ui::RegisterPathProvider();
+    ui::RegisterPathProvider();
 
-  base::FilePath ui_test_pak_path;
-  CHECK(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
-  ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
+    base::FilePath ui_test_pak_path;
+    CHECK(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
+    ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
 #endif
 
+    bool enable_mojo_media_renderer = false;
+    for (const auto& arg : app->args()) {
+      if (arg == kEnableMojoMediaRenderer) {
+        enable_mojo_media_renderer = true;
+        break;
+      }
+    }
+
     compositor_thread_.Start();
     web_media_player_factory_.reset(new WebMediaPlayerFactory(
-        compositor_thread_.message_loop_proxy()));
+        compositor_thread_.message_loop_proxy(), enable_mojo_media_renderer));
   }
 
   bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
diff --git a/mojo/services/html_viewer/webmediaplayer_factory.cc b/mojo/services/html_viewer/webmediaplayer_factory.cc
index bbf8c81..8e3aee4 100644
--- a/mojo/services/html_viewer/webmediaplayer_factory.cc
+++ b/mojo/services/html_viewer/webmediaplayer_factory.cc
@@ -9,20 +9,25 @@
 #include "base/threading/thread.h"
 #include "media/audio/audio_manager.h"
 #include "media/audio/audio_manager_base.h"
-#include "media/audio/null_audio_sink.h"
+#include "media/audio/audio_output_stream_sink.h"
 #include "media/base/audio_hardware_config.h"
 #include "media/base/media.h"
 #include "media/base/media_log.h"
+#include "media/base/renderer.h"
 #include "media/blink/null_encrypted_media_player_support.h"
 #include "media/blink/webmediaplayer_impl.h"
 #include "media/blink/webmediaplayer_params.h"
 #include "media/filters/gpu_video_accelerator_factories.h"
+#include "media/mojo/services/mojo_renderer_impl.h"
+#include "mojo/public/interfaces/application/shell.mojom.h"
 
 namespace mojo {
 
 WebMediaPlayerFactory::WebMediaPlayerFactory(
-    const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner)
+    const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner,
+    bool enable_mojo_media_renderer)
     : compositor_task_runner_(compositor_task_runner),
+      enable_mojo_media_renderer_(enable_mojo_media_renderer),
       media_thread_("Media"),
       audio_manager_(media::AudioManager::Create(&fake_audio_log_factory_)),
       audio_hardware_config_(
@@ -43,10 +48,20 @@
 blink::WebMediaPlayer* WebMediaPlayerFactory::CreateMediaPlayer(
     blink::WebLocalFrame* frame,
     const blink::WebURL& url,
-    blink::WebMediaPlayerClient* client) {
+    blink::WebMediaPlayerClient* client,
+    Shell* shell) {
 #if defined(OS_ANDROID)
   return NULL;
 #else
+  scoped_ptr<media::Renderer> renderer;
+
+  if (enable_mojo_media_renderer_) {
+    ServiceProviderPtr media_renderer_service_provider;
+    shell->ConnectToApplication("mojo:mojo_media_renderer_app",
+                                GetProxy(&media_renderer_service_provider));
+    renderer.reset(new media::MojoRendererImpl(
+        GetMediaThreadTaskRunner(), media_renderer_service_provider.get()));
+  }
 
   media::WebMediaPlayerParams params(
       media::WebMediaPlayerParams::DeferLoadCB(),
@@ -60,7 +75,8 @@
       NULL);
   base::WeakPtr<media::WebMediaPlayerDelegate> delegate;
 
-  return new media::WebMediaPlayerImpl(frame, client, delegate, params);
+  return new media::WebMediaPlayerImpl(
+      frame, client, delegate, renderer.Pass(), params);
 #endif
 }
 
@@ -71,9 +87,9 @@
 
 scoped_refptr<media::AudioRendererSink>
 WebMediaPlayerFactory::CreateAudioRendererSink() {
-  // TODO(acolwell): Replace this with an AudioRendererSink implementation
-  // that actually talks to the audio device or an audio mojo service.
-  return new media::NullAudioSink(GetMediaThreadTaskRunner());
+  // TODO(dalecurtis): Replace this with an interface to an actual mojo service;
+  // the AudioOutputStreamSink will not work in sandboxed processes.
+  return new media::AudioOutputStreamSink();
 }
 
 scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/mojo/services/html_viewer/webmediaplayer_factory.h b/mojo/services/html_viewer/webmediaplayer_factory.h
index db853703..a7050096 100644
--- a/mojo/services/html_viewer/webmediaplayer_factory.h
+++ b/mojo/services/html_viewer/webmediaplayer_factory.h
@@ -30,18 +30,23 @@
 
 namespace mojo {
 
+class Shell;
+
 // Helper class used to create blink::WebMediaPlayer objects.
 // This class stores the "global state" shared across all WebMediaPlayer
 // instances.
 class WebMediaPlayerFactory {
  public:
   explicit WebMediaPlayerFactory(const scoped_refptr<
-      base::SingleThreadTaskRunner>& compositor_task_runner);
+      base::SingleThreadTaskRunner>& compositor_task_runner,
+      bool enable_mojo_media_renderer);
   ~WebMediaPlayerFactory();
 
-  blink::WebMediaPlayer* CreateMediaPlayer(blink::WebLocalFrame* frame,
-                                           const blink::WebURL& url,
-                                           blink::WebMediaPlayerClient* client);
+  blink::WebMediaPlayer* CreateMediaPlayer(
+      blink::WebLocalFrame* frame,
+      const blink::WebURL& url,
+      blink::WebMediaPlayerClient* client,
+      Shell* shell);
 
  private:
   const media::AudioHardwareConfig& GetAudioHardwareConfig();
@@ -49,6 +54,7 @@
   scoped_refptr<base::SingleThreadTaskRunner> GetMediaThreadTaskRunner();
 
   scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
+  const bool enable_mojo_media_renderer_;
   base::Thread media_thread_;
   media::FakeAudioLogFactory fake_audio_log_factory_;
   scoped_ptr<media::AudioManager> audio_manager_;
diff --git a/mojo/services/native_viewport/platform_viewport_x11.cc b/mojo/services/native_viewport/platform_viewport_x11.cc
index b34928e..099b31c 100644
--- a/mojo/services/native_viewport/platform_viewport_x11.cc
+++ b/mojo/services/native_viewport/platform_viewport_x11.cc
@@ -24,14 +24,14 @@
   explicit PlatformViewportX11(Delegate* delegate) : delegate_(delegate) {
   }
 
-  virtual ~PlatformViewportX11() {
+  ~PlatformViewportX11() override {
     // Destroy the platform-window while |this| is still alive.
     platform_window_.reset();
   }
 
  private:
   // Overridden from PlatformViewport:
-  virtual void Init(const gfx::Rect& bounds) override {
+  void Init(const gfx::Rect& bounds) override {
     CHECK(!event_source_);
     CHECK(!platform_window_);
 
@@ -41,44 +41,31 @@
     platform_window_->SetBounds(bounds);
   }
 
-  virtual void Show() override {
-    platform_window_->Show();
-  }
+  void Show() override { platform_window_->Show(); }
 
-  virtual void Hide() override {
-    platform_window_->Hide();
-  }
+  void Hide() override { platform_window_->Hide(); }
 
-  virtual void Close() override {
-    platform_window_->Close();
-  }
+  void Close() override { platform_window_->Close(); }
 
-  virtual gfx::Size GetSize() override {
-    return bounds_.size();
-  }
+  gfx::Size GetSize() override { return bounds_.size(); }
 
-  virtual void SetBounds(const gfx::Rect& bounds) override {
+  void SetBounds(const gfx::Rect& bounds) override {
     platform_window_->SetBounds(bounds);
   }
 
-  virtual void SetCapture() override {
-    platform_window_->SetCapture();
-  }
+  void SetCapture() override { platform_window_->SetCapture(); }
 
-  virtual void ReleaseCapture() override {
-    platform_window_->ReleaseCapture();
-  }
+  void ReleaseCapture() override { platform_window_->ReleaseCapture(); }
 
   // ui::PlatformWindowDelegate:
-  virtual void OnBoundsChanged(const gfx::Rect& new_bounds) override {
+  void OnBoundsChanged(const gfx::Rect& new_bounds) override {
     bounds_ = new_bounds;
     delegate_->OnBoundsChanged(new_bounds);
   }
 
-  virtual void OnDamageRect(const gfx::Rect& damaged_region) override {
-  }
+  void OnDamageRect(const gfx::Rect& damaged_region) override {}
 
-  virtual void DispatchEvent(ui::Event* event) override {
+  void DispatchEvent(ui::Event* event) override {
     delegate_->OnEvent(event);
 
     // We want to emulate the WM_CHAR generation behaviour of Windows.
@@ -113,26 +100,19 @@
     }
   }
 
-  virtual void OnCloseRequest() override {
-    platform_window_->Close();
-  }
+  void OnCloseRequest() override { platform_window_->Close(); }
 
-  virtual void OnClosed() override {
-    delegate_->OnDestroyed();
-  }
+  void OnClosed() override { delegate_->OnDestroyed(); }
 
-  virtual void OnWindowStateChanged(ui::PlatformWindowState state) override {
-  }
+  void OnWindowStateChanged(ui::PlatformWindowState state) override {}
 
-  virtual void OnLostCapture() override {
-  }
+  void OnLostCapture() override {}
 
-  virtual void OnAcceleratedWidgetAvailable(
-      gfx::AcceleratedWidget widget) override {
+  void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override {
     delegate_->OnAcceleratedWidgetAvailable(widget);
   }
 
-  virtual void OnActivationChanged(bool active) override {}
+  void OnActivationChanged(bool active) override {}
 
   scoped_ptr<ui::PlatformEventSource> event_source_;
   scoped_ptr<ui::PlatformWindow> platform_window_;
diff --git a/mojo/services/public/cpp/network/BUILD.gn b/mojo/services/public/cpp/network/BUILD.gn
index 81e64b497..045c0b7 100644
--- a/mojo/services/public/cpp/network/BUILD.gn
+++ b/mojo/services/public/cpp/network/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# GYP version: mojo/mojo_services.gypi:mojo_network_utility
 source_set("network") {
   deps = [
     "//base",
@@ -10,9 +9,12 @@
     "//mojo/common",
     "//mojo/environment:chromium",
     "//mojo/public/c/system:for_component",
+    "//mojo/services/public/interfaces/network",
   ]
 
   sources = [
+    "udp_socket_wrapper.cc",
+    "udp_socket_wrapper.h",
     "web_socket_read_queue.cc",
     "web_socket_read_queue.h",
     "web_socket_write_queue.cc",
diff --git a/mojo/services/public/cpp/network/udp_socket_wrapper.cc b/mojo/services/public/cpp/network/udp_socket_wrapper.cc
new file mode 100644
index 0000000..f5a7564
--- /dev/null
+++ b/mojo/services/public/cpp/network/udp_socket_wrapper.cc
@@ -0,0 +1,214 @@
+// 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 "mojo/services/public/cpp/network/udp_socket_wrapper.h"
+
+#include <assert.h>
+
+#include "mojo/public/cpp/environment/logging.h"
+
+namespace mojo {
+namespace {
+
+const uint32_t kDefaultReceiveQueueSlots = 32;
+
+}  // namespace
+
+UDPSocketWrapper::NegotiateCallbackHandler::NegotiateCallbackHandler(
+    UDPSocketWrapper* delegate)
+    : delegate_(delegate) {
+}
+
+UDPSocketWrapper::NegotiateCallbackHandler::~NegotiateCallbackHandler() {
+}
+
+void UDPSocketWrapper::NegotiateCallbackHandler::Run(
+    uint32_t actual_size) const {
+  delegate_->OnNegotiateMaxPendingSendRequestsCompleted(actual_size);
+}
+
+UDPSocketWrapper::SendCallbackHandler::SendCallbackHandler(
+    UDPSocketWrapper* delegate,
+    const ErrorCallback& forward_callback)
+    : delegate_(delegate), forward_callback_(forward_callback) {
+}
+
+UDPSocketWrapper::SendCallbackHandler::~SendCallbackHandler() {
+}
+
+void UDPSocketWrapper::SendCallbackHandler::Run(NetworkErrorPtr result) const {
+  delegate_->OnSendToCompleted(result.Pass(), forward_callback_);
+}
+
+UDPSocketWrapper::ReceivedData::ReceivedData() {
+}
+UDPSocketWrapper::ReceivedData::~ReceivedData() {
+}
+
+UDPSocketWrapper::SendRequest::SendRequest() {
+}
+UDPSocketWrapper::SendRequest::~SendRequest() {
+}
+
+UDPSocketWrapper::UDPSocketWrapper(UDPSocketPtr socket)
+    : socket_(socket.Pass()),
+      max_receive_queue_size_(kDefaultReceiveQueueSlots),
+      max_pending_sends_(1),
+      current_pending_sends_(0) {
+  Initialize(0);
+}
+
+UDPSocketWrapper::UDPSocketWrapper(UDPSocketPtr socket,
+                                   uint32_t receive_queue_slots,
+                                   uint32_t requested_max_pending_sends)
+    : socket_(socket.Pass()),
+      max_receive_queue_size_(receive_queue_slots),
+      max_pending_sends_(1),
+      current_pending_sends_(0) {
+  Initialize(requested_max_pending_sends);
+}
+
+UDPSocketWrapper::~UDPSocketWrapper() {
+  while (!receive_queue_.empty()) {
+    delete receive_queue_.front();
+    receive_queue_.pop();
+  }
+  while (!send_requests_.empty()) {
+    delete send_requests_.front();
+    send_requests_.pop();
+  }
+}
+
+void UDPSocketWrapper::AllowAddressReuse(const ErrorCallback& callback) {
+  socket_->AllowAddressReuse(callback);
+}
+
+void UDPSocketWrapper::Bind(
+    NetAddressPtr addr,
+    const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback) {
+  socket_->Bind(addr.Pass(), callback);
+}
+
+void UDPSocketWrapper::SetSendBufferSize(uint32_t size,
+                                         const ErrorCallback& callback) {
+  socket_->SetSendBufferSize(size, callback);
+}
+
+void UDPSocketWrapper::SetReceiveBufferSize(uint32_t size,
+                                            const ErrorCallback& callback) {
+  socket_->SetReceiveBufferSize(size, callback);
+}
+
+bool UDPSocketWrapper::ReceiveFrom(const ReceiveCallback& callback) {
+  if (receive_queue_.empty()) {
+    receive_requests_.push(callback);
+    return false;
+  }
+
+  ReceivedData* data = receive_queue_.front();
+  receive_queue_.pop();
+  socket_->ReceiveMore(1);
+  callback.Run(data->result.Pass(), data->src_addr.Pass(), data->data.Pass());
+  delete data;
+  return true;
+}
+
+void UDPSocketWrapper::SendTo(NetAddressPtr dest_addr,
+                              Array<uint8_t> data,
+                              const ErrorCallback& callback) {
+  if (current_pending_sends_ >= max_pending_sends_) {
+    SendRequest* request = new SendRequest();
+    request->dest_addr = dest_addr.Pass();
+    request->data = data.Pass();
+    request->callback = callback;
+    send_requests_.push(request);
+    return;
+  }
+
+  MOJO_DCHECK(send_requests_.empty());
+  current_pending_sends_++;
+  socket_->SendTo(dest_addr.Pass(),
+                  data.Pass(),
+                  ErrorCallback(static_cast<typename ErrorCallback::Runnable*>(
+                      new SendCallbackHandler(this, callback))));
+}
+
+void UDPSocketWrapper::OnReceived(NetworkErrorPtr result,
+                                  NetAddressPtr src_addr,
+                                  Array<uint8_t> data) {
+  if (!receive_requests_.empty()) {
+    // The cache should be empty if there are user requests waiting for data.
+    MOJO_DCHECK(receive_queue_.empty());
+
+    socket_->ReceiveMore(1);
+
+    ReceiveCallback callback = receive_requests_.front();
+    receive_requests_.pop();
+
+    callback.Run(result.Pass(), src_addr.Pass(), data.Pass());
+    return;
+  }
+
+  MOJO_DCHECK(receive_queue_.size() < max_receive_queue_size_);
+  ReceivedData* received_data = new ReceivedData();
+  received_data->result = result.Pass();
+  received_data->src_addr = src_addr.Pass();
+  received_data->data = data.Pass();
+  receive_queue_.push(received_data);
+}
+
+void UDPSocketWrapper::Initialize(uint32_t requested_max_pending_sends) {
+  socket_.set_client(this);
+  socket_->NegotiateMaxPendingSendRequests(
+      requested_max_pending_sends,
+      Callback<void(uint32_t)>(
+          static_cast<typename Callback<void(uint32_t)>::Runnable*>(
+              new NegotiateCallbackHandler(this))));
+  socket_->ReceiveMore(max_receive_queue_size_);
+}
+
+void UDPSocketWrapper::OnNegotiateMaxPendingSendRequestsCompleted(
+    uint32_t actual_size) {
+  MOJO_DCHECK(max_pending_sends_ == 1);
+
+  if (actual_size == 0) {
+    assert(false);
+    return;
+  }
+
+  max_pending_sends_ = actual_size;
+
+  while (ProcessNextSendRequest())
+    ;
+}
+
+void UDPSocketWrapper::OnSendToCompleted(
+    NetworkErrorPtr result,
+    const ErrorCallback& forward_callback) {
+  current_pending_sends_--;
+  ProcessNextSendRequest();
+
+  forward_callback.Run(result.Pass());
+}
+
+bool UDPSocketWrapper::ProcessNextSendRequest() {
+  if (current_pending_sends_ >= max_pending_sends_ || send_requests_.empty())
+    return false;
+
+  SendRequest* request = send_requests_.front();
+  send_requests_.pop();
+
+  current_pending_sends_++;
+
+  socket_->SendTo(request->dest_addr.Pass(),
+                  request->data.Pass(),
+                  ErrorCallback(static_cast<typename ErrorCallback::Runnable*>(
+                      new SendCallbackHandler(this, request->callback))));
+
+  delete request;
+
+  return true;
+}
+
+}  // namespace mojo
diff --git a/mojo/services/public/cpp/network/udp_socket_wrapper.h b/mojo/services/public/cpp/network/udp_socket_wrapper.h
new file mode 100644
index 0000000..b2eda8d
--- /dev/null
+++ b/mojo/services/public/cpp/network/udp_socket_wrapper.h
@@ -0,0 +1,145 @@
+// 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 MOJO_SERVICES_PUBLIC_CPP_NETWORK_UDP_SOCKET_WRAPPER_H_
+#define MOJO_SERVICES_PUBLIC_CPP_NETWORK_UDP_SOCKET_WRAPPER_H_
+
+#include <queue>
+
+#include "mojo/services/public/interfaces/network/udp_socket.mojom.h"
+
+namespace mojo {
+
+// This class is a wrapper around the UDPSocket interface. It provides local
+// cache for received datagrams as well as for (excessive) send requests:
+// - You call ReceiveFrom() to retrieve one datagram. If there is already cached
+//   data, the operation completes synchronously.
+// - You don't need to worry about the max-pending-send-requests restriction
+//   imposed by the service side. If you make many SendTo() calls in a short
+//   period of time, it caches excessive requests and sends them later.
+class UDPSocketWrapper : public UDPSocketClient {
+ public:
+  typedef Callback<void(NetworkErrorPtr, NetAddressPtr, Array<uint8_t>)>
+      ReceiveCallback;
+  typedef Callback<void(NetworkErrorPtr)> ErrorCallback;
+
+  explicit UDPSocketWrapper(UDPSocketPtr socket);
+
+  // |receive_queue_slots| determines the size (in datagrams) of the local
+  // receive queue, which caches incoming datagrams.
+  // |requested_max_pending_sends| is used to call
+  // NegotiateMaxPendingSendRequests() on |socket|.
+  // The two numbers should be greater than 0. If you would like to use default
+  // values, please use the other constructor.
+  UDPSocketWrapper(UDPSocketPtr socket,
+                   uint32_t receive_queue_slots,
+                   uint32_t requested_max_pending_sends);
+
+  ~UDPSocketWrapper() override;
+
+  void AllowAddressReuse(const ErrorCallback& callback);
+
+  void Bind(NetAddressPtr addr,
+            const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback);
+
+  void SetSendBufferSize(uint32_t size, const ErrorCallback& callback);
+
+  void SetReceiveBufferSize(uint32_t size, const ErrorCallback& callback);
+
+  // If there are already incoming datagrams cached locally, this method runs
+  // |callback| before it returns, and the return value is set to true.
+  // Otherwise, the return value is set to false and the callback will be run
+  // asynchronously.
+  bool ReceiveFrom(const ReceiveCallback& callback);
+
+  // This method is aware of the max pending send requests allowed by the
+  // service, and caches send requests locally if necessary.
+  void SendTo(NetAddressPtr dest_addr,
+              Array<uint8_t> data,
+              const ErrorCallback& callback);
+
+ private:
+  class NegotiateCallbackHandler : public Callback<void(uint32_t)>::Runnable {
+   public:
+    explicit NegotiateCallbackHandler(UDPSocketWrapper* delegate);
+    ~NegotiateCallbackHandler() override;
+
+    // Callback<void(uint32_t)>::Runnable implementation:
+    void Run(uint32_t actual_size) const override;
+
+   private:
+    // Because this callback is passed to a method of |socket_|, and |socket_|
+    // is owned by |delegate_|, it should be safe to assume that |delegate_| is
+    // valid if/when Run() is called.
+    UDPSocketWrapper* delegate_;
+  };
+
+  class SendCallbackHandler : public ErrorCallback::Runnable {
+   public:
+    explicit SendCallbackHandler(UDPSocketWrapper* delegate,
+                                 const ErrorCallback& forward_callback);
+    ~SendCallbackHandler() override;
+
+    // ErrorCallback::Runnable implementation:
+    void Run(NetworkErrorPtr result) const override;
+
+   private:
+    // Because this callback is passed to a method of |socket_|, and |socket_|
+    // is owned by |delegate_|, it should be safe to assume that |delegate_| is
+    // valid if/when Run() is called.
+    UDPSocketWrapper* delegate_;
+    ErrorCallback forward_callback_;
+  };
+
+  struct ReceivedData {
+    ReceivedData();
+    ~ReceivedData();
+
+    NetworkErrorPtr result;
+    NetAddressPtr src_addr;
+    Array<uint8_t> data;
+  };
+
+  struct SendRequest {
+    SendRequest();
+    ~SendRequest();
+
+    NetAddressPtr dest_addr;
+    Array<uint8_t> data;
+    ErrorCallback callback;
+  };
+
+  // UDPSocketClient implementation:
+  void OnReceived(NetworkErrorPtr result,
+                  NetAddressPtr src_addr,
+                  Array<uint8_t> data) override;
+
+  void Initialize(uint32_t requested_max_pending_sends);
+  void OnNegotiateMaxPendingSendRequestsCompleted(uint32_t actual_size);
+
+  void OnSendToCompleted(NetworkErrorPtr result,
+                         const ErrorCallback& forward_callback);
+
+  // Returns true if a send request in |send_requests_| has been processed.
+  bool ProcessNextSendRequest();
+
+  UDPSocketPtr socket_;
+
+  uint32_t max_receive_queue_size_;
+
+  // Owns all the objects that its elements point to.
+  std::queue<ReceivedData*> receive_queue_;
+
+  std::queue<ReceiveCallback> receive_requests_;
+
+  uint32_t max_pending_sends_;
+  uint32_t current_pending_sends_;
+
+  // Owns all the objects that its elements point to.
+  std::queue<SendRequest*> send_requests_;
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_SERVICES_PUBLIC_CPP_NETWORK_UDP_SOCKET_WRAPPER_H_
diff --git a/mojo/services/public/cpp/view_manager/BUILD.gn b/mojo/services/public/cpp/view_manager/BUILD.gn
index a3e29dd5..1b38771 100644
--- a/mojo/services/public/cpp/view_manager/BUILD.gn
+++ b/mojo/services/public/cpp/view_manager/BUILD.gn
@@ -36,6 +36,7 @@
     "//mojo/services/public/interfaces/input_events:input_events",
     "//mojo/services/public/interfaces/surfaces:surface_id",
     "//mojo/services/public/interfaces/view_manager",
+    "//mojo/services/public/interfaces/window_manager",
     "//mojo/services/public/interfaces/window_manager2",
     "//ui/gfx/geometry",
   ]
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_client_factory.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_client_factory.cc
index 8b8ada1b..91bc26571 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_client_factory.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_client_factory.cc
@@ -18,6 +18,18 @@
 ViewManagerClientFactory::~ViewManagerClientFactory() {
 }
 
+// static
+scoped_ptr<ViewManagerClient>
+ViewManagerClientFactory::WeakBindViewManagerToPipe(
+    ScopedMessagePipeHandle handle,
+    Shell* shell,
+    ViewManagerDelegate* delegate) {
+  scoped_ptr<ViewManagerClientImpl> client(
+      new ViewManagerClientImpl(delegate, shell));
+  WeakBindToPipe(client.get(), handle.Pass());
+  return client.Pass();
+}
+
 // InterfaceFactory<ViewManagerClient> implementation.
 void ViewManagerClientFactory::Create(
     ApplicationConnection* connection,
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc
index 3818a36c..8004d29 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc
@@ -249,11 +249,15 @@
   roots_.push_back(root);
   root->AddObserver(new RootObserver(root));
 
-  // BindToRequest() binds the lifetime of |exported_services| to the pipe.
-  ServiceProviderImpl* exported_services = new ServiceProviderImpl;
-  BindToRequest(exported_services, &service_provider);
-  scoped_ptr<ServiceProvider> remote(
-      exported_services->CreateRemoteServiceProvider());
+  ServiceProviderImpl* exported_services = nullptr;
+  scoped_ptr<ServiceProvider> remote;
+
+  if (service_provider.is_pending()) {
+    // BindToRequest() binds the lifetime of |exported_services| to the pipe.
+    exported_services = new ServiceProviderImpl;
+    BindToRequest(exported_services, &service_provider);
+    remote.reset(exported_services->CreateRemoteServiceProvider());
+  }
   delegate_->OnEmbed(this, root, exported_services, remote.Pass());
 }
 
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_context.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_context.cc
index 5d00f3b..ff1b8eb0 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_context.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_context.cc
@@ -5,24 +5,23 @@
 #include "mojo/services/public/cpp/view_manager/view_manager_context.h"
 
 #include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h"
 
 namespace mojo {
 class ApplicationImpl;
 
-void ConnectCallback(bool success) {}
-
 class ViewManagerContext::InternalState {
  public:
-  InternalState(ApplicationImpl* application_impl) {
-    application_impl->ConnectToService("mojo:view_manager", &init_service_);
+  explicit InternalState(ApplicationImpl* application_impl) {
+    application_impl->ConnectToService("mojo:window_manager", &wm_);
   }
   ~InternalState() {}
 
-  ViewManagerInitService* init_service() { return init_service_.get(); }
+  WindowManager* wm() { return wm_.get(); }
 
  private:
-  ViewManagerInitServicePtr init_service_;
+  WindowManagerPtr wm_;
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(InternalState);
 };
@@ -47,7 +46,7 @@
     BindToProxy(registry, &sp);
     imported_services.reset(registry->CreateRemoteServiceProvider());
   }
-  state_->init_service()->Embed(url, sp.Pass(), base::Bind(&ConnectCallback));
+  state_->wm()->Embed(url, MakeRequest<ServiceProvider>(sp.PassMessagePipe()));
   return imported_services.Pass();
 }
 
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h b/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h
index 28d3c24..439fa1c 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_test_suite.h
@@ -12,10 +12,10 @@
 class ViewManagerTestSuite : public base::TestSuite {
  public:
   ViewManagerTestSuite(int argc, char** argv);
-  virtual ~ViewManagerTestSuite();
+  ~ViewManagerTestSuite() override;
 
  protected:
-  virtual void Initialize() override;
+  void Initialize() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ViewManagerTestSuite);
diff --git a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
index 3229b09..eafc3b9 100644
--- a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
+++ b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
@@ -299,7 +299,7 @@
 
  private:
   // Overridden from testing::Test:
-  virtual void SetUp() override {
+  void SetUp() override {
     ConnectApplicationLoader::LoadedCallback ready_callback = base::Bind(
         &ViewManagerTest::OnViewManagerLoaded, base::Unretained(this));
     test_helper_.Init();
@@ -312,27 +312,7 @@
             new ConnectApplicationLoader(ready_callback)),
         GURL(kEmbeddedApp1URL));
 
-    test_helper_.application_manager()->ConnectToService(
-        GURL("mojo:view_manager"), &view_manager_init_);
-    ASSERT_TRUE(EmbedRoot(view_manager_init_.get(), kWindowManagerURL));
-  }
-
-  void EmbedRootCallback(bool* result_cache, bool result) {
-    *result_cache = result;
-  }
-
-  bool EmbedRoot(ViewManagerInitService* view_manager_init,
-                 const std::string& url) {
-    bool result = false;
-    ServiceProviderPtr sp;
-    BindToProxy(new ServiceProviderImpl, &sp);
-    view_manager_init->Embed(
-        url, sp.Pass(),
-        base::Bind(&ViewManagerTest::EmbedRootCallback, base::Unretained(this),
-                   &result));
-    RunRunLoop();
-    window_manager_ = GetLoadedViewManager();
-    return result;
+    // TODO(sky): resolve this. Need to establish initial connection.
   }
 
   void OnViewManagerLoaded(ViewManager* view_manager, View* root) {
@@ -349,7 +329,6 @@
 
   base::RunLoop* connect_loop_;
   shell::ShellTestHelper test_helper_;
-  ViewManagerInitServicePtr view_manager_init_;
   // Used to receive the most recent view manager loaded by an embed action.
   ViewManager* loaded_view_manager_;
   // The View Manager connection held by the window manager (app running at the
diff --git a/mojo/services/public/cpp/view_manager/view_manager_client_factory.h b/mojo/services/public/cpp/view_manager/view_manager_client_factory.h
index c828900..70e5927 100644
--- a/mojo/services/public/cpp/view_manager/view_manager_client_factory.h
+++ b/mojo/services/public/cpp/view_manager/view_manager_client_factory.h
@@ -5,6 +5,7 @@
 #ifndef MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_MANAGER_CLIENT_FACTORY_H_
 #define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_MANAGER_CLIENT_FACTORY_H_
 
+#include "base/memory/scoped_ptr.h"
 #include "mojo/public/cpp/application/interface_factory.h"
 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
 
@@ -21,6 +22,12 @@
   ViewManagerClientFactory(Shell* shell, ViewManagerDelegate* delegate);
   ~ViewManagerClientFactory() override;
 
+  // Creates a ViewManagerClient from the supplied arguments.
+  static scoped_ptr<ViewManagerClient> WeakBindViewManagerToPipe(
+      ScopedMessagePipeHandle handle,
+      Shell* shell,
+      ViewManagerDelegate* delegate);
+
   // InterfaceFactory<ViewManagerClient> implementation.
   void Create(ApplicationConnection* connection,
               InterfaceRequest<ViewManagerClient> request) override;
diff --git a/mojo/services/public/cpp/view_manager/view_manager_delegate.h b/mojo/services/public/cpp/view_manager/view_manager_delegate.h
index bbb9867..9798e10 100644
--- a/mojo/services/public/cpp/view_manager/view_manager_delegate.h
+++ b/mojo/services/public/cpp/view_manager/view_manager_delegate.h
@@ -25,7 +25,7 @@
   // instance of |view_manager| only for every unique connection. See
   // the class description of ViewManager for some rules about when a new
   // connection is made.
-  // |exported_services| is an object that the delegate can add services to to
+  // |exported_services| is an object that the delegate can add services to
   // expose to the embedder. |imported_services| exposes the services offered by
   // the embedder to the delegate. Note that if a different application is
   // subsequently embedded at |root|, the pipe(s) connecting |imported_services|
diff --git a/mojo/services/public/interfaces/network/udp_socket.mojom b/mojo/services/public/interfaces/network/udp_socket.mojom
index 0816ace..f26cd09 100644
--- a/mojo/services/public/interfaces/network/udp_socket.mojom
+++ b/mojo/services/public/interfaces/network/udp_socket.mojom
@@ -54,7 +54,7 @@
   // Notifies that the client is ready to accept |number| of datagrams.
   // Correspondingly, OnReceived() of the UDPSocketClient interface will be
   // called |number| times (errors also count), unless the connection is closed
-  // before that. The socket must be bound.
+  // before that.
   //
   // It is allowed to call this method again before the previous request is
   // completely satisfied. For example:
diff --git a/mojo/services/public/interfaces/view_manager/view_manager.mojom b/mojo/services/public/interfaces/view_manager/view_manager.mojom
index bf8b82f..7019f150 100644
--- a/mojo/services/public/interfaces/view_manager/view_manager.mojom
+++ b/mojo/services/public/interfaces/view_manager/view_manager.mojom
@@ -28,21 +28,6 @@
   ILLEGAL_ARGUMENT,
 };
 
-// ViewManagerInitService is used to grant an application a connection to the
-// ViewManager by embedding it at an approriate View.
-interface ViewManagerInitService {
-  // Embed the application @ |url| at an appropriate View.
-  // The first time this method is called in the lifetime of a View Manager
-  // application instance, the "appropriate View" is defined as being the
-  // service root View.
-  // Subsequent times, implementation of this method is delegated to the
-  // application embedded at the service root View. This application is
-  // typically referred to as the "window manager", and will have a specific
-  // definition of where within its View hierarchy to embed an unparented URL.
-  // See ViewManagerService below for more details about |service_provider|.
-  Embed(string url, ServiceProvider? service_provider) => (bool success);
-};
-
 // Views are identified by a uint32. The upper 16 bits are the connection id,
 // and the lower 16 the id assigned by the client.
 //
@@ -124,10 +109,6 @@
   // children the children are removed. The one exception is the root
   // connection.
   //
-  // If |view_id| is 0, the View Manager delegates determination of what view to
-  // embed |url| at to the app embedded at the service root view (i.e. the
-  // window manager).
-  // 
   // |service_provider| encapsulates services offered by the embedder to the
   // embedded app alongside this Embed() call. It also provides a means for
   // the embedder to connect to services symmetrically exposed by the embedded
diff --git a/mojo/services/public/interfaces/window_manager/window_manager.mojom b/mojo/services/public/interfaces/window_manager/window_manager.mojom
index a0a4ed9..804bd37 100644
--- a/mojo/services/public/interfaces/window_manager/window_manager.mojom
+++ b/mojo/services/public/interfaces/window_manager/window_manager.mojom
@@ -7,26 +7,30 @@
 
 module mojo {
 
-// WindowManagerService provides high level window management policies.
-// WindowManagerService is used by the ViewManager. More specifically the first
-// connection from the ViewManager is expected to provide the
-// WindowManagerService.
-[Client=WindowManagerClient]
-interface WindowManagerService {
-  // Asks the WindowManager to embed |url| at the appropriate place. See
-  // ViewManager::Embed for details of |service_provider|.
+interface WindowManager {
+  // Requests the WindowManager to embed the app for |url| at an appropriate
+  // View. See ViewManger::Embed() for details on |service_provider|.
   Embed(string url, ServiceProvider&? service_provider);
+};
 
+// WindowManagerInternalService provides high level window management policies
+// and is used by the ViewManager. This interface is marked as internal as only
+// the view manager is allowed to connect to this.
+[Client=WindowManagerInternalClient]
+interface WindowManagerInternalService {
   // Called when an input event is received from the native system. It's
-  // expected that when this is received the WindowManagerService will call back
-  // to WindowManagerServieClient will call DispatchInputEventToView().
+  // expected that when this is received the WindowManagerInternalService will
+  // call back to WindowManagerInternalServieClient will call
+  // DispatchInputEventToView().
+  // TODO(sky): nuke this and instead have an interface specifically for
+  // dispatching events in the NativeViewportService.
   OnViewInputEvent(mojo.Event event);
 };
 
 // ViewManager provides this interface for functionality only exposed to the
-// WindowManagerServie.
-[Client=WindowManagerService]
-interface WindowManagerClient {
+// WindowManagerInternalServie.
+[Client=WindowManagerInternalService]
+interface WindowManagerInternalClient {
   // Dispatches the specified input event to the specified view.
   DispatchInputEventToView(uint32 view_id, mojo.Event event);
 };
diff --git a/mojo/services/public/mojo_services_public.gyp b/mojo/services/public/mojo_services_public.gyp
index e344b9f..5ea52219 100644
--- a/mojo/services/public/mojo_services_public.gyp
+++ b/mojo/services/public/mojo_services_public.gyp
@@ -13,7 +13,6 @@
       'dependencies': [
         'mojo_clipboard_bindings',
         'mojo_content_handler_bindings',
-        'mojo_core_window_manager_bindings',
         'mojo_geometry_bindings',
         'mojo_gpu_bindings',
         'mojo_input_events_bindings',
@@ -24,6 +23,7 @@
         'mojo_surfaces_bindings',
         'mojo_view_manager_bindings',
         'mojo_view_manager_common',
+        'mojo_window_manager_bindings',
       ],
     },
     {
@@ -263,7 +263,7 @@
     },
     {
       # GN version: //mojo/services/public/interfaces/window_manager2
-      'target_name': 'mojo_core_window_manager_bindings',
+      'target_name': 'mojo_window_manager2_bindings',
       'type': 'static_library',
       'sources': [
         'interfaces/window_manager2/window_manager2.mojom',
diff --git a/mojo/services/view_manager/BUILD.gn b/mojo/services/view_manager/BUILD.gn
deleted file mode 100644
index a870c3f6..0000000
--- a/mojo/services/view_manager/BUILD.gn
+++ /dev/null
@@ -1,102 +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.
-
-import("//build/config/ui.gni")
-
-# GYP version: mojo/mojo_services.gypi:mojo_view_manager
-shared_library("view_manager") {
-  output_name = "mojo_view_manager"
-
-  deps = [
-    "//base",
-    "//cc/surfaces",
-    "//mojo/application",
-    "//mojo/common",
-    "//mojo/converters/geometry",
-    "//mojo/converters/input_events",
-    "//mojo/converters/surfaces",
-    "//mojo/environment:chromium",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/public/cpp/bindings",
-    "//mojo/public/interfaces/application",
-    "//mojo/services/public/interfaces/geometry",
-    "//mojo/services/public/interfaces/input_events",
-    "//mojo/services/public/interfaces/native_viewport",
-    "//mojo/services/public/interfaces/surfaces",
-    "//mojo/services/public/interfaces/view_manager",
-    "//mojo/services/public/interfaces/window_manager",
-    "//ui/base",
-    "//ui/events",
-    "//ui/events:events_base",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-  ]
-
-  defines = [
-    "MOJO_VIEW_MANAGER_IMPLEMENTATION",
-  ]
-
-  sources = [
-    "access_policy.h",
-    "access_policy_delegate.h",
-    "connection_manager.cc",
-    "connection_manager.h",
-    "default_access_policy.cc",
-    "default_access_policy.h",
-    "display_manager.cc",
-    "display_manager.h",
-    "main.cc",
-    "server_view.cc",
-    "server_view.h",
-    "server_view_delegate.h",
-    "view_manager_export.h",
-    "view_manager_init_service_context.cc",
-    "view_manager_init_service_context.h",
-    "view_manager_init_service_impl.cc",
-    "view_manager_init_service_impl.h",
-    "view_manager_service_impl.cc",
-    "view_manager_service_impl.h",
-    "window_manager_access_policy.cc",
-    "window_manager_access_policy.h",
-    "window_manager_client_impl.cc",
-    "window_manager_client_impl.h",
-  ]
-}
-
-# GYP version: mojo/mojo_services.gypi:mojo_view_manager_unittests
-test("mojo_view_manager_unittests") {
-  deps = [
-    "//base",
-    "//base/test:test_support",
-    "//mojo/application",
-    "//mojo/application_manager",
-    "//mojo/converters/geometry",
-    "//mojo/converters/input_events",
-    "//mojo/edk/system",
-    "//mojo/environment:chromium",
-    "//mojo/public/cpp/bindings",
-    "//mojo/services/public/cpp/native_viewport:args",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/public/cpp/view_manager/lib:run_unittests",
-    "//mojo/services/public/interfaces/view_manager",
-    "//mojo/services/public/interfaces/window_manager",
-    "//mojo/shell:test_support",
-    "//testing/gtest",
-    "//ui/gfx/geometry",
-  ]
-
-  if (use_x11) {
-    deps += ["//ui/gfx/x"]
-  }
-
-  if (is_component_build) {
-    deps += ["//ui/gl"]
-  }
-
-  sources = [
-    "test_change_tracker.cc",
-    "test_change_tracker.h",
-    "view_manager_unittest.cc",
-  ]
-}
diff --git a/mojo/services/view_manager/DEPS b/mojo/services/view_manager/DEPS
deleted file mode 100644
index b9172b5..0000000
--- a/mojo/services/view_manager/DEPS
+++ /dev/null
@@ -1,26 +0,0 @@
-include_rules = [
-  "+cc",
-  "-cc/blink",
-  "+gpu/command_buffer/service/mailbox_manager.h",
-  "+mojo/application",
-  "+mojo/cc",
-  "+mojo/converters/geometry",
-  "+mojo/converters/input_events",
-  "+mojo/converters/surfaces",
-  "+mojo/geometry",
-  "+mojo/services",
-  "+third_party/skia",
-  "+ui/base/cursor/cursor.h",
-  "+ui/base/hit_test.h",
-  "+ui/compositor",
-  "+ui/events",
-  "+ui/gfx",
-  "+ui/gl",
-  "+webkit/common/gpu",
-]
-
-specific_include_rules = {
-  "view_manager_unittest.cc": [
-    "+mojo/application_manager/application_manager.h",
-  ],
-}
diff --git a/mojo/services/view_manager/access_policy.h b/mojo/services/view_manager/access_policy.h
deleted file mode 100644
index cac5579..0000000
--- a/mojo/services/view_manager/access_policy.h
+++ /dev/null
@@ -1,53 +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 MOJO_SERVICES_VIEW_MANAGER_ACCESS_POLICY_H_
-#define MOJO_SERVICES_VIEW_MANAGER_ACCESS_POLICY_H_
-
-#include "mojo/services/public/interfaces/view_manager/view_manager_constants.mojom.h"
-#include "mojo/services/view_manager/ids.h"
-
-namespace mojo {
-namespace service {
-
-class ServerView;
-
-// AccessPolicy is used by ViewManagerServiceImpl to determine what a connection
-// is allowed to do.
-class AccessPolicy {
- public:
-  virtual ~AccessPolicy() {}
-
-  // Unless otherwise mentioned all arguments have been validated. That is the
-  // |view| arguments are non-null unless otherwise stated (eg CanSetView() is
-  // allowed to take a NULL view).
-  virtual bool CanRemoveViewFromParent(const ServerView* view) const = 0;
-  virtual bool CanAddView(const ServerView* parent,
-                          const ServerView* child) const = 0;
-  virtual bool CanReorderView(const ServerView* view,
-                              const ServerView* relative_view,
-                              OrderDirection direction) const = 0;
-  virtual bool CanDeleteView(const ServerView* view) const = 0;
-  virtual bool CanGetViewTree(const ServerView* view) const = 0;
-  // Used when building a view tree (GetViewTree()) to decide if we should
-  // descend into |view|.
-  virtual bool CanDescendIntoViewForViewTree(const ServerView* view) const = 0;
-  virtual bool CanEmbed(const ServerView* view) const = 0;
-  virtual bool CanChangeViewVisibility(const ServerView* view) const = 0;
-  virtual bool CanSetViewSurfaceId(const ServerView* view) const = 0;
-  virtual bool CanSetViewBounds(const ServerView* view) const = 0;
-
-  // Returns whether the connection should notify on a hierarchy change.
-  // |new_parent| and |old_parent| are initially set to the new and old parents
-  // but may be altered so that the client only sees a certain set of views.
-  virtual bool ShouldNotifyOnHierarchyChange(
-      const ServerView* view,
-      const ServerView** new_parent,
-      const ServerView** old_parent) const = 0;
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_ACCESS_POLICY_H_
diff --git a/mojo/services/view_manager/access_policy_delegate.h b/mojo/services/view_manager/access_policy_delegate.h
deleted file mode 100644
index 12c74793..0000000
--- a/mojo/services/view_manager/access_policy_delegate.h
+++ /dev/null
@@ -1,39 +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 MOJO_SERVICES_VIEW_MANAGER_ACCESS_POLICY_DELEGATE_H_
-#define MOJO_SERVICES_VIEW_MANAGER_ACCESS_POLICY_DELEGATE_H_
-
-#include <vector>
-
-#include "base/containers/hash_tables.h"
-#include "mojo/services/view_manager/ids.h"
-
-namespace mojo {
-namespace service {
-
-class ServerView;
-
-// Delegate used by the AccessPolicy implementations to get state.
-class AccessPolicyDelegate {
- public:
-  // Returns the ids of the roots views for this connection. That is, this is
-  // the set of views the connection was embedded at.
-  virtual const base::hash_set<Id>& GetRootsForAccessPolicy() const = 0;
-
-  // Returns true if |view| has been exposed to the client.
-  virtual bool IsViewKnownForAccessPolicy(const ServerView* view) const = 0;
-
-  // Returns true if Embed(view) has been invoked on |view|.
-  virtual bool IsViewRootOfAnotherConnectionForAccessPolicy(
-      const ServerView* view) const = 0;
-
- protected:
-  virtual ~AccessPolicyDelegate() {}
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_ACCESS_POLICY_DELEGATE_H_
diff --git a/mojo/services/view_manager/connection_manager.cc b/mojo/services/view_manager/connection_manager.cc
deleted file mode 100644
index d610392..0000000
--- a/mojo/services/view_manager/connection_manager.cc
+++ /dev/null
@@ -1,301 +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 "mojo/services/view_manager/connection_manager.h"
-
-#include "base/logging.h"
-#include "mojo/converters/input_events/input_events_type_converters.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/interfaces/application/service_provider.mojom.h"
-#include "mojo/services/view_manager/view_manager_service_impl.h"
-
-namespace mojo {
-namespace service {
-
-ConnectionManager::ScopedChange::ScopedChange(
-    ViewManagerServiceImpl* connection,
-    ConnectionManager* connection_manager,
-    bool is_delete_view)
-    : connection_manager_(connection_manager),
-      connection_id_(connection->id()),
-      is_delete_view_(is_delete_view) {
-  connection_manager_->PrepareForChange(this);
-}
-
-ConnectionManager::ScopedChange::~ScopedChange() {
-  connection_manager_->FinishChange();
-}
-
-ConnectionManager::ConnectionManager(
-    ApplicationConnection* app_connection,
-    const Callback<void()>& native_viewport_closed_callback)
-    : app_connection_(app_connection),
-      wm_client_impl_(this),
-      next_connection_id_(1),
-      display_manager_(app_connection, this, native_viewport_closed_callback),
-      root_(new ServerView(this, RootViewId())),
-      current_change_(NULL) {
-  root_->SetBounds(gfx::Rect(800, 600));
-}
-
-ConnectionManager::~ConnectionManager() {
-  while (!connections_created_by_connect_.empty())
-    delete *(connections_created_by_connect_.begin());
-  // All the connections should have been destroyed.
-  DCHECK(connection_map_.empty());
-  root_.reset();
-}
-
-ConnectionSpecificId ConnectionManager::GetAndAdvanceNextConnectionId() {
-  const ConnectionSpecificId id = next_connection_id_++;
-  DCHECK_LT(id, next_connection_id_);
-  return id;
-}
-
-void ConnectionManager::AddConnection(ViewManagerServiceImpl* connection) {
-  DCHECK_EQ(0u, connection_map_.count(connection->id()));
-  connection_map_[connection->id()] = connection;
-}
-
-void ConnectionManager::RemoveConnection(ViewManagerServiceImpl* connection) {
-  connection_map_.erase(connection->id());
-  connections_created_by_connect_.erase(connection);
-
-  // Notify remaining connections so that they can cleanup.
-  for (ConnectionMap::const_iterator i = connection_map_.begin();
-       i != connection_map_.end();
-       ++i) {
-    i->second->OnViewManagerServiceImplDestroyed(connection->id());
-  }
-}
-
-void ConnectionManager::Embed(
-    const std::string& url,
-    InterfaceRequest<ServiceProvider> service_provider) {
-  if (connection_map_.empty()) {
-    // TODO(sky): this is unsafe and racy. Need a better way to determine the
-    // window manager.
-    EmbedImpl(kInvalidConnectionId,
-              String::From(url),
-              RootViewId(),
-              service_provider.Pass());
-    return;
-  }
-  wm_client_impl_.client()->Embed(url, service_provider.Pass());
-}
-
-void ConnectionManager::EmbedAtView(
-    ConnectionSpecificId creator_id,
-    const String& url,
-    Id transport_view_id,
-    InterfaceRequest<ServiceProvider> service_provider) {
-  EmbedImpl(creator_id,
-            url,
-            ViewIdFromTransportId(transport_view_id),
-            service_provider.Pass())->set_delete_on_connection_error();
-}
-
-ViewManagerServiceImpl* ConnectionManager::GetConnection(
-    ConnectionSpecificId connection_id) {
-  ConnectionMap::iterator i = connection_map_.find(connection_id);
-  return i == connection_map_.end() ? NULL : i->second;
-}
-
-ServerView* ConnectionManager::GetView(const ViewId& id) {
-  if (id == root_->id())
-    return root_.get();
-  ConnectionMap::iterator i = connection_map_.find(id.connection_id);
-  return i == connection_map_.end() ? NULL : i->second->GetView(id);
-}
-
-void ConnectionManager::OnConnectionMessagedClient(ConnectionSpecificId id) {
-  if (current_change_)
-    current_change_->MarkConnectionAsMessaged(id);
-}
-
-bool ConnectionManager::DidConnectionMessageClient(
-    ConnectionSpecificId id) const {
-  return current_change_ && current_change_->DidMessageConnection(id);
-}
-
-const ViewManagerServiceImpl* ConnectionManager::GetConnectionWithRoot(
-    const ViewId& id) const {
-  for (ConnectionMap::const_iterator i = connection_map_.begin();
-       i != connection_map_.end();
-       ++i) {
-    if (i->second->HasRoot(id))
-      return i->second;
-  }
-  return NULL;
-}
-
-void ConnectionManager::DispatchViewInputEventToDelegate(EventPtr event) {
-  if (wm_client_impl_.client())
-    wm_client_impl_.client()->OnViewInputEvent(event.Pass());
-}
-
-void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view,
-                                                 const gfx::Rect& old_bounds,
-                                                 const gfx::Rect& new_bounds) {
-  for (ConnectionMap::iterator i = connection_map_.begin();
-       i != connection_map_.end();
-       ++i) {
-    i->second->ProcessViewBoundsChanged(
-        view, old_bounds, new_bounds, IsChangeSource(i->first));
-  }
-}
-
-void ConnectionManager::ProcessWillChangeViewHierarchy(
-    const ServerView* view,
-    const ServerView* new_parent,
-    const ServerView* old_parent) {
-  for (ConnectionMap::iterator i = connection_map_.begin();
-       i != connection_map_.end();
-       ++i) {
-    i->second->ProcessWillChangeViewHierarchy(
-        view, new_parent, old_parent, IsChangeSource(i->first));
-  }
-}
-
-void ConnectionManager::ProcessViewHierarchyChanged(
-    const ServerView* view,
-    const ServerView* new_parent,
-    const ServerView* old_parent) {
-  for (ConnectionMap::iterator i = connection_map_.begin();
-       i != connection_map_.end();
-       ++i) {
-    i->second->ProcessViewHierarchyChanged(
-        view, new_parent, old_parent, IsChangeSource(i->first));
-  }
-}
-
-void ConnectionManager::ProcessViewReorder(const ServerView* view,
-                                           const ServerView* relative_view,
-                                           const OrderDirection direction) {
-  for (ConnectionMap::iterator i = connection_map_.begin();
-       i != connection_map_.end();
-       ++i) {
-    i->second->ProcessViewReorder(
-        view, relative_view, direction, IsChangeSource(i->first));
-  }
-}
-
-void ConnectionManager::ProcessViewDeleted(const ViewId& view) {
-  for (ConnectionMap::iterator i = connection_map_.begin();
-       i != connection_map_.end();
-       ++i) {
-    i->second->ProcessViewDeleted(view, IsChangeSource(i->first));
-  }
-}
-
-void ConnectionManager::PrepareForChange(ScopedChange* change) {
-  // Should only ever have one change in flight.
-  CHECK(!current_change_);
-  current_change_ = change;
-}
-
-void ConnectionManager::FinishChange() {
-  // PrepareForChange/FinishChange should be balanced.
-  CHECK(current_change_);
-  current_change_ = NULL;
-}
-
-ViewManagerServiceImpl* ConnectionManager::EmbedImpl(
-    const ConnectionSpecificId creator_id,
-    const String& url,
-    const ViewId& root_id,
-    InterfaceRequest<ServiceProvider> service_provider) {
-  MessagePipe pipe;
-
-  ServiceProvider* view_manager_service_provider =
-      app_connection_->ConnectToApplication(url)->GetServiceProvider();
-
-  view_manager_service_provider->ConnectToService(
-      ViewManagerServiceImpl::Client::Name_, pipe.handle1.Pass());
-
-  if (root_id == RootViewId()) {
-    MessagePipe wm_pipe;
-    view_manager_service_provider->ConnectToService(
-        WindowManagerClientImpl::Client::Name_, wm_pipe.handle1.Pass());
-    WeakBindToPipe(&wm_client_impl_, wm_pipe.handle0.Pass());
-  }
-
-  std::string creator_url;
-  ConnectionMap::const_iterator it = connection_map_.find(creator_id);
-  if (it != connection_map_.end())
-    creator_url = it->second->url();
-
-  ViewManagerServiceImpl* connection =
-      new ViewManagerServiceImpl(this,
-                                 creator_id,
-                                 creator_url,
-                                 url.To<std::string>(),
-                                 root_id,
-                                 service_provider.Pass());
-  WeakBindToPipe(connection, pipe.handle0.Pass());
-  connections_created_by_connect_.insert(connection);
-  OnConnectionMessagedClient(connection->id());
-  return connection;
-}
-
-void ConnectionManager::OnViewDestroyed(const ServerView* view) {
-  ProcessViewDeleted(view->id());
-}
-
-void ConnectionManager::OnWillChangeViewHierarchy(
-    const ServerView* view,
-    const ServerView* new_parent,
-    const ServerView* old_parent) {
-  if (!display_manager_.in_setup())
-    ProcessWillChangeViewHierarchy(view, new_parent, old_parent);
-}
-
-void ConnectionManager::OnViewHierarchyChanged(const ServerView* view,
-                                               const ServerView* new_parent,
-                                               const ServerView* old_parent) {
-  if (!display_manager_.in_setup())
-    ProcessViewHierarchyChanged(view, new_parent, old_parent);
-  // TODO(beng): optimize.
-  if (old_parent) {
-    display_manager_.SchedulePaint(old_parent,
-                                   gfx::Rect(old_parent->bounds().size()));
-  }
-  if (new_parent) {
-    display_manager_.SchedulePaint(new_parent,
-                                   gfx::Rect(new_parent->bounds().size()));
-  }
-}
-
-void ConnectionManager::OnViewBoundsChanged(const ServerView* view,
-                                            const gfx::Rect& old_bounds,
-                                            const gfx::Rect& new_bounds) {
-  ProcessViewBoundsChanged(view, old_bounds, new_bounds);
-  if (!view->parent())
-    return;
-
-  // TODO(sky): optimize this.
-  display_manager_.SchedulePaint(view->parent(), old_bounds);
-  display_manager_.SchedulePaint(view->parent(), new_bounds);
-}
-
-void ConnectionManager::OnViewSurfaceIdChanged(const ServerView* view) {
-  display_manager_.SchedulePaint(view, gfx::Rect(view->bounds().size()));
-}
-
-void ConnectionManager::OnViewReordered(const ServerView* view,
-                                        const ServerView* relative,
-                                        OrderDirection direction) {
-  display_manager_.SchedulePaint(view, gfx::Rect(view->bounds().size()));
-}
-
-void ConnectionManager::OnWillChangeViewVisibility(const ServerView* view) {
-  for (ConnectionMap::iterator i = connection_map_.begin();
-       i != connection_map_.end();
-       ++i) {
-    i->second->ProcessWillChangeViewVisibility(view, IsChangeSource(i->first));
-  }
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/connection_manager.h b/mojo/services/view_manager/connection_manager.h
deleted file mode 100644
index 1917439c..0000000
--- a/mojo/services/view_manager/connection_manager.h
+++ /dev/null
@@ -1,211 +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 MOJO_SERVICES_VIEW_MANAGER_CONNECTION_MANAGER_H_
-#define MOJO_SERVICES_VIEW_MANAGER_CONNECTION_MANAGER_H_
-
-#include <map>
-#include <set>
-
-#include "base/basictypes.h"
-#include "mojo/public/cpp/bindings/array.h"
-#include "mojo/services/view_manager/display_manager.h"
-#include "mojo/services/view_manager/ids.h"
-#include "mojo/services/view_manager/server_view.h"
-#include "mojo/services/view_manager/server_view_delegate.h"
-#include "mojo/services/view_manager/view_manager_export.h"
-#include "mojo/services/view_manager/window_manager_client_impl.h"
-
-namespace ui {
-class Event;
-}
-
-namespace mojo {
-
-class ApplicationConnection;
-
-namespace service {
-
-class ViewManagerServiceImpl;
-
-// ConnectionManager manages the set of connections to the ViewManager (all the
-// ViewManagerServiceImpls) as well as providing the root of the hierarchy.
-class MOJO_VIEW_MANAGER_EXPORT ConnectionManager : public ServerViewDelegate {
- public:
-  // Create when a ViewManagerServiceImpl is about to make a change. Ensures
-  // clients are notified correctly.
-  class ScopedChange {
-   public:
-    ScopedChange(ViewManagerServiceImpl* connection,
-                 ConnectionManager* connection_manager,
-                 bool is_delete_view);
-    ~ScopedChange();
-
-    ConnectionSpecificId connection_id() const { return connection_id_; }
-    bool is_delete_view() const { return is_delete_view_; }
-
-    // Marks the connection with the specified id as having seen a message.
-    void MarkConnectionAsMessaged(ConnectionSpecificId connection_id) {
-      message_ids_.insert(connection_id);
-    }
-
-    // Returns true if MarkConnectionAsMessaged(connection_id) was invoked.
-    bool DidMessageConnection(ConnectionSpecificId connection_id) const {
-      return message_ids_.count(connection_id) > 0;
-    }
-
-   private:
-    ConnectionManager* connection_manager_;
-    const ConnectionSpecificId connection_id_;
-    const bool is_delete_view_;
-
-    // See description of MarkConnectionAsMessaged/DidMessageConnection.
-    std::set<ConnectionSpecificId> message_ids_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedChange);
-  };
-
-  ConnectionManager(ApplicationConnection* app_connection,
-                    const Callback<void()>& native_viewport_closed_callback);
-  virtual ~ConnectionManager();
-
-  // Returns the id for the next ViewManagerServiceImpl.
-  ConnectionSpecificId GetAndAdvanceNextConnectionId();
-
-  void AddConnection(ViewManagerServiceImpl* connection);
-  void RemoveConnection(ViewManagerServiceImpl* connection);
-
-  // Used in two cases:
-  // . Establishes the client for the root.
-  // . Requests to Embed() at an unspecified view. For this case the request
-  //   is passed on to the WindowManagerService.
-  void Embed(const std::string& url,
-             InterfaceRequest<ServiceProvider> service_provider);
-
-  // See description of ViewManagerService::Embed() for details. This assumes
-  // |transport_view_id| is valid.
-  void EmbedAtView(ConnectionSpecificId creator_id,
-                   const String& url,
-                   Id transport_view_id,
-                   InterfaceRequest<ServiceProvider> service_provider);
-
-  // Returns the connection by id.
-  ViewManagerServiceImpl* GetConnection(ConnectionSpecificId connection_id);
-
-  // Returns the View identified by |id|.
-  ServerView* GetView(const ViewId& id);
-
-  ServerView* root() { return root_.get(); }
-
-  bool IsProcessingChange() const { return current_change_ != NULL; }
-
-  bool is_processing_delete_view() const {
-    return current_change_ && current_change_->is_delete_view();
-  }
-
-  // Invoked when a connection messages a client about the change. This is used
-  // to avoid sending ServerChangeIdAdvanced() unnecessarily.
-  void OnConnectionMessagedClient(ConnectionSpecificId id);
-
-  // Returns true if OnConnectionMessagedClient() was invoked for id.
-  bool DidConnectionMessageClient(ConnectionSpecificId id) const;
-
-  // Returns the ViewManagerServiceImpl that has |id| as a root.
-  ViewManagerServiceImpl* GetConnectionWithRoot(const ViewId& id) {
-    return const_cast<ViewManagerServiceImpl*>(
-        const_cast<const ConnectionManager*>(this)->GetConnectionWithRoot(id));
-  }
-  const ViewManagerServiceImpl* GetConnectionWithRoot(const ViewId& id) const;
-
-  void DispatchViewInputEventToDelegate(EventPtr event);
-
-  // These functions trivially delegate to all ViewManagerServiceImpls, which in
-  // term notify their clients.
-  void ProcessViewDestroyed(ServerView* view);
-  void ProcessViewBoundsChanged(const ServerView* view,
-                                const gfx::Rect& old_bounds,
-                                const gfx::Rect& new_bounds);
-  void ProcessWillChangeViewHierarchy(const ServerView* view,
-                                      const ServerView* new_parent,
-                                      const ServerView* old_parent);
-  void ProcessViewHierarchyChanged(const ServerView* view,
-                                   const ServerView* new_parent,
-                                   const ServerView* old_parent);
-  void ProcessViewReorder(const ServerView* view,
-                          const ServerView* relative_view,
-                          const OrderDirection direction);
-  void ProcessViewDeleted(const ViewId& view);
-
- private:
-  typedef std::map<ConnectionSpecificId, ViewManagerServiceImpl*> ConnectionMap;
-
-  // Invoked when a connection is about to make a change.  Subsequently followed
-  // by FinishChange() once the change is done.
-  //
-  // Changes should never nest, meaning each PrepareForChange() must be
-  // balanced with a call to FinishChange() with no PrepareForChange()
-  // in between.
-  void PrepareForChange(ScopedChange* change);
-
-  // Balances a call to PrepareForChange().
-  void FinishChange();
-
-  // Returns true if the specified connection originated the current change.
-  bool IsChangeSource(ConnectionSpecificId connection_id) const {
-    return current_change_ && current_change_->connection_id() == connection_id;
-  }
-
-  // Implementation of the two embed variants.
-  ViewManagerServiceImpl* EmbedImpl(
-      ConnectionSpecificId creator_id,
-      const String& url,
-      const ViewId& root_id,
-      InterfaceRequest<ServiceProvider> service_provider);
-
-  // Overridden from ServerViewDelegate:
-  virtual void OnViewDestroyed(const ServerView* view) override;
-  virtual void OnWillChangeViewHierarchy(const ServerView* view,
-                                         const ServerView* new_parent,
-                                         const ServerView* old_parent) override;
-  virtual void OnViewHierarchyChanged(const ServerView* view,
-                                      const ServerView* new_parent,
-                                      const ServerView* old_parent) override;
-  virtual void OnViewBoundsChanged(const ServerView* view,
-                                   const gfx::Rect& old_bounds,
-                                   const gfx::Rect& new_bounds) override;
-  virtual void OnViewSurfaceIdChanged(const ServerView* view) override;
-  virtual void OnViewReordered(const ServerView* view,
-                               const ServerView* relative,
-                               OrderDirection direction) override;
-  virtual void OnWillChangeViewVisibility(const ServerView* view) override;
-
-  ApplicationConnection* app_connection_;
-
-  WindowManagerClientImpl wm_client_impl_;
-
-  // ID to use for next ViewManagerServiceImpl.
-  ConnectionSpecificId next_connection_id_;
-
-  // Set of ViewManagerServiceImpls.
-  ConnectionMap connection_map_;
-
-  DisplayManager display_manager_;
-
-  scoped_ptr<ServerView> root_;
-
-  // Set of ViewManagerServiceImpls created by way of Connect(). These have to
-  // be explicitly destroyed.
-  std::set<ViewManagerServiceImpl*> connections_created_by_connect_;
-
-  // If non-null we're processing a change. The ScopedChange is not owned by us
-  // (it's created on the stack by ViewManagerServiceImpl).
-  ScopedChange* current_change_;
-
-  DISALLOW_COPY_AND_ASSIGN(ConnectionManager);
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_CONNECTION_MANAGER_H_
diff --git a/mojo/services/view_manager/default_access_policy.cc b/mojo/services/view_manager/default_access_policy.cc
deleted file mode 100644
index a2443c3..0000000
--- a/mojo/services/view_manager/default_access_policy.cc
+++ /dev/null
@@ -1,106 +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 "mojo/services/view_manager/default_access_policy.h"
-
-#include "mojo/services/view_manager/access_policy_delegate.h"
-#include "mojo/services/view_manager/server_view.h"
-
-namespace mojo {
-namespace service {
-
-DefaultAccessPolicy::DefaultAccessPolicy(ConnectionSpecificId connection_id,
-                                         AccessPolicyDelegate* delegate)
-    : connection_id_(connection_id),
-      delegate_(delegate) {
-}
-
-DefaultAccessPolicy::~DefaultAccessPolicy() {
-}
-
-bool DefaultAccessPolicy::CanRemoveViewFromParent(
-    const ServerView* view) const {
-  if (!WasCreatedByThisConnection(view))
-    return false;  // Can only unparent views we created.
-
-  return IsViewInRoots(view->parent()) ||
-         WasCreatedByThisConnection(view->parent());
-}
-
-bool DefaultAccessPolicy::CanAddView(const ServerView* parent,
-                                     const ServerView* child) const {
-  return WasCreatedByThisConnection(child) &&
-         (IsViewInRoots(parent) ||
-          (WasCreatedByThisConnection(parent) &&
-           !delegate_->IsViewRootOfAnotherConnectionForAccessPolicy(parent)));
-}
-
-bool DefaultAccessPolicy::CanReorderView(const ServerView* view,
-                                         const ServerView* relative_view,
-                                         OrderDirection direction) const {
-  return WasCreatedByThisConnection(view) &&
-         WasCreatedByThisConnection(relative_view);
-}
-
-bool DefaultAccessPolicy::CanDeleteView(const ServerView* view) const {
-  return WasCreatedByThisConnection(view);
-}
-
-bool DefaultAccessPolicy::CanGetViewTree(const ServerView* view) const {
-  return WasCreatedByThisConnection(view) || IsViewInRoots(view);
-}
-
-bool DefaultAccessPolicy::CanDescendIntoViewForViewTree(
-    const ServerView* view) const {
-  return WasCreatedByThisConnection(view) &&
-         !delegate_->IsViewRootOfAnotherConnectionForAccessPolicy(view);
-}
-
-bool DefaultAccessPolicy::CanEmbed(const ServerView* view) const {
-  return WasCreatedByThisConnection(view);
-}
-
-bool DefaultAccessPolicy::CanChangeViewVisibility(
-    const ServerView* view) const {
-  return WasCreatedByThisConnection(view) || IsViewInRoots(view);
-}
-
-bool DefaultAccessPolicy::CanSetViewSurfaceId(const ServerView* view) const {
-  // Once a view embeds another app, the embedder app is no longer able to
-  // call SetViewSurfaceId() - this ability is transferred to the embedded app.
-  if (delegate_->IsViewRootOfAnotherConnectionForAccessPolicy(view))
-    return false;
-  return WasCreatedByThisConnection(view) || IsViewInRoots(view);
-}
-
-bool DefaultAccessPolicy::CanSetViewBounds(const ServerView* view) const {
-  return WasCreatedByThisConnection(view);
-}
-
-bool DefaultAccessPolicy::ShouldNotifyOnHierarchyChange(
-    const ServerView* view,
-    const ServerView** new_parent,
-    const ServerView** old_parent) const {
-  if (!WasCreatedByThisConnection(view))
-    return false;
-
-  if (*new_parent && !WasCreatedByThisConnection(*new_parent) &&
-      !IsViewInRoots(*new_parent)) {
-    *new_parent = NULL;
-  }
-
-  if (*old_parent && !WasCreatedByThisConnection(*old_parent) &&
-      !IsViewInRoots(*old_parent)) {
-    *old_parent = NULL;
-  }
-  return true;
-}
-
-bool DefaultAccessPolicy::IsViewInRoots(const ServerView* view) const {
-  return delegate_->GetRootsForAccessPolicy().count(
-             ViewIdToTransportId(view->id())) > 0;
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/default_access_policy.h b/mojo/services/view_manager/default_access_policy.h
deleted file mode 100644
index d8c0194..0000000
--- a/mojo/services/view_manager/default_access_policy.h
+++ /dev/null
@@ -1,60 +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 MOJO_SERVICES_VIEW_MANAGER_DEFAULT_ACCESS_POLICY_H_
-#define MOJO_SERVICES_VIEW_MANAGER_DEFAULT_ACCESS_POLICY_H_
-
-#include "base/basictypes.h"
-#include "mojo/services/view_manager/access_policy.h"
-
-namespace mojo {
-namespace service {
-
-class AccessPolicyDelegate;
-
-// AccessPolicy for all connections, except the window manager.
-class DefaultAccessPolicy : public AccessPolicy {
- public:
-  DefaultAccessPolicy(ConnectionSpecificId connection_id,
-                      AccessPolicyDelegate* delegate);
-  virtual ~DefaultAccessPolicy();
-
-  // AccessPolicy:
-  virtual bool CanRemoveViewFromParent(const ServerView* view) const override;
-  virtual bool CanAddView(const ServerView* parent,
-                          const ServerView* child) const override;
-  virtual bool CanReorderView(const ServerView* view,
-                              const ServerView* relative_view,
-                              OrderDirection direction) const override;
-  virtual bool CanDeleteView(const ServerView* view) const override;
-  virtual bool CanGetViewTree(const ServerView* view) const override;
-  virtual bool CanDescendIntoViewForViewTree(
-      const ServerView* view) const override;
-  virtual bool CanEmbed(const ServerView* view) const override;
-  virtual bool CanChangeViewVisibility(const ServerView* view) const override;
-  virtual bool CanSetViewSurfaceId(const ServerView* view) const override;
-  virtual bool CanSetViewBounds(const ServerView* view) const override;
-  virtual bool ShouldNotifyOnHierarchyChange(
-      const ServerView* view,
-      const ServerView** new_parent,
-      const ServerView** old_parent) const override;
-
- private:
-  bool IsViewInRoots(const ServerView* view) const;
-
-  template <typename T>
-  bool WasCreatedByThisConnection(const T* t) const {
-    return t->id().connection_id == connection_id_;
-  }
-
-  const ConnectionSpecificId connection_id_;
-  AccessPolicyDelegate* delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(DefaultAccessPolicy);
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_DEFAULT_ACCESS_POLICY_H_
diff --git a/mojo/services/view_manager/display_manager.cc b/mojo/services/view_manager/display_manager.cc
deleted file mode 100644
index 5488177..0000000
--- a/mojo/services/view_manager/display_manager.cc
+++ /dev/null
@@ -1,171 +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 "mojo/services/view_manager/display_manager.h"
-
-#include "base/numerics/safe_conversions.h"
-#include "cc/surfaces/surface_id_allocator.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/converters/surfaces/surfaces_type_converters.h"
-#include "mojo/converters/surfaces/surfaces_utils.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/services/public/interfaces/gpu/gpu.mojom.h"
-#include "mojo/services/public/interfaces/surfaces/quads.mojom.h"
-#include "mojo/services/view_manager/connection_manager.h"
-
-namespace mojo {
-namespace service {
-namespace {
-
-gfx::Rect ConvertRectToRoot(const ServerView* view, const gfx::Rect& bounds) {
-  gfx::Point origin(bounds.origin());
-  while (view->parent()) {
-    origin += view->bounds().OffsetFromOrigin();
-    view = view->parent();
-    if (!view->visible())
-      return gfx::Rect();
-  }
-  return gfx::Rect(origin, bounds.size());
-}
-
-void DrawViewTree(Pass* pass, const ServerView* view, gfx::Vector2d offset) {
-  if (!view->visible())
-    return;
-
-  gfx::Rect node_bounds = view->bounds() + offset;
-  std::vector<const ServerView*> children(view->GetChildren());
-  for (std::vector<const ServerView*>::reverse_iterator it = children.rbegin();
-       it != children.rend();
-       ++it) {
-    DrawViewTree(pass, *it, offset + view->bounds().OffsetFromOrigin());
-  }
-
-  cc::SurfaceId node_id = view->surface_id();
-
-  SurfaceQuadStatePtr surface_quad_state = SurfaceQuadState::New();
-  surface_quad_state->surface = SurfaceId::From(node_id);
-
-  gfx::Transform node_transform;
-  node_transform.Translate(node_bounds.x(), node_bounds.y());
-
-  QuadPtr surface_quad = Quad::New();
-  surface_quad->material = Material::MATERIAL_SURFACE_CONTENT;
-  surface_quad->rect = Rect::From(node_bounds);
-  surface_quad->opaque_rect = Rect::From(node_bounds);
-  surface_quad->visible_rect = Rect::From(node_bounds);
-  surface_quad->needs_blending = true;
-  surface_quad->shared_quad_state_index =
-      base::saturated_cast<int32_t>(pass->shared_quad_states.size());
-  surface_quad->surface_quad_state = surface_quad_state.Pass();
-
-  SharedQuadStatePtr sqs = CreateDefaultSQS(node_bounds.size());
-  sqs->content_to_target_transform = Transform::From(node_transform);
-
-  pass->quads.push_back(surface_quad.Pass());
-  pass->shared_quad_states.push_back(sqs.Pass());
-}
-
-}  // namespace
-
-DisplayManager::DisplayManager(
-    ApplicationConnection* app_connection,
-    ConnectionManager* connection_manager,
-    const Callback<void()>& native_viewport_closed_callback)
-    : connection_manager_(connection_manager),
-      in_setup_(false),
-      size_(800, 600),
-      draw_timer_(false, false),
-      weak_factory_(this) {
-  app_connection->ConnectToService("mojo:native_viewport_service",
-                                   &native_viewport_);
-  native_viewport_.set_client(this);
-  native_viewport_->Create(
-      Size::From(size_),
-      base::Bind(&DisplayManager::OnCreatedNativeViewport,
-                 weak_factory_.GetWeakPtr()));
-  native_viewport_->Show();
-  app_connection->ConnectToService("mojo:surfaces_service", &surfaces_service_);
-  surfaces_service_->CreateSurfaceConnection(base::Bind(
-      &DisplayManager::OnSurfaceConnectionCreated, weak_factory_.GetWeakPtr()));
-}
-
-DisplayManager::~DisplayManager() {
-}
-
-void DisplayManager::SchedulePaint(const ServerView* view,
-                                   const gfx::Rect& bounds) {
-  if (!view->visible())
-    return;
-  gfx::Rect root_relative_rect = ConvertRectToRoot(view, bounds);
-  if (root_relative_rect.IsEmpty())
-    return;
-  dirty_rect_.Union(root_relative_rect);
-  if (!draw_timer_.IsRunning()) {
-    draw_timer_.Start(
-        FROM_HERE,
-        base::TimeDelta(),
-        base::Bind(&DisplayManager::Draw, base::Unretained(this)));
-  }
-}
-
-void DisplayManager::OnCreatedNativeViewport(uint64_t native_viewport_id) {
-}
-
-void DisplayManager::OnSurfaceConnectionCreated(SurfacePtr surface,
-                                                uint32_t id_namespace) {
-  surface_ = surface.Pass();
-  surface_.set_client(this);
-  surface_id_allocator_.reset(new cc::SurfaceIdAllocator(id_namespace));
-  Draw();
-}
-
-void DisplayManager::Draw() {
-  if (!surface_)
-    return;
-  if (surface_id_.is_null()) {
-    surface_id_ = surface_id_allocator_->GenerateId();
-    surface_->CreateSurface(SurfaceId::From(surface_id_), Size::From(size_));
-  }
-
-  PassPtr pass = CreateDefaultPass(1, gfx::Rect(size_));
-  pass->damage_rect = Rect::From(dirty_rect_);
-
-  DrawViewTree(pass.get(), connection_manager_->root(), gfx::Vector2d());
-
-  FramePtr frame = Frame::New();
-  frame->passes.push_back(pass.Pass());
-  frame->resources.resize(0u);
-  surface_->SubmitFrame(SurfaceId::From(surface_id_), frame.Pass());
-
-  native_viewport_->SubmittedFrame(SurfaceId::From(surface_id_));
-
-  dirty_rect_ = gfx::Rect();
-}
-
-void DisplayManager::OnDestroyed() {
-  native_viewport_closed_callback_.Run();
-}
-
-void DisplayManager::OnSizeChanged(SizePtr size) {
-  size_ = size.To<gfx::Size>();
-  connection_manager_->root()->SetBounds(gfx::Rect(size_));
-  if (surface_id_.is_null())
-    return;
-  surface_->DestroySurface(SurfaceId::From(surface_id_));
-  surface_id_ = cc::SurfaceId();
-  SchedulePaint(connection_manager_->root(), gfx::Rect(size_));
-}
-
-void DisplayManager::OnEvent(EventPtr event,
-                             const mojo::Callback<void()>& callback) {
-  connection_manager_->DispatchViewInputEventToDelegate(event.Pass());
-  callback.Run();
-}
-
-void DisplayManager::ReturnResources(Array<ReturnedResourcePtr> resources) {
-  DCHECK_EQ(0u, resources.size());
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/display_manager.h b/mojo/services/view_manager/display_manager.h
deleted file mode 100644
index 8b95a57..0000000
--- a/mojo/services/view_manager/display_manager.h
+++ /dev/null
@@ -1,88 +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 MOJO_SERVICES_VIEW_MANAGER_DISPLAY_MANAGER_H_
-#define MOJO_SERVICES_VIEW_MANAGER_DISPLAY_MANAGER_H_
-
-#include <map>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
-#include "cc/surfaces/surface_id.h"
-#include "mojo/public/cpp/bindings/callback.h"
-#include "mojo/services/public/interfaces/native_viewport/native_viewport.mojom.h"
-#include "mojo/services/public/interfaces/surfaces/surfaces.mojom.h"
-#include "mojo/services/public/interfaces/surfaces/surfaces_service.mojom.h"
-#include "mojo/services/view_manager/view_manager_export.h"
-#include "ui/gfx/rect.h"
-
-namespace cc {
-class SurfaceIdAllocator;
-}
-
-namespace mojo {
-
-class ApplicationConnection;
-
-namespace service {
-
-class ConnectionManager;
-class ServerView;
-
-// DisplayManager binds the root node to an actual display.
-class MOJO_VIEW_MANAGER_EXPORT DisplayManager
-    : NON_EXPORTED_BASE(public NativeViewportClient),
-      NON_EXPORTED_BASE(public SurfaceClient) {
- public:
-  DisplayManager(ApplicationConnection* app_connection,
-                 ConnectionManager* connection_manager,
-                 const Callback<void()>& native_viewport_closed_callback);
-  virtual ~DisplayManager();
-
-  // Schedules a paint for the specified region of the specified view.
-  void SchedulePaint(const ServerView* view, const gfx::Rect& bounds);
-
-  // See description above field for details.
-  bool in_setup() const { return in_setup_; }
-
- private:
-  void OnCreatedNativeViewport(uint64_t native_viewport_id);
-  void OnSurfaceConnectionCreated(SurfacePtr surface, uint32_t id_namespace);
-  void Draw();
-
-  // NativeViewportClient implementation.
-  virtual void OnDestroyed() override;
-  virtual void OnSizeChanged(SizePtr size) override;
-  virtual void OnEvent(EventPtr event,
-                       const mojo::Callback<void()>& callback) override;
-
-  // SurfaceClient implementation.
-  virtual void ReturnResources(Array<ReturnedResourcePtr> resources) override;
-
-  ConnectionManager* connection_manager_;
-
-  // Returns true if adding the root view's window to |window_tree_host_|.
-  bool in_setup_;
-
-  gfx::Size size_;
-  gfx::Rect dirty_rect_;
-  base::Timer draw_timer_;
-
-  SurfacesServicePtr surfaces_service_;
-  SurfacePtr surface_;
-  scoped_ptr<cc::SurfaceIdAllocator> surface_id_allocator_;
-  cc::SurfaceId surface_id_;
-  NativeViewportPtr native_viewport_;
-  Callback<void()> native_viewport_closed_callback_;
-  base::WeakPtrFactory<DisplayManager> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(DisplayManager);
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_DISPLAY_MANAGER_H_
diff --git a/mojo/services/view_manager/ids.h b/mojo/services/view_manager/ids.h
deleted file mode 100644
index 0d1c486..0000000
--- a/mojo/services/view_manager/ids.h
+++ /dev/null
@@ -1,63 +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 MOJO_SERVICES_VIEW_MANAGER_IDS_H_
-#define MOJO_SERVICES_VIEW_MANAGER_IDS_H_
-
-#include "mojo/services/public/cpp/view_manager/types.h"
-#include "mojo/services/public/cpp/view_manager/util.h"
-
-namespace mojo {
-namespace service {
-
-// Connection id is used to indicate no connection. That is, no
-// ViewManagerServiceImpl ever gets this id.
-const ConnectionSpecificId kInvalidConnectionId = 0;
-
-// TODO(sky): remove this, temporary while window manager API is in existing
-// api.
-const ConnectionSpecificId kWindowManagerConnection = 1;
-
-// Adds a bit of type safety to view ids.
-struct ViewId {
-  ViewId(ConnectionSpecificId connection_id, ConnectionSpecificId view_id)
-      : connection_id(connection_id),
-        view_id(view_id) {}
-  ViewId() : connection_id(0), view_id(0) {}
-
-  bool operator==(const ViewId& other) const {
-    return other.connection_id == connection_id &&
-        other.view_id == view_id;
-  }
-
-  bool operator!=(const ViewId& other) const {
-    return !(*this == other);
-  }
-
-  ConnectionSpecificId connection_id;
-  ConnectionSpecificId view_id;
-};
-
-inline ViewId ViewIdFromTransportId(Id id) {
-  return ViewId(HiWord(id), LoWord(id));
-}
-
-inline Id ViewIdToTransportId(const ViewId& id) {
-  return (id.connection_id << 16) | id.view_id;
-}
-
-inline ViewId RootViewId() {
-  return ViewId(kInvalidConnectionId, 1);
-}
-
-// Returns a ViewId that is reserved to indicate no view. That is, no view will
-// ever be created with this id.
-inline ViewId InvalidViewId() {
-  return ViewId(kInvalidConnectionId, 0);
-}
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_IDS_H_
diff --git a/mojo/services/view_manager/main.cc b/mojo/services/view_manager/main.cc
deleted file mode 100644
index cd14dc0..0000000
--- a/mojo/services/view_manager/main.cc
+++ /dev/null
@@ -1,49 +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 "mojo/application/application_runner_chromium.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/services/view_manager/view_manager_init_service_context.h"
-#include "mojo/services/view_manager/view_manager_init_service_impl.h"
-
-namespace mojo {
-namespace service {
-
-class ViewManagerApp : public ApplicationDelegate,
-                       public InterfaceFactory<ViewManagerInitService> {
- public:
-  ViewManagerApp() {}
-  virtual ~ViewManagerApp() {}
-
-  virtual bool ConfigureIncomingConnection(
-      ApplicationConnection* connection) override {
-    context_.ConfigureIncomingConnection(connection);
-    // TODO(sky): this needs some sort of authentication as well as making sure
-    // we only ever have one active at a time.
-    connection->AddService(this);
-    return true;
-  }
-
-  virtual void Create(
-      ApplicationConnection* connection,
-      InterfaceRequest<ViewManagerInitService> request) override {
-    BindToRequest(new ViewManagerInitServiceImpl(connection, &context_),
-                  &request);
-  }
-
- private:
-  ViewManagerInitServiceContext context_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerApp);
-};
-
-}  // namespace service
-}  // namespace mojo
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new mojo::service::ViewManagerApp);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/services/view_manager/server_view.cc b/mojo/services/view_manager/server_view.cc
deleted file mode 100644
index 8f5a559..0000000
--- a/mojo/services/view_manager/server_view.cc
+++ /dev/null
@@ -1,144 +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 "mojo/services/view_manager/server_view.h"
-
-#include "mojo/services/view_manager/server_view_delegate.h"
-
-namespace mojo {
-namespace service {
-
-ServerView::ServerView(ServerViewDelegate* delegate, const ViewId& id)
-    : delegate_(delegate), id_(id), parent_(NULL), visible_(true) {
-  DCHECK(delegate);  // Must provide a delegate.
-}
-
-ServerView::~ServerView() {
-  while (!children_.empty())
-    children_.front()->parent()->Remove(children_.front());
-
-  if (parent_)
-    parent_->Remove(this);
-
-  delegate_->OnViewDestroyed(this);
-}
-
-void ServerView::Add(ServerView* child) {
-  // We assume validation checks happened already.
-  DCHECK(child);
-  DCHECK(child != this);
-  DCHECK(!child->Contains(this));
-  if (child->parent() == this) {
-    if (children_.size() == 1)
-      return;  // Already in the right position.
-    Reorder(child, children_.back(), ORDER_DIRECTION_ABOVE);
-    return;
-  }
-
-  const ServerView* old_parent = child->parent();
-  child->delegate_->OnWillChangeViewHierarchy(child, this, old_parent);
-  if (child->parent())
-    child->parent()->RemoveImpl(child);
-
-  child->parent_ = this;
-  children_.push_back(child);
-  child->delegate_->OnViewHierarchyChanged(child, this, old_parent);
-}
-
-void ServerView::Remove(ServerView* child) {
-  // We assume validation checks happened else where.
-  DCHECK(child);
-  DCHECK(child != this);
-  DCHECK(child->parent() == this);
-
-  child->delegate_->OnWillChangeViewHierarchy(child, NULL, this);
-  RemoveImpl(child);
-  child->delegate_->OnViewHierarchyChanged(child, NULL, this);
-}
-
-void ServerView::Reorder(ServerView* child,
-                         ServerView* relative,
-                         OrderDirection direction) {
-  // We assume validation checks happened else where.
-  DCHECK(child);
-  DCHECK(child->parent() == this);
-  DCHECK_GT(children_.size(), 1u);
-  children_.erase(std::find(children_.begin(), children_.end(), child));
-  Views::iterator i = std::find(children_.begin(), children_.end(), relative);
-  if (direction == ORDER_DIRECTION_ABOVE) {
-    DCHECK(i != children_.end());
-    children_.insert(++i, child);
-  } else if (direction == ORDER_DIRECTION_BELOW) {
-    DCHECK(i != children_.end());
-    children_.insert(i, child);
-  }
-  delegate_->OnViewReordered(this, relative, direction);
-}
-
-void ServerView::SetBounds(const gfx::Rect& bounds) {
-  if (bounds_ == bounds)
-    return;
-
-  const gfx::Rect old_bounds = bounds_;
-  bounds_ = bounds;
-  delegate_->OnViewBoundsChanged(this, old_bounds, bounds);
-}
-
-const ServerView* ServerView::GetRoot() const {
-  const ServerView* view = this;
-  while (view && view->parent())
-    view = view->parent();
-  return view;
-}
-
-std::vector<const ServerView*> ServerView::GetChildren() const {
-  std::vector<const ServerView*> children;
-  children.reserve(children_.size());
-  for (size_t i = 0; i < children_.size(); ++i)
-    children.push_back(children_[i]);
-  return children;
-}
-
-std::vector<ServerView*> ServerView::GetChildren() {
-  // TODO(sky): rename to children() and fix return type.
-  return children_;
-}
-
-bool ServerView::Contains(const ServerView* view) const {
-  for (const ServerView* parent = view; parent; parent = parent->parent_) {
-    if (parent == this)
-      return true;
-  }
-  return false;
-}
-
-void ServerView::SetVisible(bool value) {
-  if (visible_ == value)
-    return;
-
-  delegate_->OnWillChangeViewVisibility(this);
-  visible_ = value;
-}
-
-bool ServerView::IsDrawn(const ServerView* root) const {
-  if (!root->visible_)
-    return false;
-  const ServerView* view = this;
-  while (view && view != root && view->visible_)
-    view = view->parent_;
-  return view == root;
-}
-
-void ServerView::SetSurfaceId(cc::SurfaceId surface_id) {
-  surface_id_ = surface_id;
-  delegate_->OnViewSurfaceIdChanged(this);
-}
-
-void ServerView::RemoveImpl(ServerView* view) {
-  view->parent_ = NULL;
-  children_.erase(std::find(children_.begin(), children_.end(), view));
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/server_view.h b/mojo/services/view_manager/server_view.h
deleted file mode 100644
index af7b37d..0000000
--- a/mojo/services/view_manager/server_view.h
+++ /dev/null
@@ -1,91 +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 MOJO_SERVICES_VIEW_MANAGER_SERVER_VIEW_H_
-#define MOJO_SERVICES_VIEW_MANAGER_SERVER_VIEW_H_
-
-#include <vector>
-
-#include "base/logging.h"
-#include "cc/surfaces/surface_id.h"
-#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
-#include "mojo/services/view_manager/ids.h"
-#include "mojo/services/view_manager/view_manager_export.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace mojo {
-namespace service {
-
-class ServerViewDelegate;
-
-// Server side representation of a view. Delegate is informed of interesting
-// events.
-//
-// It is assumed that all functions that mutate the tree have validated the
-// mutation is possible before hand. For example, Reorder() assumes the supplied
-// view is a child and not already in position.
-class MOJO_VIEW_MANAGER_EXPORT ServerView {
- public:
-  ServerView(ServerViewDelegate* delegate, const ViewId& id);
-  virtual ~ServerView();
-
-  const ViewId& id() const { return id_; }
-
-  void Add(ServerView* child);
-  void Remove(ServerView* child);
-  void Reorder(ServerView* child,
-               ServerView* relative,
-               OrderDirection direction);
-
-  const gfx::Rect& bounds() const { return bounds_; }
-  void SetBounds(const gfx::Rect& bounds);
-
-  const ServerView* parent() const { return parent_; }
-  ServerView* parent() { return parent_; }
-
-  const ServerView* GetRoot() const;
-  ServerView* GetRoot() {
-    return const_cast<ServerView*>(
-        const_cast<const ServerView*>(this)->GetRoot());
-  }
-
-  std::vector<const ServerView*> GetChildren() const;
-  std::vector<ServerView*> GetChildren();
-
-  // Returns true if this contains |view| or is |view|.
-  bool Contains(const ServerView* view) const;
-
-  // Returns true if the window is visible. This does not consider visibility
-  // of any ancestors.
-  bool visible() const { return visible_; }
-  void SetVisible(bool value);
-
-  // Returns true if this view is attached to |root| and all ancestors are
-  // visible.
-  bool IsDrawn(const ServerView* root) const;
-
-  void SetSurfaceId(cc::SurfaceId surface_id);
-  const cc::SurfaceId surface_id() const { return surface_id_; }
-
- private:
-  typedef std::vector<ServerView*> Views;
-
-  // Implementation of removing a view. Doesn't send any notification.
-  void RemoveImpl(ServerView* view);
-
-  ServerViewDelegate* delegate_;
-  const ViewId id_;
-  ServerView* parent_;
-  Views children_;
-  bool visible_;
-  gfx::Rect bounds_;
-  cc::SurfaceId surface_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServerView);
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_SERVER_VIEW_H_
diff --git a/mojo/services/view_manager/server_view_delegate.h b/mojo/services/view_manager/server_view_delegate.h
deleted file mode 100644
index 24e5f8f..0000000
--- a/mojo/services/view_manager/server_view_delegate.h
+++ /dev/null
@@ -1,52 +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 MOJO_SERVICES_VIEW_MANAGER_SERVER_VIEW_DELEGATE_H_
-#define MOJO_SERVICES_VIEW_MANAGER_SERVER_VIEW_DELEGATE_H_
-
-#include "mojo/services/view_manager/view_manager_export.h"
-
-namespace gfx {
-class Rect;
-}
-
-namespace mojo {
-namespace service {
-
-class ServerView;
-
-class MOJO_VIEW_MANAGER_EXPORT ServerViewDelegate {
- public:
-  // Invoked at the end of the View's destructor (after it has been removed from
-  // the hierarchy).
-  virtual void OnViewDestroyed(const ServerView* view) = 0;
-
-  virtual void OnWillChangeViewHierarchy(const ServerView* view,
-                                         const ServerView* new_parent,
-                                         const ServerView* old_parent) = 0;
-
-  virtual void OnViewHierarchyChanged(const ServerView* view,
-                                      const ServerView* new_parent,
-                                      const ServerView* old_parent) = 0;
-
-  virtual void OnViewBoundsChanged(const ServerView* view,
-                                   const gfx::Rect& old_bounds,
-                                   const gfx::Rect& new_bounds) = 0;
-
-  virtual void OnViewSurfaceIdChanged(const ServerView* view) = 0;
-
-  virtual void OnViewReordered(const ServerView* view,
-                               const ServerView* relative,
-                               OrderDirection direction) = 0;
-
-  virtual void OnWillChangeViewVisibility(const ServerView* view) = 0;
-
- protected:
-  virtual ~ServerViewDelegate() {}
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_SERVER_VIEW_DELEGATE_H_
diff --git a/mojo/services/view_manager/test_change_tracker.cc b/mojo/services/view_manager/test_change_tracker.cc
deleted file mode 100644
index 2b127cde..0000000
--- a/mojo/services/view_manager/test_change_tracker.cc
+++ /dev/null
@@ -1,244 +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 "mojo/services/view_manager/test_change_tracker.h"
-
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "mojo/common/common_type_converters.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/services/public/cpp/view_manager/util.h"
-
-namespace mojo {
-namespace service {
-
-std::string ViewIdToString(Id id) {
-  return (id == 0) ? "null" :
-      base::StringPrintf("%d,%d", HiWord(id), LoWord(id));
-}
-
-namespace {
-
-std::string RectToString(const gfx::Rect& rect) {
-  return base::StringPrintf("%d,%d %dx%d", rect.x(), rect.y(), rect.width(),
-                            rect.height());
-}
-
-std::string DirectionToString(OrderDirection direction) {
-  return direction == ORDER_DIRECTION_ABOVE ? "above" : "below";
-}
-
-std::string ChangeToDescription1(const Change& change) {
-  switch (change.type) {
-    case CHANGE_TYPE_EMBED:
-      return base::StringPrintf("OnEmbed creator=%s",
-                                change.creator_url.data());
-
-    case CHANGE_TYPE_NODE_BOUNDS_CHANGED:
-      return base::StringPrintf(
-          "BoundsChanged view=%s old_bounds=%s new_bounds=%s",
-          ViewIdToString(change.view_id).c_str(),
-          RectToString(change.bounds).c_str(),
-          RectToString(change.bounds2).c_str());
-
-    case CHANGE_TYPE_NODE_HIERARCHY_CHANGED:
-      return base::StringPrintf(
-          "HierarchyChanged view=%s new_parent=%s old_parent=%s",
-          ViewIdToString(change.view_id).c_str(),
-          ViewIdToString(change.view_id2).c_str(),
-          ViewIdToString(change.view_id3).c_str());
-
-    case CHANGE_TYPE_NODE_REORDERED:
-      return base::StringPrintf("Reordered view=%s relative=%s direction=%s",
-                                ViewIdToString(change.view_id).c_str(),
-                                ViewIdToString(change.view_id2).c_str(),
-                                DirectionToString(change.direction).c_str());
-
-    case CHANGE_TYPE_NODE_DELETED:
-      return base::StringPrintf("ViewDeleted view=%s",
-                                ViewIdToString(change.view_id).c_str());
-
-    case CHANGE_TYPE_NODE_VISIBILITY_CHANGED:
-      return base::StringPrintf("VisibilityChanged view=%s visible=%s",
-                                ViewIdToString(change.view_id).c_str(),
-                                change.bool_value ? "true" : "false");
-
-    case CHANGE_TYPE_NODE_DRAWN_STATE_CHANGED:
-      return base::StringPrintf("DrawnStateChanged view=%s drawn=%s",
-                                ViewIdToString(change.view_id).c_str(),
-                                change.bool_value ? "true" : "false");
-
-    case CHANGE_TYPE_INPUT_EVENT:
-      return base::StringPrintf("InputEvent view=%s event_action=%d",
-                                ViewIdToString(change.view_id).c_str(),
-                                change.event_action);
-
-    case CHANGE_TYPE_DELEGATE_EMBED:
-      return base::StringPrintf("DelegateEmbed url=%s",
-                                change.embed_url.data());
-  }
-  return std::string();
-}
-
-}  // namespace
-
-std::vector<std::string> ChangesToDescription1(
-    const std::vector<Change>& changes) {
-  std::vector<std::string> strings(changes.size());
-  for (size_t i = 0; i < changes.size(); ++i)
-    strings[i] = ChangeToDescription1(changes[i]);
-  return strings;
-}
-
-std::string ChangeViewDescription(const std::vector<Change>& changes) {
-  if (changes.size() != 1)
-    return std::string();
-  std::vector<std::string> view_strings(changes[0].views.size());
-  for (size_t i = 0; i < changes[0].views.size(); ++i)
-    view_strings[i] = "[" + changes[0].views[i].ToString() + "]";
-  return JoinString(view_strings, ',');
-}
-
-TestView ViewDataToTestView(const ViewDataPtr& data) {
-  TestView view;
-  view.parent_id = data->parent_id;
-  view.view_id = data->view_id;
-  view.visible = data->visible;
-  view.drawn = data->drawn;
-  return view;
-}
-
-void ViewDatasToTestViews(const Array<ViewDataPtr>& data,
-                          std::vector<TestView>* test_views) {
-  for (size_t i = 0; i < data.size(); ++i)
-    test_views->push_back(ViewDataToTestView(data[i]));
-}
-
-Change::Change()
-    : type(CHANGE_TYPE_EMBED),
-      connection_id(0),
-      view_id(0),
-      view_id2(0),
-      view_id3(0),
-      event_action(0),
-      direction(ORDER_DIRECTION_ABOVE),
-      bool_value(false) {
-}
-
-Change::~Change() {
-}
-
-TestChangeTracker::TestChangeTracker()
-    : delegate_(NULL) {
-}
-
-TestChangeTracker::~TestChangeTracker() {
-}
-
-void TestChangeTracker::OnEmbed(ConnectionSpecificId connection_id,
-                                const String& creator_url,
-                                ViewDataPtr root) {
-  Change change;
-  change.type = CHANGE_TYPE_EMBED;
-  change.connection_id = connection_id;
-  change.creator_url = creator_url;
-  change.views.push_back(ViewDataToTestView(root));
-  AddChange(change);
-}
-
-void TestChangeTracker::OnViewBoundsChanged(Id view_id,
-                                            RectPtr old_bounds,
-                                            RectPtr new_bounds) {
-  Change change;
-  change.type = CHANGE_TYPE_NODE_BOUNDS_CHANGED;
-  change.view_id = view_id;
-  change.bounds = old_bounds.To<gfx::Rect>();
-  change.bounds2 = new_bounds.To<gfx::Rect>();
-  AddChange(change);
-}
-
-void TestChangeTracker::OnViewHierarchyChanged(Id view_id,
-                                               Id new_parent_id,
-                                               Id old_parent_id,
-                                               Array<ViewDataPtr> views) {
-  Change change;
-  change.type = CHANGE_TYPE_NODE_HIERARCHY_CHANGED;
-  change.view_id = view_id;
-  change.view_id2 = new_parent_id;
-  change.view_id3 = old_parent_id;
-  ViewDatasToTestViews(views, &change.views);
-  AddChange(change);
-}
-
-void TestChangeTracker::OnViewReordered(Id view_id,
-                                        Id relative_view_id,
-                                        OrderDirection direction) {
-  Change change;
-  change.type = CHANGE_TYPE_NODE_REORDERED;
-  change.view_id = view_id;
-  change.view_id2 = relative_view_id;
-  change.direction = direction;
-  AddChange(change);
-}
-
-void TestChangeTracker::OnViewDeleted(Id view_id) {
-  Change change;
-  change.type = CHANGE_TYPE_NODE_DELETED;
-  change.view_id = view_id;
-  AddChange(change);
-}
-
-void TestChangeTracker::OnViewVisibilityChanged(Id view_id, bool visible) {
-  Change change;
-  change.type = CHANGE_TYPE_NODE_VISIBILITY_CHANGED;
-  change.view_id = view_id;
-  change.bool_value = visible;
-  AddChange(change);
-}
-
-void TestChangeTracker::OnViewDrawnStateChanged(Id view_id, bool drawn) {
-  Change change;
-  change.type = CHANGE_TYPE_NODE_DRAWN_STATE_CHANGED;
-  change.view_id = view_id;
-  change.bool_value = drawn;
-  AddChange(change);
-}
-
-void TestChangeTracker::OnViewInputEvent(Id view_id, EventPtr event) {
-  Change change;
-  change.type = CHANGE_TYPE_INPUT_EVENT;
-  change.view_id = view_id;
-  change.event_action = event->action;
-  AddChange(change);
-}
-
-void TestChangeTracker::DelegateEmbed(const String& url) {
-  Change change;
-  change.type = CHANGE_TYPE_DELEGATE_EMBED;
-  change.embed_url = url;
-  AddChange(change);
-}
-
-void TestChangeTracker::AddChange(const Change& change) {
-  changes_.push_back(change);
-  if (delegate_)
-    delegate_->OnChangeAdded();
-}
-
-std::string TestView::ToString() const {
-  return base::StringPrintf("view=%s parent=%s",
-                            ViewIdToString(view_id).c_str(),
-                            ViewIdToString(parent_id).c_str());
-}
-
-std::string TestView::ToString2() const {
-  return base::StringPrintf("view=%s parent=%s visible=%s drawn=%s",
-                            ViewIdToString(view_id).c_str(),
-                            ViewIdToString(parent_id).c_str(),
-                            visible ? "true" : "false",
-                            drawn ? "true" : "false");
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/test_change_tracker.h b/mojo/services/view_manager/test_change_tracker.h
deleted file mode 100644
index 791c8adc..0000000
--- a/mojo/services/view_manager/test_change_tracker.h
+++ /dev/null
@@ -1,133 +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 MOJO_SERVICES_VIEW_MANAGER_TEST_CHANGE_TRACKER_H_
-#define MOJO_SERVICES_VIEW_MANAGER_TEST_CHANGE_TRACKER_H_
-
-#include <string>
-#include <vector>
-
-#include "mojo/public/cpp/bindings/array.h"
-#include "mojo/services/public/cpp/view_manager/types.h"
-#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
-#include "ui/gfx/rect.h"
-
-namespace mojo {
-namespace service {
-
-enum ChangeType {
-  CHANGE_TYPE_EMBED,
-  // TODO(sky): NODE->VIEW.
-  CHANGE_TYPE_NODE_BOUNDS_CHANGED,
-  CHANGE_TYPE_NODE_HIERARCHY_CHANGED,
-  CHANGE_TYPE_NODE_REORDERED,
-  CHANGE_TYPE_NODE_VISIBILITY_CHANGED,
-  CHANGE_TYPE_NODE_DRAWN_STATE_CHANGED,
-  CHANGE_TYPE_NODE_DELETED,
-  CHANGE_TYPE_INPUT_EVENT,
-  CHANGE_TYPE_DELEGATE_EMBED,
-};
-
-// TODO(sky): consider nuking and converting directly to ViewData.
-struct TestView {
-  // Returns a string description of this.
-  std::string ToString() const;
-
-  // Returns a string description that includes visible and drawn.
-  std::string ToString2() const;
-
-  Id parent_id;
-  Id view_id;
-  bool visible;
-  bool drawn;
-};
-
-// Tracks a call to ViewManagerClient. See the individual functions for the
-// fields that are used.
-struct Change {
-  Change();
-  ~Change();
-
-  ChangeType type;
-  ConnectionSpecificId connection_id;
-  std::vector<TestView> views;
-  Id view_id;
-  Id view_id2;
-  Id view_id3;
-  gfx::Rect bounds;
-  gfx::Rect bounds2;
-  int32 event_action;
-  String creator_url;
-  String embed_url;
-  OrderDirection direction;
-  bool bool_value;
-};
-
-// Converts Changes to string descriptions.
-std::vector<std::string> ChangesToDescription1(
-    const std::vector<Change>& changes);
-
-// Returns a string description of |changes[0].views|. Returns an empty string
-// if change.size() != 1.
-std::string ChangeViewDescription(const std::vector<Change>& changes);
-
-// Converts ViewDatas to TestViews.
-void ViewDatasToTestViews(const Array<ViewDataPtr>& data,
-                          std::vector<TestView>* test_views);
-
-// TestChangeTracker is used to record ViewManagerClient functions. It notifies
-// a delegate any time a change is added.
-class TestChangeTracker {
- public:
-  // Used to notify the delegate when a change is added. A change corresponds to
-  // a single ViewManagerClient function.
-  class Delegate {
-   public:
-    virtual void OnChangeAdded() = 0;
-
-   protected:
-    virtual ~Delegate() {}
-  };
-
-  TestChangeTracker();
-  ~TestChangeTracker();
-
-  void set_delegate(Delegate* delegate) {
-    delegate_ = delegate;
-  }
-
-  std::vector<Change>* changes() { return &changes_; }
-
-  // Each of these functions generate a Change. There is one per
-  // ViewManagerClient function.
-  void OnEmbed(ConnectionSpecificId connection_id,
-               const String& creator_url,
-               ViewDataPtr root);
-  void OnViewBoundsChanged(Id view_id, RectPtr old_bounds, RectPtr new_bounds);
-  void OnViewHierarchyChanged(Id view_id,
-                              Id new_parent_id,
-                              Id old_parent_id,
-                              Array<ViewDataPtr> views);
-  void OnViewReordered(Id view_id,
-                       Id relative_view_id,
-                       OrderDirection direction);
-  void OnViewDeleted(Id view_id);
-  void OnViewVisibilityChanged(Id view_id, bool visible);
-  void OnViewDrawnStateChanged(Id view_id, bool drawn);
-  void OnViewInputEvent(Id view_id, EventPtr event);
-  void DelegateEmbed(const String& url);
-
- private:
-  void AddChange(const Change& change);
-
-  Delegate* delegate_;
-  std::vector<Change> changes_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestChangeTracker);
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_TEST_CHANGE_TRACKER_H_
diff --git a/mojo/services/view_manager/view_manager_export.h b/mojo/services/view_manager/view_manager_export.h
deleted file mode 100644
index 29b0e621..0000000
--- a/mojo/services/view_manager/view_manager_export.h
+++ /dev/null
@@ -1,31 +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 MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_EXPORT_H_
-#define MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_EXPORT_H_
-
-#if defined(COMPONENT_BUILD)
-#if defined(WIN32)
-
-#if defined(MOJO_VIEW_MANAGER_IMPLEMENTATION)
-#define MOJO_VIEW_MANAGER_EXPORT __declspec(dllexport)
-#else
-#define MOJO_VIEW_MANAGER_EXPORT __declspec(dllimport)
-#endif
-
-#else  // !defined(WIN32)
-
-#if defined(MOJO_VIEW_MANAGER_IMPLEMENTATION)
-#define MOJO_VIEW_MANAGER_EXPORT __attribute__((visibility("default")))
-#else
-#define MOJO_VIEW_MANAGER_EXPORT
-#endif
-
-#endif  // defined(WIN32)
-
-#else  // defined(COMPONENT_BUILD)
-#define MOJO_VIEW_MANAGER_EXPORT
-#endif
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_EXPORT_H_
diff --git a/mojo/services/view_manager/view_manager_init_service_context.cc b/mojo/services/view_manager/view_manager_init_service_context.cc
deleted file mode 100644
index d23bec75..0000000
--- a/mojo/services/view_manager/view_manager_init_service_context.cc
+++ /dev/null
@@ -1,78 +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 "mojo/services/view_manager/view_manager_init_service_context.h"
-
-#include "base/auto_reset.h"
-#include "base/bind.h"
-#include "mojo/services/view_manager/connection_manager.h"
-#include "mojo/services/view_manager/view_manager_init_service_impl.h"
-
-namespace mojo {
-namespace service {
-
-ViewManagerInitServiceContext::ConnectParams::ConnectParams() {}
-
-ViewManagerInitServiceContext::ConnectParams::~ConnectParams() {}
-
-ViewManagerInitServiceContext::ViewManagerInitServiceContext()
-    : deleting_connection_(false) {
-}
-ViewManagerInitServiceContext::~ViewManagerInitServiceContext() {}
-
-void ViewManagerInitServiceContext::AddConnection(
-    ViewManagerInitServiceImpl* connection) {
-  DCHECK(std::find(connections_.begin(), connections_.end(), connection) ==
-                   connections_.end());
-  connections_.push_back(connection);
-}
-
-void ViewManagerInitServiceContext::RemoveConnection(
-    ViewManagerInitServiceImpl* connection) {
-  if (!deleting_connection_) {
-    Connections::iterator it =
-        std::find(connections_.begin(), connections_.end(), connection);
-    DCHECK(it != connections_.end());
-    connections_.erase(it);
-  }
-
-  // This object is owned by an object that outlives the current thread's
-  // message loop, so we need to destroy the ConnectionManager earlier, as it
-  // may attempt to post tasks during its destruction.
-  if (connections_.empty())
-    connection_manager_.reset();
-}
-
-void ViewManagerInitServiceContext::ConfigureIncomingConnection(
-    ApplicationConnection* connection) {
-  if (!connection_manager_.get()) {
-    connection_manager_.reset(new ConnectionManager(
-        connection,
-        base::Bind(&ViewManagerInitServiceContext::OnNativeViewportDeleted,
-                   base::Unretained(this))));
-  }
-}
-
-void ViewManagerInitServiceContext::Embed(
-    const String& url,
-    ServiceProviderPtr service_provider,
-    const Callback<void(bool)>& callback) {
-  connection_manager_->Embed(url, GetProxy(&service_provider));
-  callback.Run(true);
-}
-
-void ViewManagerInitServiceContext::OnNativeViewportDeleted() {
-  // Prevent the connection from modifying the connection list during manual
-  // teardown.
-  base::AutoReset<bool> deleting_connection(&deleting_connection_, true);
-  for (Connections::const_iterator it = connections_.begin();
-       it != connections_.end(); ++it) {
-    delete *it;
-  }
-  connections_.clear();
-  connection_manager_.reset();
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/view_manager_init_service_context.h b/mojo/services/view_manager/view_manager_init_service_context.h
deleted file mode 100644
index 5019c68..0000000
--- a/mojo/services/view_manager/view_manager_init_service_context.h
+++ /dev/null
@@ -1,64 +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 MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_INIT_SERVICE_CONTEXT_H_
-#define MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_INIT_SERVICE_CONTEXT_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "mojo/public/cpp/bindings/callback.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "mojo/public/interfaces/application/service_provider.mojom.h"
-#include "mojo/services/view_manager/view_manager_export.h"
-
-namespace mojo {
-class ApplicationConnection;
-
-namespace service {
-
-class ConnectionManager;
-class ViewManagerInitServiceImpl;
-
-// State shared between all ViewManagerInitService impls.
-class MOJO_VIEW_MANAGER_EXPORT ViewManagerInitServiceContext {
- public:
-  ViewManagerInitServiceContext();
-  virtual ~ViewManagerInitServiceContext();
-
-  void AddConnection(ViewManagerInitServiceImpl* connection);
-  void RemoveConnection(ViewManagerInitServiceImpl* connection);
-
-  void ConfigureIncomingConnection(ApplicationConnection* connection);
-
-  void Embed(const String& url,
-             ServiceProviderPtr service_provider,
-             const Callback<void(bool)>& callback);
-
-  ConnectionManager* connection_manager() { return connection_manager_.get(); }
-
- private:
-  typedef std::vector<ViewManagerInitServiceImpl*> Connections;
-
-  struct ConnectParams {
-    ConnectParams();
-    ~ConnectParams();
-
-    std::string url;
-    InterfaceRequest<ServiceProvider> service_provider;
-    Callback<void(bool)> callback;
-  };
-
-  void OnNativeViewportDeleted();
-
-  scoped_ptr<ConnectionManager> connection_manager_;
-  Connections connections_;
-
-  bool deleting_connection_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerInitServiceContext);
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_INIT_SERVICE_CONTEXT_H_
diff --git a/mojo/services/view_manager/view_manager_init_service_impl.cc b/mojo/services/view_manager/view_manager_init_service_impl.cc
deleted file mode 100644
index ab30718..0000000
--- a/mojo/services/view_manager/view_manager_init_service_impl.cc
+++ /dev/null
@@ -1,34 +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 "mojo/services/view_manager/view_manager_init_service_impl.h"
-
-#include "base/bind.h"
-#include "mojo/services/view_manager/ids.h"
-#include "mojo/services/view_manager/view_manager_init_service_context.h"
-#include "mojo/services/view_manager/view_manager_service_impl.h"
-
-namespace mojo {
-namespace service {
-
-ViewManagerInitServiceImpl::ViewManagerInitServiceImpl(
-    ApplicationConnection* connection,
-    ViewManagerInitServiceContext* context)
-    : context_(context) {
-  context_->AddConnection(this);
-}
-
-ViewManagerInitServiceImpl::~ViewManagerInitServiceImpl() {
-  context_->RemoveConnection(this);
-}
-
-void ViewManagerInitServiceImpl::Embed(
-    const String& url,
-    ServiceProviderPtr service_provider,
-    const Callback<void(bool)>& callback) {
-  context_->Embed(url, service_provider.Pass(), callback);
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/view_manager_init_service_impl.h b/mojo/services/view_manager/view_manager_init_service_impl.h
deleted file mode 100644
index 63fbc38..0000000
--- a/mojo/services/view_manager/view_manager_init_service_impl.h
+++ /dev/null
@@ -1,57 +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 MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_INIT_SERVICE_IMPL_H_
-#define MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_INIT_SERVICE_IMPL_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
-#include "mojo/services/view_manager/connection_manager.h"
-#include "mojo/services/view_manager/view_manager_export.h"
-
-namespace mojo {
-
-class ApplicationConnection;
-
-namespace service {
-
-class ViewManagerInitServiceContext;
-
-#if defined(OS_WIN)
-// Equivalent of NON_EXPORTED_BASE which does not work with the template snafu
-// below.
-#pragma warning(push)
-#pragma warning(disable : 4275)
-#endif
-
-// Used to create the initial ViewManagerClient. Doesn't initiate the Connect()
-// until the WindowTreeHost has been created.
-class MOJO_VIEW_MANAGER_EXPORT ViewManagerInitServiceImpl
-    : public InterfaceImpl<ViewManagerInitService> {
- public:
-  ViewManagerInitServiceImpl(ApplicationConnection* connection,
-                             ViewManagerInitServiceContext* context);
-  virtual ~ViewManagerInitServiceImpl();
-
- private:
-  // ViewManagerInitService overrides:
-  virtual void Embed(const String& url,
-                     ServiceProviderPtr service_provider,
-                     const Callback<void(bool)>& callback) override;
-
-  ViewManagerInitServiceContext* context_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerInitServiceImpl);
-};
-
-#if defined(OS_WIN)
-#pragma warning(pop)
-#endif
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_INIT_SERVICE_IMPL_H_
diff --git a/mojo/services/view_manager/view_manager_service_impl.cc b/mojo/services/view_manager/view_manager_service_impl.cc
deleted file mode 100644
index f066b8250..0000000
--- a/mojo/services/view_manager/view_manager_service_impl.cc
+++ /dev/null
@@ -1,541 +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 "mojo/services/view_manager/view_manager_service_impl.h"
-
-#include "base/bind.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/converters/input_events/input_events_type_converters.h"
-#include "mojo/converters/surfaces/surfaces_type_converters.h"
-#include "mojo/services/view_manager/connection_manager.h"
-#include "mojo/services/view_manager/default_access_policy.h"
-#include "mojo/services/view_manager/server_view.h"
-#include "mojo/services/view_manager/window_manager_access_policy.h"
-
-namespace mojo {
-namespace service {
-
-ViewManagerServiceImpl::ViewManagerServiceImpl(
-    ConnectionManager* connection_manager,
-    ConnectionSpecificId creator_id,
-    const std::string& creator_url,
-    const std::string& url,
-    const ViewId& root_id,
-    InterfaceRequest<ServiceProvider> service_provider)
-    : connection_manager_(connection_manager),
-      id_(connection_manager_->GetAndAdvanceNextConnectionId()),
-      url_(url),
-      creator_id_(creator_id),
-      creator_url_(creator_url),
-      delete_on_connection_error_(false),
-      service_provider_(service_provider.Pass()) {
-  CHECK(GetView(root_id));
-  roots_.insert(ViewIdToTransportId(root_id));
-  if (root_id == RootViewId())
-    access_policy_.reset(new WindowManagerAccessPolicy(id_, this));
-  else
-    access_policy_.reset(new DefaultAccessPolicy(id_, this));
-}
-
-ViewManagerServiceImpl::~ViewManagerServiceImpl() {
-  // Delete any views we created.
-  if (!view_map_.empty()) {
-    ConnectionManager::ScopedChange change(this, connection_manager_, true);
-    while (!view_map_.empty())
-      delete view_map_.begin()->second;
-  }
-
-  connection_manager_->RemoveConnection(this);
-}
-
-const ServerView* ViewManagerServiceImpl::GetView(const ViewId& id) const {
-  if (id_ == id.connection_id) {
-    ViewMap::const_iterator i = view_map_.find(id.view_id);
-    return i == view_map_.end() ? NULL : i->second;
-  }
-  return connection_manager_->GetView(id);
-}
-
-bool ViewManagerServiceImpl::HasRoot(const ViewId& id) const {
-  return roots_.find(ViewIdToTransportId(id)) != roots_.end();
-}
-
-void ViewManagerServiceImpl::OnViewManagerServiceImplDestroyed(
-    ConnectionSpecificId id) {
-  if (creator_id_ == id)
-    creator_id_ = kInvalidConnectionId;
-}
-
-void ViewManagerServiceImpl::ProcessViewBoundsChanged(
-    const ServerView* view,
-    const gfx::Rect& old_bounds,
-    const gfx::Rect& new_bounds,
-    bool originated_change) {
-  if (originated_change || !IsViewKnown(view))
-    return;
-  client()->OnViewBoundsChanged(ViewIdToTransportId(view->id()),
-                                Rect::From(old_bounds),
-                                Rect::From(new_bounds));
-}
-
-void ViewManagerServiceImpl::ProcessWillChangeViewHierarchy(
-    const ServerView* view,
-    const ServerView* new_parent,
-    const ServerView* old_parent,
-    bool originated_change) {
-  if (originated_change)
-    return;
-
-  const bool old_drawn = view->IsDrawn(connection_manager_->root());
-  const bool new_drawn = view->visible() && new_parent &&
-      new_parent->IsDrawn(connection_manager_->root());
-  if (old_drawn == new_drawn)
-    return;
-
-  NotifyDrawnStateChanged(view, new_drawn);
-}
-
-void ViewManagerServiceImpl::ProcessViewHierarchyChanged(
-    const ServerView* view,
-    const ServerView* new_parent,
-    const ServerView* old_parent,
-    bool originated_change) {
-  if (originated_change && !IsViewKnown(view) && new_parent &&
-      IsViewKnown(new_parent)) {
-    std::vector<const ServerView*> unused;
-    GetUnknownViewsFrom(view, &unused);
-  }
-  if (originated_change || connection_manager_->is_processing_delete_view() ||
-      connection_manager_->DidConnectionMessageClient(id_)) {
-    return;
-  }
-
-  if (!access_policy_->ShouldNotifyOnHierarchyChange(
-          view, &new_parent, &old_parent)) {
-    return;
-  }
-  // Inform the client of any new views and update the set of views we know
-  // about.
-  std::vector<const ServerView*> to_send;
-  if (!IsViewKnown(view))
-    GetUnknownViewsFrom(view, &to_send);
-  const ViewId new_parent_id(new_parent ? new_parent->id() : ViewId());
-  const ViewId old_parent_id(old_parent ? old_parent->id() : ViewId());
-  client()->OnViewHierarchyChanged(ViewIdToTransportId(view->id()),
-                                   ViewIdToTransportId(new_parent_id),
-                                   ViewIdToTransportId(old_parent_id),
-                                   ViewsToViewDatas(to_send));
-  connection_manager_->OnConnectionMessagedClient(id_);
-}
-
-void ViewManagerServiceImpl::ProcessViewReorder(const ServerView* view,
-                                                const ServerView* relative_view,
-                                                OrderDirection direction,
-                                                bool originated_change) {
-  if (originated_change || !IsViewKnown(view) || !IsViewKnown(relative_view))
-    return;
-
-  client()->OnViewReordered(ViewIdToTransportId(view->id()),
-                            ViewIdToTransportId(relative_view->id()),
-                            direction);
-}
-
-void ViewManagerServiceImpl::ProcessViewDeleted(const ViewId& view,
-                                                bool originated_change) {
-  view_map_.erase(view.view_id);
-
-  const bool in_known = known_views_.erase(ViewIdToTransportId(view)) > 0;
-  roots_.erase(ViewIdToTransportId(view));
-
-  if (originated_change)
-    return;
-
-  if (in_known) {
-    client()->OnViewDeleted(ViewIdToTransportId(view));
-    connection_manager_->OnConnectionMessagedClient(id_);
-  }
-}
-
-void ViewManagerServiceImpl::ProcessWillChangeViewVisibility(
-    const ServerView* view,
-    bool originated_change) {
-  if (originated_change)
-    return;
-
-  if (IsViewKnown(view)) {
-    client()->OnViewVisibilityChanged(ViewIdToTransportId(view->id()),
-                                      !view->visible());
-    return;
-  }
-
-  bool view_target_drawn_state;
-  if (view->visible()) {
-    // View is being hidden, won't be drawn.
-    view_target_drawn_state = false;
-  } else {
-    // View is being shown. View will be drawn if its parent is drawn.
-    view_target_drawn_state =
-        view->parent() && view->parent()->IsDrawn(connection_manager_->root());
-  }
-
-  NotifyDrawnStateChanged(view, view_target_drawn_state);
-}
-
-void ViewManagerServiceImpl::OnConnectionError() {
-  if (delete_on_connection_error_)
-    delete this;
-}
-
-bool ViewManagerServiceImpl::IsViewKnown(const ServerView* view) const {
-  return known_views_.count(ViewIdToTransportId(view->id())) > 0;
-}
-
-bool ViewManagerServiceImpl::CanReorderView(const ServerView* view,
-                                            const ServerView* relative_view,
-                                            OrderDirection direction) const {
-  if (!view || !relative_view)
-    return false;
-
-  if (!view->parent() || view->parent() != relative_view->parent())
-    return false;
-
-  if (!access_policy_->CanReorderView(view, relative_view, direction))
-    return false;
-
-  std::vector<const ServerView*> children = view->parent()->GetChildren();
-  const size_t child_i =
-      std::find(children.begin(), children.end(), view) - children.begin();
-  const size_t target_i =
-      std::find(children.begin(), children.end(), relative_view) -
-      children.begin();
-  if ((direction == ORDER_DIRECTION_ABOVE && child_i == target_i + 1) ||
-      (direction == ORDER_DIRECTION_BELOW && child_i + 1 == target_i)) {
-    return false;
-  }
-
-  return true;
-}
-
-bool ViewManagerServiceImpl::DeleteViewImpl(ViewManagerServiceImpl* source,
-                                            ServerView* view) {
-  DCHECK(view);
-  DCHECK_EQ(view->id().connection_id, id_);
-  ConnectionManager::ScopedChange change(source, connection_manager_, true);
-  delete view;
-  return true;
-}
-
-void ViewManagerServiceImpl::GetUnknownViewsFrom(
-    const ServerView* view,
-    std::vector<const ServerView*>* views) {
-  if (IsViewKnown(view) || !access_policy_->CanGetViewTree(view))
-    return;
-  views->push_back(view);
-  known_views_.insert(ViewIdToTransportId(view->id()));
-  if (!access_policy_->CanDescendIntoViewForViewTree(view))
-    return;
-  std::vector<const ServerView*> children(view->GetChildren());
-  for (size_t i = 0 ; i < children.size(); ++i)
-    GetUnknownViewsFrom(children[i], views);
-}
-
-void ViewManagerServiceImpl::RemoveFromKnown(
-    const ServerView* view,
-    std::vector<ServerView*>* local_views) {
-  if (view->id().connection_id == id_) {
-    if (local_views)
-      local_views->push_back(GetView(view->id()));
-    return;
-  }
-  known_views_.erase(ViewIdToTransportId(view->id()));
-  std::vector<const ServerView*> children = view->GetChildren();
-  for (size_t i = 0; i < children.size(); ++i)
-    RemoveFromKnown(children[i], local_views);
-}
-
-void ViewManagerServiceImpl::RemoveRoot(const ViewId& view_id) {
-  const Id transport_view_id(ViewIdToTransportId(view_id));
-  CHECK(roots_.count(transport_view_id) > 0);
-
-  roots_.erase(transport_view_id);
-
-  // No need to do anything if we created the view.
-  if (view_id.connection_id == id_)
-    return;
-
-  client()->OnViewDeleted(transport_view_id);
-  connection_manager_->OnConnectionMessagedClient(id_);
-
-  // This connection no longer knows about the view. Unparent any views that
-  // were parented to views in the root.
-  std::vector<ServerView*> local_views;
-  RemoveFromKnown(GetView(view_id), &local_views);
-  for (size_t i = 0; i < local_views.size(); ++i)
-    local_views[i]->parent()->Remove(local_views[i]);
-}
-
-void ViewManagerServiceImpl::RemoveChildrenAsPartOfEmbed(
-    const ViewId& view_id) {
-  ServerView* view = GetView(view_id);
-  CHECK(view);
-  CHECK(view->id().connection_id == view_id.connection_id);
-  std::vector<ServerView*> children = view->GetChildren();
-  for (size_t i = 0; i < children.size(); ++i)
-    view->Remove(children[i]);
-}
-
-Array<ViewDataPtr> ViewManagerServiceImpl::ViewsToViewDatas(
-    const std::vector<const ServerView*>& views) {
-  Array<ViewDataPtr> array(views.size());
-  for (size_t i = 0; i < views.size(); ++i)
-    array[i] = ViewToViewData(views[i]).Pass();
-  return array.Pass();
-}
-
-ViewDataPtr ViewManagerServiceImpl::ViewToViewData(const ServerView* view) {
-  DCHECK(IsViewKnown(view));
-  const ServerView* parent = view->parent();
-  // If the parent isn't known, it means the parent is not visible to us (not
-  // in roots), and should not be sent over.
-  if (parent && !IsViewKnown(parent))
-    parent = NULL;
-  ViewDataPtr view_data(ViewData::New());
-  view_data->parent_id = ViewIdToTransportId(parent ? parent->id() : ViewId());
-  view_data->view_id = ViewIdToTransportId(view->id());
-  view_data->bounds = Rect::From(view->bounds());
-  view_data->visible = view->visible();
-  view_data->drawn = view->IsDrawn(connection_manager_->root());
-  return view_data.Pass();
-}
-
-void ViewManagerServiceImpl::GetViewTreeImpl(
-    const ServerView* view,
-    std::vector<const ServerView*>* views) const {
-  DCHECK(view);
-
-  if (!access_policy_->CanGetViewTree(view))
-    return;
-
-  views->push_back(view);
-
-  if (!access_policy_->CanDescendIntoViewForViewTree(view))
-    return;
-
-  std::vector<const ServerView*> children(view->GetChildren());
-  for (size_t i = 0 ; i < children.size(); ++i)
-    GetViewTreeImpl(children[i], views);
-}
-
-void ViewManagerServiceImpl::NotifyDrawnStateChanged(const ServerView* view,
-                                                     bool new_drawn_value) {
-  // Even though we don't know about view, it may be an ancestor of one of our
-  // roots, in which case the change may effect our roots drawn state.
-  for (ViewIdSet::iterator i = roots_.begin(); i != roots_.end(); ++i) {
-    const ServerView* root = GetView(ViewIdFromTransportId(*i));
-    DCHECK(root);
-    if (view->Contains(root) &&
-        (new_drawn_value != root->IsDrawn(connection_manager_->root()))) {
-      client()->OnViewDrawnStateChanged(ViewIdToTransportId(root->id()),
-                                        new_drawn_value);
-    }
-  }
-}
-
-void ViewManagerServiceImpl::CreateView(
-    Id transport_view_id,
-    const Callback<void(ErrorCode)>& callback) {
-  const ViewId view_id(ViewIdFromTransportId(transport_view_id));
-  ErrorCode error_code = ERROR_CODE_NONE;
-  if (view_id.connection_id != id_) {
-    error_code = ERROR_CODE_ILLEGAL_ARGUMENT;
-  } else if (view_map_.find(view_id.view_id) != view_map_.end()) {
-    error_code = ERROR_CODE_VALUE_IN_USE;
-  } else {
-    view_map_[view_id.view_id] = new ServerView(connection_manager_, view_id);
-    known_views_.insert(transport_view_id);
-  }
-  callback.Run(error_code);
-}
-
-void ViewManagerServiceImpl::DeleteView(
-    Id transport_view_id,
-    const Callback<void(bool)>& callback) {
-  ServerView* view = GetView(ViewIdFromTransportId(transport_view_id));
-  bool success = false;
-  if (view && access_policy_->CanDeleteView(view)) {
-    ViewManagerServiceImpl* connection =
-        connection_manager_->GetConnection(view->id().connection_id);
-    success = connection && connection->DeleteViewImpl(this, view);
-  }
-  callback.Run(success);
-}
-
-void ViewManagerServiceImpl::AddView(
-    Id parent_id,
-    Id child_id,
-    const Callback<void(bool)>& callback) {
-  bool success = false;
-  ServerView* parent = GetView(ViewIdFromTransportId(parent_id));
-  ServerView* child = GetView(ViewIdFromTransportId(child_id));
-  if (parent && child && child->parent() != parent &&
-      !child->Contains(parent) && access_policy_->CanAddView(parent, child)) {
-    success = true;
-    ConnectionManager::ScopedChange change(this, connection_manager_, false);
-    parent->Add(child);
-  }
-  callback.Run(success);
-}
-
-void ViewManagerServiceImpl::RemoveViewFromParent(
-    Id view_id,
-    const Callback<void(bool)>& callback) {
-  bool success = false;
-  ServerView* view = GetView(ViewIdFromTransportId(view_id));
-  if (view && view->parent() && access_policy_->CanRemoveViewFromParent(view)) {
-    success = true;
-    ConnectionManager::ScopedChange change(this, connection_manager_, false);
-    view->parent()->Remove(view);
-  }
-  callback.Run(success);
-}
-
-void ViewManagerServiceImpl::ReorderView(Id view_id,
-                                         Id relative_view_id,
-                                         OrderDirection direction,
-                                         const Callback<void(bool)>& callback) {
-  bool success = false;
-  ServerView* view = GetView(ViewIdFromTransportId(view_id));
-  ServerView* relative_view = GetView(ViewIdFromTransportId(relative_view_id));
-  if (CanReorderView(view, relative_view, direction)) {
-    success = true;
-    ConnectionManager::ScopedChange change(this, connection_manager_, false);
-    view->parent()->Reorder(view, relative_view, direction);
-    connection_manager_->ProcessViewReorder(view, relative_view, direction);
-  }
-  callback.Run(success);
-}
-
-void ViewManagerServiceImpl::GetViewTree(
-    Id view_id,
-    const Callback<void(Array<ViewDataPtr>)>& callback) {
-  ServerView* view = GetView(ViewIdFromTransportId(view_id));
-  std::vector<const ServerView*> views;
-  if (view) {
-    GetViewTreeImpl(view, &views);
-    // TODO(sky): this should map in views that weren't none.
-  }
-  callback.Run(ViewsToViewDatas(views));
-}
-
-void ViewManagerServiceImpl::SetViewSurfaceId(
-    Id view_id,
-    SurfaceIdPtr surface_id,
-    const Callback<void(bool)>& callback) {
-  // TODO(sky): add coverage of not being able to set for random node.
-  ServerView* view = GetView(ViewIdFromTransportId(view_id));
-  if (!view || !access_policy_->CanSetViewSurfaceId(view)) {
-    callback.Run(false);
-    return;
-  }
-  view->SetSurfaceId(surface_id.To<cc::SurfaceId>());
-  callback.Run(true);
-}
-
-void ViewManagerServiceImpl::SetViewBounds(
-    Id view_id,
-    RectPtr bounds,
-    const Callback<void(bool)>& callback) {
-  ServerView* view = GetView(ViewIdFromTransportId(view_id));
-  const bool success = view && access_policy_->CanSetViewBounds(view);
-  if (success) {
-    ConnectionManager::ScopedChange change(this, connection_manager_, false);
-    view->SetBounds(bounds.To<gfx::Rect>());
-  }
-  callback.Run(success);
-}
-
-void ViewManagerServiceImpl::SetViewVisibility(
-    Id transport_view_id,
-    bool visible,
-    const Callback<void(bool)>& callback) {
-  ServerView* view = GetView(ViewIdFromTransportId(transport_view_id));
-  if (!view || view->visible() == visible ||
-      !access_policy_->CanChangeViewVisibility(view)) {
-    callback.Run(false);
-    return;
-  }
-  {
-    ConnectionManager::ScopedChange change(this, connection_manager_, false);
-    view->SetVisible(visible);
-  }
-  callback.Run(true);
-}
-
-void ViewManagerServiceImpl::Embed(
-    const String& url,
-    Id transport_view_id,
-    ServiceProviderPtr service_provider,
-    const Callback<void(bool)>& callback) {
-  InterfaceRequest<ServiceProvider> spir;
-  spir.Bind(service_provider.PassMessagePipe());
-
-  if (ViewIdFromTransportId(transport_view_id) == InvalidViewId()) {
-    connection_manager_->Embed(url, spir.Pass());
-    callback.Run(true);
-    return;
-  }
-  const ServerView* view = GetView(ViewIdFromTransportId(transport_view_id));
-  if (!view || !access_policy_->CanEmbed(view)) {
-    callback.Run(false);
-    return;
-  }
-
-  // Only allow a node to be the root for one connection.
-  const ViewId view_id(ViewIdFromTransportId(transport_view_id));
-  ViewManagerServiceImpl* existing_owner =
-      connection_manager_->GetConnectionWithRoot(view_id);
-
-  ConnectionManager::ScopedChange change(this, connection_manager_, true);
-  RemoveChildrenAsPartOfEmbed(view_id);
-  if (existing_owner) {
-    // Never message the originating connection.
-    connection_manager_->OnConnectionMessagedClient(id_);
-    existing_owner->RemoveRoot(view_id);
-  }
-  connection_manager_->EmbedAtView(id_, url, transport_view_id, spir.Pass());
-  callback.Run(true);
-}
-
-void ViewManagerServiceImpl::OnConnectionEstablished() {
-  connection_manager_->AddConnection(this);
-
-  std::vector<const ServerView*> to_send;
-  for (ViewIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i)
-    GetUnknownViewsFrom(GetView(ViewIdFromTransportId(*i)), &to_send);
-
-  client()->OnEmbed(id_,
-                    creator_url_,
-                    ViewToViewData(to_send.front()),
-                    service_provider_.Pass());
-}
-
-const base::hash_set<Id>&
-ViewManagerServiceImpl::GetRootsForAccessPolicy() const {
-  return roots_;
-}
-
-bool ViewManagerServiceImpl::IsViewKnownForAccessPolicy(
-    const ServerView* view) const {
-  return IsViewKnown(view);
-}
-
-bool ViewManagerServiceImpl::IsViewRootOfAnotherConnectionForAccessPolicy(
-    const ServerView* view) const {
-  ViewManagerServiceImpl* connection =
-      connection_manager_->GetConnectionWithRoot(view->id());
-  return connection && connection != this;
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/view_manager_service_impl.h b/mojo/services/view_manager/view_manager_service_impl.h
deleted file mode 100644
index c77f28591..0000000
--- a/mojo/services/view_manager/view_manager_service_impl.h
+++ /dev/null
@@ -1,238 +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 MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_SERVICE_IMPL_H_
-#define MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_SERVICE_IMPL_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/containers/hash_tables.h"
-#include "base/memory/scoped_ptr.h"
-#include "mojo/services/public/interfaces/surfaces/surface_id.mojom.h"
-#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
-#include "mojo/services/view_manager/access_policy_delegate.h"
-#include "mojo/services/view_manager/ids.h"
-#include "mojo/services/view_manager/view_manager_export.h"
-
-namespace gfx {
-class Rect;
-}
-
-namespace mojo {
-namespace service {
-
-class AccessPolicy;
-class ConnectionManager;
-class ServerView;
-
-#if defined(OS_WIN)
-// Equivalent of NON_EXPORTED_BASE which does not work with the template snafu
-// below.
-#pragma warning(push)
-#pragma warning(disable : 4275)
-#endif
-
-// Manages a connection from the client.
-class MOJO_VIEW_MANAGER_EXPORT ViewManagerServiceImpl
-    : public InterfaceImpl<ViewManagerService>,
-      public AccessPolicyDelegate {
- public:
-  ViewManagerServiceImpl(ConnectionManager* connection_manager,
-                         ConnectionSpecificId creator_id,
-                         const std::string& creator_url,
-                         const std::string& url,
-                         const ViewId& root_id,
-                         InterfaceRequest<ServiceProvider> service_provider);
-  virtual ~ViewManagerServiceImpl();
-
-  // Used to mark this connection as originating from a call to
-  // ViewManagerService::Connect(). When set OnConnectionError() deletes |this|.
-  void set_delete_on_connection_error() { delete_on_connection_error_ = true; }
-
-  ConnectionSpecificId id() const { return id_; }
-  ConnectionSpecificId creator_id() const { return creator_id_; }
-  const std::string& url() const { return url_; }
-
-  // Returns the View with the specified id.
-  ServerView* GetView(const ViewId& id) {
-    return const_cast<ServerView*>(
-        const_cast<const ViewManagerServiceImpl*>(this)->GetView(id));
-  }
-  const ServerView* GetView(const ViewId& id) const;
-
-  // Returns true if this has |id| as a root.
-  bool HasRoot(const ViewId& id) const;
-
-  // Invoked when a connection is destroyed.
-  void OnViewManagerServiceImplDestroyed(ConnectionSpecificId id);
-
-  // The following methods are invoked after the corresponding change has been
-  // processed. They do the appropriate bookkeeping and update the client as
-  // necessary.
-  void ProcessViewBoundsChanged(const ServerView* view,
-                                const gfx::Rect& old_bounds,
-                                const gfx::Rect& new_bounds,
-                                bool originated_change);
-  void ProcessWillChangeViewHierarchy(const ServerView* view,
-                                      const ServerView* new_parent,
-                                      const ServerView* old_parent,
-                                      bool originated_change);
-  void ProcessViewHierarchyChanged(const ServerView* view,
-                                   const ServerView* new_parent,
-                                   const ServerView* old_parent,
-                                   bool originated_change);
-  void ProcessViewReorder(const ServerView* view,
-                          const ServerView* relative_view,
-                          OrderDirection direction,
-                          bool originated_change);
-  void ProcessViewDeleted(const ViewId& view, bool originated_change);
-  void ProcessWillChangeViewVisibility(const ServerView* view,
-                                       bool originated_change);
-
-  // TODO(sky): move this to private section (currently can't because of
-  // bindings).
-  // InterfaceImp overrides:
-  virtual void OnConnectionError() override;
-
- private:
-  typedef std::map<ConnectionSpecificId, ServerView*> ViewMap;
-  typedef base::hash_set<Id> ViewIdSet;
-
-  bool IsViewKnown(const ServerView* view) const;
-
-  // These functions return true if the corresponding mojom function is allowed
-  // for this connection.
-  bool CanReorderView(const ServerView* view,
-                      const ServerView* relative_view,
-                      OrderDirection direction) const;
-
-  // Deletes a view owned by this connection. Returns true on success. |source|
-  // is the connection that originated the change.
-  bool DeleteViewImpl(ViewManagerServiceImpl* source, ServerView* view);
-
-  // If |view| is known (in |known_views_|) does nothing. Otherwise adds |view|
-  // to |views|, marks |view| as known and recurses.
-  void GetUnknownViewsFrom(const ServerView* view,
-                           std::vector<const ServerView*>* views);
-
-  // Removes |view| and all its descendants from |known_views_|. This does not
-  // recurse through views that were created by this connection. All views owned
-  // by this connection are added to |local_views|.
-  void RemoveFromKnown(const ServerView* view,
-                       std::vector<ServerView*>* local_views);
-
-  // Removes |view_id| from the set of roots this connection knows about.
-  void RemoveRoot(const ViewId& view_id);
-
-  void RemoveChildrenAsPartOfEmbed(const ViewId& view_id);
-
-  // Converts View(s) to ViewData(s) for transport. This assumes all the views
-  // are valid for the client. The parent of views the client is not allowed to
-  // see are set to NULL (in the returned ViewData(s)).
-  Array<ViewDataPtr> ViewsToViewDatas(
-      const std::vector<const ServerView*>& views);
-  ViewDataPtr ViewToViewData(const ServerView* view);
-
-  // Implementation of GetViewTree(). Adds |view| to |views| and recurses if
-  // CanDescendIntoViewForViewTree() returns true.
-  void GetViewTreeImpl(const ServerView* view,
-                       std::vector<const ServerView*>* views) const;
-
-  // Notify the client if the drawn state of any of the roots changes.
-  // |view| is the view that is changing to the drawn state |new_drawn_value|.
-  void NotifyDrawnStateChanged(const ServerView* view, bool new_drawn_value);
-
-  // ViewManagerService:
-  virtual void CreateView(Id transport_view_id,
-                          const Callback<void(ErrorCode)>& callback) override;
-  virtual void DeleteView(Id transport_view_id,
-                          const Callback<void(bool)>& callback) override;
-  virtual void AddView(Id parent_id,
-                       Id child_id,
-                       const Callback<void(bool)>& callback) override;
-  virtual void RemoveViewFromParent(
-      Id view_id,
-      const Callback<void(bool)>& callback) override;
-  virtual void ReorderView(Id view_id,
-                           Id relative_view_id,
-                           OrderDirection direction,
-                           const Callback<void(bool)>& callback) override;
-  virtual void GetViewTree(
-      Id view_id,
-      const Callback<void(Array<ViewDataPtr>)>& callback) override;
-  virtual void SetViewSurfaceId(Id view_id,
-                                SurfaceIdPtr surface_id,
-                                const Callback<void(bool)>& callback) override;
-  virtual void SetViewBounds(Id view_id,
-                             RectPtr bounds,
-                             const Callback<void(bool)>& callback) override;
-  virtual void SetViewVisibility(Id view_id,
-                                 bool visible,
-                                 const Callback<void(bool)>& callback) override;
-  virtual void Embed(const String& url,
-                     Id view_id,
-                     ServiceProviderPtr service_provider,
-                     const Callback<void(bool)>& callback) override;
-
-  // InterfaceImpl:
-  virtual void OnConnectionEstablished() override;
-
-  // AccessPolicyDelegate:
-  virtual const base::hash_set<Id>& GetRootsForAccessPolicy() const override;
-  virtual bool IsViewKnownForAccessPolicy(
-      const ServerView* view) const override;
-  virtual bool IsViewRootOfAnotherConnectionForAccessPolicy(
-      const ServerView* view) const override;
-
-  ConnectionManager* connection_manager_;
-
-  // Id of this connection as assigned by ConnectionManager.
-  const ConnectionSpecificId id_;
-
-  // URL this connection was created for.
-  const std::string url_;
-
-  // ID of the connection that created us. If 0 it indicates either we were
-  // created by the root, or the connection that created us has been destroyed.
-  ConnectionSpecificId creator_id_;
-
-  // The URL of the app that embedded the app this connection was created for.
-  const std::string creator_url_;
-
-  scoped_ptr<AccessPolicy> access_policy_;
-
-  // The views and views created by this connection. This connection owns these
-  // objects.
-  ViewMap view_map_;
-
-  // The set of views that has been communicated to the client.
-  ViewIdSet known_views_;
-
-  // Set of root views from other connections. More specifically any time
-  // Embed() is invoked the id of the view is added to this set for the child
-  // connection. The connection Embed() was invoked on (the parent) doesn't
-  // directly track which connections are attached to which of its views. That
-  // information can be found by looking through the |roots_| of all
-  // connections.
-  ViewIdSet roots_;
-
-  // See description above setter.
-  bool delete_on_connection_error_;
-
-  InterfaceRequest<ServiceProvider> service_provider_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerServiceImpl);
-};
-
-#if defined(OS_WIN)
-#pragma warning(pop)
-#endif
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_VIEW_MANAGER_SERVICE_IMPL_H_
diff --git a/mojo/services/view_manager/view_manager_unittest.cc b/mojo/services/view_manager/view_manager_unittest.cc
deleted file mode 100644
index abf874e..0000000
--- a/mojo/services/view_manager/view_manager_unittest.cc
+++ /dev/null
@@ -1,1485 +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 <string>
-#include <vector>
-
-#include "base/at_exit.h"
-#include "base/auto_reset.h"
-#include "base/bind.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/strings/stringprintf.h"
-#include "mojo/application_manager/application_manager.h"
-#include "mojo/common/common_type_converters.h"
-#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/connect.h"
-#include "mojo/public/cpp/application/interface_factory_impl.h"
-#include "mojo/public/cpp/bindings/lib/router.h"
-#include "mojo/public/interfaces/application/service_provider.mojom.h"
-#include "mojo/services/public/cpp/native_viewport/args.h"
-#include "mojo/services/public/cpp/view_manager/types.h"
-#include "mojo/services/public/cpp/view_manager/util.h"
-#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
-#include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h"
-#include "mojo/services/view_manager/ids.h"
-#include "mojo/services/view_manager/test_change_tracker.h"
-#include "mojo/shell/shell_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/rect.h"
-
-#if defined(OS_WIN)
-#include "ui/gfx/win/window_impl.h"
-#endif
-
-namespace mojo {
-namespace service {
-
-namespace {
-
-const char kTestServiceURL[] = "mojo:test_url";
-const char kTestServiceURL2[] = "mojo:test_url2";
-
-// ViewManagerProxy is a proxy to an ViewManagerService. It handles invoking
-// ViewManagerService functions on the right thread in a synchronous manner
-// (each ViewManagerService cover function blocks until the response from the
-// ViewManagerService is returned). In addition it tracks the set of
-// ViewManagerClient messages received by way of a vector of Changes. Use
-// DoRunLoopUntilChangesCount() to wait for a certain number of messages to be
-// received.
-class ViewManagerProxy : public TestChangeTracker::Delegate {
- public:
-  explicit ViewManagerProxy(TestChangeTracker* tracker)
-      : tracker_(tracker),
-        main_loop_(nullptr),
-        view_manager_(nullptr),
-        window_manager_client_(nullptr),
-        quit_count_(0),
-        router_(nullptr) {
-    SetInstance(this);
-  }
-
-  virtual ~ViewManagerProxy() {
-  }
-
-  // Returns true if in an initial state. If this returns false it means the
-  // last test didn't clean up properly, or most likely didn't invoke
-  // WaitForInstance() when it needed to.
-  static bool IsInInitialState() { return instance_ == NULL; }
-
-  // Runs a message loop until the single instance has been created.
-  static ViewManagerProxy* WaitForInstance() {
-    if (!instance_)
-      RunMainLoop();
-    ViewManagerProxy* instance = instance_;
-    instance_ = NULL;
-    return instance;
-  }
-
-  ViewManagerService* view_manager() { return view_manager_; }
-  WindowManagerClient* window_manager_client() {
-    return window_manager_client_;
-  }
-
-  // Runs the main loop until |count| changes have been received.
-  std::vector<Change> DoRunLoopUntilChangesCount(size_t count) {
-    DCHECK_EQ(0u, quit_count_);
-    if (tracker_->changes()->size() >= count) {
-      CopyChangesFromTracker();
-      return changes_;
-    }
-    quit_count_ = count - tracker_->changes()->size();
-    // Run the current message loop. When |count| Changes have been received,
-    // we'll quit.
-    RunMainLoop();
-    return changes_;
-  }
-
-  const std::vector<Change>& changes() const { return changes_; }
-
-  // Destroys the connection, blocking until done.
-  void Destroy() {
-    router_->CloseMessagePipe();
-  }
-
-  void ClearChanges() {
-    changes_.clear();
-    tracker_->changes()->clear();
-  }
-
-  void CopyChangesFromTracker() {
-    std::vector<Change> changes;
-    tracker_->changes()->swap(changes);
-    changes_.swap(changes);
-  }
-
-  // The following functions are cover methods for ViewManagerService. They
-  // block until the result is received.
-  bool CreateView(Id view_id) {
-    changes_.clear();
-    ErrorCode result = ERROR_CODE_NONE;
-    view_manager_->CreateView(
-        view_id,
-        base::Bind(&ViewManagerProxy::GotResultWithErrorCode,
-                   base::Unretained(this),
-                   &result));
-    RunMainLoop();
-    return result == ERROR_CODE_NONE;
-  }
-  ErrorCode CreateViewWithErrorCode(Id view_id) {
-    changes_.clear();
-    ErrorCode result = ERROR_CODE_NONE;
-    view_manager_->CreateView(
-        view_id,
-        base::Bind(&ViewManagerProxy::GotResultWithErrorCode,
-                   base::Unretained(this),
-                   &result));
-    RunMainLoop();
-    return result;
-  }
-  bool AddView(Id parent, Id child) {
-    changes_.clear();
-    bool result = false;
-    view_manager_->AddView(parent, child,
-                           base::Bind(&ViewManagerProxy::GotResult,
-                                      base::Unretained(this), &result));
-    RunMainLoop();
-    return result;
-  }
-  bool RemoveViewFromParent(Id view_id) {
-    changes_.clear();
-    bool result = false;
-    view_manager_->RemoveViewFromParent(
-        view_id,
-        base::Bind(
-            &ViewManagerProxy::GotResult, base::Unretained(this), &result));
-    RunMainLoop();
-    return result;
-  }
-  bool ReorderView(Id view_id, Id relative_view_id, OrderDirection direction) {
-    changes_.clear();
-    bool result = false;
-    view_manager_->ReorderView(
-        view_id,
-        relative_view_id,
-        direction,
-        base::Bind(
-            &ViewManagerProxy::GotResult, base::Unretained(this), &result));
-    RunMainLoop();
-    return result;
-  }
-  void GetViewTree(Id view_id, std::vector<TestView>* views) {
-    changes_.clear();
-    view_manager_->GetViewTree(
-        view_id,
-        base::Bind(
-            &ViewManagerProxy::GotViewTree, base::Unretained(this), views));
-    RunMainLoop();
-  }
-  bool Embed(const Id view_id, const char* url) {
-    changes_.clear();
-    base::AutoReset<bool> auto_reset(&in_embed_, true);
-    bool result = false;
-    ServiceProviderPtr services;
-    view_manager_->Embed(
-        url,
-        view_id,
-        services.Pass(),
-        base::Bind(
-            &ViewManagerProxy::GotResult, base::Unretained(this), &result));
-    RunMainLoop();
-    return result;
-  }
-  bool DeleteView(Id view_id) {
-    changes_.clear();
-    bool result = false;
-    view_manager_->DeleteView(
-        view_id,
-        base::Bind(
-            &ViewManagerProxy::GotResult, base::Unretained(this), &result));
-    RunMainLoop();
-    return result;
-  }
-  bool SetViewBounds(Id view_id, const gfx::Rect& bounds) {
-    changes_.clear();
-    bool result = false;
-    view_manager_->SetViewBounds(
-        view_id,
-        Rect::From(bounds),
-        base::Bind(
-            &ViewManagerProxy::GotResult, base::Unretained(this), &result));
-    RunMainLoop();
-    return result;
-  }
-  bool SetViewVisibility(Id view_id, bool visible) {
-    changes_.clear();
-    bool result = false;
-    view_manager_->SetViewVisibility(
-        view_id,
-        visible,
-        base::Bind(
-            &ViewManagerProxy::GotResult, base::Unretained(this), &result));
-    RunMainLoop();
-    return result;
-  }
-
- private:
-  friend class TestViewManagerClientConnection;
-  friend class WindowManagerServiceImpl;
-
-  void set_router(mojo::internal::Router* router) { router_ = router; }
-
-  void set_view_manager(ViewManagerService* view_manager) {
-    view_manager_ = view_manager;
-  }
-
-  void set_window_manager_client(WindowManagerClient* client) {
-    window_manager_client_ = client;
-  }
-
-  static void RunMainLoop() {
-    DCHECK(!main_run_loop_);
-    main_run_loop_ = new base::RunLoop;
-    main_run_loop_->Run();
-    delete main_run_loop_;
-    main_run_loop_ = NULL;
-  }
-
-  void QuitCountReached() {
-    CopyChangesFromTracker();
-    main_run_loop_->Quit();
-  }
-
-  static void SetInstance(ViewManagerProxy* instance) {
-    DCHECK(!instance_);
-    instance_ = instance;
-    // Embed() runs its own run loop that is quit when the result is
-    // received. Embed() also results in a new instance. If we quit here while
-    // waiting for a Embed() we would prematurely return before we got the
-    // result from Embed().
-    if (!in_embed_ && main_run_loop_)
-      main_run_loop_->Quit();
-  }
-
-  // Callbacks from the various ViewManagerService functions.
-  void GotResult(bool* result_cache, bool result) {
-    *result_cache = result;
-    DCHECK(main_run_loop_);
-    main_run_loop_->Quit();
-  }
-
-  void GotResultWithErrorCode(ErrorCode* error_code_cache,
-                              ErrorCode error_code) {
-    *error_code_cache = error_code;
-    DCHECK(main_run_loop_);
-    main_run_loop_->Quit();
-  }
-
-  void GotViewTree(std::vector<TestView>* views, Array<ViewDataPtr> results) {
-    ViewDatasToTestViews(results, views);
-    DCHECK(main_run_loop_);
-    main_run_loop_->Quit();
-  }
-
-  // TestChangeTracker::Delegate:
-  virtual void OnChangeAdded() override {
-    if (quit_count_ > 0 && --quit_count_ == 0)
-      QuitCountReached();
-  }
-
-  static ViewManagerProxy* instance_;
-  static base::RunLoop* main_run_loop_;
-  static bool in_embed_;
-
-  TestChangeTracker* tracker_;
-
-  // MessageLoop of the test.
-  base::MessageLoop* main_loop_;
-
-  ViewManagerService* view_manager_;
-  WindowManagerClient* window_manager_client_;
-
-  // Number of changes we're waiting on until we quit the current loop.
-  size_t quit_count_;
-
-  std::vector<Change> changes_;
-
-  mojo::internal::Router* router_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerProxy);
-};
-
-// static
-ViewManagerProxy* ViewManagerProxy::instance_ = NULL;
-
-// static
-base::RunLoop* ViewManagerProxy::main_run_loop_ = NULL;
-
-// static
-bool ViewManagerProxy::in_embed_ = false;
-
-class TestViewManagerClientConnection
-    : public InterfaceImpl<ViewManagerClient> {
- public:
-  TestViewManagerClientConnection() : proxy_(&tracker_) {
-    tracker_.set_delegate(&proxy_);
-  }
-
-  TestChangeTracker* tracker() { return &tracker_; }
-
-  ViewManagerProxy* proxy() { return &proxy_; }
-
-  // InterfaceImpl:
-  virtual void OnConnectionEstablished() override {
-    proxy_.set_router(internal_state()->router());
-    proxy_.set_view_manager(client());
-  }
-
-  // ViewManagerClient:
-  virtual void OnEmbed(
-      ConnectionSpecificId connection_id,
-      const String& creator_url,
-      ViewDataPtr root,
-      InterfaceRequest<ServiceProvider> services) override {
-    tracker_.OnEmbed(connection_id, creator_url, root.Pass());
-  }
-  virtual void OnViewBoundsChanged(Id view_id,
-                                   RectPtr old_bounds,
-                                   RectPtr new_bounds) override {
-    tracker_.OnViewBoundsChanged(view_id, old_bounds.Pass(), new_bounds.Pass());
-  }
-  virtual void OnViewHierarchyChanged(Id view,
-                                      Id new_parent,
-                                      Id old_parent,
-                                      Array<ViewDataPtr> views) override {
-    tracker_.OnViewHierarchyChanged(view, new_parent, old_parent, views.Pass());
-  }
-  virtual void OnViewReordered(Id view_id,
-                               Id relative_view_id,
-                               OrderDirection direction) override {
-    tracker_.OnViewReordered(view_id, relative_view_id, direction);
-  }
-  virtual void OnViewDeleted(Id view) override { tracker_.OnViewDeleted(view); }
-  virtual void OnViewVisibilityChanged(uint32_t view, bool visible) override {
-    tracker_.OnViewVisibilityChanged(view, visible);
-  }
-  virtual void OnViewDrawnStateChanged(uint32_t view, bool drawn) override {
-    tracker_.OnViewDrawnStateChanged(view, drawn);
-  }
-  virtual void OnViewInputEvent(Id view_id,
-                                EventPtr event,
-                                const Callback<void()>& callback) override {
-    tracker_.OnViewInputEvent(view_id, event.Pass());
-  }
-
- private:
-  TestChangeTracker tracker_;
-  ViewManagerProxy proxy_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestViewManagerClientConnection);
-};
-
-class WindowManagerServiceImpl : public InterfaceImpl<WindowManagerService> {
- public:
-  explicit WindowManagerServiceImpl(TestViewManagerClientConnection* connection)
-      : connection_(connection) {}
-  virtual ~WindowManagerServiceImpl() {}
-
-  // InterfaceImpl:
-  virtual void OnConnectionEstablished() override {
-    connection_->proxy()->set_window_manager_client(client());
-  }
-
-  // WindowManagerService:
-  virtual void Embed(
-      const String& url,
-      InterfaceRequest<ServiceProvider> service_provider) override {
-    connection_->tracker()->DelegateEmbed(url);
-  }
-  virtual void OnViewInputEvent(mojo::EventPtr event) override {}
-
- private:
-  TestViewManagerClientConnection* connection_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerServiceImpl);
-};
-
-// Used with ViewManagerService::Embed(). Creates a
-// TestViewManagerClientConnection, which creates and owns the ViewManagerProxy.
-class EmbedApplicationLoader : public ApplicationLoader,
-                               ApplicationDelegate,
-                               public InterfaceFactory<ViewManagerClient>,
-                               public InterfaceFactory<WindowManagerService> {
- public:
-  EmbedApplicationLoader() : last_view_manager_client_(nullptr) {}
-  virtual ~EmbedApplicationLoader() {}
-
-  // ApplicationLoader implementation:
-  virtual void Load(ApplicationManager* manager,
-                    const GURL& url,
-                    scoped_refptr<LoadCallbacks> callbacks) override {
-    ScopedMessagePipeHandle shell_handle = callbacks->RegisterApplication();
-    if (!shell_handle.is_valid())
-      return;
-    scoped_ptr<ApplicationImpl> app(new ApplicationImpl(this,
-                                                        shell_handle.Pass()));
-    apps_.push_back(app.release());
-  }
-  virtual void OnApplicationError(ApplicationManager* manager,
-                                  const GURL& url) override {}
-
-  // ApplicationDelegate implementation:
-  virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
-      override {
-    connection->AddService<ViewManagerClient>(this);
-    connection->AddService<WindowManagerService>(this);
-    return true;
-  }
-
-  // InterfaceFactory<ViewManagerClient> implementation:
-  virtual void Create(ApplicationConnection* connection,
-                      InterfaceRequest<ViewManagerClient> request) override {
-    last_view_manager_client_ = new TestViewManagerClientConnection;
-    BindToRequest(last_view_manager_client_, &request);
-  }
-  virtual void Create(ApplicationConnection* connection,
-                      InterfaceRequest<WindowManagerService> request) override {
-    BindToRequest(new WindowManagerServiceImpl(last_view_manager_client_),
-                  &request);
-  }
-
- private:
-  // Used so that TestViewManagerClientConnection and
-  // WindowManagerServiceImpl can share the same TestChangeTracker.
-  TestViewManagerClientConnection* last_view_manager_client_;
-  ScopedVector<ApplicationImpl> apps_;
-
-  DISALLOW_COPY_AND_ASSIGN(EmbedApplicationLoader);
-};
-
-// Creates an id used for transport from the specified parameters.
-Id BuildViewId(ConnectionSpecificId connection_id,
-               ConnectionSpecificId view_id) {
-  return (connection_id << 16) | view_id;
-}
-
-// Callback from Embed(). |result| is the result of the
-// Embed() call and |run_loop| the nested RunLoop.
-void EmbedCallback(bool* result_cache, base::RunLoop* run_loop, bool result) {
-  *result_cache = result;
-  run_loop->Quit();
-}
-
-// Embed from an application that does not yet have a view manager connection.
-// Blocks until result is determined.
-bool InitEmbed(ViewManagerInitService* view_manager_init,
-               const std::string& url,
-               size_t number_of_calls) {
-  bool result = false;
-  base::RunLoop run_loop;
-  for (size_t i = 0; i < number_of_calls; ++i) {
-    ServiceProviderPtr sp;
-    view_manager_init->Embed(url, sp.Pass(),
-                             base::Bind(&EmbedCallback, &result, &run_loop));
-  }
-  run_loop.Run();
-  return result;
-}
-
-}  // namespace
-
-typedef std::vector<std::string> Changes;
-
-class ViewManagerTest : public testing::Test {
- public:
-  ViewManagerTest()
-      : connection_(NULL),
-        connection2_(NULL),
-        connection3_(NULL) {}
-
-  virtual void SetUp() override {
-    ASSERT_TRUE(ViewManagerProxy::IsInInitialState());
-    test_helper_.Init();
-    std::vector<std::string> native_viewport_args;
-    native_viewport_args.push_back(kUseTestConfig);
-    test_helper_.application_manager()->SetArgsForURL(
-        native_viewport_args, GURL("mojo:native_viewport_service"));
-    printf("Setting args\n");
-
-#if defined(OS_WIN)
-    // As we unload the wndproc of window classes we need to be sure to
-    // unregister them.
-    gfx::WindowImpl::UnregisterClassesAtExit();
-#endif
-
-    test_helper_.SetLoaderForURL(
-        scoped_ptr<ApplicationLoader>(new EmbedApplicationLoader()),
-        GURL(kTestServiceURL));
-
-    test_helper_.SetLoaderForURL(
-        scoped_ptr<ApplicationLoader>(new EmbedApplicationLoader()),
-        GURL(kTestServiceURL2));
-
-    test_helper_.application_manager()->ConnectToService(
-        GURL("mojo:view_manager"), &view_manager_init_);
-    ASSERT_TRUE(InitEmbed(view_manager_init_.get(), kTestServiceURL, 1));
-
-    connection_ = ViewManagerProxy::WaitForInstance();
-    ASSERT_TRUE(connection_ != NULL);
-    connection_->DoRunLoopUntilChangesCount(1);
-  }
-
-  virtual void TearDown() override {
-    if (connection3_)
-      connection3_->Destroy();
-    if (connection2_)
-      connection2_->Destroy();
-    if (connection_)
-      connection_->Destroy();
-  }
-
- protected:
-  void EstablishSecondConnectionWithRoot(Id root_id) {
-    ASSERT_TRUE(connection_->Embed(root_id, kTestServiceURL));
-    connection2_ = ViewManagerProxy::WaitForInstance();
-    ASSERT_TRUE(connection2_ != NULL);
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-  }
-
-  // Creates a second connection to the viewmanager.
-  void EstablishSecondConnection(bool create_initial_view) {
-    if (create_initial_view)
-      ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-    ASSERT_NO_FATAL_FAILURE(
-        EstablishSecondConnectionWithRoot(BuildViewId(1, 1)));
-    const std::vector<Change>& changes(connection2_->changes());
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("OnEmbed creator=mojo:test_url",
-              ChangesToDescription1(changes)[0]);
-    if (create_initial_view)
-      EXPECT_EQ("[view=1,1 parent=null]", ChangeViewDescription(changes));
-  }
-
-  void EstablishThirdConnection(ViewManagerProxy* owner, Id root_id) {
-    ASSERT_TRUE(connection3_ == NULL);
-    ASSERT_TRUE(owner->Embed(root_id, kTestServiceURL2));
-    connection3_ = ViewManagerProxy::WaitForInstance();
-    ASSERT_TRUE(connection3_ != NULL);
-    connection3_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection3_->changes().size());
-    EXPECT_EQ("OnEmbed creator=mojo:test_url",
-              ChangesToDescription1(connection3_->changes())[0]);
-  }
-
-  void DestroySecondConnection() {
-    connection2_->Destroy();
-    connection2_ = NULL;
-  }
-
-  base::ShadowingAtExitManager at_exit_;
-  shell::ShellTestHelper test_helper_;
-
-  ViewManagerInitServicePtr view_manager_init_;
-
-  // NOTE: this connection is the root. As such, it has special permissions.
-  ViewManagerProxy* connection_;
-  ViewManagerProxy* connection2_;
-  ViewManagerProxy* connection3_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerTest);
-};
-
-TEST_F(ViewManagerTest, SecondEmbedRoot_InitService) {
-  ASSERT_TRUE(InitEmbed(view_manager_init_.get(), kTestServiceURL, 1));
-  connection_->DoRunLoopUntilChangesCount(1);
-  EXPECT_EQ(kTestServiceURL, connection_->changes()[0].embed_url);
-}
-
-TEST_F(ViewManagerTest, SecondEmbedRoot_Service) {
-  ASSERT_TRUE(connection_->Embed(BuildViewId(0, 0), kTestServiceURL));
-  connection_->DoRunLoopUntilChangesCount(1);
-  EXPECT_EQ(kTestServiceURL, connection_->changes()[0].embed_url);
-}
-
-TEST_F(ViewManagerTest, MultipleEmbedRootsBeforeWTHReady) {
-  ASSERT_TRUE(InitEmbed(view_manager_init_.get(), kTestServiceURL, 2));
-  connection_->DoRunLoopUntilChangesCount(2);
-  EXPECT_EQ(kTestServiceURL, connection_->changes()[0].embed_url);
-  EXPECT_EQ(kTestServiceURL, connection_->changes()[1].embed_url);
-}
-
-// Verifies client gets a valid id.
-// http://crbug.com/396492
-TEST_F(ViewManagerTest, DISABLED_ValidId) {
-  // TODO(beng): this should really have the URL of the application that
-  //             connected to ViewManagerInit.
-  EXPECT_EQ("OnEmbed creator=",
-            ChangesToDescription1(connection_->changes())[0]);
-
-  // All these tests assume 1 for the client id. The only real assertion here is
-  // the client id is not zero, but adding this as rest of code here assumes 1.
-  EXPECT_EQ(1, connection_->changes()[0].connection_id);
-}
-
-// Verifies two clients/connections get different ids.
-TEST_F(ViewManagerTest, TwoClientsGetDifferentConnectionIds) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-  EXPECT_EQ("OnEmbed creator=mojo:test_url",
-            ChangesToDescription1(connection2_->changes())[0]);
-
-  // It isn't strictly necessary that the second connection gets 2, but these
-  // tests are written assuming that is the case. The key thing is the
-  // connection ids of |connection_| and |connection2_| differ.
-  EXPECT_EQ(2, connection2_->changes()[0].connection_id);
-}
-
-// Verifies when Embed() is invoked any child views are removed.
-TEST_F(ViewManagerTest, ViewsRemovedWhenEmbedding) {
-  // Two views 1 and 2. 2 is parented to 1.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 2)));
-
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-  EXPECT_EQ("[view=1,1 parent=null]",
-            ChangeViewDescription(connection2_->changes()));
-
-  // Embed() removed view 2.
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(1, 2), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=1,2 parent=null", views[0].ToString());
-  }
-
-  // |connection2_| should not see view 2.
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(1, 1), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=1,1 parent=null", views[0].ToString());
-  }
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(1, 2), &views);
-    EXPECT_TRUE(views.empty());
-  }
-
-  // Views 3 and 4 in connection 2.
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 3)));
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 4)));
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(2, 3), BuildViewId(2, 4)));
-
-  // Connection 3 rooted at 2.
-  ASSERT_NO_FATAL_FAILURE(
-      EstablishThirdConnection(connection2_, BuildViewId(2, 3)));
-
-  // View 4 should no longer have a parent.
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(2, 3), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=2,3 parent=null", views[0].ToString());
-
-    views.clear();
-    connection2_->GetViewTree(BuildViewId(2, 4), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=2,4 parent=null", views[0].ToString());
-  }
-
-  // And view 4 should not be visible to connection 3.
-  {
-    std::vector<TestView> views;
-    connection3_->GetViewTree(BuildViewId(2, 3), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=2,3 parent=null", views[0].ToString());
-  }
-}
-
-// Verifies once Embed() has been invoked the parent connection can't see any
-// children.
-TEST_F(ViewManagerTest, CantAccessChildrenOfEmbeddedView) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2)));
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2)));
-
-  ASSERT_NO_FATAL_FAILURE(
-      EstablishThirdConnection(connection2_, BuildViewId(2, 2)));
-
-  ASSERT_TRUE(connection3_->CreateView(BuildViewId(3, 3)));
-  ASSERT_TRUE(connection3_->AddView(BuildViewId(2, 2), BuildViewId(3, 3)));
-
-  // Even though 3 is a child of 2 connection 2 can't see 3 as it's from a
-  // different connection.
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(2, 2), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=2,2 parent=1,1", views[0].ToString());
-  }
-
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(3, 3), &views);
-    EXPECT_TRUE(views.empty());
-  }
-
-  // Connection 2 shouldn't be able to get view 3 at all.
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(3, 3), &views);
-    EXPECT_TRUE(views.empty());
-  }
-
-  // Connection 1 should be able to see it all (its the root).
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(1, 1), &views);
-    ASSERT_EQ(3u, views.size());
-    EXPECT_EQ("view=1,1 parent=null", views[0].ToString());
-    EXPECT_EQ("view=2,2 parent=1,1", views[1].ToString());
-    EXPECT_EQ("view=3,3 parent=2,2", views[2].ToString());
-  }
-}
-
-// Verifies once Embed() has been invoked the parent can't mutate the children.
-TEST_F(ViewManagerTest, CantModifyChildrenOfEmbeddedView) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2)));
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2)));
-
-  ASSERT_NO_FATAL_FAILURE(
-      EstablishThirdConnection(connection2_, BuildViewId(2, 2)));
-
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 3)));
-  // Connection 2 shouldn't be able to add anything to the view anymore.
-  ASSERT_FALSE(connection2_->AddView(BuildViewId(2, 2), BuildViewId(2, 3)));
-
-  // Create view 3 in connection 3 and add it to view 3.
-  ASSERT_TRUE(connection3_->CreateView(BuildViewId(3, 3)));
-  ASSERT_TRUE(connection3_->AddView(BuildViewId(2, 2), BuildViewId(3, 3)));
-
-  // Connection 2 shouldn't be able to remove view 3.
-  ASSERT_FALSE(connection2_->RemoveViewFromParent(BuildViewId(3, 3)));
-}
-
-// Verifies client gets a valid id.
-TEST_F(ViewManagerTest, CreateView) {
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  EXPECT_TRUE(connection_->changes().empty());
-
-  // Can't create a view with the same id.
-  ASSERT_EQ(ERROR_CODE_VALUE_IN_USE,
-            connection_->CreateViewWithErrorCode(BuildViewId(1, 1)));
-  EXPECT_TRUE(connection_->changes().empty());
-
-  // Can't create a view with a bogus connection id.
-  EXPECT_EQ(ERROR_CODE_ILLEGAL_ARGUMENT,
-            connection_->CreateViewWithErrorCode(BuildViewId(2, 1)));
-  EXPECT_TRUE(connection_->changes().empty());
-}
-
-// Verifies AddView fails when view is already in position.
-TEST_F(ViewManagerTest, AddViewWithNoChange) {
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 3)));
-
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  // Make 3 a child of 2.
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 2), BuildViewId(1, 3)));
-
-  // Try again, this should fail.
-  EXPECT_FALSE(connection_->AddView(BuildViewId(1, 2), BuildViewId(1, 3)));
-}
-
-// Verifies AddView fails when view is already in position.
-TEST_F(ViewManagerTest, AddAncestorFails) {
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 3)));
-
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  // Make 3 a child of 2.
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 2), BuildViewId(1, 3)));
-
-  // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3.
-  EXPECT_FALSE(connection_->AddView(BuildViewId(1, 3), BuildViewId(1, 2)));
-}
-
-// Verifies adding to root sends right notifications.
-TEST_F(ViewManagerTest, AddToRoot) {
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 21)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 3)));
-
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  // Make 3 a child of 21.
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 21), BuildViewId(1, 3)));
-
-  // Make 21 a child of 1.
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 21)));
-
-  // Connection 2 should not be told anything (because the view is from a
-  // different connection). Create a view to ensure we got a response from
-  // the server.
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 100)));
-  connection2_->CopyChangesFromTracker();
-  EXPECT_TRUE(connection2_->changes().empty());
-}
-
-// Verifies HierarchyChanged is correctly sent for various adds/removes.
-TEST_F(ViewManagerTest, ViewHierarchyChangedViews) {
-  // 1,2->1,11.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 2), BuildViewId(1, 11)));
-
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  // 1,1->1,2->1,11
-  {
-    // Client 2 should not get anything (1,2 is from another connection).
-    connection2_->ClearChanges();
-    ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 2)));
-    ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 100)));
-    connection2_->CopyChangesFromTracker();
-    EXPECT_TRUE(connection2_->changes().empty());
-  }
-
-  // 0,1->1,1->1,2->1,11.
-  {
-    // Client 2 is now connected to the root, so it should have gotten a drawn
-    // notification.
-    ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-    EXPECT_EQ("DrawnStateChanged view=1,1 drawn=true",
-              ChangesToDescription1(connection2_->changes())[0]);
-  }
-
-  // 1,1->1,2->1,11.
-  {
-    // Client 2 is no longer connected to the root, should get drawn state
-    // changed.
-    ASSERT_TRUE(connection_->RemoveViewFromParent(BuildViewId(1, 1)));
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-    EXPECT_EQ("DrawnStateChanged view=1,1 drawn=false",
-              ChangesToDescription1(connection2_->changes())[0]);
-  }
-
-  // 1,1->1,2->1,11->1,111.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 111)));
-  {
-    connection2_->ClearChanges();
-    ASSERT_TRUE(connection_->AddView(BuildViewId(1, 11), BuildViewId(1, 111)));
-    ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 103)));
-    connection2_->CopyChangesFromTracker();
-    EXPECT_TRUE(connection2_->changes().empty());
-  }
-
-  // 0,1->1,1->1,2->1,11->1,111
-  {
-    connection2_->ClearChanges();
-    ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-    EXPECT_EQ("DrawnStateChanged view=1,1 drawn=true",
-              ChangesToDescription1(connection2_->changes())[0]);
-  }
-}
-
-TEST_F(ViewManagerTest, ViewHierarchyChangedAddingKnownToUnknown) {
-  // Create the following structure: root -> 1 -> 11 and 2->21 (2 has no
-  // parent).
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 11)));
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2)));
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 21)));
-
-  // Set up the hierarchy.
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 11)));
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(2, 2), BuildViewId(2, 21)));
-
-  // Remove 11, should result in a hierarchy change for the root.
-  {
-    connection_->ClearChanges();
-    ASSERT_TRUE(connection2_->RemoveViewFromParent(BuildViewId(2, 11)));
-
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("HierarchyChanged view=2,11 new_parent=null old_parent=1,1",
-              changes[0]);
-  }
-
-  // Add 2 to 1.
-  {
-    ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2)));
-
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("HierarchyChanged view=2,2 new_parent=1,1 old_parent=null",
-              changes[0]);
-    EXPECT_EQ(
-        "[view=2,2 parent=1,1],"
-        "[view=2,21 parent=2,2]",
-        ChangeViewDescription(connection_->changes()));
-  }
-}
-
-TEST_F(ViewManagerTest, ReorderView) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  Id view1_id = BuildViewId(2, 1);
-  Id view2_id = BuildViewId(2, 2);
-  Id view3_id = BuildViewId(2, 3);
-  Id view4_id = BuildViewId(1, 4);  // Peer to 1,1
-  Id view5_id = BuildViewId(1, 5);  // Peer to 1,1
-  Id view6_id = BuildViewId(2, 6);  // Child of 1,2.
-  Id view7_id = BuildViewId(2, 7);  // Unparented.
-  Id view8_id = BuildViewId(2, 8);  // Unparented.
-  ASSERT_TRUE(connection2_->CreateView(view1_id));
-  ASSERT_TRUE(connection2_->CreateView(view2_id));
-  ASSERT_TRUE(connection2_->CreateView(view3_id));
-  ASSERT_TRUE(connection_->CreateView(view4_id));
-  ASSERT_TRUE(connection_->CreateView(view5_id));
-  ASSERT_TRUE(connection2_->CreateView(view6_id));
-  ASSERT_TRUE(connection2_->CreateView(view7_id));
-  ASSERT_TRUE(connection2_->CreateView(view8_id));
-  ASSERT_TRUE(connection2_->AddView(view1_id, view2_id));
-  ASSERT_TRUE(connection2_->AddView(view2_id, view6_id));
-  ASSERT_TRUE(connection2_->AddView(view1_id, view3_id));
-  ASSERT_TRUE(
-      connection_->AddView(ViewIdToTransportId(RootViewId()), view4_id));
-  ASSERT_TRUE(
-      connection_->AddView(ViewIdToTransportId(RootViewId()), view5_id));
-
-  ASSERT_TRUE(
-      connection_->AddView(ViewIdToTransportId(RootViewId()), view1_id));
-
-  {
-    ASSERT_TRUE(
-        connection2_->ReorderView(view2_id, view3_id, ORDER_DIRECTION_ABOVE));
-
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("Reordered view=2,2 relative=2,3 direction=above", changes[0]);
-  }
-
-  {
-    ASSERT_TRUE(
-        connection2_->ReorderView(view2_id, view3_id, ORDER_DIRECTION_BELOW));
-
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("Reordered view=2,2 relative=2,3 direction=below", changes[0]);
-  }
-
-  // view2 is already below view3.
-  EXPECT_FALSE(
-      connection2_->ReorderView(view2_id, view3_id, ORDER_DIRECTION_BELOW));
-
-  // view4 & 5 are unknown to connection2_.
-  EXPECT_FALSE(
-      connection2_->ReorderView(view4_id, view5_id, ORDER_DIRECTION_ABOVE));
-
-  // view6 & view3 have different parents.
-  EXPECT_FALSE(
-      connection_->ReorderView(view3_id, view6_id, ORDER_DIRECTION_ABOVE));
-
-  // Non-existent view-ids
-  EXPECT_FALSE(connection_->ReorderView(
-      BuildViewId(1, 27), BuildViewId(1, 28), ORDER_DIRECTION_ABOVE));
-
-  // view7 & view8 are un-parented.
-  EXPECT_FALSE(
-      connection_->ReorderView(view7_id, view8_id, ORDER_DIRECTION_ABOVE));
-}
-
-// Verifies DeleteView works.
-TEST_F(ViewManagerTest, DeleteView) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2)));
-
-  // Make 2 a child of 1.
-  {
-    ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2)));
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("HierarchyChanged view=2,2 new_parent=1,1 old_parent=null",
-              changes[0]);
-  }
-
-  // Delete 2.
-  {
-    ASSERT_TRUE(connection2_->DeleteView(BuildViewId(2, 2)));
-    EXPECT_TRUE(connection2_->changes().empty());
-
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("ViewDeleted view=2,2", changes[0]);
-  }
-}
-
-// Verifies DeleteView isn't allowed from a separate connection.
-TEST_F(ViewManagerTest, DeleteViewFromAnotherConnectionDisallowed) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-  EXPECT_FALSE(connection2_->DeleteView(BuildViewId(1, 1)));
-}
-
-// Verifies if a view was deleted and then reused that other clients are
-// properly notified.
-TEST_F(ViewManagerTest, ReuseDeletedViewId) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2)));
-
-  // Add 2 to 1.
-  {
-    ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2)));
-
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    EXPECT_EQ("HierarchyChanged view=2,2 new_parent=1,1 old_parent=null",
-              changes[0]);
-    EXPECT_EQ("[view=2,2 parent=1,1]",
-              ChangeViewDescription(connection_->changes()));
-  }
-
-  // Delete 2.
-  {
-    ASSERT_TRUE(connection2_->DeleteView(BuildViewId(2, 2)));
-
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("ViewDeleted view=2,2", changes[0]);
-  }
-
-  // Create 2 again, and add it back to 1. Should get the same notification.
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2)));
-  {
-    ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2)));
-
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    EXPECT_EQ("HierarchyChanged view=2,2 new_parent=1,1 old_parent=null",
-              changes[0]);
-    EXPECT_EQ("[view=2,2 parent=1,1]",
-              ChangeViewDescription(connection_->changes()));
-  }
-}
-
-// Assertions for GetViewTree.
-TEST_F(ViewManagerTest, GetViewTree) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  // Create 11 in first connection and make it a child of 1.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 11)));
-
-  // Create two views in second connection, 2 and 3, both children of 1.
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2)));
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 3)));
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2)));
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 3)));
-
-  // Verifies GetViewTree() on the root. The root connection sees all.
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(0, 1), &views);
-    ASSERT_EQ(5u, views.size());
-    EXPECT_EQ("view=0,1 parent=null", views[0].ToString());
-    EXPECT_EQ("view=1,1 parent=0,1", views[1].ToString());
-    EXPECT_EQ("view=1,11 parent=1,1", views[2].ToString());
-    EXPECT_EQ("view=2,2 parent=1,1", views[3].ToString());
-    EXPECT_EQ("view=2,3 parent=1,1", views[4].ToString());
-  }
-
-  // Verifies GetViewTree() on the view 1,1. This does not include any children
-  // as they are not from this connection.
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(1, 1), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=1,1 parent=null", views[0].ToString());
-  }
-
-  // Connection 2 shouldn't be able to get the root tree.
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(0, 1), &views);
-    ASSERT_EQ(0u, views.size());
-  }
-}
-
-TEST_F(ViewManagerTest, SetViewBounds) {
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-
-  ASSERT_TRUE(
-      connection_->SetViewBounds(BuildViewId(1, 1), gfx::Rect(0, 0, 100, 100)));
-
-  connection2_->DoRunLoopUntilChangesCount(1);
-  const Changes changes(ChangesToDescription1(connection2_->changes()));
-  ASSERT_EQ(1u, changes.size());
-  EXPECT_EQ("BoundsChanged view=1,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100",
-            changes[0]);
-
-  // Should not be possible to change the bounds of a view created by another
-  // connection.
-  ASSERT_FALSE(
-      connection2_->SetViewBounds(BuildViewId(1, 1), gfx::Rect(0, 0, 0, 0)));
-}
-
-// Verify AddView fails when trying to manipulate views in other roots.
-TEST_F(ViewManagerTest, CantMoveViewsFromOtherRoot) {
-  // Create 1 and 2 in the first connection.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-
-  // Try to move 2 to be a child of 1 from connection 2. This should fail as 2
-  // should not be able to access 1.
-  ASSERT_FALSE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(1, 2)));
-
-  // Try to reparent 1 to the root. A connection is not allowed to reparent its
-  // roots.
-  ASSERT_FALSE(connection2_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-}
-
-// Verify RemoveViewFromParent fails for views that are descendants of the
-// roots.
-TEST_F(ViewManagerTest, CantRemoveViewsInOtherRoots) {
-  // Create 1 and 2 in the first connection and parent both to the root.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 2)));
-
-  // Establish the second connection and give it the root 1.
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-
-  // Connection 2 should not be able to remove view 2 or 1 from its parent.
-  ASSERT_FALSE(connection2_->RemoveViewFromParent(BuildViewId(1, 2)));
-  ASSERT_FALSE(connection2_->RemoveViewFromParent(BuildViewId(1, 1)));
-
-  // Create views 10 and 11 in 2.
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 10)));
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 11)));
-
-  // Parent 11 to 10.
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(2, 10), BuildViewId(2, 11)));
-  // Remove 11 from 10.
-  ASSERT_TRUE(connection2_->RemoveViewFromParent(BuildViewId(2, 11)));
-
-  // Verify nothing was actually removed.
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(0, 1), &views);
-    ASSERT_EQ(3u, views.size());
-    EXPECT_EQ("view=0,1 parent=null", views[0].ToString());
-    EXPECT_EQ("view=1,1 parent=0,1", views[1].ToString());
-    EXPECT_EQ("view=1,2 parent=0,1", views[2].ToString());
-  }
-}
-
-// Verify GetViewTree fails for views that are not descendants of the roots.
-TEST_F(ViewManagerTest, CantGetViewTreeOfOtherRoots) {
-  // Create 1 and 2 in the first connection and parent both to the root.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 2)));
-
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-
-  std::vector<TestView> views;
-
-  // Should get nothing for the root.
-  connection2_->GetViewTree(BuildViewId(0, 1), &views);
-  ASSERT_TRUE(views.empty());
-
-  // Should get nothing for view 2.
-  connection2_->GetViewTree(BuildViewId(1, 2), &views);
-  ASSERT_TRUE(views.empty());
-
-  // Should get view 1 if asked for.
-  connection2_->GetViewTree(BuildViewId(1, 1), &views);
-  ASSERT_EQ(1u, views.size());
-  EXPECT_EQ("view=1,1 parent=null", views[0].ToString());
-}
-
-TEST_F(ViewManagerTest, OnViewInput) {
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false));
-
-  // Dispatch an event to the view and verify its received.
-  {
-    EventPtr event(Event::New());
-    event->action = static_cast<EventType>(1);
-    connection_->window_manager_client()->DispatchInputEventToView(
-        BuildViewId(1, 1), event.Pass());
-    connection2_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection2_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("InputEvent view=1,1 event_action=1", changes[0]);
-  }
-}
-
-TEST_F(ViewManagerTest, EmbedWithSameViewId) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  ASSERT_NO_FATAL_FAILURE(
-      EstablishThirdConnection(connection_, BuildViewId(1, 1)));
-
-  // Connection2 should have been told the view was deleted.
-  {
-    connection2_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection2_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("ViewDeleted view=1,1", changes[0]);
-  }
-
-  // Connection2 has no root. Verify it can't see view 1,1 anymore.
-  {
-    std::vector<TestView> views;
-    connection2_->GetViewTree(BuildViewId(1, 1), &views);
-    EXPECT_TRUE(views.empty());
-  }
-}
-
-TEST_F(ViewManagerTest, EmbedWithSameViewId2) {
-  ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true));
-
-  ASSERT_NO_FATAL_FAILURE(
-      EstablishThirdConnection(connection_, BuildViewId(1, 1)));
-
-  // Connection2 should have been told the view was deleted.
-  connection2_->DoRunLoopUntilChangesCount(1);
-  connection2_->ClearChanges();
-
-  // Create a view in the third connection and parent it to the root.
-  ASSERT_TRUE(connection3_->CreateView(BuildViewId(3, 1)));
-  ASSERT_TRUE(connection3_->AddView(BuildViewId(1, 1), BuildViewId(3, 1)));
-
-  // Connection 1 should have been told about the add (it owns the view).
-  {
-    connection_->DoRunLoopUntilChangesCount(1);
-    const Changes changes(ChangesToDescription1(connection_->changes()));
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("HierarchyChanged view=3,1 new_parent=1,1 old_parent=null",
-              changes[0]);
-  }
-
-  // Embed 1,1 again.
-  {
-    // We should get a new connection for the new embedding.
-    ASSERT_TRUE(connection_->Embed(BuildViewId(1, 1), kTestServiceURL));
-    ViewManagerProxy* connection4 = ViewManagerProxy::WaitForInstance();
-    connection4->DoRunLoopUntilChangesCount(1);
-    const std::vector<Change>& changes(connection4->changes());
-    ASSERT_EQ(1u, changes.size());
-    EXPECT_EQ("OnEmbed creator=mojo:test_url",
-              ChangesToDescription1(changes)[0]);
-    EXPECT_EQ("[view=1,1 parent=null]", ChangeViewDescription(changes));
-
-    // And 3 should get a delete.
-    connection3_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection3_->changes().size());
-    EXPECT_EQ("ViewDeleted view=1,1",
-              ChangesToDescription1(connection3_->changes())[0]);
-  }
-
-  // Connection3_ has no root. Verify it can't see view 1,1 anymore.
-  {
-    std::vector<TestView> views;
-    connection3_->GetViewTree(BuildViewId(1, 1), &views);
-    EXPECT_TRUE(views.empty());
-  }
-
-  // Verify 3,1 is no longer parented to 1,1. We have to do this from 1,1 as
-  // connection3_ can no longer see 1,1.
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(1, 1), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=1,1 parent=null", views[0].ToString());
-  }
-
-  // Verify connection3_ can still see the view it created 3,1.
-  {
-    std::vector<TestView> views;
-    connection3_->GetViewTree(BuildViewId(3, 1), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=3,1 parent=null", views[0].ToString());
-  }
-}
-
-// Assertions for SetViewVisibility.
-TEST_F(ViewManagerTest, SetViewVisibility) {
-  // Create 1 and 2 in the first connection and parent both to the root.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(0, 1), &views);
-    ASSERT_EQ(2u, views.size());
-    EXPECT_EQ("view=0,1 parent=null visible=true drawn=true",
-              views[0].ToString2());
-    EXPECT_EQ("view=1,1 parent=0,1 visible=true drawn=true",
-              views[1].ToString2());
-  }
-
-  // Hide 1.
-  ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), false));
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(1, 1), &views);
-    ASSERT_EQ(1u, views.size());
-    EXPECT_EQ("view=1,1 parent=0,1 visible=false drawn=false",
-              views[0].ToString2());
-  }
-
-  // Attach 2 to 1.
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 2)));
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(1, 1), &views);
-    ASSERT_EQ(2u, views.size());
-    EXPECT_EQ("view=1,1 parent=0,1 visible=false drawn=false",
-              views[0].ToString2());
-    EXPECT_EQ("view=1,2 parent=1,1 visible=true drawn=false",
-              views[1].ToString2());
-  }
-
-  // Show 1.
-  ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), true));
-  {
-    std::vector<TestView> views;
-    connection_->GetViewTree(BuildViewId(1, 1), &views);
-    ASSERT_EQ(2u, views.size());
-    EXPECT_EQ("view=1,1 parent=0,1 visible=true drawn=true",
-              views[0].ToString2());
-    EXPECT_EQ("view=1,2 parent=1,1 visible=true drawn=true",
-              views[1].ToString2());
-  }
-}
-
-// Assertions for SetViewVisibility sending notifications.
-TEST_F(ViewManagerTest, SetViewVisibilityNotifications) {
-  // Create 1,1 and 1,2, 1,2 and child of 1,1 and 1,1 a child of the root.
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-  ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 2)));
-
-  // Establish the second connection at 1,2.
-  ASSERT_NO_FATAL_FAILURE(
-      EstablishSecondConnectionWithRoot(BuildViewId(1, 2)));
-
-  // Add 2,3 as a child of 1,2.
-  ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 3)));
-  connection_->ClearChanges();
-  ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 2), BuildViewId(2, 3)));
-  connection_->DoRunLoopUntilChangesCount(1);
-
-  // Hide 1,2 from connection 1. Connection 2 should see this.
-  ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 2), false));
-  {
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-    EXPECT_EQ("VisibilityChanged view=1,2 visible=false",
-              ChangesToDescription1(connection2_->changes())[0]);
-  }
-
-  // Show 1,2 from connection 2, connection 1 should be notified.
-  ASSERT_TRUE(connection2_->SetViewVisibility(BuildViewId(1, 2), true));
-  {
-    connection_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection_->changes().size());
-    EXPECT_EQ("VisibilityChanged view=1,2 visible=true",
-              ChangesToDescription1(connection_->changes())[0]);
-  }
-
-  // Hide 1,1, connection 2 should be told the draw state changed.
-  ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), false));
-  {
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-    EXPECT_EQ("DrawnStateChanged view=1,2 drawn=false",
-              ChangesToDescription1(connection2_->changes())[0]);
-  }
-
-  // Show 1,1 from connection 1. Connection 2 should see this.
-  ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), true));
-  {
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-    EXPECT_EQ("DrawnStateChanged view=1,2 drawn=true",
-              ChangesToDescription1(connection2_->changes())[0]);
-  }
-
-  // Change visibility of 2,3, connection 1 should see this.
-  connection_->ClearChanges();
-  ASSERT_TRUE(connection2_->SetViewVisibility(BuildViewId(2, 3), false));
-  {
-    connection_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection_->changes().size());
-    EXPECT_EQ("VisibilityChanged view=2,3 visible=false",
-              ChangesToDescription1(connection_->changes())[0]);
-  }
-
-  // Remove 1,1 from the root, connection 2 should see drawn state changed.
-  ASSERT_TRUE(connection_->RemoveViewFromParent(BuildViewId(1, 1)));
-  {
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-    EXPECT_EQ("DrawnStateChanged view=1,2 drawn=false",
-              ChangesToDescription1(connection2_->changes())[0]);
-  }
-
-  // Add 1,1 back to the root, connection 2 should see drawn state changed.
-  ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1)));
-  {
-    connection2_->DoRunLoopUntilChangesCount(1);
-    ASSERT_EQ(1u, connection2_->changes().size());
-    EXPECT_EQ("DrawnStateChanged view=1,2 drawn=true",
-              ChangesToDescription1(connection2_->changes())[0]);
-  }
-}
-
-// TODO(sky): add coverage of test that destroys connections and ensures other
-// connections get deletion notification.
-
-// TODO(sky): need to better track changes to initial connection. For example,
-// that SetBounsdViews/AddView and the like don't result in messages to the
-// originating connection.
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/window_manager_access_policy.cc b/mojo/services/view_manager/window_manager_access_policy.cc
deleted file mode 100644
index f781534..0000000
--- a/mojo/services/view_manager/window_manager_access_policy.cc
+++ /dev/null
@@ -1,92 +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 "mojo/services/view_manager/window_manager_access_policy.h"
-
-#include "mojo/services/view_manager/access_policy_delegate.h"
-#include "mojo/services/view_manager/server_view.h"
-
-namespace mojo {
-namespace service {
-
-// TODO(sky): document why this differs from default for each case. Maybe want
-// to subclass DefaultAccessPolicy.
-
-WindowManagerAccessPolicy::WindowManagerAccessPolicy(
-    ConnectionSpecificId connection_id,
-    AccessPolicyDelegate* delegate)
-    : connection_id_(connection_id),
-      delegate_(delegate) {
-}
-
-WindowManagerAccessPolicy::~WindowManagerAccessPolicy() {
-}
-
-bool WindowManagerAccessPolicy::CanRemoveViewFromParent(
-    const ServerView* view) const {
-  return true;
-}
-
-bool WindowManagerAccessPolicy::CanAddView(const ServerView* parent,
-                                           const ServerView* child) const {
-  return true;
-}
-
-bool WindowManagerAccessPolicy::CanReorderView(const ServerView* view,
-                                               const ServerView* relative_view,
-                                               OrderDirection direction) const {
-  return true;
-}
-
-bool WindowManagerAccessPolicy::CanDeleteView(const ServerView* view) const {
-  return view->id().connection_id == connection_id_;
-}
-
-bool WindowManagerAccessPolicy::CanGetViewTree(const ServerView* view) const {
-  return true;
-}
-
-bool WindowManagerAccessPolicy::CanDescendIntoViewForViewTree(
-    const ServerView* view) const {
-  return true;
-}
-
-bool WindowManagerAccessPolicy::CanEmbed(const ServerView* view) const {
-  return view->id().connection_id == connection_id_;
-}
-
-bool WindowManagerAccessPolicy::CanChangeViewVisibility(
-    const ServerView* view) const {
-  return view->id().connection_id == connection_id_;
-}
-
-bool WindowManagerAccessPolicy::CanSetViewSurfaceId(
-    const ServerView* view) const {
-  if (delegate_->IsViewRootOfAnotherConnectionForAccessPolicy(view))
-    return false;
-  return view->id().connection_id == connection_id_ ||
-         (delegate_->GetRootsForAccessPolicy().count(
-              ViewIdToTransportId(view->id())) > 0);
-}
-
-bool WindowManagerAccessPolicy::CanSetViewBounds(const ServerView* view) const {
-  return view->id().connection_id == connection_id_;
-}
-
-bool WindowManagerAccessPolicy::ShouldNotifyOnHierarchyChange(
-    const ServerView* view,
-    const ServerView** new_parent,
-    const ServerView** old_parent) const {
-  // Notify if we've already told the window manager about the view, or if we've
-  // already told the window manager about the parent. The later handles the
-  // case of a view that wasn't parented to the root getting added to the root.
-  return IsViewKnown(view) || (*new_parent && IsViewKnown(*new_parent));
-}
-
-bool WindowManagerAccessPolicy::IsViewKnown(const ServerView* view) const {
-  return delegate_->IsViewKnownForAccessPolicy(view);
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/window_manager_access_policy.h b/mojo/services/view_manager/window_manager_access_policy.h
deleted file mode 100644
index aa44fd6..0000000
--- a/mojo/services/view_manager/window_manager_access_policy.h
+++ /dev/null
@@ -1,54 +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 MOJO_SERVICES_VIEW_MANAGER_WINDOW_MANAGER_ACCESS_POLICY_H_
-#define MOJO_SERVICES_VIEW_MANAGER_WINDOW_MANAGER_ACCESS_POLICY_H_
-
-#include "base/basictypes.h"
-#include "mojo/services/view_manager/access_policy.h"
-
-namespace mojo {
-namespace service {
-
-class AccessPolicyDelegate;
-
-class WindowManagerAccessPolicy : public AccessPolicy {
- public:
-  WindowManagerAccessPolicy(ConnectionSpecificId connection_id,
-                            AccessPolicyDelegate* delegate);
-  virtual ~WindowManagerAccessPolicy();
-
-  // AccessPolicy:
-  virtual bool CanRemoveViewFromParent(const ServerView* view) const override;
-  virtual bool CanAddView(const ServerView* parent,
-                          const ServerView* child) const override;
-  virtual bool CanReorderView(const ServerView* view,
-                              const ServerView* relative_view,
-                              OrderDirection direction) const override;
-  virtual bool CanDeleteView(const ServerView* view) const override;
-  virtual bool CanGetViewTree(const ServerView* view) const override;
-  virtual bool CanDescendIntoViewForViewTree(
-      const ServerView* view) const override;
-  virtual bool CanEmbed(const ServerView* view) const override;
-  virtual bool CanChangeViewVisibility(const ServerView* view) const override;
-  virtual bool CanSetViewSurfaceId(const ServerView* view) const override;
-  virtual bool CanSetViewBounds(const ServerView* view) const override;
-  virtual bool ShouldNotifyOnHierarchyChange(
-      const ServerView* view,
-      const ServerView** new_parent,
-      const ServerView** old_parent) const override;
-
- private:
-  bool IsViewKnown(const ServerView* view) const;
-
-  const ConnectionSpecificId connection_id_;
-  AccessPolicyDelegate* delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerAccessPolicy);
-};
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_WINDOW_MANAGER_ACCESS_POLICY_H_
diff --git a/mojo/services/view_manager/window_manager_client_impl.cc b/mojo/services/view_manager/window_manager_client_impl.cc
deleted file mode 100644
index 493e8f1..0000000
--- a/mojo/services/view_manager/window_manager_client_impl.cc
+++ /dev/null
@@ -1,41 +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 "mojo/services/view_manager/window_manager_client_impl.h"
-
-#include "base/bind.h"
-#include "mojo/services/view_manager/connection_manager.h"
-#include "mojo/services/view_manager/view_manager_service_impl.h"
-
-namespace mojo {
-namespace service {
-
-WindowManagerClientImpl::WindowManagerClientImpl(
-    ConnectionManager* connection_manager)
-    : connection_manager_(connection_manager) {
-}
-
-WindowManagerClientImpl::~WindowManagerClientImpl() {
-}
-
-void WindowManagerClientImpl::DispatchInputEventToView(Id transport_view_id,
-                                                       EventPtr event) {
-  const ViewId view_id(ViewIdFromTransportId(transport_view_id));
-
-  ViewManagerServiceImpl* connection =
-      connection_manager_->GetConnectionWithRoot(view_id);
-  if (!connection)
-    connection = connection_manager_->GetConnection(view_id.connection_id);
-  if (connection) {
-    connection->client()->OnViewInputEvent(
-        transport_view_id, event.Pass(), base::Bind(&base::DoNothing));
-  }
-}
-
-void WindowManagerClientImpl::OnConnectionError() {
-  // TODO(sky): deal with this. We may need to tear everything down here.
-}
-
-}  // namespace service
-}  // namespace mojo
diff --git a/mojo/services/view_manager/window_manager_client_impl.h b/mojo/services/view_manager/window_manager_client_impl.h
deleted file mode 100644
index b25aafe..0000000
--- a/mojo/services/view_manager/window_manager_client_impl.h
+++ /dev/null
@@ -1,55 +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 MOJO_SERVICES_VIEW_MANAGER_WINDOW_MANAGER_CLIENT_IMPL_H_
-#define MOJO_SERVICES_VIEW_MANAGER_WINDOW_MANAGER_CLIENT_IMPL_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h"
-#include "mojo/services/view_manager/ids.h"
-#include "mojo/services/view_manager/view_manager_export.h"
-
-namespace mojo {
-namespace service {
-
-class ConnectionManager;
-
-#if defined(OS_WIN)
-// Equivalent of NON_EXPORTED_BASE which does not work with the template snafu
-// below.
-#pragma warning(push)
-#pragma warning(disable : 4275)
-#endif
-
-class MOJO_VIEW_MANAGER_EXPORT WindowManagerClientImpl
-    : public InterfaceImpl<WindowManagerClient> {
- public:
-  explicit WindowManagerClientImpl(ConnectionManager* connection_manager);
-  virtual ~WindowManagerClientImpl();
-
-  // WindowManagerClient:
-  virtual void DispatchInputEventToView(Id transport_view_id,
-                                        EventPtr event) override;
-
-  // InterfaceImp overrides:
-  virtual void OnConnectionError() override;
-
- private:
-  ConnectionManager* connection_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerClientImpl);
-};
-
-#if defined(OS_WIN)
-#pragma warning(pop)
-#endif
-
-}  // namespace service
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_VIEW_MANAGER_WINDOW_MANAGER_CLIENT_IMPL_H_
diff --git a/mojo/services/window_manager/BUILD.gn b/mojo/services/window_manager/BUILD.gn
deleted file mode 100644
index 98a8b36..0000000
--- a/mojo/services/window_manager/BUILD.gn
+++ /dev/null
@@ -1,83 +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.
-
-import("//build/config/ui.gni")
-
-if (use_aura) {
-
-# GYP version: mojo/mojo_services.gypi:mojo_core_window_manager
-shared_library("window_manager") {
-  output_name = "mojo_core_window_manager"
-
-  sources = [ "main.cc" ]
-
-  public_deps = [
-    ":lib",
-  ]
-  deps = [
-    "//base",
-    "//mojo/application",
-    "//mojo/public/c/system:for_shared_library",
-    "//mojo/services/public/cpp/view_manager",
-  ]
-}
-
-# GYP version: mojo/mojo_services.gypi:mojo_core_window_manager_lib
-source_set("lib") {
-  sources = [
-    "window_manager_app.cc",
-    "window_manager_app.h",
-    "window_manager_delegate.h",
-    "window_manager_service_impl.cc",
-    "window_manager_service_impl.h",
-    "window_manager_service2_impl.cc",
-    "window_manager_service2_impl.h",
-  ]
-
-  public_deps = [
-    "//mojo/aura",
-  ]
-  deps = [
-    "//base",
-    "//ui/base",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-    "//ui/wm",
-    "//mojo/aura",
-    "//mojo/application",
-    "//mojo/common",
-    "//mojo/converters/input_events",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/public/interfaces/application:application",
-    "//mojo/services/public/interfaces/window_manager",
-    "//mojo/services/public/interfaces/window_manager2",
-  ]
-}
-
-# GYP version: mojo/mojo_services.gypi:mojo_core_window_manager_unittests
-test("mojo_core_window_manager_unittests") {
-  sources = [
-    "window_manager_api_unittest.cc",
-    "window_manager_unittests.cc",
-  ]
-
-  deps = [
-    "//base/test:test_support",
-    "//mojo/application_manager",
-    "//mojo/edk/system",
-    "//mojo/environment:chromium",
-    "//mojo/services/public/cpp/view_manager",
-    "//mojo/services/public/interfaces/view_manager",
-    "//mojo/services/public/interfaces/window_manager",
-    "//mojo/services/public/interfaces/window_manager2",
-    "//mojo/shell:test_support",
-    "//testing/gtest",
-    "//ui/gl",
-  ]
-  if (use_x11) {
-    deps += [ "//ui/gfx/x" ]
-  }
-}
-
-}  # use_aura
diff --git a/mojo/services/window_manager/DEPS b/mojo/services/window_manager/DEPS
deleted file mode 100644
index bbaa409..0000000
--- a/mojo/services/window_manager/DEPS
+++ /dev/null
@@ -1,14 +0,0 @@
-include_rules = [
-  "+mojo/aura",
-  "+mojo/application",
-  "+mojo/application_manager",
-  "+mojo/converters/input_events",
-  "+mojo/services/native_viewport",
-  "+mojo/services/public",
-  "+ui/aura",
-  "+ui/base",
-  "+ui/events",
-  "+ui/gfx",
-  "+ui/gl",
-  "+ui/wm",
-]
diff --git a/mojo/services/window_manager/main.cc b/mojo/services/window_manager/main.cc
deleted file mode 100644
index 3e2d37c..0000000
--- a/mojo/services/window_manager/main.cc
+++ /dev/null
@@ -1,75 +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 "base/memory/scoped_ptr.h"
-#include "mojo/application/application_runner_chromium.h"
-#include "mojo/public/c/system/main.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/service_provider_impl.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/window_manager/window_manager_app.h"
-#include "mojo/services/window_manager/window_manager_delegate.h"
-
-// ApplicationDelegate implementation file for WindowManager users (e.g.
-// core window manager tests) that do not want to provide their own
-// ApplicationDelegate::Create().
-
-namespace mojo {
-
-class DefaultWindowManager : public ApplicationDelegate,
-                             public ViewManagerDelegate,
-                             public WindowManagerDelegate {
- public:
-  DefaultWindowManager()
-      : window_manager_app_(new WindowManagerApp(this, this)),
-        view_manager_(NULL),
-        root_(NULL) {}
-  virtual ~DefaultWindowManager() {}
-
- private:
-  // Overridden from ApplicationDelegate:
-  virtual void Initialize(ApplicationImpl* impl) override {
-    window_manager_app_->Initialize(impl);
-  }
-  virtual bool ConfigureIncomingConnection(
-      ApplicationConnection* connection) override {
-    window_manager_app_->ConfigureIncomingConnection(connection);
-    return true;
-  }
-
-  // Overridden from ViewManagerDelegate:
-  virtual void OnEmbed(ViewManager* view_manager,
-                       View* root,
-                       ServiceProviderImpl* exported_services,
-                       scoped_ptr<ServiceProvider> imported_services) override {
-    view_manager_ = view_manager;
-    root_ = root;
-  }
-  virtual void OnViewManagerDisconnected(ViewManager* view_manager) override {}
-
-  // Overridden from WindowManagerDelegate:
-  virtual void Embed(
-      const String& url,
-      InterfaceRequest<ServiceProvider> service_provider) override {
-    View* view = View::Create(view_manager_);
-    root_->AddChild(view);
-    view->Embed(url, scoped_ptr<mojo::ServiceProviderImpl>(
-        new mojo::ServiceProviderImpl).Pass());
-  }
-
-  scoped_ptr<WindowManagerApp> window_manager_app_;
-
-  ViewManager* view_manager_;
-  View* root_;
-
-  MOJO_DISALLOW_COPY_AND_ASSIGN(DefaultWindowManager);
-};
-
-}  // namespace mojo
-
-MojoResult MojoMain(MojoHandle shell_handle) {
-  mojo::ApplicationRunnerChromium runner(new mojo::DefaultWindowManager);
-  return runner.Run(shell_handle);
-}
diff --git a/mojo/services/window_manager/window_manager_api_unittest.cc b/mojo/services/window_manager/window_manager_api_unittest.cc
deleted file mode 100644
index 7f89283..0000000
--- a/mojo/services/window_manager/window_manager_api_unittest.cc
+++ /dev/null
@@ -1,278 +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 "base/bind.h"
-#include "base/memory/scoped_vector.h"
-#include "mojo/application_manager/application_manager.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/cpp/application/service_provider_impl.h"
-#include "mojo/public/interfaces/application/service_provider.mojom.h"
-#include "mojo/services/public/cpp/view_manager/types.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
-#include "mojo/services/public/interfaces/window_manager2/window_manager2.mojom.h"
-#include "mojo/shell/shell_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace {
-
-const char kTestServiceURL[] = "mojo:test_url";
-
-void EmptyResultCallback(bool result) {}
-
-// Callback from Embed(). |result| is the result of the Embed() call and
-// |run_loop| the nested RunLoop.
-void ResultCallback(bool* result_cache, base::RunLoop* run_loop, bool result) {
-  *result_cache = result;
-  run_loop->Quit();
-}
-
-// Responsible for establishing the initial ViewManagerService connection.
-// Blocks until result is determined.
-bool InitEmbed(ViewManagerInitService* view_manager_init,
-               const std::string& url) {
-  bool result = false;
-  base::RunLoop run_loop;
-  ServiceProviderPtr sp;
-  BindToProxy(new ServiceProviderImpl, &sp);
-  view_manager_init->Embed(url, sp.Pass(),
-                           base::Bind(&ResultCallback, &result, &run_loop));
-  run_loop.Run();
-  return result;
-}
-
-class TestWindowManagerClient : public WindowManagerClient2 {
- public:
-  typedef base::Callback<void(Id, Id)>
-      TwoNodeCallback;
-
-  explicit TestWindowManagerClient(base::RunLoop* run_loop)
-      : run_loop_(run_loop) {}
-  virtual ~TestWindowManagerClient() {}
-
-  void set_focus_changed_callback(const TwoNodeCallback& callback) {
-    focus_changed_callback_ = callback;
-  }
-  void set_active_window_changed_callback(const TwoNodeCallback& callback) {
-    active_window_changed_callback_ = callback;
-  }
-
- private:
-  // Overridden from WindowManagerClient:
-  virtual void OnWindowManagerReady() override { run_loop_->Quit(); }
-  virtual void OnCaptureChanged(Id old_capture_node_id,
-                                Id new_capture_node_id) override {}
-  virtual void OnFocusChanged(Id old_focused_node_id,
-                              Id new_focused_node_id) override {
-    if (!focus_changed_callback_.is_null())
-      focus_changed_callback_.Run(old_focused_node_id, new_focused_node_id);
-  }
-  virtual void OnActiveWindowChanged(Id old_active_window,
-                                     Id new_active_window) override {
-    if (!active_window_changed_callback_.is_null())
-      active_window_changed_callback_.Run(old_active_window, new_active_window);
-  }
-
-  base::RunLoop* run_loop_;
-  TwoNodeCallback focus_changed_callback_;
-  TwoNodeCallback active_window_changed_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWindowManagerClient);
-};
-
-class TestApplicationLoader : public ApplicationLoader,
-                              public ApplicationDelegate,
-                              public ViewManagerDelegate {
- public:
-  typedef base::Callback<void(View*)> RootAddedCallback;
-
-  explicit TestApplicationLoader(const RootAddedCallback& root_added_callback)
-      : root_added_callback_(root_added_callback) {}
-  virtual ~TestApplicationLoader() {}
-
- private:
-  // Overridden from ApplicationLoader:
-  virtual void Load(ApplicationManager* application_manager,
-                    const GURL& url,
-                    scoped_refptr<LoadCallbacks> callbacks) override {
-    ScopedMessagePipeHandle shell_handle = callbacks->RegisterApplication();
-    if (!shell_handle.is_valid())
-      return;
-    scoped_ptr<ApplicationImpl> app(
-        new ApplicationImpl(this, shell_handle.Pass()));
-    apps_.push_back(app.release());
-  }
-  virtual void OnApplicationError(ApplicationManager* application_manager,
-                                  const GURL& url) override {}
-
-  // Overridden from ApplicationDelegate:
-  virtual void Initialize(ApplicationImpl* app) override {
-    view_manager_client_factory_.reset(
-        new ViewManagerClientFactory(app->shell(), this));
-  }
-
-  virtual bool ConfigureIncomingConnection(
-      ApplicationConnection* connection) override {
-    connection->AddService(view_manager_client_factory_.get());
-    return true;
-  }
-
-  // Overridden from ViewManagerDelegate:
-  virtual void OnEmbed(ViewManager* view_manager,
-                       View* root,
-                       ServiceProviderImpl* exported_services,
-                       scoped_ptr<ServiceProvider> imported_services) override {
-    root_added_callback_.Run(root);
-  }
-  virtual void OnViewManagerDisconnected(ViewManager* view_manager) override {}
-
-  RootAddedCallback root_added_callback_;
-
-  ScopedVector<ApplicationImpl> apps_;
-  scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
-};
-
-}  // namespace
-
-class WindowManagerApiTest : public testing::Test {
- public:
-  WindowManagerApiTest() {}
-  virtual ~WindowManagerApiTest() {}
-
- protected:
-  typedef std::pair<Id, Id> TwoIds;
-
-  Id WaitForEmbed() {
-    Id id;
-    base::RunLoop run_loop;
-    root_added_callback_ = base::Bind(&WindowManagerApiTest::OnEmbed,
-                                      base::Unretained(this), &id, &run_loop);
-    run_loop.Run();
-    return id;
-  }
-
-  TwoIds WaitForFocusChange() {
-    TwoIds old_and_new;
-    base::RunLoop run_loop;
-    window_manager_client()->set_focus_changed_callback(
-        base::Bind(&WindowManagerApiTest::OnFocusChanged,
-                   base::Unretained(this), &old_and_new, &run_loop));
-    run_loop.Run();
-    return old_and_new;
-  }
-
-  TwoIds WaitForActiveWindowChange() {
-    TwoIds old_and_new;
-    base::RunLoop run_loop;
-    window_manager_client()->set_active_window_changed_callback(
-        base::Bind(&WindowManagerApiTest::OnActiveWindowChanged,
-                   base::Unretained(this), &old_and_new, &run_loop));
-    run_loop.Run();
-    return old_and_new;
-  }
-
-  Id OpenWindow() {
-    return OpenWindowWithURL(kTestServiceURL);
-  }
-
-  Id OpenWindowWithURL(const std::string& url) {
-    InitEmbed(view_manager_init_.get(), url);
-    return WaitForEmbed();
-  }
-
-  TestWindowManagerClient* window_manager_client() {
-    return window_manager_client_.get();
-  }
-
-  WindowManagerService2Ptr window_manager_;
-
- private:
-  // Overridden from testing::Test:
-  virtual void SetUp() override {
-    test_helper_.Init();
-    test_helper_.SetLoaderForURL(
-        scoped_ptr<ApplicationLoader>(new TestApplicationLoader(base::Bind(
-            &WindowManagerApiTest::OnRootAdded, base::Unretained(this)))),
-        GURL(kTestServiceURL));
-    test_helper_.application_manager()->ConnectToService(
-        GURL("mojo:view_manager"), &view_manager_init_);
-    ASSERT_TRUE(
-        InitEmbed(view_manager_init_.get(), "mojo:core_window_manager"));
-    ConnectToWindowManager();
-  }
-  virtual void TearDown() override {}
-
-  void ConnectToWindowManager() {
-    test_helper_.application_manager()->ConnectToService(
-        GURL("mojo:core_window_manager"), &window_manager_);
-    base::RunLoop connect_loop;
-    window_manager_client_.reset(new TestWindowManagerClient(&connect_loop));
-    window_manager_.set_client(window_manager_client());
-    connect_loop.Run();
-  }
-
-  void OnRootAdded(View* root) {
-    if (!root_added_callback_.is_null())
-      root_added_callback_.Run(root);
-  }
-
-  void OnEmbed(Id* root_id,
-               base::RunLoop* loop,
-               View* root) {
-    *root_id = root->id();
-    loop->Quit();
-  }
-
-  void OnFocusChanged(TwoIds* old_and_new,
-                      base::RunLoop* run_loop,
-                      Id old_focused_node_id,
-                      Id new_focused_node_id) {
-    DCHECK(old_and_new);
-    old_and_new->first = old_focused_node_id;
-    old_and_new->second = new_focused_node_id;
-    run_loop->Quit();
-  }
-
-  void OnActiveWindowChanged(TwoIds* old_and_new,
-                             base::RunLoop* run_loop,
-                             Id old_focused_node_id,
-                             Id new_focused_node_id) {
-    DCHECK(old_and_new);
-    old_and_new->first = old_focused_node_id;
-    old_and_new->second = new_focused_node_id;
-    run_loop->Quit();
-  }
-
-  shell::ShellTestHelper test_helper_;
-  ViewManagerInitServicePtr view_manager_init_;
-  scoped_ptr<TestWindowManagerClient> window_manager_client_;
-  TestApplicationLoader::RootAddedCallback root_added_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerApiTest);
-};
-
-TEST_F(WindowManagerApiTest, FocusAndActivateWindow) {
-  Id first_window = OpenWindow();
-  window_manager_->FocusWindow(first_window,
-                               base::Bind(&EmptyResultCallback));
-  TwoIds ids = WaitForFocusChange();
-  EXPECT_TRUE(ids.first == 0);
-  EXPECT_EQ(ids.second, first_window);
-
-  Id second_window = OpenWindow();
-  window_manager_->ActivateWindow(second_window,
-                                  base::Bind(&EmptyResultCallback));
-  ids = WaitForActiveWindowChange();
-  EXPECT_EQ(ids.first, first_window);
-  EXPECT_EQ(ids.second, second_window);
-}
-
-}  // namespace mojo
diff --git a/mojo/services/window_manager/window_manager_app.cc b/mojo/services/window_manager/window_manager_app.cc
deleted file mode 100644
index ffd80a8..0000000
--- a/mojo/services/window_manager/window_manager_app.cc
+++ /dev/null
@@ -1,342 +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 "mojo/services/window_manager/window_manager_app.h"
-
-#include "base/message_loop/message_loop.h"
-#include "base/stl_util.h"
-#include "mojo/aura/aura_init.h"
-#include "mojo/converters/input_events/input_events_type_converters.h"
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/public/interfaces/application/shell.mojom.h"
-#include "mojo/services/public/cpp/view_manager/view.h"
-#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_delegate.h"
-#include "ui/aura/window_property.h"
-#include "ui/base/hit_test.h"
-#include "ui/wm/core/capture_controller.h"
-#include "ui/wm/core/focus_controller.h"
-#include "ui/wm/public/activation_client.h"
-
-DECLARE_WINDOW_PROPERTY_TYPE(mojo::View*);
-
-namespace mojo {
-
-// The aura::Windows we use to track Views don't render, so we don't actually
-// need to supply a fully functional WindowDelegate. We do need to provide _a_
-// delegate however, otherwise the event dispatcher won't dispatch events to
-// these windows. (The aura WindowTargeter won't allow a delegate-less window
-// to be the target of an event, since the window delegate is considered the
-// "target handler").
-class DummyDelegate : public aura::WindowDelegate {
- public:
-  DummyDelegate() {}
-  virtual ~DummyDelegate() {}
-
- private:
-  // WindowDelegate overrides:
-  virtual gfx::Size GetMinimumSize() const override { return gfx::Size(); }
-  virtual gfx::Size GetMaximumSize() const override { return gfx::Size(); }
-  virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
-                               const gfx::Rect& new_bounds) override {}
-  virtual gfx::NativeCursor GetCursor(const gfx::Point& point) override {
-    return gfx::kNullCursor;
-  }
-  virtual int GetNonClientComponent(const gfx::Point& point) const override {
-    return HTCAPTION;
-  }
-  virtual bool ShouldDescendIntoChildForEventHandling(
-      aura::Window* child,
-      const gfx::Point& location) override { return true; }
-  virtual bool CanFocus() override { return true; }
-  virtual void OnCaptureLost() override {}
-  virtual void OnPaint(gfx::Canvas* canvas) override {}
-  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
-  virtual void OnWindowDestroying(aura::Window* window) override {}
-  virtual void OnWindowDestroyed(aura::Window* window) override {}
-  virtual void OnWindowTargetVisibilityChanged(bool visible) override {}
-  virtual bool HasHitTestMask() const override { return false; }
-  virtual void GetHitTestMask(gfx::Path* mask) const override {}
-
-  DISALLOW_COPY_AND_ASSIGN(DummyDelegate);
-};
-
-namespace {
-
-DEFINE_WINDOW_PROPERTY_KEY(View*, kViewKey, NULL);
-
-Id GetIdForWindow(aura::Window* window) {
-  return window ? WindowManagerApp::GetViewForWindow(window)->id() : 0;
-}
-
-}  // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerApp, public:
-
-WindowManagerApp::WindowManagerApp(
-    ViewManagerDelegate* view_manager_delegate,
-    WindowManagerDelegate* window_manager_delegate)
-    : shell_(nullptr),
-      window_manager_service2_factory_(this),
-      window_manager_service_factory_(this),
-      wrapped_view_manager_delegate_(view_manager_delegate),
-      window_manager_delegate_(window_manager_delegate),
-      view_manager_(NULL),
-      root_(NULL),
-      dummy_delegate_(new DummyDelegate),
-      window_manager_client_(nullptr) {
-}
-
-WindowManagerApp::~WindowManagerApp() {}
-
-// static
-View* WindowManagerApp::GetViewForWindow(aura::Window* window) {
-  return window->GetProperty(kViewKey);
-}
-
-aura::Window* WindowManagerApp::GetWindowForViewId(Id view) {
-  ViewIdToWindowMap::const_iterator it = view_id_to_window_map_.find(view);
-  return it != view_id_to_window_map_.end() ? it->second : NULL;
-}
-
-void WindowManagerApp::AddConnection(WindowManagerService2Impl* connection) {
-  DCHECK(connections_.find(connection) == connections_.end());
-  connections_.insert(connection);
-}
-
-void WindowManagerApp::RemoveConnection(WindowManagerService2Impl* connection) {
-  DCHECK(connections_.find(connection) != connections_.end());
-  connections_.erase(connection);
-}
-
-void WindowManagerApp::SetCapture(Id view) {
-  capture_client_->capture_client()->SetCapture(GetWindowForViewId(view));
-  // TODO(beng): notify connected clients that capture has changed, probably
-  //             by implementing some capture-client observer.
-}
-
-void WindowManagerApp::FocusWindow(Id view) {
-  aura::Window* window = GetWindowForViewId(view);
-  DCHECK(window);
-  focus_client_->FocusWindow(window);
-}
-
-void WindowManagerApp::ActivateWindow(Id view) {
-  aura::Window* window = GetWindowForViewId(view);
-  DCHECK(window);
-  activation_client_->ActivateWindow(window);
-}
-
-bool WindowManagerApp::IsReady() const {
-  return view_manager_ && root_;
-}
-
-void WindowManagerApp::InitFocus(wm::FocusRules* rules) {
-  wm::FocusController* focus_controller = new wm::FocusController(rules);
-  activation_client_ = focus_controller;
-  focus_client_.reset(focus_controller);
-  aura::client::SetFocusClient(window_tree_host_->window(), focus_controller);
-  aura::client::SetActivationClient(window_tree_host_->window(),
-                                    focus_controller);
-
-  focus_client_->AddObserver(this);
-  activation_client_->AddObserver(this);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerApp, ApplicationDelegate implementation:
-
-void WindowManagerApp::Initialize(ApplicationImpl* impl) {
-  shell_ = impl->shell();
-  aura_init_.reset(new AuraInit);
-  view_manager_client_factory_.reset(
-      new ViewManagerClientFactory(shell_, this));
-}
-
-bool WindowManagerApp::ConfigureIncomingConnection(
-    ApplicationConnection* connection) {
-  connection->AddService(&window_manager_service2_factory_);
-  connection->AddService(view_manager_client_factory_.get());
-  connection->AddService(&window_manager_service_factory_);
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerApp, ViewManagerDelegate implementation:
-
-void WindowManagerApp::OnEmbed(ViewManager* view_manager,
-                               View* root,
-                               ServiceProviderImpl* exported_services,
-                               scoped_ptr<ServiceProvider> imported_services) {
-  DCHECK(!view_manager_ && !root_);
-  view_manager_ = view_manager;
-  root_ = root;
-
-  window_tree_host_.reset(new WindowTreeHostMojo(shell_, root_));
-  window_tree_host_->window()->SetBounds(root->bounds());
-  window_tree_host_->window()->Show();
-
-  RegisterSubtree(root_, window_tree_host_->window());
-
-  capture_client_.reset(
-      new wm::ScopedCaptureClient(window_tree_host_->window()));
-
-  if (wrapped_view_manager_delegate_) {
-    wrapped_view_manager_delegate_->OnEmbed(
-        view_manager, root, exported_services, imported_services.Pass());
-  }
-
-  for (Connections::const_iterator it = connections_.begin();
-       it != connections_.end(); ++it) {
-    (*it)->NotifyReady();
-  }
-}
-
-void WindowManagerApp::OnViewManagerDisconnected(
-    ViewManager* view_manager) {
-  DCHECK_EQ(view_manager_, view_manager);
-  if (wrapped_view_manager_delegate_)
-    wrapped_view_manager_delegate_->OnViewManagerDisconnected(view_manager);
-  view_manager_ = NULL;
-  base::MessageLoop::current()->Quit();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerApp, ViewObserver implementation:
-
-void WindowManagerApp::OnTreeChanged(
-    const ViewObserver::TreeChangeParams& params) {
-  if (params.receiver != root_)
-    return;
-  DCHECK(params.old_parent || params.new_parent);
-  if (!params.target)
-    return;
-
-  if (params.new_parent) {
-    if (view_id_to_window_map_.find(params.target->id()) ==
-        view_id_to_window_map_.end()) {
-      ViewIdToWindowMap::const_iterator it =
-          view_id_to_window_map_.find(params.new_parent->id());
-      DCHECK(it != view_id_to_window_map_.end());
-      RegisterSubtree(params.target, it->second);
-    }
-  } else if (params.old_parent) {
-    UnregisterSubtree(params.target);
-  }
-}
-
-void WindowManagerApp::OnViewDestroying(View* view) {
-  if (view != root_) {
-    Unregister(view);
-    return;
-  }
-  aura::Window* window = GetWindowForViewId(view->id());
-  window->RemovePreTargetHandler(this);
-  root_ = NULL;
-  STLDeleteValues(&view_id_to_window_map_);
-  if (focus_client_.get())
-    focus_client_->RemoveObserver(this);
-  if (activation_client_)
-    activation_client_->RemoveObserver(this);
-  window_tree_host_.reset();
-}
-
-void WindowManagerApp::OnViewBoundsChanged(View* view,
-                                           const gfx::Rect& old_bounds,
-                                           const gfx::Rect& new_bounds) {
-  aura::Window* window = GetWindowForViewId(view->id());
-  window->SetBounds(new_bounds);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerApp, ui::EventHandler implementation:
-
-void WindowManagerApp::OnEvent(ui::Event* event) {
-  if (!window_manager_client_)
-    return;
-
-  View* view = GetViewForWindow(static_cast<aura::Window*>(event->target()));
-  if (!view)
-    return;
-
-  window_manager_client_->DispatchInputEventToView(view->id(),
-                                                   Event::From(*event));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerApp, aura::client::FocusChangeObserver implementation:
-
-void WindowManagerApp::OnWindowFocused(aura::Window* gained_focus,
-                                       aura::Window* lost_focus) {
-  for (Connections::const_iterator it = connections_.begin();
-       it != connections_.end(); ++it) {
-    (*it)->NotifyViewFocused(GetIdForWindow(gained_focus),
-                             GetIdForWindow(lost_focus));
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerApp, aura::client::ActivationChangeObserver implementation:
-
-void WindowManagerApp::OnWindowActivated(aura::Window* gained_active,
-                                         aura::Window* lost_active) {
-  for (Connections::const_iterator it = connections_.begin();
-       it != connections_.end(); ++it) {
-    (*it)->NotifyWindowActivated(GetIdForWindow(gained_active),
-                                 GetIdForWindow(lost_active));
-  }
-  if (gained_active) {
-    View* view = GetViewForWindow(gained_active);
-    view->MoveToFront();
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerApp, private:
-
-void WindowManagerApp::RegisterSubtree(View* view, aura::Window* parent) {
-  view->AddObserver(this);
-  DCHECK(view_id_to_window_map_.find(view->id()) ==
-         view_id_to_window_map_.end());
-  aura::Window* window = new aura::Window(dummy_delegate_.get());
-  window->set_id(view->id());
-  window->SetProperty(kViewKey, view);
-  // All events pass through the root during dispatch, so we only need a handler
-  // installed there.
-  if (view == root_)
-    window->AddPreTargetHandler(this);
-  parent->AddChild(window);
-  window->SetBounds(view->bounds());
-  window->Show();
-  view_id_to_window_map_[view->id()] = window;
-  View::Children::const_iterator it = view->children().begin();
-  for (; it != view->children().end(); ++it)
-    RegisterSubtree(*it, window);
-}
-
-void WindowManagerApp::UnregisterSubtree(View* view) {
-  for (View* child : view->children())
-    UnregisterSubtree(child);
-  Unregister(view);
-}
-
-void WindowManagerApp::Unregister(View* view) {
-  ViewIdToWindowMap::iterator it = view_id_to_window_map_.find(view->id());
-  if (it == view_id_to_window_map_.end()) {
-    // Because we unregister in OnViewDestroying() we can still get a subsequent
-    // OnTreeChanged for the same view. Ignore this one.
-    return;
-  }
-  view->RemoveObserver(this);
-  DCHECK(it != view_id_to_window_map_.end());
-  // Delete before we remove from map as destruction may want to look up view
-  // for window.
-  delete it->second;
-  view_id_to_window_map_.erase(it);
-}
-
-}  // namespace mojo
diff --git a/mojo/services/window_manager/window_manager_app.h b/mojo/services/window_manager/window_manager_app.h
deleted file mode 100644
index 8c9c244..0000000
--- a/mojo/services/window_manager/window_manager_app.h
+++ /dev/null
@@ -1,177 +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 MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_APP_H_
-#define MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_APP_H_
-
-#include <set>
-
-#include "base/memory/scoped_ptr.h"
-#include "mojo/aura/window_tree_host_mojo.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/interface_factory_impl.h"
-#include "mojo/public/cpp/bindings/string.h"
-#include "mojo/services/public/cpp/view_manager/types.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
-#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
-#include "mojo/services/public/cpp/view_manager/view_observer.h"
-#include "mojo/services/window_manager/window_manager_service2_impl.h"
-#include "mojo/services/window_manager/window_manager_service_impl.h"
-#include "ui/aura/client/focus_change_observer.h"
-#include "ui/events/event_handler.h"
-#include "ui/wm/public/activation_change_observer.h"
-
-namespace aura {
-namespace client {
-class ActivationClient;
-class FocusClient;
-}
-class Window;
-}
-
-namespace wm {
-class FocusRules;
-class ScopedCaptureClient;
-}
-
-namespace mojo {
-
-class AuraInit;
-class DummyDelegate;
-class WindowManagerClient;
-class WindowManagerDelegate;
-class WindowManagerService2Impl;
-
-// Implements core window manager functionality that could conceivably be shared
-// across multiple window managers implementing superficially different user
-// experiences. Establishes communication with the view manager.
-// A window manager wishing to use this core should create and own an instance
-// of this object. They may implement the associated ViewManager/WindowManager
-// delegate interfaces exposed by the view manager, this object provides the
-// canonical implementation of said interfaces but will call out to the wrapped
-// instances.
-// This object maintains an aura::WindowTreeHost containing a hierarchy of
-// aura::Windows. Window manager functionality (e.g. focus, activation,
-// modality, etc.) are implemented using aura core window manager components.
-class WindowManagerApp
-    : public ApplicationDelegate,
-      public ViewManagerDelegate,
-      public ViewObserver,
-      public ui::EventHandler,
-      public aura::client::FocusChangeObserver,
-      public aura::client::ActivationChangeObserver {
- public:
-  WindowManagerApp(ViewManagerDelegate* view_manager_delegate,
-                   WindowManagerDelegate* window_manager_delegate);
-  virtual ~WindowManagerApp();
-
-  static View* GetViewForWindow(aura::Window* window);
-  aura::Window* GetWindowForViewId(Id view);
-
-  // Register/deregister new connections to the window manager service.
-  void AddConnection(WindowManagerService2Impl* connection);
-  void RemoveConnection(WindowManagerService2Impl* connection);
-
-  // These are canonical implementations of the window manager API methods.
-  void SetCapture(Id view);
-  void FocusWindow(Id view);
-  void ActivateWindow(Id view);
-
-  bool IsReady() const;
-
-  // A client of this object will use this accessor to gain access to the
-  // aura::Window hierarchy and attach event handlers.
-  WindowTreeHostMojo* host() { return window_tree_host_.get(); }
-
-  WindowManagerDelegate* window_manager_delegate() {
-    return window_manager_delegate_;
-  }
-
-  void InitFocus(wm::FocusRules* rules);
-
-  void set_window_manager_client(WindowManagerClient* client) {
-    window_manager_client_ = client;
-  }
-
-  // Overridden from ApplicationDelegate:
-  virtual void Initialize(ApplicationImpl* impl) override;
-  virtual bool ConfigureIncomingConnection(
-      ApplicationConnection* connection) override;
-
- private:
-  typedef std::set<WindowManagerService2Impl*> Connections;
-  typedef std::map<Id, aura::Window*> ViewIdToWindowMap;
-
-  // Overridden from ViewManagerDelegate:
-  virtual void OnEmbed(ViewManager* view_manager,
-                       View* root,
-                       ServiceProviderImpl* exported_services,
-                       scoped_ptr<ServiceProvider> imported_services) override;
-  virtual void OnViewManagerDisconnected(ViewManager* view_manager) override;
-
-  // Overridden from ViewObserver:
-  virtual void OnTreeChanged(
-      const ViewObserver::TreeChangeParams& params) override;
-  virtual void OnViewDestroying(View* view) override;
-  virtual void OnViewBoundsChanged(View* view,
-                                   const gfx::Rect& old_bounds,
-                                   const gfx::Rect& new_bounds) override;
-
-  // Overridden from ui::EventHandler:
-  virtual void OnEvent(ui::Event* event) override;
-
-  // Overridden from aura::client::FocusChangeObserver:
-  virtual void OnWindowFocused(aura::Window* gained_focus,
-                               aura::Window* lost_focus) override;
-
-  // Overridden from aura::client::ActivationChangeObserver:
-  virtual void OnWindowActivated(aura::Window* gained_active,
-                                 aura::Window* lost_active) override;
-
-  // Creates an aura::Window for every view in the hierarchy beneath |view|,
-  // and adds to the registry so that it can be retrieved later via
-  // GetWindowForViewId().
-  // TODO(beng): perhaps View should have a property bag.
-  void RegisterSubtree(View* view, aura::Window* parent);
-  // Recursively invokes Unregister() for |view| and all its descendants.
-  void UnregisterSubtree(View* view);
-  // Deletes the aura::Windows associated with the hierarchy beneath |id|,
-  // and removes from the registry.
-  void Unregister(View* view);
-
-  Shell* shell_;
-
-  InterfaceFactoryImplWithContext<WindowManagerService2Impl, WindowManagerApp>
-      window_manager_service2_factory_;
-
-  InterfaceFactoryImplWithContext<WindowManagerServiceImpl, WindowManagerApp>
-      window_manager_service_factory_;
-
-  ViewManagerDelegate* wrapped_view_manager_delegate_;
-  WindowManagerDelegate* window_manager_delegate_;
-
-  ViewManager* view_manager_;
-  scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
-  View* root_;
-
-  scoped_ptr<AuraInit> aura_init_;
-  scoped_ptr<WindowTreeHostMojo> window_tree_host_;
-
-  scoped_ptr<wm::ScopedCaptureClient> capture_client_;
-  scoped_ptr<aura::client::FocusClient> focus_client_;
-  aura::client::ActivationClient* activation_client_;
-
-  Connections connections_;
-  ViewIdToWindowMap view_id_to_window_map_;
-
-  scoped_ptr<DummyDelegate> dummy_delegate_;
-
-  WindowManagerClient* window_manager_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerApp);
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_APP_H_
diff --git a/mojo/services/window_manager/window_manager_delegate.h b/mojo/services/window_manager/window_manager_delegate.h
deleted file mode 100644
index 72d7d92..0000000
--- a/mojo/services/window_manager/window_manager_delegate.h
+++ /dev/null
@@ -1,25 +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 MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_DELEGATE_H_
-#define MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_DELEGATE_H_
-
-#include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/interfaces/application/service_provider.mojom.h"
-
-namespace mojo {
-
-class WindowManagerDelegate {
- public:
-  // See WindowManager::Embed() for details.
-  virtual void Embed(const String& url,
-                     InterfaceRequest<ServiceProvider> service_provider) = 0;
-
- protected:
-  virtual ~WindowManagerDelegate() {}
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_DELEGATE_H_
diff --git a/mojo/services/window_manager/window_manager_service2_impl.cc b/mojo/services/window_manager/window_manager_service2_impl.cc
deleted file mode 100644
index e00c987..0000000
--- a/mojo/services/window_manager/window_manager_service2_impl.cc
+++ /dev/null
@@ -1,80 +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 "mojo/services/window_manager/window_manager_service2_impl.h"
-
-#include "mojo/services/window_manager/window_manager_app.h"
-
-namespace mojo {
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerService2Impl, public:
-
-WindowManagerService2Impl::WindowManagerService2Impl(
-    WindowManagerApp* window_manager)
-    : window_manager_(window_manager) {
-  window_manager_->AddConnection(this);
-}
-
-WindowManagerService2Impl::~WindowManagerService2Impl() {
-  window_manager_->RemoveConnection(this);
-}
-
-void WindowManagerService2Impl::NotifyReady() {
-  client()->OnWindowManagerReady();
-}
-
-void WindowManagerService2Impl::NotifyViewFocused(Id new_focused_id,
-                                                  Id old_focused_id) {
-  client()->OnFocusChanged(old_focused_id, new_focused_id);
-}
-
-void WindowManagerService2Impl::NotifyWindowActivated(Id new_active_id,
-                                                      Id old_active_id) {
-  client()->OnActiveWindowChanged(old_active_id, new_active_id);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerService2Impl, WindowManager implementation:
-
-void WindowManagerService2Impl::SetCapture(
-    Id view,
-    const Callback<void(bool)>& callback) {
-  bool success = window_manager_->IsReady();
-  if (success)
-    window_manager_->SetCapture(view);
-  callback.Run(success);
-}
-
-void WindowManagerService2Impl::FocusWindow(
-    Id view,
-    const Callback<void(bool)>& callback) {
-  bool success = window_manager_->IsReady();
-  if (success)
-    window_manager_->FocusWindow(view);
-  callback.Run(success);
-}
-
-void WindowManagerService2Impl::ActivateWindow(
-    Id view,
-    const Callback<void(bool)>& callback) {
-  bool success = window_manager_->IsReady();
-  if (success)
-    window_manager_->ActivateWindow(view);
-  callback.Run(success);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// WindowManagerService2Impl, InterfaceImpl overrides:
-
-void WindowManagerService2Impl::OnConnectionEstablished() {
-  // If the connection was established prior to the window manager being
-  // embedded by the view manager, |window_manager_|'s ViewManagerDelegate
-  // impl will call NotifyReady() when it is.
-  if (window_manager_->IsReady())
-    NotifyReady();
-}
-
-}  // namespace mojo
diff --git a/mojo/services/window_manager/window_manager_service2_impl.h b/mojo/services/window_manager/window_manager_service2_impl.h
deleted file mode 100644
index be129b4..0000000
--- a/mojo/services/window_manager/window_manager_service2_impl.h
+++ /dev/null
@@ -1,44 +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 MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_SERVICE2_IMPL_H_
-#define MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_SERVICE2_IMPL_H_
-
-#include "base/basictypes.h"
-#include "mojo/services/public/cpp/view_manager/types.h"
-#include "mojo/services/public/interfaces/window_manager2/window_manager2.mojom.h"
-
-namespace mojo {
-
-class WindowManagerApp;
-
-class WindowManagerService2Impl : public InterfaceImpl<WindowManagerService2> {
- public:
-  explicit WindowManagerService2Impl(WindowManagerApp* manager);
-  virtual ~WindowManagerService2Impl();
-
-  void NotifyReady();
-  void NotifyViewFocused(Id new_focused_id, Id old_focused_id);
-  void NotifyWindowActivated(Id new_active_id, Id old_active_id);
-
- private:
-  // Overridden from WindowManagerService:
-  virtual void SetCapture(Id view,
-                          const Callback<void(bool)>& callback) override;
-  virtual void FocusWindow(Id view,
-                           const Callback<void(bool)>& callback) override;
-  virtual void ActivateWindow(Id view,
-                              const Callback<void(bool)>& callback) override;
-
-  // Overridden from InterfaceImpl:
-  virtual void OnConnectionEstablished() override;
-
-  WindowManagerApp* window_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerService2Impl);
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_SERVICE2_IMPL_H_
diff --git a/mojo/services/window_manager/window_manager_service_impl.cc b/mojo/services/window_manager/window_manager_service_impl.cc
deleted file mode 100644
index 2ceee5c2..0000000
--- a/mojo/services/window_manager/window_manager_service_impl.cc
+++ /dev/null
@@ -1,37 +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 "mojo/services/window_manager/window_manager_service_impl.h"
-
-#include "mojo/aura/window_tree_host_mojo.h"
-#include "mojo/converters/input_events/input_events_type_converters.h"
-#include "mojo/services/window_manager/window_manager_app.h"
-#include "mojo/services/window_manager/window_manager_delegate.h"
-
-namespace mojo {
-
-WindowManagerServiceImpl::WindowManagerServiceImpl(WindowManagerApp* app)
-    : app_(app) {
-}
-
-WindowManagerServiceImpl::~WindowManagerServiceImpl() {
-}
-
-void WindowManagerServiceImpl::Embed(
-    const String& url,
-    InterfaceRequest<ServiceProvider> service_provider) {
-  app_->window_manager_delegate()->Embed(url, service_provider.Pass());
-}
-
-void WindowManagerServiceImpl::OnViewInputEvent(mojo::EventPtr event) {
-  scoped_ptr<ui::Event> ui_event = event.To<scoped_ptr<ui::Event>>();
-  if (ui_event)
-    app_->host()->SendEventToProcessor(ui_event.get());
-}
-
-void WindowManagerServiceImpl::OnConnectionEstablished() {
-  app_->set_window_manager_client(client());
-}
-
-}  // namespace mojo
diff --git a/mojo/services/window_manager/window_manager_service_impl.h b/mojo/services/window_manager/window_manager_service_impl.h
deleted file mode 100644
index ba2d29e..0000000
--- a/mojo/services/window_manager/window_manager_service_impl.h
+++ /dev/null
@@ -1,37 +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 MOJO_SERVICES_WINDOW_MANAGER_WNDOW_MANAGER_SERVICE_IMPL_H_
-#define MOJO_SERVICES_WINDOW_MANAGER_WNDOW_MANAGER_SERVICE_IMPL_H_
-
-#include "base/basictypes.h"
-#include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h"
-
-namespace mojo {
-
-class WindowManagerApp;
-
-class WindowManagerServiceImpl : public InterfaceImpl<WindowManagerService> {
- public:
-  explicit WindowManagerServiceImpl(WindowManagerApp* app);
-  virtual ~WindowManagerServiceImpl();
-
- private:
-  // WindowManagerServiceImpl:
-  virtual void Embed(
-      const String& url,
-      InterfaceRequest<ServiceProvider> service_provider) override;
-  virtual void OnViewInputEvent(mojo::EventPtr event) override;
-
-  // InterfaceImpl:
-  virtual void OnConnectionEstablished() override;
-
-  WindowManagerApp* app_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerServiceImpl);
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_WINDOW_MANAGER_WNDOW_MANAGER_SERVICE_IMPL_H_
diff --git a/mojo/services/window_manager/window_manager_unittests.cc b/mojo/services/window_manager/window_manager_unittests.cc
deleted file mode 100644
index dbd9a48..0000000
--- a/mojo/services/window_manager/window_manager_unittests.cc
+++ /dev/null
@@ -1,43 +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 "base/bind.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "ui/gl/gl_surface.h"
-
-#if defined(USE_X11)
-#include "ui/gfx/x/x11_connection.h"
-#endif
-
-namespace mojo {
-
-class WindowManagerTestSuite : public base::TestSuite {
- public:
-  WindowManagerTestSuite(int argc, char** argv) : TestSuite(argc, argv) {}
-  virtual ~WindowManagerTestSuite() {}
-
- protected:
-  virtual void Initialize() override {
-#if defined(USE_X11)
-    // Each test ends up creating a new thread for the native viewport service.
-    // In other words we'll use X on different threads, so tell it that.
-    gfx::InitializeThreadedX11();
-#endif
-    base::TestSuite::Initialize();
-    gfx::GLSurface::InitializeOneOffForTests();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerTestSuite);
-};
-
-}  // namespace mojo
-
-int main(int argc, char** argv) {
-  mojo::WindowManagerTestSuite test_suite(argc, argv);
-
-  return base::LaunchUnitTests(
-      argc, argv, base::Bind(&TestSuite::Run, base::Unretained(&test_suite)));
-}
diff --git a/mojo/shell/android/apk/AndroidManifest.xml b/mojo/shell/android/apk/AndroidManifest.xml
index 32b48e9..3c4c3ae 100644
--- a/mojo/shell/android/apk/AndroidManifest.xml
+++ b/mojo/shell/android/apk/AndroidManifest.xml
@@ -23,6 +23,6 @@
         </activity>
     </application>
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <uses-permission android:name="android.permission.INTERNET"/>
 </manifest>
diff --git a/mojo/shell/external_application_listener_unittest.cc b/mojo/shell/external_application_listener_unittest.cc
index 7f675aed..2fc5511 100644
--- a/mojo/shell/external_application_listener_unittest.cc
+++ b/mojo/shell/external_application_listener_unittest.cc
@@ -56,7 +56,7 @@
 
 class StubShellImpl : public InterfaceImpl<Shell> {
  private:
-  virtual void ConnectToApplication(
+  void ConnectToApplication(
       const String& requestor_url,
       InterfaceRequest<ServiceProvider> in_service_provider) override {
     ServiceProviderPtr out_service_provider;
@@ -106,10 +106,10 @@
       : url_(url), to_quit_(loop), quit_callback_(quit_callback) {}
 
  private:
-  virtual void Initialize(Array<String> args) override {}
+  void Initialize(Array<String> args) override {}
 
-  virtual void AcceptConnection(const String& requestor_url,
-                                ServiceProviderPtr p) override {
+  void AcceptConnection(const String& requestor_url,
+                        ServiceProviderPtr p) override {
     DVLOG(1) << url_ << " accepting connection from " << requestor_url;
     to_quit_->PostTask(FROM_HERE, quit_callback_);
   }
diff --git a/mojo/shell/external_application_registrar_connection.h b/mojo/shell/external_application_registrar_connection.h
index 327d19b4..dbe02e68 100644
--- a/mojo/shell/external_application_registrar_connection.h
+++ b/mojo/shell/external_application_registrar_connection.h
@@ -29,10 +29,10 @@
   // Configures client_socket_ to point at socket_path.
   explicit ExternalApplicationRegistrarConnection(
       const base::FilePath& socket_path);
-  virtual ~ExternalApplicationRegistrarConnection();
+  ~ExternalApplicationRegistrarConnection() override;
 
   // Implementation of ErrorHandler
-  virtual void OnConnectionError() override;
+  void OnConnectionError() override;
 
   // Connects client_socket_ and binds it to registrar_.
   // Status code is passed to callback upon success or failure.
diff --git a/mojo/shell/incoming_connection_listener_unittest.cc b/mojo/shell/incoming_connection_listener_unittest.cc
index 5488c98..61b0a5e 100644
--- a/mojo/shell/incoming_connection_listener_unittest.cc
+++ b/mojo/shell/incoming_connection_listener_unittest.cc
@@ -25,10 +25,10 @@
 class TestDelegate : public IncomingConnectionListenerPosix::Delegate {
  public:
   TestDelegate() {}
-  virtual ~TestDelegate() {}
+  ~TestDelegate() override {}
 
-  virtual void OnListening(int rv) override { EXPECT_EQ(net::OK, rv); }
-  virtual void OnConnection(net::SocketDescriptor incoming) override {
+  void OnListening(int rv) override { EXPECT_EQ(net::OK, rv); }
+  void OnConnection(net::SocketDescriptor incoming) override {
     EXPECT_NE(net::kInvalidSocket, incoming);
   }
 };
@@ -38,10 +38,10 @@
     : public IncomingConnectionListenerPosix::Delegate {
  public:
   explicit ListeningFailsDelegate(int expected) : expected_error_(expected) {}
-  virtual ~ListeningFailsDelegate() {}
+  ~ListeningFailsDelegate() override {}
 
-  virtual void OnListening(int rv) override { EXPECT_EQ(expected_error_, rv); }
-  virtual void OnConnection(net::SocketDescriptor incoming) override {
+  void OnListening(int rv) override { EXPECT_EQ(expected_error_, rv); }
+  void OnConnection(net::SocketDescriptor incoming) override {
     FAIL() << "No connection should be attempted.";
   }
 
diff --git a/mojo/shell/view_manager_loader.cc b/mojo/shell/view_manager_loader.cc
deleted file mode 100644
index 9128084..0000000
--- a/mojo/shell/view_manager_loader.cc
+++ /dev/null
@@ -1,56 +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 "mojo/shell/view_manager_loader.h"
-
-#include "mojo/public/cpp/application/application_connection.h"
-#include "mojo/public/cpp/application/application_impl.h"
-#include "mojo/services/view_manager/view_manager_init_service_impl.h"
-
-namespace mojo {
-
-using service::ViewManagerInitServiceImpl;
-
-namespace shell {
-
-ViewManagerLoader::ViewManagerLoader() {
-}
-
-ViewManagerLoader::~ViewManagerLoader() {
-}
-
-void ViewManagerLoader::Load(ApplicationManager* manager,
-                             const GURL& url,
-                             scoped_refptr<LoadCallbacks> callbacks) {
-  ScopedMessagePipeHandle shell_handle = callbacks->RegisterApplication();
-  if (!shell_handle.is_valid())
-    return;
-
-  // TODO(sky): this needs some sort of authentication as well as making sure
-  // we only ever have one active at a time.
-  scoped_ptr<ApplicationImpl> app(
-      new ApplicationImpl(this, shell_handle.Pass()));
-  apps_.push_back(app.release());
-}
-
-void ViewManagerLoader::OnApplicationError(ApplicationManager* manager,
-                                           const GURL& url) {
-}
-
-bool ViewManagerLoader::ConfigureIncomingConnection(
-    ApplicationConnection* connection)  {
-  context_.ConfigureIncomingConnection(connection);
-  connection->AddService(this);
-  return true;
-}
-
-void ViewManagerLoader::Create(
-    ApplicationConnection* connection,
-    InterfaceRequest<ViewManagerInitService> request) {
-  BindToRequest(new ViewManagerInitServiceImpl(connection, &context_),
-                &request);
-}
-
-}  // namespace shell
-}  // namespace mojo
diff --git a/mojo/shell/view_manager_loader.h b/mojo/shell/view_manager_loader.h
deleted file mode 100644
index 83c5f31f..0000000
--- a/mojo/shell/view_manager_loader.h
+++ /dev/null
@@ -1,57 +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 MOJO_SHELL_VIEW_MANAGER_LOADER_H_
-#define MOJO_SHELL_VIEW_MANAGER_LOADER_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
-#include "mojo/application_manager/application_loader.h"
-#include "mojo/public/cpp/application/application_delegate.h"
-#include "mojo/public/cpp/application/interface_factory.h"
-#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
-#include "mojo/services/view_manager/view_manager_init_service_context.h"
-
-namespace mojo {
-
-class Application;
-
-namespace shell {
-
-// ApplicationLoader responsible for creating connections to the ViewManager.
-class ViewManagerLoader : public ApplicationLoader,
-                          public ApplicationDelegate,
-                          public InterfaceFactory<ViewManagerInitService> {
- public:
-  ViewManagerLoader();
-  virtual ~ViewManagerLoader();
-
- private:
-  // ApplicationLoader overrides:
-  virtual void Load(ApplicationManager* manager,
-                    const GURL& url,
-                    scoped_refptr<LoadCallbacks> callbacks) override;
-  virtual void OnApplicationError(ApplicationManager* manager,
-                                  const GURL& url) override;
-
-  // ApplicationDelegate overrides.
-  virtual bool ConfigureIncomingConnection(
-      mojo::ApplicationConnection* connection) override;
-
-  // InterfaceFactory<ViewManagerInitService> overrides.
-  virtual void Create(
-      ApplicationConnection* connection,
-      InterfaceRequest<ViewManagerInitService> request) override;
-
-  ScopedVector<Application> apps_;
-  service::ViewManagerInitServiceContext context_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerLoader);
-};
-
-}  // namespace shell
-}  // namespace mojo
-
-#endif  // MOJO_SHELL_VIEW_MANAGER_LOADER_H_
diff --git a/mojo/tools/mojob.sh b/mojo/tools/mojob.sh
index f1c5d6e..eddefe24 100755
--- a/mojo/tools/mojob.sh
+++ b/mojo/tools/mojob.sh
@@ -68,13 +68,6 @@
   "out/$1/mojo_public_system_perftests" || exit 1
 }
 
-do_pytests() {
-  echo "Running python tests in out/$1 ..."
-  python mojo/tools/run_mojo_python_tests.py || exit 1
-  python mojo/tools/run_mojo_python_bindings_tests.py "--build-dir=out/$1" || \
-      exit 1
-}
-
 do_gn() {
   local gn_args="$(make_gn_args $1)"
   echo "Running gn with --args=\"${gn_args}\" ..."
@@ -164,10 +157,6 @@
       should_do_Debug && do_perftests Debug
       should_do_Release && do_perftests Release
       ;;
-    pytest)
-      should_do_Debug && do_pytests Debug
-      should_do_Release && do_pytests Release
-      ;;
     gn)
       should_do_Debug && do_gn Debug
       should_do_Release && do_gn Release
diff --git a/native_client_sdk/src/libraries/nacl_io/library.dsc b/native_client_sdk/src/libraries/nacl_io/library.dsc
index 1f24f18..ddf1ba5 100644
--- a/native_client_sdk/src/libraries/nacl_io/library.dsc
+++ b/native_client_sdk/src/libraries/nacl_io/library.dsc
@@ -232,7 +232,6 @@
         "sys/mount.h",
         "sys/poll.h",
         "sys/select.h",
-        "sys/signal.h",
         "sys/socket.h",
         "sys/termios.h",
         "sys/time.h",
diff --git a/native_client_sdk/src/libraries/third_party/newlib-extras/sys/signal.h b/native_client_sdk/src/libraries/third_party/newlib-extras/sys/signal.h
deleted file mode 100644
index 4242481..0000000
--- a/native_client_sdk/src/libraries/third_party/newlib-extras/sys/signal.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/* sys/signal.h */
-
-#ifndef _SYS_SIGNAL_H
-#define _SYS_SIGNAL_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "_ansi.h"
-#include <sys/features.h>
-#include <sys/types.h>
-
-/* #ifndef __STRICT_ANSI__*/
-
-/* Cygwin defines it's own sigset_t in include/cygwin/signal.h */
-#ifndef __CYGWIN__
-typedef unsigned long sigset_t;
-#endif
-
-#if defined(__rtems__) || defined (__native_client__)
-
-#if defined(_POSIX_REALTIME_SIGNALS)
-
-/* sigev_notify values
-   NOTE: P1003.1c/D10, p. 34 adds SIGEV_THREAD.  */
-
-#define SIGEV_NONE   1  /* No asynchronous notification shall be delivered */
-                        /*   when the event of interest occurs. */
-#define SIGEV_SIGNAL 2  /* A queued signal, with an application defined */
-                        /*  value, shall be delivered when the event of */
-                        /*  interest occurs. */
-#define SIGEV_THREAD 3  /* A notification function shall be called to */
-                        /*   perform notification. */
-
-/*  Signal Generation and Delivery, P1003.1b-1993, p. 63
-    NOTE: P1003.1c/D10, p. 34 adds sigev_notify_function and
-          sigev_notify_attributes to the sigevent structure.  */
-
-union sigval {
-  int    sival_int;    /* Integer signal value */
-  void  *sival_ptr;    /* Pointer signal value */
-};
-
-struct sigevent {
-  int              sigev_notify;               /* Notification type */
-  int              sigev_signo;                /* Signal number */
-  union sigval     sigev_value;                /* Signal value */
-
-#if defined(_POSIX_THREADS)
-  void           (*sigev_notify_function)( union sigval );
-                                               /* Notification function */
-  pthread_attr_t  *sigev_notify_attributes;    /* Notification Attributes */
-#endif
-};
-
-/* Signal Actions, P1003.1b-1993, p. 64 */
-/* si_code values, p. 66 */
-
-#define SI_USER    1    /* Sent by a user. kill(), abort(), etc */
-#define SI_QUEUE   2    /* Sent by sigqueue() */
-#define SI_TIMER   3    /* Sent by expiration of a timer_settime() timer */
-#define SI_ASYNCIO 4    /* Indicates completion of asycnhronous IO */
-#define SI_MESGQ   5    /* Indicates arrival of a message at an empty queue */
-
-typedef struct {
-  int          si_signo;    /* Signal number */
-  int          si_code;     /* Cause of the signal */
-  union sigval si_value;    /* Signal value */
-} siginfo_t;
-#endif
-
-/*  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 */
-
-#define SA_NOCLDSTOP 1   /* Do not generate SIGCHLD when children stop */
-#define SA_SIGINFO   2   /* Invoke the signal catching function with */
-                         /*   three arguments instead of one. */
-
-/* struct sigaction notes from POSIX:
- *
- *  (1) Routines stored in sa_handler should take a single int as
- *      their argument although the POSIX standard does not require this.
- *      This is not longer true since at least POSIX.1-2008
- *  (2) The fields sa_handler and sa_sigaction may overlap, and a conforming
- *      application should not use both simultaneously.
- */
-
-typedef void (*_sig_func_ptr)(int);
-
-struct sigaction {
-  int         sa_flags;       /* Special flags to affect behavior of signal */
-  sigset_t    sa_mask;        /* Additional set of signals to be blocked */
-                              /*   during execution of signal-catching */
-                              /*   function. */
-  union {
-    _sig_func_ptr _handler;  /* SIG_DFL, SIG_IGN, or pointer to a function */
-#if defined(_POSIX_REALTIME_SIGNALS)
-    void      (*_sigaction)( int, siginfo_t *, void * );
-#endif
-  } _signal_handlers;
-};
-
-#define sa_handler    _signal_handlers._handler
-#if defined(_POSIX_REALTIME_SIGNALS)
-#define sa_sigaction  _signal_handlers._sigaction
-#endif
-
-#elif defined(__CYGWIN__)
-#include <cygwin/signal.h>
-#else
-#define SA_NOCLDSTOP 1  /* only value supported now for sa_flags */
-
-typedef void (*_sig_func_ptr)(int);
-
-struct sigaction 
-{
-	_sig_func_ptr sa_handler;
-	sigset_t sa_mask;
-	int sa_flags;
-};
-#endif /* defined(__rtems__) || defined(__native_client__) */
-
-#define SIG_SETMASK 0	/* set mask with sigprocmask() */
-#define SIG_BLOCK 1	/* set of signals to block */
-#define SIG_UNBLOCK 2	/* set of signals to, well, unblock */
-
-/* These depend upon the type of sigset_t, which right now 
-   is always a long.. They're in the POSIX namespace, but
-   are not ANSI. */
-#define sigaddset(what,sig) (*(what) |= (1<<(sig)), 0)
-#define sigdelset(what,sig) (*(what) &= ~(1<<(sig)), 0)
-#define sigemptyset(what)   (*(what) = 0, 0)
-#define sigfillset(what)    (*(what) = ~(0), 0)
-#define sigismember(what,sig) (((*(what)) & (1<<(sig))) != 0)
-
-int _EXFUN(sigprocmask, (int how, const sigset_t *set, sigset_t *oset));
-
-#if defined(_POSIX_THREADS)
-int _EXFUN(pthread_sigmask, (int how, const sigset_t *set, sigset_t *oset));
-#endif
-
-/* protos for functions found in winsup sources for CYGWIN */
-#if defined(__CYGWIN__) || defined(__rtems__) || defined(__native_client__)
-#undef sigaddset
-#undef sigdelset
-#undef sigemptyset
-#undef sigfillset
-#undef sigismember
-
-#ifdef _COMPILING_NEWLIB
-int _EXFUN(_kill, (pid_t, int));
-#endif
-int _EXFUN(kill, (pid_t, int));
-int _EXFUN(killpg, (pid_t, int));
-int _EXFUN(sigaction, (int, const struct sigaction *, struct sigaction *));
-int _EXFUN(sigaddset, (sigset_t *, const int));
-int _EXFUN(sigdelset, (sigset_t *, const int));
-int _EXFUN(sigismember, (const sigset_t *, int));
-int _EXFUN(sigfillset, (sigset_t *));
-int _EXFUN(sigemptyset, (sigset_t *));
-int _EXFUN(sigpending, (sigset_t *));
-int _EXFUN(sigsuspend, (const sigset_t *));
-int _EXFUN(sigpause, (int));
-
-#if defined(_POSIX_THREADS) && !defined(__native_client__)
-#ifdef __CYGWIN__
-#  ifndef _CYGWIN_TYPES_H
-#    error You need the winsup sources or a cygwin installation to compile the cygwin version of newlib.
-#  endif
-#endif
-int _EXFUN(pthread_kill, (pthread_t thread, int sig));
-#endif
-
-#if defined(_POSIX_REALTIME_SIGNALS)
-
-/*  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
-    NOTE: P1003.1c/D10, p. 39 adds sigwait().  */
-
-int _EXFUN(sigwaitinfo, (const sigset_t *set, siginfo_t *info));
-int _EXFUN(sigtimedwait,
-  (const sigset_t *set, siginfo_t *info, const struct timespec  *timeout)
-);
-int _EXFUN(sigwait, (const sigset_t *set, int *sig));
-
-/*  3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78 */
-int _EXFUN(sigqueue, (pid_t pid, int signo, const union sigval value));
-
-#endif /* defined(_POSIX_REALTIME_SIGNALS) */
-
-#endif /* defined(__CYGWIN__) || defined(__rtems__) */
-
-/* #endif __STRICT_ANSI__ */
-
-#if defined(___AM29K__)
-/* These all need to be defined for ANSI C, but I don't think they are
-   meaningful.  */
-#define SIGABRT 1
-#define SIGFPE 1
-#define SIGILL 1
-#define SIGINT 1
-#define SIGSEGV 1
-#define SIGTERM 1
-/* These need to be defined for POSIX, and some others do too.  */
-#define SIGHUP 1
-#define SIGQUIT 1
-#define NSIG 2
-#elif defined(__GO32__)
-#define SIGINT  1
-#define SIGKILL 2
-#define SIGPIPE 3
-#define SIGFPE  4
-#define SIGHUP  5
-#define SIGTERM 6
-#define SIGSEGV 7
-#define SIGTSTP 8
-#define SIGQUIT 9
-#define SIGTRAP 10
-#define SIGILL  11
-#define SIGEMT  12
-#define SIGALRM 13
-#define SIGBUS  14
-#define SIGLOST 15
-#define SIGSTOP 16
-#define SIGABRT 17
-#define SIGUSR1	18
-#define SIGUSR2	19
-#define NSIG    20
-#elif !defined(SIGTRAP)
-#define	SIGHUP	1	/* hangup */
-#define	SIGINT	2	/* interrupt */
-#define	SIGQUIT	3	/* quit */
-#define	SIGILL	4	/* illegal instruction (not reset when caught) */
-#define	SIGTRAP	5	/* trace trap (not reset when caught) */
-#define	SIGIOT	6	/* IOT instruction */
-#define	SIGABRT 6	/* used by abort, replace SIGIOT in the future */
-#define	SIGEMT	7	/* EMT instruction */
-#define	SIGFPE	8	/* floating point exception */
-#define	SIGKILL	9	/* kill (cannot be caught or ignored) */
-#define	SIGBUS	10	/* bus error */
-#define	SIGSEGV	11	/* segmentation violation */
-#define	SIGSYS	12	/* bad argument to system call */
-#define	SIGPIPE	13	/* write on a pipe with no one to read it */
-#define	SIGALRM	14	/* alarm clock */
-#define	SIGTERM	15	/* software termination signal from kill */
-
-#if defined(__rtems__)
-#define	SIGURG	16	/* urgent condition on IO channel */
-#define	SIGSTOP	17	/* sendable stop signal not from tty */
-#define	SIGTSTP	18	/* stop signal from tty */
-#define	SIGCONT	19	/* continue a stopped process */
-#define	SIGCHLD	20	/* to parent on child stop or exit */
-#define	SIGCLD	20	/* System V name for SIGCHLD */
-#define	SIGTTIN	21	/* to readers pgrp upon background tty read */
-#define	SIGTTOU	22	/* like TTIN for output if (tp->t_local&LTOSTOP) */
-#define	SIGIO	23	/* input/output possible signal */
-#define	SIGPOLL	SIGIO	/* System V name for SIGIO */
-#define	SIGWINCH 24	/* window changed */
-#define	SIGUSR1 25	/* user defined signal 1 */
-#define	SIGUSR2 26	/* user defined signal 2 */
-
-/* Real-Time Signals Range, P1003.1b-1993, p. 61
-   NOTE: By P1003.1b-1993, this should be at least RTSIG_MAX
-         (which is a minimum of 8) signals.
- */
-#define SIGRTMIN 27
-#define SIGRTMAX 31
-#define __SIGFIRSTNOTRT SIGHUP
-#define __SIGLASTNOTRT  SIGUSR2
-
-#define NSIG	32      /* signal 0 implied */
-
-#elif defined(__svr4__)
-/* svr4 specifics. different signals above 15, and sigaction. */
-#define	SIGUSR1	16
-#define SIGUSR2	17
-#define SIGCLD	18
-#define	SIGPWR	19
-#define SIGWINCH 20
-#define	SIGPOLL	22	/* 20 for x.out binaries!!!! */
-#define	SIGSTOP	23	/* sendable stop signal not from tty */
-#define	SIGTSTP	24	/* stop signal from tty */
-#define	SIGCONT	25	/* continue a stopped process */
-#define	SIGTTIN	26	/* to readers pgrp upon background tty read */
-#define	SIGTTOU	27	/* like TTIN for output if (tp->t_local&LTOSTOP) */
-#define NSIG	28	
-#else
-#define	SIGURG	16	/* urgent condition on IO channel */
-#define	SIGSTOP	17	/* sendable stop signal not from tty */
-#define	SIGTSTP	18	/* stop signal from tty */
-#define	SIGCONT	19	/* continue a stopped process */
-#define	SIGCHLD	20	/* to parent on child stop or exit */
-#define	SIGCLD	20	/* System V name for SIGCHLD */
-#define	SIGTTIN	21	/* to readers pgrp upon background tty read */
-#define	SIGTTOU	22	/* like TTIN for output if (tp->t_local&LTOSTOP) */
-#define	SIGIO	23	/* input/output possible signal */
-#define	SIGPOLL	SIGIO	/* System V name for SIGIO */
-#define	SIGXCPU	24	/* exceeded CPU time limit */
-#define	SIGXFSZ	25	/* exceeded file size limit */
-#define	SIGVTALRM 26	/* virtual time alarm */
-#define	SIGPROF	27	/* profiling time alarm */
-#define	SIGWINCH 28	/* window changed */
-#define	SIGLOST 29	/* resource lost (eg, record-lock lost) */
-#define	SIGUSR1 30	/* user defined signal 1 */
-#define	SIGUSR2 31	/* user defined signal 2 */
-#define NSIG	32      /* signal 0 implied */
-#endif
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#ifndef _SIGNAL_H_
-/* Some applications take advantage of the fact that <sys/signal.h>
- * and <signal.h> are equivalent in glibc.  Allow for that here.  */
-#include <signal.h>
-#endif
-#endif /* _SYS_SIGNAL_H */
diff --git a/net/PRESUBMIT.py b/net/PRESUBMIT.py
index e898d990..e82166c 100644
--- a/net/PRESUBMIT.py
+++ b/net/PRESUBMIT.py
@@ -11,13 +11,13 @@
 def GetPreferredTryMasters(project, change):
   masters = {
     'tryserver.chromium.linux': {
-      'linux_chromium_rel_swarming': set(['defaulttests']),
+      'linux_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.mac': {
-      'mac_chromium_rel_swarming': set(['defaulttests']),
+      'mac_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.win': {
-      'win_chromium_rel_swarming': set(['defaulttests']),
+      'win_chromium_rel': set(['defaulttests']),
     }
   }
   # Changes that touch NSS files will likely need a corresponding OpenSSL edit.
diff --git a/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java b/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
index 6b91318..32b7192 100644
--- a/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
+++ b/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
@@ -14,9 +14,6 @@
 import org.chromium.base.CalledByNative;
 import org.chromium.base.CalledByNativeUnchecked;
 
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InterfaceAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.net.URLConnection;
@@ -140,65 +137,6 @@
     }
 
     /**
-     * @return the network interfaces list (if any) string. The items in
-     *         the list string are delimited by a new line, each item
-     *         is tab separated network interface name, address with network
-     *         prefix length and network interface index.
-     *         as "name\taddress/prefix\tindex". e.g.
-     *           eth0\t10.0.0.2/8\t5\neth0\tfe80::5054:ff:fe12:3456/16\t5
-     *         represents a network list string with two items.
-     */
-    @CalledByNative
-    public static String getNetworkList() {
-        Enumeration<NetworkInterface> list = null;
-        try {
-            list = NetworkInterface.getNetworkInterfaces();
-            if (list == null) return "";
-        } catch (SocketException e) {
-            Log.w(TAG, "Unable to get network interfaces: " + e);
-            return "";
-        }
-
-        StringBuilder result = new StringBuilder();
-        while (list.hasMoreElements()) {
-            NetworkInterface netIf = list.nextElement();
-            try {
-                // Skip loopback interfaces, and ones which are down.
-                if (!netIf.isUp() || netIf.isLoopback())
-                    continue;
-                for (InterfaceAddress interfaceAddress : netIf.getInterfaceAddresses()) {
-                    InetAddress address = interfaceAddress.getAddress();
-                    // Skip loopback addresses configured on non-loopback interfaces.
-                    if (address.isLoopbackAddress())
-                        continue;
-                    StringBuilder addressString = new StringBuilder();
-                    addressString.append(netIf.getName());
-                    addressString.append("\t");
-
-                    String ipAddress = address.getHostAddress();
-                    if (address instanceof Inet6Address && ipAddress.contains("%")) {
-                        ipAddress = ipAddress.substring(0, ipAddress.lastIndexOf("%"));
-                    }
-                    addressString.append(ipAddress);
-                    addressString.append("/");
-                    addressString.append(interfaceAddress.getNetworkPrefixLength());
-                    addressString.append("\t");
-
-                    // TODO(vitalybuka): use netIf.getIndex() when API level 19 is availible.
-                    addressString.append("0");
-
-                    if (result.length() != 0)
-                        result.append("\n");
-                    result.append(addressString.toString());
-                }
-            } catch (SocketException e) {
-                continue;
-            }
-        }
-        return result.toString();
-    }
-
-    /**
      * Validate the server's certificate chain is trusted. Note that the caller
      * must still verify the name matches that of the leaf certificate.
      *
diff --git a/net/android/network_library.cc b/net/android/network_library.cc
index c3a42f7..0544395 100644
--- a/net/android/network_library.cc
+++ b/net/android/network_library.cc
@@ -99,13 +99,6 @@
   return Java_AndroidNetworkLibrary_haveOnlyLoopbackAddresses(env);
 }
 
-std::string GetNetworkList() {
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jstring> ret =
-      Java_AndroidNetworkLibrary_getNetworkList(env);
-  return ConvertJavaStringToUTF8(ret);
-}
-
 bool GetMimeTypeFromExtension(const std::string& extension,
                               std::string* result) {
   JNIEnv* env = AttachCurrentThread();
diff --git a/net/android/network_library.h b/net/android/network_library.h
index ba2bfb5..4a4ddca 100644
--- a/net/android/network_library.h
+++ b/net/android/network_library.h
@@ -60,12 +60,6 @@
 // Also returns false if it cannot determine this.
 bool HaveOnlyLoopbackAddresses();
 
-// Return a string containing a list of network interfaces, each item is a
-// network name and address pair.
-// e.g. "eth0,10.0.0.2;eth0,fe80::5054:ff:fe12:3456" is a result string
-// containing two items.
-std::string GetNetworkList();
-
 // Get the mime type (if any) that is associated with the file extension.
 // Returns true if a corresponding mime type exists.
 bool GetMimeTypeFromExtension(const std::string& extension,
diff --git a/net/base/data_url_unittest.cc b/net/base/data_url_unittest.cc
index 3876301c..bcb2b49a 100644
--- a/net/base/data_url_unittest.cc
+++ b/net/base/data_url_unittest.cc
@@ -184,6 +184,44 @@
       "",
       "" },
 
+    // BiDi control characters should be unescaped and preserved as is, and
+    // should not be replaced with % versions. In the below case, \xE2\x80\x8F
+    // is the RTL mark and the parsed text should preserve it as is.
+    {
+      "data:text/plain;charset=utf-8,\xE2\x80\x8Ftest",
+      true,
+      "text/plain",
+      "utf-8",
+      "\xE2\x80\x8Ftest"},
+
+    // Same as above but with Arabic text after RTL mark.
+    {
+      "data:text/plain;charset=utf-8,"
+          "\xE2\x80\x8F\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1",
+      true,
+      "text/plain",
+      "utf-8",
+      "\xE2\x80\x8F\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1"},
+
+    // RTL mark encoded as %E2%80%8F should be unescaped too. Note that when
+    // wrapped in a GURL, this URL and the next effectively become the same as
+    // the previous two URLs.
+    {
+      "data:text/plain;charset=utf-8,%E2%80%8Ftest",
+      true,
+      "text/plain",
+      "utf-8",
+      "\xE2\x80\x8Ftest"},
+
+    // Same as above but with Arabic text after RTL mark.
+    {
+      "data:text/plain;charset=utf-8,"
+          "%E2%80%8F\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1",
+      true,
+      "text/plain",
+      "utf-8",
+      "\xE2\x80\x8F\xD8\xA7\xD8\xAE\xD8\xAA\xD8\xA8\xD8\xA7\xD8\xB1"}
+
     // TODO(darin): add more interesting tests
   };
 
diff --git a/net/base/escape.cc b/net/base/escape.cc
index 1798b6c..7a068f87 100644
--- a/net/base/escape.cc
+++ b/net/base/escape.cc
@@ -39,15 +39,21 @@
 // Given text to escape and a Charmap defining which values to escape,
 // return an escaped string.  If use_plus is true, spaces are converted
 // to +, otherwise, if spaces are in the charmap, they are converted to
-// %20.
-std::string Escape(const std::string& text, const Charmap& charmap,
-                   bool use_plus) {
+// %20. And if keep_escaped is true, %XX will be kept as it is, otherwise, if
+// '%' is in the charmap, it is converted to %25.
+std::string Escape(const std::string& text,
+                   const Charmap& charmap,
+                   bool use_plus,
+                   bool keep_escaped = false) {
   std::string escaped;
   escaped.reserve(text.length() * 3);
   for (unsigned int i = 0; i < text.length(); ++i) {
     unsigned char c = static_cast<unsigned char>(text[i]);
     if (use_plus && ' ' == c) {
       escaped.push_back('+');
+    } else if (keep_escaped && '%' == c && i + 2 < text.length() &&
+               IsHexDigit(text[i + 1]) && IsHexDigit(text[i + 2])) {
+      escaped.push_back('%');
     } else if (charmap.Contains(c)) {
       escaped.push_back('%');
       escaped.push_back(IntToHex(c >> 4));
@@ -120,6 +126,44 @@
   return false;
 }
 
+// Returns true if there is an Arabic Language Mark at |index|. |first_byte|
+// is the byte at |index|.
+template<typename STR>
+bool HasArabicLanguageMarkAtIndex(const STR& escaped_text,
+                                  unsigned char first_byte,
+                                  size_t index) {
+  if (first_byte != 0xD8)
+    return false;
+  unsigned char second_byte;
+  if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 3, &second_byte))
+    return false;
+  return second_byte == 0x9c;
+}
+
+// Returns true if there is a BiDi control char at |index|. |first_byte| is the
+// byte at |index|.
+template<typename STR>
+bool HasThreeByteBidiControlCharAtIndex(const STR& escaped_text,
+                                        unsigned char first_byte,
+                                        size_t index) {
+  if (first_byte != 0xE2)
+    return false;
+  unsigned char second_byte;
+  if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 3, &second_byte))
+    return false;
+  if (second_byte != 0x80 && second_byte != 0x81)
+    return false;
+  unsigned char third_byte;
+  if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 6, &third_byte))
+    return false;
+  if (second_byte == 0x80) {
+    return third_byte == 0x8E ||
+           third_byte == 0x8F ||
+           (third_byte >= 0xAA && third_byte <= 0xAE);
+  }
+  return third_byte >= 0xA6 && third_byte <= 0xA9;
+}
+
 // Unescapes |escaped_text| according to |rules|, returning the resulting
 // string.  Fills in an |adjustments| parameter, if non-NULL, so it reflects
 // the alterations done to the string that are not one-character-to-one-
@@ -172,27 +216,21 @@
       // U+2067 RIGHT-TO-LEFT ISOLATE      (%E2%81%A7)
       // U+2068 FIRST STRONG ISOLATE       (%E2%81%A8)
       // U+2069 POP DIRECTIONAL ISOLATE    (%E2%81%A9)
-
-      unsigned char second_byte;
-      // Check for ALM.
-      if ((first_byte == 0xD8) &&
-          UnescapeUnsignedCharAtIndex(escaped_text, i + 3, &second_byte) &&
-          (second_byte == 0x9c)) {
-        result.append(escaped_text, i, 6);
-        i += 5;
-        continue;
-      }
-
-      // Check for other BiDi control characters.
-      if ((first_byte == 0xE2) &&
-          UnescapeUnsignedCharAtIndex(escaped_text, i + 3, &second_byte) &&
-          ((second_byte == 0x80) || (second_byte == 0x81))) {
-        unsigned char third_byte;
-        if (UnescapeUnsignedCharAtIndex(escaped_text, i + 6, &third_byte) &&
-            ((second_byte == 0x80) ?
-             ((third_byte == 0x8E) || (third_byte == 0x8F) ||
-              ((third_byte >= 0xAA) && (third_byte <= 0xAE))) :
-             ((third_byte >= 0xA6) && (third_byte <= 0xA9)))) {
+      //
+      // However, some schemes such as data: and file: need to parse the exact
+      // binary data when loading the URL. For that reason, CONTROL_CHARS allows
+      // unescaping BiDi control characters.
+      // DO NOT use CONTROL_CHARS if the parsed URL is going to be displayed
+      // in the UI.
+      if (!(rules & UnescapeRule::CONTROL_CHARS)) {
+        if (HasArabicLanguageMarkAtIndex(escaped_text, first_byte, i)) {
+          // Keep Arabic Language Mark escaped.
+          result.append(escaped_text, i, 6);
+          i += 5;
+          continue;
+        }
+        if (HasThreeByteBidiControlCharAtIndex(escaped_text, first_byte, i)) {
+          // Keep BiDi control char escaped.
           result.append(escaped_text, i, 9);
           i += 8;
           continue;
@@ -293,9 +331,9 @@
 }};
 
 // Everything except alphanumerics, the reserved characters(;/?:@&=+$,) and
-// !'()*-._~%
+// !'()*-._~#[]
 static const Charmap kExternalHandlerCharmap = {{
-  0xffffffffL, 0x5000080dL, 0x68000000L, 0xb8000001L,
+  0xffffffffL, 0x50000025L, 0x50000000L, 0xb8000001L,
   0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
 }};
 
@@ -318,7 +356,7 @@
 }
 
 std::string EscapeExternalHandlerValue(const std::string& text) {
-  return Escape(text, kExternalHandlerCharmap, false);
+  return Escape(text, kExternalHandlerCharmap, false, true);
 }
 
 void AppendEscapedCharForHTML(char c, std::string* output) {
diff --git a/net/base/escape.h b/net/base/escape.h
index 1915d24..6c92333 100644
--- a/net/base/escape.h
+++ b/net/base/escape.h
@@ -42,8 +42,8 @@
 
 // Escapes characters in text suitable for use as an external protocol handler
 // command.
-// We %XX everything except alphanumerics and %-_.!~*'() and the restricted
-// chracters (;/?:@&=+$,).
+// We %XX everything except alphanumerics and -_.!~*'() and the restricted
+// chracters (;/?:@&=+$,#[]) and a valid percent escape sequence (%XX).
 NET_EXPORT std::string EscapeExternalHandlerValue(const std::string& text);
 
 // Appends the given character to the output string, escaping the character if
@@ -88,7 +88,10 @@
 
     // Unescapes control characters such as %01. This INCLUDES NULLs. This is
     // used for rare cases such as data: URL decoding where the result is binary
-    // data. You should not use this for normal URLs!
+    // data. This flag also unescapes BiDi control characters.
+    //
+    // DO NOT use CONTROL_CHARS if the URL is going to be displayed in the UI
+    // for security reasons.
     CONTROL_CHARS = 8,
 
     // URL queries use "+" for space. This flag controls that replacement.
diff --git a/net/base/escape_unittest.cc b/net/base/escape_unittest.cc
index 74ae293..4d3bcbdd 100644
--- a/net/base/escape_unittest.cc
+++ b/net/base/escape_unittest.cc
@@ -232,7 +232,8 @@
     {L"Some%20random text %25%E2%80%84OK", UnescapeRule::NORMAL,
      L"Some%20random text %25\xE2\x80\x84OK"},
 
-    // BiDi Control characters should not be unescaped.
+    // BiDi Control characters should not be unescaped unless explicity told to
+    // do so with UnescapeRule::CONTROL_CHARS
     {L"Some%20random text %25%D8%9COK", UnescapeRule::NORMAL,
      L"Some%20random text %25%D8%9COK"},
     {L"Some%20random text %25%E2%80%8EOK", UnescapeRule::NORMAL,
@@ -249,6 +250,31 @@
      L"Some%20random text %25%E2%81%A6OK"},
     {L"Some%20random text %25%E2%81%A9OK", UnescapeRule::NORMAL,
      L"Some%20random text %25%E2%81%A9OK"},
+    // UnescapeRule::CONTROL_CHARS should unescape BiDi Control characters.
+    {L"Some%20random text %25%D8%9COK",
+     UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+     L"Some%20random text %25\xD8\x9COK"},
+    {L"Some%20random text %25%E2%80%8EOK",
+     UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+     L"Some%20random text %25\xE2\x80\x8EOK"},
+    {L"Some%20random text %25%E2%80%8FOK",
+     UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+     L"Some%20random text %25\xE2\x80\x8FOK"},
+    {L"Some%20random text %25%E2%80%AAOK",
+     UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+     L"Some%20random text %25\xE2\x80\xAAOK"},
+    {L"Some%20random text %25%E2%80%ABOK",
+     UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+     L"Some%20random text %25\xE2\x80\xABOK"},
+    {L"Some%20random text %25%E2%80%AEOK",
+     UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+     L"Some%20random text %25\xE2\x80\xAEOK"},
+    {L"Some%20random text %25%E2%81%A6OK",
+     UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+     L"Some%20random text %25\xE2\x81\xA6OK"},
+    {L"Some%20random text %25%E2%81%A9OK",
+     UnescapeRule::NORMAL | UnescapeRule::CONTROL_CHARS,
+     L"Some%20random text %25\xE2\x81\xA9OK"},
 
     {L"Some%20random text %25%2dOK", UnescapeRule::SPACES,
      L"Some random text %25-OK"},
@@ -453,6 +479,43 @@
   }
 }
 
+TEST(EscapeTest, EscapeExternalHandlerValue) {
+  ASSERT_EQ(
+      // Escaped
+      "%02%0A%1D%20!%22#$%25&'()*+,-./0123456789:;"
+      "%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+      "[%5C]%5E_%60abcdefghijklmnopqrstuvwxyz"
+      "%7B%7C%7D~%7F%80%FF",
+      // Most of the character space we care about, un-escaped
+      EscapeExternalHandlerValue(
+          "\x02\n\x1d !\"#$%&'()*+,-./0123456789:;"
+          "<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+          "[\\]^_`abcdefghijklmnopqrstuvwxyz"
+          "{|}~\x7f\x80\xff"));
+
+  ASSERT_EQ(
+      "!#$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_"
+      "abcdefghijklmnopqrstuvwxyz~",
+      EscapeExternalHandlerValue(
+          "!#$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_"
+          "abcdefghijklmnopqrstuvwxyz~"));
+
+  ASSERT_EQ("%258k", EscapeExternalHandlerValue("%8k"));
+  ASSERT_EQ("a%25", EscapeExternalHandlerValue("a%"));
+  ASSERT_EQ("%25a", EscapeExternalHandlerValue("%a"));
+  ASSERT_EQ("a%258", EscapeExternalHandlerValue("a%8"));
+  ASSERT_EQ("%ab", EscapeExternalHandlerValue("%ab"));
+  ASSERT_EQ("%AB", EscapeExternalHandlerValue("%AB"));
+
+  ASSERT_EQ("http://example.com/path/sub?q=a%7Cb%7Cc&q=1%7C2%7C3#ref%7C",
+            EscapeExternalHandlerValue(
+                "http://example.com/path/sub?q=a|b|c&q=1|2|3#ref|"));
+  ASSERT_EQ("http://example.com/path/sub?q=a%7Cb%7Cc&q=1%7C2%7C3#ref%7C",
+            EscapeExternalHandlerValue(
+                "http://example.com/path/sub?q=a%7Cb%7Cc&q=1%7C2%7C3#ref%7C"));
+  ASSERT_EQ("http://[2001:db8:0:1]:80",
+            EscapeExternalHandlerValue("http://[2001:db8:0:1]:80"));
+}
 
 }  // namespace
 }  // namespace net
diff --git a/net/base/net_log_logger.cc b/net/base/net_log_logger.cc
index 76b5b32..99e769b 100644
--- a/net/base/net_log_logger.cc
+++ b/net/base/net_log_logger.cc
@@ -9,6 +9,7 @@
 #include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/metrics/field_trial.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "net/base/address_family.h"
@@ -258,6 +259,20 @@
   // Provide a default empty value for compatibility.
   constants_dict->Set("clientInfo", new base::DictionaryValue());
 
+  // Add a list of active field experiments.
+  {
+    base::FieldTrial::ActiveGroups active_groups;
+    base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
+    base::ListValue* field_trial_groups = new base::ListValue();
+    for (base::FieldTrial::ActiveGroups::const_iterator it =
+             active_groups.begin();
+         it != active_groups.end(); ++it) {
+      field_trial_groups->AppendString(it->trial_name + ":" +
+                                       it->group_name);
+    }
+    constants_dict->Set("activeFieldTrialGroups", field_trial_groups);
+  }
+
   return constants_dict;
 }
 
diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc
index 73704cd..a2fa6cdf 100644
--- a/net/base/net_util_posix.cc
+++ b/net/base/net_util_posix.cc
@@ -19,11 +19,16 @@
 #include "net/base/net_errors.h"
 #include "url/gurl.h"
 
-#if !defined(OS_ANDROID) && !defined(OS_NACL)
+#if !defined(OS_NACL)
+#if defined(OS_MACOSX)
 #include <ifaddrs.h>
+#else
+#include "net/base/address_tracker_linux.h"
+#include "net/base/net_util_posix.h"
+#endif  // OS_MACOSX
 #include <net/if.h>
 #include <netinet/in.h>
-#endif
+#endif  // !defined(OS_NACL)
 
 #if defined(OS_MACOSX) && !defined(OS_IOS)
 #include <net/if_media.h>
@@ -31,15 +36,48 @@
 #include <sys/ioctl.h>
 #endif
 
-#if defined(OS_ANDROID)
-#include "net/android/network_library.h"
-#endif
-
 namespace net {
 
 namespace {
 
-#if !defined(OS_ANDROID)
+// The application layer can pass |policy| defined in net_util.h to
+// request filtering out certain type of interfaces.
+bool ShouldIgnoreInterface(const std::string& name, int policy) {
+  // Filter out VMware interfaces, typically named vmnet1 and vmnet8,
+  // which might not be useful for use cases like WebRTC.
+  if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) &&
+      ((name.find("vmnet") != std::string::npos) ||
+       (name.find("vnic") != std::string::npos))) {
+    return true;
+  }
+
+  return false;
+}
+
+// Check if the address is unspecified (i.e. made of zeroes) or loopback.
+bool IsLoopbackOrUnspecifiedAddress(const sockaddr* addr) {
+  if (addr->sa_family == AF_INET6) {
+    const struct sockaddr_in6* addr_in6 =
+        reinterpret_cast<const struct sockaddr_in6*>(addr);
+    const struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
+    if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) {
+      return true;
+    }
+  } else if (addr->sa_family == AF_INET) {
+    const struct sockaddr_in* addr_in =
+        reinterpret_cast<const struct sockaddr_in*>(addr);
+    if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK ||
+        addr_in->sin_addr.s_addr == 0) {
+      return true;
+    }
+  } else {
+    // Skip non-IP addresses.
+    return true;
+  }
+  return false;
+}
+
+#if defined(OS_MACOSX)
 
 struct NetworkInterfaceInfo {
   NetworkInterfaceInfo() : permanent(true) { }
@@ -83,10 +121,7 @@
   }
 }
 
-#endif
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-
+#if !defined(OS_IOS)
 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(
     int addr_family, const std::string& interface_name) {
   NetworkChangeNotifier::ConnectionType type =
@@ -111,50 +146,151 @@
   return type;
 }
 
-#endif
+#endif                   // !defined(OS_IOS)
+#elif !defined(OS_NACL)  // OS_MACOSX
 
+// Convert platform native IPv6 address attributes to net IP address
+// attributes and drop ones that can't be used by the application
+// layer.
+bool TryConvertNativeToNetIPAttributes(int native_attributes,
+                                       int* net_attributes) {
+  // For Linux/ChromeOS/Android, we disallow addresses with attributes
+  // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these
+  // are still progressing through duplicated address detection (DAD)
+  // and shouldn't be used by the application layer until DAD process
+  // is completed.
+  if (native_attributes & (
+#if !defined(OS_ANDROID)
+    IFA_F_OPTIMISTIC | IFA_F_DADFAILED |
+#endif  // !OS_ANDROID
+    IFA_F_TENTATIVE)) {
+    return false;
+  }
+
+  if (native_attributes & IFA_F_TEMPORARY) {
+    *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
+  }
+
+  if (native_attributes & IFA_F_DEPRECATED) {
+    *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
+  }
+
+  return true;
+}
+#endif  // OS_MACOSX
 }  // namespace
 
+namespace internal {
+
+#if !defined(OS_MACOSX) && !defined(OS_NACL)
+
+inline const unsigned char* GetIPAddressData(const IPAddressNumber& ip) {
+#if defined(OS_ANDROID)
+  return ip.begin();
+#else
+  return ip.data();
+#endif
+}
+
+bool GetNetworkListImpl(
+    NetworkInterfaceList* networks,
+    int policy,
+    const base::hash_set<int>& online_links,
+    const internal::AddressTrackerLinux::AddressMap& address_map,
+    GetInterfaceNameFunction get_interface_name) {
+  std::map<int, std::string> ifnames;
+
+  for (internal::AddressTrackerLinux::AddressMap::const_iterator it =
+           address_map.begin();
+       it != address_map.end();
+       ++it) {
+    // Ignore addresses whose links are not online.
+    if (online_links.find(it->second.ifa_index) == online_links.end())
+      continue;
+
+    sockaddr_storage sock_addr;
+    socklen_t sock_len = sizeof(sockaddr_storage);
+
+    // Convert to sockaddr for next check.
+    if (!IPEndPoint(it->first, 0)
+             .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addr), &sock_len)) {
+      continue;
+    }
+
+    // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
+    if (IsLoopbackOrUnspecifiedAddress(reinterpret_cast<sockaddr*>(&sock_addr)))
+      continue;
+
+    int ip_attributes = IP_ADDRESS_ATTRIBUTE_NONE;
+
+    if (it->second.ifa_family == AF_INET6) {
+      // Ignore addresses whose attributes are not actionable by
+      // the application layer.
+      if (!TryConvertNativeToNetIPAttributes(it->second.ifa_flags,
+                                             &ip_attributes))
+        continue;
+    }
+
+    // Find the name of this link.
+    std::map<int, std::string>::const_iterator itname =
+        ifnames.find(it->second.ifa_index);
+    std::string ifname;
+    if (itname == ifnames.end()) {
+      char buffer[IF_NAMESIZE] = {0};
+      if (get_interface_name(it->second.ifa_index, buffer)) {
+        ifname = ifnames[it->second.ifa_index] = buffer;
+      } else {
+        // Ignore addresses whose interface name can't be retrieved.
+        continue;
+      }
+    } else {
+      ifname = itname->second;
+    }
+
+    // Based on the interface name and policy, determine whether we
+    // should ignore it.
+    if (ShouldIgnoreInterface(ifname, policy))
+      continue;
+
+    networks->push_back(
+        NetworkInterface(ifname,
+                         ifname,
+                         it->second.ifa_index,
+                         NetworkChangeNotifier::CONNECTION_UNKNOWN,
+                         it->first,
+                         it->second.ifa_prefixlen,
+                         ip_attributes));
+  }
+
+  return true;
+}
+#endif
+
+}  // namespace internal
+
 bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
+  if (networks == NULL)
+    return false;
 #if defined(OS_NACL)
   NOTIMPLEMENTED();
   return false;
-#elif defined(OS_ANDROID)
-  std::string network_list = android::GetNetworkList();
-  base::StringTokenizer network_interfaces(network_list, "\n");
-  while (network_interfaces.GetNext()) {
-    std::string network_item = network_interfaces.token();
-    base::StringTokenizer network_tokenizer(network_item, "\t");
-    CHECK(network_tokenizer.GetNext());
-    std::string name = network_tokenizer.token();
+#elif !defined(OS_MACOSX)
 
-    CHECK(network_tokenizer.GetNext());
-    std::string interface_address = network_tokenizer.token();
-    IPAddressNumber address;
-    size_t network_prefix = 0;
-    CHECK(ParseCIDRBlock(network_tokenizer.token(),
-                         &address,
-                         &network_prefix));
+  internal::AddressTrackerLinux tracker;
+  tracker.Init();
 
-    CHECK(network_tokenizer.GetNext());
-    uint32 index = 0;
-    CHECK(base::StringToUint(network_tokenizer.token(), &index));
+  return internal::GetNetworkListImpl(networks,
+                                      policy,
+                                      tracker.GetOnlineLinks(),
+                                      tracker.GetAddressMap(),
+                                      &if_indextoname);
 
-    networks->push_back(
-        NetworkInterface(name,
-                         name,
-                         index,
-                         NetworkChangeNotifier::CONNECTION_UNKNOWN,
-                         address,
-                         network_prefix,
-                         IP_ADDRESS_ATTRIBUTE_NONE));
-  }
-  return true;
-#else
+#else  // Only OS_MACOSX and OS_IOS will run the code below
+
   // getifaddrs() may require IO operations.
   base::ThreadRestrictions::AssertIOAllowed();
 
-#if defined(OS_MACOSX) && !defined(OS_IOS)
+#if !defined(OS_IOS)
   int ioctl_socket = -1;
   if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) {
     // we need a socket to query information about temporary address.
@@ -163,7 +299,7 @@
   }
 #endif
 
-  ifaddrs *interfaces;
+  ifaddrs* interfaces;
   if (getifaddrs(&interfaces) < 0) {
     PLOG(ERROR) << "getifaddrs";
     return false;
@@ -187,41 +323,26 @@
 
     // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
     // configured on non-loopback interfaces.
+    if (IsLoopbackOrUnspecifiedAddress(addr))
+      continue;
+
     int addr_size = 0;
     if (addr->sa_family == AF_INET6) {
-      struct sockaddr_in6* addr_in6 =
-          reinterpret_cast<struct sockaddr_in6*>(addr);
-      struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
-      addr_size = sizeof(*addr_in6);
-      if (IN6_IS_ADDR_LOOPBACK(sin6_addr) ||
-          IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) {
-        continue;
-      }
+      addr_size = sizeof(sockaddr_in6);
     } else if (addr->sa_family == AF_INET) {
-      struct sockaddr_in* addr_in =
-          reinterpret_cast<struct sockaddr_in*>(addr);
-      addr_size = sizeof(*addr_in);
-      if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK ||
-          addr_in->sin_addr.s_addr == 0) {
-        continue;
-      }
-    } else {
-      // Skip non-IP addresses.
-      continue;
+      addr_size = sizeof(sockaddr_in);
     }
 
     const std::string& name = interface->ifa_name;
     // Filter out VMware interfaces, typically named vmnet1 and vmnet8.
-    if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) &&
-        ((name.find("vmnet") != std::string::npos) ||
-         (name.find("vnic") != std::string::npos))) {
+    if (ShouldIgnoreInterface(name, policy)) {
       continue;
     }
 
     NetworkInterfaceInfo network_info;
     NetworkChangeNotifier::ConnectionType connection_type =
         NetworkChangeNotifier::CONNECTION_UNKNOWN;
-#if defined(OS_MACOSX) && !defined(OS_IOS)
+#if !defined(OS_IOS)
     // Check if this is a temporary address. Currently this is only supported
     // on Mac.
     if ((policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) &&
@@ -264,7 +385,7 @@
     }
   }
   freeifaddrs(interfaces);
-#if defined(OS_MACOSX) && !defined(OS_IOS)
+#if !defined(OS_IOS)
   if (ioctl_socket >= 0) {
     close(ioctl_socket);
   }
diff --git a/net/base/net_util_posix.h b/net/base/net_util_posix.h
new file mode 100644
index 0000000..b553d1c
--- /dev/null
+++ b/net/base/net_util_posix.h
@@ -0,0 +1,31 @@
+// Copyright (c) 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 NET_BASE_NET_UTIL_POSIX_H_
+#define NET_BASE_NET_UTIL_POSIX_H_
+
+// This file is only used to expose some of the internals
+// of net_util_posix.cc to tests.
+
+namespace net {
+namespace internal {
+
+#if !defined(OS_MACOSX) && !defined(OS_NACL)
+typedef char* (*GetInterfaceNameFunction)(unsigned int interface_index,
+                                          char* ifname);
+
+NET_EXPORT bool GetNetworkListImpl(
+    NetworkInterfaceList* networks,
+    int policy,
+    const base::hash_set<int>& online_links,
+    const internal::AddressTrackerLinux::AddressMap& address_map,
+    GetInterfaceNameFunction get_interface_name);
+
+#endif  // !OS_MACOSX && !OS_NACL
+
+}  // namespace internal
+
+}  // namespace net
+
+#endif  // NET_BASE_NET_UTIL_POSIX_H_
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 4883ff2..45f0857 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -17,6 +17,11 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/sys_byteorder.h"
 #include "base/time/time.h"
+
+#if !defined(OS_NACL) && !defined(OS_WIN)
+#include <net/if.h>
+#include <netinet/in.h>
+#endif  // !OS_NACL && !OS_WIN
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -25,10 +30,16 @@
 #include <objbase.h>
 #include "base/win/windows_version.h"
 #include "net/base/net_util_win.h"
-#elif !defined(OS_ANDROID)
-#include <net/if.h>
 #endif  // OS_WIN
 
+#if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_WIN)
+#include "net/base/address_tracker_linux.h"
+#endif  // !OS_MACOSX && !OS_NACL && !OS_WIN
+
+#if !defined(OS_WIN)
+#include "net/base/net_util_posix.h"
+#endif  // !OS_WIN
+
 using base::ASCIIToUTF16;
 using base::WideToUTF16;
 
@@ -801,6 +812,152 @@
   }
 }
 
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_NACL)
+
+char* CopyInterfaceName(const char* ifname, int ifname_size, char* output) {
+  EXPECT_LT(ifname_size, IF_NAMESIZE);
+  memcpy(output, ifname, ifname_size);
+  return output;
+}
+
+static const char ifname_em1[] = "em1";
+char* GetInterfaceName(unsigned int interface_index, char* ifname) {
+  return CopyInterfaceName(ifname_em1, arraysize(ifname_em1), ifname);
+}
+
+static const char ifname_vm[] = "vmnet";
+char* GetInterfaceNameVM(unsigned int interface_index, char* ifname) {
+  return CopyInterfaceName(ifname_vm, arraysize(ifname_vm), ifname);
+}
+
+TEST(NetUtilTest, GetNetworkListTrimming) {
+  NetworkInterfaceList results;
+  ::base::hash_set<int> online_links;
+  net::internal::AddressTrackerLinux::AddressMap address_map;
+
+  const unsigned char kIPv6LocalAddr[] = {
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+  const unsigned char kIPv6Addr[] =
+    {0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
+     0xfe, 0xe5, 0x00, 0xc3};
+
+  IPAddressNumber ipv6_local_address(
+      kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
+  IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
+
+  // Interface 1 is offline.
+  struct ifaddrmsg msg = {
+      AF_INET6,
+      1,               /* prefix length */
+      IFA_F_TEMPORARY, /* address flags */
+      0,               /* link scope */
+      1                /* link index */
+  };
+
+  // Address of offline links should be ignored.
+  ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+  EXPECT_TRUE(
+      net::internal::GetNetworkListImpl(&results,
+                                        INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+                                        online_links,
+                                        address_map,
+                                        GetInterfaceName));
+  EXPECT_EQ(results.size(), 0ul);
+
+  // Mark interface 1 online.
+  online_links.insert(1);
+
+  // Local address should be trimmed out.
+  address_map.clear();
+  ASSERT_TRUE(
+      address_map.insert(std::make_pair(ipv6_local_address, msg)).second);
+  EXPECT_TRUE(
+      net::internal::GetNetworkListImpl(&results,
+                                        INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+                                        online_links,
+                                        address_map,
+                                        GetInterfaceName));
+  EXPECT_EQ(results.size(), 0ul);
+
+  // vmware address should return by default.
+  address_map.clear();
+  ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+  EXPECT_TRUE(
+      net::internal::GetNetworkListImpl(&results,
+                                        INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+                                        online_links,
+                                        address_map,
+                                        GetInterfaceNameVM));
+  EXPECT_EQ(results.size(), 1ul);
+  EXPECT_EQ(results[0].name, ifname_vm);
+  EXPECT_EQ(results[0].network_prefix, 1ul);
+  EXPECT_EQ(results[0].address, ipv6_address);
+  results.clear();
+
+  // vmware address should be trimmed out if policy specified so.
+  address_map.clear();
+  ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+  EXPECT_TRUE(
+      net::internal::GetNetworkListImpl(&results,
+                                        EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+                                        online_links,
+                                        address_map,
+                                        GetInterfaceNameVM));
+  EXPECT_EQ(results.size(), 0ul);
+  results.clear();
+
+  // Addresses with banned attributes should be ignored.
+  address_map.clear();
+  msg.ifa_flags = IFA_F_TENTATIVE;
+  ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+  EXPECT_TRUE(
+      net::internal::GetNetworkListImpl(&results,
+                                        INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+                                        online_links,
+                                        address_map,
+                                        GetInterfaceName));
+  EXPECT_EQ(results.size(), 0ul);
+  results.clear();
+
+  // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and
+  // attributes should be translated correctly.
+  address_map.clear();
+  msg.ifa_flags = IFA_F_TEMPORARY;
+  ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+  EXPECT_TRUE(
+      net::internal::GetNetworkListImpl(&results,
+                                        INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+                                        online_links,
+                                        address_map,
+                                        GetInterfaceName));
+  EXPECT_EQ(results.size(), 1ul);
+  EXPECT_EQ(results[0].name, ifname_em1);
+  EXPECT_EQ(results[0].network_prefix, 1ul);
+  EXPECT_EQ(results[0].address, ipv6_address);
+  EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
+  results.clear();
+
+  // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and
+  // attributes should be translated correctly.
+  address_map.clear();
+  msg.ifa_flags = IFA_F_DEPRECATED;
+  ASSERT_TRUE(address_map.insert(std::make_pair(ipv6_address, msg)).second);
+  EXPECT_TRUE(
+      net::internal::GetNetworkListImpl(&results,
+                                        INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES,
+                                        online_links,
+                                        address_map,
+                                        GetInterfaceName));
+  EXPECT_EQ(results.size(), 1ul);
+  EXPECT_EQ(results[0].name, ifname_em1);
+  EXPECT_EQ(results[0].network_prefix, 1ul);
+  EXPECT_EQ(results[0].address, ipv6_address);
+  EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
+  results.clear();
+}
+
+#endif
+
 namespace {
 
 #if defined(OS_WIN)
diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc
index 0f31d5ce..2a6ef4d 100644
--- a/net/base/sdch_manager.cc
+++ b/net/base/sdch_manager.cc
@@ -54,7 +54,12 @@
 bool SdchManager::g_sdch_enabled_ = true;
 
 // static
+#if defined(OS_IOS)
+// Workaround for http://crbug.com/418975; remove when fixed.
+bool SdchManager::g_secure_scheme_supported_ = false;
+#else
 bool SdchManager::g_secure_scheme_supported_ = true;
+#endif
 
 //------------------------------------------------------------------------------
 SdchManager::Dictionary::Dictionary(const std::string& dictionary_text,
diff --git a/net/base/sdch_manager_unittest.cc b/net/base/sdch_manager_unittest.cc
index f6d44be..f1b39e7 100644
--- a/net/base/sdch_manager_unittest.cc
+++ b/net/base/sdch_manager_unittest.cc
@@ -518,12 +518,21 @@
   GURL url("http://www.google.com");
   GURL secure_url("https://www.google.com");
 
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(secure_url));
+#if !defined(OS_IOS)
+  // Workaround for http://crbug.com/418975; remove when fixed.
+  bool expect_https_support = true;
+#else
+  bool expect_https_support = false;
+#endif
 
-  SdchManager::EnableSecureSchemeSupport(false);
   EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
-  EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(secure_url));
+  EXPECT_EQ(expect_https_support,
+            sdch_manager()->IsInSupportedDomain(secure_url));
+
+  SdchManager::EnableSecureSchemeSupport(!expect_https_support);
+  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
+  EXPECT_NE(expect_https_support,
+            sdch_manager()->IsInSupportedDomain(secure_url));
 }
 
 TEST_F(SdchManagerTest, ClearDictionaryData) {
diff --git a/net/base/trace_net_log_observer.cc b/net/base/trace_net_log_observer.cc
index 15960c3..5d98c41 100644
--- a/net/base/trace_net_log_observer.cc
+++ b/net/base/trace_net_log_observer.cc
@@ -19,6 +19,9 @@
 
 namespace {
 
+// TraceLog category for NetLog events.
+const char kNetLogTracingCategory[] = TRACE_DISABLED_BY_DEFAULT("netlog");
+
 class TracedValue : public base::debug::ConvertableToTraceFormat {
  public:
   explicit TracedValue(scoped_ptr<base::Value> value) : value_(value.Pass()) {}
@@ -55,21 +58,24 @@
   switch (entry.phase()) {
     case NetLog::PHASE_BEGIN:
       TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
-          "netlog", NetLog::EventTypeToString(entry.type()), entry.source().id,
+          kNetLogTracingCategory,
+          NetLog::EventTypeToString(entry.type()), entry.source().id,
           "source_type", NetLog::SourceTypeToString(entry.source().type),
           "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
               new TracedValue(params.Pass())));
       break;
     case NetLog::PHASE_END:
       TRACE_EVENT_NESTABLE_ASYNC_END2(
-          "netlog", NetLog::EventTypeToString(entry.type()), entry.source().id,
+          kNetLogTracingCategory,
+          NetLog::EventTypeToString(entry.type()), entry.source().id,
           "source_type", NetLog::SourceTypeToString(entry.source().type),
           "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
               new TracedValue(params.Pass())));
       break;
     case NetLog::PHASE_NONE:
       TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(
-          "netlog", NetLog::EventTypeToString(entry.type()), entry.source().id,
+          kNetLogTracingCategory,
+          NetLog::EventTypeToString(entry.type()), entry.source().id,
           "source_type", NetLog::SourceTypeToString(entry.source().type),
           "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
               new TracedValue(params.Pass())));
diff --git a/net/base/trace_net_log_observer_unittest.cc b/net/base/trace_net_log_observer_unittest.cc
index c1a8803c..2e20707 100644
--- a/net/base/trace_net_log_observer_unittest.cc
+++ b/net/base/trace_net_log_observer_unittest.cc
@@ -27,6 +27,9 @@
 
 namespace {
 
+// TraceLog category for NetLog events.
+const char kNetLogTracingCategory[] = TRACE_DISABLED_BY_DEFAULT("netlog");
+
 struct TraceEntryInfo {
   std::string category;
   std::string id;
@@ -86,9 +89,10 @@
   }
 
   static void EnableTraceLog() {
-    TraceLog::GetInstance()->SetEnabled(base::debug::CategoryFilter("netlog"),
-                                        TraceLog::RECORDING_MODE,
-                                        base::debug::TraceOptions());
+    TraceLog::GetInstance()->SetEnabled(
+        base::debug::CategoryFilter(kNetLogTracingCategory),
+        TraceLog::RECORDING_MODE,
+        base::debug::TraceOptions());
   }
 
   void EndTraceAndFlush() {
@@ -120,7 +124,7 @@
             << "Unexpected item without a category field in trace_events";
         continue;
       }
-      if (category != "netlog")
+      if (category != kNetLogTracingCategory)
         continue;
       filtered_trace_events->Append(dict->DeepCopy());
     }
@@ -185,7 +189,7 @@
   TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
   TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
   TraceEntryInfo actual_item3 = GetTraceEntryInfoFromValue(*item3);
-  EXPECT_EQ("netlog", actual_item1.category);
+  EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
   EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id);
   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
             actual_item1.phase);
@@ -194,7 +198,7 @@
   EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
             actual_item1.source_type);
 
-  EXPECT_EQ("netlog", actual_item2.category);
+  EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
   EXPECT_EQ(base::StringPrintf("0x%d", entries[1].source.id), actual_item2.id);
   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN),
             actual_item2.phase);
@@ -203,7 +207,7 @@
   EXPECT_EQ(NetLog::SourceTypeToString(entries[1].source.type),
             actual_item2.source_type);
 
-  EXPECT_EQ("netlog", actual_item3.category);
+  EXPECT_EQ(kNetLogTracingCategory, actual_item3.category);
   EXPECT_EQ(base::StringPrintf("0x%d", entries[2].source.id), actual_item3.id);
   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_END),
             actual_item3.phase);
@@ -236,7 +240,7 @@
 
   TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
   TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
-  EXPECT_EQ("netlog", actual_item1.category);
+  EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
   EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id);
   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
             actual_item1.phase);
@@ -245,7 +249,7 @@
   EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
             actual_item1.source_type);
 
-  EXPECT_EQ("netlog", actual_item2.category);
+  EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
   EXPECT_EQ(base::StringPrintf("0x%d", entries[2].source.id), actual_item2.id);
   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
             actual_item2.phase);
@@ -274,7 +278,7 @@
   ASSERT_TRUE(trace_events()->GetDictionary(0, &item1));
 
   TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
-  EXPECT_EQ("netlog", actual_item1.category);
+  EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
   EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id);
   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
             actual_item1.phase);
@@ -342,7 +346,7 @@
 
   TraceEntryInfo actual_item1 = GetTraceEntryInfoFromValue(*item1);
   TraceEntryInfo actual_item2 = GetTraceEntryInfoFromValue(*item2);
-  EXPECT_EQ("netlog", actual_item1.category);
+  EXPECT_EQ(kNetLogTracingCategory, actual_item1.category);
   EXPECT_EQ(base::StringPrintf("0x%d", entries[0].source.id), actual_item1.id);
   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
             actual_item1.phase);
@@ -351,7 +355,7 @@
   EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type),
             actual_item1.source_type);
 
-  EXPECT_EQ("netlog", actual_item2.category);
+  EXPECT_EQ(kNetLogTracingCategory, actual_item2.category);
   EXPECT_EQ(base::StringPrintf("0x%d", entries[1].source.id), actual_item2.id);
   EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT),
             actual_item2.phase);
diff --git a/net/cert/x509_certificate.h b/net/cert/x509_certificate.h
index 97906ed..008de71f 100644
--- a/net/cert/x509_certificate.h
+++ b/net/cert/x509_certificate.h
@@ -395,6 +395,10 @@
   // the same.
   static SHA1HashValue CalculateFingerprint(OSCertHandle cert_handle);
 
+  // Calculates the SHA-256 fingerprint of the certificate.  Returns an empty
+  // (all zero) fingerprint on failure.
+  static SHA256HashValue CalculateFingerprint256(OSCertHandle cert_handle);
+
   // Calculates the SHA-1 fingerprint of the intermediate CA certificates.
   // Returns an empty (all zero) fingerprint on failure.
   //
diff --git a/net/cert/x509_certificate_ios.cc b/net/cert/x509_certificate_ios.cc
index f59cb65..b0908b7 100644
--- a/net/cert/x509_certificate_ios.cc
+++ b/net/cert/x509_certificate_ios.cc
@@ -186,6 +186,22 @@
 }
 
 // static
+SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
+  SHA256HashValue sha256;
+  memset(sha256.data, 0, sizeof(sha256.data));
+
+  ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
+  if (!cert_data)
+    return sha256;
+  DCHECK(CFDataGetBytePtr(cert_data));
+  DCHECK_NE(0, CFDataGetLength(cert_data));
+  CC_SHA256(
+      CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha256.data);
+
+  return sha256;
+}
+
+// static
 SHA1HashValue X509Certificate::CalculateCAFingerprint(
     const OSCertHandles& intermediates) {
   SHA1HashValue sha1;
diff --git a/net/cert/x509_certificate_mac.cc b/net/cert/x509_certificate_mac.cc
index 716bdd5..ecdf137 100644
--- a/net/cert/x509_certificate_mac.cc
+++ b/net/cert/x509_certificate_mac.cc
@@ -374,6 +374,24 @@
 }
 
 // static
+SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
+  SHA256HashValue sha256;
+  memset(sha256.data, 0, sizeof(sha256.data));
+
+  CSSM_DATA cert_data;
+  OSStatus status = SecCertificateGetData(cert, &cert_data);
+  if (status)
+    return sha256;
+
+  DCHECK(cert_data.Data);
+  DCHECK_NE(cert_data.Length, 0U);
+
+  CC_SHA256(cert_data.Data, cert_data.Length, sha256.data);
+
+  return sha256;
+}
+
+// static
 SHA1HashValue X509Certificate::CalculateCAFingerprint(
     const OSCertHandles& intermediates) {
   SHA1HashValue sha1;
diff --git a/net/cert/x509_certificate_nss.cc b/net/cert/x509_certificate_nss.cc
index 9019625..a57f9ce7 100644
--- a/net/cert/x509_certificate_nss.cc
+++ b/net/cert/x509_certificate_nss.cc
@@ -225,6 +225,21 @@
 }
 
 // static
+SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
+  SHA256HashValue sha256;
+  memset(sha256.data, 0, sizeof(sha256.data));
+
+  DCHECK(NULL != cert->derCert.data);
+  DCHECK_NE(0U, cert->derCert.len);
+
+  SECStatus rv = HASH_HashBuf(
+      HASH_AlgSHA256, sha256.data, cert->derCert.data, cert->derCert.len);
+  DCHECK_EQ(SECSuccess, rv);
+
+  return sha256;
+}
+
+// static
 SHA1HashValue X509Certificate::CalculateCAFingerprint(
     const OSCertHandles& intermediates) {
   SHA1HashValue sha1;
diff --git a/net/cert/x509_certificate_openssl.cc b/net/cert/x509_certificate_openssl.cc
index 9cb0670..91501f84 100644
--- a/net/cert/x509_certificate_openssl.cc
+++ b/net/cert/x509_certificate_openssl.cc
@@ -230,6 +230,16 @@
 }
 
 // static
+SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
+  SHA256HashValue sha256;
+  unsigned int sha256_size = static_cast<unsigned int>(sizeof(sha256.data));
+  int ret = X509_digest(cert, EVP_sha256(), sha256.data, &sha256_size);
+  CHECK(ret);
+  CHECK_EQ(sha256_size, sizeof(sha256.data));
+  return sha256;
+}
+
+// static
 SHA1HashValue X509Certificate::CalculateCAFingerprint(
     const OSCertHandles& intermediates) {
   SHA1HashValue sha1;
diff --git a/net/cert/x509_certificate_unittest.cc b/net/cert/x509_certificate_unittest.cc
index 158806e..33985104 100644
--- a/net/cert/x509_certificate_unittest.cc
+++ b/net/cert/x509_certificate_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/sha1.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
 #include "crypto/rsa_private_key.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_data_directory.h"
@@ -323,6 +324,22 @@
                      paypal_null_serial, sizeof(paypal_null_serial)) == 0);
 }
 
+TEST(X509CertificateTest, SHA256FingerprintsCorrectly) {
+  scoped_refptr<X509Certificate> google_cert(X509Certificate::CreateFromBytes(
+      reinterpret_cast<const char*>(google_der), sizeof(google_der)));
+
+  static const uint8 google_sha256_fingerprint[32] = {
+      0x21, 0xaf, 0x58, 0x74, 0xea, 0x6b, 0xad, 0xbd, 0xe4, 0xb3, 0xb1,
+      0xaa, 0x53, 0x32, 0x80, 0x8f, 0xbf, 0x8a, 0x24, 0x7d, 0x98, 0xec,
+      0x7f, 0x77, 0x49, 0x38, 0x42, 0x81, 0x26, 0x7f, 0xed, 0x38};
+
+  SHA256HashValue fingerprint =
+      X509Certificate::CalculateFingerprint256(google_cert->os_cert_handle());
+
+  for (size_t i = 0; i < 32; ++i)
+    EXPECT_EQ(google_sha256_fingerprint[i], fingerprint.data[i]);
+}
+
 TEST(X509CertificateTest, CAFingerprints) {
   base::FilePath certs_dir = GetTestCertsDirectory();
 
diff --git a/net/cert/x509_certificate_win.cc b/net/cert/x509_certificate_win.cc
index ab92b6f..df263d8 100644
--- a/net/cert/x509_certificate_win.cc
+++ b/net/cert/x509_certificate_win.cc
@@ -14,6 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "crypto/capi_util.h"
 #include "crypto/scoped_capi_types.h"
+#include "crypto/sha2.h"
 #include "net/base/net_errors.h"
 
 #pragma comment(lib, "crypt32.lib")
@@ -315,6 +316,24 @@
   return sha1;
 }
 
+// static
+SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
+  DCHECK(NULL != cert->pbCertEncoded);
+  DCHECK_NE(0u, cert->cbCertEncoded);
+
+  SHA256HashValue sha256;
+  size_t sha256_size = sizeof(sha256.data);
+
+  // Use crypto::SHA256HashString for two reasons:
+  // * < Windows Vista does not have universal SHA-256 support.
+  // * More efficient on Windows > Vista (less overhead since non-default CSP
+  // is not needed).
+  base::StringPiece der_cert(reinterpret_cast<const char*>(cert->pbCertEncoded),
+                             cert->cbCertEncoded);
+  crypto::SHA256HashString(der_cert, sha256.data, sha256_size);
+  return sha256;
+}
+
 // TODO(wtc): This function is implemented with NSS low-level hash
 // functions to ensure it is fast.  Reimplement this function with
 // CryptoAPI.  May need to cache the HCRYPTPROV to reduce the overhead.
diff --git a/net/http/disk_cache_based_quic_server_info.cc b/net/http/disk_cache_based_quic_server_info.cc
index d55349e1..44332c9 100644
--- a/net/http/disk_cache_based_quic_server_info.cc
+++ b/net/http/disk_cache_based_quic_server_info.cc
@@ -78,6 +78,7 @@
 void DiskCacheBasedQuicServerInfo::Start() {
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(GET_BACKEND, state_);
+  load_start_time_ = base::TimeTicks::Now();
   DoLoop(OK);
 }
 
@@ -312,6 +313,8 @@
   }
   entry_ = NULL;
   Parse(data_);
+  UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheLoadTime",
+                      base::TimeTicks::Now() - load_start_time_);
   return OK;
 }
 
diff --git a/net/http/disk_cache_based_quic_server_info.h b/net/http/disk_cache_based_quic_server_info.h
index e5ced3f2..f904042 100644
--- a/net/http/disk_cache_based_quic_server_info.h
+++ b/net/http/disk_cache_based_quic_server_info.h
@@ -10,6 +10,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/non_thread_safe.h"
+#include "base/time/time.h"
 #include "net/base/completion_callback.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/quic/crypto/quic_server_info.h"
@@ -98,6 +99,7 @@
   scoped_refptr<IOBuffer> read_buffer_;
   scoped_refptr<IOBuffer> write_buffer_;
   std::string data_;
+  base::TimeTicks load_start_time_;
 
   base::WeakPtrFactory<DiskCacheBasedQuicServerInfo> weak_factory_;
 };
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 5441e90..c39a38a 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -1208,6 +1208,7 @@
     UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED);
   }
 
+  // Invalidate any cached GET with a successful PUT or DELETE.
   if (mode_ == WRITE &&
       (request_->method == "PUT" || request_->method == "DELETE")) {
     if (NonErrorResponse(new_response->headers->response_code())) {
@@ -1219,7 +1220,9 @@
     mode_ = NONE;
   }
 
-  if (request_->method == "POST" &&
+  // Invalidate any cached GET with a successful POST.
+  if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) &&
+      request_->method == "POST" &&
       NonErrorResponse(new_response->headers->response_code())) {
     cache_->DoomMainEntryForUrl(request_->url);
   }
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index a0225e8..5199368 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -2741,6 +2741,18 @@
   EXPECT_EQ(0, cache.disk_cache()->create_count());
 }
 
+// Tests POST handling with a disabled cache (no DCHECK).
+TEST(HttpCache, SimplePOST_DisabledCache) {
+  MockHttpCache cache;
+  cache.http_cache()->set_mode(net::HttpCache::Mode::DISABLE);
+
+  RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
+
+  EXPECT_EQ(1, cache.network_layer()->transaction_count());
+  EXPECT_EQ(0, cache.disk_cache()->open_count());
+  EXPECT_EQ(0, cache.disk_cache()->create_count());
+}
+
 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
   MockHttpCache cache;
 
diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc
index 601646a..a9cbd72 100644
--- a/net/http/http_server_properties.cc
+++ b/net/http/http_server_properties.cc
@@ -31,20 +31,9 @@
 
 }  // namespace
 
-void HistogramAlternateProtocolUsage(
-    AlternateProtocolUsage usage,
-    AlternateProtocolExperiment alternate_protocol_experiment) {
+void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage) {
   UMA_HISTOGRAM_ENUMERATION("Net.AlternateProtocolUsage", usage,
                             ALTERNATE_PROTOCOL_USAGE_MAX);
-  if (alternate_protocol_experiment ==
-      ALTERNATE_PROTOCOL_TRUNCATED_200_SERVERS) {
-    UMA_HISTOGRAM_ENUMERATION("Net.AlternateProtocolUsage.200Truncated", usage,
-                              ALTERNATE_PROTOCOL_USAGE_MAX);
-  } else if (alternate_protocol_experiment ==
-      ALTERNATE_PROTOCOL_TRUNCATED_1000_SERVERS) {
-    UMA_HISTOGRAM_ENUMERATION("Net.AlternateProtocolUsage.1000Truncated", usage,
-                              ALTERNATE_PROTOCOL_USAGE_MAX);
-  }
 }
 
 void HistogramBrokenAlternateProtocolLocation(
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h
index ae12052..e171075 100644
--- a/net/http/http_server_properties.h
+++ b/net/http/http_server_properties.h
@@ -18,15 +18,6 @@
 
 namespace net {
 
-enum AlternateProtocolExperiment {
-  // 200 alternate_protocol servers are loaded (persisted 200 MRU servers).
-  ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT = 0,
-  // 200 alternate_protocol servers are loaded (persisted 1000 MRU servers).
-  ALTERNATE_PROTOCOL_TRUNCATED_200_SERVERS,
-  // 1000 alternate_protocol servers are loaded (persisted 1000 MRU servers).
-  ALTERNATE_PROTOCOL_TRUNCATED_1000_SERVERS,
-};
-
 enum AlternateProtocolUsage {
   // Alternate Protocol was used without racing a normal connection.
   ALTERNATE_PROTOCOL_USAGE_NO_RACE = 0,
@@ -44,10 +35,8 @@
   ALTERNATE_PROTOCOL_USAGE_MAX,
 };
 
-// Log a histogram to reflect |usage| and |alternate_protocol_experiment|.
-NET_EXPORT void HistogramAlternateProtocolUsage(
-    AlternateProtocolUsage usage,
-    AlternateProtocolExperiment alternate_protocol_experiment);
+// Log a histogram to reflect |usage|.
+NET_EXPORT void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage);
 
 enum BrokenAlternateProtocolLocation {
   BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB = 0,
@@ -193,9 +182,6 @@
   // Returns all Alternate-Protocol mappings.
   virtual const AlternateProtocolMap& alternate_protocol_map() const = 0;
 
-  virtual void SetAlternateProtocolExperiment(
-      AlternateProtocolExperiment experiment) = 0;
-
   // Sets the threshold to be used when evaluating Alternate-Protocol
   // advertisments. Only advertisements with a with a probability
   // greater than |threshold| will be honored. |threshold| must be
@@ -204,9 +190,6 @@
   virtual void SetAlternateProtocolProbabilityThreshold(
       double threshold) = 0;
 
-  virtual AlternateProtocolExperiment GetAlternateProtocolExperiment()
-      const = 0;
-
   // Gets a reference to the SettingsMap stored for a host.
   // If no settings are stored, returns an empty SettingsMap.
   virtual const SettingsMap& GetSpdySettings(
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc
index c55f32b..201e19f 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -23,8 +23,6 @@
 HttpServerPropertiesImpl::HttpServerPropertiesImpl()
     : spdy_servers_map_(SpdyServerHostPortMap::NO_AUTO_EVICT),
       alternate_protocol_map_(AlternateProtocolMap::NO_AUTO_EVICT),
-      alternate_protocol_experiment_(
-          ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT),
       spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT),
       alternate_protocol_probability_threshold_(1),
       weak_ptr_factory_(this) {
@@ -287,8 +285,7 @@
       // TODO(rch): Consider the case where multiple requests are started
       // before the first completes. In this case, only one of the jobs
       // would reach this code, whereas all of them should should have.
-      HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING,
-                                      alternate_protocol_experiment_);
+      HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING);
     }
   }
 
@@ -361,16 +358,6 @@
   return alternate_protocol_map_;
 }
 
-void HttpServerPropertiesImpl::SetAlternateProtocolExperiment(
-    AlternateProtocolExperiment experiment) {
-  alternate_protocol_experiment_ = experiment;
-}
-
-AlternateProtocolExperiment
-HttpServerPropertiesImpl::GetAlternateProtocolExperiment() const {
-  return alternate_protocol_experiment_;
-}
-
 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings(
     const HostPortPair& host_port_pair) {
   SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair);
diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h
index 7b5f2f6..222d609 100644
--- a/net/http/http_server_properties_impl.h
+++ b/net/http/http_server_properties_impl.h
@@ -109,13 +109,8 @@
   // Returns all Alternate-Protocol mappings.
   const AlternateProtocolMap& alternate_protocol_map() const override;
 
-  void SetAlternateProtocolExperiment(
-      AlternateProtocolExperiment experiment) override;
-
   void SetAlternateProtocolProbabilityThreshold(double threshold) override;
 
-  AlternateProtocolExperiment GetAlternateProtocolExperiment() const override;
-
   // Gets a reference to the SettingsMap stored for a host.
   // If no settings are stored, returns an empty SettingsMap.
   const SettingsMap& GetSpdySettings(
@@ -184,7 +179,6 @@
   AlternateProtocolMap alternate_protocol_map_;
   BrokenAlternateProtocolList broken_alternate_protocol_list_;
   BrokenAlternateProtocolMap broken_alternate_protocol_map_;
-  AlternateProtocolExperiment alternate_protocol_experiment_;
 
   SpdySettingsMap spdy_settings_map_;
   SupportsQuicMap supports_quic_map_;
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc
index 08e4f6a..6796fb1 100644
--- a/net/http/http_server_properties_manager.cc
+++ b/net/http/http_server_properties_manager.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
-#include "base/rand_util.h"
 #include "base/single_thread_task_runner.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -44,11 +43,8 @@
 
 typedef std::vector<std::string> StringVector;
 
-// Load either 200 or 1000 servers based on a coin flip.
-const int k200AlternateProtocolHostsToLoad = 200;
-const int k1000AlternateProtocolHostsToLoad = 1000;
-// Persist 1000 MRU AlternateProtocolHostPortPairs.
-const int kMaxAlternateProtocolHostsToPersist = 1000;
+// Persist 200 MRU AlternateProtocolHostPortPairs.
+const int kMaxAlternateProtocolHostsToPersist = 200;
 
 // Persist 200 MRU SpdySettingsHostPortPairs.
 const int kMaxSpdySettingsHostsToPersist = 200;
@@ -213,12 +209,6 @@
   return http_server_properties_impl_->alternate_protocol_map();
 }
 
-void HttpServerPropertiesManager::SetAlternateProtocolExperiment(
-    AlternateProtocolExperiment experiment) {
-  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
-  http_server_properties_impl_->SetAlternateProtocolExperiment(experiment);
-}
-
 void HttpServerPropertiesManager::SetAlternateProtocolProbabilityThreshold(
     double threshold) {
   DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
@@ -226,12 +216,6 @@
       threshold);
 }
 
-AlternateProtocolExperiment
-HttpServerPropertiesManager::GetAlternateProtocolExperiment() const {
-  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
-  return http_server_properties_impl_->GetAlternateProtocolExperiment();
-}
-
 const SettingsMap& HttpServerPropertiesManager::GetSpdySettings(
     const HostPortPair& host_port_pair) {
   DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
@@ -363,22 +347,6 @@
       new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist));
   scoped_ptr<net::SupportsQuicMap> supports_quic_map(
       new net::SupportsQuicMap());
-  // TODO(rtenneti): Delete the following code after the experiment.
-  int alternate_protocols_to_load = k200AlternateProtocolHostsToLoad;
-  net::AlternateProtocolExperiment alternate_protocol_experiment =
-      net::ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT;
-  if (version == kVersionNumber) {
-    if (base::RandInt(0, 99) == 0) {
-      alternate_protocol_experiment =
-          net::ALTERNATE_PROTOCOL_TRUNCATED_200_SERVERS;
-    } else {
-      alternate_protocols_to_load = k1000AlternateProtocolHostsToLoad;
-      alternate_protocol_experiment =
-          net::ALTERNATE_PROTOCOL_TRUNCATED_1000_SERVERS;
-    }
-    DVLOG(1) << "# of servers that support alternate_protocol: "
-             << alternate_protocols_to_load;
-  }
 
   int count = 0;
   for (base::DictionaryValue::Iterator it(*servers_dict); !it.IsAtEnd();
@@ -445,7 +413,7 @@
       continue;
     }
 
-    if (count >= alternate_protocols_to_load)
+    if (count >= kMaxAlternateProtocolHostsToPersist)
       continue;
     do {
       int port = 0;
@@ -522,7 +490,6 @@
           base::Owned(spdy_servers.release()),
           base::Owned(spdy_settings_map.release()),
           base::Owned(alternate_protocol_map.release()),
-          alternate_protocol_experiment,
           base::Owned(supports_quic_map.release()),
           detected_corrupted_prefs));
 }
@@ -531,7 +498,6 @@
     StringVector* spdy_servers,
     net::SpdySettingsMap* spdy_settings_map,
     net::AlternateProtocolMap* alternate_protocol_map,
-    net::AlternateProtocolExperiment alternate_protocol_experiment,
     net::SupportsQuicMap* supports_quic_map,
     bool detected_corrupted_prefs) {
   // Preferences have the master data because admins might have pushed new
@@ -552,8 +518,6 @@
                        alternate_protocol_map->size());
   http_server_properties_impl_->InitializeAlternateProtocolServers(
       alternate_protocol_map);
-  http_server_properties_impl_->SetAlternateProtocolExperiment(
-      alternate_protocol_experiment);
 
   http_server_properties_impl_->InitializeSupportsQuic(supports_quic_map);
 
diff --git a/net/http/http_server_properties_manager.h b/net/http/http_server_properties_manager.h
index 79506c4..4acf76f 100644
--- a/net/http/http_server_properties_manager.h
+++ b/net/http/http_server_properties_manager.h
@@ -120,13 +120,8 @@
   // Returns all Alternate-Protocol mappings.
   const AlternateProtocolMap& alternate_protocol_map() const override;
 
-  void SetAlternateProtocolExperiment(
-      AlternateProtocolExperiment experiment) override;
-
   void SetAlternateProtocolProbabilityThreshold(double threshold) override;
 
-  AlternateProtocolExperiment GetAlternateProtocolExperiment() const override;
-
   // Gets a reference to the SettingsMap stored for a host.
   // If no settings are stored, returns an empty SettingsMap.
   const SettingsMap& GetSpdySettings(
@@ -189,7 +184,6 @@
       std::vector<std::string>* spdy_servers,
       SpdySettingsMap* spdy_settings_map,
       AlternateProtocolMap* alternate_protocol_map,
-      AlternateProtocolExperiment alternate_protocol_experiment,
       SupportsQuicMap* supports_quic_map,
       bool detected_corrupted_prefs);
 
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc
index dbbfc2d..fcc253e 100644
--- a/net/http/http_server_properties_manager_unittest.cc
+++ b/net/http/http_server_properties_manager_unittest.cc
@@ -67,11 +67,10 @@
 
   MOCK_METHOD0(UpdateCacheFromPrefsOnPrefThread, void());
   MOCK_METHOD1(UpdatePrefsFromCacheOnNetworkThread, void(const base::Closure&));
-  MOCK_METHOD6(UpdateCacheFromPrefsOnNetworkThread,
+  MOCK_METHOD5(UpdateCacheFromPrefsOnNetworkThread,
                void(std::vector<std::string>* spdy_servers,
                     net::SpdySettingsMap* spdy_settings_map,
                     net::AlternateProtocolMap* alternate_protocol_map,
-                    net::AlternateProtocolExperiment experiment,
                     net::SupportsQuicMap* supports_quic_map,
                     bool detected_corrupted_prefs));
   MOCK_METHOD4(UpdatePrefsOnPref,
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc
index ced5f2b..689bcf9 100644
--- a/net/http/http_stream_factory_impl.cc
+++ b/net/http/http_stream_factory_impl.cc
@@ -195,9 +195,7 @@
   AlternateProtocolInfo alternate =
       http_server_properties.GetAlternateProtocol(origin);
   if (alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) {
-    HistogramAlternateProtocolUsage(
-        ALTERNATE_PROTOCOL_USAGE_BROKEN,
-        http_server_properties.GetAlternateProtocolExperiment());
+    HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN);
     return kNoAlternateProtocol;
   }
 
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
index 45d152a..a11dd2e9 100644
--- a/net/http/http_stream_factory_impl_job.cc
+++ b/net/http/http_stream_factory_impl_job.cc
@@ -1430,28 +1430,17 @@
 }
 
 void HttpStreamFactoryImpl::Job::ReportJobSuccededForRequest() {
-  net::AlternateProtocolExperiment alternate_protocol_experiment =
-      ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT;
-  base::WeakPtr<HttpServerProperties> http_server_properties =
-      session_->http_server_properties();
-  if (http_server_properties) {
-    alternate_protocol_experiment =
-        http_server_properties->GetAlternateProtocolExperiment();
-  }
   if (using_existing_quic_session_) {
     // If an existing session was used, then no TCP connection was
     // started.
-    HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE,
-                                    alternate_protocol_experiment);
+    HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_NO_RACE);
   } else if (original_url_) {
     // This job was the alternate protocol job, and hence won the race.
-    HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE,
-                                    alternate_protocol_experiment);
+    HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_WON_RACE);
   } else {
     // This job was the normal job, and hence the alternate protocol job lost
     // the race.
-    HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE,
-                                    alternate_protocol_experiment);
+    HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_LOST_RACE);
   }
 }
 
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index b5ca18b..205a571 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -47,7 +47,6 @@
 
 base::Value* NetLogQuicPacketSentCallback(
     const SerializedPacket& serialized_packet,
-    QuicPacketSequenceNumber original_sequence_number,
     EncryptionLevel level,
     TransmissionType transmission_type,
     size_t packet_size,
@@ -58,13 +57,23 @@
   dict->SetInteger("transmission_type", transmission_type);
   dict->SetString("packet_sequence_number",
                   base::Uint64ToString(serialized_packet.sequence_number));
-  dict->SetString("original_sequence_number",
-                  base::Uint64ToString(original_sequence_number));
   dict->SetInteger("size", packet_size);
   dict->SetInteger("sent_time_us", sent_time.ToDebuggingValue());
   return dict;
 }
 
+base::Value* NetLogQuicPacketRetransmittedCallback(
+    QuicPacketSequenceNumber old_sequence_number,
+    QuicPacketSequenceNumber new_sequence_number,
+    NetLog::LogLevel /* log_level */) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetString("old_packet_sequence_number",
+                  base::Uint64ToString(old_sequence_number));
+  dict->SetString("new_packet_sequence_number",
+                  base::Uint64ToString(new_sequence_number));
+  return dict;
+}
+
 base::Value* NetLogQuicPacketHeaderCallback(const QuicPacketHeader* header,
                                             NetLog::LogLevel /* log_level */) {
   base::DictionaryValue* dict = new base::DictionaryValue();
@@ -339,6 +348,8 @@
       num_incorrect_connection_ids_(0),
       num_undecryptable_packets_(0),
       num_duplicate_packets_(0),
+      num_blocked_frames_received_(0),
+      num_blocked_frames_sent_(0),
       connection_description_(GetConnectionDescriptionString()) {
 }
 
@@ -355,6 +366,10 @@
                        num_undecryptable_packets_);
   UMA_HISTOGRAM_COUNTS("Net.QuicSession.DuplicatePacketsReceived",
                        num_duplicate_packets_);
+  UMA_HISTOGRAM_COUNTS("Net.QuicSession.BlockedFrames.Received",
+                       num_blocked_frames_received_);
+  UMA_HISTOGRAM_COUNTS("Net.QuicSession.BlockedFrames.Sent",
+                       num_blocked_frames_sent_);
 
   if (num_frames_received_ > 0) {
     int duplicate_stream_frame_per_thousand =
@@ -442,6 +457,7 @@
                      frame.window_update_frame));
       break;
     case BLOCKED_FRAME:
+      ++num_blocked_frames_sent_;
       net_log_.AddEvent(
           NetLog::TYPE_QUIC_SESSION_BLOCKED_FRAME_SENT,
           base::Bind(&NetLogQuicBlockedFrameCallback,
@@ -473,11 +489,18 @@
     TransmissionType transmission_type,
     const QuicEncryptedPacket& packet,
     QuicTime sent_time) {
-  net_log_.AddEvent(
-      NetLog::TYPE_QUIC_SESSION_PACKET_SENT,
-      base::Bind(&NetLogQuicPacketSentCallback, serialized_packet,
-                 original_sequence_number, level, transmission_type,
-                 packet.length(), sent_time));
+  if (original_sequence_number == 0) {
+    net_log_.AddEvent(
+        NetLog::TYPE_QUIC_SESSION_PACKET_SENT,
+        base::Bind(&NetLogQuicPacketSentCallback, serialized_packet,
+                   level, transmission_type, packet.length(), sent_time));
+  }  else {
+    net_log_.AddEvent(
+        NetLog::TYPE_QUIC_SESSION_PACKET_RETRANSMITTED,
+        base::Bind(&NetLogQuicPacketRetransmittedCallback,
+                   original_sequence_number,
+                   serialized_packet.sequence_number));
+  }
 }
 
 void QuicConnectionLogger::OnPacketReceived(const IPEndPoint& self_address,
@@ -636,6 +659,7 @@
 }
 
 void QuicConnectionLogger::OnBlockedFrame(const QuicBlockedFrame& frame) {
+  ++num_blocked_frames_received_;
   net_log_.AddEvent(
       NetLog::TYPE_QUIC_SESSION_BLOCKED_FRAME_RECEIVED,
       base::Bind(&NetLogQuicBlockedFrameCallback, &frame));
diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h
index 1d38049e..29acfdc 100644
--- a/net/quic/quic_connection_logger.h
+++ b/net/quic/quic_connection_logger.h
@@ -151,6 +151,10 @@
   int num_undecryptable_packets_;
   // Count of the number of duplicate packets received.
   int num_duplicate_packets_;
+  // Count of the number of BLOCKED frames received.
+  int num_blocked_frames_received_;
+  // Count of the number of BLOCKED frames sent.
+  int num_blocked_frames_sent_;
   // Vector of inital packets status' indexed by packet sequence numbers, where
   // false means never received.  Zero is not a valid packet sequence number, so
   // that offset is never used, and we'll track 150 packets.
diff --git a/net/quic/quic_reliable_client_stream.cc b/net/quic/quic_reliable_client_stream.cc
index b1a82d1..e186b03e 100644
--- a/net/quic/quic_reliable_client_stream.cc
+++ b/net/quic/quic_reliable_client_stream.cc
@@ -42,12 +42,12 @@
   return data_len;
 }
 
-void QuicReliableClientStream::OnFinRead() {
+void QuicReliableClientStream::OnClose() {
   if (delegate_) {
     delegate_->OnClose(connection_error());
     delegate_ = nullptr;
   }
-  ReliableQuicStream::OnFinRead();
+  ReliableQuicStream::OnClose();
 }
 
 void QuicReliableClientStream::OnCanWrite() {
diff --git a/net/quic/quic_reliable_client_stream.h b/net/quic/quic_reliable_client_stream.h
index 9ed6601..48f5cc9 100644
--- a/net/quic/quic_reliable_client_stream.h
+++ b/net/quic/quic_reliable_client_stream.h
@@ -55,7 +55,7 @@
 
   // QuicDataStream
   uint32 ProcessData(const char* data, uint32 data_len) override;
-  void OnFinRead() override;
+  void OnClose() override;
   void OnCanWrite() override;
   QuicPriority EffectivePriority() const override;
 
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index 0a5032e..77a9e89 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -729,23 +729,26 @@
   EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
   QuicStreamId stream_id = 5;
   // Write until the header stream is flow control blocked.
-  while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2010) {
+  SpdyHeaderBlock headers;
+  while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) {
     EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
     EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
-    SpdyHeaderBlock headers;
     headers["header"] = base::Uint64ToString(base::RandUint64()) +
         base::Uint64ToString(base::RandUint64()) +
         base::Uint64ToString(base::RandUint64());
     headers_stream->WriteHeaders(stream_id, headers, true, nullptr);
     stream_id += 2;
   }
+  // Write one more to ensure that the headers stream has buffered data. The
+  // random headers may have exactly filled the flow control window.
+  headers_stream->WriteHeaders(stream_id, headers, true, nullptr);
+  EXPECT_TRUE(headers_stream->HasBufferedData());
+
   EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked());
   EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
   EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
   EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
   EXPECT_FALSE(session_.HasDataToWrite());
-  // TODO(rtenneti): crbug.com/423586 headers_stream->HasBufferedData is flaky.
-  // EXPECT_TRUE(headers_stream->HasBufferedData());
 
   // Now complete the crypto handshake, resulting in an increased flow control
   // send window.
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index dac30962..046c0a1 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -312,7 +312,6 @@
 int QuicStreamFactory::Job::DoResolveHost() {
   // Start loading the data now, and wait for it after we resolve the host.
   if (server_info_) {
-    disk_cache_load_start_time_ = base::TimeTicks::Now();
     server_info_->Start();
   }
 
@@ -351,6 +350,7 @@
   if (!server_info_)
     return OK;
 
+  disk_cache_load_start_time_ = base::TimeTicks::Now();
   return server_info_->WaitForDataReady(
       base::Bind(&QuicStreamFactory::Job::OnIOComplete,
                  weak_factory_.GetWeakPtr()));
@@ -358,7 +358,7 @@
 
 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) {
   if (server_info_) {
-    UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheReadTime",
+    UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime",
                         base::TimeTicks::Now() - disk_cache_load_start_time_);
   }
 
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index 953f3363..fc74d8c 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -632,7 +632,7 @@
   user_read_buf_ = buf;
   user_read_buf_len_ = buf_len;
 
-  int rv = DoReadLoop(OK);
+  int rv = DoReadLoop();
 
   if (rv == ERR_IO_PENDING) {
     user_read_callback_ = callback;
@@ -657,7 +657,7 @@
   user_write_buf_ = buf;
   user_write_buf_len_ = buf_len;
 
-  int rv = DoWriteLoop(OK);
+  int rv = DoWriteLoop();
 
   if (rv == ERR_IO_PENDING) {
     user_write_callback_ = callback;
@@ -1236,7 +1236,7 @@
   if (!user_read_buf_.get())
     return;
 
-  int rv = DoReadLoop(result);
+  int rv = DoReadLoop();
   if (rv != ERR_IO_PENDING)
     DoReadCallback(rv);
 }
@@ -1288,10 +1288,7 @@
   return rv;
 }
 
-int SSLClientSocketOpenSSL::DoReadLoop(int result) {
-  if (result < 0)
-    return result;
-
+int SSLClientSocketOpenSSL::DoReadLoop() {
   bool network_moved;
   int rv;
   do {
@@ -1302,10 +1299,7 @@
   return rv;
 }
 
-int SSLClientSocketOpenSSL::DoWriteLoop(int result) {
-  if (result < 0)
-    return result;
-
+int SSLClientSocketOpenSSL::DoWriteLoop() {
   bool network_moved;
   int rv;
   do {
diff --git a/net/socket/ssl_client_socket_openssl.h b/net/socket/ssl_client_socket_openssl.h
index 49a2b45..8ed45c3 100644
--- a/net/socket/ssl_client_socket_openssl.h
+++ b/net/socket/ssl_client_socket_openssl.h
@@ -130,8 +130,8 @@
   void OnRecvComplete(int result);
 
   int DoHandshakeLoop(int last_io_result);
-  int DoReadLoop(int result);
-  int DoWriteLoop(int result);
+  int DoReadLoop();
+  int DoWriteLoop();
   int DoPayloadRead();
   int DoPayloadWrite();
 
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 13a38631..16e03f7e 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -1822,7 +1822,7 @@
 
   SynchronousErrorStreamSocket* raw_transport = transport.get();
   scoped_ptr<SSLClientSocket> sock(
-      CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
+      CreateSSLClientSocket(transport.Pass(),
                             test_server.host_port_pair(),
                             kDefaultSSLConfig));
 
@@ -1859,7 +1859,7 @@
 
   SynchronousErrorStreamSocket* raw_transport = transport.get();
   scoped_ptr<SSLClientSocket> sock(
-      CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
+      CreateSSLClientSocket(transport.Pass(),
                             test_server.host_port_pair(),
                             ssl_config));
 
@@ -1873,6 +1873,54 @@
   EXPECT_EQ(0, rv);
 }
 
+// Tests that SSLClientSocket cleanly returns a Read of size 0 if the
+// underlying socket is cleanly closed asynchronously.
+// This is a regression test for https://crbug.com/422246
+TEST_F(SSLClientSocketTest, Read_WithAsyncZeroReturn) {
+  SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
+                                SpawnedTestServer::kLocalhost,
+                                base::FilePath());
+  ASSERT_TRUE(test_server.Start());
+
+  AddressList addr;
+  ASSERT_TRUE(test_server.GetAddressList(&addr));
+
+  TestCompletionCallback callback;
+  scoped_ptr<StreamSocket> real_transport(
+      new TCPClientSocket(addr, NULL, NetLog::Source()));
+  scoped_ptr<SynchronousErrorStreamSocket> error_socket(
+      new SynchronousErrorStreamSocket(real_transport.Pass()));
+  SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
+  scoped_ptr<FakeBlockingStreamSocket> transport(
+      new FakeBlockingStreamSocket(error_socket.Pass()));
+  FakeBlockingStreamSocket* raw_transport = transport.get();
+  int rv = callback.GetResult(transport->Connect(callback.callback()));
+  EXPECT_EQ(OK, rv);
+
+  // Disable TLS False Start to ensure the handshake has completed.
+  SSLConfig ssl_config;
+  ssl_config.false_start_enabled = false;
+
+  scoped_ptr<SSLClientSocket> sock(
+      CreateSSLClientSocket(transport.Pass(),
+                            test_server.host_port_pair(),
+                            ssl_config));
+
+  rv = callback.GetResult(sock->Connect(callback.callback()));
+  EXPECT_EQ(OK, rv);
+  EXPECT_TRUE(sock->IsConnected());
+
+  raw_error_socket->SetNextReadError(0);
+  raw_transport->BlockReadResult();
+  scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
+  rv = sock->Read(buf.get(), 4096, callback.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  raw_transport->UnblockReadResult();
+  rv = callback.GetResult(rv);
+  EXPECT_EQ(0, rv);
+}
+
 TEST_F(SSLClientSocketTest, Read_SmallChunks) {
   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
                                 SpawnedTestServer::kLocalhost,
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index 9d7ea87..fae97e8 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -70,6 +70,9 @@
 const size_t kPriorityDependencyPayloadSize = 4;
 const size_t kPriorityWeightPayloadSize = 1;
 
+// Wire size of pad length field.
+const size_t kPadLengthFieldSize = 1;
+
 }  // namespace
 
 const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1);
@@ -379,8 +382,8 @@
       return "READING_COMMON_HEADER";
     case SPDY_CONTROL_FRAME_PAYLOAD:
       return "CONTROL_FRAME_PAYLOAD";
-    case SPDY_READ_PADDING_LENGTH:
-      return "SPDY_READ_PADDING_LENGTH";
+    case SPDY_READ_DATA_FRAME_PADDING_LENGTH:
+      return "SPDY_READ_DATA_FRAME_PADDING_LENGTH";
     case SPDY_CONSUME_PADDING:
       return "SPDY_CONSUME_PADDING";
     case SPDY_IGNORE_REMAINING_PAYLOAD:
@@ -601,8 +604,8 @@
         break;
       }
 
-      case SPDY_READ_PADDING_LENGTH: {
-        size_t bytes_read = ProcessFramePaddingLength(data, len);
+      case SPDY_READ_DATA_FRAME_PADDING_LENGTH: {
+        size_t bytes_read = ProcessDataFramePaddingLength(data, len);
         len -= bytes_read;
         data += bytes_read;
         break;
@@ -809,7 +812,7 @@
                                   remaining_data_length_,
                                   current_frame_flags_ & DATA_FLAG_FIN);
       if (remaining_data_length_ > 0) {
-        CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
+        CHANGE_STATE(SPDY_READ_DATA_FRAME_PADDING_LENGTH);
       } else {
         // Empty data frame.
         if (current_frame_flags_ & DATA_FLAG_FIN) {
@@ -1083,15 +1086,23 @@
       break;
     case HEADERS:
       frame_size_without_variable_data = GetHeadersMinimumSize();
-      if (protocol_version() > SPDY3 &&
-          current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
+      if (protocol_version() > SPDY3) {
+        if (current_frame_flags_ & HEADERS_FLAG_PADDED) {
+          frame_size_without_variable_data += kPadLengthFieldSize;
+        }
+        if (current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
         frame_size_without_variable_data +=
             kPriorityDependencyPayloadSize +
             kPriorityWeightPayloadSize;
+        }
       }
       break;
     case PUSH_PROMISE:
       frame_size_without_variable_data = GetPushPromiseMinimumSize();
+      if (protocol_version() > SPDY3 &&
+          current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) {
+        frame_size_without_variable_data += kPadLengthFieldSize;
+      }
       break;
     case CONTINUATION:
       frame_size_without_variable_data = GetContinuationMinimumSize();
@@ -1457,6 +1468,14 @@
             expect_continuation_ = current_frame_stream_id_;
             end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN;
           }
+          if (protocol_version() > SPDY3 &&
+              current_frame_flags_ & HEADERS_FLAG_PADDED) {
+            uint8 pad_payload_len = 0;
+            DCHECK_EQ(remaining_padding_payload_length_, 0u);
+            successful_read = reader.ReadUInt8(&pad_payload_len);
+            DCHECK(successful_read);
+            remaining_padding_payload_length_ = pad_payload_len;
+          }
           const bool has_priority =
               (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
           uint32 priority = 0;
@@ -1502,7 +1521,7 @@
                 expect_continuation_ == 0);
           }
         }
-        CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
+        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
         break;
       case PUSH_PROMISE:
         {
@@ -1511,6 +1530,17 @@
             set_error(SPDY_INVALID_CONTROL_FRAME);
             break;
           }
+          bool successful_read = true;
+          if (protocol_version() > SPDY3 &&
+              current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) {
+            DCHECK_EQ(remaining_padding_payload_length_, 0u);
+            uint8 pad_payload_len = 0;
+            successful_read = reader.ReadUInt8(&pad_payload_len);
+            DCHECK(successful_read);
+            remaining_padding_payload_length_ = pad_payload_len;
+          }
+        }
+        {
           SpdyStreamId promised_stream_id = kInvalidStream;
           bool successful_read = reader.ReadUInt31(&promised_stream_id);
           DCHECK(successful_read);
@@ -1533,7 +1563,7 @@
                                   (current_frame_flags_ &
                                    PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0);
         }
-        CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
+        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
         break;
       case CONTINUATION:
         {
@@ -2120,11 +2150,10 @@
   return processed_bytes;
 }
 
-// TODO(raullenchai): ProcessFramePaddingLength should be able to deal with
-// HEADERS_FLAG_PADDED and PUSH_PROMISE_FLAG_PADDED as well (see b/15777051).
-size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
-  DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);
-  DCHECK_EQ(remaining_padding_payload_length_, 0u);
+size_t SpdyFramer::ProcessDataFramePaddingLength(const char* data, size_t len) {
+  DCHECK_EQ(SPDY_READ_DATA_FRAME_PADDING_LENGTH, state_);
+  DCHECK_EQ(0u, remaining_padding_payload_length_);
+  DCHECK_EQ(DATA, current_frame_type_);
 
   size_t original_len = len;
   if (current_frame_flags_ & DATA_FLAG_PADDED) {
@@ -2149,16 +2178,7 @@
     set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
     return 0;
   }
-  if (current_frame_type_ == DATA) {
-    CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
-  } else {
-    DCHECK(current_frame_type_ == HEADERS ||
-           current_frame_type_ == PUSH_PROMISE ||
-           current_frame_type_ == SYN_STREAM ||
-           current_frame_type_ == SYN_REPLY)
-        << current_frame_type_;
-    CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
-  }
+  CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
   return original_len - len;
 }
 
@@ -2606,11 +2626,20 @@
     if (headers.has_priority()) {
       flags |= HEADERS_FLAG_PRIORITY;
     }
+    if (headers.padded()) {
+      flags |= HEADERS_FLAG_PADDED;
+    }
   }
 
-  // The size of this frame, including variable-length name-value block.
+  // The size of this frame, including padding (if there is any)
+  // and variable-length name-value block.
   size_t size = GetHeadersMinimumSize();
 
+  if (protocol_version() > SPDY3 && headers.padded()) {
+    size += kPadLengthFieldSize;
+    size += headers.padding_payload_len();
+  }
+
   uint32 priority = headers.priority();
   if (headers.has_priority()) {
     if (priority > GetLowestPriority()) {
@@ -2655,6 +2684,11 @@
   DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
 
   if (protocol_version() > SPDY3) {
+    int padding_payload_len = 0;
+    if (headers.padded()) {
+      builder.WriteUInt8(headers.padding_payload_len());
+      padding_payload_len = headers.padding_payload_len();
+    }
     if (headers.has_priority()) {
       // TODO(jgraettinger): Plumb priorities and stream dependencies.
       builder.WriteUInt32(0);  // Non-exclusive bit and root stream ID.
@@ -2663,7 +2697,8 @@
     WritePayloadWithContinuation(&builder,
                                  hpack_encoding,
                                  headers.stream_id(),
-                                 HEADERS);
+                                 HEADERS,
+                                 padding_payload_len);
   } else {
     SerializeNameValueBlock(&builder, headers);
   }
@@ -2717,6 +2752,12 @@
   // The size of this frame, including variable-length name-value block.
   size_t size = GetPushPromiseMinimumSize();
 
+  if (push_promise.padded()) {
+    flags |= PUSH_PROMISE_FLAG_PADDED;
+    size += kPadLengthFieldSize;
+    size += push_promise.padding_payload_len();
+  }
+
   string hpack_encoding;
   if (enable_compression_) {
     GetHpackEncoder()->EncodeHeaderSet(
@@ -2737,13 +2778,24 @@
                         PUSH_PROMISE,
                         flags,
                         push_promise.stream_id());
-  builder.WriteUInt32(push_promise.promised_stream_id());
-  DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
+  int padding_payload_len = 0;
+  if (push_promise.padded()) {
+    builder.WriteUInt8(push_promise.padding_payload_len());
+    builder.WriteUInt32(push_promise.promised_stream_id());
+    DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize,
+              builder.length());
+
+    padding_payload_len = push_promise.padding_payload_len();
+  } else {
+    builder.WriteUInt32(push_promise.promised_stream_id());
+    DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
+  }
 
   WritePayloadWithContinuation(&builder,
                                hpack_encoding,
                                push_promise.stream_id(),
-                               PUSH_PROMISE);
+                               PUSH_PROMISE,
+                               padding_payload_len);
 
   if (debug_visitor_) {
     // SPDY4 uses HPACK for header compression. However, continue to
@@ -2923,32 +2975,34 @@
 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
                                               const string& hpack_encoding,
                                               SpdyStreamId stream_id,
-                                              SpdyFrameType type) {
+                                              SpdyFrameType type,
+                                              int padding_payload_len) {
   const size_t kMaxControlFrameSize = GetHeaderFragmentMaxSize();
 
-    // In addition to the prefix, fixed_field_size includes the size of
-    // any fields that come before the variable-length name/value block.
-    size_t fixed_field_size = 0;
     uint8 end_flag = 0;
     uint8 flags = 0;
     if (type == HEADERS) {
-      fixed_field_size = GetHeadersMinimumSize();
       end_flag = HEADERS_FLAG_END_HEADERS;
     } else if (type == PUSH_PROMISE) {
-      fixed_field_size = GetPushPromiseMinimumSize();
       end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
     } else {
       DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
                   << FrameTypeToString(type);
     }
 
-    // Write as much of the payload as possible into the initial frame.
-    size_t bytes_remaining = hpack_encoding.size() -
-        std::min(hpack_encoding.size(),
-                 kMaxControlFrameSize - fixed_field_size);
+    // Write all the padding payload and as much of the data payload as possible
+    // into the initial frame.
+    size_t bytes_remaining = 0;
+    bytes_remaining = hpack_encoding.size() -
+                      std::min(hpack_encoding.size(),
+                               kMaxControlFrameSize - builder->length() -
+                                   padding_payload_len);
     builder->WriteBytes(&hpack_encoding[0],
                         hpack_encoding.size() - bytes_remaining);
-
+    if (padding_payload_len > 0) {
+      string padding = string(padding_payload_len, 0);
+      builder->WriteBytes(padding.data(), padding.length());
+    }
     if (bytes_remaining > 0) {
       builder->OverwriteLength(*this,
           kMaxControlFrameSize - GetControlFrameHeaderSize());
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index 42711c2..99db36a 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -336,7 +336,7 @@
     SPDY_AUTO_RESET,
     SPDY_READING_COMMON_HEADER,
     SPDY_CONTROL_FRAME_PAYLOAD,
-    SPDY_READ_PADDING_LENGTH,
+    SPDY_READ_DATA_FRAME_PADDING_LENGTH,
     SPDY_CONSUME_PADDING,
     SPDY_IGNORE_REMAINING_PAYLOAD,
     SPDY_FORWARD_STREAM_FRAME,
@@ -601,6 +601,8 @@
                            UnclosedStreamDataCompressorsOneByteAtATime);
   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
                            UncompressLargerThanFrameBufferInitialSize);
+  FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
+                           CreatePushPromiseThenContinuationUncompressed);
   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ReadLargeSettingsFrame);
   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
                            ReadLargeSettingsFrameInSmallChunks);
@@ -634,7 +636,7 @@
   size_t ProcessControlFrameHeaderBlock(const char* data,
                                         size_t len,
                                         bool is_hpack_header_block);
-  size_t ProcessFramePaddingLength(const char* data, size_t len);
+  size_t ProcessDataFramePaddingLength(const char* data, size_t len);
   size_t ProcessFramePadding(const char* data, size_t len);
   size_t ProcessDataFramePayload(const char* data, size_t len);
   size_t ProcessGoAwayFramePayload(const char* data, size_t len);
@@ -672,7 +674,8 @@
   void WritePayloadWithContinuation(SpdyFrameBuilder* builder,
                                     const std::string& hpack_encoding,
                                     SpdyStreamId stream_id,
-                                    SpdyFrameType type);
+                                    SpdyFrameType type,
+                                    int padding_payload_len);
 
  private:
   // Deliver the given control frame's uncompressed headers block to the
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 35b8a46c..84ea0d73 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -2805,6 +2805,35 @@
       CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
     }
   }
+
+  {
+    const char kDescription[] =
+        "HEADERS frame with a 0-length header name, FIN, max stream ID, padded";
+
+    const unsigned char kV4FrameData[] = {
+        0x00, 0x00, 0x15, 0x01,  // Headers
+        0x0d, 0x7f, 0xff, 0xff,  // FIN | END_HEADERS | PADDED, Stream
+                                 // 0x7fffffff
+        0xff, 0x05, 0x00, 0x00,  // Pad length field
+        0x03, 0x66, 0x6f, 0x6f,  // .foo
+        0x00, 0x03, 0x66, 0x6f,  // @.fo
+        0x6f, 0x03, 0x62, 0x61,  // o.ba
+        0x72,                    // r
+        // Padding payload
+        0x00, 0x00, 0x00, 0x00, 0x00,
+    };
+    SpdyHeadersIR headers_ir(0x7fffffff);
+    headers_ir.set_fin(true);
+    headers_ir.SetHeader("", "foo");
+    headers_ir.SetHeader("foo", "bar");
+    headers_ir.set_padding_len(6);
+    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    if (IsSpdy2() || IsSpdy3()) {
+      // Padding is not supported.
+    } else {
+      CompareFrame(kDescription, *frame, kV4FrameData, arraysize(kV4FrameData));
+    }
+  }
 }
 
 // TODO(phajdan.jr): Clean up after we no longer need
@@ -2982,27 +3011,98 @@
     return;
   }
 
-  SpdyFramer framer(spdy_version_);
-  framer.set_enable_compression(false);
-  const char kDescription[] = "PUSH_PROMISE frame";
+  {
+    // Test framing PUSH_PROMISE without padding.
+    SpdyFramer framer(spdy_version_);
+    framer.set_enable_compression(false);
+    const char kDescription[] = "PUSH_PROMISE frame without padding";
 
-  const unsigned char kFrameData[] = {
-    0x00, 0x00, 0x16, 0x05, 0x04,  // PUSH_PROMISE: END_HEADERS
-    0x00, 0x00, 0x00, 0x2a,  // Stream 42
-    0x00, 0x00, 0x00, 0x39,  // Promised stream 57
-    0x00, 0x03, 0x62, 0x61,  // @.ba
-    0x72, 0x03, 0x66, 0x6f,  // r.fo
-    0x6f, 0x00, 0x03, 0x66,  // o@.f
-    0x6f, 0x6f, 0x03, 0x62,  // oo.b
-    0x61, 0x72,              // ar
-  };
+    const unsigned char kFrameData[] = {
+        0x00, 0x00, 0x16, 0x05,  // PUSH_PROMISE
+        0x04, 0x00, 0x00, 0x00,  // END_HEADERS
+        0x2a, 0x00, 0x00, 0x00,  // Stream 42
+        0x39, 0x00, 0x03, 0x62,  // Promised stream 57, @.b
+        0x61, 0x72, 0x03, 0x66,  // ar.f
+        0x6f, 0x6f, 0x00, 0x03,  // oo@.
+        0x66, 0x6f, 0x6f, 0x03,  // foo.
+        0x62, 0x61, 0x72,        // bar
+    };
 
-  SpdyPushPromiseIR push_promise(42, 57);
-  push_promise.SetHeader("bar", "foo");
-  push_promise.SetHeader("foo", "bar");
-  scoped_ptr<SpdySerializedFrame> frame(
-    framer.SerializePushPromise(push_promise));
-  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+    SpdyPushPromiseIR push_promise(42, 57);
+    push_promise.SetHeader("bar", "foo");
+    push_promise.SetHeader("foo", "bar");
+    scoped_ptr<SpdySerializedFrame> frame(
+        framer.SerializePushPromise(push_promise));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    // Test framing PUSH_PROMISE with one byte of padding.
+    SpdyFramer framer(spdy_version_);
+    framer.set_enable_compression(false);
+    const char kDescription[] = "PUSH_PROMISE frame with one byte of padding";
+
+    const unsigned char kFrameData[] = {
+        0x00, 0x00, 0x17, 0x05,  // PUSH_PROMISE
+        0x0c, 0x00, 0x00, 0x00,  // END_HEADERS | PADDED
+        0x2a, 0x00, 0x00, 0x00,  // Stream 42, Pad length field
+        0x00, 0x39, 0x00, 0x03,  // Promised stream 57
+        0x62, 0x61, 0x72, 0x03,  // bar.
+        0x66, 0x6f, 0x6f, 0x00,  // foo@
+        0x03, 0x66, 0x6f, 0x6f,  // .foo
+        0x03, 0x62, 0x61, 0x72,  // .bar
+    };
+
+    SpdyPushPromiseIR push_promise(42, 57);
+    push_promise.set_padding_len(1);
+    push_promise.SetHeader("bar", "foo");
+    push_promise.SetHeader("foo", "bar");
+    scoped_ptr<SpdySerializedFrame> frame(
+        framer.SerializePushPromise(push_promise));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
+
+  {
+    // Test framing PUSH_PROMISE with 177 bytes of padding.
+    SpdyFramer framer(spdy_version_);
+    framer.set_enable_compression(false);
+    const char kDescription[] = "PUSH_PROMISE frame with 177 bytes of padding";
+
+    const unsigned char kFrameData[] = {
+        0x00, 0x00, 0xc7, 0x05,  // PUSH_PROMISE
+        0x0c, 0x00, 0x00, 0x00,  // END_HEADERS | PADDED
+        0x2a, 0xb0, 0x00, 0x00,  // Stream 42, Pad length field
+        0x00, 0x39, 0x00, 0x03,  // Promised stream 57
+        0x62, 0x61, 0x72, 0x03,  // bar.
+        0x66, 0x6f, 0x6f, 0x00,  // foo@
+        0x03, 0x66, 0x6f, 0x6f,  // .foo
+        0x03, 0x62, 0x61, 0x72,  // .bar
+        // Padding of 176 0x00(s).
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    };
+
+    SpdyPushPromiseIR push_promise(42, 57);
+    push_promise.set_padding_len(177);
+    push_promise.SetHeader("bar", "foo");
+    push_promise.SetHeader("foo", "bar");
+    scoped_ptr<SpdySerializedFrame> frame(
+        framer.SerializePushPromise(push_promise));
+    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  }
 }
 
 TEST_P(SpdyFramerTest, CreateContinuationUncompressed) {
@@ -3032,6 +3132,107 @@
   CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
 }
 
+TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) {
+  if (spdy_version_ <= SPDY3) {
+    return;
+  }
+
+  {
+    // Test framing in a case such that a PUSH_PROMISE frame, with one byte of
+    // padding, cannot hold all the data payload, which is overflowed to the
+    // consecutive CONTINUATION frame.
+    SpdyFramer framer(spdy_version_);
+    framer.set_enable_compression(false);
+    const char kDescription[] =
+        "PUSH_PROMISE and CONTINUATION frames with one byte of padding";
+
+    const unsigned char kPartialPushPromiseFrameData[] = {
+        0x00, 0x03, 0xf6, 0x05,  // PUSH_PROMISE
+        0x08, 0x00, 0x00, 0x00,  // PADDED
+        0x2a, 0x00, 0x00, 0x00,  // Stream 42
+        0x00, 0x39, 0x00, 0x03,  // Promised stream 57
+        0x78, 0x78, 0x78, 0x7f,  // xxx.
+        0x80, 0x07, 0x78, 0x78,  // ..xx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78,              // xx
+    };
+
+    const unsigned char kContinuationFrameData[] = {
+        0x00, 0x00, 0x16, 0x09,  // CONTINUATION
+        0x04, 0x00, 0x00, 0x00,  // END_HEADERS
+        0x2a, 0x78, 0x78, 0x78,  // Stream 42, xxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78, 0x78, 0x78,  // xxxx
+        0x78, 0x78,
+    };
+
+    SpdyPushPromiseIR push_promise(42, 57);
+    push_promise.set_padding_len(1);
+    string big_value(framer.GetHeaderFragmentMaxSize(), 'x');
+    push_promise.SetHeader("xxx", big_value);
+    scoped_ptr<SpdySerializedFrame> frame(
+        framer.SerializePushPromise(push_promise));
+
+    // The entire frame should look like below:
+    // Name                     Length in Byte
+    // ------------------------------------------- Begin of PUSH_PROMISE frame
+    // PUSH_PROMISE header      9
+    // Pad length field         1
+    // Promised stream          4
+    // Length field of key      2
+    // Content of key           3
+    // Length field of value    3
+    // Part of big_value        16361
+    // ------------------------------------------- Begin of CONTINUATION frame
+    // CONTINUATION header      9
+    // Remaining of big_value   22
+    // ------------------------------------------- End
+
+    // Length of everything listed above except big_value.
+    int len_non_data_payload = 31;
+    EXPECT_EQ(framer.GetHeaderFragmentMaxSize() + len_non_data_payload,
+              frame->size());
+
+    // Partially compare the PUSH_PROMISE frame against the template.
+    const unsigned char* frame_data =
+        reinterpret_cast<const unsigned char*>(frame->data());
+    CompareCharArraysWithHexError(kDescription,
+                                  frame_data,
+                                  arraysize(kPartialPushPromiseFrameData),
+                                  kPartialPushPromiseFrameData,
+                                  arraysize(kPartialPushPromiseFrameData));
+
+    // Compare the CONTINUATION frame against the template.
+    frame_data += framer.GetHeaderFragmentMaxSize();
+    CompareCharArraysWithHexError(kDescription,
+                                  frame_data,
+                                  arraysize(kContinuationFrameData),
+                                  kContinuationFrameData,
+                                  arraysize(kContinuationFrameData));
+  }
+}
+
 TEST_P(SpdyFramerTest, CreateAltSvc) {
   if (spdy_version_ <= SPDY3) {
     return;
@@ -3263,6 +3464,7 @@
   SpdyFramer framer(spdy_version_);
   framer.set_enable_compression(false);
   SpdyHeadersIR headers(1);
+  headers.set_padding_len(256);
 
   // Exact payload length will change with HPACK, but this should be long
   // enough to cause an overflow.
@@ -3291,6 +3493,7 @@
   SpdyFramer framer(spdy_version_);
   framer.set_enable_compression(false);
   SpdyPushPromiseIR push_promise(1, 2);
+  push_promise.set_padding_len(256);
 
   // Exact payload length will change with HPACK, but this should be long
   // enough to cause an overflow.
@@ -3729,7 +3932,7 @@
   CHECK_EQ(framer.GetDataFrameMinimumSize(),
            framer.ProcessInput(frame->data(),
                                framer.GetDataFrameMinimumSize()));
-  CHECK_EQ(framer.state(), SpdyFramer::SPDY_READ_PADDING_LENGTH);
+  CHECK_EQ(framer.state(), SpdyFramer::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
   CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
   bytes_consumed += framer.GetDataFrameMinimumSize();
 
@@ -3966,31 +4169,31 @@
   }
 
   const unsigned char kInput[] = {
-    0x00, 0x00, 0x17, 0x05, 0x08,  // PUSH_PROMISE: PADDED
-    0x00, 0x00, 0x00, 0x01,  // Stream 1
-    0x00, 0x00, 0x00, 0x2A,  // Promised stream 42
-    0x02,                    // Padding of 2.
-    0x00, 0x06, 0x63, 0x6f,
-    0x6f, 0x6b, 0x69, 0x65,
-    0x07, 0x66, 0x6f, 0x6f,
-    0x3d, 0x62, 0x61, 0x72,
-    0x00, 0x00,
+    0x00, 0x00, 0x17, 0x05,  // PUSH_PROMISE
+    0x08, 0x00, 0x00, 0x00,  // PADDED
+    0x01, 0x02, 0x00, 0x00,  // Stream 1, Pad length field
+    0x00, 0x2A, 0x00, 0x06,  // Promised stream 42
+    0x63, 0x6f, 0x6f, 0x6b,
+    0x69, 0x65, 0x07, 0x66,
+    0x6f, 0x6f, 0x3d, 0x62,
+    0x61, 0x72, 0x00, 0x00,
 
-    0x00, 0x00, 0x14, 0x09, 0x00,  // CONTINUATION
-    0x00, 0x00, 0x00, 0x01,  // Stream 1
-    0x00, 0x06, 0x63, 0x6f,
-    0x6f, 0x6b, 0x69, 0x65,
-    0x08, 0x62, 0x61, 0x7a,
-    0x3d, 0x62, 0x69, 0x6e,
-    0x67, 0x00, 0x06, 0x63,
-
-    0x00, 0x00, 0x12, 0x09, 0x04,  // CONTINUATION: END_HEADERS
-    0x00, 0x00, 0x00, 0x01,  // Stream 1
+    0x00, 0x00, 0x14, 0x09,  // CONTINUATION
+    0x00, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x06, 0x63,  // Stream 1
     0x6f, 0x6f, 0x6b, 0x69,
-    0x65, 0x00, 0x00, 0x04,
-    0x6e, 0x61, 0x6d, 0x65,
-    0x05, 0x76, 0x61, 0x6c,
-    0x75, 0x65,
+    0x65, 0x08, 0x62, 0x61,
+    0x7a, 0x3d, 0x62, 0x69,
+    0x6e, 0x67, 0x00, 0x06,
+    0x63,
+
+    0x00, 0x00, 0x12, 0x09,  // CONTINUATION
+    0x04, 0x00, 0x00, 0x00,  // END_HEADERS
+    0x01, 0x6f, 0x6f, 0x6b,  // Stream 1
+    0x69, 0x65, 0x00, 0x00,
+    0x04, 0x6e, 0x61, 0x6d,
+    0x65, 0x05, 0x76, 0x61,
+    0x6c, 0x75, 0x65,
   };
 
   SpdyFramer framer(spdy_version_);
diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h
index c408f0a4..3a979b9 100644
--- a/net/spdy/spdy_protocol.h
+++ b/net/spdy/spdy_protocol.h
@@ -845,9 +845,11 @@
 class NET_EXPORT_PRIVATE SpdyHeadersIR : public SpdyFrameWithNameValueBlockIR {
  public:
   explicit SpdyHeadersIR(SpdyStreamId stream_id)
-    : SpdyFrameWithNameValueBlockIR(stream_id),
-      has_priority_(false),
-      priority_(0) {}
+      : SpdyFrameWithNameValueBlockIR(stream_id),
+        has_priority_(false),
+        priority_(0),
+        padded_(false),
+        padding_payload_len_(0) {}
 
   void Visit(SpdyFrameVisitor* visitor) const override;
 
@@ -856,10 +858,24 @@
   uint32 priority() const { return priority_; }
   void set_priority(SpdyPriority priority) { priority_ = priority; }
 
+  bool padded() const { return padded_; }
+  int padding_payload_len() const { return padding_payload_len_; }
+  void set_padding_len(int padding_len) {
+    DCHECK_GT(padding_len, 0);
+    DCHECK_LE(padding_len, kPaddingSizePerFrame);
+    padded_ = true;
+    // The pad field takes one octet on the wire.
+    padding_payload_len_ = padding_len - 1;
+  }
+
  private:
   bool has_priority_;
   // 31-bit priority.
   uint32 priority_;
+
+  bool padded_;
+  int padding_payload_len_;
+
   DISALLOW_COPY_AND_ASSIGN(SpdyHeadersIR);
 };
 
@@ -901,14 +917,30 @@
  public:
   SpdyPushPromiseIR(SpdyStreamId stream_id, SpdyStreamId promised_stream_id)
       : SpdyFrameWithNameValueBlockIR(stream_id),
-        promised_stream_id_(promised_stream_id) {}
+        promised_stream_id_(promised_stream_id),
+        padded_(false),
+        padding_payload_len_(0) {}
   SpdyStreamId promised_stream_id() const { return promised_stream_id_; }
   void set_promised_stream_id(SpdyStreamId id) { promised_stream_id_ = id; }
 
   void Visit(SpdyFrameVisitor* visitor) const override;
 
+  bool padded() const { return padded_; }
+  int padding_payload_len() const { return padding_payload_len_; }
+  void set_padding_len(int padding_len) {
+    DCHECK_GT(padding_len, 0);
+    DCHECK_LE(padding_len, kPaddingSizePerFrame);
+    padded_ = true;
+    // The pad field takes one octet on the wire.
+    padding_payload_len_ = padding_len - 1;
+  }
+
  private:
   SpdyStreamId promised_stream_id_;
+
+  bool padded_;
+  int padding_payload_len_;
+
   DISALLOW_COPY_AND_ASSIGN(SpdyPushPromiseIR);
 };
 
diff --git a/net/ssl/default_channel_id_store.cc b/net/ssl/default_channel_id_store.cc
index b71d7b35..60e06ed06 100644
--- a/net/ssl/default_channel_id_store.cc
+++ b/net/ssl/default_channel_id_store.cc
@@ -7,6 +7,7 @@
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram.h"
+#include "base/profiler/scoped_profile.h"
 #include "net/base/net_errors.h"
 
 namespace net {
@@ -61,6 +62,11 @@
 
 void DefaultChannelIDStore::GetChannelIDTask::Run(
     DefaultChannelIDStore* store) {
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/425814 is fixed.
+  tracked_objects::ScopedProfile tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "425814 DefaultChannelIDStore::GetChannelIDTask::Run"));
+
   base::Time expiration_time;
   std::string private_key_result;
   std::string cert_result;
@@ -112,6 +118,11 @@
 
 void DefaultChannelIDStore::SetChannelIDTask::Run(
     DefaultChannelIDStore* store) {
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/425814 is fixed.
+  tracked_objects::ScopedProfile tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "425814 DefaultChannelIDStore::SetChannelIDTask::Run"));
+
   store->SyncSetChannelID(server_identifier_, creation_time_,
                           expiration_time_, private_key_, cert_);
 }
@@ -145,6 +156,11 @@
 
 void DefaultChannelIDStore::DeleteChannelIDTask::Run(
     DefaultChannelIDStore* store) {
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/425814 is fixed.
+  tracked_objects::ScopedProfile tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "425814 DefaultChannelIDStore::DeleteChannelIDTask::Run"));
+
   store->SyncDeleteChannelID(server_identifier_);
 
   InvokeCallback(callback_);
@@ -183,6 +199,11 @@
 
 void DefaultChannelIDStore::DeleteAllCreatedBetweenTask::Run(
     DefaultChannelIDStore* store) {
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/425814 is fixed.
+  tracked_objects::ScopedProfile tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "425814 DefaultChannelIDStore::DeleteAllCreatedBetweenTask::Run"));
+
   store->SyncDeleteAllCreatedBetween(delete_begin_, delete_end_);
 
   InvokeCallback(callback_);
@@ -213,6 +234,11 @@
 
 void DefaultChannelIDStore::GetAllChannelIDsTask::Run(
     DefaultChannelIDStore* store) {
+  // TODO(vadimt): Remove ScopedProfile below once crbug.com/425814 is fixed.
+  tracked_objects::ScopedProfile tracking_profile(
+      FROM_HERE_WITH_EXPLICIT_FUNCTION(
+          "425814 DefaultChannelIDStore::GetAllChannelIDsTask::Run"));
+
   ChannelIDList cert_list;
   store->SyncGetAllChannelIDs(&cert_list);
 
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc
index 61f8c01..5b5c415 100644
--- a/net/tools/quic/quic_client_session_test.cc
+++ b/net/tools/quic/quic_client_session_test.cc
@@ -33,7 +33,7 @@
 namespace test {
 namespace {
 
-const char kServerHostname[] = "www.example.com";
+const char kServerHostname[] = "www.example.org";
 const uint16 kPort = 80;
 
 class ToolsQuicClientSessionTest
diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py
index 4294414..2fc58cf 100755
--- a/net/tools/testserver/testserver.py
+++ b/net/tools/testserver/testserver.py
@@ -358,6 +358,7 @@
       'gif': 'image/gif',
       'jpeg' : 'image/jpeg',
       'jpg' : 'image/jpeg',
+      'js' : 'application/javascript',
       'json': 'application/json',
       'pdf' : 'application/pdf',
       'txt' : 'text/plain',
diff --git a/pdf/document_loader.cc b/pdf/document_loader.cc
index 6b871d6..b2628a6 100644
--- a/pdf/document_loader.cc
+++ b/pdf/document_loader.cc
@@ -298,6 +298,15 @@
     return;
   }
 
+  int32_t http_code = loader_.GetResponseInfo().GetStatusCode();
+  if (http_code >= 400 && http_code < 500) {
+    // Error accessing resource. 4xx error indicate subsequent requests
+    // will fail too.
+    // E.g. resource has been removed from the server while loading it.
+    // https://code.google.com/p/chromium/issues/detail?id=414827
+    return;
+  }
+
   is_multipart_ = false;
   current_chunk_size_ = 0;
   current_chunk_read_ = 0;
diff --git a/ppapi/nacl_irt/irt_ppapi.cc b/ppapi/nacl_irt/irt_ppapi.cc
index 466573ce6..b56fc8c7 100644
--- a/ppapi/nacl_irt/irt_ppapi.cc
+++ b/ppapi/nacl_irt/irt_ppapi.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <unistd.h>
+
 #include "native_client/src/public/irt_core.h"
 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h"
 #include "native_client/src/untrusted/irt/irt.h"
diff --git a/printing/backend/print_backend_cups.cc b/printing/backend/print_backend_cups.cc
index e672b89..58ae20f 100644
--- a/printing/backend/print_backend_cups.cc
+++ b/printing/backend/print_backend_cups.cc
@@ -34,20 +34,18 @@
                    http_encryption_t encryption, bool blocking);
 
   // PrintBackend implementation.
-  virtual bool EnumeratePrinters(PrinterList* printer_list) override;
-  virtual std::string GetDefaultPrinterName() override;
-  virtual bool GetPrinterSemanticCapsAndDefaults(
+  bool EnumeratePrinters(PrinterList* printer_list) override;
+  std::string GetDefaultPrinterName() override;
+  bool GetPrinterSemanticCapsAndDefaults(
       const std::string& printer_name,
       PrinterSemanticCapsAndDefaults* printer_info) override;
-  virtual bool GetPrinterCapsAndDefaults(
-      const std::string& printer_name,
-      PrinterCapsAndDefaults* printer_info) override;
-  virtual std::string GetPrinterDriverInfo(
-      const std::string& printer_name) override;
-  virtual bool IsValidPrinter(const std::string& printer_name) override;
+  bool GetPrinterCapsAndDefaults(const std::string& printer_name,
+                                 PrinterCapsAndDefaults* printer_info) override;
+  std::string GetPrinterDriverInfo(const std::string& printer_name) override;
+  bool IsValidPrinter(const std::string& printer_name) override;
 
  protected:
-  virtual ~PrintBackendCUPS() {}
+  ~PrintBackendCUPS() override {}
 
  private:
   // Following functions are wrappers around corresponding CUPS functions.
diff --git a/printing/metafile.h b/printing/metafile.h
index 0078d8b..12b50334 100644
--- a/printing/metafile.h
+++ b/printing/metafile.h
@@ -99,7 +99,7 @@
 class PRINTING_EXPORT Metafile : public MetafilePlayer {
  public:
   Metafile();
-  virtual ~Metafile();
+  ~Metafile() override;
 
   // Initializes a fresh new metafile for rendering. Returns false on failure.
   // Note: It should only be called from within the renderer process to allocate
@@ -163,7 +163,7 @@
 
   bool GetDataAsVector(std::vector<char>* buffer) const;
 
-  virtual bool SaveTo(base::File* file) const override;
+  bool SaveTo(base::File* file) const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Metafile);
diff --git a/printing/pdf_metafile_cg_mac.h b/printing/pdf_metafile_cg_mac.h
index c7c1a5ac..9744a9b 100644
--- a/printing/pdf_metafile_cg_mac.h
+++ b/printing/pdf_metafile_cg_mac.h
@@ -29,37 +29,36 @@
 class PRINTING_EXPORT PdfMetafileCg : public Metafile {
  public:
   PdfMetafileCg();
-  virtual ~PdfMetafileCg();
+  ~PdfMetafileCg() override;
 
   // Metafile methods.
-  virtual bool Init() override;
-  virtual bool InitFromData(const void* src_buffer,
-                            uint32 src_buffer_size) override;
+  bool Init() override;
+  bool InitFromData(const void* src_buffer, uint32 src_buffer_size) override;
 
   // Not implemented on mac.
-  virtual SkBaseDevice* StartPageForVectorCanvas(
-      const gfx::Size& page_size, const gfx::Rect& content_area,
-      const float& scale_factor) override;
-  virtual bool StartPage(const gfx::Size& page_size,
-                         const gfx::Rect& content_area,
-                         const float& scale_factor) override;
-  virtual bool FinishPage() override;
-  virtual bool FinishDocument() override;
+  SkBaseDevice* StartPageForVectorCanvas(const gfx::Size& page_size,
+                                         const gfx::Rect& content_area,
+                                         const float& scale_factor) override;
+  bool StartPage(const gfx::Size& page_size,
+                 const gfx::Rect& content_area,
+                 const float& scale_factor) override;
+  bool FinishPage() override;
+  bool FinishDocument() override;
 
-  virtual uint32 GetDataSize() const override;
-  virtual bool GetData(void* dst_buffer, uint32 dst_buffer_size) const override;
+  uint32 GetDataSize() const override;
+  bool GetData(void* dst_buffer, uint32 dst_buffer_size) const override;
 
-  virtual gfx::Rect GetPageBounds(unsigned int page_number) const override;
-  virtual unsigned int GetPageCount() const override;
+  gfx::Rect GetPageBounds(unsigned int page_number) const override;
+  unsigned int GetPageCount() const override;
 
   // Note: The returned context *must not be retained* past Close(). If it is,
   // the data returned from GetData will not be valid PDF data.
-  virtual CGContextRef context() const override;
+  CGContextRef context() const override;
 
-  virtual bool RenderPage(unsigned int page_number,
-                          gfx::NativeDrawingContext context,
-                          const CGRect rect,
-                          const MacRenderPageParams& params) const override;
+  bool RenderPage(unsigned int page_number,
+                  gfx::NativeDrawingContext context,
+                  const CGRect rect,
+                  const MacRenderPageParams& params) const override;
 
  private:
   // Returns a CGPDFDocumentRef version of pdf_data_.
diff --git a/printing/pdf_metafile_skia.h b/printing/pdf_metafile_skia.h
index 387ce9ac..706c56a 100644
--- a/printing/pdf_metafile_skia.h
+++ b/printing/pdf_metafile_skia.h
@@ -29,41 +29,39 @@
 class PRINTING_EXPORT PdfMetafileSkia : public Metafile {
  public:
   PdfMetafileSkia();
-  virtual ~PdfMetafileSkia();
+  ~PdfMetafileSkia() override;
 
   // Metafile methods.
-  virtual bool Init() override;
-  virtual bool InitFromData(const void* src_buffer,
-                            uint32 src_buffer_size) override;
+  bool Init() override;
+  bool InitFromData(const void* src_buffer, uint32 src_buffer_size) override;
 
-  virtual SkBaseDevice* StartPageForVectorCanvas(
-      const gfx::Size& page_size,
-      const gfx::Rect& content_area,
-      const float& scale_factor) override;
+  SkBaseDevice* StartPageForVectorCanvas(const gfx::Size& page_size,
+                                         const gfx::Rect& content_area,
+                                         const float& scale_factor) override;
 
-  virtual bool StartPage(const gfx::Size& page_size,
-                         const gfx::Rect& content_area,
-                         const float& scale_factor) override;
-  virtual bool FinishPage() override;
-  virtual bool FinishDocument() override;
+  bool StartPage(const gfx::Size& page_size,
+                 const gfx::Rect& content_area,
+                 const float& scale_factor) override;
+  bool FinishPage() override;
+  bool FinishDocument() override;
 
-  virtual uint32 GetDataSize() const override;
-  virtual bool GetData(void* dst_buffer, uint32 dst_buffer_size) const override;
+  uint32 GetDataSize() const override;
+  bool GetData(void* dst_buffer, uint32 dst_buffer_size) const override;
 
-  virtual gfx::Rect GetPageBounds(unsigned int page_number) const override;
-  virtual unsigned int GetPageCount() const override;
+  gfx::Rect GetPageBounds(unsigned int page_number) const override;
+  unsigned int GetPageCount() const override;
 
-  virtual gfx::NativeDrawingContext context() const override;
+  gfx::NativeDrawingContext context() const override;
 
 #if defined(OS_WIN)
   virtual bool Playback(gfx::NativeDrawingContext hdc,
                         const RECT* rect) const override;
   virtual bool SafePlayback(gfx::NativeDrawingContext hdc) const override;
 #elif defined(OS_MACOSX)
-  virtual bool RenderPage(unsigned int page_number,
-                          gfx::NativeDrawingContext context,
-                          const CGRect rect,
-                          const MacRenderPageParams& params) const override;
+  bool RenderPage(unsigned int page_number,
+                  gfx::NativeDrawingContext context,
+                  const CGRect rect,
+                  const MacRenderPageParams& params) const override;
 #endif
 
 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
diff --git a/printing/printing_context_mac.h b/printing/printing_context_mac.h
index 3701597..561b25d 100644
--- a/printing/printing_context_mac.h
+++ b/printing/printing_context_mac.h
@@ -22,25 +22,24 @@
 class PRINTING_EXPORT PrintingContextMac : public PrintingContext {
  public:
   explicit PrintingContextMac(Delegate* delegate);
-  virtual ~PrintingContextMac();
+  ~PrintingContextMac() override;
 
   // PrintingContext implementation.
-  virtual void AskUserForSettings(
-      int max_pages,
-      bool has_selection,
-      const PrintSettingsCallback& callback) override;
-  virtual Result UseDefaultSettings() override;
-  virtual gfx::Size GetPdfPaperSizeDeviceUnits() override;
-  virtual Result UpdatePrinterSettings(bool external_preview,
-                                       bool show_system_dialog) override;
-  virtual Result InitWithSettings(const PrintSettings& settings) override;
-  virtual Result NewDocument(const base::string16& document_name) override;
-  virtual Result NewPage() override;
-  virtual Result PageDone() override;
-  virtual Result DocumentDone() override;
-  virtual void Cancel() override;
-  virtual void ReleaseContext() override;
-  virtual gfx::NativeDrawingContext context() const override;
+  void AskUserForSettings(int max_pages,
+                          bool has_selection,
+                          const PrintSettingsCallback& callback) override;
+  Result UseDefaultSettings() override;
+  gfx::Size GetPdfPaperSizeDeviceUnits() override;
+  Result UpdatePrinterSettings(bool external_preview,
+                               bool show_system_dialog) override;
+  Result InitWithSettings(const PrintSettings& settings) override;
+  Result NewDocument(const base::string16& document_name) override;
+  Result NewPage() override;
+  Result PageDone() override;
+  Result DocumentDone() override;
+  void Cancel() override;
+  void ReleaseContext() override;
+  gfx::NativeDrawingContext context() const override;
 
  private:
   // Initializes PrintSettings from |print_info_|. This must be called
diff --git a/remoting/android/cast/AndroidManifest.xml.jinja2 b/remoting/android/cast/AndroidManifest.xml.jinja2
index f1ed533c..ad573b3 100644
--- a/remoting/android/cast/AndroidManifest.xml.jinja2
+++ b/remoting/android/cast/AndroidManifest.xml.jinja2
@@ -2,7 +2,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="{{ APK_PACKAGE_NAME }}">
     <uses-sdk android:minSdkVersion="14"
-            android:targetSdkVersion="20"/>
+            android:targetSdkVersion="21"/>
     <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
diff --git a/remoting/android/java/AndroidManifest.xml.jinja2 b/remoting/android/java/AndroidManifest.xml.jinja2
index 836533c8..97c6364 100644
--- a/remoting/android/java/AndroidManifest.xml.jinja2
+++ b/remoting/android/java/AndroidManifest.xml.jinja2
@@ -2,7 +2,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="{{ APK_PACKAGE_NAME }}">
     <uses-sdk android:minSdkVersion="14"
-            android:targetSdkVersion="20"/>
+            android:targetSdkVersion="21"/>
     <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
diff --git a/remoting/android/java/src/org/chromium/chromoting/Chromoting.java b/remoting/android/java/src/org/chromium/chromoting/Chromoting.java
index 3fbf764f..005bb45c 100644
--- a/remoting/android/java/src/org/chromium/chromoting/Chromoting.java
+++ b/remoting/android/java/src/org/chromium/chromoting/Chromoting.java
@@ -45,8 +45,8 @@
     private static final String ACCOUNT_TYPE = "com.google";
 
     /** Scopes at which the authentication token we request will be valid. */
-    private static final String TOKEN_SCOPE = "oauth2:https://www.googleapis.com/auth/chromoting " +
-            "https://www.googleapis.com/auth/googletalk";
+    private static final String TOKEN_SCOPE = "oauth2:https://www.googleapis.com/auth/chromoting "
+            + "https://www.googleapis.com/auth/googletalk";
 
     /** Web page to be displayed in the Help screen when launched from this activity. */
     private static final String HELP_URL =
@@ -355,8 +355,8 @@
     public boolean onNavigationItemSelected(int itemPosition, long itemId) {
         mAccount = mAccounts[itemPosition];
 
-        getPreferences(MODE_PRIVATE).edit().putString("account_name", mAccount.name).
-                    putString("account_type", mAccount.type).apply();
+        getPreferences(MODE_PRIVATE).edit().putString("account_name", mAccount.name)
+                .putString("account_type", mAccount.type).apply();
 
         // The current host list is no longer valid for the new account, so clear the list.
         mHosts = new HostInfo[0];
diff --git a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java
index c5f56cd..d6dd179 100644
--- a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java
+++ b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java
@@ -318,15 +318,15 @@
     private static void commitPairingCredentials(String host, String id, String secret) {
         // Empty |id| indicates that pairing needs to be removed.
         if (id.isEmpty()) {
-            sContext.getPreferences(Activity.MODE_PRIVATE).edit().
-                    remove(host + "_id").
-                    remove(host + "_secret").
-                    apply();
+            sContext.getPreferences(Activity.MODE_PRIVATE).edit()
+                    .remove(host + "_id")
+                    .remove(host + "_secret")
+                    .apply();
         } else {
-            sContext.getPreferences(Activity.MODE_PRIVATE).edit().
-                    putString(host + "_id", id).
-                    putString(host + "_secret", secret).
-                    apply();
+            sContext.getPreferences(Activity.MODE_PRIVATE).edit()
+                    .putString(host + "_id", id)
+                    .putString(host + "_secret", secret)
+                    .apply();
         }
     }
 
diff --git a/remoting/android/javatests/AndroidManifest.xml b/remoting/android/javatests/AndroidManifest.xml
index 88bd77a..23e4d41 100644
--- a/remoting/android/javatests/AndroidManifest.xml
+++ b/remoting/android/javatests/AndroidManifest.xml
@@ -14,7 +14,7 @@
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
     <instrumentation android:name="android.test.InstrumentationTestRunner"
         android:targetPackage="org.chromium.chromoting"
         android:label="Tests for org.chromium.chromoting"/>
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 335c54498..638135e 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -170,19 +170,19 @@
           'host/win/host_messages.mc.jinja2',
           'host/win/version.rc.jinja2',
           'resources/play_store_resources.cc',
-          'webapp/background/background.js',
-          'webapp/background/it2me_helpee_channel.js',
-          'webapp/butter_bar.js',
-          'webapp/client_screen.js',
-          'webapp/error.js',
-          'webapp/host_list.js',
-          'webapp/host_setup_dialog.js',
-          'webapp/host_table_entry.js',
-          'webapp/options_menu.js',
-          'webapp/manifest.json.jinja2',
-          'webapp/paired_client_manager.js',
-          'webapp/remoting.js',
-          'webapp/window_frame.js',
+          'webapp/crd/js/background.js',
+          'webapp/crd/js/butter_bar.js',
+          'webapp/crd/js/client_screen.js',
+          'webapp/crd/js/error.js',
+          'webapp/crd/js/host_list.js',
+          'webapp/crd/js/host_setup_dialog.js',
+          'webapp/crd/js/host_table_entry.js',
+          'webapp/crd/js/it2me_helpee_channel.js',
+          'webapp/crd/js/options_menu.js',
+          'webapp/crd/js/paired_client_manager.js',
+          'webapp/crd/js/remoting.js',
+          'webapp/crd/js/window_frame.js',
+          'webapp/crd/manifest.json.jinja2',
         ],
       },
       'actions': [
diff --git a/remoting/remoting_client.gypi b/remoting/remoting_client.gypi
index ea513d5..786389a 100644
--- a/remoting/remoting_client.gypi
+++ b/remoting/remoting_client.gypi
@@ -142,7 +142,7 @@
           'variables': {
             'webapp_type': 'v2_pnacl',
             'extra_files': [
-              'webapp/remoting_client_pnacl.nmf',
+              'webapp/crd/remoting_client_pnacl.nmf',
               '<(PRODUCT_DIR)/remoting_client_plugin_newlib.pexe',
             ],
           },
diff --git a/remoting/remoting_host.gypi b/remoting/remoting_host.gypi
index 55387003..acd1d4e 100644
--- a/remoting/remoting_host.gypi
+++ b/remoting/remoting_host.gypi
@@ -310,7 +310,7 @@
                 ],
               },
             }],
-            ['OS=="linux" and chromeos==0', {
+            ['OS=="linux" and chromeos==0 and use_ozone==0', {
               'dependencies' : [
                 # Always use GTK on Linux, even for Aura builds.
                 '../build/linux/system.gyp:gtk',
@@ -874,7 +874,7 @@
             'host/it2me/it2me_native_messaging_host_main.h',
           ],
           'conditions': [
-            ['OS=="linux" and chromeos==0', {
+            ['OS=="linux" and chromeos==0 and use_ozone==0', {
               'dependencies': [
                 # Always use GTK on Linux, even for Aura builds.
                 '../build/linux/system.gyp:gtk',
diff --git a/remoting/remoting_webapp.gypi b/remoting/remoting_webapp.gypi
index b5ea119b..57d0c36 100644
--- a/remoting/remoting_webapp.gypi
+++ b/remoting/remoting_webapp.gypi
@@ -48,7 +48,7 @@
       'action_name': 'Build Remoting WebApp',
       'inputs': [
         'webapp/build-webapp.py',
-        'webapp/manifest.json.jinja2',
+        'webapp/crd/manifest.json.jinja2',
         '<(chrome_version_path)',
         '<(remoting_version_path)',
         '<@(generated_html_files)',
@@ -66,7 +66,7 @@
         '<(version_full)',
         '<(output_dir)',
         '<(zip_path)',
-        'webapp/manifest.json.jinja2',
+        'webapp/crd/manifest.json.jinja2',
         '<(webapp_type)',
         '<@(generated_html_files)',
         '<@(remoting_webapp_files)',
diff --git a/remoting/remoting_webapp_files.gypi b/remoting/remoting_webapp_files.gypi
index 6ab3afe2..179ca45fe 100644
--- a/remoting/remoting_webapp_files.gypi
+++ b/remoting/remoting_webapp_files.gypi
@@ -23,117 +23,117 @@
     # These files aren't included directly from main.html. They are
     # referenced from the manifest.json file (appsv1 only).
     'remoting_webapp_js_auth_v1_files': [
-      'webapp/cs_third_party_auth_trampoline.js',  # client to host
-      'webapp/cs_oauth2_trampoline.js',  # Google account
+      'webapp/crd/js/cs_third_party_auth_trampoline.js',  # client to host
+      'webapp/crd/js/cs_oauth2_trampoline.js',  # Google account
     ],
     # Auth (client to host) JavaScript files.
     'remoting_webapp_js_auth_client2host_files': [
-      'webapp/third_party_host_permissions.js',
-      'webapp/third_party_token_fetcher.js',
+      'webapp/crd/js/third_party_host_permissions.js',
+      'webapp/crd/js/third_party_token_fetcher.js',
     ],
     # Auth (Google account) JavaScript files.
     'remoting_webapp_js_auth_google_files': [
-      'webapp/identity.js',
-      'webapp/oauth2.js',
-      'webapp/oauth2_api.js',
+      'webapp/crd/js/identity.js',
+      'webapp/crd/js/oauth2.js',
+      'webapp/crd/js/oauth2_api.js',
     ],
     # Client JavaScript files.
     'remoting_webapp_js_client_files': [
-      'webapp/client_plugin.js',
-      'webapp/client_plugin_impl.js',
+      'webapp/crd/js/client_plugin.js',
+      'webapp/crd/js/client_plugin_impl.js',
       # TODO(garykac) For client_screen:
       # * Split out pin/access code stuff into separate file.
       # * Move client logic into session_connector
-      'webapp/client_screen.js',
-      'webapp/client_session.js',
-      'webapp/clipboard.js',
-      'webapp/hangout_session.js',
-      'webapp/media_source_renderer.js',
-      'webapp/session_connector.js',
-      'webapp/session_connector_impl.js',
-      'webapp/smart_reconnector.js',
-      'webapp/video_frame_recorder.js',
+      'webapp/crd/js/client_screen.js',
+      'webapp/crd/js/client_session.js',
+      'webapp/crd/js/clipboard.js',
+      'webapp/crd/js/hangout_session.js',
+      'webapp/crd/js/media_source_renderer.js',
+      'webapp/crd/js/session_connector.js',
+      'webapp/crd/js/session_connector_impl.js',
+      'webapp/crd/js/smart_reconnector.js',
+      'webapp/crd/js/video_frame_recorder.js',
     ],
     # Remoting core JavaScript files.
     'remoting_webapp_js_core_files': [
-      'webapp/base.js',
-      'webapp/error.js',
-      'webapp/event_handlers.js',
-      'webapp/platform.js',
-      'webapp/plugin_settings.js',
+      'webapp/base/js/base.js',
+      'webapp/base/js/platform.js',
+      'webapp/crd/js/error.js',
+      'webapp/crd/js/event_handlers.js',
+      'webapp/crd/js/plugin_settings.js',
       # TODO(garykac) Split out UI client stuff from remoting.js.
-      'webapp/remoting.js',
-      'webapp/typecheck.js',
-      'webapp/xhr.js',
+      'webapp/crd/js/remoting.js',
+      'webapp/crd/js/typecheck.js',
+      'webapp/crd/js/xhr.js',
     ],
     # Host JavaScript files.
     # Includes both it2me and me2me files.
     'remoting_webapp_js_host_files': [
-      'webapp/host_controller.js',
-      'webapp/host_daemon_facade.js',
-      'webapp/it2me_host_facade.js',
-      'webapp/host_session.js',
+      'webapp/crd/js/host_controller.js',
+      'webapp/crd/js/host_daemon_facade.js',
+      'webapp/crd/js/it2me_host_facade.js',
+      'webapp/crd/js/host_session.js',
     ],
     # Logging and stats JavaScript files.
     'remoting_webapp_js_logging_files': [
-      'webapp/format_iq.js',
-      'webapp/log_to_server.js',
-      'webapp/server_log_entry.js',
-      'webapp/stats_accumulator.js',
+      'webapp/crd/js/format_iq.js',
+      'webapp/crd/js/log_to_server.js',
+      'webapp/crd/js/server_log_entry.js',
+      'webapp/crd/js/stats_accumulator.js',
     ],
     # UI JavaScript files.
     'remoting_webapp_js_ui_files': [
-      'webapp/butter_bar.js',
-      'webapp/connection_stats.js',
-      'webapp/feedback.js',
-      'webapp/fullscreen.js',
-      'webapp/fullscreen_v1.js',
-      'webapp/fullscreen_v2.js',
-      'webapp/l10n.js',
-      'webapp/menu_button.js',
-      'webapp/options_menu.js',
-      'webapp/ui_mode.js',
-      'webapp/toolbar.js',
-      'webapp/window_frame.js',
+      'webapp/crd/js/butter_bar.js',
+      'webapp/crd/js/connection_stats.js',
+      'webapp/crd/js/feedback.js',
+      'webapp/crd/js/fullscreen.js',
+      'webapp/crd/js/fullscreen_v1.js',
+      'webapp/crd/js/fullscreen_v2.js',
+      'webapp/crd/js/l10n.js',
+      'webapp/crd/js/menu_button.js',
+      'webapp/crd/js/options_menu.js',
+      'webapp/crd/js/ui_mode.js',
+      'webapp/crd/js/toolbar.js',
+      'webapp/crd/js/window_frame.js',
     ],
     # UI files for controlling the local machine as a host.
     'remoting_webapp_js_ui_host_control_files': [
-      'webapp/host_screen.js',
-      'webapp/host_setup_dialog.js',
-      'webapp/host_install_dialog.js',
-      'webapp/host_installer.js',
-      'webapp/paired_client_manager.js',
+      'webapp/crd/js/host_screen.js',
+      'webapp/crd/js/host_setup_dialog.js',
+      'webapp/crd/js/host_install_dialog.js',
+      'webapp/crd/js/host_installer.js',
+      'webapp/crd/js/paired_client_manager.js',
     ],
     # UI files for displaying (in the client) info about available hosts.
     'remoting_webapp_js_ui_host_display_files': [
-      'webapp/host.js',
-      'webapp/host_list.js',
-      'webapp/host_settings.js',
-      'webapp/host_table_entry.js',
+      'webapp/crd/js/host.js',
+      'webapp/crd/js/host_list.js',
+      'webapp/crd/js/host_settings.js',
+      'webapp/crd/js/host_table_entry.js',
     ],
     # Remoting signaling files.
     'remoting_webapp_js_signaling_files': [
-      'webapp/signal_strategy.js',
-      'webapp/wcs_adapter.js',
-      'webapp/wcs_sandbox_container.js',
-      'webapp/xmpp_connection.js',
-      'webapp/xmpp_login_handler.js',
-      'webapp/xmpp_stream_parser.js',
+      'webapp/crd/js/signal_strategy.js',
+      'webapp/crd/js/wcs_adapter.js',
+      'webapp/crd/js/wcs_sandbox_container.js',
+      'webapp/crd/js/xmpp_connection.js',
+      'webapp/crd/js/xmpp_login_handler.js',
+      'webapp/crd/js/xmpp_stream_parser.js',
     ],
     # Remoting WCS sandbox JavaScript files.
     'remoting_webapp_js_wcs_sandbox_files': [
-      'webapp/wcs.js',
-      'webapp/wcs_loader.js',
-      'webapp/wcs_sandbox_content.js',
-      'webapp/xhr_proxy.js',
+      'webapp/crd/js/wcs.js',
+      'webapp/crd/js/wcs_loader.js',
+      'webapp/crd/js/wcs_sandbox_content.js',
+      'webapp/crd/js/xhr_proxy.js',
     ],
     # gnubby authentication JavaScript files.
     'remoting_webapp_js_gnubby_auth_files': [
-      'webapp/gnubby_auth_handler.js',
+      'webapp/crd/js/gnubby_auth_handler.js',
     ],
     # cast extension handler JavaScript files.
     'remoting_webapp_js_cast_extension_files': [
-      'webapp/cast_extension_handler.js',
+      'webapp/crd/js/cast_extension_handler.js',
     ],
     # browser test JavaScript files.
     'remoting_webapp_js_browser_test_files': [
@@ -151,10 +151,10 @@
     'remoting_webapp_unittest_exclude_files': [
       # background.js is where the onLoad handler is defined, which
       # makes it the entry point of the background page.
-      'webapp/background/background.js',
+      'webapp/crd/js/background.js',
       # event_handlers.js is where the onLoad handler is defined, which
       # makes it the entry point of the webapp.
-      'webapp/event_handlers.js',
+      'webapp/crd/js/event_handlers.js',
     ],
     # The unit test cases for the webapp
     'remoting_webapp_unittest_js_files': [
@@ -171,10 +171,10 @@
       'webapp/unittests/xmpp_stream_parser_unittest.js',
     ],
     'remoting_webapp_unittest_additional_files': [
-      'webapp/menu_button.css',
+      'webapp/crd/html/menu_button.css',
     ],
     'remoting_webapp_unittest_template_main':
-      'webapp/html/template_unittest.html',
+      'webapp/crd/html/template_unittest.html',
 
     # The JavaScript files required by main.html.
     'remoting_webapp_main_html_js_files': [
@@ -199,29 +199,29 @@
 
     # The JavaScript files that are used in the background page.
     'remoting_webapp_background_js_files': [
-      'webapp/base.js',
-      'webapp/client_session.js',
-      'webapp/error.js',
-      'webapp/host_installer.js',
-      'webapp/host_session.js',
-      'webapp/it2me_host_facade.js',
-      'webapp/l10n.js',
-      'webapp/plugin_settings.js',
-      'webapp/typecheck.js',
-      'webapp/background/app_launcher.js',
-      'webapp/background/background.js',
-      'webapp/background/it2me_helpee_channel.js',
-      'webapp/background/it2me_helper_channel.js',
-      'webapp/background/it2me_service.js',
-      'webapp/background/message_window_helper.js',
-      'webapp/background/message_window_manager.js',
+      'webapp/base/js/base.js',
+      'webapp/base/js/message_window_helper.js',
+      'webapp/base/js/message_window_manager.js',
+      'webapp/crd/js/app_launcher.js',
+      'webapp/crd/js/background.js',
+      'webapp/crd/js/client_session.js',
+      'webapp/crd/js/error.js',
+      'webapp/crd/js/host_installer.js',
+      'webapp/crd/js/host_session.js',
+      'webapp/crd/js/it2me_helpee_channel.js',
+      'webapp/crd/js/it2me_helper_channel.js',
+      'webapp/crd/js/it2me_host_facade.js',
+      'webapp/crd/js/it2me_service.js',
+      'webapp/crd/js/l10n.js',
+      'webapp/crd/js/plugin_settings.js',
+      'webapp/crd/js/typecheck.js',
     ],
 
     # The JavaScript files required by wcs_sandbox.html.
     'remoting_webapp_wcs_sandbox_html_js_files': [
       '<@(remoting_webapp_js_wcs_sandbox_files)',
-      'webapp/error.js',
-      'webapp/plugin_settings.js',
+      'webapp/crd/js/error.js',
+      'webapp/crd/js/plugin_settings.js',
     ],
 
     # All the JavaScript files required by the webapp.
@@ -230,7 +230,7 @@
       '<@(remoting_webapp_main_html_js_files)',
       '<@(remoting_webapp_background_js_files)',
       # JS files for message_window.html
-      'webapp/background/message_window.js',
+      'webapp/base/js/message_window.js',
       # JS files for wcs_sandbox.html.
       # Use r_w_js_wcs_sandbox_files instead of r_w_wcs_sandbox_html_js_files
       # so that we don't double include error.js and plugin_settings.js.
@@ -260,17 +260,17 @@
       'resources/plus.webp',
       'resources/reload.webp',
       'resources/tick.webp',
-      'webapp/connection_stats.css',
-      'webapp/html/message_window.html',
-      'webapp/main.css',
-      'webapp/menu_button.css',
-      'webapp/message_window.css',
-      'webapp/open_sans.css',
-      'webapp/open_sans.woff',
-      'webapp/scale-to-fit.webp',
-      'webapp/spinner.gif',
-      'webapp/toolbar.css',
-      'webapp/window_frame.css',
+      'webapp/base/html/connection_stats.css',
+      'webapp/base/html/message_window.html',
+      'webapp/base/html/main.css',
+      'webapp/base/html/message_window.css',
+      'webapp/base/resources/open_sans.css',
+      'webapp/base/resources/open_sans.woff',
+      'webapp/base/resources/spinner.gif',
+      'webapp/crd/html/toolbar.css',
+      'webapp/crd/html/menu_button.css',
+      'webapp/crd/html/window_frame.css',
+      'webapp/crd/resources/scale-to-fit.webp',
     ],
 
     'remoting_webapp_files': [
@@ -281,37 +281,37 @@
 
     # These template files are used to construct the webapp html files.
     'remoting_webapp_template_main':
-      'webapp/html/template_main.html',
+      'webapp/crd/html/template_main.html',
 
     'remoting_webapp_template_wcs_sandbox':
-      'webapp/html/template_wcs_sandbox.html',
+      'webapp/base/html/template_wcs_sandbox.html',
 
     'remoting_webapp_template_background':
-      'webapp/html/template_background.html',
+      'webapp/crd/html/template_background.html',
 
     'remoting_webapp_template_files': [
-      'webapp/html/butterbar.html',
-      'webapp/html/client_plugin.html',
-      'webapp/html/dialog_auth.html',
-      'webapp/html/dialog_client_connect_failed.html',
-      'webapp/html/dialog_client_connecting.html',
-      'webapp/html/dialog_client_host_needs_upgrade.html',
-      'webapp/html/dialog_client_pin_prompt.html',
-      'webapp/html/dialog_client_session_finished.html',
-      'webapp/html/dialog_client_third_party_auth.html',
-      'webapp/html/dialog_client_unconnected.html',
-      'webapp/html/dialog_confirm_host_delete.html',
-      'webapp/html/dialog_connection_history.html',
-      'webapp/html/dialog_host.html',
-      'webapp/html/dialog_host_install.html',
-      'webapp/html/dialog_host_setup.html',
-      'webapp/html/dialog_manage_pairings.html',
-      'webapp/html/dialog_token_refresh_failed.html',
-      'webapp/html/toolbar.html',
-      'webapp/html/ui_header.html',
-      'webapp/html/ui_it2me.html',
-      'webapp/html/ui_me2me.html',
-      'webapp/html/window_frame.html',
+      'webapp/base/html/client_plugin.html',
+      'webapp/base/html/dialog_auth.html',
+      'webapp/crd/html/butterbar.html',
+      'webapp/crd/html/dialog_client_connect_failed.html',
+      'webapp/crd/html/dialog_client_connecting.html',
+      'webapp/crd/html/dialog_client_host_needs_upgrade.html',
+      'webapp/crd/html/dialog_client_pin_prompt.html',
+      'webapp/crd/html/dialog_client_session_finished.html',
+      'webapp/crd/html/dialog_client_third_party_auth.html',
+      'webapp/crd/html/dialog_client_unconnected.html',
+      'webapp/crd/html/dialog_confirm_host_delete.html',
+      'webapp/crd/html/dialog_connection_history.html',
+      'webapp/crd/html/dialog_host.html',
+      'webapp/crd/html/dialog_host_install.html',
+      'webapp/crd/html/dialog_host_setup.html',
+      'webapp/crd/html/dialog_manage_pairings.html',
+      'webapp/crd/html/dialog_token_refresh_failed.html',
+      'webapp/crd/html/toolbar.html',
+      'webapp/crd/html/ui_header.html',
+      'webapp/crd/html/ui_it2me.html',
+      'webapp/crd/html/ui_me2me.html',
+      'webapp/crd/html/window_frame.html',
     ],
 
   },
diff --git a/remoting/resources/remoting_strings.grd b/remoting/resources/remoting_strings.grd
index 60c3923..764cf78 100644
--- a/remoting/resources/remoting_strings.grd
+++ b/remoting/resources/remoting_strings.grd
@@ -463,7 +463,7 @@
 For information about privacy, please see the Google Privacy Policy (http://goo.gl/SyrVzj) and the Chrome Privacy Policy (http://goo.gl/0uXE5d).
         </message>
         <message name="IDS_PLAY_STORE_CHANGES" desc="List of what's changed in this release of Chrome Remote Desktop for Android. [CHAR-LIMIT=500] [NAME=play_store_changes]">
-• Fixes for Android L.
+• Fixes for Android Lollipop.
         </message>
       </if>
 
diff --git a/remoting/webapp/html/client_plugin.html b/remoting/webapp/base/html/client_plugin.html
similarity index 100%
rename from remoting/webapp/html/client_plugin.html
rename to remoting/webapp/base/html/client_plugin.html
diff --git a/remoting/webapp/connection_stats.css b/remoting/webapp/base/html/connection_stats.css
similarity index 100%
rename from remoting/webapp/connection_stats.css
rename to remoting/webapp/base/html/connection_stats.css
diff --git a/remoting/webapp/html/dialog_auth.html b/remoting/webapp/base/html/dialog_auth.html
similarity index 100%
rename from remoting/webapp/html/dialog_auth.html
rename to remoting/webapp/base/html/dialog_auth.html
diff --git a/remoting/webapp/main.css b/remoting/webapp/base/html/main.css
similarity index 100%
rename from remoting/webapp/main.css
rename to remoting/webapp/base/html/main.css
diff --git a/remoting/webapp/message_window.css b/remoting/webapp/base/html/message_window.css
similarity index 100%
rename from remoting/webapp/message_window.css
rename to remoting/webapp/base/html/message_window.css
diff --git a/remoting/webapp/html/message_window.html b/remoting/webapp/base/html/message_window.html
similarity index 100%
rename from remoting/webapp/html/message_window.html
rename to remoting/webapp/base/html/message_window.html
diff --git a/remoting/webapp/html/template_wcs_sandbox.html b/remoting/webapp/base/html/template_wcs_sandbox.html
similarity index 100%
rename from remoting/webapp/html/template_wcs_sandbox.html
rename to remoting/webapp/base/html/template_wcs_sandbox.html
diff --git a/remoting/webapp/base.js b/remoting/webapp/base/js/base.js
similarity index 100%
rename from remoting/webapp/base.js
rename to remoting/webapp/base/js/base.js
diff --git a/remoting/webapp/background/message_window.js b/remoting/webapp/base/js/message_window.js
similarity index 100%
rename from remoting/webapp/background/message_window.js
rename to remoting/webapp/base/js/message_window.js
diff --git a/remoting/webapp/background/message_window_helper.js b/remoting/webapp/base/js/message_window_helper.js
similarity index 100%
rename from remoting/webapp/background/message_window_helper.js
rename to remoting/webapp/base/js/message_window_helper.js
diff --git a/remoting/webapp/background/message_window_manager.js b/remoting/webapp/base/js/message_window_manager.js
similarity index 100%
rename from remoting/webapp/background/message_window_manager.js
rename to remoting/webapp/base/js/message_window_manager.js
diff --git a/remoting/webapp/platform.js b/remoting/webapp/base/js/platform.js
similarity index 100%
rename from remoting/webapp/platform.js
rename to remoting/webapp/base/js/platform.js
diff --git a/remoting/webapp/open_sans.css b/remoting/webapp/base/resources/open_sans.css
similarity index 100%
rename from remoting/webapp/open_sans.css
rename to remoting/webapp/base/resources/open_sans.css
diff --git a/remoting/webapp/open_sans.woff b/remoting/webapp/base/resources/open_sans.woff
similarity index 100%
rename from remoting/webapp/open_sans.woff
rename to remoting/webapp/base/resources/open_sans.woff
Binary files differ
diff --git a/remoting/webapp/spinner.gif b/remoting/webapp/base/resources/spinner.gif
similarity index 100%
rename from remoting/webapp/spinner.gif
rename to remoting/webapp/base/resources/spinner.gif
Binary files differ
diff --git a/remoting/webapp/html/butterbar.html b/remoting/webapp/crd/html/butterbar.html
similarity index 100%
rename from remoting/webapp/html/butterbar.html
rename to remoting/webapp/crd/html/butterbar.html
diff --git a/remoting/webapp/html/dialog_client_connect_failed.html b/remoting/webapp/crd/html/dialog_client_connect_failed.html
similarity index 100%
rename from remoting/webapp/html/dialog_client_connect_failed.html
rename to remoting/webapp/crd/html/dialog_client_connect_failed.html
diff --git a/remoting/webapp/html/dialog_client_connecting.html b/remoting/webapp/crd/html/dialog_client_connecting.html
similarity index 100%
rename from remoting/webapp/html/dialog_client_connecting.html
rename to remoting/webapp/crd/html/dialog_client_connecting.html
diff --git a/remoting/webapp/html/dialog_client_host_needs_upgrade.html b/remoting/webapp/crd/html/dialog_client_host_needs_upgrade.html
similarity index 100%
rename from remoting/webapp/html/dialog_client_host_needs_upgrade.html
rename to remoting/webapp/crd/html/dialog_client_host_needs_upgrade.html
diff --git a/remoting/webapp/html/dialog_client_pin_prompt.html b/remoting/webapp/crd/html/dialog_client_pin_prompt.html
similarity index 100%
rename from remoting/webapp/html/dialog_client_pin_prompt.html
rename to remoting/webapp/crd/html/dialog_client_pin_prompt.html
diff --git a/remoting/webapp/html/dialog_client_session_finished.html b/remoting/webapp/crd/html/dialog_client_session_finished.html
similarity index 100%
rename from remoting/webapp/html/dialog_client_session_finished.html
rename to remoting/webapp/crd/html/dialog_client_session_finished.html
diff --git a/remoting/webapp/html/dialog_client_third_party_auth.html b/remoting/webapp/crd/html/dialog_client_third_party_auth.html
similarity index 100%
rename from remoting/webapp/html/dialog_client_third_party_auth.html
rename to remoting/webapp/crd/html/dialog_client_third_party_auth.html
diff --git a/remoting/webapp/html/dialog_client_unconnected.html b/remoting/webapp/crd/html/dialog_client_unconnected.html
similarity index 100%
rename from remoting/webapp/html/dialog_client_unconnected.html
rename to remoting/webapp/crd/html/dialog_client_unconnected.html
diff --git a/remoting/webapp/html/dialog_confirm_host_delete.html b/remoting/webapp/crd/html/dialog_confirm_host_delete.html
similarity index 100%
rename from remoting/webapp/html/dialog_confirm_host_delete.html
rename to remoting/webapp/crd/html/dialog_confirm_host_delete.html
diff --git a/remoting/webapp/html/dialog_connection_history.html b/remoting/webapp/crd/html/dialog_connection_history.html
similarity index 100%
rename from remoting/webapp/html/dialog_connection_history.html
rename to remoting/webapp/crd/html/dialog_connection_history.html
diff --git a/remoting/webapp/html/dialog_host.html b/remoting/webapp/crd/html/dialog_host.html
similarity index 100%
rename from remoting/webapp/html/dialog_host.html
rename to remoting/webapp/crd/html/dialog_host.html
diff --git a/remoting/webapp/html/dialog_host_install.html b/remoting/webapp/crd/html/dialog_host_install.html
similarity index 100%
rename from remoting/webapp/html/dialog_host_install.html
rename to remoting/webapp/crd/html/dialog_host_install.html
diff --git a/remoting/webapp/html/dialog_host_setup.html b/remoting/webapp/crd/html/dialog_host_setup.html
similarity index 100%
rename from remoting/webapp/html/dialog_host_setup.html
rename to remoting/webapp/crd/html/dialog_host_setup.html
diff --git a/remoting/webapp/html/dialog_manage_pairings.html b/remoting/webapp/crd/html/dialog_manage_pairings.html
similarity index 100%
rename from remoting/webapp/html/dialog_manage_pairings.html
rename to remoting/webapp/crd/html/dialog_manage_pairings.html
diff --git a/remoting/webapp/html/dialog_token_refresh_failed.html b/remoting/webapp/crd/html/dialog_token_refresh_failed.html
similarity index 100%
rename from remoting/webapp/html/dialog_token_refresh_failed.html
rename to remoting/webapp/crd/html/dialog_token_refresh_failed.html
diff --git a/remoting/webapp/menu_button.css b/remoting/webapp/crd/html/menu_button.css
similarity index 100%
rename from remoting/webapp/menu_button.css
rename to remoting/webapp/crd/html/menu_button.css
diff --git a/remoting/webapp/html/template_background.html b/remoting/webapp/crd/html/template_background.html
similarity index 100%
rename from remoting/webapp/html/template_background.html
rename to remoting/webapp/crd/html/template_background.html
diff --git a/remoting/webapp/html/template_main.html b/remoting/webapp/crd/html/template_main.html
similarity index 62%
rename from remoting/webapp/html/template_main.html
rename to remoting/webapp/crd/html/template_main.html
index b468339..2ba4d04 100644
--- a/remoting/webapp/html/template_main.html
+++ b/remoting/webapp/crd/html/template_main.html
@@ -23,7 +23,7 @@
 
   <body class="full-height">
 
-    <meta-include src="webapp/html/window_frame.html"/>
+    <meta-include src="webapp/crd/html/window_frame.html"/>
 
     <div class="window-body full-height">
 
@@ -44,10 +44,10 @@
              data-ui-mode="home"
              hidden>
 
-          <meta-include src="webapp/html/ui_header.html"/>
-          <meta-include src="webapp/html/butterbar.html"/>
-          <meta-include src="webapp/html/ui_it2me.html"/>
-          <meta-include src="webapp/html/ui_me2me.html"/>
+          <meta-include src="webapp/crd/html/ui_header.html"/>
+          <meta-include src="webapp/crd/html/butterbar.html"/>
+          <meta-include src="webapp/crd/html/ui_it2me.html"/>
+          <meta-include src="webapp/crd/html/ui_me2me.html"/>
 
           <!-- The bottom-marker div is used to verify scroll-bar correctness
                in browser tests; it is not rendered. -->
@@ -60,8 +60,8 @@
              class="full-height"
              hidden>
 
-          <meta-include src="webapp/html/toolbar.html"/>
-          <meta-include src="webapp/html/client_plugin.html"/>
+          <meta-include src="webapp/crd/html/toolbar.html"/>
+          <meta-include src="webapp/base/html/client_plugin.html"/>
 
         </div>  <!-- session-mode -->
 
@@ -70,7 +70,7 @@
 
       </div>  <!-- scroller -->
 
-      <meta-include src="webapp/html/dialog_auth.html"/>
+      <meta-include src="webapp/base/html/dialog_auth.html"/>
 
       <div class="dialog-screen"
            data-ui-mode="home.host home.client home.history home.confirm-host-delete home.host-setup home.token-refresh-failed home.manage-pairings home.host-setup home.host-install"
@@ -80,27 +80,27 @@
            data-ui-mode="home.host home.client home.history home.confirm-host-delete home.host-install home.host-setup home.token-refresh-failed home.manage-pairings"
            hidden>
 
-        <meta-include src="webapp/html/dialog_token_refresh_failed.html"/>
-        <meta-include src="webapp/html/dialog_host_setup.html"/>
-        <meta-include src="webapp/html/dialog_host_install.html"/>
-        <meta-include src="webapp/html/dialog_host.html"/>
+        <meta-include src="webapp/crd/html/dialog_token_refresh_failed.html"/>
+        <meta-include src="webapp/crd/html/dialog_host_setup.html"/>
+        <meta-include src="webapp/crd/html/dialog_host_install.html"/>
+        <meta-include src="webapp/crd/html/dialog_host.html"/>
 
         <div id="client-dialog"
              class="kd-modaldialog"
              data-ui-mode="home.client">
 
-          <meta-include src="webapp/html/dialog_client_unconnected.html"/>
-          <meta-include src="webapp/html/dialog_client_connecting.html"/>
-          <meta-include src="webapp/html/dialog_client_host_needs_upgrade.html"/>
-          <meta-include src="webapp/html/dialog_client_pin_prompt.html"/>
-          <meta-include src="webapp/html/dialog_client_third_party_auth.html"/>
-          <meta-include src="webapp/html/dialog_client_connect_failed.html"/>
-          <meta-include src="webapp/html/dialog_client_session_finished.html"/>
+          <meta-include src="webapp/crd/html/dialog_client_unconnected.html"/>
+          <meta-include src="webapp/crd/html/dialog_client_connecting.html"/>
+          <meta-include src="webapp/crd/html/dialog_client_host_needs_upgrade.html"/>
+          <meta-include src="webapp/crd/html/dialog_client_pin_prompt.html"/>
+          <meta-include src="webapp/crd/html/dialog_client_third_party_auth.html"/>
+          <meta-include src="webapp/crd/html/dialog_client_connect_failed.html"/>
+          <meta-include src="webapp/crd/html/dialog_client_session_finished.html"/>
         </div>
 
-        <meta-include src="webapp/html/dialog_connection_history.html"/>
-        <meta-include src="webapp/html/dialog_confirm_host_delete.html"/>
-        <meta-include src="webapp/html/dialog_manage_pairings.html"/>
+        <meta-include src="webapp/crd/html/dialog_connection_history.html"/>
+        <meta-include src="webapp/crd/html/dialog_confirm_host_delete.html"/>
+        <meta-include src="webapp/crd/html/dialog_manage_pairings.html"/>
 
       </div>  <!-- dialog-container -->
 
diff --git a/remoting/webapp/html/template_unittest.html b/remoting/webapp/crd/html/template_unittest.html
similarity index 100%
rename from remoting/webapp/html/template_unittest.html
rename to remoting/webapp/crd/html/template_unittest.html
diff --git a/remoting/webapp/toolbar.css b/remoting/webapp/crd/html/toolbar.css
similarity index 100%
rename from remoting/webapp/toolbar.css
rename to remoting/webapp/crd/html/toolbar.css
diff --git a/remoting/webapp/html/toolbar.html b/remoting/webapp/crd/html/toolbar.html
similarity index 100%
rename from remoting/webapp/html/toolbar.html
rename to remoting/webapp/crd/html/toolbar.html
diff --git a/remoting/webapp/html/ui_header.html b/remoting/webapp/crd/html/ui_header.html
similarity index 100%
rename from remoting/webapp/html/ui_header.html
rename to remoting/webapp/crd/html/ui_header.html
diff --git a/remoting/webapp/html/ui_it2me.html b/remoting/webapp/crd/html/ui_it2me.html
similarity index 100%
rename from remoting/webapp/html/ui_it2me.html
rename to remoting/webapp/crd/html/ui_it2me.html
diff --git a/remoting/webapp/html/ui_me2me.html b/remoting/webapp/crd/html/ui_me2me.html
similarity index 100%
rename from remoting/webapp/html/ui_me2me.html
rename to remoting/webapp/crd/html/ui_me2me.html
diff --git a/remoting/webapp/window_frame.css b/remoting/webapp/crd/html/window_frame.css
similarity index 100%
rename from remoting/webapp/window_frame.css
rename to remoting/webapp/crd/html/window_frame.css
diff --git a/remoting/webapp/html/window_frame.html b/remoting/webapp/crd/html/window_frame.html
similarity index 100%
rename from remoting/webapp/html/window_frame.html
rename to remoting/webapp/crd/html/window_frame.html
diff --git a/remoting/webapp/background/app_launcher.js b/remoting/webapp/crd/js/app_launcher.js
similarity index 100%
rename from remoting/webapp/background/app_launcher.js
rename to remoting/webapp/crd/js/app_launcher.js
diff --git a/remoting/webapp/background/background.js b/remoting/webapp/crd/js/background.js
similarity index 100%
rename from remoting/webapp/background/background.js
rename to remoting/webapp/crd/js/background.js
diff --git a/remoting/webapp/butter_bar.js b/remoting/webapp/crd/js/butter_bar.js
similarity index 100%
rename from remoting/webapp/butter_bar.js
rename to remoting/webapp/crd/js/butter_bar.js
diff --git a/remoting/webapp/cast_extension_handler.js b/remoting/webapp/crd/js/cast_extension_handler.js
similarity index 100%
rename from remoting/webapp/cast_extension_handler.js
rename to remoting/webapp/crd/js/cast_extension_handler.js
diff --git a/remoting/webapp/client_plugin.js b/remoting/webapp/crd/js/client_plugin.js
similarity index 100%
rename from remoting/webapp/client_plugin.js
rename to remoting/webapp/crd/js/client_plugin.js
diff --git a/remoting/webapp/client_plugin_impl.js b/remoting/webapp/crd/js/client_plugin_impl.js
similarity index 100%
rename from remoting/webapp/client_plugin_impl.js
rename to remoting/webapp/crd/js/client_plugin_impl.js
diff --git a/remoting/webapp/client_screen.js b/remoting/webapp/crd/js/client_screen.js
similarity index 100%
rename from remoting/webapp/client_screen.js
rename to remoting/webapp/crd/js/client_screen.js
diff --git a/remoting/webapp/client_session.js b/remoting/webapp/crd/js/client_session.js
similarity index 100%
rename from remoting/webapp/client_session.js
rename to remoting/webapp/crd/js/client_session.js
diff --git a/remoting/webapp/clipboard.js b/remoting/webapp/crd/js/clipboard.js
similarity index 100%
rename from remoting/webapp/clipboard.js
rename to remoting/webapp/crd/js/clipboard.js
diff --git a/remoting/webapp/connection_stats.js b/remoting/webapp/crd/js/connection_stats.js
similarity index 100%
rename from remoting/webapp/connection_stats.js
rename to remoting/webapp/crd/js/connection_stats.js
diff --git a/remoting/webapp/cs_oauth2_trampoline.js b/remoting/webapp/crd/js/cs_oauth2_trampoline.js
similarity index 100%
rename from remoting/webapp/cs_oauth2_trampoline.js
rename to remoting/webapp/crd/js/cs_oauth2_trampoline.js
diff --git a/remoting/webapp/cs_third_party_auth_trampoline.js b/remoting/webapp/crd/js/cs_third_party_auth_trampoline.js
similarity index 100%
rename from remoting/webapp/cs_third_party_auth_trampoline.js
rename to remoting/webapp/crd/js/cs_third_party_auth_trampoline.js
diff --git a/remoting/webapp/error.js b/remoting/webapp/crd/js/error.js
similarity index 100%
rename from remoting/webapp/error.js
rename to remoting/webapp/crd/js/error.js
diff --git a/remoting/webapp/event_handlers.js b/remoting/webapp/crd/js/event_handlers.js
similarity index 100%
rename from remoting/webapp/event_handlers.js
rename to remoting/webapp/crd/js/event_handlers.js
diff --git a/remoting/webapp/feedback.js b/remoting/webapp/crd/js/feedback.js
similarity index 100%
rename from remoting/webapp/feedback.js
rename to remoting/webapp/crd/js/feedback.js
diff --git a/remoting/webapp/format_iq.js b/remoting/webapp/crd/js/format_iq.js
similarity index 100%
rename from remoting/webapp/format_iq.js
rename to remoting/webapp/crd/js/format_iq.js
diff --git a/remoting/webapp/fullscreen.js b/remoting/webapp/crd/js/fullscreen.js
similarity index 100%
rename from remoting/webapp/fullscreen.js
rename to remoting/webapp/crd/js/fullscreen.js
diff --git a/remoting/webapp/fullscreen_v1.js b/remoting/webapp/crd/js/fullscreen_v1.js
similarity index 100%
rename from remoting/webapp/fullscreen_v1.js
rename to remoting/webapp/crd/js/fullscreen_v1.js
diff --git a/remoting/webapp/fullscreen_v2.js b/remoting/webapp/crd/js/fullscreen_v2.js
similarity index 100%
rename from remoting/webapp/fullscreen_v2.js
rename to remoting/webapp/crd/js/fullscreen_v2.js
diff --git a/remoting/webapp/gnubby_auth_handler.js b/remoting/webapp/crd/js/gnubby_auth_handler.js
similarity index 100%
rename from remoting/webapp/gnubby_auth_handler.js
rename to remoting/webapp/crd/js/gnubby_auth_handler.js
diff --git a/remoting/webapp/hangout_session.js b/remoting/webapp/crd/js/hangout_session.js
similarity index 100%
rename from remoting/webapp/hangout_session.js
rename to remoting/webapp/crd/js/hangout_session.js
diff --git a/remoting/webapp/host.js b/remoting/webapp/crd/js/host.js
similarity index 100%
rename from remoting/webapp/host.js
rename to remoting/webapp/crd/js/host.js
diff --git a/remoting/webapp/host_controller.js b/remoting/webapp/crd/js/host_controller.js
similarity index 100%
rename from remoting/webapp/host_controller.js
rename to remoting/webapp/crd/js/host_controller.js
diff --git a/remoting/webapp/host_daemon_facade.js b/remoting/webapp/crd/js/host_daemon_facade.js
similarity index 100%
rename from remoting/webapp/host_daemon_facade.js
rename to remoting/webapp/crd/js/host_daemon_facade.js
diff --git a/remoting/webapp/host_install_dialog.js b/remoting/webapp/crd/js/host_install_dialog.js
similarity index 100%
rename from remoting/webapp/host_install_dialog.js
rename to remoting/webapp/crd/js/host_install_dialog.js
diff --git a/remoting/webapp/host_installer.js b/remoting/webapp/crd/js/host_installer.js
similarity index 100%
rename from remoting/webapp/host_installer.js
rename to remoting/webapp/crd/js/host_installer.js
diff --git a/remoting/webapp/host_list.js b/remoting/webapp/crd/js/host_list.js
similarity index 100%
rename from remoting/webapp/host_list.js
rename to remoting/webapp/crd/js/host_list.js
diff --git a/remoting/webapp/host_screen.js b/remoting/webapp/crd/js/host_screen.js
similarity index 100%
rename from remoting/webapp/host_screen.js
rename to remoting/webapp/crd/js/host_screen.js
diff --git a/remoting/webapp/host_session.js b/remoting/webapp/crd/js/host_session.js
similarity index 100%
rename from remoting/webapp/host_session.js
rename to remoting/webapp/crd/js/host_session.js
diff --git a/remoting/webapp/host_settings.js b/remoting/webapp/crd/js/host_settings.js
similarity index 100%
rename from remoting/webapp/host_settings.js
rename to remoting/webapp/crd/js/host_settings.js
diff --git a/remoting/webapp/host_setup_dialog.js b/remoting/webapp/crd/js/host_setup_dialog.js
similarity index 100%
rename from remoting/webapp/host_setup_dialog.js
rename to remoting/webapp/crd/js/host_setup_dialog.js
diff --git a/remoting/webapp/host_table_entry.js b/remoting/webapp/crd/js/host_table_entry.js
similarity index 100%
rename from remoting/webapp/host_table_entry.js
rename to remoting/webapp/crd/js/host_table_entry.js
diff --git a/remoting/webapp/identity.js b/remoting/webapp/crd/js/identity.js
similarity index 100%
rename from remoting/webapp/identity.js
rename to remoting/webapp/crd/js/identity.js
diff --git a/remoting/webapp/background/it2me_helpee_channel.js b/remoting/webapp/crd/js/it2me_helpee_channel.js
similarity index 100%
rename from remoting/webapp/background/it2me_helpee_channel.js
rename to remoting/webapp/crd/js/it2me_helpee_channel.js
diff --git a/remoting/webapp/background/it2me_helper_channel.js b/remoting/webapp/crd/js/it2me_helper_channel.js
similarity index 100%
rename from remoting/webapp/background/it2me_helper_channel.js
rename to remoting/webapp/crd/js/it2me_helper_channel.js
diff --git a/remoting/webapp/it2me_host_facade.js b/remoting/webapp/crd/js/it2me_host_facade.js
similarity index 100%
rename from remoting/webapp/it2me_host_facade.js
rename to remoting/webapp/crd/js/it2me_host_facade.js
diff --git a/remoting/webapp/background/it2me_service.js b/remoting/webapp/crd/js/it2me_service.js
similarity index 100%
rename from remoting/webapp/background/it2me_service.js
rename to remoting/webapp/crd/js/it2me_service.js
diff --git a/remoting/webapp/l10n.js b/remoting/webapp/crd/js/l10n.js
similarity index 100%
rename from remoting/webapp/l10n.js
rename to remoting/webapp/crd/js/l10n.js
diff --git a/remoting/webapp/log_to_server.js b/remoting/webapp/crd/js/log_to_server.js
similarity index 100%
rename from remoting/webapp/log_to_server.js
rename to remoting/webapp/crd/js/log_to_server.js
diff --git a/remoting/webapp/media_source_renderer.js b/remoting/webapp/crd/js/media_source_renderer.js
similarity index 100%
rename from remoting/webapp/media_source_renderer.js
rename to remoting/webapp/crd/js/media_source_renderer.js
diff --git a/remoting/webapp/menu_button.js b/remoting/webapp/crd/js/menu_button.js
similarity index 100%
rename from remoting/webapp/menu_button.js
rename to remoting/webapp/crd/js/menu_button.js
diff --git a/remoting/webapp/oauth2.js b/remoting/webapp/crd/js/oauth2.js
similarity index 100%
rename from remoting/webapp/oauth2.js
rename to remoting/webapp/crd/js/oauth2.js
diff --git a/remoting/webapp/oauth2_api.js b/remoting/webapp/crd/js/oauth2_api.js
similarity index 100%
rename from remoting/webapp/oauth2_api.js
rename to remoting/webapp/crd/js/oauth2_api.js
diff --git a/remoting/webapp/options_menu.js b/remoting/webapp/crd/js/options_menu.js
similarity index 100%
rename from remoting/webapp/options_menu.js
rename to remoting/webapp/crd/js/options_menu.js
diff --git a/remoting/webapp/paired_client_manager.js b/remoting/webapp/crd/js/paired_client_manager.js
similarity index 100%
rename from remoting/webapp/paired_client_manager.js
rename to remoting/webapp/crd/js/paired_client_manager.js
diff --git a/remoting/webapp/plugin_settings.js b/remoting/webapp/crd/js/plugin_settings.js
similarity index 100%
rename from remoting/webapp/plugin_settings.js
rename to remoting/webapp/crd/js/plugin_settings.js
diff --git a/remoting/webapp/remoting.js b/remoting/webapp/crd/js/remoting.js
similarity index 100%
rename from remoting/webapp/remoting.js
rename to remoting/webapp/crd/js/remoting.js
diff --git a/remoting/webapp/server_log_entry.js b/remoting/webapp/crd/js/server_log_entry.js
similarity index 100%
rename from remoting/webapp/server_log_entry.js
rename to remoting/webapp/crd/js/server_log_entry.js
diff --git a/remoting/webapp/session_connector.js b/remoting/webapp/crd/js/session_connector.js
similarity index 100%
rename from remoting/webapp/session_connector.js
rename to remoting/webapp/crd/js/session_connector.js
diff --git a/remoting/webapp/session_connector_impl.js b/remoting/webapp/crd/js/session_connector_impl.js
similarity index 100%
rename from remoting/webapp/session_connector_impl.js
rename to remoting/webapp/crd/js/session_connector_impl.js
diff --git a/remoting/webapp/signal_strategy.js b/remoting/webapp/crd/js/signal_strategy.js
similarity index 100%
rename from remoting/webapp/signal_strategy.js
rename to remoting/webapp/crd/js/signal_strategy.js
diff --git a/remoting/webapp/smart_reconnector.js b/remoting/webapp/crd/js/smart_reconnector.js
similarity index 100%
rename from remoting/webapp/smart_reconnector.js
rename to remoting/webapp/crd/js/smart_reconnector.js
diff --git a/remoting/webapp/stats_accumulator.js b/remoting/webapp/crd/js/stats_accumulator.js
similarity index 100%
rename from remoting/webapp/stats_accumulator.js
rename to remoting/webapp/crd/js/stats_accumulator.js
diff --git a/remoting/webapp/third_party_host_permissions.js b/remoting/webapp/crd/js/third_party_host_permissions.js
similarity index 100%
rename from remoting/webapp/third_party_host_permissions.js
rename to remoting/webapp/crd/js/third_party_host_permissions.js
diff --git a/remoting/webapp/third_party_token_fetcher.js b/remoting/webapp/crd/js/third_party_token_fetcher.js
similarity index 100%
rename from remoting/webapp/third_party_token_fetcher.js
rename to remoting/webapp/crd/js/third_party_token_fetcher.js
diff --git a/remoting/webapp/toolbar.js b/remoting/webapp/crd/js/toolbar.js
similarity index 100%
rename from remoting/webapp/toolbar.js
rename to remoting/webapp/crd/js/toolbar.js
diff --git a/remoting/webapp/typecheck.js b/remoting/webapp/crd/js/typecheck.js
similarity index 100%
rename from remoting/webapp/typecheck.js
rename to remoting/webapp/crd/js/typecheck.js
diff --git a/remoting/webapp/ui_mode.js b/remoting/webapp/crd/js/ui_mode.js
similarity index 100%
rename from remoting/webapp/ui_mode.js
rename to remoting/webapp/crd/js/ui_mode.js
diff --git a/remoting/webapp/video_frame_recorder.js b/remoting/webapp/crd/js/video_frame_recorder.js
similarity index 100%
rename from remoting/webapp/video_frame_recorder.js
rename to remoting/webapp/crd/js/video_frame_recorder.js
diff --git a/remoting/webapp/wcs.js b/remoting/webapp/crd/js/wcs.js
similarity index 100%
rename from remoting/webapp/wcs.js
rename to remoting/webapp/crd/js/wcs.js
diff --git a/remoting/webapp/wcs_adapter.js b/remoting/webapp/crd/js/wcs_adapter.js
similarity index 100%
rename from remoting/webapp/wcs_adapter.js
rename to remoting/webapp/crd/js/wcs_adapter.js
diff --git a/remoting/webapp/wcs_loader.js b/remoting/webapp/crd/js/wcs_loader.js
similarity index 100%
rename from remoting/webapp/wcs_loader.js
rename to remoting/webapp/crd/js/wcs_loader.js
diff --git a/remoting/webapp/wcs_sandbox_container.js b/remoting/webapp/crd/js/wcs_sandbox_container.js
similarity index 100%
rename from remoting/webapp/wcs_sandbox_container.js
rename to remoting/webapp/crd/js/wcs_sandbox_container.js
diff --git a/remoting/webapp/wcs_sandbox_content.js b/remoting/webapp/crd/js/wcs_sandbox_content.js
similarity index 100%
rename from remoting/webapp/wcs_sandbox_content.js
rename to remoting/webapp/crd/js/wcs_sandbox_content.js
diff --git a/remoting/webapp/window_frame.js b/remoting/webapp/crd/js/window_frame.js
similarity index 100%
rename from remoting/webapp/window_frame.js
rename to remoting/webapp/crd/js/window_frame.js
diff --git a/remoting/webapp/xhr.js b/remoting/webapp/crd/js/xhr.js
similarity index 100%
rename from remoting/webapp/xhr.js
rename to remoting/webapp/crd/js/xhr.js
diff --git a/remoting/webapp/xhr_proxy.js b/remoting/webapp/crd/js/xhr_proxy.js
similarity index 100%
rename from remoting/webapp/xhr_proxy.js
rename to remoting/webapp/crd/js/xhr_proxy.js
diff --git a/remoting/webapp/xmpp_connection.js b/remoting/webapp/crd/js/xmpp_connection.js
similarity index 100%
rename from remoting/webapp/xmpp_connection.js
rename to remoting/webapp/crd/js/xmpp_connection.js
diff --git a/remoting/webapp/xmpp_login_handler.js b/remoting/webapp/crd/js/xmpp_login_handler.js
similarity index 100%
rename from remoting/webapp/xmpp_login_handler.js
rename to remoting/webapp/crd/js/xmpp_login_handler.js
diff --git a/remoting/webapp/xmpp_stream_parser.js b/remoting/webapp/crd/js/xmpp_stream_parser.js
similarity index 100%
rename from remoting/webapp/xmpp_stream_parser.js
rename to remoting/webapp/crd/js/xmpp_stream_parser.js
diff --git a/remoting/webapp/manifest.json.jinja2 b/remoting/webapp/crd/manifest.json.jinja2
similarity index 100%
rename from remoting/webapp/manifest.json.jinja2
rename to remoting/webapp/crd/manifest.json.jinja2
diff --git a/remoting/webapp/remoting_client_pnacl.nmf b/remoting/webapp/crd/remoting_client_pnacl.nmf
similarity index 100%
rename from remoting/webapp/remoting_client_pnacl.nmf
rename to remoting/webapp/crd/remoting_client_pnacl.nmf
diff --git a/remoting/webapp/dividerbottom.webp b/remoting/webapp/crd/resources/dividerbottom.webp
similarity index 100%
rename from remoting/webapp/dividerbottom.webp
rename to remoting/webapp/crd/resources/dividerbottom.webp
Binary files differ
diff --git a/remoting/webapp/dividertop.webp b/remoting/webapp/crd/resources/dividertop.webp
similarity index 100%
rename from remoting/webapp/dividertop.webp
rename to remoting/webapp/crd/resources/dividertop.webp
Binary files differ
diff --git a/remoting/webapp/scale-to-fit.webp b/remoting/webapp/crd/resources/scale-to-fit.webp
similarity index 100%
rename from remoting/webapp/scale-to-fit.webp
rename to remoting/webapp/crd/resources/scale-to-fit.webp
Binary files differ
diff --git a/sandbox/linux/bpf_dsl/policy_compiler.cc b/sandbox/linux/bpf_dsl/policy_compiler.cc
index ad100f9..0eb85ca6 100644
--- a/sandbox/linux/bpf_dsl/policy_compiler.cc
+++ b/sandbox/linux/bpf_dsl/policy_compiler.cc
@@ -76,9 +76,8 @@
 }
 
 bool HasUnsafeTraps(const SandboxBPFDSLPolicy* policy) {
-  for (SyscallIterator iter(false); !iter.Done();) {
-    uint32_t sysnum = iter.Next();
-    if (SyscallIterator::IsValid(sysnum) &&
+  for (uint32_t sysnum : SyscallSet::All()) {
+    if (SyscallSet::IsValid(sysnum) &&
         policy->EvaluateSyscall(sysnum)->HasUnsafeTraps()) {
       return true;
     }
@@ -89,8 +88,8 @@
 }  // namespace
 
 struct PolicyCompiler::Range {
-  Range(uint32_t f, uint32_t t, const ErrorCode& e) : from(f), to(t), err(e) {}
-  uint32_t from, to;
+  Range(uint32_t f, const ErrorCode& e) : from(f), err(e) {}
+  uint32_t from;
   ErrorCode err;
 };
 
@@ -252,22 +251,22 @@
   // negative) all return the same ErrorCode.
   const ErrorCode invalid_err = policy_->InvalidSyscall()->Compile(this);
   uint32_t old_sysnum = 0;
-  ErrorCode old_err = SyscallIterator::IsValid(old_sysnum)
+  ErrorCode old_err = SyscallSet::IsValid(old_sysnum)
                           ? policy_->EvaluateSyscall(old_sysnum)->Compile(this)
                           : invalid_err;
 
-  for (SyscallIterator iter(false); !iter.Done();) {
-    uint32_t sysnum = iter.Next();
+  for (uint32_t sysnum : SyscallSet::All()) {
     ErrorCode err =
-        SyscallIterator::IsValid(sysnum)
+        SyscallSet::IsValid(sysnum)
             ? policy_->EvaluateSyscall(static_cast<int>(sysnum))->Compile(this)
             : invalid_err;
-    if (!err.Equals(old_err) || iter.Done()) {
-      ranges->push_back(Range(old_sysnum, sysnum - 1, old_err));
+    if (!err.Equals(old_err)) {
+      ranges->push_back(Range(old_sysnum, old_err));
       old_sysnum = sysnum;
       old_err = err;
     }
   }
+  ranges->push_back(Range(old_sysnum, old_err));
 }
 
 Instruction* PolicyCompiler::AssembleJumpTable(Ranges::const_iterator start,
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 72efda7..20dac8f1f 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -153,6 +153,11 @@
       'defines': [
         'SANDBOX_IMPLEMENTATION',
       ],
+      'includes': [
+        # Disable LTO due to compiler bug
+        # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57703
+        '../../build/android/disable_lto.gypi',
+      ],
       'include_dirs': [
         '../..',
       ],
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index f1073c1..8a9b3f7 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -150,7 +150,7 @@
 }
 
 bool SandboxBPF::IsValidSyscallNumber(int sysnum) {
-  return SyscallIterator::IsValid(sysnum);
+  return SyscallSet::IsValid(sysnum);
 }
 
 bool SandboxBPF::RunFunctionInPolicy(
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator.cc b/sandbox/linux/seccomp-bpf/syscall_iterator.cc
index 6701d50d7..1b4e0678 100644
--- a/sandbox/linux/seccomp-bpf/syscall_iterator.cc
+++ b/sandbox/linux/seccomp-bpf/syscall_iterator.cc
@@ -4,6 +4,7 @@
 
 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
 
+#include "base/logging.h"
 #include "base/macros.h"
 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
 
@@ -38,14 +39,16 @@
 #endif
 };
 
+// NextSyscall returns the next system call in the specified system
+// call set after |cur|, or 0 if no such system call exists.
 uint32_t NextSyscall(uint32_t cur, bool invalid_only) {
   for (const SyscallRange& range : kValidSyscallRanges) {
     if (range.first > 0 && cur < range.first - 1) {
       return range.first - 1;
     }
     if (cur <= range.last) {
-      if (invalid_only && cur < range.last) {
-        return range.last;
+      if (invalid_only) {
+        return range.last + 1;
       }
       return cur + 1;
     }
@@ -62,27 +65,22 @@
   if (cur < 0x80000000u)
     return 0x80000000u;
 
-  return 0xFFFFFFFFu;
+  if (cur < 0xFFFFFFFFu)
+    return 0xFFFFFFFFu;
+  return 0;
 }
 
 }  // namespace
 
-uint32_t SyscallIterator::Next() {
-  if (done_) {
-    return num_;
-  }
-
-  uint32_t val;
-  do {
-    val = num_;
-    num_ = NextSyscall(num_, invalid_only_);
-  } while (invalid_only_ && IsValid(val));
-
-  done_ |= val == 0xFFFFFFFFu;
-  return val;
+SyscallSet::Iterator SyscallSet::begin() const {
+  return Iterator(set_, false);
 }
 
-bool SyscallIterator::IsValid(uint32_t num) {
+SyscallSet::Iterator SyscallSet::end() const {
+  return Iterator(set_, true);
+}
+
+bool SyscallSet::IsValid(uint32_t num) {
   for (const SyscallRange& range : kValidSyscallRanges) {
     if (num >= range.first && num <= range.last) {
       return true;
@@ -91,4 +89,42 @@
   return false;
 }
 
+bool operator==(const SyscallSet& lhs, const SyscallSet& rhs) {
+  return (lhs.set_ == rhs.set_);
+}
+
+SyscallSet::Iterator::Iterator(Set set, bool done)
+    : set_(set), done_(done), num_(0) {
+  if (set_ == Set::INVALID_ONLY && !done_ && IsValid(num_)) {
+    ++*this;
+  }
+}
+
+uint32_t SyscallSet::Iterator::operator*() const {
+  DCHECK(!done_);
+  return num_;
+}
+
+SyscallSet::Iterator& SyscallSet::Iterator::operator++() {
+  DCHECK(!done_);
+
+  num_ = NextSyscall(num_, set_ == Set::INVALID_ONLY);
+  if (num_ == 0) {
+    done_ = true;
+  }
+
+  return *this;
+}
+
+bool operator==(const SyscallSet::Iterator& lhs,
+                const SyscallSet::Iterator& rhs) {
+  DCHECK(lhs.set_ == rhs.set_);
+  return (lhs.done_ == rhs.done_) && (lhs.num_ == rhs.num_);
+}
+
+bool operator!=(const SyscallSet::Iterator& lhs,
+                const SyscallSet::Iterator& rhs) {
+  return !(lhs == rhs);
+}
+
 }  // namespace sandbox
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator.h b/sandbox/linux/seccomp-bpf/syscall_iterator.h
index 3796be5..d89b981 100644
--- a/sandbox/linux/seccomp-bpf/syscall_iterator.h
+++ b/sandbox/linux/seccomp-bpf/syscall_iterator.h
@@ -12,6 +12,8 @@
 
 namespace sandbox {
 
+// TODO(mdempsky): Rename this header to syscall_set.h.
+
 // Iterates over the entire system call range from 0..0xFFFFFFFFu. This
 // iterator is aware of how system calls look like and will skip quickly
 // over ranges that can't contain system calls. It iterates more slowly
@@ -20,35 +22,75 @@
 // first invalid value after a valid range of syscalls. It iterates over
 // individual values whenever it is in the normal range for system calls
 // (typically MIN_SYSCALL..MAX_SYSCALL).
-// If |invalid_only| is true, this iterator will only return invalid
-// syscall numbers, but will still skip quickly over invalid ranges,
-// returning the first invalid value in the range and then skipping
-// to the last invalid value in the range.
 //
 // Example usage:
-//   for (SyscallIterator iter(false); !iter.Done(); ) {
-//     uint32_t sysnum = iter.Next();
+//   for (uint32_t sysnum : SyscallSet::All()) {
 //     // Do something with sysnum.
 //   }
-//
-// TODO(markus): Make this a classic C++ iterator.
-class SANDBOX_EXPORT SyscallIterator {
+class SANDBOX_EXPORT SyscallSet {
  public:
-  explicit SyscallIterator(bool invalid_only)
-      : invalid_only_(invalid_only), done_(false), num_(0) {}
+  class Iterator;
 
-  bool Done() const { return done_; }
-  uint32_t Next();
+  SyscallSet(const SyscallSet& ss) : set_(ss.set_) {}
+  ~SyscallSet() {}
+
+  Iterator begin() const;
+  Iterator end() const;
+
+  // All returns a SyscallSet that contains both valid and invalid
+  // system call numbers.
+  static SyscallSet All() { return SyscallSet(Set::ALL); }
+
+  // InvalidOnly returns a SyscallSet that contains only invalid
+  // system call numbers, but still omits numbers in the middle of a
+  // range of invalid system call numbers.
+  static SyscallSet InvalidOnly() { return SyscallSet(Set::INVALID_ONLY); }
+
+  // IsValid returns whether |num| specifies a valid system call
+  // number.
   static bool IsValid(uint32_t num);
 
  private:
-  bool invalid_only_;
+  enum class Set { ALL, INVALID_ONLY };
+
+  explicit SyscallSet(Set set) : set_(set) {}
+
+  Set set_;
+
+  friend bool operator==(const SyscallSet&, const SyscallSet&);
+  DISALLOW_ASSIGN(SyscallSet);
+};
+
+SANDBOX_EXPORT bool operator==(const SyscallSet& lhs, const SyscallSet& rhs);
+
+// Iterator provides C++ input iterator semantics for traversing a
+// SyscallSet.
+class SyscallSet::Iterator {
+ public:
+  Iterator(const Iterator& it)
+      : set_(it.set_), done_(it.done_), num_(it.num_) {}
+  ~Iterator() {}
+
+  uint32_t operator*() const;
+  Iterator& operator++();
+
+ private:
+  Iterator(Set set, bool done);
+
+  Set set_;
   bool done_;
   uint32_t num_;
 
-  DISALLOW_IMPLICIT_CONSTRUCTORS(SyscallIterator);
+  friend SyscallSet;
+  friend bool operator==(const Iterator&, const Iterator&);
+  DISALLOW_ASSIGN(Iterator);
 };
 
+SANDBOX_EXPORT bool operator==(const SyscallSet::Iterator& lhs,
+                               const SyscallSet::Iterator& rhs);
+SANDBOX_EXPORT bool operator!=(const SyscallSet::Iterator& lhs,
+                               const SyscallSet::Iterator& rhs);
+
 }  // namespace sandbox
 
 #endif  // SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_ITERATOR_H__
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc b/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc
index b01bfc6..e277f86 100644
--- a/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc
@@ -13,18 +13,19 @@
 
 namespace {
 
-const bool kFalseTrue[] = {false, true};
+const SyscallSet kSyscallSets[] = {
+    SyscallSet::All(),
+    SyscallSet::InvalidOnly(),
+};
 
 SANDBOX_TEST(SyscallIterator, Monotonous) {
-  for (bool invalid_only : kFalseTrue) {
+  for (const SyscallSet& set : kSyscallSets) {
     uint32_t prev = 0;
     bool have_prev = false;
-    for (SyscallIterator iter(invalid_only); !iter.Done();) {
-      uint32_t sysnum = iter.Next();
-
+    for (uint32_t sysnum : set) {
       if (have_prev) {
         SANDBOX_ASSERT(sysnum > prev);
-      } else if (!invalid_only) {
+      } else if (set == SyscallSet::All()) {
         // The iterator should start at 0.
         SANDBOX_ASSERT(sysnum == 0);
       }
@@ -44,8 +45,7 @@
 void AssertRange(uint32_t min, uint32_t max) {
   SANDBOX_ASSERT(min < max);
   uint32_t prev = min - 1;
-  for (SyscallIterator iter(false); !iter.Done();) {
-    uint32_t sysnum = iter.Next();
+  for (uint32_t sysnum : SyscallSet::All()) {
     if (sysnum >= min && sysnum <= max) {
       SANDBOX_ASSERT(prev == sysnum - 1);
       prev = sysnum;
@@ -80,11 +80,10 @@
     0xFFFFFFFFu,
   };
 
-  for (bool invalid_only : kFalseTrue) {
+  for (const SyscallSet& set : kSyscallSets) {
     size_t i = 0;
-    for (SyscallIterator iter(invalid_only); !iter.Done();) {
-      uint32_t sysnum = iter.Next();
-      if (!SyscallIterator::IsValid(sysnum)) {
+    for (uint32_t sysnum : set) {
+      if (!SyscallSet::IsValid(sysnum)) {
         SANDBOX_ASSERT(i < arraysize(kExpected));
         SANDBOX_ASSERT(kExpected[i] == sysnum);
         ++i;
@@ -94,6 +93,12 @@
   }
 }
 
+SANDBOX_TEST(SyscallIterator, InvalidOnlyIsOnlyInvalid) {
+  for (uint32_t sysnum : SyscallSet::InvalidOnly()) {
+    SANDBOX_ASSERT(!SyscallSet::IsValid(sysnum));
+  }
+}
+
 }  // namespace
 
 }  // namespace sandbox
diff --git a/sandbox/linux/seccomp-bpf/verifier.cc b/sandbox/linux/seccomp-bpf/verifier.cc
index 707bc45..0c344b0 100644
--- a/sandbox/linux/seccomp-bpf/verifier.cc
+++ b/sandbox/linux/seccomp-bpf/verifier.cc
@@ -318,8 +318,7 @@
                          const bpf_dsl::SandboxBPFDSLPolicy& policy,
                          const char** err) {
   *err = NULL;
-  for (SyscallIterator iter(false); !iter.Done();) {
-    uint32_t sysnum = iter.Next();
+  for (uint32_t sysnum : SyscallSet::All()) {
     // We ideally want to iterate over the full system call range and values
     // just above and just below this range. This gives us the full result set
     // of the "evaluators".
@@ -340,7 +339,7 @@
     }
 #endif
 #endif
-    ErrorCode code = iter.IsValid(sysnum)
+    ErrorCode code = SyscallSet::IsValid(sysnum)
                          ? policy.EvaluateSyscall(sysnum)->Compile(compiler)
                          : policy.InvalidSyscall()->Compile(compiler);
     if (!VerifyErrorCode(compiler, program, &data, code, code, err)) {
diff --git a/sandbox/mac/launchd_interception_server.h b/sandbox/mac/launchd_interception_server.h
index 67baae00..144d67d9 100644
--- a/sandbox/mac/launchd_interception_server.h
+++ b/sandbox/mac/launchd_interception_server.h
@@ -25,7 +25,7 @@
 class LaunchdInterceptionServer : public MessageDemuxer {
  public:
   explicit LaunchdInterceptionServer(const BootstrapSandbox* sandbox);
-  virtual ~LaunchdInterceptionServer();
+  ~LaunchdInterceptionServer() override;
 
   // Initializes the class and starts running the message server. If the
   // |server_receive_right| is non-NULL, this class will take ownership of
@@ -33,7 +33,7 @@
   bool Initialize(mach_port_t server_receive_right);
 
   // MessageDemuxer:
-  virtual void DemuxMessage(IPCMessage request) override;
+  void DemuxMessage(IPCMessage request) override;
 
   mach_port_t server_port() const { return message_server_->GetServerPort(); }
 
diff --git a/sandbox/mac/mach_message_server.h b/sandbox/mac/mach_message_server.h
index 7c344f9..645b6918 100644
--- a/sandbox/mac/mach_message_server.h
+++ b/sandbox/mac/mach_message_server.h
@@ -30,19 +30,18 @@
   MachMessageServer(MessageDemuxer* demuxer,
                     mach_port_t server_receive_right,
                     mach_msg_size_t buffer_size);
-  virtual ~MachMessageServer();
+  ~MachMessageServer() override;
 
   // MessageServer:
-  virtual bool Initialize() override;
-  virtual pid_t GetMessageSenderPID(IPCMessage request) override;
-  virtual IPCMessage CreateReply(IPCMessage request) override;
-  virtual bool SendReply(IPCMessage reply) override;
-  virtual void ForwardMessage(IPCMessage request,
-                              mach_port_t destination) override;
+  bool Initialize() override;
+  pid_t GetMessageSenderPID(IPCMessage request) override;
+  IPCMessage CreateReply(IPCMessage request) override;
+  bool SendReply(IPCMessage reply) override;
+  void ForwardMessage(IPCMessage request, mach_port_t destination) override;
   // Replies to the message with the specified |error_code| as a MIG
   // error_reply RetCode.
-  virtual void RejectMessage(IPCMessage request, int error_code) override;
-  virtual mach_port_t GetServerPort() const override;
+  void RejectMessage(IPCMessage request, int error_code) override;
+  mach_port_t GetServerPort() const override;
 
  private:
   // Event handler for the |server_source_| that reads a message from the queue
diff --git a/sandbox/mac/xpc_message_server.h b/sandbox/mac/xpc_message_server.h
index 44ba806..0c546971 100644
--- a/sandbox/mac/xpc_message_server.h
+++ b/sandbox/mac/xpc_message_server.h
@@ -25,18 +25,17 @@
   // Otherwise the server will create a new receive right on which to listen.
   XPCMessageServer(MessageDemuxer* demuxer,
                    mach_port_t server_receive_right);
-  virtual ~XPCMessageServer();
+  ~XPCMessageServer() override;
 
   // MessageServer:
-  virtual bool Initialize() override;
-  virtual pid_t GetMessageSenderPID(IPCMessage request) override;
-  virtual IPCMessage CreateReply(IPCMessage request) override;
-  virtual bool SendReply(IPCMessage reply) override;
-  virtual void ForwardMessage(IPCMessage request,
-                              mach_port_t destination) override;
+  bool Initialize() override;
+  pid_t GetMessageSenderPID(IPCMessage request) override;
+  IPCMessage CreateReply(IPCMessage request) override;
+  bool SendReply(IPCMessage reply) override;
+  void ForwardMessage(IPCMessage request, mach_port_t destination) override;
   // Creates an error reply message with a field "error" set to |error_code|.
-  virtual void RejectMessage(IPCMessage request, int error_code) override;
-  virtual mach_port_t GetServerPort() const override;
+  void RejectMessage(IPCMessage request, int error_code) override;
+  mach_port_t GetServerPort() const override;
 
  private:
   // Reads a message from the XPC pipe.
diff --git a/sandbox/mac/xpc_message_server_unittest.cc b/sandbox/mac/xpc_message_server_unittest.cc
index af8280e4..734096cd 100644
--- a/sandbox/mac/xpc_message_server_unittest.cc
+++ b/sandbox/mac/xpc_message_server_unittest.cc
@@ -43,7 +43,7 @@
         pipe_(NULL) {
   }
 
-  virtual ~BlockDemuxer() {
+  ~BlockDemuxer() override {
     if (pipe_)
       xpc_release(pipe_);
     if (demux_block_)
@@ -68,7 +68,7 @@
     return true;
   }
 
-  virtual void DemuxMessage(IPCMessage request) override {
+  void DemuxMessage(IPCMessage request) override {
     demux_block_(request);
   }
 
diff --git a/sandbox/win/src/sandbox_nt_util.cc b/sandbox/win/src/sandbox_nt_util.cc
index 28ddd47bf..12dd7d8c 100644
--- a/sandbox/win/src/sandbox_nt_util.cc
+++ b/sandbox/win/src/sandbox_nt_util.cc
@@ -361,6 +361,9 @@
 }
 
 UNICODE_STRING* GetImageInfoFromModule(HMODULE module, uint32* flags) {
+  // PEImage's dtor won't be run during SEH unwinding, but that's OK.
+#pragma warning(push)
+#pragma warning(disable: 4509)
   UNICODE_STRING* out_name = NULL;
   __try {
     do {
@@ -389,6 +392,7 @@
   }
 
   return out_name;
+#pragma warning(pop)
 }
 
 UNICODE_STRING* GetBackingFilePath(PVOID address) {
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 042d03d..356c6ae2 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -11,6 +11,15 @@
 skia_support_gpu = !is_ios
 skia_support_pdf = !is_ios && printing_mode != 0
 
+# The list of Skia defines that are to be set for blink.
+gypi_blink_skia_defines = exec_script(
+    "//build/gypi_to_gn.py",
+    [ rebase_path("//third_party/WebKit/public/blink_skia_config.gypi"),
+      "--replace=<(skia_include_path)=//third_party/skia/include",
+      "--replace=<(skia_src_path)=//third_party/skia/src" ],
+    "scope",
+    [ "//third_party/WebKit/public/blink_skia_config.gypi" ])
+
 # The list of Skia defines that are to be set for chromium.
 gypi_skia_defines = exec_script(
     "//build/gypi_to_gn.py",
@@ -98,7 +107,8 @@
     "//third_party/skia/src/lazy",
   ]
 
-  defines = gypi_skia_defines.skia_for_chromium_defines
+  defines = gypi_blink_skia_defines.blink_skia_defines
+  defines += gypi_skia_defines.skia_for_chromium_defines
 
   defines += [
     "SK_ENABLE_INST_COUNT=0",
diff --git a/skia/ext/SkDiscardableMemory_chrome.h b/skia/ext/SkDiscardableMemory_chrome.h
index 18088c5..50946e6 100644
--- a/skia/ext/SkDiscardableMemory_chrome.h
+++ b/skia/ext/SkDiscardableMemory_chrome.h
@@ -13,12 +13,12 @@
 // base::DiscardableMemory.
 class SK_API SkDiscardableMemoryChrome : public SkDiscardableMemory {
 public:
-  virtual ~SkDiscardableMemoryChrome();
+ ~SkDiscardableMemoryChrome() override;
 
   // SkDiscardableMemory:
-  virtual bool lock() override;
-  virtual void* data() override;
-  virtual void unlock() override;
+ bool lock() override;
+ void* data() override;
+ void unlock() override;
 
 private:
   friend class SkDiscardableMemory;
diff --git a/skia/ext/analysis_canvas.h b/skia/ext/analysis_canvas.h
index d3d3b80..abedcaf 100644
--- a/skia/ext/analysis_canvas.h
+++ b/skia/ext/analysis_canvas.h
@@ -18,7 +18,7 @@
 class SK_API AnalysisCanvas : public SkCanvas, public SkDrawPictureCallback {
  public:
   AnalysisCanvas(int width, int height);
-  virtual ~AnalysisCanvas();
+  ~AnalysisCanvas() override;
 
   // Returns true when a SkColor can be used to represent result.
   bool GetColorIfSolid(SkColor* color) const;
@@ -27,92 +27,93 @@
   void SetForceNotTransparent(bool flag);
 
   // SkDrawPictureCallback override.
-  virtual bool abortDrawing() override;
+  bool abortDrawing() override;
 
   // SkCanvas overrides.
-  virtual void clear(SkColor) override;
-  virtual void drawPaint(const SkPaint& paint) override;
-  virtual void drawPoints(PointMode,
-                          size_t count,
-                          const SkPoint pts[],
-                          const SkPaint&) override;
-  virtual void drawOval(const SkRect&, const SkPaint&) override;
-  virtual void drawRect(const SkRect&, const SkPaint&) override;
-  virtual void drawRRect(const SkRRect&, const SkPaint&) override;
-  virtual void drawPath(const SkPath& path, const SkPaint&) override;
-  virtual void drawBitmap(const SkBitmap&,
-                          SkScalar left,
-                          SkScalar top,
-                          const SkPaint* paint = NULL) override;
-  virtual void drawBitmapRectToRect(const SkBitmap&,
-                                    const SkRect* src,
-                                    const SkRect& dst,
-                                    const SkPaint* paint,
-                                    DrawBitmapRectFlags flags) override;
-  virtual void drawBitmapMatrix(const SkBitmap&,
-                                const SkMatrix&,
-                                const SkPaint* paint = NULL) override;
-  virtual void drawBitmapNine(const SkBitmap& bitmap,
-                              const SkIRect& center,
-                              const SkRect& dst,
-                              const SkPaint* paint = NULL) override;
-  virtual void drawSprite(const SkBitmap&, int left, int top,
-                          const SkPaint* paint = NULL) override;
-  virtual void drawVertices(VertexMode,
-                            int vertexCount,
-                            const SkPoint vertices[],
-                            const SkPoint texs[],
-                            const SkColor colors[],
-                            SkXfermode*,
-                            const uint16_t indices[],
-                            int indexCount,
-                            const SkPaint&) override;
+  void clear(SkColor) override;
+  void drawPaint(const SkPaint& paint) override;
+  void drawPoints(PointMode,
+                  size_t count,
+                  const SkPoint pts[],
+                  const SkPaint&) override;
+  void drawOval(const SkRect&, const SkPaint&) override;
+  void drawRect(const SkRect&, const SkPaint&) override;
+  void drawRRect(const SkRRect&, const SkPaint&) override;
+  void drawPath(const SkPath& path, const SkPaint&) override;
+  void drawBitmap(const SkBitmap&,
+                  SkScalar left,
+                  SkScalar top,
+                  const SkPaint* paint = NULL) override;
+  void drawBitmapRectToRect(const SkBitmap&,
+                            const SkRect* src,
+                            const SkRect& dst,
+                            const SkPaint* paint,
+                            DrawBitmapRectFlags flags) override;
+  void drawBitmapMatrix(const SkBitmap&,
+                        const SkMatrix&,
+                        const SkPaint* paint = NULL) override;
+  void drawBitmapNine(const SkBitmap& bitmap,
+                      const SkIRect& center,
+                      const SkRect& dst,
+                      const SkPaint* paint = NULL) override;
+  void drawSprite(const SkBitmap&,
+                  int left,
+                  int top,
+                  const SkPaint* paint = NULL) override;
+  void drawVertices(VertexMode,
+                    int vertexCount,
+                    const SkPoint vertices[],
+                    const SkPoint texs[],
+                    const SkColor colors[],
+                    SkXfermode*,
+                    const uint16_t indices[],
+                    int indexCount,
+                    const SkPaint&) override;
 
  protected:
-  virtual void willSave() override;
-  virtual SaveLayerStrategy willSaveLayer(const SkRect*,
-                                          const SkPaint*,
-                                          SaveFlags) override;
-  virtual void willRestore() override;
+  void willSave() override;
+  SaveLayerStrategy willSaveLayer(const SkRect*,
+                                  const SkPaint*,
+                                  SaveFlags) override;
+  void willRestore() override;
 
-  virtual void onClipRect(const SkRect& rect,
-                          SkRegion::Op op,
-                          ClipEdgeStyle edge_style) override;
-  virtual void onClipRRect(const SkRRect& rrect,
-                           SkRegion::Op op,
-                           ClipEdgeStyle edge_style) override;
-  virtual void onClipPath(const SkPath& path,
-                          SkRegion::Op op,
-                          ClipEdgeStyle edge_style) override;
-  virtual void onClipRegion(const SkRegion& deviceRgn,
-                            SkRegion::Op op) override;
+  void onClipRect(const SkRect& rect,
+                  SkRegion::Op op,
+                  ClipEdgeStyle edge_style) override;
+  void onClipRRect(const SkRRect& rrect,
+                   SkRegion::Op op,
+                   ClipEdgeStyle edge_style) override;
+  void onClipPath(const SkPath& path,
+                  SkRegion::Op op,
+                  ClipEdgeStyle edge_style) override;
+  void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) override;
 
-  virtual void onDrawText(const void* text,
-                          size_t byteLength,
-                          SkScalar x,
-                          SkScalar y,
-                          const SkPaint&) override;
-  virtual void onDrawPosText(const void* text,
-                             size_t byteLength,
-                             const SkPoint pos[],
-                             const SkPaint&) override;
-  virtual void onDrawPosTextH(const void* text,
-                              size_t byteLength,
-                              const SkScalar xpos[],
-                              SkScalar constY,
-                              const SkPaint&) override;
-  virtual void onDrawTextOnPath(const void* text,
-                                size_t byteLength,
-                                const SkPath& path,
-                                const SkMatrix* matrix,
-                                const SkPaint&) override;
-  virtual void onDrawTextBlob(const SkTextBlob* blob,
-                              SkScalar x,
-                              SkScalar y,
-                              const SkPaint& paint) override;
-  virtual void onDrawDRRect(const SkRRect& outer,
-                            const SkRRect& inner,
-                            const SkPaint&) override;
+  void onDrawText(const void* text,
+                  size_t byteLength,
+                  SkScalar x,
+                  SkScalar y,
+                  const SkPaint&) override;
+  void onDrawPosText(const void* text,
+                     size_t byteLength,
+                     const SkPoint pos[],
+                     const SkPaint&) override;
+  void onDrawPosTextH(const void* text,
+                      size_t byteLength,
+                      const SkScalar xpos[],
+                      SkScalar constY,
+                      const SkPaint&) override;
+  void onDrawTextOnPath(const void* text,
+                        size_t byteLength,
+                        const SkPath& path,
+                        const SkMatrix* matrix,
+                        const SkPaint&) override;
+  void onDrawTextBlob(const SkTextBlob* blob,
+                      SkScalar x,
+                      SkScalar y,
+                      const SkPaint& paint) override;
+  void onDrawDRRect(const SkRRect& outer,
+                    const SkRRect& inner,
+                    const SkPaint&) override;
 
   void OnComplexClip();
 
diff --git a/skia/ext/benchmarking_canvas.cc b/skia/ext/benchmarking_canvas.cc
index f3f8cc5..64d3f6c 100644
--- a/skia/ext/benchmarking_canvas.cc
+++ b/skia/ext/benchmarking_canvas.cc
@@ -29,8 +29,7 @@
     setProxy(canvas_.get());
   }
 
-  virtual ~TimingCanvas() {
-  }
+  ~TimingCanvas() override {}
 
   double GetTime(size_t index) {
     TimingsMap::const_iterator timing_info = timings_map_.find(index);
@@ -40,149 +39,172 @@
   }
 
   // SkCanvas overrides.
-  virtual void willSave() override {
+  void willSave() override {
     AutoStamper stamper(this);
     SkProxyCanvas::willSave();
   }
 
-  virtual SaveLayerStrategy willSaveLayer(const SkRect* bounds,
-                                          const SkPaint* paint,
-                                          SaveFlags flags) override {
+  SaveLayerStrategy willSaveLayer(const SkRect* bounds,
+                                  const SkPaint* paint,
+                                  SaveFlags flags) override {
     AutoStamper stamper(this);
     return SkProxyCanvas::willSaveLayer(bounds, paint, flags);
   }
 
-  virtual void willRestore() override {
+  void willRestore() override {
     AutoStamper stamper(this);
     SkProxyCanvas::willRestore();
   }
 
-  virtual void drawPaint(const SkPaint& paint) override {
+  void drawPaint(const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawPaint(paint);
   }
 
-  virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
-                          const SkPaint& paint) override {
+  void drawPoints(PointMode mode,
+                  size_t count,
+                  const SkPoint pts[],
+                  const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawPoints(mode, count, pts, paint);
   }
 
-  virtual void drawOval(const SkRect& rect, const SkPaint& paint) override {
+  void drawOval(const SkRect& rect, const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawOval(rect, paint);
   }
 
-  virtual void drawRect(const SkRect& rect, const SkPaint& paint) override {
+  void drawRect(const SkRect& rect, const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawRect(rect, paint);
   }
 
-  virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint) override {
+  void drawRRect(const SkRRect& rrect, const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawRRect(rrect, paint);
   }
 
-  virtual void drawPath(const SkPath& path, const SkPaint& paint) override {
+  void drawPath(const SkPath& path, const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawPath(path, paint);
   }
 
-  virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
-                          const SkPaint* paint = NULL) override {
+  void drawBitmap(const SkBitmap& bitmap,
+                  SkScalar left,
+                  SkScalar top,
+                  const SkPaint* paint = NULL) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawBitmap(bitmap, left, top, paint);
   }
 
-  virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
-                                    const SkRect& dst,
-                                    const SkPaint* paint,
-                                    DrawBitmapRectFlags flags) override {
+  void drawBitmapRectToRect(const SkBitmap& bitmap,
+                            const SkRect* src,
+                            const SkRect& dst,
+                            const SkPaint* paint,
+                            DrawBitmapRectFlags flags) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawBitmapRectToRect(bitmap, src, dst, paint, flags);
   }
 
-  virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
-                                const SkPaint* paint = NULL) override {
+  void drawBitmapMatrix(const SkBitmap& bitmap,
+                        const SkMatrix& m,
+                        const SkPaint* paint = NULL) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawBitmapMatrix(bitmap, m, paint);
   }
 
-  virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
-                          const SkPaint* paint = NULL) override {
+  void drawSprite(const SkBitmap& bitmap,
+                  int left,
+                  int top,
+                  const SkPaint* paint = NULL) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawSprite(bitmap, left, top, paint);
   }
 
-  virtual void drawVertices(VertexMode vmode, int vertexCount,
-                            const SkPoint vertices[], const SkPoint texs[],
-                            const SkColor colors[], SkXfermode* xmode,
-                            const uint16_t indices[], int indexCount,
-                            const SkPaint& paint) override {
+  void drawVertices(VertexMode vmode,
+                    int vertexCount,
+                    const SkPoint vertices[],
+                    const SkPoint texs[],
+                    const SkColor colors[],
+                    SkXfermode* xmode,
+                    const uint16_t indices[],
+                    int indexCount,
+                    const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawVertices(vmode, vertexCount, vertices, texs, colors,
                                 xmode, indices, indexCount, paint);
   }
 
-  virtual void drawData(const void* data, size_t length) override {
+  void drawData(const void* data, size_t length) override {
     AutoStamper stamper(this);
     SkProxyCanvas::drawData(data, length);
   }
 
 protected:
-  virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
-                          SkScalar y, const SkPaint& paint) override {
+ void onDrawText(const void* text,
+                 size_t byteLength,
+                 SkScalar x,
+                 SkScalar y,
+                 const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onDrawText(text, byteLength, x, y, paint);
   }
 
-  virtual void onDrawPosText(const void* text, size_t byteLength,
-                             const SkPoint pos[],
-                             const SkPaint& paint) override {
+  void onDrawPosText(const void* text,
+                     size_t byteLength,
+                     const SkPoint pos[],
+                     const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onDrawPosText(text, byteLength, pos, paint);
   }
 
-  virtual void onDrawPosTextH(const void* text, size_t byteLength,
-                              const SkScalar xpos[], SkScalar constY,
-                              const SkPaint& paint) override {
+  void onDrawPosTextH(const void* text,
+                      size_t byteLength,
+                      const SkScalar xpos[],
+                      SkScalar constY,
+                      const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onDrawPosTextH(text, byteLength, xpos, constY, paint);
   }
 
-  virtual void onDrawTextOnPath(const void* text, size_t byteLength,
-                                const SkPath& path, const SkMatrix* matrix,
-                                const SkPaint& paint) override {
+  void onDrawTextOnPath(const void* text,
+                        size_t byteLength,
+                        const SkPath& path,
+                        const SkMatrix* matrix,
+                        const SkPaint& paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onDrawTextOnPath(text, byteLength, path, matrix, paint);
   }
 
-  virtual void onClipRect(const SkRect& rect, SkRegion::Op op,
-                          ClipEdgeStyle edge_style) override {
+  void onClipRect(const SkRect& rect,
+                  SkRegion::Op op,
+                  ClipEdgeStyle edge_style) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onClipRect(rect, op, edge_style);
   }
 
-  virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op,
-                          ClipEdgeStyle edge_style) override {
+  void onClipRRect(const SkRRect& rrect,
+                   SkRegion::Op op,
+                   ClipEdgeStyle edge_style) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onClipRRect(rrect, op, edge_style);
   }
 
-  virtual void onClipPath(const SkPath& path, SkRegion::Op op,
-                          ClipEdgeStyle edge_style) override {
+  void onClipPath(const SkPath& path,
+                  SkRegion::Op op,
+                  ClipEdgeStyle edge_style) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onClipPath(path, op, edge_style);
   }
 
-  virtual void onClipRegion(const SkRegion& region,
-                            SkRegion::Op op) override {
+  void onClipRegion(const SkRegion& region, SkRegion::Op op) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onClipRegion(region, op);
   }
 
-  virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
-                             const SkPaint* paint) override {
+  void onDrawPicture(const SkPicture* picture,
+                     const SkMatrix* matrix,
+                     const SkPaint* paint) override {
     AutoStamper stamper(this);
     SkProxyCanvas::onDrawPicture(picture, matrix, paint);
   }
diff --git a/skia/ext/benchmarking_canvas.h b/skia/ext/benchmarking_canvas.h
index 7ef8204..50289a57 100644
--- a/skia/ext/benchmarking_canvas.h
+++ b/skia/ext/benchmarking_canvas.h
@@ -17,7 +17,7 @@
 class SK_API BenchmarkingCanvas : public SkNWayCanvas {
 public:
   BenchmarkingCanvas(int width, int height);
-  virtual ~BenchmarkingCanvas();
+  ~BenchmarkingCanvas() override;
 
   // Returns the number of draw commands executed on this canvas.
   size_t CommandCount() const;
diff --git a/skia/ext/bitmap_platform_device_mac.h b/skia/ext/bitmap_platform_device_mac.h
index eb142e2..dc78562 100644
--- a/skia/ext/bitmap_platform_device_mac.h
+++ b/skia/ext/bitmap_platform_device_mac.h
@@ -48,23 +48,25 @@
                                               int width, int height,
                                               bool is_opaque);
 
-  virtual ~BitmapPlatformDevice();
+  ~BitmapPlatformDevice() override;
 
   // PlatformDevice overrides
-  virtual CGContextRef GetBitmapContext() override;
-  virtual void DrawToNativeContext(CGContextRef context, int x, int y,
-                                   const CGRect* src_rect) override;
+  CGContextRef GetBitmapContext() override;
+  void DrawToNativeContext(CGContextRef context,
+                           int x,
+                           int y,
+                           const CGRect* src_rect) override;
 
   // SkBaseDevice overrides
-  virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region,
-                             const SkClipStack&) override;
+  void setMatrixClip(const SkMatrix& transform,
+                     const SkRegion& region,
+                     const SkClipStack&) override;
 
  protected:
   BitmapPlatformDevice(CGContextRef context,
                        const SkBitmap& bitmap);
 
-  virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info,
-                                       Usage usage) override;
+  SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) override;
 
  private:
   void ReleaseBitmapContext();
diff --git a/skia/ext/event_tracer_impl.cc b/skia/ext/event_tracer_impl.cc
index f5e081d..53ddf2b8 100644
--- a/skia/ext/event_tracer_impl.cc
+++ b/skia/ext/event_tracer_impl.cc
@@ -9,23 +9,20 @@
 namespace skia {
 
 class SkChromiumEventTracer: public SkEventTracer {
-  virtual const uint8_t* getCategoryGroupEnabled(const char* name) override;
-  virtual const char* getCategoryGroupName(
-      const uint8_t* categoryEnabledFlag) override;
-  virtual SkEventTracer::Handle
-    addTraceEvent(char phase,
-                  const uint8_t* categoryEnabledFlag,
-                  const char* name,
-                  uint64_t id,
-                  int32_t numArgs,
-                  const char** argNames,
-                  const uint8_t* argTypes,
-                  const uint64_t* argValues,
-                  uint8_t flags) override;
-  virtual void
-    updateTraceEventDuration(const uint8_t* categoryEnabledFlag,
-                             const char *name,
-                             SkEventTracer::Handle handle) override;
+  const uint8_t* getCategoryGroupEnabled(const char* name) override;
+  const char* getCategoryGroupName(const uint8_t* categoryEnabledFlag) override;
+  SkEventTracer::Handle addTraceEvent(char phase,
+                                      const uint8_t* categoryEnabledFlag,
+                                      const char* name,
+                                      uint64_t id,
+                                      int32_t numArgs,
+                                      const char** argNames,
+                                      const uint8_t* argTypes,
+                                      const uint64_t* argValues,
+                                      uint8_t flags) override;
+  void updateTraceEventDuration(const uint8_t* categoryEnabledFlag,
+                                const char* name,
+                                SkEventTracer::Handle handle) override;
 };
 
 const uint8_t*
diff --git a/skia/ext/lazy_pixel_ref.h b/skia/ext/lazy_pixel_ref.h
index b3f704d..2335fdf 100644
--- a/skia/ext/lazy_pixel_ref.h
+++ b/skia/ext/lazy_pixel_ref.h
@@ -15,7 +15,7 @@
 class SK_API LazyPixelRef : public SkPixelRef {
  public:
   explicit LazyPixelRef(const SkImageInfo& info);
-  virtual ~LazyPixelRef();
+  ~LazyPixelRef() override;
 
   struct PrepareParams {
     // Clipping rect for this pixel ref.
diff --git a/skia/ext/opacity_draw_filter.h b/skia/ext/opacity_draw_filter.h
index 9789cc2..7d11d68 100644
--- a/skia/ext/opacity_draw_filter.h
+++ b/skia/ext/opacity_draw_filter.h
@@ -19,8 +19,8 @@
 class SK_API OpacityDrawFilter : public SkDrawFilter {
  public:
   OpacityDrawFilter(float opacity, bool disable_image_filtering);
-  virtual ~OpacityDrawFilter();
-  virtual bool filter(SkPaint* paint, SkDrawFilter::Type type) override;
+  ~OpacityDrawFilter() override;
+  bool filter(SkPaint* paint, SkDrawFilter::Type type) override;
 
  private:
   int alpha_;
diff --git a/skia/ext/pixel_ref_utils.cc b/skia/ext/pixel_ref_utils.cc
index 6eb73613..4e85f7a 100644
--- a/skia/ext/pixel_ref_utils.cc
+++ b/skia/ext/pixel_ref_utils.cc
@@ -51,8 +51,8 @@
                        DiscardablePixelRefSet* pixel_ref_set)
       : SkBitmapDevice(bm), pixel_ref_set_(pixel_ref_set) {}
 
-  virtual void clear(SkColor color) override {}
-  virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) override {
+  void clear(SkColor color) override {}
+  void drawPaint(const SkDraw& draw, const SkPaint& paint) override {
     SkBitmap bitmap;
     if (GetBitmapFromPaint(paint, &bitmap)) {
       SkRect clip_rect = SkRect::Make(draw.fRC->getBounds());
@@ -60,11 +60,11 @@
     }
   }
 
-  virtual void drawPoints(const SkDraw& draw,
-                          SkCanvas::PointMode mode,
-                          size_t count,
-                          const SkPoint points[],
-                          const SkPaint& paint) override {
+  void drawPoints(const SkDraw& draw,
+                  SkCanvas::PointMode mode,
+                  size_t count,
+                  const SkPoint points[],
+                  const SkPaint& paint) override {
     SkBitmap bitmap;
     if (!GetBitmapFromPaint(paint, &bitmap))
       return;
@@ -87,9 +87,9 @@
 
     GatherPixelRefDevice::drawRect(draw, bounds, paint);
   }
-  virtual void drawRect(const SkDraw& draw,
-                        const SkRect& rect,
-                        const SkPaint& paint) override {
+  void drawRect(const SkDraw& draw,
+                const SkRect& rect,
+                const SkPaint& paint) override {
     SkBitmap bitmap;
     if (GetBitmapFromPaint(paint, &bitmap)) {
       SkRect mapped_rect;
@@ -98,21 +98,21 @@
       AddBitmap(bitmap, mapped_rect);
     }
   }
-  virtual void drawOval(const SkDraw& draw,
-                        const SkRect& rect,
-                        const SkPaint& paint) override {
+  void drawOval(const SkDraw& draw,
+                const SkRect& rect,
+                const SkPaint& paint) override {
     GatherPixelRefDevice::drawRect(draw, rect, paint);
   }
-  virtual void drawRRect(const SkDraw& draw,
-                         const SkRRect& rect,
-                         const SkPaint& paint) override {
+  void drawRRect(const SkDraw& draw,
+                 const SkRRect& rect,
+                 const SkPaint& paint) override {
     GatherPixelRefDevice::drawRect(draw, rect.rect(), paint);
   }
-  virtual void drawPath(const SkDraw& draw,
-                        const SkPath& path,
-                        const SkPaint& paint,
-                        const SkMatrix* pre_path_matrix,
-                        bool path_is_mutable) override {
+  void drawPath(const SkDraw& draw,
+                const SkPath& path,
+                const SkPaint& paint,
+                const SkMatrix* pre_path_matrix,
+                bool path_is_mutable) override {
     SkBitmap bitmap;
     if (!GetBitmapFromPaint(paint, &bitmap))
       return;
@@ -126,10 +126,10 @@
 
     GatherPixelRefDevice::drawRect(draw, final_rect, paint);
   }
-  virtual void drawBitmap(const SkDraw& draw,
-                          const SkBitmap& bitmap,
-                          const SkMatrix& matrix,
-                          const SkPaint& paint) override {
+  void drawBitmap(const SkDraw& draw,
+                  const SkBitmap& bitmap,
+                  const SkMatrix& matrix,
+                  const SkPaint& paint) override {
     SkMatrix total_matrix;
     total_matrix.setConcat(*draw.fMatrix, matrix);
 
@@ -142,22 +142,22 @@
     if (GetBitmapFromPaint(paint, &paint_bitmap))
       AddBitmap(paint_bitmap, mapped_rect);
   }
-  virtual void drawBitmapRect(const SkDraw& draw,
-                              const SkBitmap& bitmap,
-                              const SkRect* src_or_null,
-                              const SkRect& dst,
-                              const SkPaint& paint,
-                              SkCanvas::DrawBitmapRectFlags flags) override {
+  void drawBitmapRect(const SkDraw& draw,
+                      const SkBitmap& bitmap,
+                      const SkRect* src_or_null,
+                      const SkRect& dst,
+                      const SkPaint& paint,
+                      SkCanvas::DrawBitmapRectFlags flags) override {
     SkRect bitmap_rect = SkRect::MakeWH(bitmap.width(), bitmap.height());
     SkMatrix matrix;
     matrix.setRectToRect(bitmap_rect, dst, SkMatrix::kFill_ScaleToFit);
     GatherPixelRefDevice::drawBitmap(draw, bitmap, matrix, paint);
   }
-  virtual void drawSprite(const SkDraw& draw,
-                          const SkBitmap& bitmap,
-                          int x,
-                          int y,
-                          const SkPaint& paint) override {
+  void drawSprite(const SkDraw& draw,
+                  const SkBitmap& bitmap,
+                  int x,
+                  int y,
+                  const SkPaint& paint) override {
     // Sprites aren't affected by current matrix, so we can't reuse drawRect.
     SkMatrix matrix;
     matrix.setTranslate(x, y);
@@ -171,12 +171,12 @@
     if (GetBitmapFromPaint(paint, &paint_bitmap))
       AddBitmap(paint_bitmap, mapped_rect);
   }
-  virtual void drawText(const SkDraw& draw,
-                        const void* text,
-                        size_t len,
-                        SkScalar x,
-                        SkScalar y,
-                        const SkPaint& paint) override {
+  void drawText(const SkDraw& draw,
+                const void* text,
+                size_t len,
+                SkScalar x,
+                SkScalar y,
+                const SkPaint& paint) override {
     SkBitmap bitmap;
     if (!GetBitmapFromPaint(paint, &bitmap))
       return;
@@ -218,13 +218,13 @@
 
     GatherPixelRefDevice::drawRect(draw, bounds, paint);
   }
-  virtual void drawPosText(const SkDraw& draw,
-                           const void* text,
-                           size_t len,
-                           const SkScalar pos[],
-                           int scalars_per_pos,
-                           const SkPoint& offset,
-                           const SkPaint& paint) override {
+  void drawPosText(const SkDraw& draw,
+                   const void* text,
+                   size_t len,
+                   const SkScalar pos[],
+                   int scalars_per_pos,
+                   const SkPoint& offset,
+                   const SkPaint& paint) override {
     SkBitmap bitmap;
     if (!GetBitmapFromPaint(paint, &bitmap))
       return;
@@ -263,12 +263,12 @@
 
     GatherPixelRefDevice::drawRect(draw, bounds, paint);
   }
-  virtual void drawTextOnPath(const SkDraw& draw,
-                              const void* text,
-                              size_t len,
-                              const SkPath& path,
-                              const SkMatrix* matrix,
-                              const SkPaint& paint) override {
+  void drawTextOnPath(const SkDraw& draw,
+                      const void* text,
+                      size_t len,
+                      const SkPath& path,
+                      const SkMatrix* matrix,
+                      const SkPaint& paint) override {
     SkBitmap bitmap;
     if (!GetBitmapFromPaint(paint, &bitmap))
       return;
@@ -286,39 +286,39 @@
 
     GatherPixelRefDevice::drawRect(draw, bounds, paint);
   }
-  virtual void drawVertices(const SkDraw& draw,
-                            SkCanvas::VertexMode,
-                            int vertex_count,
-                            const SkPoint verts[],
-                            const SkPoint texs[],
-                            const SkColor colors[],
-                            SkXfermode* xmode,
-                            const uint16_t indices[],
-                            int index_count,
-                            const SkPaint& paint) override {
+  void drawVertices(const SkDraw& draw,
+                    SkCanvas::VertexMode,
+                    int vertex_count,
+                    const SkPoint verts[],
+                    const SkPoint texs[],
+                    const SkColor colors[],
+                    SkXfermode* xmode,
+                    const uint16_t indices[],
+                    int index_count,
+                    const SkPaint& paint) override {
     GatherPixelRefDevice::drawPoints(
         draw, SkCanvas::kPolygon_PointMode, vertex_count, verts, paint);
   }
-  virtual void drawDevice(const SkDraw&,
-                          SkBaseDevice*,
-                          int x,
-                          int y,
-                          const SkPaint&) override {}
+  void drawDevice(const SkDraw&,
+                  SkBaseDevice*,
+                  int x,
+                  int y,
+                  const SkPaint&) override {}
 
  protected:
-  virtual bool onReadPixels(const SkImageInfo& info,
-                            void* pixels,
-                            size_t rowBytes,
-                            int x,
-                            int y) override {
+  bool onReadPixels(const SkImageInfo& info,
+                    void* pixels,
+                    size_t rowBytes,
+                    int x,
+                    int y) override {
     return false;
   }
 
-  virtual bool onWritePixels(const SkImageInfo& info,
-                             const void* pixels,
-                             size_t rowBytes,
-                             int x,
-                             int y) override {
+  bool onWritePixels(const SkImageInfo& info,
+                     const void* pixels,
+                     size_t rowBytes,
+                     int x,
+                     int y) override {
     return false;
   }
 
diff --git a/skia/ext/pixel_ref_utils_unittest.cc b/skia/ext/pixel_ref_utils_unittest.cc
index aef5766..656ef5c 100644
--- a/skia/ext/pixel_ref_utils_unittest.cc
+++ b/skia/ext/pixel_ref_utils_unittest.cc
@@ -34,20 +34,18 @@
     CreateBitmap(gfx::Size(50, 50), "discardable", &bitmap_);
   }
 
-  virtual SkShader::BitmapType asABitmap(SkBitmap* bitmap,
-                                         SkMatrix* matrix,
-                                         TileMode xy[2]) const override {
+  SkShader::BitmapType asABitmap(SkBitmap* bitmap,
+                                 SkMatrix* matrix,
+                                 TileMode xy[2]) const override {
     if (bitmap)
       *bitmap = bitmap_;
     return SkShader::kDefault_BitmapType;
   }
 
   // not indended to return an actual context. Just need to supply this.
-  virtual size_t contextSize() const override {
-    return sizeof(SkShader::Context);
-  }
+  size_t contextSize() const override { return sizeof(SkShader::Context); }
 
-  virtual void flatten(SkWriteBuffer&) const override {}
+  void flatten(SkWriteBuffer&) const override {}
 
   SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(TestDiscardableShader);
 
diff --git a/skia/ext/vector_platform_device_skia.h b/skia/ext/vector_platform_device_skia.h
index fc88904..528eac9 100644
--- a/skia/ext/vector_platform_device_skia.h
+++ b/skia/ext/vector_platform_device_skia.h
@@ -23,24 +23,24 @@
   SK_API VectorPlatformDeviceSkia(const SkISize& pageSize,
                                   const SkISize& contentSize,
                                   const SkMatrix& initialTransform);
-  virtual ~VectorPlatformDeviceSkia();
+  ~VectorPlatformDeviceSkia() override;
 
   // PlatformDevice methods.
-  virtual bool SupportsPlatformPaint() override;
+  bool SupportsPlatformPaint() override;
 
-  virtual PlatformSurface BeginPlatformPaint() override;
-  virtual void EndPlatformPaint() override;
+  PlatformSurface BeginPlatformPaint() override;
+  void EndPlatformPaint() override;
 #if defined(OS_WIN)
   virtual void DrawToNativeContext(HDC dc,
                                    int x,
                                    int y,
                                    const RECT* src_rect) override;
 #elif defined(OS_MACOSX)
-  virtual void DrawToNativeContext(CGContext* context,
-                                   int x,
-                                   int y,
-                                   const CGRect* src_rect) override;
-  virtual CGContextRef GetBitmapContext() override;
+  void DrawToNativeContext(CGContext* context,
+                           int x,
+                           int y,
+                           const CGRect* src_rect) override;
+  CGContextRef GetBitmapContext() override;
 #elif defined(OS_POSIX)
   virtual void DrawToNativeContext(PlatformSurface surface,
                                    int x,
diff --git a/skia/skia.gyp b/skia/skia.gyp
index c4129db..2d2668a1 100644
--- a/skia/skia.gyp
+++ b/skia/skia.gyp
@@ -17,6 +17,10 @@
             'skia_library.gypi',
             'skia_common.gypi',
             '../build/android/increase_size_for_speed.gypi',
+            # Disable LTO due to compiler error
+            # in mems_in_disjoint_alias_sets_p, at alias.c:393
+            # crbug.com/422255
+            '../build/android/disable_lto.gypi',
           ],
         },
       ],
diff --git a/skia/skia_common.gypi b/skia/skia_common.gypi
index 6137352..ff42074 100644
--- a/skia/skia_common.gypi
+++ b/skia/skia_common.gypi
@@ -6,6 +6,9 @@
 # Skia build.
 {
   'includes': [
+    # blink_skia_config.gypi defines blink_skia_defines
+    '../third_party/WebKit/public/blink_skia_config.gypi',
+
     # skia_for_chromium_defines.gypi defines skia_for_chromium_defines
     '../third_party/skia/gyp/skia_for_chromium_defines.gypi',
   ],
@@ -156,6 +159,10 @@
       'GR_GL_IGNORE_ES3_MSAA=0',
       'SK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT',
 
+      # This variable contains additional defines, specified in blink's
+      # blink_skia_config.gypi file.
+      '<@(blink_skia_defines)',
+
       # This variable contains additional defines, specified in skia's
       # skia_for_chromium_defines.gypi file.
       '<@(skia_for_chromium_defines)',
diff --git a/skia/skia_library.gypi b/skia/skia_library.gypi
index 2df089e..e54b31f 100644
--- a/skia/skia_library.gypi
+++ b/skia/skia_library.gypi
@@ -205,14 +205,6 @@
       ],
     }],
 
-    [ 'OS != "ios"', {
-      'dependencies': [
-        '../third_party/WebKit/public/blink_skia_config.gyp:blink_skia_config',
-      ],
-      'export_dependent_settings': [
-        '../third_party/WebKit/public/blink_skia_config.gyp:blink_skia_config',
-      ],
-    }],
     [ 'OS != "mac"', {
       'sources/': [
         ['exclude', '/mac/']
diff --git a/skia/skia_library_opts.gyp b/skia/skia_library_opts.gyp
index 54137217..66731050 100644
--- a/skia/skia_library_opts.gyp
+++ b/skia/skia_library_opts.gyp
@@ -30,6 +30,10 @@
       'includes': [
         'skia_common.gypi',
         '../build/android/increase_size_for_speed.gypi',
+        # Disable LTO due to compiler error
+        # in mems_in_disjoint_alias_sets_p, at alias.c:393
+        # crbug.com/422255
+        '../build/android/disable_lto.gypi',
       ],
       'include_dirs': [
         '../third_party/skia/include/core',
@@ -298,6 +302,9 @@
           'includes': [
             'skia_common.gypi',
             '../build/android/increase_size_for_speed.gypi',
+            # Disable LTO due to Neon issues
+            # crbug.com/408997
+            '../build/android/disable_lto.gypi',
           ],
           'include_dirs': [
             '../third_party/skia/include/core',
diff --git a/sync/PRESUBMIT.py b/sync/PRESUBMIT.py
index 87d68b4c..45f461e 100644
--- a/sync/PRESUBMIT.py
+++ b/sync/PRESUBMIT.py
@@ -11,10 +11,10 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_rel_swarming': set(['defaulttests']),
+      'linux_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.mac': {
-      'mac_chromium_rel_swarming': set(['defaulttests']),
+      'mac_chromium_rel': set(['defaulttests']),
     },
     'tryserver.chromium.win': {
       'win_chromium_rel': set(['defaulttests']),
diff --git a/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java b/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java
index 5178387..a25a786 100644
--- a/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java
+++ b/sync/android/java/src/org/chromium/sync/notifier/SyncStatusHelper.java
@@ -279,8 +279,8 @@
         if (account == null) return false;
         boolean returnValue;
         synchronized (mCachedSettings) {
-            returnValue = mCachedMasterSyncAutomatically &&
-                mCachedSettings.getSyncAutomatically(account);
+            returnValue = mCachedMasterSyncAutomatically
+                    && mCachedSettings.getSyncAutomatically(account);
         }
 
         notifyObserversIfAccountSettingsChanged();
@@ -374,11 +374,11 @@
         // Disable the syncability of Chrome for all other accounts. Don't use
         // our cache as we're touching many accounts that aren't signed in, so this saves
         // extra calls to Android sync configuration.
-        Account[] googleAccounts = AccountManagerHelper.get(mApplicationContext).
-                getGoogleAccounts();
+        Account[] googleAccounts = AccountManagerHelper.get(mApplicationContext)
+                .getGoogleAccounts();
         for (Account accountToSetNotSyncable : googleAccounts) {
-            if (!accountToSetNotSyncable.equals(account) &&
-                    mSyncContentResolverDelegate.getIsSyncable(
+            if (!accountToSetNotSyncable.equals(account)
+                    && mSyncContentResolverDelegate.getIsSyncable(
                             accountToSetNotSyncable, mContractAuthority) > 0) {
                 mSyncContentResolverDelegate.setIsSyncable(accountToSetNotSyncable,
                         mContractAuthority, 0);
diff --git a/sync/android/javatests/src/org/chromium/sync/notifier/signin/SyncStatusHelperTest.java b/sync/android/javatests/src/org/chromium/sync/notifier/signin/SyncStatusHelperTest.java
index e57dc35b..c9b5d33 100644
--- a/sync/android/javatests/src/org/chromium/sync/notifier/signin/SyncStatusHelperTest.java
+++ b/sync/android/javatests/src/org/chromium/sync/notifier/signin/SyncStatusHelperTest.java
@@ -320,20 +320,20 @@
         mSyncContentResolverDelegate.disableObserverNotifications();
 
         mCachedAccountSyncSettings.updateSyncSettingsForAccount(null);
-        assertTrue("Update sync settings failed to exit early", mCachedAccountSyncSettings.
-                mUpdateSyncSettingsForAccountInternalCalls == 0);
+        assertTrue("Update sync settings failed to exit early", mCachedAccountSyncSettings
+                .mUpdateSyncSettingsForAccountInternalCalls == 0);
 
         mCachedAccountSyncSettings.updateSyncSettingsForAccount(mTestAccount);
-        assertTrue("Update sync settings should not have exited early", mCachedAccountSyncSettings.
-                mUpdateSyncSettingsForAccountInternalCalls == 1);
+        assertTrue("Update sync settings should not have exited early", mCachedAccountSyncSettings
+                .mUpdateSyncSettingsForAccountInternalCalls == 1);
 
         mCachedAccountSyncSettings.setIsSyncable(mTestAccount);
         assertTrue("setIsSyncable should not have exited early",
                 mCachedAccountSyncSettings.mSetIsSyncableInternalCalls == 1);
 
         mCachedAccountSyncSettings.setIsSyncable(mTestAccount);
-        assertTrue("setIsSyncable failed to exit early", mCachedAccountSyncSettings.
-                mSetIsSyncableInternalCalls == 1);
+        assertTrue("setIsSyncable failed to exit early", mCachedAccountSyncSettings
+                .mSetIsSyncableInternalCalls == 1);
 
         mCachedAccountSyncSettings.setSyncAutomatically(mTestAccount, true);
         assertTrue("setSyncAutomatically should not have to exited early",
diff --git a/sync/api/attachments/attachment_store.h b/sync/api/attachments/attachment_store.h
index 520c441..3c41a27 100644
--- a/sync/api/attachments/attachment_store.h
+++ b/sync/api/attachments/attachment_store.h
@@ -115,7 +115,7 @@
 
  protected:
   friend class base::RefCountedThreadSafe<AttachmentStore>;
-  virtual ~AttachmentStore();
+  ~AttachmentStore() override;
 
  private:
   static void CreateOnDiskStoreOnBackendThread(
diff --git a/sync/api/fake_sync_change_processor.h b/sync/api/fake_sync_change_processor.h
index 498aef82..d9bd5964 100644
--- a/sync/api/fake_sync_change_processor.h
+++ b/sync/api/fake_sync_change_processor.h
@@ -12,29 +12,27 @@
 class FakeSyncChangeProcessor : public SyncChangeProcessor {
  public:
   FakeSyncChangeProcessor();
-  virtual ~FakeSyncChangeProcessor();
+  ~FakeSyncChangeProcessor() override;
 
   // SyncChangeProcessor implementation.
   //
   // ProcessSyncChanges will accumulate changes in changes() until they are
   // cleared.
-  virtual syncer::SyncError ProcessSyncChanges(
+  syncer::SyncError ProcessSyncChanges(
       const tracked_objects::Location& from_here,
       const syncer::SyncChangeList& change_list) override;
 
   // SyncChangeProcessor implementation.
   //
   // Returns data().
-  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
-      const override;
+  syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override;
 
   // SyncChangeProcessor implementation.
   //
   // Updates context().
-  virtual syncer::SyncError UpdateDataTypeContext(
-      ModelType type,
-      ContextRefreshStatus refresh_status,
-      const std::string& context) override;
+  syncer::SyncError UpdateDataTypeContext(ModelType type,
+                                          ContextRefreshStatus refresh_status,
+                                          const std::string& context) override;
 
   virtual const syncer::SyncChangeList& changes() const;
   virtual syncer::SyncChangeList& changes();
diff --git a/sync/api/fake_syncable_service.h b/sync/api/fake_syncable_service.h
index 1f1ffaf..8ecf05e2 100644
--- a/sync/api/fake_syncable_service.h
+++ b/sync/api/fake_syncable_service.h
@@ -16,7 +16,7 @@
 class FakeSyncableService : public SyncableService {
  public:
   FakeSyncableService();
-  virtual ~FakeSyncableService();
+  ~FakeSyncableService() override;
 
   // Setters for SyncableService implementation results.
   void set_merge_data_and_start_syncing_error(const SyncError& error);
@@ -27,16 +27,15 @@
   bool syncing() const;
 
   // SyncableService implementation.
-  virtual SyncMergeResult MergeDataAndStartSyncing(
+  SyncMergeResult MergeDataAndStartSyncing(
       ModelType type,
       const SyncDataList& initial_sync_data,
       scoped_ptr<SyncChangeProcessor> sync_processor,
       scoped_ptr<SyncErrorFactory> sync_error_factory) override;
-  virtual void StopSyncing(ModelType type) override;
-  virtual SyncDataList GetAllSyncData(ModelType type) const override;
-  virtual SyncError ProcessSyncChanges(
-      const tracked_objects::Location& from_here,
-      const SyncChangeList& change_list) override;
+  void StopSyncing(ModelType type) override;
+  SyncDataList GetAllSyncData(ModelType type) const override;
+  SyncError ProcessSyncChanges(const tracked_objects::Location& from_here,
+                               const SyncChangeList& change_list) override;
 
  private:
   scoped_ptr<SyncChangeProcessor> sync_processor_;
diff --git a/sync/api/sync_change_processor_wrapper_for_test.h b/sync/api/sync_change_processor_wrapper_for_test.h
index 8521df9f..d7ca77a 100644
--- a/sync/api/sync_change_processor_wrapper_for_test.h
+++ b/sync/api/sync_change_processor_wrapper_for_test.h
@@ -18,14 +18,13 @@
   // of |wrapped| and is responsible for ensuring it outlives this object.
   explicit SyncChangeProcessorWrapperForTest(
       syncer::SyncChangeProcessor* wrapped);
-  virtual ~SyncChangeProcessorWrapperForTest();
+  ~SyncChangeProcessorWrapperForTest() override;
 
   // SyncChangeProcessor implementation.
-  virtual syncer::SyncError ProcessSyncChanges(
+  syncer::SyncError ProcessSyncChanges(
       const tracked_objects::Location& from_here,
       const syncer::SyncChangeList& change_list) override;
-  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
-      const override;
+  syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override;
 
  private:
   syncer::SyncChangeProcessor* const wrapped_;
diff --git a/sync/api/syncable_service.h b/sync/api/syncable_service.h
index b5861e2..17feb63b 100644
--- a/sync/api/syncable_service.h
+++ b/sync/api/syncable_service.h
@@ -77,7 +77,7 @@
   virtual scoped_refptr<AttachmentStore> GetAttachmentStore();
 
  protected:
-  virtual ~SyncableService();
+  ~SyncableService() override;
 };
 
 }  // namespace syncer
diff --git a/sync/engine/all_status.h b/sync/engine/all_status.h
index ba2dd742..6eadc6d 100644
--- a/sync/engine/all_status.h
+++ b/sync/engine/all_status.h
@@ -38,15 +38,15 @@
   friend class ScopedStatusLock;
  public:
   AllStatus();
-  virtual ~AllStatus();
+  ~AllStatus() override;
 
   // SyncEngineEventListener implementation.
-  virtual void OnSyncCycleEvent(const SyncCycleEvent& event) override;
-  virtual void OnActionableError(const SyncProtocolError& error) override;
-  virtual void OnRetryTimeChanged(base::Time retry_time) override;
-  virtual void OnThrottledTypesChanged(ModelTypeSet throttled_types) override;
-  virtual void OnMigrationRequested(ModelTypeSet types) override;
-  virtual void OnProtocolEvent(const ProtocolEvent& event) override;
+  void OnSyncCycleEvent(const SyncCycleEvent& event) override;
+  void OnActionableError(const SyncProtocolError& error) override;
+  void OnRetryTimeChanged(base::Time retry_time) override;
+  void OnThrottledTypesChanged(ModelTypeSet throttled_types) override;
+  void OnMigrationRequested(ModelTypeSet types) override;
+  void OnProtocolEvent(const ProtocolEvent& event) override;
 
   SyncStatus status() const;
 
diff --git a/sync/engine/directory_commit_contribution.h b/sync/engine/directory_commit_contribution.h
index b00b86b..d8d6aa9 100644
--- a/sync/engine/directory_commit_contribution.h
+++ b/sync/engine/directory_commit_contribution.h
@@ -37,7 +37,7 @@
     : public CommitContribution {
  public:
   // This destructor will DCHECK if UnsetSyncingBits() has not been called yet.
-  virtual ~DirectoryCommitContribution();
+  ~DirectoryCommitContribution() override;
 
   // Build a CommitContribution from the IS_UNSYNCED items in |dir| with the
   // given |type|.  The contribution will include at most |max_items| entries.
@@ -56,7 +56,7 @@
   // This function is not const.  It will update some state in this contribution
   // that will be used when processing the associated commit response.  This
   // function should not be called more than once.
-  virtual void AddToCommitMessage(sync_pb::ClientToServerMessage* msg) override;
+  void AddToCommitMessage(sync_pb::ClientToServerMessage* msg) override;
 
   // Updates this contribution's contents in accordance with the provided
   // |response|.
@@ -64,16 +64,16 @@
   // This function may make model-neutral changes to the directory.  It is not
   // valid to call this function unless AddToCommitMessage() was called earlier.
   // This function should not be called more than once.
-  virtual SyncerError ProcessCommitResponse(
+  SyncerError ProcessCommitResponse(
       const sync_pb::ClientToServerResponse& response,
       sessions::StatusController* status) override;
 
   // Cleans up any temporary state associated with the commit.  Must be called
   // before destruction.
-  virtual void CleanUp() override;
+  void CleanUp() override;
 
   // Returns the number of entries included in this contribution.
-  virtual size_t GetNumEntries() const override;
+  size_t GetNumEntries() const override;
 
  private:
   class DirectoryCommitContributionTest;
diff --git a/sync/engine/directory_commit_contributor.h b/sync/engine/directory_commit_contributor.h
index 126709a5..62251f7c 100644
--- a/sync/engine/directory_commit_contributor.h
+++ b/sync/engine/directory_commit_contributor.h
@@ -32,10 +32,9 @@
   DirectoryCommitContributor(syncable::Directory* dir,
                              ModelType type,
                              DirectoryTypeDebugInfoEmitter* debug_info_emitter);
-  virtual ~DirectoryCommitContributor();
+  ~DirectoryCommitContributor() override;
 
-  virtual scoped_ptr<CommitContribution> GetContribution(
-      size_t max_entries) override;
+  scoped_ptr<CommitContribution> GetContribution(size_t max_entries) override;
 
  private:
   syncable::Directory* dir_;
diff --git a/sync/engine/directory_update_handler.h b/sync/engine/directory_update_handler.h
index 2706774..230fbc3 100644
--- a/sync/engine/directory_update_handler.h
+++ b/sync/engine/directory_update_handler.h
@@ -47,20 +47,19 @@
                          ModelType type,
                          scoped_refptr<ModelSafeWorker> worker,
                          DirectoryTypeDebugInfoEmitter* debug_info_emitter);
-  virtual ~DirectoryUpdateHandler();
+  ~DirectoryUpdateHandler() override;
 
   // UpdateHandler implementation.
-  virtual void GetDownloadProgress(
+  void GetDownloadProgress(
       sync_pb::DataTypeProgressMarker* progress_marker) const override;
-  virtual void GetDataTypeContext(sync_pb::DataTypeContext* context) const
-      override;
-  virtual SyncerError ProcessGetUpdatesResponse(
+  void GetDataTypeContext(sync_pb::DataTypeContext* context) const override;
+  SyncerError ProcessGetUpdatesResponse(
       const sync_pb::DataTypeProgressMarker& progress_marker,
       const sync_pb::DataTypeContext& mutated_context,
       const SyncEntityList& applicable_updates,
       sessions::StatusController* status) override;
-  virtual void ApplyUpdates(sessions::StatusController* status) override;
-  virtual void PassiveApplyUpdates(sessions::StatusController* status) override;
+  void ApplyUpdates(sessions::StatusController* status) override;
+  void PassiveApplyUpdates(sessions::StatusController* status) override;
 
  private:
   friend class DirectoryUpdateHandlerApplyUpdateTest;
diff --git a/sync/engine/get_updates_delegate.h b/sync/engine/get_updates_delegate.h
index a4f999ab..32d74328a 100644
--- a/sync/engine/get_updates_delegate.h
+++ b/sync/engine/get_updates_delegate.h
@@ -43,21 +43,21 @@
 class SYNC_EXPORT_PRIVATE NormalGetUpdatesDelegate : public GetUpdatesDelegate {
  public:
   NormalGetUpdatesDelegate(const sessions::NudgeTracker& nudge_tracker);
-  virtual ~NormalGetUpdatesDelegate();
+  ~NormalGetUpdatesDelegate() override;
 
   // Uses the member NudgeTracker to populate some fields of this GU message.
-  virtual void HelpPopulateGuMessage(
+  void HelpPopulateGuMessage(
       sync_pb::GetUpdatesMessage* get_updates) const override;
 
   // Applies pending updates on the appropriate data type threads.
-  virtual void ApplyUpdates(
-      ModelTypeSet gu_types,
-      sessions::StatusController* status,
-      UpdateHandlerMap* update_handler_map) const override;
+  void ApplyUpdates(ModelTypeSet gu_types,
+                    sessions::StatusController* status,
+                    UpdateHandlerMap* update_handler_map) const override;
 
-  virtual scoped_ptr<ProtocolEvent> GetNetworkRequestEvent(
+  scoped_ptr<ProtocolEvent> GetNetworkRequestEvent(
       base::Time timestamp,
       const sync_pb::ClientToServerMessage& request) const override;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(NormalGetUpdatesDelegate);
 
@@ -70,24 +70,24 @@
  public:
   ConfigureGetUpdatesDelegate(
       sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source);
-  virtual ~ConfigureGetUpdatesDelegate();
+  ~ConfigureGetUpdatesDelegate() override;
 
   // Sets the 'source' and 'origin' fields for this request.
-  virtual void HelpPopulateGuMessage(
+  void HelpPopulateGuMessage(
       sync_pb::GetUpdatesMessage* get_updates) const override;
 
   // Applies updates passively (ie. on the sync thread).
   //
   // This is safe only if the ChangeProcessor is not listening to changes at
   // this time.
-  virtual void ApplyUpdates(
-      ModelTypeSet gu_types,
-      sessions::StatusController* status,
-      UpdateHandlerMap* update_handler_map) const override;
+  void ApplyUpdates(ModelTypeSet gu_types,
+                    sessions::StatusController* status,
+                    UpdateHandlerMap* update_handler_map) const override;
 
-  virtual scoped_ptr<ProtocolEvent> GetNetworkRequestEvent(
+  scoped_ptr<ProtocolEvent> GetNetworkRequestEvent(
       base::Time timestamp,
       const sync_pb::ClientToServerMessage& request) const override;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(ConfigureGetUpdatesDelegate);
 
@@ -101,21 +101,21 @@
 class SYNC_EXPORT_PRIVATE PollGetUpdatesDelegate : public GetUpdatesDelegate {
  public:
   PollGetUpdatesDelegate();
-  virtual ~PollGetUpdatesDelegate();
+  ~PollGetUpdatesDelegate() override;
 
   // Sets the 'source' and 'origin' to indicate this is a poll request.
-  virtual void HelpPopulateGuMessage(
+  void HelpPopulateGuMessage(
       sync_pb::GetUpdatesMessage* get_updates) const override;
 
   // Applies updates on the appropriate data type thread.
-  virtual void ApplyUpdates(
-      ModelTypeSet gu_types,
-      sessions::StatusController* status,
-      UpdateHandlerMap* update_handler_map) const override;
+  void ApplyUpdates(ModelTypeSet gu_types,
+                    sessions::StatusController* status,
+                    UpdateHandlerMap* update_handler_map) const override;
 
-  virtual scoped_ptr<ProtocolEvent> GetNetworkRequestEvent(
+  scoped_ptr<ProtocolEvent> GetNetworkRequestEvent(
       base::Time timestamp,
       const sync_pb::ClientToServerMessage& request) const override;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(PollGetUpdatesDelegate);
 };
diff --git a/sync/engine/model_type_sync_worker_impl.h b/sync/engine/model_type_sync_worker_impl.h
index 1116ade..3001569 100644
--- a/sync/engine/model_type_sync_worker_impl.h
+++ b/sync/engine/model_type_sync_worker_impl.h
@@ -59,7 +59,7 @@
                           scoped_ptr<Cryptographer> cryptographer,
                           NudgeHandler* nudge_handler,
                           scoped_ptr<ModelTypeSyncProxy> type_sync_proxy);
-  virtual ~ModelTypeSyncWorkerImpl();
+  ~ModelTypeSyncWorkerImpl() override;
 
   ModelType GetModelType() const;
 
@@ -67,25 +67,22 @@
   void UpdateCryptographer(scoped_ptr<Cryptographer> cryptographer);
 
   // UpdateHandler implementation.
-  virtual void GetDownloadProgress(
+  void GetDownloadProgress(
       sync_pb::DataTypeProgressMarker* progress_marker) const override;
-  virtual void GetDataTypeContext(
-      sync_pb::DataTypeContext* context) const override;
-  virtual SyncerError ProcessGetUpdatesResponse(
+  void GetDataTypeContext(sync_pb::DataTypeContext* context) const override;
+  SyncerError ProcessGetUpdatesResponse(
       const sync_pb::DataTypeProgressMarker& progress_marker,
       const sync_pb::DataTypeContext& mutated_context,
       const SyncEntityList& applicable_updates,
       sessions::StatusController* status) override;
-  virtual void ApplyUpdates(sessions::StatusController* status) override;
-  virtual void PassiveApplyUpdates(sessions::StatusController* status) override;
+  void ApplyUpdates(sessions::StatusController* status) override;
+  void PassiveApplyUpdates(sessions::StatusController* status) override;
 
   // ModelTypeSyncWorker implementation.
-  virtual void EnqueueForCommit(
-      const CommitRequestDataList& request_list) override;
+  void EnqueueForCommit(const CommitRequestDataList& request_list) override;
 
   // CommitContributor implementation.
-  virtual scoped_ptr<CommitContribution> GetContribution(
-      size_t max_entries) override;
+  scoped_ptr<CommitContribution> GetContribution(size_t max_entries) override;
 
   // Callback for when our contribution gets a response.
   void OnCommitResponse(const CommitResponseDataList& response_list);
diff --git a/sync/engine/net/server_connection_manager.h b/sync/engine/net/server_connection_manager.h
index f7a7575..44edc484 100644
--- a/sync/engine/net/server_connection_manager.h
+++ b/sync/engine/net/server_connection_manager.h
@@ -183,7 +183,7 @@
                           bool use_ssl,
                           CancelationSignal* cancelation_signal);
 
-  virtual ~ServerConnectionManager();
+  ~ServerConnectionManager() override;
 
   // POSTS buffer_in and reads a response into buffer_out. Uses our currently
   // set auth token in our headers.
@@ -217,7 +217,7 @@
   // We expect this to get called on a different thread than the valid
   // ThreadChecker thread, as we want to kill any pending http traffic without
   // having to wait for the request to complete.
-  virtual void OnSignalReceived() override final;
+  void OnSignalReceived() final;
 
   void set_client_id(const std::string& client_id) {
     DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/sync/engine/non_blocking_type_commit_contribution.h b/sync/engine/non_blocking_type_commit_contribution.h
index 5633277..0ee54f0 100644
--- a/sync/engine/non_blocking_type_commit_contribution.h
+++ b/sync/engine/non_blocking_type_commit_contribution.h
@@ -26,15 +26,15 @@
       const google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>& entities,
       const std::vector<int64>& sequence_numbers,
       ModelTypeSyncWorkerImpl* worker);
-  virtual ~NonBlockingTypeCommitContribution();
+  ~NonBlockingTypeCommitContribution() override;
 
   // Implementation of CommitContribution
-  virtual void AddToCommitMessage(sync_pb::ClientToServerMessage* msg) override;
-  virtual SyncerError ProcessCommitResponse(
+  void AddToCommitMessage(sync_pb::ClientToServerMessage* msg) override;
+  SyncerError ProcessCommitResponse(
       const sync_pb::ClientToServerResponse& response,
       sessions::StatusController* status) override;
-  virtual void CleanUp() override;
-  virtual size_t GetNumEntries() const override;
+  void CleanUp() override;
+  size_t GetNumEntries() const override;
 
  private:
   // A non-owned pointer back to the object that created this contribution.
diff --git a/sync/engine/sync_scheduler.h b/sync/engine/sync_scheduler.h
index e91ce61..5dd1fd0 100644
--- a/sync/engine/sync_scheduler.h
+++ b/sync/engine/sync_scheduler.h
@@ -64,7 +64,7 @@
   // (except for RequestEarlyExit()).
 
   SyncScheduler();
-  virtual ~SyncScheduler();
+  ~SyncScheduler() override;
 
   // Start the scheduler with the given mode.  If the scheduler is
   // already started, switch to the given mode, although some
diff --git a/sync/engine/sync_scheduler_impl.h b/sync/engine/sync_scheduler_impl.h
index b197e88..e3c505b 100644
--- a/sync/engine/sync_scheduler_impl.h
+++ b/sync/engine/sync_scheduler_impl.h
@@ -49,45 +49,43 @@
                     Syncer* syncer);
 
   // Calls Stop().
-  virtual ~SyncSchedulerImpl();
+  ~SyncSchedulerImpl() override;
 
-  virtual void Start(Mode mode) override;
-  virtual void ScheduleConfiguration(
-      const ConfigurationParams& params) override;
-  virtual void Stop() override;
-  virtual void ScheduleLocalNudge(
+  void Start(Mode mode) override;
+  void ScheduleConfiguration(const ConfigurationParams& params) override;
+  void Stop() override;
+  void ScheduleLocalNudge(
       ModelTypeSet types,
       const tracked_objects::Location& nudge_location) override;
-  virtual void ScheduleLocalRefreshRequest(
+  void ScheduleLocalRefreshRequest(
       ModelTypeSet types,
       const tracked_objects::Location& nudge_location) override;
-  virtual void ScheduleInvalidationNudge(
+  void ScheduleInvalidationNudge(
       syncer::ModelType type,
       scoped_ptr<InvalidationInterface> invalidation,
       const tracked_objects::Location& nudge_location) override;
-  virtual void ScheduleInitialSyncNudge(syncer::ModelType model_type) override;
-  virtual void SetNotificationsEnabled(bool notifications_enabled) override;
+  void ScheduleInitialSyncNudge(syncer::ModelType model_type) override;
+  void SetNotificationsEnabled(bool notifications_enabled) override;
 
-  virtual void OnCredentialsUpdated() override;
-  virtual void OnConnectionStatusChange() override;
+  void OnCredentialsUpdated() override;
+  void OnConnectionStatusChange() override;
 
   // SyncSession::Delegate implementation.
-  virtual void OnThrottled(const base::TimeDelta& throttle_duration) override;
-  virtual void OnTypesThrottled(
-      ModelTypeSet types,
-      const base::TimeDelta& throttle_duration) override;
-  virtual bool IsCurrentlyThrottled() override;
-  virtual void OnReceivedShortPollIntervalUpdate(
+  void OnThrottled(const base::TimeDelta& throttle_duration) override;
+  void OnTypesThrottled(ModelTypeSet types,
+                        const base::TimeDelta& throttle_duration) override;
+  bool IsCurrentlyThrottled() override;
+  void OnReceivedShortPollIntervalUpdate(
       const base::TimeDelta& new_interval) override;
-  virtual void OnReceivedLongPollIntervalUpdate(
+  void OnReceivedLongPollIntervalUpdate(
       const base::TimeDelta& new_interval) override;
-  virtual void OnReceivedCustomNudgeDelays(
+  void OnReceivedCustomNudgeDelays(
       const std::map<ModelType, base::TimeDelta>& nudge_delays) override;
-  virtual void OnReceivedClientInvalidationHintBufferSize(int size) override;
-  virtual void OnSyncProtocolError(
+  void OnReceivedClientInvalidationHintBufferSize(int size) override;
+  void OnSyncProtocolError(
       const SyncProtocolError& sync_protocol_error) override;
-  virtual void OnReceivedGuRetryDelay(const base::TimeDelta& delay) override;
-  virtual void OnReceivedMigrationRequest(syncer::ModelTypeSet types) override;
+  void OnReceivedGuRetryDelay(const base::TimeDelta& delay) override;
+  void OnReceivedMigrationRequest(syncer::ModelTypeSet types) override;
 
   // Returns true if the client is currently in exponential backoff.
   bool IsBackingOff() const;
diff --git a/sync/engine/syncer_proto_util_unittest.cc b/sync/engine/syncer_proto_util_unittest.cc
index 8e731937..81b2566 100644
--- a/sync/engine/syncer_proto_util_unittest.cc
+++ b/sync/engine/syncer_proto_util_unittest.cc
@@ -257,10 +257,9 @@
         send_error_(false),
         access_denied_(false) {}
 
-  virtual ~DummyConnectionManager() {}
-  virtual bool PostBufferWithCachedAuth(
-      PostBufferParams* params,
-      ScopedServerStatusWatcher* watcher) override {
+  ~DummyConnectionManager() override {}
+  bool PostBufferWithCachedAuth(PostBufferParams* params,
+                                ScopedServerStatusWatcher* watcher) override {
     if (send_error_) {
       return false;
     }
diff --git a/sync/engine/syncer_unittest.cc b/sync/engine/syncer_unittest.cc
index 9d3334f..46fa871 100644
--- a/sync/engine/syncer_unittest.cc
+++ b/sync/engine/syncer_unittest.cc
@@ -101,22 +101,19 @@
 class TypeDebugInfoCache : public TypeDebugInfoObserver {
  public:
   TypeDebugInfoCache();
-  virtual ~TypeDebugInfoCache();
+  ~TypeDebugInfoCache() override;
 
   CommitCounters GetLatestCommitCounters(ModelType type) const;
   UpdateCounters GetLatestUpdateCounters(ModelType type) const;
   StatusCounters GetLatestStatusCounters(ModelType type) const;
 
   // TypeDebugInfoObserver implementation.
-  virtual void OnCommitCountersUpdated(
-      syncer::ModelType type,
-      const CommitCounters& counters) override;
-  virtual void OnUpdateCountersUpdated(
-      syncer::ModelType type,
-      const UpdateCounters& counters) override;
-  virtual void OnStatusCountersUpdated(
-      syncer::ModelType type,
-      const StatusCounters& counters) override;
+  void OnCommitCountersUpdated(syncer::ModelType type,
+                               const CommitCounters& counters) override;
+  void OnUpdateCountersUpdated(syncer::ModelType type,
+                               const UpdateCounters& counters) override;
+  void OnStatusCountersUpdated(syncer::ModelType type,
+                               const StatusCounters& counters) override;
 
  private:
   std::map<ModelType, CommitCounters> commit_counters_map_;
@@ -193,26 +190,23 @@
 }
 
   // SyncSession::Delegate implementation.
-  virtual void OnThrottled(const base::TimeDelta& throttle_duration) override {
+  void OnThrottled(const base::TimeDelta& throttle_duration) override {
     FAIL() << "Should not get silenced.";
   }
-  virtual void OnTypesThrottled(
-      ModelTypeSet types,
-      const base::TimeDelta& throttle_duration) override {
+  void OnTypesThrottled(ModelTypeSet types,
+                        const base::TimeDelta& throttle_duration) override {
     FAIL() << "Should not get silenced.";
   }
-  virtual bool IsCurrentlyThrottled() override {
-    return false;
-  }
-  virtual void OnReceivedLongPollIntervalUpdate(
+  bool IsCurrentlyThrottled() override { return false; }
+  void OnReceivedLongPollIntervalUpdate(
       const base::TimeDelta& new_interval) override {
     last_long_poll_interval_received_ = new_interval;
   }
-  virtual void OnReceivedShortPollIntervalUpdate(
+  void OnReceivedShortPollIntervalUpdate(
       const base::TimeDelta& new_interval) override {
     last_short_poll_interval_received_ = new_interval;
   }
-  virtual void OnReceivedCustomNudgeDelays(
+  void OnReceivedCustomNudgeDelays(
       const std::map<ModelType, base::TimeDelta>& delay_map) override {
     std::map<ModelType, base::TimeDelta>::const_iterator iter =
         delay_map.find(SESSIONS);
@@ -222,14 +216,13 @@
     if (iter != delay_map.end() && iter->second > base::TimeDelta())
       last_bookmarks_commit_delay_ = iter->second;
   }
-  virtual void OnReceivedClientInvalidationHintBufferSize(
-      int size) override {
+  void OnReceivedClientInvalidationHintBufferSize(int size) override {
     last_client_invalidation_hint_buffer_size_ = size;
   }
-  virtual void OnReceivedGuRetryDelay(const base::TimeDelta& delay) override {}
-  virtual void OnReceivedMigrationRequest(ModelTypeSet types) override {}
-  virtual void OnProtocolEvent(const ProtocolEvent& event) override {}
-  virtual void OnSyncProtocolError(const SyncProtocolError& error) override {}
+  void OnReceivedGuRetryDelay(const base::TimeDelta& delay) override {}
+  void OnReceivedMigrationRequest(ModelTypeSet types) override {}
+  void OnProtocolEvent(const ProtocolEvent& event) override {}
+  void OnSyncProtocolError(const SyncProtocolError& error) override {}
 
   void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) {
     // We're just testing the sync engine here, so we shunt everything to
@@ -240,7 +233,7 @@
     }
   }
 
-  virtual void OnSyncCycleEvent(const SyncCycleEvent& event) override {
+  void OnSyncCycleEvent(const SyncCycleEvent& event) override {
     DVLOG(1) << "HandleSyncEngineEvent in unittest " << event.what_happened;
     // we only test for entry-specific events, not status changed ones.
     switch (event.what_happened) {
@@ -254,10 +247,10 @@
     saw_syncer_event_ = true;
   }
 
-  virtual void OnActionableError(const SyncProtocolError& error) override {}
-  virtual void OnRetryTimeChanged(base::Time retry_time) override {}
-  virtual void OnThrottledTypesChanged(ModelTypeSet throttled_types) override {}
-  virtual void OnMigrationRequested(ModelTypeSet types) override {}
+  void OnActionableError(const SyncProtocolError& error) override {}
+  void OnRetryTimeChanged(base::Time retry_time) override {}
+  void OnThrottledTypesChanged(ModelTypeSet throttled_types) override {}
+  void OnMigrationRequested(ModelTypeSet types) override {}
 
   void ResetSession() {
     session_.reset(SyncSession::Build(context_.get(), this));
diff --git a/sync/internal_api/attachments/attachment_downloader_impl_unittest.cc b/sync/internal_api/attachments/attachment_downloader_impl_unittest.cc
index 64e6779..0f8aa8ff 100644
--- a/sync/internal_api/attachments/attachment_downloader_impl_unittest.cc
+++ b/sync/internal_api/attachments/attachment_downloader_impl_unittest.cc
@@ -34,24 +34,24 @@
  public:
   MockOAuth2TokenService() : num_invalidate_token_(0) {}
 
-  virtual ~MockOAuth2TokenService() {}
+  ~MockOAuth2TokenService() override {}
 
   void RespondToAccessTokenRequest(GoogleServiceAuthError error);
 
   int num_invalidate_token() const { return num_invalidate_token_; }
 
  protected:
-  virtual void FetchOAuth2Token(RequestImpl* request,
-                                const std::string& account_id,
-                                net::URLRequestContextGetter* getter,
-                                const std::string& client_id,
-                                const std::string& client_secret,
-                                const ScopeSet& scopes) override;
+  void FetchOAuth2Token(RequestImpl* request,
+                        const std::string& account_id,
+                        net::URLRequestContextGetter* getter,
+                        const std::string& client_id,
+                        const std::string& client_secret,
+                        const ScopeSet& scopes) override;
 
-  virtual void InvalidateOAuth2Token(const std::string& account_id,
-                                     const std::string& client_id,
-                                     const ScopeSet& scopes,
-                                     const std::string& access_token) override;
+  void InvalidateOAuth2Token(const std::string& account_id,
+                             const std::string& client_id,
+                             const ScopeSet& scopes,
+                             const std::string& access_token) override;
 
  private:
   base::WeakPtr<RequestImpl> last_request_;
@@ -103,12 +103,12 @@
   TokenServiceProvider(OAuth2TokenService* token_service);
 
   // OAuth2TokenService::TokenServiceProvider implementation.
-  virtual scoped_refptr<base::SingleThreadTaskRunner>
-      GetTokenServiceTaskRunner() override;
-  virtual OAuth2TokenService* GetTokenService() override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner()
+      override;
+  OAuth2TokenService* GetTokenService() override;
 
  private:
-  virtual ~TokenServiceProvider();
+  ~TokenServiceProvider() override;
 
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   OAuth2TokenService* token_service_;
diff --git a/sync/internal_api/attachments/attachment_service_impl_unittest.cc b/sync/internal_api/attachments/attachment_service_impl_unittest.cc
index eaa02f7..857514a 100644
--- a/sync/internal_api/attachments/attachment_service_impl_unittest.cc
+++ b/sync/internal_api/attachments/attachment_service_impl_unittest.cc
@@ -23,20 +23,20 @@
  public:
   MockAttachmentStore() {}
 
-  virtual void Read(const AttachmentIdList& ids,
-                    const ReadCallback& callback) override {
+  void Read(const AttachmentIdList& ids,
+            const ReadCallback& callback) override {
     read_ids.push_back(ids);
     read_callbacks.push_back(callback);
   }
 
-  virtual void Write(const AttachmentList& attachments,
-                     const WriteCallback& callback) override {
+  void Write(const AttachmentList& attachments,
+             const WriteCallback& callback) override {
     write_attachments.push_back(attachments);
     write_callbacks.push_back(callback);
   }
 
-  virtual void Drop(const AttachmentIdList& ids,
-                    const DropCallback& callback) override {
+  void Drop(const AttachmentIdList& ids,
+            const DropCallback& callback) override {
     NOTREACHED();
   }
 
@@ -88,7 +88,7 @@
   std::vector<WriteCallback> write_callbacks;
 
  private:
-  virtual ~MockAttachmentStore() {}
+  ~MockAttachmentStore() override {}
 
   DISALLOW_COPY_AND_ASSIGN(MockAttachmentStore);
 };
@@ -99,8 +99,8 @@
  public:
   MockAttachmentDownloader() {}
 
-  virtual void DownloadAttachment(const AttachmentId& id,
-                                  const DownloadCallback& callback) override {
+  void DownloadAttachment(const AttachmentId& id,
+                          const DownloadCallback& callback) override {
     ASSERT_TRUE(download_requests.find(id) == download_requests.end());
     download_requests.insert(std::make_pair(id, callback));
   }
@@ -133,8 +133,8 @@
   MockAttachmentUploader() {}
 
   // AttachmentUploader implementation.
-  virtual void UploadAttachment(const Attachment& attachment,
-                                const UploadCallback& callback) override {
+  void UploadAttachment(const Attachment& attachment,
+                        const UploadCallback& callback) override {
     const AttachmentId id = attachment.GetId();
     ASSERT_TRUE(upload_requests.find(id) == upload_requests.end());
     upload_requests.insert(std::make_pair(id, callback));
@@ -174,8 +174,7 @@
   }
 
   // AttachmentService::Delegate implementation.
-  virtual void OnAttachmentUploaded(
-      const AttachmentId& attachment_id) override {
+  void OnAttachmentUploaded(const AttachmentId& attachment_id) override {
     on_attachment_uploaded_list_.push_back(attachment_id);
   }
 
diff --git a/sync/internal_api/attachments/attachment_service_proxy_unittest.cc b/sync/internal_api/attachments/attachment_service_proxy_unittest.cc
index 68bd021..3d5cd552 100644
--- a/sync/internal_api/attachments/attachment_service_proxy_unittest.cc
+++ b/sync/internal_api/attachments/attachment_service_proxy_unittest.cc
@@ -32,13 +32,13 @@
     DetachFromThread();
   }
 
-  virtual ~StubAttachmentService() {}
+  ~StubAttachmentService() override {}
 
-  virtual AttachmentStore* GetStore() override { return NULL; }
+  AttachmentStore* GetStore() override { return NULL; }
 
-  virtual void GetOrDownloadAttachments(const AttachmentIdList& attachment_ids,
-                                        const GetOrDownloadCallback& callback)
-      override {
+  void GetOrDownloadAttachments(
+      const AttachmentIdList& attachment_ids,
+      const GetOrDownloadCallback& callback) override {
     CalledOnValidThread();
     Increment();
     scoped_ptr<AttachmentMap> attachments(new AttachmentMap());
@@ -49,16 +49,15 @@
                    base::Passed(&attachments)));
   }
 
-  virtual void DropAttachments(const AttachmentIdList& attachment_ids,
-                               const DropCallback& callback) override {
+  void DropAttachments(const AttachmentIdList& attachment_ids,
+                       const DropCallback& callback) override {
     CalledOnValidThread();
     Increment();
     base::MessageLoop::current()->PostTask(
         FROM_HERE, base::Bind(callback, AttachmentService::DROP_SUCCESS));
   }
 
-  virtual void UploadAttachments(
-      const AttachmentIdSet& attachments_ids) override {
+  void UploadAttachments(const AttachmentIdSet& attachments_ids) override {
     CalledOnValidThread();
     Increment();
   }
diff --git a/sync/internal_api/attachments/attachment_store_handle_unittest.cc b/sync/internal_api/attachments/attachment_store_handle_unittest.cc
index 0ce411f..637e374 100644
--- a/sync/internal_api/attachments/attachment_store_handle_unittest.cc
+++ b/sync/internal_api/attachments/attachment_store_handle_unittest.cc
@@ -30,22 +30,20 @@
         drop_called_(drop_called),
         dtor_called_(dtor_called) {}
 
-  virtual ~MockAttachmentStore() {
-    dtor_called_.Run();
-  }
+  ~MockAttachmentStore() override { dtor_called_.Run(); }
 
-  virtual void Read(const AttachmentIdList& ids,
-                    const ReadCallback& callback) override {
+  void Read(const AttachmentIdList& ids,
+            const ReadCallback& callback) override {
     read_called_.Run();
   }
 
-  virtual void Write(const AttachmentList& attachments,
-                     const WriteCallback& callback) override {
+  void Write(const AttachmentList& attachments,
+             const WriteCallback& callback) override {
     write_called_.Run();
   }
 
-  virtual void Drop(const AttachmentIdList& ids,
-                    const DropCallback& callback) override {
+  void Drop(const AttachmentIdList& ids,
+            const DropCallback& callback) override {
     drop_called_.Run();
   }
 
diff --git a/sync/internal_api/attachments/attachment_uploader_impl.cc b/sync/internal_api/attachments/attachment_uploader_impl.cc
index 72b9c013..73335965 100644
--- a/sync/internal_api/attachments/attachment_uploader_impl.cc
+++ b/sync/internal_api/attachments/attachment_uploader_impl.cc
@@ -55,7 +55,7 @@
       OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider,
       const base::WeakPtr<AttachmentUploaderImpl>& owner);
 
-  virtual ~UploadState();
+  ~UploadState() override;
 
   // Returns true if this object is stopped.  Once stopped, this object is
   // effectively dead and can be destroyed.
@@ -72,14 +72,14 @@
   const Attachment& GetAttachment();
 
   // URLFetcher implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   // OAuth2TokenService::Consumer.
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
  private:
   typedef std::vector<UploadCallback> UploadCallbackList;
diff --git a/sync/internal_api/attachments/attachment_uploader_impl_unittest.cc b/sync/internal_api/attachments/attachment_uploader_impl_unittest.cc
index b6aa9e0..1213b9f 100644
--- a/sync/internal_api/attachments/attachment_uploader_impl_unittest.cc
+++ b/sync/internal_api/attachments/attachment_uploader_impl_unittest.cc
@@ -58,7 +58,7 @@
 class MockOAuth2TokenService : public FakeOAuth2TokenService {
  public:
   MockOAuth2TokenService();
-  virtual ~MockOAuth2TokenService();
+  ~MockOAuth2TokenService() override;
 
   void SetResponse(const GoogleServiceAuthError& error,
                    const std::string& access_token,
@@ -71,17 +71,17 @@
   }
 
  protected:
-  virtual void FetchOAuth2Token(RequestImpl* request,
-                                const std::string& account_id,
-                                net::URLRequestContextGetter* getter,
-                                const std::string& client_id,
-                                const std::string& client_secret,
-                                const ScopeSet& scopes) override;
+  void FetchOAuth2Token(RequestImpl* request,
+                        const std::string& account_id,
+                        net::URLRequestContextGetter* getter,
+                        const std::string& client_id,
+                        const std::string& client_secret,
+                        const ScopeSet& scopes) override;
 
-  virtual void InvalidateOAuth2Token(const std::string& account_id,
-                                     const std::string& client_id,
-                                     const ScopeSet& scopes,
-                                     const std::string& access_token) override;
+  void InvalidateOAuth2Token(const std::string& account_id,
+                             const std::string& client_id,
+                             const ScopeSet& scopes,
+                             const std::string& access_token) override;
 
  private:
   GoogleServiceAuthError response_error_;
@@ -141,12 +141,12 @@
   TokenServiceProvider(OAuth2TokenService* token_service);
 
   // OAuth2TokenService::TokenServiceProvider implementation.
-  virtual scoped_refptr<base::SingleThreadTaskRunner>
-      GetTokenServiceTaskRunner() override;
-  virtual OAuth2TokenService* GetTokenService() override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner()
+      override;
+  OAuth2TokenService* GetTokenService() override;
 
  private:
-  virtual ~TokenServiceProvider();
+  ~TokenServiceProvider() override;
 
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   OAuth2TokenService* token_service_;
diff --git a/sync/internal_api/debug_info_event_listener.h b/sync/internal_api/debug_info_event_listener.h
index 762d570..ba55650 100644
--- a/sync/internal_api/debug_info_event_listener.h
+++ b/sync/internal_api/debug_info_event_listener.h
@@ -37,51 +37,46 @@
       public DataTypeDebugInfoListener {
  public:
   DebugInfoEventListener();
-  virtual ~DebugInfoEventListener();
+  ~DebugInfoEventListener() override;
 
   // SyncManager::Observer implementation.
-  virtual void OnSyncCycleCompleted(
-    const sessions::SyncSessionSnapshot& snapshot) override;
-  virtual void OnInitializationComplete(
+  void OnSyncCycleCompleted(
+      const sessions::SyncSessionSnapshot& snapshot) override;
+  void OnInitializationComplete(
       const WeakHandle<JsBackend>& js_backend,
       const WeakHandle<DataTypeDebugInfoListener>& debug_listener,
-      bool success, ModelTypeSet restored_types) override;
-  virtual void OnConnectionStatusChange(
-      ConnectionStatus connection_status) override;
-  virtual void OnActionableError(
-      const SyncProtocolError& sync_error) override;
-  virtual void OnMigrationRequested(ModelTypeSet types) override;
-  virtual void OnProtocolEvent(const ProtocolEvent& event) override;
+      bool success,
+      ModelTypeSet restored_types) override;
+  void OnConnectionStatusChange(ConnectionStatus connection_status) override;
+  void OnActionableError(const SyncProtocolError& sync_error) override;
+  void OnMigrationRequested(ModelTypeSet types) override;
+  void OnProtocolEvent(const ProtocolEvent& event) override;
 
   // SyncEncryptionHandler::Observer implementation.
-  virtual void OnPassphraseRequired(
+  void OnPassphraseRequired(
       PassphraseRequiredReason reason,
       const sync_pb::EncryptedData& pending_keys) override;
-  virtual void OnPassphraseAccepted() override;
-  virtual void OnBootstrapTokenUpdated(
-      const std::string& bootstrap_token,
-      BootstrapTokenType type) override;
-  virtual void OnEncryptedTypesChanged(
-      ModelTypeSet encrypted_types,
-      bool encrypt_everything) override;
-  virtual void OnEncryptionComplete() override;
-  virtual void OnCryptographerStateChanged(
-      Cryptographer* cryptographer) override;
-  virtual void OnPassphraseTypeChanged(
-      PassphraseType type,
-      base::Time explicit_passphrase_time) override;
+  void OnPassphraseAccepted() override;
+  void OnBootstrapTokenUpdated(const std::string& bootstrap_token,
+                               BootstrapTokenType type) override;
+  void OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
+                               bool encrypt_everything) override;
+  void OnEncryptionComplete() override;
+  void OnCryptographerStateChanged(Cryptographer* cryptographer) override;
+  void OnPassphraseTypeChanged(PassphraseType type,
+                               base::Time explicit_passphrase_time) override;
 
   // Sync manager events.
   void OnNudgeFromDatatype(ModelType datatype);
 
   // DebugInfoGetter implementation.
-  virtual void GetDebugInfo(sync_pb::DebugInfo* debug_info) override;
+  void GetDebugInfo(sync_pb::DebugInfo* debug_info) override;
 
   // DebugInfoGetter implementation.
-  virtual void ClearDebugInfo() override;
+  void ClearDebugInfo() override;
 
   // DataTypeDebugInfoListener implementation.
-  virtual void OnDataTypeConfigureComplete(
+  void OnDataTypeConfigureComplete(
       const std::vector<DataTypeConfigurationStats>& configuration_stats)
       override;
 
diff --git a/sync/internal_api/http_bridge_unittest.cc b/sync/internal_api/http_bridge_unittest.cc
index 7a2ec92..b03ddcd6 100644
--- a/sync/internal_api/http_bridge_unittest.cc
+++ b/sync/internal_api/http_bridge_unittest.cc
@@ -124,7 +124,7 @@
           NetworkTimeUpdateCallback()),
         test_(test), never_finishes_(never_finishes) { }
  protected:
-  virtual void MakeAsynchronousPost() override {
+  void MakeAsynchronousPost() override {
     ASSERT_TRUE(base::MessageLoop::current() == test_->GetIOThreadLoop());
     if (never_finishes_)
       return;
@@ -135,7 +135,7 @@
         base::Bind(&ShuntedHttpBridge::CallOnURLFetchComplete, this));
   }
  private:
-  virtual ~ShuntedHttpBridge() {}
+  ~ShuntedHttpBridge() override {}
 
   void CallOnURLFetchComplete() {
     ASSERT_TRUE(base::MessageLoop::current() == test_->GetIOThreadLoop());
diff --git a/sync/internal_api/js_mutation_event_observer.h b/sync/internal_api/js_mutation_event_observer.h
index 5a007cb..41bd9fab 100644
--- a/sync/internal_api/js_mutation_event_observer.h
+++ b/sync/internal_api/js_mutation_event_observer.h
@@ -34,7 +34,7 @@
  public:
   JsMutationEventObserver();
 
-  virtual ~JsMutationEventObserver();
+  ~JsMutationEventObserver() override;
 
   base::WeakPtr<JsMutationEventObserver> AsWeakPtr();
 
@@ -43,14 +43,13 @@
   void SetJsEventHandler(const WeakHandle<JsEventHandler>& event_handler);
 
   // SyncManager::ChangeObserver implementation.
-  virtual void OnChangesApplied(
-      ModelType model_type,
-      int64 write_transaction_id,
-      const ImmutableChangeRecordList& changes) override;
-  virtual void OnChangesComplete(ModelType model_type) override;
+  void OnChangesApplied(ModelType model_type,
+                        int64 write_transaction_id,
+                        const ImmutableChangeRecordList& changes) override;
+  void OnChangesComplete(ModelType model_type) override;
 
   // syncable::TransactionObserver implementation.
-  virtual void OnTransactionWrite(
+  void OnTransactionWrite(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       ModelTypeSet models_with_changes) override;
 
diff --git a/sync/internal_api/js_sync_encryption_handler_observer.h b/sync/internal_api/js_sync_encryption_handler_observer.h
index 94a085e..82d5743f0 100644
--- a/sync/internal_api/js_sync_encryption_handler_observer.h
+++ b/sync/internal_api/js_sync_encryption_handler_observer.h
@@ -28,27 +28,23 @@
     : public SyncEncryptionHandler::Observer {
  public:
   JsSyncEncryptionHandlerObserver();
-  virtual ~JsSyncEncryptionHandlerObserver();
+  ~JsSyncEncryptionHandlerObserver() override;
 
   void SetJsEventHandler(const WeakHandle<JsEventHandler>& event_handler);
 
   // SyncEncryptionHandlerObserver::Observer implementation.
-  virtual void OnPassphraseRequired(
+  void OnPassphraseRequired(
       PassphraseRequiredReason reason,
       const sync_pb::EncryptedData& pending_keys) override;
-  virtual void OnPassphraseAccepted() override;
-  virtual void OnBootstrapTokenUpdated(
-      const std::string& bootstrap_token,
-      BootstrapTokenType type) override;
-  virtual void OnEncryptedTypesChanged(
-      ModelTypeSet encrypted_types,
-      bool encrypt_everything) override;
-  virtual void OnEncryptionComplete() override;
-  virtual void OnCryptographerStateChanged(
-      Cryptographer* cryptographer) override;
-  virtual void OnPassphraseTypeChanged(
-      PassphraseType type,
-      base::Time explicit_passphrase_time) override;
+  void OnPassphraseAccepted() override;
+  void OnBootstrapTokenUpdated(const std::string& bootstrap_token,
+                               BootstrapTokenType type) override;
+  void OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
+                               bool encrypt_everything) override;
+  void OnEncryptionComplete() override;
+  void OnCryptographerStateChanged(Cryptographer* cryptographer) override;
+  void OnPassphraseTypeChanged(PassphraseType type,
+                               base::Time explicit_passphrase_time) override;
 
  private:
   void HandleJsEvent(const tracked_objects::Location& from_here,
diff --git a/sync/internal_api/js_sync_manager_observer.h b/sync/internal_api/js_sync_manager_observer.h
index 1e694a8..58df73de 100644
--- a/sync/internal_api/js_sync_manager_observer.h
+++ b/sync/internal_api/js_sync_manager_observer.h
@@ -27,24 +27,22 @@
 class SYNC_EXPORT_PRIVATE JsSyncManagerObserver : public SyncManager::Observer {
  public:
   JsSyncManagerObserver();
-  virtual ~JsSyncManagerObserver();
+  ~JsSyncManagerObserver() override;
 
   void SetJsEventHandler(const WeakHandle<JsEventHandler>& event_handler);
 
   // SyncManager::Observer implementation.
-  virtual void OnSyncCycleCompleted(
+  void OnSyncCycleCompleted(
       const sessions::SyncSessionSnapshot& snapshot) override;
-  virtual void OnConnectionStatusChange(ConnectionStatus status) override;
-  virtual void OnInitializationComplete(
+  void OnConnectionStatusChange(ConnectionStatus status) override;
+  void OnInitializationComplete(
       const WeakHandle<JsBackend>& js_backend,
       const WeakHandle<DataTypeDebugInfoListener>& debug_info_listener,
       bool success,
       syncer::ModelTypeSet restored_types) override;
-  virtual void OnActionableError(
-      const SyncProtocolError& sync_protocol_error) override;
-  virtual void OnProtocolEvent(const ProtocolEvent& event) override;
-  virtual void OnMigrationRequested(
-      syncer::ModelTypeSet types) override;
+  void OnActionableError(const SyncProtocolError& sync_protocol_error) override;
+  void OnProtocolEvent(const ProtocolEvent& event) override;
+  void OnMigrationRequested(syncer::ModelTypeSet types) override;
 
  private:
   void HandleJsEvent(const tracked_objects::Location& from_here,
diff --git a/sync/internal_api/public/attachments/attachment_downloader_impl.h b/sync/internal_api/public/attachments/attachment_downloader_impl.h
index 5a8a5c1..363d805 100644
--- a/sync/internal_api/public/attachments/attachment_downloader_impl.h
+++ b/sync/internal_api/public/attachments/attachment_downloader_impl.h
@@ -42,21 +42,21 @@
       const OAuth2TokenService::ScopeSet& scopes,
       const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
           token_service_provider);
-  virtual ~AttachmentDownloaderImpl();
+  ~AttachmentDownloaderImpl() override;
 
   // AttachmentDownloader implementation.
-  virtual void DownloadAttachment(const AttachmentId& attachment_id,
-                                  const DownloadCallback& callback) override;
+  void DownloadAttachment(const AttachmentId& attachment_id,
+                          const DownloadCallback& callback) override;
 
   // OAuth2TokenService::Consumer implementation.
-  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                                 const std::string& access_token,
-                                 const base::Time& expiration_time) override;
-  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                                 const GoogleServiceAuthError& error) override;
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
 
   // net::URLFetcherDelegate implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(AttachmentDownloaderImplTest, ExtractCrc32c_First);
diff --git a/sync/internal_api/public/attachments/attachment_service_impl.h b/sync/internal_api/public/attachments/attachment_service_impl.h
index 89cc333..ae2e8b3 100644
--- a/sync/internal_api/public/attachments/attachment_service_impl.h
+++ b/sync/internal_api/public/attachments/attachment_service_impl.h
@@ -53,23 +53,21 @@
                         Delegate* delegate,
                         const base::TimeDelta& initial_backoff_delay,
                         const base::TimeDelta& max_backoff_delay);
-  virtual ~AttachmentServiceImpl();
+  ~AttachmentServiceImpl() override;
 
   // Create an AttachmentServiceImpl suitable for use in tests.
   static scoped_ptr<syncer::AttachmentService> CreateForTest();
 
   // AttachmentService implementation.
-  virtual AttachmentStore* GetStore() override;
-  virtual void GetOrDownloadAttachments(
-      const AttachmentIdList& attachment_ids,
-      const GetOrDownloadCallback& callback) override;
-  virtual void DropAttachments(const AttachmentIdList& attachment_ids,
-                               const DropCallback& callback) override;
-  virtual void UploadAttachments(
-      const AttachmentIdSet& attachment_ids) override;
+  AttachmentStore* GetStore() override;
+  void GetOrDownloadAttachments(const AttachmentIdList& attachment_ids,
+                                const GetOrDownloadCallback& callback) override;
+  void DropAttachments(const AttachmentIdList& attachment_ids,
+                       const DropCallback& callback) override;
+  void UploadAttachments(const AttachmentIdSet& attachment_ids) override;
 
   // NetworkChangeObserver implementation.
-  virtual void OnNetworkChanged(
+  void OnNetworkChanged(
       net::NetworkChangeNotifier::ConnectionType type) override;
 
   // Use |timer| in the underlying TaskQueue.
diff --git a/sync/internal_api/public/attachments/attachment_service_proxy.h b/sync/internal_api/public/attachments/attachment_service_proxy.h
index e41459d..cab107ef 100644
--- a/sync/internal_api/public/attachments/attachment_service_proxy.h
+++ b/sync/internal_api/public/attachments/attachment_service_proxy.h
@@ -48,19 +48,17 @@
       const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
       const base::WeakPtr<syncer::AttachmentService>& wrapped);
 
-  virtual ~AttachmentServiceProxy();
+  ~AttachmentServiceProxy() override;
 
   // AttachmentService implementation.
   //
   // GetStore always returns NULL.
-  virtual AttachmentStore* GetStore() override;
-  virtual void GetOrDownloadAttachments(
-      const AttachmentIdList& attachment_ids,
-      const GetOrDownloadCallback& callback) override;
-  virtual void DropAttachments(const AttachmentIdList& attachment_ids,
-                               const DropCallback& callback) override;
-  virtual void UploadAttachments(
-      const AttachmentIdSet& attachment_ids) override;
+  AttachmentStore* GetStore() override;
+  void GetOrDownloadAttachments(const AttachmentIdList& attachment_ids,
+                                const GetOrDownloadCallback& callback) override;
+  void DropAttachments(const AttachmentIdList& attachment_ids,
+                       const DropCallback& callback) override;
+  void UploadAttachments(const AttachmentIdSet& attachment_ids) override;
 
  protected:
   // Core does the work of proxying calls to AttachmentService methods from one
@@ -83,18 +81,17 @@
     Core(const base::WeakPtr<syncer::AttachmentService>& wrapped);
 
     // AttachmentService implementation.
-    virtual AttachmentStore* GetStore() override;
-    virtual void GetOrDownloadAttachments(
+    AttachmentStore* GetStore() override;
+    void GetOrDownloadAttachments(
         const AttachmentIdList& attachment_ids,
         const GetOrDownloadCallback& callback) override;
-    virtual void DropAttachments(const AttachmentIdList& attachment_ids,
-                                 const DropCallback& callback) override;
-    virtual void UploadAttachments(
-        const AttachmentIdSet& attachment_ids) override;
+    void DropAttachments(const AttachmentIdList& attachment_ids,
+                         const DropCallback& callback) override;
+    void UploadAttachments(const AttachmentIdSet& attachment_ids) override;
 
    protected:
     friend class base::RefCountedThreadSafe<Core>;
-    virtual ~Core();
+    ~Core() override;
 
    private:
     base::WeakPtr<AttachmentService> wrapped_;
diff --git a/sync/internal_api/public/attachments/attachment_service_proxy_for_test.h b/sync/internal_api/public/attachments/attachment_service_proxy_for_test.h
index b5cbdca..47a990b 100644
--- a/sync/internal_api/public/attachments/attachment_service_proxy_for_test.h
+++ b/sync/internal_api/public/attachments/attachment_service_proxy_for_test.h
@@ -21,7 +21,7 @@
     : public AttachmentServiceProxy {
  public:
   static AttachmentServiceProxy Create();
-  virtual ~AttachmentServiceProxyForTest();
+  ~AttachmentServiceProxyForTest() override;
 
  private:
   // A Core that owns the wrapped AttachmentService.
@@ -32,7 +32,7 @@
         scoped_ptr<base::WeakPtrFactory<AttachmentService> > weak_ptr_factory);
 
    private:
-    virtual ~OwningCore();
+    ~OwningCore() override;
 
     scoped_ptr<AttachmentService> wrapped_;
     // WeakPtrFactory for wrapped_.  See Create() for why this is a scoped_ptr.
diff --git a/sync/internal_api/public/attachments/attachment_store_handle.h b/sync/internal_api/public/attachments/attachment_store_handle.h
index fae6660..012a603 100644
--- a/sync/internal_api/public/attachments/attachment_store_handle.h
+++ b/sync/internal_api/public/attachments/attachment_store_handle.h
@@ -41,15 +41,13 @@
       const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner);
 
   // AttachmentStore implementation.
-  virtual void Read(const AttachmentIdList& id,
-                    const ReadCallback& callback) override;
-  virtual void Write(const AttachmentList& attachments,
-                     const WriteCallback& callback) override;
-  virtual void Drop(const AttachmentIdList& id,
-                    const DropCallback& callback) override;
+  void Read(const AttachmentIdList& id, const ReadCallback& callback) override;
+  void Write(const AttachmentList& attachments,
+             const WriteCallback& callback) override;
+  void Drop(const AttachmentIdList& id, const DropCallback& callback) override;
 
  private:
-  virtual ~AttachmentStoreHandle();
+  ~AttachmentStoreHandle() override;
 
   // AttachmentStoreHandle controls backend's lifetime. It is safe for
   // AttachmentStoreHandle to bind backend through base::Unretained for posts.
diff --git a/sync/internal_api/public/attachments/attachment_uploader_impl.h b/sync/internal_api/public/attachments/attachment_uploader_impl.h
index 7b5c7fc..fde544c5 100644
--- a/sync/internal_api/public/attachments/attachment_uploader_impl.h
+++ b/sync/internal_api/public/attachments/attachment_uploader_impl.h
@@ -41,11 +41,11 @@
       const OAuth2TokenService::ScopeSet& scopes,
       const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
           token_service_provider);
-  virtual ~AttachmentUploaderImpl();
+  ~AttachmentUploaderImpl() override;
 
   // AttachmentUploader implementation.
-  virtual void UploadAttachment(const Attachment& attachment,
-                                const UploadCallback& callback) override;
+  void UploadAttachment(const Attachment& attachment,
+                        const UploadCallback& callback) override;
 
   // Return the URL for the given |sync_service_url| and |attachment_id|.
   static GURL GetURLForAttachmentId(const GURL& sync_service_url,
diff --git a/sync/internal_api/public/attachments/fake_attachment_downloader.h b/sync/internal_api/public/attachments/fake_attachment_downloader.h
index 0b13a0e..576d06b 100644
--- a/sync/internal_api/public/attachments/fake_attachment_downloader.h
+++ b/sync/internal_api/public/attachments/fake_attachment_downloader.h
@@ -16,11 +16,11 @@
                                              public base::NonThreadSafe {
  public:
   FakeAttachmentDownloader();
-  virtual ~FakeAttachmentDownloader();
+  ~FakeAttachmentDownloader() override;
 
   // AttachmentDownloader implementation.
-  virtual void DownloadAttachment(const AttachmentId& attachment_id,
-                                  const DownloadCallback& callback) override;
+  void DownloadAttachment(const AttachmentId& attachment_id,
+                          const DownloadCallback& callback) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FakeAttachmentDownloader);
diff --git a/sync/internal_api/public/attachments/fake_attachment_uploader.h b/sync/internal_api/public/attachments/fake_attachment_uploader.h
index 16d3a51c..74f2a1ff1 100644
--- a/sync/internal_api/public/attachments/fake_attachment_uploader.h
+++ b/sync/internal_api/public/attachments/fake_attachment_uploader.h
@@ -15,11 +15,11 @@
                                            public base::NonThreadSafe {
  public:
   FakeAttachmentUploader();
-  virtual ~FakeAttachmentUploader();
+  ~FakeAttachmentUploader() override;
 
   // AttachmentUploader implementation.
-  virtual void UploadAttachment(const Attachment& attachment,
-                                const UploadCallback& callback) override;
+  void UploadAttachment(const Attachment& attachment,
+                        const UploadCallback& callback) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FakeAttachmentUploader);
diff --git a/sync/internal_api/public/attachments/in_memory_attachment_store.h b/sync/internal_api/public/attachments/in_memory_attachment_store.h
index adf4035..c586ef0ef 100644
--- a/sync/internal_api/public/attachments/in_memory_attachment_store.h
+++ b/sync/internal_api/public/attachments/in_memory_attachment_store.h
@@ -23,15 +23,13 @@
  public:
   InMemoryAttachmentStore(
       const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner);
-  virtual ~InMemoryAttachmentStore();
+  ~InMemoryAttachmentStore() override;
 
   // AttachmentStoreBase implementation.
-  virtual void Read(const AttachmentIdList& ids,
-                    const ReadCallback& callback) override;
-  virtual void Write(const AttachmentList& attachments,
-                     const WriteCallback& callback) override;
-  virtual void Drop(const AttachmentIdList& ids,
-                    const DropCallback& callback) override;
+  void Read(const AttachmentIdList& ids, const ReadCallback& callback) override;
+  void Write(const AttachmentList& attachments,
+             const WriteCallback& callback) override;
+  void Drop(const AttachmentIdList& ids, const DropCallback& callback) override;
 
  private:
   scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_;
diff --git a/sync/internal_api/public/attachments/on_disk_attachment_store.h b/sync/internal_api/public/attachments/on_disk_attachment_store.h
index d74b60bf..fad362f8 100644
--- a/sync/internal_api/public/attachments/on_disk_attachment_store.h
+++ b/sync/internal_api/public/attachments/on_disk_attachment_store.h
@@ -31,18 +31,16 @@
   // Constructs attachment store.
   OnDiskAttachmentStore(
       const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner);
-  virtual ~OnDiskAttachmentStore();
+  ~OnDiskAttachmentStore() override;
 
   // AttachmentStoreBase implementation.
   // Load opens database, creating it if needed. In the future upgrade code will
   // be invoked from Load as well. If loading fails it posts |callback| with
   // UNSPECIFIED_ERROR.
-  virtual void Read(const AttachmentIdList& ids,
-                    const ReadCallback& callback) override;
-  virtual void Write(const AttachmentList& attachments,
-                     const WriteCallback& callback) override;
-  virtual void Drop(const AttachmentIdList& ids,
-                    const DropCallback& callback) override;
+  void Read(const AttachmentIdList& ids, const ReadCallback& callback) override;
+  void Write(const AttachmentList& attachments,
+             const WriteCallback& callback) override;
+  void Drop(const AttachmentIdList& ids, const DropCallback& callback) override;
 
   // Opens leveldb database at |path|. It will create directory and database if
   // it doesn't exist.
diff --git a/sync/internal_api/public/base/cancelation_signal_unittest.cc b/sync/internal_api/public/base/cancelation_signal_unittest.cc
index e8b375da..58a35cc 100644
--- a/sync/internal_api/public/base/cancelation_signal_unittest.cc
+++ b/sync/internal_api/public/base/cancelation_signal_unittest.cc
@@ -18,7 +18,7 @@
 class BlockingTask : public CancelationObserver {
  public:
   BlockingTask(CancelationSignal* cancel_signal);
-  virtual ~BlockingTask();
+  ~BlockingTask() override;
 
   // Starts the |exec_thread_| and uses it to execute DoRun().
   void RunAsync(base::WaitableEvent* task_start_signal,
@@ -33,7 +33,7 @@
 
   // Implementation of CancelationObserver.
   // Wakes up the thread blocked in Run().
-  virtual void OnSignalReceived() override;
+  void OnSignalReceived() override;
 
   // Checks if we ever did successfully start waiting for |event_|.  Be careful
   // with this.  The flag itself is thread-unsafe, and the event that flips it
@@ -150,7 +150,7 @@
 }
 
 class FakeCancelationObserver : public CancelationObserver {
-  virtual void OnSignalReceived() override { }
+  void OnSignalReceived() override {}
 };
 
 TEST(CancelationSignalTest_SingleThread, CheckFlags) {
diff --git a/sync/internal_api/public/engine/model_safe_worker.cc b/sync/internal_api/public/engine/model_safe_worker.cc
index 2aea5cf..ea8bd4b 100644
--- a/sync/internal_api/public/engine/model_safe_worker.cc
+++ b/sync/internal_api/public/engine/model_safe_worker.cc
@@ -133,23 +133,32 @@
 }
 
 void ModelSafeWorker::SetWorkingLoopToCurrent() {
-  base::AutoLock l(working_loop_lock_);
-  DCHECK(!working_loop_);
+  base::Callback<void(ModelSafeGroup)> unregister_done_callback;
 
-  if (unregister_done_callback_.is_null()) {
-    // Expected case - UnregisterForLoopDestruction hasn't been called yet.
-    base::MessageLoop::current()->AddDestructionObserver(this);
-    working_loop_ = base::MessageLoop::current();
-  } else {
-    // Rare case which is possible when the model type thread remains
-    // blocked for the entire session and UnregisterForLoopDestruction ends
-    // up being called before this method. This method is posted unlike
-    // UnregisterForLoopDestruction - that's why they can end up being called
-    // out of order.
-    // In this case we skip the destruction observer registration
-    // and just invoke the callback stored at UnregisterForLoopDestruction.
-    DCHECK(stopped_);
-    unregister_done_callback_.Run(GetModelSafeGroup());
+  {
+    base::AutoLock l(working_loop_lock_);
+    DCHECK(!working_loop_);
+
+    if (unregister_done_callback_.is_null()) {
+      // Expected case - UnregisterForLoopDestruction hasn't been called yet.
+      base::MessageLoop::current()->AddDestructionObserver(this);
+      working_loop_ = base::MessageLoop::current();
+    } else {
+      // Rare case which is possible when the model type thread remains
+      // blocked for the entire session and UnregisterForLoopDestruction ends
+      // up being called before this method. This method is posted unlike
+      // UnregisterForLoopDestruction - that's why they can end up being called
+      // out of order.
+      // In this case we skip the destruction observer registration
+      // and just invoke the callback stored at UnregisterForLoopDestruction.
+      DCHECK(stopped_);
+      unregister_done_callback = unregister_done_callback_;
+      unregister_done_callback_.Reset();
+    }
+  }
+
+  if (!unregister_done_callback.is_null()) {
+    unregister_done_callback.Run(GetModelSafeGroup());
   }
 }
 
diff --git a/sync/internal_api/public/engine/model_safe_worker.h b/sync/internal_api/public/engine/model_safe_worker.h
index df5bba9b..ad84d492 100644
--- a/sync/internal_api/public/engine/model_safe_worker.h
+++ b/sync/internal_api/public/engine/model_safe_worker.h
@@ -89,13 +89,13 @@
   virtual ModelSafeGroup GetModelSafeGroup() = 0;
 
   // MessageLoop::DestructionObserver implementation.
-  virtual void WillDestroyCurrentMessageLoop() override;
+  void WillDestroyCurrentMessageLoop() override;
 
  protected:
   friend class base::RefCountedThreadSafe<ModelSafeWorker>;
 
   explicit ModelSafeWorker(WorkerLoopDestructionObserver* observer);
-  virtual ~ModelSafeWorker();
+  ~ModelSafeWorker() override;
 
   // Any time the Syncer performs model modifications (e.g employing a
   // WriteTransaction), it should be done by this method to ensure it is done
diff --git a/sync/internal_api/public/engine/passive_model_worker.h b/sync/internal_api/public/engine/passive_model_worker.h
index bc95461..d7f076e 100644
--- a/sync/internal_api/public/engine/passive_model_worker.h
+++ b/sync/internal_api/public/engine/passive_model_worker.h
@@ -22,15 +22,14 @@
                               WorkerLoopDestructionObserver* observer);
 
   // ModelSafeWorker implementation. Called on the sync thread.
-  virtual void RegisterForLoopDestruction() override;
-  virtual ModelSafeGroup GetModelSafeGroup() override;
+  void RegisterForLoopDestruction() override;
+  ModelSafeGroup GetModelSafeGroup() override;
 
  protected:
-  virtual SyncerError DoWorkAndWaitUntilDoneImpl(
-      const WorkCallback& work) override;
+  SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) override;
 
  private:
-  virtual ~PassiveModelWorker();
+  ~PassiveModelWorker() override;
 
   const base::MessageLoop* const sync_loop_;
 
diff --git a/sync/internal_api/public/events/commit_request_event.h b/sync/internal_api/public/events/commit_request_event.h
index e8f7a1c..23f3cd8 100644
--- a/sync/internal_api/public/events/commit_request_event.h
+++ b/sync/internal_api/public/events/commit_request_event.h
@@ -25,13 +25,13 @@
       size_t num_items,
       ModelTypeSet contributing_types,
       const sync_pb::ClientToServerMessage& request);
-  virtual ~CommitRequestEvent();
+  ~CommitRequestEvent() override;
 
-  virtual base::Time GetTimestamp() const override;
-  virtual std::string GetType() const override;
-  virtual std::string GetDetails() const override;
-  virtual scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
-  virtual scoped_ptr<ProtocolEvent> Clone() const override;
+  base::Time GetTimestamp() const override;
+  std::string GetType() const override;
+  std::string GetDetails() const override;
+  scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
+  scoped_ptr<ProtocolEvent> Clone() const override;
 
   static scoped_ptr<base::DictionaryValue> ToValue(
       const ProtocolEvent& event);
diff --git a/sync/internal_api/public/events/commit_response_event.h b/sync/internal_api/public/events/commit_response_event.h
index 0fba203..4de82837 100644
--- a/sync/internal_api/public/events/commit_response_event.h
+++ b/sync/internal_api/public/events/commit_response_event.h
@@ -24,13 +24,13 @@
       base::Time timestamp,
       SyncerError result,
       const sync_pb::ClientToServerResponse& response);
-  virtual ~CommitResponseEvent();
+  ~CommitResponseEvent() override;
 
-  virtual base::Time GetTimestamp() const override;
-  virtual std::string GetType() const override;
-  virtual std::string GetDetails() const override;
-  virtual scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
-  virtual scoped_ptr<ProtocolEvent> Clone() const override;
+  base::Time GetTimestamp() const override;
+  std::string GetType() const override;
+  std::string GetDetails() const override;
+  scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
+  scoped_ptr<ProtocolEvent> Clone() const override;
 
   static scoped_ptr<base::DictionaryValue> ToValue(
       const ProtocolEvent& event);
diff --git a/sync/internal_api/public/events/configure_get_updates_request_event.h b/sync/internal_api/public/events/configure_get_updates_request_event.h
index fd98074..984f3e8 100644
--- a/sync/internal_api/public/events/configure_get_updates_request_event.h
+++ b/sync/internal_api/public/events/configure_get_updates_request_event.h
@@ -22,13 +22,13 @@
       base::Time timestamp,
       sync_pb::SyncEnums::GetUpdatesOrigin origin,
       const sync_pb::ClientToServerMessage& request);
-  virtual ~ConfigureGetUpdatesRequestEvent();
+  ~ConfigureGetUpdatesRequestEvent() override;
 
-  virtual base::Time GetTimestamp() const override;
-  virtual std::string GetType() const override;
-  virtual std::string GetDetails() const override;
-  virtual scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
-  virtual scoped_ptr<ProtocolEvent> Clone() const override;
+  base::Time GetTimestamp() const override;
+  std::string GetType() const override;
+  std::string GetDetails() const override;
+  scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
+  scoped_ptr<ProtocolEvent> Clone() const override;
 
  private:
   const base::Time timestamp_;
diff --git a/sync/internal_api/public/events/get_updates_response_event.h b/sync/internal_api/public/events/get_updates_response_event.h
index a9764621..3c76c9ac 100644
--- a/sync/internal_api/public/events/get_updates_response_event.h
+++ b/sync/internal_api/public/events/get_updates_response_event.h
@@ -26,13 +26,13 @@
       const sync_pb::ClientToServerResponse& response,
       SyncerError error);
 
-  virtual ~GetUpdatesResponseEvent();
+  ~GetUpdatesResponseEvent() override;
 
-  virtual base::Time GetTimestamp() const override;
-  virtual std::string GetType() const override;
-  virtual std::string GetDetails() const override;
-  virtual scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
-  virtual scoped_ptr<ProtocolEvent> Clone() const override;
+  base::Time GetTimestamp() const override;
+  std::string GetType() const override;
+  std::string GetDetails() const override;
+  scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
+  scoped_ptr<ProtocolEvent> Clone() const override;
 
  private:
   const base::Time timestamp_;
diff --git a/sync/internal_api/public/events/normal_get_updates_request_event.h b/sync/internal_api/public/events/normal_get_updates_request_event.h
index 466b895c..5765dece 100644
--- a/sync/internal_api/public/events/normal_get_updates_request_event.h
+++ b/sync/internal_api/public/events/normal_get_updates_request_event.h
@@ -27,13 +27,13 @@
       const sessions::NudgeTracker& nudge_tracker,
       const sync_pb::ClientToServerMessage& request);
 
-  virtual ~NormalGetUpdatesRequestEvent();
+  ~NormalGetUpdatesRequestEvent() override;
 
-  virtual base::Time GetTimestamp() const override;
-  virtual std::string GetType() const override;
-  virtual std::string GetDetails() const override;
-  virtual scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
-  virtual scoped_ptr<ProtocolEvent> Clone() const override;
+  base::Time GetTimestamp() const override;
+  std::string GetType() const override;
+  std::string GetDetails() const override;
+  scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
+  scoped_ptr<ProtocolEvent> Clone() const override;
 
  private:
   NormalGetUpdatesRequestEvent(
diff --git a/sync/internal_api/public/events/poll_get_updates_request_event.h b/sync/internal_api/public/events/poll_get_updates_request_event.h
index 9f7f3933..3db5247 100644
--- a/sync/internal_api/public/events/poll_get_updates_request_event.h
+++ b/sync/internal_api/public/events/poll_get_updates_request_event.h
@@ -25,13 +25,13 @@
   PollGetUpdatesRequestEvent(
       base::Time timestamp,
       const sync_pb::ClientToServerMessage& request);
-  virtual ~PollGetUpdatesRequestEvent();
+  ~PollGetUpdatesRequestEvent() override;
 
-  virtual base::Time GetTimestamp() const override;
-  virtual std::string GetType() const override;
-  virtual std::string GetDetails() const override;
-  virtual scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
-  virtual scoped_ptr<ProtocolEvent> Clone() const override;
+  base::Time GetTimestamp() const override;
+  std::string GetType() const override;
+  std::string GetDetails() const override;
+  scoped_ptr<base::DictionaryValue> GetProtoMessage() const override;
+  scoped_ptr<ProtocolEvent> Clone() const override;
 
  private:
   const base::Time timestamp_;
diff --git a/sync/internal_api/public/http_bridge.h b/sync/internal_api/public/http_bridge.h
index 801873e..8b7839a 100644
--- a/sync/internal_api/public/http_bridge.h
+++ b/sync/internal_api/public/http_bridge.h
@@ -67,7 +67,7 @@
         const std::string& user_agent);
 
     // The destructor MUST be called on the IO thread.
-    virtual ~RequestContext();
+    ~RequestContext() override;
 
    private:
     net::URLRequestContext* const baseline_context_;
@@ -87,12 +87,12 @@
         const std::string& user_agent);
 
     // net::URLRequestContextGetter implementation.
-    virtual net::URLRequestContext* GetURLRequestContext() override;
-    virtual scoped_refptr<base::SingleThreadTaskRunner>
-        GetNetworkTaskRunner() const override;
+    net::URLRequestContext* GetURLRequestContext() override;
+    scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+        const override;
 
    protected:
-    virtual ~RequestContextGetter();
+    ~RequestContextGetter() override;
 
    private:
     scoped_refptr<net::URLRequestContextGetter> baseline_context_getter_;
@@ -110,32 +110,32 @@
              const NetworkTimeUpdateCallback& network_time_update_callback);
 
   // HttpPostProvider implementation.
-  virtual void SetExtraRequestHeaders(const char* headers) override;
-  virtual void SetURL(const char* url, int port) override;
-  virtual void SetPostPayload(const char* content_type, int content_length,
-                              const char* content) override;
-  virtual bool MakeSynchronousPost(int* error_code,
-                                   int* response_code) override;
-  virtual void Abort() override;
+  void SetExtraRequestHeaders(const char* headers) override;
+  void SetURL(const char* url, int port) override;
+  void SetPostPayload(const char* content_type,
+                      int content_length,
+                      const char* content) override;
+  bool MakeSynchronousPost(int* error_code, int* response_code) override;
+  void Abort() override;
 
   // WARNING: these response content methods are used to extract plain old data
   // and not null terminated strings, so you should make sure you have read
   // GetResponseContentLength() characters when using GetResponseContent. e.g
   // string r(b->GetResponseContent(), b->GetResponseContentLength()).
-  virtual int GetResponseContentLength() const override;
-  virtual const char* GetResponseContent() const override;
-  virtual const std::string GetResponseHeaderValue(
+  int GetResponseContentLength() const override;
+  const char* GetResponseContent() const override;
+  const std::string GetResponseHeaderValue(
       const std::string& name) const override;
 
   // net::URLFetcherDelegate implementation.
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   net::URLRequestContextGetter* GetRequestContextGetterForTest() const;
 
  protected:
   friend class base::RefCountedThreadSafe<HttpBridge>;
 
-  virtual ~HttpBridge();
+  ~HttpBridge() override;
 
   // Protected virtual so the unit test can override to shunt network requests.
   virtual void MakeAsynchronousPost();
@@ -232,15 +232,15 @@
           baseline_context_getter,
       const NetworkTimeUpdateCallback& network_time_update_callback,
       CancelationSignal* cancelation_signal);
-  virtual ~HttpBridgeFactory();
+  ~HttpBridgeFactory() override;
 
   // HttpPostProviderFactory:
-  virtual void Init(const std::string& user_agent) override;
-  virtual HttpPostProviderInterface* Create() override;
-  virtual void Destroy(HttpPostProviderInterface* http) override;
+  void Init(const std::string& user_agent) override;
+  HttpPostProviderInterface* Create() override;
+  void Destroy(HttpPostProviderInterface* http) override;
 
   // CancelationObserver implementation:
-  virtual void OnSignalReceived() override;
+  void OnSignalReceived() override;
 
  private:
   // Protects |request_context_getter_| and |baseline_request_context_getter_|.
diff --git a/sync/internal_api/public/http_bridge_network_resources.h b/sync/internal_api/public/http_bridge_network_resources.h
index 0ea1ced..bd97da1 100644
--- a/sync/internal_api/public/http_bridge_network_resources.h
+++ b/sync/internal_api/public/http_bridge_network_resources.h
@@ -21,10 +21,10 @@
 
 class SYNC_EXPORT HttpBridgeNetworkResources : public NetworkResources {
   public:
-   virtual ~HttpBridgeNetworkResources();
+   ~HttpBridgeNetworkResources() override;
 
    // NetworkResources
-   virtual scoped_ptr<HttpPostProviderFactory> GetHttpPostProviderFactory(
+   scoped_ptr<HttpPostProviderFactory> GetHttpPostProviderFactory(
        const scoped_refptr<net::URLRequestContextGetter>&
            baseline_context_getter,
        const NetworkTimeUpdateCallback& network_time_update_callback,
diff --git a/sync/internal_api/public/internal_components_factory_impl.h b/sync/internal_api/public/internal_components_factory_impl.h
index 3fe5278e0..e29fa85f 100644
--- a/sync/internal_api/public/internal_components_factory_impl.h
+++ b/sync/internal_api/public/internal_components_factory_impl.h
@@ -17,14 +17,14 @@
     : public InternalComponentsFactory {
  public:
   InternalComponentsFactoryImpl(const Switches& switches);
-  virtual ~InternalComponentsFactoryImpl();
+  ~InternalComponentsFactoryImpl() override;
 
-  virtual scoped_ptr<SyncScheduler> BuildScheduler(
+  scoped_ptr<SyncScheduler> BuildScheduler(
       const std::string& name,
       sessions::SyncSessionContext* context,
       syncer::CancelationSignal* cancelation_signal) override;
 
-  virtual scoped_ptr<sessions::SyncSessionContext> BuildContext(
+  scoped_ptr<sessions::SyncSessionContext> BuildContext(
       ServerConnectionManager* connection_manager,
       syncable::Directory* directory,
       ExtensionsActivity* extensions_activity,
@@ -33,12 +33,12 @@
       ModelTypeRegistry* model_type_registry,
       const std::string& invalidator_client_id) override;
 
-  virtual scoped_ptr<syncable::DirectoryBackingStore>
-  BuildDirectoryBackingStore(StorageOption storage,
-                             const std::string& dir_name,
-                             const base::FilePath& backing_filepath) override;
+  scoped_ptr<syncable::DirectoryBackingStore> BuildDirectoryBackingStore(
+      StorageOption storage,
+      const std::string& dir_name,
+      const base::FilePath& backing_filepath) override;
 
-  virtual Switches GetSwitches() const override;
+  Switches GetSwitches() const override;
 
  private:
   const Switches switches_;
diff --git a/sync/internal_api/public/read_node.h b/sync/internal_api/public/read_node.h
index 6d46eea70..5749f9c 100644
--- a/sync/internal_api/public/read_node.h
+++ b/sync/internal_api/public/read_node.h
@@ -22,16 +22,15 @@
   // Create an unpopulated ReadNode on the given transaction.  Call some flavor
   // of Init to populate the ReadNode with a database entry.
   explicit ReadNode(const BaseTransaction* transaction);
-  virtual ~ReadNode();
+  ~ReadNode() override;
 
   // A client must use one (and only one) of the following Init variants to
   // populate the node.
 
   // BaseNode implementation.
-  virtual InitByLookupResult InitByIdLookup(int64 id) override;
-  virtual InitByLookupResult InitByClientTagLookup(
-      ModelType model_type,
-      const std::string& tag) override;
+  InitByLookupResult InitByIdLookup(int64 id) override;
+  InitByLookupResult InitByClientTagLookup(ModelType model_type,
+                                           const std::string& tag) override;
 
   // There is always a root node, so this can't fail.  The root node is
   // never mutable, so root lookup is only possible on a ReadNode.
@@ -50,8 +49,8 @@
   InitByLookupResult InitByTagLookupForBookmarks(const std::string& tag);
 
   // Implementation of BaseNode's abstract virtual accessors.
-  virtual const syncable::Entry* GetEntry() const override;
-  virtual const BaseTransaction* GetTransaction() const override;
+  const syncable::Entry* GetEntry() const override;
+  const BaseTransaction* GetTransaction() const override;
 
  protected:
   ReadNode();
diff --git a/sync/internal_api/public/read_transaction.h b/sync/internal_api/public/read_transaction.h
index 364f6be6..2084b9a 100644
--- a/sync/internal_api/public/read_transaction.h
+++ b/sync/internal_api/public/read_transaction.h
@@ -33,10 +33,10 @@
   // Resume the middle of a transaction. Will not close transaction.
   ReadTransaction(UserShare* share, syncable::BaseTransaction* trans);
 
-  virtual ~ReadTransaction();
+  ~ReadTransaction() override;
 
   // BaseTransaction override.
-  virtual syncable::BaseTransaction* GetWrappedTrans() const override;
+  syncable::BaseTransaction* GetWrappedTrans() const override;
 
   // Return |transaction_version| of |type| stored in sync directory's
   // persisted info.
diff --git a/sync/internal_api/public/test/fake_sync_manager.h b/sync/internal_api/public/test/fake_sync_manager.h
index 8d38457..edad9b9 100644
--- a/sync/internal_api/public/test/fake_sync_manager.h
+++ b/sync/internal_api/public/test/fake_sync_manager.h
@@ -40,7 +40,7 @@
   FakeSyncManager(ModelTypeSet initial_sync_ended_types,
                   ModelTypeSet progress_marker_types,
                   ModelTypeSet configure_fail_types);
-  virtual ~FakeSyncManager();
+  ~FakeSyncManager() override;
 
   // Returns those types that have been cleaned (purged from the directory)
   // since the last call to GetAndResetCleanedTypes(), or since startup if never
@@ -64,12 +64,12 @@
   ConfigureReason GetAndResetConfigureReason();
 
   // Posts a method to invalidate the given IDs on the sync thread.
-  virtual void OnIncomingInvalidation(
+  void OnIncomingInvalidation(
       syncer::ModelType type,
       scoped_ptr<InvalidationInterface> interface) override;
 
   // Posts a method to update the invalidator state on the sync thread.
-  virtual void SetInvalidatorEnabled(bool invalidator_enabled) override;
+  void SetInvalidatorEnabled(bool invalidator_enabled) override;
 
   // Block until the sync thread has finished processing any pending messages.
   void WaitForSyncThread();
@@ -77,46 +77,43 @@
   // SyncManager implementation.
   // Note: we treat whatever message loop this is called from as the sync
   // loop for purposes of callbacks.
-  virtual void Init(InitArgs* args) override;
-  virtual ModelTypeSet InitialSyncEndedTypes() override;
-  virtual ModelTypeSet GetTypesWithEmptyProgressMarkerToken(
+  void Init(InitArgs* args) override;
+  ModelTypeSet InitialSyncEndedTypes() override;
+  ModelTypeSet GetTypesWithEmptyProgressMarkerToken(
       ModelTypeSet types) override;
-  virtual bool PurgePartiallySyncedTypes() override;
-  virtual void UpdateCredentials(const SyncCredentials& credentials) override;
-  virtual void StartSyncingNormally(
-      const ModelSafeRoutingInfo& routing_info) override;
-  virtual void ConfigureSyncer(
-      ConfigureReason reason,
-      ModelTypeSet to_download,
-      ModelTypeSet to_purge,
-      ModelTypeSet to_journal,
-      ModelTypeSet to_unapply,
-      const ModelSafeRoutingInfo& new_routing_info,
-      const base::Closure& ready_task,
-      const base::Closure& retry_task) override;
-  virtual void AddObserver(Observer* observer) override;
-  virtual void RemoveObserver(Observer* observer) override;
-  virtual SyncStatus GetDetailedStatus() const override;
-  virtual void SaveChanges() override;
-  virtual void ShutdownOnSyncThread(ShutdownReason reason) override;
-  virtual UserShare* GetUserShare() override;
-  virtual syncer::SyncContextProxy* GetSyncContextProxy() override;
-  virtual const std::string cache_guid() override;
-  virtual bool ReceivedExperiment(Experiments* experiments) override;
-  virtual bool HasUnsyncedItems() override;
-  virtual SyncEncryptionHandler* GetEncryptionHandler() override;
-  virtual ScopedVector<syncer::ProtocolEvent>
-      GetBufferedProtocolEvents() override;
-  virtual scoped_ptr<base::ListValue> GetAllNodesForType(
+  bool PurgePartiallySyncedTypes() override;
+  void UpdateCredentials(const SyncCredentials& credentials) override;
+  void StartSyncingNormally(const ModelSafeRoutingInfo& routing_info) override;
+  void ConfigureSyncer(ConfigureReason reason,
+                       ModelTypeSet to_download,
+                       ModelTypeSet to_purge,
+                       ModelTypeSet to_journal,
+                       ModelTypeSet to_unapply,
+                       const ModelSafeRoutingInfo& new_routing_info,
+                       const base::Closure& ready_task,
+                       const base::Closure& retry_task) override;
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
+  SyncStatus GetDetailedStatus() const override;
+  void SaveChanges() override;
+  void ShutdownOnSyncThread(ShutdownReason reason) override;
+  UserShare* GetUserShare() override;
+  syncer::SyncContextProxy* GetSyncContextProxy() override;
+  const std::string cache_guid() override;
+  bool ReceivedExperiment(Experiments* experiments) override;
+  bool HasUnsyncedItems() override;
+  SyncEncryptionHandler* GetEncryptionHandler() override;
+  ScopedVector<syncer::ProtocolEvent> GetBufferedProtocolEvents() override;
+  scoped_ptr<base::ListValue> GetAllNodesForType(
       syncer::ModelType type) override;
-  virtual void RefreshTypes(ModelTypeSet types) override;
-  virtual void RegisterDirectoryTypeDebugInfoObserver(
+  void RefreshTypes(ModelTypeSet types) override;
+  void RegisterDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+  void UnregisterDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual bool HasDirectoryTypeDebugInfoObserver(
+  bool HasDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual void RequestEmitDebugInfo() override;
+  void RequestEmitDebugInfo() override;
 
  private:
   scoped_refptr<base::SequencedTaskRunner> sync_task_runner_;
diff --git a/sync/internal_api/public/test/null_sync_context_proxy.h b/sync/internal_api/public/test/null_sync_context_proxy.h
index 2694d8a6..3a6a726 100644
--- a/sync/internal_api/public/test/null_sync_context_proxy.h
+++ b/sync/internal_api/public/test/null_sync_context_proxy.h
@@ -19,15 +19,15 @@
 class NullSyncContextProxy : public SyncContextProxy {
  public:
   NullSyncContextProxy();
-  virtual ~NullSyncContextProxy();
+  ~NullSyncContextProxy() override;
 
-  virtual void ConnectTypeToSync(
+  void ConnectTypeToSync(
       syncer::ModelType type,
       const DataTypeState& data_type_state,
       const UpdateResponseDataList& saved_pending_updates,
       const base::WeakPtr<ModelTypeSyncProxyImpl>& type_sync_proxy) override;
-  virtual void Disconnect(syncer::ModelType type) override;
-  virtual scoped_ptr<SyncContextProxy> Clone() const override;
+  void Disconnect(syncer::ModelType type) override;
+  scoped_ptr<SyncContextProxy> Clone() const override;
 };
 
 }  // namespace syncer
diff --git a/sync/internal_api/public/test/sync_manager_factory_for_profile_sync_test.h b/sync/internal_api/public/test/sync_manager_factory_for_profile_sync_test.h
index d0ba111..695d07e 100644
--- a/sync/internal_api/public/test/sync_manager_factory_for_profile_sync_test.h
+++ b/sync/internal_api/public/test/sync_manager_factory_for_profile_sync_test.h
@@ -16,9 +16,9 @@
 class SyncManagerFactoryForProfileSyncTest : public syncer::SyncManagerFactory {
  public:
   SyncManagerFactoryForProfileSyncTest(base::Closure init_callback);
-  virtual ~SyncManagerFactoryForProfileSyncTest();
-  virtual scoped_ptr<syncer::SyncManager> CreateSyncManager(
-      std::string name) override;
+  ~SyncManagerFactoryForProfileSyncTest() override;
+  scoped_ptr<syncer::SyncManager> CreateSyncManager(std::string name) override;
+
  private:
   base::Closure init_callback_;
 };
diff --git a/sync/internal_api/public/test/test_internal_components_factory.h b/sync/internal_api/public/test/test_internal_components_factory.h
index 9b763eb..c8f6148 100644
--- a/sync/internal_api/public/test/test_internal_components_factory.h
+++ b/sync/internal_api/public/test/test_internal_components_factory.h
@@ -14,14 +14,14 @@
   explicit TestInternalComponentsFactory(const Switches& switches,
                                          StorageOption option,
                                          StorageOption* storage_used);
-  virtual ~TestInternalComponentsFactory();
+  ~TestInternalComponentsFactory() override;
 
-  virtual scoped_ptr<SyncScheduler> BuildScheduler(
+  scoped_ptr<SyncScheduler> BuildScheduler(
       const std::string& name,
       sessions::SyncSessionContext* context,
       syncer::CancelationSignal* cancelation_signal) override;
 
-  virtual scoped_ptr<sessions::SyncSessionContext> BuildContext(
+  scoped_ptr<sessions::SyncSessionContext> BuildContext(
       ServerConnectionManager* connection_manager,
       syncable::Directory* directory,
       ExtensionsActivity* monitor,
@@ -30,13 +30,12 @@
       ModelTypeRegistry* model_type_registry,
       const std::string& invalidator_client_id) override;
 
-  virtual scoped_ptr<syncable::DirectoryBackingStore>
-  BuildDirectoryBackingStore(
+  scoped_ptr<syncable::DirectoryBackingStore> BuildDirectoryBackingStore(
       StorageOption storage,
       const std::string& dir_name,
       const base::FilePath& backing_filepath) override;
 
-  virtual Switches GetSwitches() const override;
+  Switches GetSwitches() const override;
 
  private:
   const Switches switches_;
diff --git a/sync/internal_api/public/write_node.h b/sync/internal_api/public/write_node.h
index 26940c5dc..2682d017 100644
--- a/sync/internal_api/public/write_node.h
+++ b/sync/internal_api/public/write_node.h
@@ -56,16 +56,15 @@
 
   // Create a WriteNode using the given transaction.
   explicit WriteNode(WriteTransaction* transaction);
-  virtual ~WriteNode();
+  ~WriteNode() override;
 
   // A client must use one (and only one) of the following Init variants to
   // populate the node.
 
   // BaseNode implementation.
-  virtual InitByLookupResult InitByIdLookup(int64 id) override;
-  virtual InitByLookupResult InitByClientTagLookup(
-      ModelType model_type,
-      const std::string& tag) override;
+  InitByLookupResult InitByIdLookup(int64 id) override;
+  InitByLookupResult InitByClientTagLookup(ModelType model_type,
+                                           const std::string& tag) override;
 
   // Create a new bookmark node with the specified parent and predecessor.  Use
   // a NULL |predecessor| to indicate that this is to be the first child.
@@ -178,9 +177,9 @@
       const sync_pb::AttachmentMetadata& attachment_metadata);
 
   // Implementation of BaseNode's abstract virtual accessors.
-  virtual const syncable::Entry* GetEntry() const override;
+  const syncable::Entry* GetEntry() const override;
 
-  virtual const BaseTransaction* GetTransaction() const override;
+  const BaseTransaction* GetTransaction() const override;
 
   syncable::MutableEntry* GetMutableEntryForTest();
 
diff --git a/sync/internal_api/public/write_transaction.h b/sync/internal_api/public/write_transaction.h
index e100041..8d8d101 100644
--- a/sync/internal_api/public/write_transaction.h
+++ b/sync/internal_api/public/write_transaction.h
@@ -38,10 +38,10 @@
   // types that support embassy data.
   WriteTransaction(const tracked_objects::Location& from_here,
                    UserShare* share, int64* transaction_version);
-  virtual ~WriteTransaction();
+  ~WriteTransaction() override;
 
   // Provide access to the syncable transaction from the API WriteNode.
-  virtual syncable::BaseTransaction* GetWrappedTrans() const override;
+  syncable::BaseTransaction* GetWrappedTrans() const override;
   syncable::WriteTransaction* GetWrappedWriteTrans() { return transaction_; }
 
   // Set's a |type|'s local context. |refresh_status| controls whether
diff --git a/sync/internal_api/sync_backup_manager.h b/sync/internal_api/sync_backup_manager.h
index 2cfef48..4fee5e44 100644
--- a/sync/internal_api/sync_backup_manager.h
+++ b/sync/internal_api/sync_backup_manager.h
@@ -18,26 +18,26 @@
 class SYNC_EXPORT_PRIVATE SyncBackupManager : public SyncRollbackManagerBase {
  public:
   SyncBackupManager();
-  virtual ~SyncBackupManager();
+  ~SyncBackupManager() override;
 
   // SyncManager implementation.
-  virtual void Init(InitArgs* args) override;
-  virtual void SaveChanges() override;
-  virtual SyncStatus GetDetailedStatus() const override;
-  virtual void ShutdownOnSyncThread(ShutdownReason reason) override;
+  void Init(InitArgs* args) override;
+  void SaveChanges() override;
+  SyncStatus GetDetailedStatus() const override;
+  void ShutdownOnSyncThread(ShutdownReason reason) override;
 
   // DirectoryChangeDelegate implementation.
-  virtual ModelTypeSet HandleTransactionEndingChangeEvent(
+  ModelTypeSet HandleTransactionEndingChangeEvent(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       syncable::BaseTransaction* trans) override;
 
-  virtual void RegisterDirectoryTypeDebugInfoObserver(
+  void RegisterDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+  void UnregisterDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual bool HasDirectoryTypeDebugInfoObserver(
+  bool HasDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual void RequestEmitDebugInfo() override;
+  void RequestEmitDebugInfo() override;
 
  private:
   // Replaces local IDs with server IDs and clear unsynced bit of modified
diff --git a/sync/internal_api/sync_context_proxy_impl.h b/sync/internal_api/sync_context_proxy_impl.h
index 09ec8b3..2bd6ba6a 100644
--- a/sync/internal_api/sync_context_proxy_impl.h
+++ b/sync/internal_api/sync_context_proxy_impl.h
@@ -28,7 +28,7 @@
   SyncContextProxyImpl(
       const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner,
       const base::WeakPtr<SyncContext>& sync_context);
-  virtual ~SyncContextProxyImpl();
+  ~SyncContextProxyImpl() override;
 
   // Attempts to connect a non-blocking type to the sync context.
   //
@@ -37,16 +37,16 @@
   // unable to distinguish a slow success from failure.
   //
   // Must be called from the thread where the data type lives.
-  virtual void ConnectTypeToSync(
+  void ConnectTypeToSync(
       syncer::ModelType type,
       const DataTypeState& data_type_state,
       const UpdateResponseDataList& pending_updates,
       const base::WeakPtr<ModelTypeSyncProxyImpl>& sync_proxy_impl) override;
 
   // Disables syncing for the given type on the sync thread.
-  virtual void Disconnect(syncer::ModelType type) override;
+  void Disconnect(syncer::ModelType type) override;
 
-  virtual scoped_ptr<SyncContextProxy> Clone() const override;
+  scoped_ptr<SyncContextProxy> Clone() const override;
 
  private:
   // A SequencedTaskRunner representing the thread where the SyncContext lives.
diff --git a/sync/internal_api/sync_encryption_handler_impl.h b/sync/internal_api/sync_encryption_handler_impl.h
index 6cbf74ed..2db4c47 100644
--- a/sync/internal_api/sync_encryption_handler_impl.h
+++ b/sync/internal_api/sync_encryption_handler_impl.h
@@ -51,34 +51,32 @@
       Encryptor* encryptor,
       const std::string& restored_key_for_bootstrapping,
       const std::string& restored_keystore_key_for_bootstrapping);
-  virtual ~SyncEncryptionHandlerImpl();
+  ~SyncEncryptionHandlerImpl() override;
 
   // SyncEncryptionHandler implementation.
-  virtual void AddObserver(Observer* observer) override;
-  virtual void RemoveObserver(Observer* observer) override;
-  virtual void Init() override;
-  virtual void SetEncryptionPassphrase(const std::string& passphrase,
-                                       bool is_explicit) override;
-  virtual void SetDecryptionPassphrase(const std::string& passphrase) override;
-  virtual void EnableEncryptEverything() override;
-  virtual bool EncryptEverythingEnabled() const override;
-  virtual PassphraseType GetPassphraseType() const override;
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
+  void Init() override;
+  void SetEncryptionPassphrase(const std::string& passphrase,
+                               bool is_explicit) override;
+  void SetDecryptionPassphrase(const std::string& passphrase) override;
+  void EnableEncryptEverything() override;
+  bool EncryptEverythingEnabled() const override;
+  PassphraseType GetPassphraseType() const override;
 
   // NigoriHandler implementation.
   // Note: all methods are invoked while the caller holds a transaction.
-  virtual void ApplyNigoriUpdate(
-      const sync_pb::NigoriSpecifics& nigori,
-      syncable::BaseTransaction* const trans) override;
-  virtual void UpdateNigoriFromEncryptedTypes(
+  void ApplyNigoriUpdate(const sync_pb::NigoriSpecifics& nigori,
+                         syncable::BaseTransaction* const trans) override;
+  void UpdateNigoriFromEncryptedTypes(
       sync_pb::NigoriSpecifics* nigori,
       syncable::BaseTransaction* const trans) const override;
-  virtual bool NeedKeystoreKey(
-      syncable::BaseTransaction* const trans) const override;
-  virtual bool SetKeystoreKeys(
+  bool NeedKeystoreKey(syncable::BaseTransaction* const trans) const override;
+  bool SetKeystoreKeys(
       const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys,
       syncable::BaseTransaction* const trans) override;
   // Can be called from any thread.
-  virtual ModelTypeSet GetEncryptedTypes(
+  ModelTypeSet GetEncryptedTypes(
       syncable::BaseTransaction* const trans) const override;
 
   // Unsafe getters. Use only if sync is not up and running and there is no risk
diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h
index bed2d76..af9068b 100644
--- a/sync/internal_api/sync_manager_impl.h
+++ b/sync/internal_api/sync_manager_impl.h
@@ -65,119 +65,111 @@
  public:
   // Create an uninitialized SyncManager.  Callers must Init() before using.
   explicit SyncManagerImpl(const std::string& name);
-  virtual ~SyncManagerImpl();
+  ~SyncManagerImpl() override;
 
   // SyncManager implementation.
-  virtual void Init(InitArgs* args) override;
-  virtual ModelTypeSet InitialSyncEndedTypes() override;
-  virtual ModelTypeSet GetTypesWithEmptyProgressMarkerToken(
+  void Init(InitArgs* args) override;
+  ModelTypeSet InitialSyncEndedTypes() override;
+  ModelTypeSet GetTypesWithEmptyProgressMarkerToken(
       ModelTypeSet types) override;
-  virtual bool PurgePartiallySyncedTypes() override;
-  virtual void UpdateCredentials(const SyncCredentials& credentials) override;
-  virtual void StartSyncingNormally(
-      const ModelSafeRoutingInfo& routing_info) override;
-  virtual void ConfigureSyncer(
-      ConfigureReason reason,
-      ModelTypeSet to_download,
-      ModelTypeSet to_purge,
-      ModelTypeSet to_journal,
-      ModelTypeSet to_unapply,
-      const ModelSafeRoutingInfo& new_routing_info,
-      const base::Closure& ready_task,
-      const base::Closure& retry_task) override;
-  virtual void SetInvalidatorEnabled(bool invalidator_enabled) override;
-  virtual void OnIncomingInvalidation(
+  bool PurgePartiallySyncedTypes() override;
+  void UpdateCredentials(const SyncCredentials& credentials) override;
+  void StartSyncingNormally(const ModelSafeRoutingInfo& routing_info) override;
+  void ConfigureSyncer(ConfigureReason reason,
+                       ModelTypeSet to_download,
+                       ModelTypeSet to_purge,
+                       ModelTypeSet to_journal,
+                       ModelTypeSet to_unapply,
+                       const ModelSafeRoutingInfo& new_routing_info,
+                       const base::Closure& ready_task,
+                       const base::Closure& retry_task) override;
+  void SetInvalidatorEnabled(bool invalidator_enabled) override;
+  void OnIncomingInvalidation(
       syncer::ModelType type,
       scoped_ptr<InvalidationInterface> invalidation) override;
-  virtual void AddObserver(SyncManager::Observer* observer) override;
-  virtual void RemoveObserver(SyncManager::Observer* observer) override;
-  virtual SyncStatus GetDetailedStatus() const override;
-  virtual void SaveChanges() override;
-  virtual void ShutdownOnSyncThread(ShutdownReason reason) override;
-  virtual UserShare* GetUserShare() override;
-  virtual syncer::SyncContextProxy* GetSyncContextProxy() override;
-  virtual const std::string cache_guid() override;
-  virtual bool ReceivedExperiment(Experiments* experiments) override;
-  virtual bool HasUnsyncedItems() override;
-  virtual SyncEncryptionHandler* GetEncryptionHandler() override;
-  virtual ScopedVector<syncer::ProtocolEvent>
-      GetBufferedProtocolEvents() override;
-  virtual scoped_ptr<base::ListValue> GetAllNodesForType(
+  void AddObserver(SyncManager::Observer* observer) override;
+  void RemoveObserver(SyncManager::Observer* observer) override;
+  SyncStatus GetDetailedStatus() const override;
+  void SaveChanges() override;
+  void ShutdownOnSyncThread(ShutdownReason reason) override;
+  UserShare* GetUserShare() override;
+  syncer::SyncContextProxy* GetSyncContextProxy() override;
+  const std::string cache_guid() override;
+  bool ReceivedExperiment(Experiments* experiments) override;
+  bool HasUnsyncedItems() override;
+  SyncEncryptionHandler* GetEncryptionHandler() override;
+  ScopedVector<syncer::ProtocolEvent> GetBufferedProtocolEvents() override;
+  scoped_ptr<base::ListValue> GetAllNodesForType(
       syncer::ModelType type) override;
-  virtual void RegisterDirectoryTypeDebugInfoObserver(
+  void RegisterDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+  void UnregisterDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual bool HasDirectoryTypeDebugInfoObserver(
+  bool HasDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual void RequestEmitDebugInfo() override;
+  void RequestEmitDebugInfo() override;
 
   // SyncEncryptionHandler::Observer implementation.
-  virtual void OnPassphraseRequired(
+  void OnPassphraseRequired(
       PassphraseRequiredReason reason,
       const sync_pb::EncryptedData& pending_keys) override;
-  virtual void OnPassphraseAccepted() override;
-  virtual void OnBootstrapTokenUpdated(
-      const std::string& bootstrap_token,
-      BootstrapTokenType type) override;
-  virtual void OnEncryptedTypesChanged(
-      ModelTypeSet encrypted_types,
-      bool encrypt_everything) override;
-  virtual void OnEncryptionComplete() override;
-  virtual void OnCryptographerStateChanged(
-      Cryptographer* cryptographer) override;
-  virtual void OnPassphraseTypeChanged(
-      PassphraseType type,
-      base::Time explicit_passphrase_time) override;
+  void OnPassphraseAccepted() override;
+  void OnBootstrapTokenUpdated(const std::string& bootstrap_token,
+                               BootstrapTokenType type) override;
+  void OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
+                               bool encrypt_everything) override;
+  void OnEncryptionComplete() override;
+  void OnCryptographerStateChanged(Cryptographer* cryptographer) override;
+  void OnPassphraseTypeChanged(PassphraseType type,
+                               base::Time explicit_passphrase_time) override;
 
   // SyncEngineEventListener implementation.
-  virtual void OnSyncCycleEvent(const SyncCycleEvent& event) override;
-  virtual void OnActionableError(const SyncProtocolError& error) override;
-  virtual void OnRetryTimeChanged(base::Time retry_time) override;
-  virtual void OnThrottledTypesChanged(ModelTypeSet throttled_types) override;
-  virtual void OnMigrationRequested(ModelTypeSet types) override;
-  virtual void OnProtocolEvent(const ProtocolEvent& event) override;
+  void OnSyncCycleEvent(const SyncCycleEvent& event) override;
+  void OnActionableError(const SyncProtocolError& error) override;
+  void OnRetryTimeChanged(base::Time retry_time) override;
+  void OnThrottledTypesChanged(ModelTypeSet throttled_types) override;
+  void OnMigrationRequested(ModelTypeSet types) override;
+  void OnProtocolEvent(const ProtocolEvent& event) override;
 
   // ServerConnectionEventListener implementation.
-  virtual void OnServerConnectionEvent(
-      const ServerConnectionEvent& event) override;
+  void OnServerConnectionEvent(const ServerConnectionEvent& event) override;
 
   // JsBackend implementation.
-  virtual void SetJsEventHandler(
+  void SetJsEventHandler(
       const WeakHandle<JsEventHandler>& event_handler) override;
 
   // DirectoryChangeDelegate implementation.
   // This listener is called upon completion of a syncable transaction, and
   // builds the list of sync-engine initiated changes that will be forwarded to
   // the SyncManager's Observers.
-  virtual void HandleTransactionCompleteChangeEvent(
+  void HandleTransactionCompleteChangeEvent(
       ModelTypeSet models_with_changes) override;
-  virtual ModelTypeSet HandleTransactionEndingChangeEvent(
+  ModelTypeSet HandleTransactionEndingChangeEvent(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       syncable::BaseTransaction* trans) override;
-  virtual void HandleCalculateChangesChangeEventFromSyncApi(
+  void HandleCalculateChangesChangeEventFromSyncApi(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       syncable::BaseTransaction* trans,
       std::vector<int64>* entries_changed) override;
-  virtual void HandleCalculateChangesChangeEventFromSyncer(
+  void HandleCalculateChangesChangeEventFromSyncer(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       syncable::BaseTransaction* trans,
       std::vector<int64>* entries_changed) override;
 
   // Handle explicit requests to fetch updates for the given types.
-  virtual void RefreshTypes(ModelTypeSet types) override;
+  void RefreshTypes(ModelTypeSet types) override;
 
   // These OnYYYChanged() methods are only called by our NetworkChangeNotifier.
   // Called when IP address of primary interface changes.
-  virtual void OnIPAddressChanged() override;
+  void OnIPAddressChanged() override;
   // Called when the connection type of the system has changed.
-  virtual void OnConnectionTypeChanged(
+  void OnConnectionTypeChanged(
       net::NetworkChangeNotifier::ConnectionType) override;
 
   // NudgeHandler implementation.
-  virtual void NudgeForInitialDownload(syncer::ModelType type) override;
-  virtual void NudgeForCommit(syncer::ModelType type) override;
-  virtual void NudgeForRefresh(syncer::ModelType type) override;
+  void NudgeForInitialDownload(syncer::ModelType type) override;
+  void NudgeForCommit(syncer::ModelType type) override;
+  void NudgeForRefresh(syncer::ModelType type) override;
 
   const SyncScheduler* scheduler() const;
 
diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc
index a2829a4..0f58bb93 100644
--- a/sync/internal_api/sync_manager_impl_unittest.cc
+++ b/sync/internal_api/sync_manager_impl_unittest.cc
@@ -691,38 +691,33 @@
 
 class TestHttpPostProviderInterface : public HttpPostProviderInterface {
  public:
-  virtual ~TestHttpPostProviderInterface() {}
+  ~TestHttpPostProviderInterface() override {}
 
-  virtual void SetExtraRequestHeaders(const char* headers) override {}
-  virtual void SetURL(const char* url, int port) override {}
-  virtual void SetPostPayload(const char* content_type,
-                              int content_length,
-                              const char* content) override {}
-  virtual bool MakeSynchronousPost(int* error_code, int* response_code)
-      override {
+  void SetExtraRequestHeaders(const char* headers) override {}
+  void SetURL(const char* url, int port) override {}
+  void SetPostPayload(const char* content_type,
+                      int content_length,
+                      const char* content) override {}
+  bool MakeSynchronousPost(int* error_code, int* response_code) override {
     return false;
   }
-  virtual int GetResponseContentLength() const override {
-    return 0;
-  }
-  virtual const char* GetResponseContent() const override {
-    return "";
-  }
-  virtual const std::string GetResponseHeaderValue(
+  int GetResponseContentLength() const override { return 0; }
+  const char* GetResponseContent() const override { return ""; }
+  const std::string GetResponseHeaderValue(
       const std::string& name) const override {
     return std::string();
   }
-  virtual void Abort() override {}
+  void Abort() override {}
 };
 
 class TestHttpPostProviderFactory : public HttpPostProviderFactory {
  public:
-  virtual ~TestHttpPostProviderFactory() {}
-  virtual void Init(const std::string& user_agent) override { }
-  virtual HttpPostProviderInterface* Create() override {
+  ~TestHttpPostProviderFactory() override {}
+  void Init(const std::string& user_agent) override {}
+  HttpPostProviderInterface* Create() override {
     return new TestHttpPostProviderInterface();
   }
-  virtual void Destroy(HttpPostProviderInterface* http) override {
+  void Destroy(HttpPostProviderInterface* http) override {
     delete static_cast<TestHttpPostProviderInterface*>(http);
   }
 };
@@ -2406,9 +2401,9 @@
           switches, InternalComponentsFactory::STORAGE_IN_MEMORY, storage_used),
         scheduler_to_use_(scheduler_to_use),
         session_context_(session_context) {}
-  virtual ~ComponentsFactory() {}
+  ~ComponentsFactory() override {}
 
-  virtual scoped_ptr<SyncScheduler> BuildScheduler(
+  scoped_ptr<SyncScheduler> BuildScheduler(
       const std::string& name,
       sessions::SyncSessionContext* context,
       CancelationSignal* stop_handle) override {
@@ -2424,7 +2419,7 @@
 class SyncManagerTestWithMockScheduler : public SyncManagerTest {
  public:
   SyncManagerTestWithMockScheduler() : scheduler_(NULL) {}
-  virtual InternalComponentsFactory* GetFactory() override {
+  InternalComponentsFactory* GetFactory() override {
     scheduler_ = new MockSyncScheduler();
     return new ComponentsFactory(GetSwitches(), scheduler_, &session_context_,
                                  &storage_used_);
@@ -2811,15 +2806,14 @@
 // ChangeProcessor.
 class SyncManagerChangeProcessingTest : public SyncManagerTest {
  public:
-  virtual void OnChangesApplied(
-      ModelType model_type,
-      int64 model_version,
-      const BaseTransaction* trans,
-      const ImmutableChangeRecordList& changes) override {
+  void OnChangesApplied(ModelType model_type,
+                        int64 model_version,
+                        const BaseTransaction* trans,
+                        const ImmutableChangeRecordList& changes) override {
     last_changes_ = changes;
   }
 
-  virtual void OnChangesComplete(ModelType model_type) override {}
+  void OnChangesComplete(ModelType model_type) override {}
 
   const ImmutableChangeRecordList& GetRecentChangeList() {
     return last_changes_;
@@ -3170,7 +3164,7 @@
   SyncManagerInitInvalidStorageTest() {
   }
 
-  virtual InternalComponentsFactory* GetFactory() override {
+  InternalComponentsFactory* GetFactory() override {
     return new TestInternalComponentsFactory(
         GetSwitches(), InternalComponentsFactory::STORAGE_INVALID,
         &storage_used_);
diff --git a/sync/internal_api/sync_rollback_manager.h b/sync/internal_api/sync_rollback_manager.h
index 4022474..0abcc27 100644
--- a/sync/internal_api/sync_rollback_manager.h
+++ b/sync/internal_api/sync_rollback_manager.h
@@ -19,12 +19,11 @@
 class SYNC_EXPORT_PRIVATE SyncRollbackManager : public SyncRollbackManagerBase {
  public:
   SyncRollbackManager();
-  virtual ~SyncRollbackManager();
+  ~SyncRollbackManager() override;
 
   // SyncManager implementation.
-  virtual void Init(InitArgs* args) override;
-  virtual void StartSyncingNormally(
-      const ModelSafeRoutingInfo& routing_info) override;
+  void Init(InitArgs* args) override;
+  void StartSyncingNormally(const ModelSafeRoutingInfo& routing_info) override;
 
  private:
   // Deletes specified entries in local model.
diff --git a/sync/internal_api/sync_rollback_manager_base.cc b/sync/internal_api/sync_rollback_manager_base.cc
index 2cc6d69..baedec0 100644
--- a/sync/internal_api/sync_rollback_manager_base.cc
+++ b/sync/internal_api/sync_rollback_manager_base.cc
@@ -19,18 +19,15 @@
 const char kOtherBookmarksTag[] = "other_bookmarks";
 
 class DummyEntryptionHandler : public syncer::SyncEncryptionHandler {
-  virtual void AddObserver(Observer* observer) override {}
-  virtual void RemoveObserver(Observer* observer) override {}
-  virtual void Init() override {}
-  virtual void SetEncryptionPassphrase(const std::string& passphrase,
-                                       bool is_explicit) override {}
-  virtual void SetDecryptionPassphrase(const std::string& passphrase)
-      override {}
-  virtual void EnableEncryptEverything() override {}
-  virtual bool EncryptEverythingEnabled() const override {
-    return false;
-  }
-  virtual syncer::PassphraseType GetPassphraseType() const override {
+  void AddObserver(Observer* observer) override {}
+  void RemoveObserver(Observer* observer) override {}
+  void Init() override {}
+  void SetEncryptionPassphrase(const std::string& passphrase,
+                               bool is_explicit) override {}
+  void SetDecryptionPassphrase(const std::string& passphrase) override {}
+  void EnableEncryptEverything() override {}
+  bool EncryptEverythingEnabled() const override { return false; }
+  syncer::PassphraseType GetPassphraseType() const override {
     return syncer::KEYSTORE_PASSPHRASE;
   }
 };
diff --git a/sync/internal_api/sync_rollback_manager_base.h b/sync/internal_api/sync_rollback_manager_base.h
index edae0e3..3fadaf4 100644
--- a/sync/internal_api/sync_rollback_manager_base.h
+++ b/sync/internal_api/sync_rollback_manager_base.h
@@ -33,63 +33,60 @@
     public syncable::TransactionObserver {
  public:
   SyncRollbackManagerBase();
-  virtual ~SyncRollbackManagerBase();
+  ~SyncRollbackManagerBase() override;
 
   // SyncManager implementation.
-  virtual ModelTypeSet InitialSyncEndedTypes() override;
-  virtual ModelTypeSet GetTypesWithEmptyProgressMarkerToken(
+  ModelTypeSet InitialSyncEndedTypes() override;
+  ModelTypeSet GetTypesWithEmptyProgressMarkerToken(
       ModelTypeSet types) override;
-  virtual bool PurgePartiallySyncedTypes() override;
-  virtual void UpdateCredentials(const SyncCredentials& credentials) override;
-  virtual void StartSyncingNormally(const ModelSafeRoutingInfo& routing_info)
-      override;
-  virtual void ConfigureSyncer(
-      ConfigureReason reason,
-      ModelTypeSet to_download,
-      ModelTypeSet to_purge,
-      ModelTypeSet to_journal,
-      ModelTypeSet to_unapply,
-      const ModelSafeRoutingInfo& new_routing_info,
-      const base::Closure& ready_task,
-      const base::Closure& retry_task) override;
-  virtual void SetInvalidatorEnabled(bool invalidator_enabled) override;
-  virtual void OnIncomingInvalidation(
+  bool PurgePartiallySyncedTypes() override;
+  void UpdateCredentials(const SyncCredentials& credentials) override;
+  void StartSyncingNormally(const ModelSafeRoutingInfo& routing_info) override;
+  void ConfigureSyncer(ConfigureReason reason,
+                       ModelTypeSet to_download,
+                       ModelTypeSet to_purge,
+                       ModelTypeSet to_journal,
+                       ModelTypeSet to_unapply,
+                       const ModelSafeRoutingInfo& new_routing_info,
+                       const base::Closure& ready_task,
+                       const base::Closure& retry_task) override;
+  void SetInvalidatorEnabled(bool invalidator_enabled) override;
+  void OnIncomingInvalidation(
       syncer::ModelType type,
       scoped_ptr<InvalidationInterface> invalidation) override;
-  virtual void AddObserver(SyncManager::Observer* observer) override;
-  virtual void RemoveObserver(SyncManager::Observer* observer) override;
-  virtual SyncStatus GetDetailedStatus() const override;
-  virtual void SaveChanges() override;
-  virtual void ShutdownOnSyncThread(ShutdownReason reason) override;
-  virtual UserShare* GetUserShare() override;
-  virtual const std::string cache_guid() override;
-  virtual bool ReceivedExperiment(Experiments* experiments) override;
-  virtual bool HasUnsyncedItems() override;
-  virtual SyncEncryptionHandler* GetEncryptionHandler() override;
-  virtual void RefreshTypes(ModelTypeSet types) override;
-  virtual SyncContextProxy* GetSyncContextProxy() override;
-  virtual ScopedVector<ProtocolEvent> GetBufferedProtocolEvents()
-      override;
-  virtual scoped_ptr<base::ListValue> GetAllNodesForType(
+  void AddObserver(SyncManager::Observer* observer) override;
+  void RemoveObserver(SyncManager::Observer* observer) override;
+  SyncStatus GetDetailedStatus() const override;
+  void SaveChanges() override;
+  void ShutdownOnSyncThread(ShutdownReason reason) override;
+  UserShare* GetUserShare() override;
+  const std::string cache_guid() override;
+  bool ReceivedExperiment(Experiments* experiments) override;
+  bool HasUnsyncedItems() override;
+  SyncEncryptionHandler* GetEncryptionHandler() override;
+  void RefreshTypes(ModelTypeSet types) override;
+  SyncContextProxy* GetSyncContextProxy() override;
+  ScopedVector<ProtocolEvent> GetBufferedProtocolEvents() override;
+  scoped_ptr<base::ListValue> GetAllNodesForType(
       syncer::ModelType type) override;
 
   // DirectoryChangeDelegate implementation.
-  virtual void HandleTransactionCompleteChangeEvent(
+  void HandleTransactionCompleteChangeEvent(
       ModelTypeSet models_with_changes) override;
-  virtual ModelTypeSet HandleTransactionEndingChangeEvent(
+  ModelTypeSet HandleTransactionEndingChangeEvent(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       syncable::BaseTransaction* trans) override;
-  virtual void HandleCalculateChangesChangeEventFromSyncApi(
+  void HandleCalculateChangesChangeEventFromSyncApi(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       syncable::BaseTransaction* trans,
       std::vector<int64>* entries_changed) override;
-  virtual void HandleCalculateChangesChangeEventFromSyncer(
+  void HandleCalculateChangesChangeEventFromSyncer(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       syncable::BaseTransaction* trans,
       std::vector<int64>* entries_changed) override;
 
   // syncable::TransactionObserver implementation.
-  virtual void OnTransactionWrite(
+  void OnTransactionWrite(
       const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
       ModelTypeSet models_with_changes) override;
 
@@ -104,13 +101,13 @@
       scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler,
       ReportUnrecoverableErrorFunction report_unrecoverable_error_function);
 
-  virtual void RegisterDirectoryTypeDebugInfoObserver(
+  void RegisterDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual void UnregisterDirectoryTypeDebugInfoObserver(
+  void UnregisterDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual bool HasDirectoryTypeDebugInfoObserver(
+  bool HasDirectoryTypeDebugInfoObserver(
       syncer::TypeDebugInfoObserver* observer) override;
-  virtual void RequestEmitDebugInfo() override;
+  void RequestEmitDebugInfo() override;
 
   bool initialized() const {
     return initialized_;
diff --git a/sync/internal_api/sync_rollback_manager_base_unittest.cc b/sync/internal_api/sync_rollback_manager_base_unittest.cc
index 8d9def8..2f682ad 100644
--- a/sync/internal_api/sync_rollback_manager_base_unittest.cc
+++ b/sync/internal_api/sync_rollback_manager_base_unittest.cc
@@ -21,7 +21,7 @@
 
 class SyncTestRollbackManager : public SyncRollbackManagerBase {
  public:
-  virtual void Init(InitArgs* args) override {
+  void Init(InitArgs* args) override {
     SyncRollbackManagerBase::InitInternal(
         args->database_location,
         args->internal_components_factory.get(),
diff --git a/sync/internal_api/syncapi_server_connection_manager.h b/sync/internal_api/syncapi_server_connection_manager.h
index 53481cc0..d016aa9 100644
--- a/sync/internal_api/syncapi_server_connection_manager.h
+++ b/sync/internal_api/syncapi_server_connection_manager.h
@@ -25,14 +25,14 @@
   SyncAPIBridgedConnection(ServerConnectionManager* scm,
                            HttpPostProviderFactory* factory);
 
-  virtual ~SyncAPIBridgedConnection();
+  ~SyncAPIBridgedConnection() override;
 
-  virtual bool Init(const char* path,
-                    const std::string& auth_token,
-                    const std::string& payload,
-                    HttpResponse* response) override;
+  bool Init(const char* path,
+            const std::string& auth_token,
+            const std::string& payload,
+            HttpResponse* response) override;
 
-  virtual void Abort() override;
+  void Abort() override;
 
  private:
   // Pointer to the factory we use for creating HttpPostProviders. We do not
@@ -56,10 +56,10 @@
                                  bool use_ssl,
                                  HttpPostProviderFactory* factory,
                                  CancelationSignal* cancelation_signal);
-  virtual ~SyncAPIServerConnectionManager();
+  ~SyncAPIServerConnectionManager() override;
 
   // ServerConnectionManager overrides.
-  virtual Connection* MakeConnection() override;
+  Connection* MakeConnection() override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(SyncAPIServerConnectionManagerTest,
diff --git a/sync/internal_api/syncapi_server_connection_manager_unittest.cc b/sync/internal_api/syncapi_server_connection_manager_unittest.cc
index 5acc6b3..10dc3118 100644
--- a/sync/internal_api/syncapi_server_connection_manager_unittest.cc
+++ b/sync/internal_api/syncapi_server_connection_manager_unittest.cc
@@ -25,44 +25,37 @@
 class BlockingHttpPost : public HttpPostProviderInterface {
  public:
   BlockingHttpPost() : wait_for_abort_(false, false) {}
-  virtual ~BlockingHttpPost() {}
+  ~BlockingHttpPost() override {}
 
-  virtual void SetExtraRequestHeaders(const char* headers) override {}
-  virtual void SetURL(const char* url, int port) override {}
-  virtual void SetPostPayload(const char* content_type,
-                              int content_length,
-                              const char* content) override {}
-  virtual bool MakeSynchronousPost(int* error_code, int* response_code)
-      override {
+  void SetExtraRequestHeaders(const char* headers) override {}
+  void SetURL(const char* url, int port) override {}
+  void SetPostPayload(const char* content_type,
+                      int content_length,
+                      const char* content) override {}
+  bool MakeSynchronousPost(int* error_code, int* response_code) override {
     wait_for_abort_.TimedWait(TestTimeouts::action_max_timeout());
     *error_code = net::ERR_ABORTED;
     return false;
   }
-  virtual int GetResponseContentLength() const override {
-    return 0;
-  }
-  virtual const char* GetResponseContent() const override {
-    return "";
-  }
-  virtual const std::string GetResponseHeaderValue(
+  int GetResponseContentLength() const override { return 0; }
+  const char* GetResponseContent() const override { return ""; }
+  const std::string GetResponseHeaderValue(
       const std::string& name) const override {
     return std::string();
   }
-  virtual void Abort() override {
-    wait_for_abort_.Signal();
-  }
+  void Abort() override { wait_for_abort_.Signal(); }
  private:
   base::WaitableEvent wait_for_abort_;
 };
 
 class BlockingHttpPostFactory : public HttpPostProviderFactory {
  public:
-  virtual ~BlockingHttpPostFactory() {}
-  virtual void Init(const std::string& user_agent) override {}
-  virtual HttpPostProviderInterface* Create() override {
+  ~BlockingHttpPostFactory() override {}
+  void Init(const std::string& user_agent) override {}
+  HttpPostProviderInterface* Create() override {
     return new BlockingHttpPost();
   }
-  virtual void Destroy(HttpPostProviderInterface* http) override {
+  void Destroy(HttpPostProviderInterface* http) override {
     delete static_cast<BlockingHttpPost*>(http);
   }
 };
diff --git a/sync/internal_api/test/sync_manager_for_profile_sync_test.h b/sync/internal_api/test/sync_manager_for_profile_sync_test.h
index 14ab883..c10312d3 100644
--- a/sync/internal_api/test/sync_manager_for_profile_sync_test.h
+++ b/sync/internal_api/test/sync_manager_for_profile_sync_test.h
@@ -20,8 +20,8 @@
  public:
   SyncManagerForProfileSyncTest(std::string name,
                                 base::Closure init_callback);
-  virtual ~SyncManagerForProfileSyncTest();
-  virtual void NotifyInitializationSuccess() override;
+  ~SyncManagerForProfileSyncTest() override;
+  void NotifyInitializationSuccess() override;
 
  private:
   base::Closure init_callback_;
diff --git a/sync/js/sync_js_controller.h b/sync/js/sync_js_controller.h
index 85c4236..57a8aa88 100644
--- a/sync/js/sync_js_controller.h
+++ b/sync/js/sync_js_controller.h
@@ -29,19 +29,19 @@
  public:
   SyncJsController();
 
-  virtual ~SyncJsController();
+  ~SyncJsController() override;
 
   // Sets the backend to route all messages to (if initialized).
   // Sends any queued-up messages if |backend| is initialized.
   void AttachJsBackend(const WeakHandle<JsBackend>& js_backend);
 
   // JsController implementation.
-  virtual void AddJsEventHandler(JsEventHandler* event_handler) override;
-  virtual void RemoveJsEventHandler(JsEventHandler* event_handler) override;
+  void AddJsEventHandler(JsEventHandler* event_handler) override;
+  void RemoveJsEventHandler(JsEventHandler* event_handler) override;
 
   // JsEventHandler implementation.
-  virtual void HandleJsEvent(const std::string& name,
-                             const JsEventDetails& details) override;
+  void HandleJsEvent(const std::string& name,
+                     const JsEventDetails& details) override;
 
  private:
   // Sets |js_backend_|'s event handler depending on how many
diff --git a/sync/sessions/model_type_registry.cc b/sync/sessions/model_type_registry.cc
index 6c5d875..fdc0e40a0 100644
--- a/sync/sessions/model_type_registry.cc
+++ b/sync/sessions/model_type_registry.cc
@@ -26,15 +26,13 @@
   ModelTypeSyncProxyWrapper(
       const base::WeakPtr<ModelTypeSyncProxyImpl>& proxy,
       const scoped_refptr<base::SequencedTaskRunner>& processor_task_runner);
-  virtual ~ModelTypeSyncProxyWrapper();
+  ~ModelTypeSyncProxyWrapper() override;
 
-  virtual void OnCommitCompleted(
-      const DataTypeState& type_state,
-      const CommitResponseDataList& response_list) override;
-  virtual void OnUpdateReceived(
-      const DataTypeState& type_state,
-      const UpdateResponseDataList& response_list,
-      const UpdateResponseDataList& pending_updates) override;
+  void OnCommitCompleted(const DataTypeState& type_state,
+                         const CommitResponseDataList& response_list) override;
+  void OnUpdateReceived(const DataTypeState& type_state,
+                        const UpdateResponseDataList& response_list,
+                        const UpdateResponseDataList& pending_updates) override;
 
  private:
   base::WeakPtr<ModelTypeSyncProxyImpl> processor_;
@@ -79,9 +77,9 @@
   ModelTypeSyncWorkerWrapper(
       const base::WeakPtr<ModelTypeSyncWorkerImpl>& worker,
       const scoped_refptr<base::SequencedTaskRunner>& sync_thread);
-  virtual ~ModelTypeSyncWorkerWrapper();
+  ~ModelTypeSyncWorkerWrapper() override;
 
-  virtual void EnqueueForCommit(const CommitRequestDataList& list) override;
+  void EnqueueForCommit(const CommitRequestDataList& list) override;
 
  private:
   base::WeakPtr<ModelTypeSyncWorkerImpl> worker_;
diff --git a/sync/sessions/model_type_registry.h b/sync/sessions/model_type_registry.h
index c44a3b732..22efdf5 100644
--- a/sync/sessions/model_type_registry.h
+++ b/sync/sessions/model_type_registry.h
@@ -48,7 +48,7 @@
   ModelTypeRegistry(const std::vector<scoped_refptr<ModelSafeWorker> >& workers,
                     syncable::Directory* directory,
                     NudgeHandler* nudge_handler);
-  virtual ~ModelTypeRegistry();
+  ~ModelTypeRegistry() override;
 
   // Sets the set of enabled types.
   void SetEnabledDirectoryTypes(const ModelSafeRoutingInfo& routing_info);
@@ -57,7 +57,7 @@
   // and its task_runner to the newly created worker.
   //
   // Expects that the proxy's ModelType is not currently enabled.
-  virtual void ConnectSyncTypeToWorker(
+  void ConnectSyncTypeToWorker(
       syncer::ModelType type,
       const DataTypeState& data_type_state,
       const syncer::UpdateResponseDataList& saved_pending_updates,
@@ -68,22 +68,21 @@
   //
   // Expects that the type is currently enabled.
   // Deletes the worker associated with the type.
-  virtual void DisconnectSyncWorker(syncer::ModelType type) override;
+  void DisconnectSyncWorker(syncer::ModelType type) override;
 
   // Implementation of SyncEncryptionHandler::Observer.
-  virtual void OnPassphraseRequired(
+  void OnPassphraseRequired(
       PassphraseRequiredReason reason,
       const sync_pb::EncryptedData& pending_keys) override;
-  virtual void OnPassphraseAccepted() override;
-  virtual void OnBootstrapTokenUpdated(const std::string& bootstrap_token,
-                                       BootstrapTokenType type) override;
-  virtual void OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
-                                       bool encrypt_everything) override;
-  virtual void OnEncryptionComplete() override;
-  virtual void OnCryptographerStateChanged(
-      Cryptographer* cryptographer) override;
-  virtual void OnPassphraseTypeChanged(PassphraseType type,
-                                       base::Time passphrase_time) override;
+  void OnPassphraseAccepted() override;
+  void OnBootstrapTokenUpdated(const std::string& bootstrap_token,
+                               BootstrapTokenType type) override;
+  void OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
+                               bool encrypt_everything) override;
+  void OnEncryptionComplete() override;
+  void OnCryptographerStateChanged(Cryptographer* cryptographer) override;
+  void OnPassphraseTypeChanged(PassphraseType type,
+                               base::Time passphrase_time) override;
 
   // Gets the set of enabled types.
   ModelTypeSet GetEnabledTypes() const;
diff --git a/sync/syncable/deferred_on_disk_directory_backing_store.h b/sync/syncable/deferred_on_disk_directory_backing_store.h
index 77a72ff..c697120 100644
--- a/sync/syncable/deferred_on_disk_directory_backing_store.h
+++ b/sync/syncable/deferred_on_disk_directory_backing_store.h
@@ -22,13 +22,11 @@
  public:
   DeferredOnDiskDirectoryBackingStore(const std::string& dir_name,
                                       const base::FilePath& backing_filepath);
-  virtual ~DeferredOnDiskDirectoryBackingStore();
-  virtual DirOpenResult Load(
-      Directory::MetahandlesMap* handles_map,
-      JournalIndex* delete_journals,
-      Directory::KernelLoadInfo* kernel_load_info) override;
-  virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot)
-      override;
+  ~DeferredOnDiskDirectoryBackingStore() override;
+  DirOpenResult Load(Directory::MetahandlesMap* handles_map,
+                     JournalIndex* delete_journals,
+                     Directory::KernelLoadInfo* kernel_load_info) override;
+  bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot) override;
 
  private:
   base::FilePath backing_filepath_;
diff --git a/sync/syncable/directory_backing_store_unittest.cc b/sync/syncable/directory_backing_store_unittest.cc
index 804fa98..9b92e56 100644
--- a/sync/syncable/directory_backing_store_unittest.cc
+++ b/sync/syncable/directory_backing_store_unittest.cc
@@ -3836,11 +3836,11 @@
  public:
   OnDiskDirectoryBackingStoreForTest(const std::string& dir_name,
                                      const base::FilePath& backing_filepath);
-  virtual ~OnDiskDirectoryBackingStoreForTest();
+  ~OnDiskDirectoryBackingStoreForTest() override;
   bool DidFailFirstOpenAttempt();
 
  protected:
-  virtual void ReportFirstTryOpenFailure() override;
+  void ReportFirstTryOpenFailure() override;
 
  private:
   bool first_open_failed_;
diff --git a/sync/syncable/directory_unittest.cc b/sync/syncable/directory_unittest.cc
index 66284cf..6aaf054 100644
--- a/sync/syncable/directory_unittest.cc
+++ b/sync/syncable/directory_unittest.cc
@@ -1534,7 +1534,7 @@
   const int thread_number_;
 
   // PlatformThread::Delegate methods:
-  virtual void ThreadMain() override {
+  void ThreadMain() override {
     int entry_count = 0;
     std::string path_name;
 
diff --git a/sync/syncable/in_memory_directory_backing_store.h b/sync/syncable/in_memory_directory_backing_store.h
index e029c74..0a0f9ba 100644
--- a/sync/syncable/in_memory_directory_backing_store.h
+++ b/sync/syncable/in_memory_directory_backing_store.h
@@ -24,10 +24,9 @@
     : public DirectoryBackingStore {
  public:
   explicit InMemoryDirectoryBackingStore(const std::string& dir_name);
-  virtual DirOpenResult Load(
-      Directory::MetahandlesMap* handles_map,
-      JournalIndex* delete_journals,
-      Directory::KernelLoadInfo* kernel_load_info) override;
+  DirOpenResult Load(Directory::MetahandlesMap* handles_map,
+                     JournalIndex* delete_journals,
+                     Directory::KernelLoadInfo* kernel_load_info) override;
 
   void request_consistent_cache_guid() {
     consistent_cache_guid_requested_ = true;
diff --git a/sync/syncable/invalid_directory_backing_store.h b/sync/syncable/invalid_directory_backing_store.h
index dbd6500..fd99653 100644
--- a/sync/syncable/invalid_directory_backing_store.h
+++ b/sync/syncable/invalid_directory_backing_store.h
@@ -16,11 +16,11 @@
     : public DirectoryBackingStore {
  public:
   InvalidDirectoryBackingStore();
-  virtual ~InvalidDirectoryBackingStore();
-  virtual DirOpenResult Load(
-      Directory::MetahandlesMap* handles_map,
-      JournalIndex* delete_journals,
-      Directory::KernelLoadInfo* kernel_load_info) override;
+  ~InvalidDirectoryBackingStore() override;
+  DirOpenResult Load(Directory::MetahandlesMap* handles_map,
+                     JournalIndex* delete_journals,
+                     Directory::KernelLoadInfo* kernel_load_info) override;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(InvalidDirectoryBackingStore);
 };
diff --git a/sync/syncable/on_disk_directory_backing_store.h b/sync/syncable/on_disk_directory_backing_store.h
index 3a0649d1..fdeda4d 100644
--- a/sync/syncable/on_disk_directory_backing_store.h
+++ b/sync/syncable/on_disk_directory_backing_store.h
@@ -19,11 +19,10 @@
  public:
   OnDiskDirectoryBackingStore(const std::string& dir_name,
                               const base::FilePath& backing_filepath);
-  virtual ~OnDiskDirectoryBackingStore();
-  virtual DirOpenResult Load(
-      Directory::MetahandlesMap* handles_map,
-      JournalIndex* delete_journals,
-      Directory::KernelLoadInfo* kernel_load_info) override;
+  ~OnDiskDirectoryBackingStore() override;
+  DirOpenResult Load(Directory::MetahandlesMap* handles_map,
+                     JournalIndex* delete_journals,
+                     Directory::KernelLoadInfo* kernel_load_info) override;
 
   // A helper function that will make one attempt to load the directory.
   // Unlike Load(), it does not attempt to recover from failure.
diff --git a/sync/syncable/syncable_base_write_transaction.h b/sync/syncable/syncable_base_write_transaction.h
index 8ea91a1..52ccc4f 100644
--- a/sync/syncable/syncable_base_write_transaction.h
+++ b/sync/syncable/syncable_base_write_transaction.h
@@ -23,7 +23,7 @@
       const char* name,
       WriterTag writer,
       Directory* directory);
-  virtual ~BaseWriteTransaction();
+  ~BaseWriteTransaction() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(BaseWriteTransaction);
diff --git a/sync/syncable/syncable_model_neutral_write_transaction.h b/sync/syncable/syncable_model_neutral_write_transaction.h
index 1ec3e93..3caa10ea3 100644
--- a/sync/syncable/syncable_model_neutral_write_transaction.h
+++ b/sync/syncable/syncable_model_neutral_write_transaction.h
@@ -28,9 +28,9 @@
       const tracked_objects::Location& location,
       WriterTag writer,
       Directory* directory);
-  virtual ~ModelNeutralWriteTransaction();
+  ~ModelNeutralWriteTransaction() override;
 
-  virtual void TrackChangesTo(const EntryKernel* entry) override;
+  void TrackChangesTo(const EntryKernel* entry) override;
 
  private:
   MetahandleSet modified_handles_;
diff --git a/sync/syncable/syncable_read_transaction.h b/sync/syncable/syncable_read_transaction.h
index 2b9729d..a13f92f 100644
--- a/sync/syncable/syncable_read_transaction.h
+++ b/sync/syncable/syncable_read_transaction.h
@@ -18,7 +18,7 @@
   ReadTransaction(const tracked_objects::Location& from_here,
                   Directory* directory);
 
-  virtual ~ReadTransaction();
+  ~ReadTransaction() override;
 
  protected:  // Don't allow creation on heap, except by sync API wrapper.
   friend class syncer::ReadTransaction;
diff --git a/sync/syncable/syncable_unittest.cc b/sync/syncable/syncable_unittest.cc
index 7115aa4..570610603 100644
--- a/sync/syncable/syncable_unittest.cc
+++ b/sync/syncable/syncable_unittest.cc
@@ -50,10 +50,9 @@
   TestBackingStore(const std::string& dir_name,
                    const base::FilePath& backing_filepath);
 
-  virtual ~TestBackingStore();
+  ~TestBackingStore() override;
 
-  virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot)
-      override;
+  bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot) override;
 
    void StartFailingSaveChanges() {
      fail_save_changes_ = true;
@@ -90,7 +89,7 @@
       const std::string& dir_name,
       const base::FilePath& backing_filepath);
 
-  virtual ~TestDirectory();
+  ~TestDirectory() override;
 
   void StartFailingSaveChanges() {
     backing_store_->StartFailingSaveChanges();
diff --git a/sync/syncable/syncable_write_transaction.h b/sync/syncable/syncable_write_transaction.h
index f3b7e49..93942c7 100644
--- a/sync/syncable/syncable_write_transaction.h
+++ b/sync/syncable/syncable_write_transaction.h
@@ -28,9 +28,9 @@
   WriteTransaction(const tracked_objects::Location& from_here,
                    Directory* directory, int64* transaction_version);
 
-  virtual ~WriteTransaction();
+  ~WriteTransaction() override;
 
-  virtual void TrackChangesTo(const EntryKernel* entry) override;
+  void TrackChangesTo(const EntryKernel* entry) override;
 
  protected:
   // Overridden by tests.
diff --git a/sync/test/accounts_client/test_accounts_client.cc b/sync/test/accounts_client/test_accounts_client.cc
index 7a5c1e7f..587c45f 100644
--- a/sync/test/accounts_client/test_accounts_client.cc
+++ b/sync/test/accounts_client/test_accounts_client.cc
@@ -39,7 +39,7 @@
   AccountsRequestDelegate(base::RunLoop* run_loop) : response_(""),
       success_(false), run_loop_(run_loop) {}
 
-  virtual void OnURLFetchComplete(const net::URLFetcher* source) override {
+  void OnURLFetchComplete(const net::URLFetcher* source) override {
     string url = source->GetURL().spec();
     source->GetResponseAsString(&response_);
 
diff --git a/sync/test/accounts_client/url_request_context_getter.h b/sync/test/accounts_client/url_request_context_getter.h
index aecf658d..20a3931 100644
--- a/sync/test/accounts_client/url_request_context_getter.h
+++ b/sync/test/accounts_client/url_request_context_getter.h
@@ -25,12 +25,12 @@
       scoped_refptr<base::SingleThreadTaskRunner> network_task_runner);
 
   // Overridden from net::URLRequestContextGetter:
-  virtual net::URLRequestContext* GetURLRequestContext() override;
-  virtual scoped_refptr<base::SingleThreadTaskRunner>
-      GetNetworkTaskRunner() const override;
+  net::URLRequestContext* GetURLRequestContext() override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+      const override;
 
  private:
-  virtual ~URLRequestContextGetter();
+  ~URLRequestContextGetter() override;
 
   scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
 
diff --git a/sync/test/android/javatests/src/org/chromium/sync/test/util/AccountHolder.java b/sync/test/android/javatests/src/org/chromium/sync/test/util/AccountHolder.java
index c22ba42..f8f7f2c 100644
--- a/sync/test/android/javatests/src/org/chromium/sync/test/util/AccountHolder.java
+++ b/sync/test/android/javatests/src/org/chromium/sync/test/util/AccountHolder.java
@@ -34,8 +34,8 @@
         mAccount = account;
         mPassword = password;
         mAuthTokens = authTokens == null ? new HashMap<String, String>() : authTokens;
-        mHasBeenAccepted = hasBeenAccepted == null ?
-                new HashMap<String, Boolean>() : hasBeenAccepted;
+        mHasBeenAccepted = hasBeenAccepted == null
+                ? new HashMap<String, Boolean>() : hasBeenAccepted;
     }
 
     public Account getAccount() {
@@ -55,8 +55,8 @@
     }
 
     public boolean hasBeenAccepted(String authTokenType) {
-        return mAlwaysAccept ||
-                mHasBeenAccepted.containsKey(authTokenType) && mHasBeenAccepted.get(authTokenType);
+        return mAlwaysAccept || mHasBeenAccepted.containsKey(authTokenType)
+                && mHasBeenAccepted.get(authTokenType);
     }
 
     /**
@@ -117,8 +117,8 @@
     }
 
     private Builder copy() {
-        return create().account(mAccount).password(mPassword).authTokens(mAuthTokens).
-                hasBeenAcceptedMap(mHasBeenAccepted).alwaysAccept(mAlwaysAccept);
+        return create().account(mAccount).password(mPassword).authTokens(mAuthTokens)
+                .hasBeenAcceptedMap(mHasBeenAccepted).alwaysAccept(mAlwaysAccept);
     }
 
     public static class Builder {
diff --git a/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java b/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
index 597fb95..3b8e1456 100644
--- a/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
+++ b/sync/test/android/javatests/src/org/chromium/sync/test/util/MockAccountManager.java
@@ -248,8 +248,8 @@
                         }
                     }));
         } else {
-            Log.d(TAG, "getAuthTokenFuture: Account " + ah.getAccount() +
-                    " is asking for permission for " + authTokenType);
+            Log.d(TAG, "getAuthTokenFuture: Account " + ah.getAccount()
+                    + " is asking for permission for " + authTokenType);
             final Intent intent = newGrantCredentialsPermissionIntent(
                     activity != null, account, authTokenType);
             return runTask(mExecutor,
@@ -277,12 +277,12 @@
     private String internalGenerateAndStoreAuthToken(AccountHolder ah, String authTokenType) {
         synchronized (mAccounts) {
             // Some tests register auth tokens with value null, and those should be preserved.
-            if (!ah.hasAuthTokenRegistered(authTokenType) &&
-                    ah.getAuthToken(authTokenType) == null) {
+            if (!ah.hasAuthTokenRegistered(authTokenType)
+                    && ah.getAuthToken(authTokenType) == null) {
                 // No authtoken registered. Need to create one.
                 String authToken = UUID.randomUUID().toString();
-                Log.d(TAG, "Created new auth token for " + ah.getAccount() +
-                        ": autTokenType = " + authTokenType + ", authToken = " + authToken);
+                Log.d(TAG, "Created new auth token for " + ah.getAccount()
+                        + ": autTokenType = " + authTokenType + ", authToken = " + authToken);
                 ah = ah.withAuthToken(authTokenType, authToken);
                 mAccounts.add(ah);
             }
@@ -334,8 +334,8 @@
     private AccountAuthTokenPreparation getPreparedPermission(Account account,
             String authTokenType) {
         for (AccountAuthTokenPreparation accountPrep : mAccountPermissionPreparations) {
-            if (accountPrep.getAccount().equals(account) &&
-                    accountPrep.getAuthTokenType().equals(authTokenType)) {
+            if (accountPrep.getAccount().equals(account)
+                    && accountPrep.getAuthTokenType().equals(authTokenType)) {
                 return accountPrep;
             }
         }
@@ -366,9 +366,9 @@
         }
         if (ai.applicationInfo != mContext.getApplicationInfo() && !ai.exported) {
             throw new IllegalStateException(
-                    "Unable to start " + ai.name + ". " +
-                    "The accounts you added to MockAccountManager may not be " +
-                    "configured correctly.");
+                    "Unable to start " + ai.name + ". "
+                    + "The accounts you added to MockAccountManager may not be "
+                    + "configured correctly.");
         }
 
         Intent intent = new Intent();
@@ -535,11 +535,11 @@
                         waitForActivity(mContext, intent);
                     }
                     if (mAccountAuthTokenPreparation == null) {
-                        throw new IllegalStateException("No account preparation ready for " +
-                                mAccount + ", authTokenType = " + mAuthTokenType +
-                                ". Add a call to either prepareGrantAppPermission(...) or " +
-                                "prepareRevokeAppPermission(...) in your test before asking for " +
-                                "an auth token");
+                        throw new IllegalStateException("No account preparation ready for "
+                                + mAccount + ", authTokenType = " + mAuthTokenType
+                                + ". Add a call to either prepareGrantAppPermission(...) or "
+                                + "prepareRevokeAppPermission(...) in your test before asking for "
+                                + "an auth token");
                     } else {
                         // We have shown the Allow/Deny activity, and it has gone away. We can now
                         // apply the pre-stored permission.
@@ -584,8 +584,8 @@
                 }
             }
         };
-        if (!MockGrantCredentialsPermissionActivity.class.getCanonicalName().
-                equals(intent.getComponent().getClassName())) {
+        if (!MockGrantCredentialsPermissionActivity.class.getCanonicalName()
+                .equals(intent.getComponent().getClassName())) {
             throw new IllegalArgumentException("Can only wait for "
                     + "MockGrantCredentialsPermissionActivity");
         }
@@ -649,11 +649,11 @@
 
         @Override
         public String toString() {
-            return "AccountAuthTokenPreparation{" +
-                    "mAccount=" + mAccount +
-                    ", mAuthTokenType='" + mAuthTokenType + '\'' +
-                    ", mAllowed=" + mAllowed +
-                    '}';
+            return "AccountAuthTokenPreparation{"
+                    + "mAccount=" + mAccount
+                    + ", mAuthTokenType='" + mAuthTokenType + '\''
+                    + ", mAllowed=" + mAllowed
+                    + '}';
         }
     }
 }
diff --git a/sync/test/engine/fake_model_worker.h b/sync/test/engine/fake_model_worker.h
index c85b666c..beb5400 100644
--- a/sync/test/engine/fake_model_worker.h
+++ b/sync/test/engine/fake_model_worker.h
@@ -22,15 +22,14 @@
   explicit FakeModelWorker(ModelSafeGroup group);
 
   // ModelSafeWorker implementation.
-  virtual void RegisterForLoopDestruction() override;
-  virtual ModelSafeGroup GetModelSafeGroup() override;
+  void RegisterForLoopDestruction() override;
+  ModelSafeGroup GetModelSafeGroup() override;
 
  protected:
-  virtual SyncerError DoWorkAndWaitUntilDoneImpl(
-      const WorkCallback& work) override;
+  SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) override;
 
  private:
-  virtual ~FakeModelWorker();
+  ~FakeModelWorker() override;
 
   const ModelSafeGroup group_;
 
diff --git a/sync/test/engine/fake_sync_scheduler.h b/sync/test/engine/fake_sync_scheduler.h
index 3c1f34c..8e44d138 100644
--- a/sync/test/engine/fake_sync_scheduler.h
+++ b/sync/test/engine/fake_sync_scheduler.h
@@ -17,47 +17,42 @@
 class FakeSyncScheduler : public SyncScheduler {
  public:
   FakeSyncScheduler();
-  virtual ~FakeSyncScheduler();
+  ~FakeSyncScheduler() override;
 
-  virtual void Start(Mode mode) override;
-  virtual void Stop() override;
-  virtual void ScheduleLocalNudge(
+  void Start(Mode mode) override;
+  void Stop() override;
+  void ScheduleLocalNudge(
       ModelTypeSet types,
       const tracked_objects::Location& nudge_location) override;
-  virtual void ScheduleLocalRefreshRequest(
+  void ScheduleLocalRefreshRequest(
       ModelTypeSet types,
       const tracked_objects::Location& nudge_location) override;
-  virtual void ScheduleInvalidationNudge(
+  void ScheduleInvalidationNudge(
       syncer::ModelType type,
       scoped_ptr<InvalidationInterface> interface,
       const tracked_objects::Location& nudge_location) override;
-  virtual void ScheduleConfiguration(
-      const ConfigurationParams& params) override;
-  virtual void ScheduleInitialSyncNudge(syncer::ModelType model_type) override;
-  virtual void SetNotificationsEnabled(bool notifications_enabled) override;
+  void ScheduleConfiguration(const ConfigurationParams& params) override;
+  void ScheduleInitialSyncNudge(syncer::ModelType model_type) override;
+  void SetNotificationsEnabled(bool notifications_enabled) override;
 
-  virtual void OnCredentialsUpdated() override;
-  virtual void OnConnectionStatusChange() override;
+  void OnCredentialsUpdated() override;
+  void OnConnectionStatusChange() override;
 
   // SyncSession::Delegate implementation.
-  virtual void OnThrottled(
-      const base::TimeDelta& throttle_duration) override;
-  virtual void OnTypesThrottled(
-      ModelTypeSet types,
-      const base::TimeDelta& throttle_duration) override;
-  virtual bool IsCurrentlyThrottled() override;
-  virtual void OnReceivedShortPollIntervalUpdate(
+  void OnThrottled(const base::TimeDelta& throttle_duration) override;
+  void OnTypesThrottled(ModelTypeSet types,
+                        const base::TimeDelta& throttle_duration) override;
+  bool IsCurrentlyThrottled() override;
+  void OnReceivedShortPollIntervalUpdate(
       const base::TimeDelta& new_interval) override;
-  virtual void OnReceivedLongPollIntervalUpdate(
+  void OnReceivedLongPollIntervalUpdate(
       const base::TimeDelta& new_interval) override;
-  virtual void OnReceivedCustomNudgeDelays(
+  void OnReceivedCustomNudgeDelays(
       const std::map<ModelType, base::TimeDelta>& nudge_delays) override;
-  virtual void OnReceivedClientInvalidationHintBufferSize(int size) override;
-  virtual void OnSyncProtocolError(
-      const SyncProtocolError& error) override;
-  virtual void OnReceivedGuRetryDelay(
-      const base::TimeDelta& delay) override;
-  virtual void OnReceivedMigrationRequest(ModelTypeSet types) override;
+  void OnReceivedClientInvalidationHintBufferSize(int size) override;
+  void OnSyncProtocolError(const SyncProtocolError& error) override;
+  void OnReceivedGuRetryDelay(const base::TimeDelta& delay) override;
+  void OnReceivedMigrationRequest(ModelTypeSet types) override;
 };
 
 }  // namespace syncer
diff --git a/sync/test/engine/injectable_sync_context_proxy.h b/sync/test/engine/injectable_sync_context_proxy.h
index 29bb8c2..3b97820 100644
--- a/sync/test/engine/injectable_sync_context_proxy.h
+++ b/sync/test/engine/injectable_sync_context_proxy.h
@@ -20,16 +20,15 @@
 class InjectableSyncContextProxy : public syncer::SyncContextProxy {
  public:
   explicit InjectableSyncContextProxy(ModelTypeSyncWorker* worker);
-  virtual ~InjectableSyncContextProxy();
+  ~InjectableSyncContextProxy() override;
 
-  virtual void ConnectTypeToSync(
-      syncer::ModelType type,
-      const DataTypeState& data_type_state,
-      const UpdateResponseDataList& pending_updates,
-      const base::WeakPtr<syncer::ModelTypeSyncProxyImpl>& type_sync_proxy)
-      override;
-  virtual void Disconnect(syncer::ModelType type) override;
-  virtual scoped_ptr<SyncContextProxy> Clone() const override;
+  void ConnectTypeToSync(syncer::ModelType type,
+                         const DataTypeState& data_type_state,
+                         const UpdateResponseDataList& pending_updates,
+                         const base::WeakPtr<syncer::ModelTypeSyncProxyImpl>&
+                             type_sync_proxy) override;
+  void Disconnect(syncer::ModelType type) override;
+  scoped_ptr<SyncContextProxy> Clone() const override;
 
   ModelTypeSyncWorker* GetWorker();
 
diff --git a/sync/test/engine/mock_connection_manager.h b/sync/test/engine/mock_connection_manager.h
index 4312080..19e483b4 100644
--- a/sync/test/engine/mock_connection_manager.h
+++ b/sync/test/engine/mock_connection_manager.h
@@ -35,14 +35,13 @@
 
   MockConnectionManager(syncable::Directory*,
                         CancelationSignal* signal);
-  virtual ~MockConnectionManager();
+  ~MockConnectionManager() override;
 
   // Overridden ServerConnectionManager functions.
-  virtual bool PostBufferToPath(
-      PostBufferParams*,
-      const std::string& path,
-      const std::string& auth_token,
-      ScopedServerStatusWatcher* watcher) override;
+  bool PostBufferToPath(PostBufferParams*,
+                        const std::string& path,
+                        const std::string& auth_token,
+                        ScopedServerStatusWatcher* watcher) override;
 
   // Control of commit response.
   // NOTE: Commit callback is invoked only once then reset.
diff --git a/sync/test/engine/mock_model_type_sync_proxy.h b/sync/test/engine/mock_model_type_sync_proxy.h
index fd09927..338a5ae 100644
--- a/sync/test/engine/mock_model_type_sync_proxy.h
+++ b/sync/test/engine/mock_model_type_sync_proxy.h
@@ -28,16 +28,14 @@
 class MockModelTypeSyncProxy : public ModelTypeSyncProxy {
  public:
   MockModelTypeSyncProxy();
-  virtual ~MockModelTypeSyncProxy();
+  ~MockModelTypeSyncProxy() override;
 
   // Implementation of ModelTypeSyncProxy.
-  virtual void OnCommitCompleted(
-      const DataTypeState& type_state,
-      const CommitResponseDataList& response_list) override;
-  virtual void OnUpdateReceived(
-      const DataTypeState& type_state,
-      const UpdateResponseDataList& response_list,
-      const UpdateResponseDataList& pending_updates) override;
+  void OnCommitCompleted(const DataTypeState& type_state,
+                         const CommitResponseDataList& response_list) override;
+  void OnUpdateReceived(const DataTypeState& type_state,
+                        const UpdateResponseDataList& response_list,
+                        const UpdateResponseDataList& pending_updates) override;
 
   // By default, this object behaves as if all messages are processed
   // immediately.  Sometimes it is useful to defer work until later, as might
diff --git a/sync/test/engine/mock_model_type_sync_worker.h b/sync/test/engine/mock_model_type_sync_worker.h
index 2078c84..688cfc3 100644
--- a/sync/test/engine/mock_model_type_sync_worker.h
+++ b/sync/test/engine/mock_model_type_sync_worker.h
@@ -21,10 +21,10 @@
 class MockModelTypeSyncWorker : public ModelTypeSyncWorker {
  public:
   MockModelTypeSyncWorker();
-  virtual ~MockModelTypeSyncWorker();
+  ~MockModelTypeSyncWorker() override;
 
   // Implementation of ModelTypeSyncWorker.
-  virtual void EnqueueForCommit(const CommitRequestDataList& list) override;
+  void EnqueueForCommit(const CommitRequestDataList& list) override;
 
   // Getters to inspect the requests sent to this object.
   size_t GetNumCommitRequestLists() const;
diff --git a/sync/test/engine/mock_nudge_handler.h b/sync/test/engine/mock_nudge_handler.h
index 11f502c..477d2bd2 100644
--- a/sync/test/engine/mock_nudge_handler.h
+++ b/sync/test/engine/mock_nudge_handler.h
@@ -15,11 +15,11 @@
 class MockNudgeHandler : public NudgeHandler {
  public:
   MockNudgeHandler();
-  virtual ~MockNudgeHandler();
+  ~MockNudgeHandler() override;
 
-  virtual void NudgeForInitialDownload(syncer::ModelType type) override;
-  virtual void NudgeForCommit(syncer::ModelType type) override;
-  virtual void NudgeForRefresh(syncer::ModelType type) override;
+  void NudgeForInitialDownload(syncer::ModelType type) override;
+  void NudgeForCommit(syncer::ModelType type) override;
+  void NudgeForRefresh(syncer::ModelType type) override;
 
   int GetNumInitialDownloadNudges() const;
   int GetNumCommitNudges() const;
diff --git a/sync/test/engine/mock_update_handler.h b/sync/test/engine/mock_update_handler.h
index 74393df..6993ab2 100644
--- a/sync/test/engine/mock_update_handler.h
+++ b/sync/test/engine/mock_update_handler.h
@@ -15,20 +15,19 @@
 class MockUpdateHandler : public UpdateHandler {
  public:
   explicit MockUpdateHandler(ModelType type);
-  virtual ~MockUpdateHandler();
+  ~MockUpdateHandler() override;
 
   // UpdateHandler implementation.
-  virtual void GetDownloadProgress(
+  void GetDownloadProgress(
       sync_pb::DataTypeProgressMarker* progress_marker) const override;
-  virtual void GetDataTypeContext(sync_pb::DataTypeContext* context) const
-      override;
-  virtual SyncerError ProcessGetUpdatesResponse(
+  void GetDataTypeContext(sync_pb::DataTypeContext* context) const override;
+  SyncerError ProcessGetUpdatesResponse(
       const sync_pb::DataTypeProgressMarker& progress_marker,
       const sync_pb::DataTypeContext& mutated_context,
       const SyncEntityList& applicable_updates,
       sessions::StatusController* status) override;
-  virtual void ApplyUpdates(sessions::StatusController* status) override;
-  virtual void PassiveApplyUpdates(sessions::StatusController* status) override;
+  void ApplyUpdates(sessions::StatusController* status) override;
+  void PassiveApplyUpdates(sessions::StatusController* status) override;
 
   // Returns the number of times ApplyUpdates() was invoked.
   int GetApplyUpdatesCount();
diff --git a/sync/test/fake_encryptor.h b/sync/test/fake_encryptor.h
index d6071132..a168999 100644
--- a/sync/test/fake_encryptor.h
+++ b/sync/test/fake_encryptor.h
@@ -14,13 +14,13 @@
 // ciphertext.  Obviously, this should be used only for testing.
 class FakeEncryptor : public Encryptor {
  public:
-  virtual ~FakeEncryptor();
+  ~FakeEncryptor() override;
 
-  virtual bool EncryptString(const std::string& plaintext,
-                             std::string* ciphertext) override;
+  bool EncryptString(const std::string& plaintext,
+                     std::string* ciphertext) override;
 
-  virtual bool DecryptString(const std::string& ciphertext,
-                             std::string* plaintext) override;
+  bool DecryptString(const std::string& ciphertext,
+                     std::string* plaintext) override;
 };
 
 }  // namespace syncer
diff --git a/sync/test/fake_server/bookmark_entity.h b/sync/test/fake_server/bookmark_entity.h
index 6161d165..5cbbdb2 100644
--- a/sync/test/fake_server/bookmark_entity.h
+++ b/sync/test/fake_server/bookmark_entity.h
@@ -19,7 +19,7 @@
 // are non-deleted, client-created, and not unique per client account.
 class BookmarkEntity : public FakeServerEntity {
  public:
-  virtual ~BookmarkEntity();
+  ~BookmarkEntity() override;
 
   // Factory function for BookmarkEntity. This factory should be used only for
   // the first time that a specific bookmark is seen by the server.
@@ -49,10 +49,10 @@
                  int64 last_modified_time);
 
   // FakeServerEntity implementation.
-  virtual std::string GetParentId() const override;
-  virtual void SerializeAsProto(sync_pb::SyncEntity* proto) override;
-  virtual bool IsDeleted() const override;
-  virtual bool IsFolder() const override;
+  std::string GetParentId() const override;
+  void SerializeAsProto(sync_pb::SyncEntity* proto) override;
+  bool IsDeleted() const override;
+  bool IsFolder() const override;
 
  private:
   // All member values have equivalent fields in SyncEntity.
diff --git a/sync/test/fake_server/bookmark_entity_builder.h b/sync/test/fake_server/bookmark_entity_builder.h
index ebf66ff..62c7169 100644
--- a/sync/test/fake_server/bookmark_entity_builder.h
+++ b/sync/test/fake_server/bookmark_entity_builder.h
@@ -23,10 +23,10 @@
                         const std::string& originator_cache_guid,
                         const std::string& originator_client_item_id);
 
-  virtual ~BookmarkEntityBuilder();
+  ~BookmarkEntityBuilder() override;
 
   // EntityBuilder
-  virtual scoped_ptr<FakeServerEntity> Build() override;
+  scoped_ptr<FakeServerEntity> Build() override;
 
  private:
   // The bookmark's URL.
diff --git a/sync/test/fake_server/fake_server_http_post_provider.h b/sync/test/fake_server/fake_server_http_post_provider.h
index 53117c28..50d23178 100644
--- a/sync/test/fake_server/fake_server_http_post_provider.h
+++ b/sync/test/fake_server/fake_server_http_post_provider.h
@@ -26,21 +26,21 @@
       scoped_refptr<base::SequencedTaskRunner> task_runner);
 
   // HttpPostProviderInterface implementation.
-  virtual void SetExtraRequestHeaders(const char* headers) override;
-  virtual void SetURL(const char* url, int port) override;
-  virtual void SetPostPayload(const char* content_type, int content_length,
-                              const char* content) override;
-  virtual bool MakeSynchronousPost(int* error_code,
-                                   int* response_code) override;
-  virtual void Abort() override;
-  virtual int GetResponseContentLength() const override;
-  virtual const char* GetResponseContent() const override;
-  virtual const std::string GetResponseHeaderValue(
+  void SetExtraRequestHeaders(const char* headers) override;
+  void SetURL(const char* url, int port) override;
+  void SetPostPayload(const char* content_type,
+                      int content_length,
+                      const char* content) override;
+  bool MakeSynchronousPost(int* error_code, int* response_code) override;
+  void Abort() override;
+  int GetResponseContentLength() const override;
+  const char* GetResponseContent() const override;
+  const std::string GetResponseHeaderValue(
       const std::string& name) const override;
 
  protected:
   friend class base::RefCountedThreadSafe<FakeServerHttpPostProvider>;
-  virtual ~FakeServerHttpPostProvider();
+  ~FakeServerHttpPostProvider() override;
 
  private:
   void OnPostComplete(int error_code,
@@ -69,12 +69,12 @@
   FakeServerHttpPostProviderFactory(
       FakeServer* fake_server,
       scoped_refptr<base::SequencedTaskRunner> task_runner);
-  virtual ~FakeServerHttpPostProviderFactory();
+  ~FakeServerHttpPostProviderFactory() override;
 
   // HttpPostProviderFactory:
-  virtual void Init(const std::string& user_agent) override;
-  virtual syncer::HttpPostProviderInterface* Create() override;
-  virtual void Destroy(syncer::HttpPostProviderInterface* http) override;
+  void Init(const std::string& user_agent) override;
+  syncer::HttpPostProviderInterface* Create() override;
+  void Destroy(syncer::HttpPostProviderInterface* http) override;
 
  private:
   FakeServer* const fake_server_;
diff --git a/sync/test/fake_server/fake_server_network_resources.h b/sync/test/fake_server/fake_server_network_resources.h
index a34d7bd..f6e1fe3 100644
--- a/sync/test/fake_server/fake_server_network_resources.h
+++ b/sync/test/fake_server/fake_server_network_resources.h
@@ -21,15 +21,14 @@
 class FakeServerNetworkResources : public syncer::NetworkResources {
  public:
   explicit FakeServerNetworkResources(FakeServer* fake_server);
-  virtual ~FakeServerNetworkResources();
+  ~FakeServerNetworkResources() override;
 
   // NetworkResources
-  virtual scoped_ptr<syncer::HttpPostProviderFactory>
-      GetHttpPostProviderFactory(
-          const scoped_refptr<net::URLRequestContextGetter>&
-              baseline_context_getter,
-          const syncer::NetworkTimeUpdateCallback& network_time_update_callback,
-          syncer::CancelationSignal* cancelation_signal) override;
+  scoped_ptr<syncer::HttpPostProviderFactory> GetHttpPostProviderFactory(
+      const scoped_refptr<net::URLRequestContextGetter>&
+          baseline_context_getter,
+      const syncer::NetworkTimeUpdateCallback& network_time_update_callback,
+      syncer::CancelationSignal* cancelation_signal) override;
 
  private:
   FakeServer* const fake_server_;
diff --git a/sync/test/fake_server/permanent_entity.h b/sync/test/fake_server/permanent_entity.h
index 210e396..253d70f 100644
--- a/sync/test/fake_server/permanent_entity.h
+++ b/sync/test/fake_server/permanent_entity.h
@@ -17,7 +17,7 @@
 // A server-created, permanent entity.
 class PermanentEntity : public FakeServerEntity {
  public:
-  virtual ~PermanentEntity();
+  ~PermanentEntity() override;
 
   // Factory function for PermanentEntity. |server_tag| should be a globally
   // unique identifier.
@@ -37,10 +37,10 @@
       FakeServerEntity* current_server_entity);
 
   // FakeServerEntity implementation.
-  virtual std::string GetParentId() const override;
-  virtual void SerializeAsProto(sync_pb::SyncEntity* proto) override;
-  virtual bool IsDeleted() const override;
-  virtual bool IsFolder() const override;
+  std::string GetParentId() const override;
+  void SerializeAsProto(sync_pb::SyncEntity* proto) override;
+  bool IsDeleted() const override;
+  bool IsFolder() const override;
 
  private:
   PermanentEntity(const std::string& id,
diff --git a/sync/test/fake_server/tombstone_entity.h b/sync/test/fake_server/tombstone_entity.h
index e7f86db..1f4986f 100644
--- a/sync/test/fake_server/tombstone_entity.h
+++ b/sync/test/fake_server/tombstone_entity.h
@@ -17,16 +17,16 @@
 // A Sync entity that represents a deleted item.
 class TombstoneEntity : public FakeServerEntity {
  public:
-  virtual ~TombstoneEntity();
+  ~TombstoneEntity() override;
 
   // Factory function for TombstoneEntity.
   static FakeServerEntity* Create(const std::string& id);
 
   // FakeServerEntity implementation.
-  virtual std::string GetParentId() const override;
-  virtual void SerializeAsProto(sync_pb::SyncEntity* proto) override;
-  virtual bool IsDeleted() const override;
-  virtual bool IsFolder() const override;
+  std::string GetParentId() const override;
+  void SerializeAsProto(sync_pb::SyncEntity* proto) override;
+  bool IsDeleted() const override;
+  bool IsFolder() const override;
 
  private:
   TombstoneEntity(const std::string& id, const syncer::ModelType& model_type);
diff --git a/sync/test/fake_server/unique_client_entity.h b/sync/test/fake_server/unique_client_entity.h
index 3d3f149c..9805ed8 100644
--- a/sync/test/fake_server/unique_client_entity.h
+++ b/sync/test/fake_server/unique_client_entity.h
@@ -17,7 +17,7 @@
 // An entity that is unique per client account.
 class UniqueClientEntity : public FakeServerEntity {
  public:
-  virtual ~UniqueClientEntity();
+  ~UniqueClientEntity() override;
 
   // Factory function for creating a UniqueClientEntity.
   static FakeServerEntity* Create(const sync_pb::SyncEntity& client_entity);
@@ -27,10 +27,10 @@
       const sync_pb::SyncEntity& entity);
 
   // FakeServerEntity implementation.
-  virtual std::string GetParentId() const override;
-  virtual void SerializeAsProto(sync_pb::SyncEntity* proto) override;
-  virtual bool IsDeleted() const override;
-  virtual bool IsFolder() const override;
+  std::string GetParentId() const override;
+  void SerializeAsProto(sync_pb::SyncEntity* proto) override;
+  bool IsDeleted() const override;
+  bool IsFolder() const override;
 
  private:
   UniqueClientEntity(const std::string& id,
diff --git a/sync/test/fake_sync_encryption_handler.h b/sync/test/fake_sync_encryption_handler.h
index df4c7704..c3180a684 100644
--- a/sync/test/fake_sync_encryption_handler.h
+++ b/sync/test/fake_sync_encryption_handler.h
@@ -26,32 +26,30 @@
                                   public syncable::NigoriHandler {
  public:
   FakeSyncEncryptionHandler();
-  virtual ~FakeSyncEncryptionHandler();
+  ~FakeSyncEncryptionHandler() override;
 
   // SyncEncryptionHandler implementation.
-  virtual void AddObserver(Observer* observer) override;
-  virtual void RemoveObserver(Observer* observer) override;
-  virtual void Init() override;
-  virtual void SetEncryptionPassphrase(const std::string& passphrase,
-                                       bool is_explicit) override;
-  virtual void SetDecryptionPassphrase(const std::string& passphrase) override;
-  virtual void EnableEncryptEverything() override;
-  virtual bool EncryptEverythingEnabled() const override;
-  virtual PassphraseType GetPassphraseType() const override;
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
+  void Init() override;
+  void SetEncryptionPassphrase(const std::string& passphrase,
+                               bool is_explicit) override;
+  void SetDecryptionPassphrase(const std::string& passphrase) override;
+  void EnableEncryptEverything() override;
+  bool EncryptEverythingEnabled() const override;
+  PassphraseType GetPassphraseType() const override;
 
   // NigoriHandler implemenation.
-  virtual void ApplyNigoriUpdate(
-      const sync_pb::NigoriSpecifics& nigori,
-      syncable::BaseTransaction* const trans) override;
-  virtual void UpdateNigoriFromEncryptedTypes(
+  void ApplyNigoriUpdate(const sync_pb::NigoriSpecifics& nigori,
+                         syncable::BaseTransaction* const trans) override;
+  void UpdateNigoriFromEncryptedTypes(
       sync_pb::NigoriSpecifics* nigori,
       syncable::BaseTransaction* const trans) const override;
-  virtual bool NeedKeystoreKey(
-      syncable::BaseTransaction* const trans) const override;
-  virtual bool SetKeystoreKeys(
+  bool NeedKeystoreKey(syncable::BaseTransaction* const trans) const override;
+  bool SetKeystoreKeys(
       const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys,
       syncable::BaseTransaction* const trans) override;
-  virtual ModelTypeSet GetEncryptedTypes(
+  ModelTypeSet GetEncryptedTypes(
       syncable::BaseTransaction* const trans) const override;
 
   Cryptographer* cryptographer() { return &cryptographer_; }
diff --git a/sync/test/local_sync_test_server.h b/sync/test/local_sync_test_server.h
index 4b29476..4c3c01f8 100644
--- a/sync/test/local_sync_test_server.h
+++ b/sync/test/local_sync_test_server.h
@@ -23,14 +23,12 @@
   // |xmpp_port| for p2p notifications.
   LocalSyncTestServer(uint16 port, uint16 xmpp_port);
 
-  virtual ~LocalSyncTestServer();
+  ~LocalSyncTestServer() override;
 
   // Overriden from net::LocalTestServer.
-  virtual bool AddCommandLineArguments(
-      base::CommandLine* command_line) const override;
-  virtual bool SetPythonPath() const override;
-  virtual bool GetTestServerPath(
-      base::FilePath* testserver_path) const override;
+  bool AddCommandLineArguments(base::CommandLine* command_line) const override;
+  bool SetPythonPath() const override;
+  bool GetTestServerPath(base::FilePath* testserver_path) const override;
 
   // Returns true if the path to |test_script_name| is successfully stored  in
   // |*test_script_path|. Used by the run_sync_testserver executable.
diff --git a/sync/test/mock_invalidation.h b/sync/test/mock_invalidation.h
index a499781..65d1bcef 100644
--- a/sync/test/mock_invalidation.h
+++ b/sync/test/mock_invalidation.h
@@ -19,14 +19,14 @@
   static scoped_ptr<MockInvalidation> Build(int64 version,
                                             const std::string& payload);
 
-  virtual ~MockInvalidation();
+  ~MockInvalidation() override;
 
   // Implementation of InvalidationInterface.
-  virtual bool IsUnknownVersion() const override;
-  virtual const std::string& GetPayload() const override;
-  virtual int64 GetVersion() const override;
-  virtual void Acknowledge() override;
-  virtual void Drop() override;
+  bool IsUnknownVersion() const override;
+  const std::string& GetPayload() const override;
+  int64 GetVersion() const override;
+  void Acknowledge() override;
+  void Drop() override;
 
  protected:
   MockInvalidation(bool is_unknown_version,
diff --git a/sync/test/null_directory_change_delegate.h b/sync/test/null_directory_change_delegate.h
index c55b27e..a37e6708 100644
--- a/sync/test/null_directory_change_delegate.h
+++ b/sync/test/null_directory_change_delegate.h
@@ -14,20 +14,20 @@
 // DirectoryChangeDelegate that does nothing in all delegate methods.
 class NullDirectoryChangeDelegate : public DirectoryChangeDelegate {
  public:
-  virtual ~NullDirectoryChangeDelegate();
+  ~NullDirectoryChangeDelegate() override;
 
-  virtual void HandleCalculateChangesChangeEventFromSyncApi(
+  void HandleCalculateChangesChangeEventFromSyncApi(
       const ImmutableWriteTransactionInfo& write_transaction_info,
       BaseTransaction* trans,
       std::vector<int64>* entries_changed) override;
-  virtual void HandleCalculateChangesChangeEventFromSyncer(
+  void HandleCalculateChangesChangeEventFromSyncer(
       const ImmutableWriteTransactionInfo& write_transaction_info,
       BaseTransaction* trans,
       std::vector<int64>* entries_changed) override;
-  virtual ModelTypeSet HandleTransactionEndingChangeEvent(
+  ModelTypeSet HandleTransactionEndingChangeEvent(
       const ImmutableWriteTransactionInfo& write_transaction_info,
       BaseTransaction* trans) override;
-  virtual void HandleTransactionCompleteChangeEvent(
+  void HandleTransactionCompleteChangeEvent(
       ModelTypeSet models_with_changes) override;
 };
 
diff --git a/sync/test/sessions/mock_debug_info_getter.h b/sync/test/sessions/mock_debug_info_getter.h
index c0f8025..1ca833e5 100644
--- a/sync/test/sessions/mock_debug_info_getter.h
+++ b/sync/test/sessions/mock_debug_info_getter.h
@@ -19,11 +19,11 @@
 class MockDebugInfoGetter : public sessions::DebugInfoGetter {
  public:
   MockDebugInfoGetter();
-  virtual ~MockDebugInfoGetter();
+  ~MockDebugInfoGetter() override;
 
   // DebugInfoGetter implementation.
-  virtual void GetDebugInfo(sync_pb::DebugInfo* debug_info) override;
-  virtual void ClearDebugInfo() override;
+  void GetDebugInfo(sync_pb::DebugInfo* debug_info) override;
+  void ClearDebugInfo() override;
 
   void AddDebugEvent();
 
diff --git a/sync/test/test_directory_backing_store.h b/sync/test/test_directory_backing_store.h
index d26bf8d..541528e 100644
--- a/sync/test/test_directory_backing_store.h
+++ b/sync/test/test_directory_backing_store.h
@@ -24,11 +24,10 @@
   // DirectoryBackingStore's internals.
   TestDirectoryBackingStore(const std::string& dir_name,
                             sql::Connection* connection);
-  virtual ~TestDirectoryBackingStore();
-  virtual DirOpenResult Load(
-      Directory::MetahandlesMap* handles_map,
-      JournalIndex* delete_journals,
-      Directory::KernelLoadInfo* kernel_load_info) override;
+  ~TestDirectoryBackingStore() override;
+  DirOpenResult Load(Directory::MetahandlesMap* handles_map,
+                     JournalIndex* delete_journals,
+                     Directory::KernelLoadInfo* kernel_load_info) override;
 
   FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion67To68);
   FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion68To69);
diff --git a/sync/test/test_transaction_observer.h b/sync/test/test_transaction_observer.h
index 7b78560..b341d1e 100644
--- a/sync/test/test_transaction_observer.h
+++ b/sync/test/test_transaction_observer.h
@@ -20,8 +20,8 @@
   public TransactionObserver {
  public:
   TestTransactionObserver();
-  virtual ~TestTransactionObserver();
-  virtual void OnTransactionWrite(
+  ~TestTransactionObserver() override;
+  void OnTransactionWrite(
       const ImmutableWriteTransactionInfo& write_transaction_info,
       ModelTypeSet models_with_changes) override;
 
diff --git a/sync/test/trackable_mock_invalidation.h b/sync/test/trackable_mock_invalidation.h
index 5687866..758ff08 100644
--- a/sync/test/trackable_mock_invalidation.h
+++ b/sync/test/trackable_mock_invalidation.h
@@ -22,14 +22,14 @@
                             const std::string& payload,
                             MockInvalidationTracker* tracker,
                             int tracking_id);
-  virtual ~TrackableMockInvalidation();
+  ~TrackableMockInvalidation() override;
 
   // Forwards notice of the acknowledgement of this invalidation to the
   // |tracker_|.
-  virtual void Acknowledge() override;
+  void Acknowledge() override;
 
   // Forwards notice of the drop of this invalidation to the |tracker_|.
-  virtual void Drop() override;
+  void Drop() override;
 
   // Returns the integer used to identify this object with the |tracker_|.
   int GetTrackingId();
diff --git a/sync/tools/null_invalidation_state_tracker.h b/sync/tools/null_invalidation_state_tracker.h
index 5f61426..19c1b2e 100644
--- a/sync/tools/null_invalidation_state_tracker.h
+++ b/sync/tools/null_invalidation_state_tracker.h
@@ -16,19 +16,18 @@
       public InvalidationStateTracker {
  public:
   NullInvalidationStateTracker();
-  virtual ~NullInvalidationStateTracker();
+  ~NullInvalidationStateTracker() override;
 
-  virtual void ClearAndSetNewClientId(const std::string& data) override;
-  virtual std::string GetInvalidatorClientId() const override;
+  void ClearAndSetNewClientId(const std::string& data) override;
+  std::string GetInvalidatorClientId() const override;
 
-  virtual std::string GetBootstrapData() const override;
-  virtual void SetBootstrapData(const std::string& data) override;
+  std::string GetBootstrapData() const override;
+  void SetBootstrapData(const std::string& data) override;
 
-  virtual void SetSavedInvalidations(
-      const UnackedInvalidationsMap& states) override;
-  virtual UnackedInvalidationsMap GetSavedInvalidations() const override;
+  void SetSavedInvalidations(const UnackedInvalidationsMap& states) override;
+  UnackedInvalidationsMap GetSavedInvalidations() const override;
 
-  virtual void Clear() override;
+  void Clear() override;
 };
 
 }  // namespace syncer
diff --git a/sync/tools/sync_client.cc b/sync/tools/sync_client.cc
index 26a6c71..d8da0d8 100644
--- a/sync/tools/sync_client.cc
+++ b/sync/tools/sync_client.cc
@@ -79,7 +79,7 @@
     Init();
   }
 
-  virtual ~MyTestURLRequestContext() {}
+  ~MyTestURLRequestContext() override {}
 };
 
 class MyTestURLRequestContextGetter : public net::TestURLRequestContextGetter {
@@ -88,7 +88,7 @@
       const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
       : TestURLRequestContextGetter(io_task_runner) {}
 
-  virtual net::TestURLRequestContext* GetURLRequestContext() override {
+  net::TestURLRequestContext* GetURLRequestContext() override {
     // Construct |context_| lazily so it gets constructed on the right
     // thread (the IO thread).
     if (!context_)
@@ -97,7 +97,7 @@
   }
 
  private:
-  virtual ~MyTestURLRequestContextGetter() {}
+  ~MyTestURLRequestContextGetter() override {}
 
   scoped_ptr<MyTestURLRequestContext> context_;
 };
@@ -105,16 +105,16 @@
 // TODO(akalin): Use system encryptor once it's moved to sync/.
 class NullEncryptor : public Encryptor {
  public:
-  virtual ~NullEncryptor() {}
+  ~NullEncryptor() override {}
 
-  virtual bool EncryptString(const std::string& plaintext,
-                             std::string* ciphertext) override {
+  bool EncryptString(const std::string& plaintext,
+                     std::string* ciphertext) override {
     *ciphertext = plaintext;
     return true;
   }
 
-  virtual bool DecryptString(const std::string& ciphertext,
-                             std::string* plaintext) override {
+  bool DecryptString(const std::string& ciphertext,
+                     std::string* plaintext) override {
     *plaintext = ciphertext;
     return true;
   }
@@ -128,13 +128,12 @@
 
 class LoggingChangeDelegate : public SyncManager::ChangeDelegate {
  public:
-  virtual ~LoggingChangeDelegate() {}
+  ~LoggingChangeDelegate() override {}
 
-  virtual void OnChangesApplied(
-      ModelType model_type,
-      int64 model_version,
-      const BaseTransaction* trans,
-      const ImmutableChangeRecordList& changes) override {
+  void OnChangesApplied(ModelType model_type,
+                        int64 model_version,
+                        const BaseTransaction* trans,
+                        const ImmutableChangeRecordList& changes) override {
     LOG(INFO) << "Changes applied for "
               << ModelTypeToString(model_type);
     size_t i = 1;
@@ -154,7 +153,7 @@
     }
   }
 
-  virtual void OnChangesComplete(ModelType model_type) override {
+  void OnChangesComplete(ModelType model_type) override {
     LOG(INFO) << "Changes complete for "
               << ModelTypeToString(model_type);
   }
@@ -163,10 +162,10 @@
 class LoggingUnrecoverableErrorHandler
     : public UnrecoverableErrorHandler {
  public:
-  virtual ~LoggingUnrecoverableErrorHandler() {}
+  ~LoggingUnrecoverableErrorHandler() override {}
 
-  virtual void OnUnrecoverableError(const tracked_objects::Location& from_here,
-                                    const std::string& message) override {
+  void OnUnrecoverableError(const tracked_objects::Location& from_here,
+                            const std::string& message) override {
     if (LOG_IS_ON(ERROR)) {
       logging::LogMessage(from_here.file_name(), from_here.line_number(),
                           logging::LOG_ERROR).stream()
@@ -179,11 +178,10 @@
     : public JsEventHandler,
       public base::SupportsWeakPtr<LoggingJsEventHandler> {
  public:
-  virtual ~LoggingJsEventHandler() {}
+  ~LoggingJsEventHandler() override {}
 
-  virtual void HandleJsEvent(
-      const std::string& name,
-      const JsEventDetails& details) override {
+  void HandleJsEvent(const std::string& name,
+                     const JsEventDetails& details) override {
     VLOG(1) << name << ": " << details.ToString();
   }
 };
@@ -192,27 +190,21 @@
  public:
   explicit InvalidationAdapter(const syncer::Invalidation& invalidation)
       : invalidation_(invalidation) {}
-  virtual ~InvalidationAdapter() {}
+  ~InvalidationAdapter() override {}
 
-  virtual bool IsUnknownVersion() const override {
+  bool IsUnknownVersion() const override {
     return invalidation_.is_unknown_version();
   }
 
-  virtual const std::string& GetPayload() const override {
+  const std::string& GetPayload() const override {
     return invalidation_.payload();
   }
 
-  virtual int64 GetVersion() const override {
-    return invalidation_.version();
-  }
+  int64 GetVersion() const override { return invalidation_.version(); }
 
-  virtual void Acknowledge() override {
-    invalidation_.Acknowledge();
-  }
+  void Acknowledge() override { invalidation_.Acknowledge(); }
 
-  virtual void Drop() override {
-    invalidation_.Drop();
-  }
+  void Drop() override { invalidation_.Drop(); }
 
  private:
   syncer::Invalidation invalidation_;
@@ -223,11 +215,11 @@
   explicit InvalidatorShim(SyncManager* sync_manager)
       : sync_manager_(sync_manager) {}
 
-  virtual void OnInvalidatorStateChange(InvalidatorState state) override {
+  void OnInvalidatorStateChange(InvalidatorState state) override {
     sync_manager_->SetInvalidatorEnabled(state == INVALIDATIONS_ENABLED);
   }
 
-  virtual void OnIncomingInvalidation(
+  void OnIncomingInvalidation(
       const ObjectIdInvalidationMap& invalidation_map) override {
     syncer::ObjectIdSet ids = invalidation_map.GetObjectIds();
     for (syncer::ObjectIdSet::const_iterator ids_it = ids.begin();
@@ -252,9 +244,7 @@
     }
   }
 
-  virtual std::string GetOwnerName() const override {
-    return "InvalidatorShim";
-  }
+  std::string GetOwnerName() const override { return "InvalidatorShim"; }
 
  private:
   SyncManager* sync_manager_;
diff --git a/sync/tools/sync_listen_notifications.cc b/sync/tools/sync_listen_notifications.cc
index 50040c09..3fa5a33a 100644
--- a/sync/tools/sync_listen_notifications.cc
+++ b/sync/tools/sync_listen_notifications.cc
@@ -52,14 +52,14 @@
 class NotificationPrinter : public InvalidationHandler {
  public:
   NotificationPrinter() {}
-  virtual ~NotificationPrinter() {}
+  ~NotificationPrinter() override {}
 
-  virtual void OnInvalidatorStateChange(InvalidatorState state) override {
+  void OnInvalidatorStateChange(InvalidatorState state) override {
     LOG(INFO) << "Invalidator state changed to "
               << InvalidatorStateToString(state);
   }
 
-  virtual void OnIncomingInvalidation(
+  void OnIncomingInvalidation(
       const ObjectIdInvalidationMap& invalidation_map) override {
     ObjectIdSet ids = invalidation_map.GetObjectIds();
     for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
@@ -68,9 +68,7 @@
     }
   }
 
-  virtual std::string GetOwnerName() const override {
-    return "NotificationPrinter";
-  }
+  std::string GetOwnerName() const override { return "NotificationPrinter"; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(NotificationPrinter);
@@ -87,7 +85,7 @@
     Init();
   }
 
-  virtual ~MyTestURLRequestContext() {}
+  ~MyTestURLRequestContext() override {}
 };
 
 class MyTestURLRequestContextGetter : public net::TestURLRequestContextGetter {
@@ -96,7 +94,7 @@
       const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
       : TestURLRequestContextGetter(io_task_runner) {}
 
-  virtual net::TestURLRequestContext* GetURLRequestContext() override {
+  net::TestURLRequestContext* GetURLRequestContext() override {
     // Construct |context_| lazily so it gets constructed on the right
     // thread (the IO thread).
     if (!context_)
@@ -105,7 +103,7 @@
   }
 
  private:
-  virtual ~MyTestURLRequestContextGetter() {}
+  ~MyTestURLRequestContextGetter() override {}
 
   scoped_ptr<MyTestURLRequestContext> context_;
 };
diff --git a/sync/util/test_unrecoverable_error_handler.h b/sync/util/test_unrecoverable_error_handler.h
index c880ffd..ae0610c 100644
--- a/sync/util/test_unrecoverable_error_handler.h
+++ b/sync/util/test_unrecoverable_error_handler.h
@@ -15,10 +15,10 @@
 class TestUnrecoverableErrorHandler : public UnrecoverableErrorHandler {
  public:
   TestUnrecoverableErrorHandler();
-  virtual ~TestUnrecoverableErrorHandler();
+  ~TestUnrecoverableErrorHandler() override;
 
-  virtual void OnUnrecoverableError(const tracked_objects::Location& from_here,
-                                    const std::string& message) override;
+  void OnUnrecoverableError(const tracked_objects::Location& from_here,
+                            const std::string& message) override;
 };
 
 }  // namespace syncer
diff --git a/testing/android/java/AndroidManifest.xml b/testing/android/java/AndroidManifest.xml
index 97d916b..c704cc4 100644
--- a/testing/android/java/AndroidManifest.xml
+++ b/testing/android/java/AndroidManifest.xml
@@ -10,7 +10,7 @@
       android:versionCode="1"
       android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="20" />
+    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
 
     <application android:label="ChromeNativeTests"
             android:name="org.chromium.base.BaseChromiumApplication">
diff --git a/testing/android/junit/BUILD.gn b/testing/android/junit/BUILD.gn
new file mode 100644
index 0000000..bd8b517
--- /dev/null
+++ b/testing/android/junit/BUILD.gn
@@ -0,0 +1,27 @@
+# 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.
+
+assert(is_android)
+
+import("//build/config/android/rules.gni")
+
+# TODO(GYP): should be java_library
+# GYP: //testing/android/junit_test.gyp:junit_test_support
+android_library("junit_test_support") {
+  DEPRECATED_java_in_dir = "java/src"
+  deps = [
+    "//third_party/junit"
+  ]
+}
+
+# TODO(GYP): should be java_library
+# GYP: //testing/android/junit_test.gyp:junit_unit_tests
+android_library("junit_unittests") {
+  deps = [
+    ":junit_test_support",
+    "//third_party/junit",
+  ]
+#main_class = "org.chromium.testing.local.JuniTestMain"
+  DEPRECATED_java_in_dir = "javatests/src"
+}
diff --git a/testing/android/junit/junit_test.gyp b/testing/android/junit/junit_test.gyp
index 35b3be4..8e726a9 100644
--- a/testing/android/junit/junit_test.gyp
+++ b/testing/android/junit/junit_test.gyp
@@ -5,6 +5,7 @@
 {
   'targets': [
     {
+      # GN: //testing/android/junit:junit_test_support
       'target_name': 'junit_test_support',
       'type': 'none',
       'dependencies': [
@@ -20,6 +21,7 @@
       ],
     },
     {
+      # GN: //testing/android/junit:junit_unittests
       'target_name': 'junit_unit_tests',
       'type': 'none',
       'dependencies': [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index a0187b95..a184a12 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -42,15 +42,12 @@
       "browser_tests",
       "content_browsertests",
       "mojo_apps_js_unittests",
-      "mojo_clipboard_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_surfaces_lib_unittests",
       "mojo_system_unittests",
       "nacl_loader_unittests"
@@ -99,15 +96,12 @@
       "browser_tests",
       "content_browsertests",
       "mojo_apps_js_unittests",
-      "mojo_clipboard_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_surfaces_lib_unittests",
       "mojo_system_unittests",
       "nacl_loader_unittests"
@@ -156,15 +150,12 @@
       "browser_tests",
       "content_browsertests",
       "mojo_apps_js_unittests",
-      "mojo_clipboard_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_surfaces_lib_unittests",
       "mojo_system_unittests",
       "nacl_loader_unittests"
@@ -213,15 +204,12 @@
       "browser_tests",
       "content_browsertests",
       "mojo_apps_js_unittests",
-      "mojo_clipboard_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_surfaces_lib_unittests",
       "mojo_system_unittests",
       "nacl_loader_unittests"
@@ -259,15 +247,12 @@
       "media_unittests",
       "message_center_unittests",
       "mojo_apps_js_unittests",
-      "mojo_clipboard_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
       "net_unittests",
       "ppapi_unittests",
@@ -341,7 +326,6 @@
       "ipc_tests",
       "jingle_unittests",
       "media_unittests",
-      "mojo_application_manager_unittests",
       "mojo_apps_js_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
@@ -349,7 +333,6 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
       "nacl_loader_unittests",
       "net_unittests",
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 9f814d3..ecce6843 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -57,7 +57,6 @@
       "ipc_tests",
       "jingle_unittests",
       "media_unittests",
-      "mojo_application_manager_unittests",
       "mojo_apps_js_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
@@ -65,9 +64,7 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
-      "mojo_view_manager_unittests",
       "nacl_loader_unittests",
       {
         "test": "net_unittests",
@@ -157,7 +154,6 @@
       "ipc_tests",
       "jingle_unittests",
       "media_unittests",
-      "mojo_application_manager_unittests",
       "mojo_apps_js_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
@@ -165,9 +161,7 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
-      "mojo_view_manager_unittests",
       "nacl_loader_unittests",
       {
         "test": "net_unittests",
@@ -258,7 +252,6 @@
       "ipc_tests",
       "jingle_unittests",
       "media_unittests",
-      "mojo_application_manager_unittests",
       "mojo_apps_js_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
@@ -266,9 +259,7 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
-      "mojo_view_manager_unittests",
       "nacl_loader_unittests",
       {
         "test": "net_unittests",
@@ -317,7 +308,6 @@
       "google_apis_unittests",
       "ipc_mojo_unittests",
       "ipc_tests",
-      "mojo_application_manager_unittests",
       "mojo_apps_js_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
@@ -325,9 +315,7 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
-      "mojo_view_manager_unittests",
       "nacl_loader_unittests",
       "sandbox_linux_unittests",
       "sql_unittests",
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index ef5867d7..018a2e3 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -56,8 +56,6 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
       {
         "test": "net_unittests",
@@ -144,8 +142,6 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
       {
         "test": "net_unittests",
@@ -232,8 +228,6 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
       {
         "test": "net_unittests",
@@ -321,8 +315,6 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_application_manager_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
       {
         "test": "net_unittests",
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json
index c2e560e..3f9acc0 100644
--- a/testing/buildbot/chromium.memory.fyi.json
+++ b/testing/buildbot/chromium.memory.fyi.json
@@ -28,7 +28,6 @@
       "ipc_tests",
       "jingle_unittests",
       "media_unittests",
-      "mojo_application_manager_unittests",
       "mojo_apps_js_unittests",
       "mojo_common_unittests",
       "mojo_js_unittests",
@@ -36,7 +35,6 @@
       "mojo_public_environment_unittests",
       "mojo_public_system_unittests",
       "mojo_public_utility_unittests",
-      "mojo_shell_tests",
       "mojo_system_unittests",
       "nacl_loader_unittests",
       "net_unittests",
diff --git a/testing/buildbot/chromium_athena.json b/testing/buildbot/chromium_athena.json
new file mode 100644
index 0000000..7b9d3c6
--- /dev/null
+++ b/testing/buildbot/chromium_athena.json
@@ -0,0 +1,22 @@
+{
+  "compile_targets": [
+    "chrome",
+    "athena_main"
+  ],
+  "gtest_tests": [
+    {
+      "test": "browser_tests",
+      "swarming": {
+        "can_use_on_swarming_builders": true,
+        "shards": 5
+      }
+    },
+    {
+      "test": "athena_unittests",
+      "swarming": {
+        "can_use_on_swarming_builders": true,
+        "shards": 5
+      }
+    }
+  ]
+}
diff --git a/testing/buildbot/chromium_trybot.json b/testing/buildbot/chromium_trybot.json
index e2fe64d..534767f 100644
--- a/testing/buildbot/chromium_trybot.json
+++ b/testing/buildbot/chromium_trybot.json
@@ -189,10 +189,6 @@
       "platforms": ["linux", "win"]
     },
     {
-      "test": "mojo_view_manager_unittests",
-      "platforms": ["linux"]
-    },
-    {
       "test": "views_unittests",
       "platforms": ["linux", "win"]
     },
diff --git a/testing/buildbot/trybot_analyze_config.json b/testing/buildbot/trybot_analyze_config.json
index d7f445f..7921d669 100644
--- a/testing/buildbot/trybot_analyze_config.json
+++ b/testing/buildbot/trybot_analyze_config.json
@@ -3,6 +3,7 @@
     "exclusions": [
       ".*isolate",
       "build/.*gyp[i]?",
+      "build/android/.*py",
       "build/android/pylib/.*",
       "build/compiler_version.py",
       "build/get_landmines.py",
diff --git a/testing/chromoting/browser_test_commands_linux.txt b/testing/chromoting/browser_test_commands_linux.txt
index 3b1be77..1c712208 100644
--- a/testing/chromoting/browser_test_commands_linux.txt
+++ b/testing/chromoting/browser_test_commands_linux.txt
@@ -1 +1,2 @@
-/usr/bin/python ../xvfb.py $(PROD_DIR) $(PROD_DIR)/browser_tests --gtest_filter=RemoteDesktopBrowserTest.MANUAL_Launch --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=$(PROD_DIR)/remoting/remoting.webapp --extension-name=Chromoting
\ No newline at end of file
+/usr/bin/python ../xvfb.py $(PROD_DIR) $(PROD_DIR)/browser_tests --gtest_filter=RemoteDesktopBrowserTest.MANUAL_Launch --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=$(PROD_DIR)/remoting/remoting.webapp --extension-name=Chromoting
+/usr/bin/python ../xvfb.py $(PROD_DIR) $(PROD_DIR)/browser_tests --gtest_filter=RemoteDesktopBrowserTest.MANUAL_Auth --run-manual --ui-test-action-timeout=100000 --webapp-unpacked=$(PROD_DIR)/remoting/remoting.webapp --extension-name=Chromoting --accounts-file=../../remoting/tools/internal/test_accounts.json --account-type=gmail
\ No newline at end of file
diff --git a/testing/gmock.gyp b/testing/gmock.gyp
index 22a1893b..dbdd36c 100644
--- a/testing/gmock.gyp
+++ b/testing/gmock.gyp
@@ -6,6 +6,7 @@
   'targets': [
     {
       'target_name': 'gmock',
+      'toolsets': ['host', 'target'],
       'type': 'static_library',
       'dependencies': [
         'gtest.gyp:gtest',
diff --git a/testing/scripts/checkdeps.py b/testing/scripts/checkdeps.py
index 83abfdf..d6140da 100755
--- a/testing/scripts/checkdeps.py
+++ b/testing/scripts/checkdeps.py
@@ -3,41 +3,18 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import argparse
-import contextlib
 import json
 import os
-import subprocess
 import sys
-import tempfile
 
 
-SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
-SRC_DIR = os.path.abspath(
-    os.path.join(SCRIPT_DIR, os.path.pardir, os.path.pardir))
+import common
 
 
-def run_command(argv):
-  print 'Running %r' % argv
-  rc = subprocess.call(argv)
-  print 'Command %r returned exit code %d' % (argv, rc)
-  return rc
-
-
-@contextlib.contextmanager
-def temporary_file():
-  fd, path = tempfile.mkstemp()
-  os.close(fd)
-  try:
-    yield path
-  finally:
-    os.remove(path)
-
-
-def mode_run(args):
-  with temporary_file() as tempfile_path:
-    rc = run_command([
-        os.path.join(SRC_DIR, 'buildtools', 'checkdeps', 'checkdeps.py'),
+def main_run(args):
+  with common.temporary_file() as tempfile_path:
+    rc = common.run_command([
+        os.path.join(common.SRC_DIR, 'buildtools', 'checkdeps', 'checkdeps.py'),
         '--json', tempfile_path
     ])
 
@@ -49,27 +26,21 @@
     for violation in result['violations']:
       result_set.add((result['dependee_path'], violation['include_path']))
 
-  with open(args.output, 'w') as f:
-    json.dump({
-        'valid': True,
-        'failures': ['%s: %s' % (r[0], r[1]) for r in result_set],
-    }, f)
+  json.dump({
+      'valid': True,
+      'failures': ['%s: %s' % (r[0], r[1]) for r in result_set],
+  }, args.output)
 
   return rc
 
 
-def main(argv):
-  parser = argparse.ArgumentParser()
-
-  subparsers = parser.add_subparsers()
-
-  run_parser = subparsers.add_parser('run')
-  run_parser.add_argument('--output', required=True)
-  run_parser.set_defaults(func=mode_run)
-
-  args = parser.parse_args(argv)
-  return args.func(args)
+def main_compile_targets(args):
+  json.dump([], args.output)
 
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+  funcs = {
+    'run': main_run,
+    'compile_targets': main_compile_targets,
+  }
+  sys.exit(common.run_script(sys.argv[1:], funcs))
diff --git a/testing/scripts/common.py b/testing/scripts/common.py
new file mode 100644
index 0000000..92ad6882
--- /dev/null
+++ b/testing/scripts/common.py
@@ -0,0 +1,117 @@
+# 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.
+
+import argparse
+import contextlib
+import json
+import os
+import subprocess
+import tempfile
+
+
+SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
+SRC_DIR = os.path.abspath(
+    os.path.join(SCRIPT_DIR, os.path.pardir, os.path.pardir))
+
+
+# run-webkit-tests returns the number of failures as the return
+# code, but caps the return code at 101 to avoid overflow or colliding
+# with reserved values from the shell.
+MAX_FAILURES_EXIT_STATUS = 101
+
+
+def run_script(argv, funcs):
+  def parse_json(path):
+    with open(path) as f:
+      return json.load(f)
+  parser = argparse.ArgumentParser()
+  # TODO(phajdan.jr): Make build-config-fs required after passing it in recipe.
+  parser.add_argument('--build-config-fs')
+  parser.add_argument('--paths', type=parse_json, default={})
+  parser.add_argument('--properties', type=parse_json, default={})
+
+  subparsers = parser.add_subparsers()
+
+  run_parser = subparsers.add_parser('run')
+  run_parser.add_argument(
+      '--output', type=argparse.FileType('w'), required=True)
+  run_parser.add_argument('--filter-file', type=argparse.FileType('r'))
+  run_parser.set_defaults(func=funcs['run'])
+
+  run_parser = subparsers.add_parser('compile_targets')
+  run_parser.add_argument(
+      '--output', type=argparse.FileType('w'), required=True)
+  run_parser.set_defaults(func=funcs['compile_targets'])
+
+  args = parser.parse_args(argv)
+  return args.func(args)
+
+
+def run_command(argv):
+  print 'Running %r' % argv
+  rc = subprocess.call(argv)
+  print 'Command %r returned exit code %d' % (argv, rc)
+  return rc
+
+
+@contextlib.contextmanager
+def temporary_file():
+  fd, path = tempfile.mkstemp()
+  os.close(fd)
+  try:
+    yield path
+  finally:
+    os.remove(path)
+
+
+def parse_common_test_results(json_results):
+  def convert_trie_to_flat_paths(trie, prefix=None):
+    # Also see webkitpy.layout_tests.layout_package.json_results_generator
+    result = {}
+    for name, data in trie.iteritems():
+      if prefix:
+        name = prefix + '/' + name
+      if len(data) and not 'actual' in data and not 'expected' in data:
+        result.update(convert_trie_to_flat_paths(data, name))
+      else:
+        result[name] = data
+    return result
+
+  results = {
+    'passes': {},
+    'unexpected_passes': {},
+    'failures': {},
+    'unexpected_failures': {},
+    'flakes': {},
+    'unexpected_flakes': {},
+  }
+
+  # TODO(dpranke): crbug.com/357866 - we should simplify the handling of
+  # both the return code and parsing the actual results, below.
+
+  passing_statuses = ('PASS', 'SLOW', 'NEEDSREBASELINE',
+                        'NEEDSMANUALREBASELINE')
+
+  for test, result in convert_trie_to_flat_paths(
+      json_results['tests']).iteritems():
+    key = 'unexpected_' if result.get('is_unexpected') else ''
+    data = result['actual']
+    actual_results = data.split()
+    last_result = actual_results[-1]
+    expected_results = result['expected'].split()
+
+    if (len(actual_results) > 1 and
+        (last_result in expected_results or last_result in passing_statuses)):
+      key += 'flakes'
+    elif last_result in passing_statuses:
+      key += 'passes'
+      # TODO(dpranke): crbug.com/357867 ...  Why are we assigning result
+      # instead of actual_result here. Do we even need these things to be
+      # hashes, or just lists?
+      data = result
+    else:
+      key += 'failures'
+    results[key][test] = data
+
+  return results
diff --git a/testing/scripts/get_compile_targets.py b/testing/scripts/get_compile_targets.py
new file mode 100755
index 0000000..16cff95
--- /dev/null
+++ b/testing/scripts/get_compile_targets.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# 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.
+
+import argparse
+import json
+import os
+import sys
+
+import common
+
+
+def main(argv):
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--output', required=True)
+  parser.add_argument('args', nargs=argparse.REMAINDER)
+
+  args = parser.parse_args(argv)
+
+  passthrough_args = args.args
+  if passthrough_args[0] == '--':
+    passthrough_args = passthrough_args[1:]
+
+  results = {}
+
+  for filename in os.listdir(common.SCRIPT_DIR):
+    if not filename.endswith('.py'):
+      continue
+    if filename in ('common.py', 'get_compile_targets.py'):
+      continue
+
+    with common.temporary_file() as tempfile_path:
+      rc = common.run_command(
+          [sys.executable, os.path.join(common.SCRIPT_DIR, filename)] +
+          passthrough_args +
+          [
+              'compile_targets',
+              '--output', tempfile_path
+          ]
+      )
+      if rc != 0:
+        return rc
+
+      with open(tempfile_path) as f:
+        results[filename] = json.load(f)
+
+  with open(args.output, 'w') as f:
+    json.dump(results, f)
+
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv[1:]))
diff --git a/testing/scripts/telemetry_unittests.py b/testing/scripts/telemetry_unittests.py
new file mode 100755
index 0000000..c652549
--- /dev/null
+++ b/testing/scripts/telemetry_unittests.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# 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.
+
+import json
+import os
+import sys
+
+
+import common
+
+
+def main_run(args):
+  filter_tests = []
+  if args.filter_file:
+    filter_tests = json.load(args.filter_file)
+
+  with common.temporary_file() as tempfile_path:
+    rc = common.run_command([
+        sys.executable,
+        os.path.join(args.paths['build'], 'scripts', 'tools', 'runit.py'),
+        '--show-path',
+        sys.executable,
+        os.path.join(args.paths['build'], 'scripts', 'slave', 'runtest.py'),
+        '--target', args.build_config_fs,
+        '--xvfb',
+        '--annotate', 'gtest',
+        '--test-type', 'telemetry_unittests',
+        '--builder-name', args.properties['buildername'],
+        '--slave-name', args.properties['slavename'],
+        '--build-number', str(args.properties['buildnumber']),
+        '--run-python-script',
+        os.path.join(common.SRC_DIR, 'tools', 'telemetry', 'run_tests'),
+        '--browser', args.build_config_fs.lower(),
+        '--retry-limit', '3',
+        '--write-full-results-to', tempfile_path,
+    ] + filter_tests)
+
+    with open(tempfile_path) as f:
+      results = json.load(f)
+
+  parsed_results = common.parse_common_test_results(results)
+  failures = parsed_results['unexpected_failures']
+
+  json.dump({
+      'valid': bool(rc <= common.MAX_FAILURES_EXIT_STATUS and
+                   ((rc == 0) or failures)),
+      'failures': failures.keys(),
+  }, args.output)
+
+  return rc
+
+
+def main_compile_targets(args):
+  json.dump(['chrome'], args.output)
+
+
+if __name__ == '__main__':
+  funcs = {
+    'run': main_run,
+    'compile_targets': main_compile_targets,
+  }
+  sys.exit(common.run_script(sys.argv[1:], funcs))
diff --git a/third_party/android_crazy_linker/README.chromium b/third_party/android_crazy_linker/README.chromium
index 91a96f07..deea35e 100644
--- a/third_party/android_crazy_linker/README.chromium
+++ b/third_party/android_crazy_linker/README.chromium
@@ -49,3 +49,5 @@
 - Add an error message for failures where no shared RELRO pages are swapped.
 
 - Remove excess newline from the message added above.
+
+- Avoid mixing size_t and uint32_t in Leb128Decoder::Dequeue().
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_leb128.h b/third_party/android_crazy_linker/src/src/crazy_linker_leb128.h
index 3d0ad8f..0888d77c 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_leb128.h
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_leb128.h
@@ -18,14 +18,14 @@
       : encoding_(encoding), cursor_(0) { }
 
   size_t Dequeue() {
-    uint32_t value = 0;
+    size_t value = 0;
 
     size_t shift = 0;
     uint8_t byte;
 
     do {
       byte = encoding_[cursor_++];
-      value |= static_cast<uint32_t>(byte & 127) << shift;
+      value |= static_cast<size_t>(byte & 127) << shift;
       shift += 7;
     } while (byte & 128);
 
diff --git a/third_party/android_platform/README.chromium b/third_party/android_platform/README.chromium
index 54d41774..b67b8e3 100644
--- a/third_party/android_platform/README.chromium
+++ b/third_party/android_platform/README.chromium
@@ -20,3 +20,4 @@
 Added support for parsing LOG(FATAL) and DCHECK errors and their
     stack traces, as emitted by src/base/debug/stack_trace_android.cc
 Added support for finding symbols when library is loaded directly from the APK.
+Changed the toolchain to remove references to 4.6 toolchains.
\ No newline at end of file
diff --git a/third_party/android_platform/development/scripts/symbol.py b/third_party/android_platform/development/scripts/symbol.py
index 44d02383..d2a247d 100755
--- a/third_party/android_platform/development/scripts/symbol.py
+++ b/third_party/android_platform/development/scripts/symbol.py
@@ -53,7 +53,7 @@
   # ToolPath looks for the tools in the completely incorrect directory.
   # This looks in the checked in android_tools.
   if ARCH == "arm":
-    toolchain_source = "arm-linux-androideabi-4.6"
+    toolchain_source = "arm-linux-androideabi-4.9"
     toolchain_prefix = "arm-linux-androideabi"
     ndk = "ndk"
   elif ARCH == "arm64":
@@ -61,15 +61,15 @@
     toolchain_prefix = "aarch64-linux-android"
     ndk = "ndk"
   elif ARCH == "x86":
-    toolchain_source = "x86-4.6"
-    toolchain_prefix = "i686-android-linux"
+    toolchain_source = "x86-4.9"
+    toolchain_prefix = "i686-linux-android"
     ndk = "ndk"
   elif ARCH == "x86_64":
     toolchain_source = "x86_64-4.9"
     toolchain_prefix = "x86_64-linux-android"
     ndk = "ndk"
   elif ARCH == "mips":
-    toolchain_source = "mipsel-linux-android-4.6"
+    toolchain_source = "mipsel-linux-android-4.9"
     toolchain_prefix = "mipsel-linux-android"
     ndk = "ndk"
   else:
@@ -97,26 +97,24 @@
     return TOOLCHAIN_INFO
 
   ## Known toolchains, newer ones in the front.
+  gcc_version = "4.9"
   if ARCH == "arm64":
-    gcc_version = "4.9"
     known_toolchains = [
       ("aarch64-linux-android-" + gcc_version, "aarch64", "aarch64-linux-android")
     ]
   elif ARCH == "arm":
-    gcc_version = "4.6"
     known_toolchains = [
-      ("arm-linux-androideabi-" + gcc_version, "arm", "arm-linux-androideabi"),
+      ("arm-linux-androideabi-" + gcc_version, "arm", "arm-linux-androideabi")
     ]
   elif ARCH =="x86":
     known_toolchains = [
-      ("i686-android-linux-4.4.3", "x86", "i686-android-linux")
+      ("x86-" + gcc_version, "x86", "i686-linux-android")
     ]
   elif ARCH =="x86_64":
     known_toolchains = [
-      ("x86_64-linux-android-4.9", "x86_64", "x86_64-linux-android")
+      ("x86_64-" + gcc_version, "x86_64", "x86_64-linux-android")
     ]
   elif ARCH == "mips":
-    gcc_version = "4.6"
     known_toolchains = [
       ("mipsel-linux-android-" + gcc_version, "mips", "mipsel-linux-android")
     ]
diff --git a/third_party/android_webview_glue/android_webview_glue.gypi b/third_party/android_webview_glue/android_webview_glue.gypi
index df80f70e..3ba317a 100644
--- a/third_party/android_webview_glue/android_webview_glue.gypi
+++ b/third_party/android_webview_glue/android_webview_glue.gypi
@@ -5,38 +5,10 @@
   'targets': [
     {
       'target_name': 'system_webview_apk',
-      'type': 'none',
-      'dependencies': [
-        'libwebviewchromium',
-        'android_webview_java',
-        'android_webview_pak',
-      ],
       'variables': {
-        'android_sdk_jar': '../third_party/android_platform/webview/frameworks.jar',
         'apk_name': 'SystemWebView',
-        'app_manifest_version_code': '999999',
-        'java_in_dir': 'src/chromium',
-        'java_in_dir_suffix': '/java',
-        'native_lib_target': 'libwebviewchromium',
-        'never_lint': 1,
-        'resource_dir': 'src/chromium/res',
-        'R_package': 'com.android.webview.chromium',
-        'R_package_relpath': 'com/android/webview/chromium',
-        'extensions_to_not_compress': 'pak',
-        'asset_location': '<(PRODUCT_DIR)/android_webview_assets',
-        # TODO: crbug.com/405035 Find a better solution for WebView .pak files.
-        'additional_input_paths': [
-          '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak',
-          '<(PRODUCT_DIR)/android_webview_assets/en-US.pak',
-        ],
-        'conditions': [
-          ['icu_use_data_file_flag==1', {
-            'additional_input_paths': [
-              '<(PRODUCT_DIR)/icudtl.dat',
-            ],
-          }],
-        ],
       },
+      'includes': [ 'android_webview_glue_common.gypi' ],
       'copies': [
         {
           'destination': '<(PRODUCT_DIR)/android_webview_assets',
@@ -49,7 +21,7 @@
             }],
           ],
         },
-      ],'includes': [ '../../build/java_apk.gypi' ],
+      ],
     },
   ],
 }
diff --git a/third_party/android_webview_glue/android_webview_glue_common.gypi b/third_party/android_webview_glue/android_webview_glue_common.gypi
new file mode 100644
index 0000000..896dee4
--- /dev/null
+++ b/third_party/android_webview_glue/android_webview_glue_common.gypi
@@ -0,0 +1,37 @@
+# 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.
+{
+  'type': 'none',
+  'dependencies': [
+    '<(DEPTH)/android_webview/android_webview.gyp:libwebviewchromium',
+    '<(DEPTH)/android_webview/android_webview.gyp:android_webview_java',
+    '<(DEPTH)/android_webview/android_webview.gyp:android_webview_pak',
+  ],
+  'variables': {
+    'android_sdk_jar': '<(DEPTH)/third_party/android_platform/webview/frameworks.jar',
+    'app_manifest_version_code%': '999999',
+    'java_in_dir': 'src/chromium',
+    'java_in_dir_suffix': '/java',
+    'native_lib_target': 'libwebviewchromium',
+    'never_lint': 1,
+    'resource_dir': 'src/chromium/res',
+    'R_package': 'com.android.webview.chromium',
+    'R_package_relpath': 'com/android/webview/chromium',
+    'extensions_to_not_compress': 'pak',
+    'asset_location': '<(PRODUCT_DIR)/android_webview_assets',
+    # TODO: crbug.com/405035 Find a better solution for WebView .pak files.
+    'additional_input_paths': [
+      '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak',
+      '<(PRODUCT_DIR)/android_webview_assets/en-US.pak',
+    ],
+    'conditions': [
+      ['icu_use_data_file_flag==1', {
+        'additional_input_paths': [
+          '<(PRODUCT_DIR)/icudtl.dat',
+        ],
+      }],
+    ],
+  },
+  'includes': [ '../../build/java_apk.gypi' ],
+}
diff --git a/third_party/jsr-305/jsr-305.gyp b/third_party/jsr-305/jsr-305.gyp
index 37af4b2..f826bf5 100644
--- a/third_party/jsr-305/jsr-305.gyp
+++ b/third_party/jsr-305/jsr-305.gyp
@@ -6,6 +6,7 @@
   'targets': [
     {
       'target_name': 'jsr_305_javalib',
+      'toolsets': ['host', 'target'],
       'type': 'none',
       'variables': {
         # The sources are not located in a folder that is called src/, so we
diff --git a/third_party/junit/BUILD.gn b/third_party/junit/BUILD.gn
new file mode 100644
index 0000000..038e1ac
--- /dev/null
+++ b/third_party/junit/BUILD.gn
@@ -0,0 +1,20 @@
+# 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.
+
+import("//build/config/android/rules.gni")
+
+# TODO(GYP): should be java_prebuilt
+# GYP: //third_party/junit.gyp:hamcrest_jar
+android_java_prebuilt("hamcrest") {
+  jar_path = "src/lib/hamcrest-core-1.3.jar"
+}
+
+# TODO(GYP): should be java_library
+# GYP: //third_party/junit.gyp:junit_jar
+android_library("junit") {
+  deps = [
+    ":hamcrest"
+  ]
+  DEPRECATED_java_in_dir = "src/src/main/java"
+}
diff --git a/third_party/junit/junit.gyp b/third_party/junit/junit.gyp
index b68534e..8477aa0 100644
--- a/third_party/junit/junit.gyp
+++ b/third_party/junit/junit.gyp
@@ -5,6 +5,7 @@
 {
   'targets': [
     {
+      # GN: //third_party/junit:hamcrest
       'target_name': 'hamcrest_jar',
       'type': 'none',
       'variables': {
@@ -15,6 +16,7 @@
       ]
     },
     {
+      # GN: //third_party/junit:junit
       'target_name': 'junit_jar',
       'type': 'none',
       'dependencies': [
diff --git a/third_party/khronos/GLES2/gl2.h b/third_party/khronos/GLES2/gl2.h
index dc749b0..15602c67 100644
--- a/third_party/khronos/GLES2/gl2.h
+++ b/third_party/khronos/GLES2/gl2.h
@@ -6,7 +6,7 @@
 #endif
 
 /*
-** Copyright (c) 2013 The Khronos Group Inc.
+** Copyright (c) 2013-2014 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
@@ -33,13 +33,13 @@
 ** used to make the header, and the header can be found at
 **   http://www.opengl.org/registry/
 **
-** Khronos $Revision: 24263 $ on $Date: 2013-12-02 03:42:02 -0800 (Mon, 02 Dec 2013) $
+** Khronos $Revision: 28366 $ on $Date: 2014-10-20 11:29:02 +0200 (Mon, 20 Oct 2014) $
 */
 
 #include <GLES2/gl2chromium.h>
 #include <GLES2/gl2platform.h>
 
-/* Generated on date 20131202 */
+/* Generated on date 20141020 */
 
 /* Generated C header for:
  * API: gles2
diff --git a/third_party/khronos/GLES2/gl2ext.h b/third_party/khronos/GLES2/gl2ext.h
index 5891c74..a3efa82 100644
--- a/third_party/khronos/GLES2/gl2ext.h
+++ b/third_party/khronos/GLES2/gl2ext.h
@@ -6,7 +6,7 @@
 #endif
 
 /*
-** Copyright (c) 2013 The Khronos Group Inc.
+** Copyright (c) 2013-2014 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
@@ -33,14 +33,14 @@
 ** used to make the header, and the header can be found at
 **   http://www.opengl.org/registry/
 **
-** Khronos $Revision: 24263 $ on $Date: 2013-12-02 03:42:02 -0800 (Mon, 02 Dec 2013) $
+** Khronos $Revision: 28366 $ on $Date: 2014-10-20 11:29:02 +0200 (Mon, 20 Oct 2014) $
 */
 
 #ifndef GL_APIENTRYP
 #define GL_APIENTRYP GL_APIENTRY*
 #endif
 
-/* Generated on date 20131202 */
+/* Generated on date 20141020 */
 
 /* Generated C header for:
  * API: gles2
@@ -52,6 +52,40 @@
  * Extensions removed: _nomatch_^
  */
 
+#ifndef GL_KHR_blend_equation_advanced
+#define GL_KHR_blend_equation_advanced 1
+#define GL_MULTIPLY_KHR                   0x9294
+#define GL_SCREEN_KHR                     0x9295
+#define GL_OVERLAY_KHR                    0x9296
+#define GL_DARKEN_KHR                     0x9297
+#define GL_LIGHTEN_KHR                    0x9298
+#define GL_COLORDODGE_KHR                 0x9299
+#define GL_COLORBURN_KHR                  0x929A
+#define GL_HARDLIGHT_KHR                  0x929B
+#define GL_SOFTLIGHT_KHR                  0x929C
+#define GL_DIFFERENCE_KHR                 0x929E
+#define GL_EXCLUSION_KHR                  0x92A0
+#define GL_HSL_HUE_KHR                    0x92AD
+#define GL_HSL_SATURATION_KHR             0x92AE
+#define GL_HSL_COLOR_KHR                  0x92AF
+#define GL_HSL_LUMINOSITY_KHR             0x92B0
+typedef void (GL_APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlendBarrierKHR (void);
+#endif
+#endif /* GL_KHR_blend_equation_advanced */
+
+#ifndef GL_KHR_blend_equation_advanced_coherent
+#define GL_KHR_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_KHR    0x9285
+#endif /* GL_KHR_blend_equation_advanced_coherent */
+
+#ifndef GL_KHR_context_flush_control
+#define GL_KHR_context_flush_control 1
+#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR   0x82FB
+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x82FC
+#endif /* GL_KHR_context_flush_control */
+
 #ifndef GL_KHR_debug
 #define GL_KHR_debug 1
 typedef void (GL_APIENTRY  *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
@@ -121,6 +155,34 @@
 #endif
 #endif /* GL_KHR_debug */
 
+#ifndef GL_KHR_robust_buffer_access_behavior
+#define GL_KHR_robust_buffer_access_behavior 1
+#endif /* GL_KHR_robust_buffer_access_behavior */
+
+#ifndef GL_KHR_robustness
+#define GL_KHR_robustness 1
+#define GL_CONTEXT_ROBUST_ACCESS_KHR      0x90F3
+#define GL_LOSE_CONTEXT_ON_RESET_KHR      0x8252
+#define GL_GUILTY_CONTEXT_RESET_KHR       0x8253
+#define GL_INNOCENT_CONTEXT_RESET_KHR     0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_KHR      0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_KHR 0x8256
+#define GL_NO_RESET_NOTIFICATION_KHR      0x8261
+#define GL_CONTEXT_LOST_KHR               0x0507
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSKHRPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void);
+GL_APICALL void GL_APIENTRY glReadnPixelsKHR (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfvKHR (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivKHR (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+GL_APICALL void GL_APIENTRY glGetnUniformuivKHR (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+#endif
+#endif /* GL_KHR_robustness */
+
 #ifndef GL_KHR_texture_compression_astc_hdr
 #define GL_KHR_texture_compression_astc_hdr 1
 #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR   0x93B0
@@ -176,6 +238,10 @@
 #define GL_SAMPLER_EXTERNAL_OES           0x8D66
 #endif /* GL_OES_EGL_image_external */
 
+#ifndef GL_OES_compressed_ETC1_RGB8_sub_texture
+#define GL_OES_compressed_ETC1_RGB8_sub_texture 1
+#endif /* GL_OES_compressed_ETC1_RGB8_sub_texture */
+
 #ifndef GL_OES_compressed_ETC1_RGB8_texture
 #define GL_OES_compressed_ETC1_RGB8_texture 1
 #define GL_ETC1_RGB8_OES                  0x8D64
@@ -277,6 +343,31 @@
 #define GL_OES_rgb8_rgba8 1
 #endif /* GL_OES_rgb8_rgba8 */
 
+#ifndef GL_OES_sample_shading
+#define GL_OES_sample_shading 1
+#define GL_SAMPLE_SHADING_OES             0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_OES   0x8C37
+typedef void (GL_APIENTRYP PFNGLMINSAMPLESHADINGOESPROC) (GLfloat value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMinSampleShadingOES (GLfloat value);
+#endif
+#endif /* GL_OES_sample_shading */
+
+#ifndef GL_OES_sample_variables
+#define GL_OES_sample_variables 1
+#endif /* GL_OES_sample_variables */
+
+#ifndef GL_OES_shader_image_atomic
+#define GL_OES_shader_image_atomic 1
+#endif /* GL_OES_shader_image_atomic */
+
+#ifndef GL_OES_shader_multisample_interpolation
+#define GL_OES_shader_multisample_interpolation 1
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D
+#endif /* GL_OES_shader_multisample_interpolation */
+
 #ifndef GL_OES_standard_derivatives
 #define GL_OES_standard_derivatives 1
 #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B
@@ -372,6 +463,25 @@
 #define GL_OES_texture_npot 1
 #endif /* GL_OES_texture_npot */
 
+#ifndef GL_OES_texture_stencil8
+#define GL_OES_texture_stencil8 1
+#define GL_STENCIL_INDEX_OES              0x1901
+#define GL_STENCIL_INDEX8_OES             0x8D48
+#endif /* GL_OES_texture_stencil8 */
+
+#ifndef GL_OES_texture_storage_multisample_2d_array
+#define GL_OES_texture_storage_multisample_2d_array 1
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexStorage3DMultisampleOES (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#endif
+#endif /* GL_OES_texture_storage_multisample_2d_array */
+
 #ifndef GL_OES_vertex_array_object
 #define GL_OES_vertex_array_object 1
 #define GL_VERTEX_ARRAY_BINDING_OES       0x85B5
@@ -450,6 +560,10 @@
 #define GL_Z400_BINARY_AMD                0x8740
 #endif /* GL_AMD_program_binary_Z400 */
 
+#ifndef GL_ANDROID_extension_pack_es31a
+#define GL_ANDROID_extension_pack_es31a 1
+#endif /* GL_ANDROID_extension_pack_es31a */
+
 #ifndef GL_ANGLE_depth_texture
 #define GL_ANGLE_depth_texture 1
 #endif /* GL_ANGLE_depth_texture */
@@ -525,6 +639,23 @@
 #endif
 #endif /* GL_ANGLE_translated_shader_source */
 
+#ifndef GL_APPLE_clip_distance
+#define GL_APPLE_clip_distance 1
+#define GL_MAX_CLIP_DISTANCES_APPLE       0x0D32
+#define GL_CLIP_DISTANCE0_APPLE           0x3000
+#define GL_CLIP_DISTANCE1_APPLE           0x3001
+#define GL_CLIP_DISTANCE2_APPLE           0x3002
+#define GL_CLIP_DISTANCE3_APPLE           0x3003
+#define GL_CLIP_DISTANCE4_APPLE           0x3004
+#define GL_CLIP_DISTANCE5_APPLE           0x3005
+#define GL_CLIP_DISTANCE6_APPLE           0x3006
+#define GL_CLIP_DISTANCE7_APPLE           0x3007
+#endif /* GL_APPLE_clip_distance */
+
+#ifndef GL_APPLE_color_buffer_packed_float
+#define GL_APPLE_color_buffer_packed_float 1
+#endif /* GL_APPLE_color_buffer_packed_float */
+
 #ifndef GL_APPLE_copy_texture_levels
 #define GL_APPLE_copy_texture_levels 1
 typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
@@ -605,6 +736,14 @@
 #define GL_TEXTURE_MAX_LEVEL_APPLE        0x813D
 #endif /* GL_APPLE_texture_max_level */
 
+#ifndef GL_APPLE_texture_packed_float
+#define GL_APPLE_texture_packed_float 1
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B
+#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E
+#define GL_R11F_G11F_B10F_APPLE           0x8C3A
+#define GL_RGB9_E5_APPLE                  0x8C3D
+#endif /* GL_APPLE_texture_packed_float */
+
 #ifndef GL_ARM_mali_program_binary
 #define GL_ARM_mali_program_binary 1
 #define GL_MALI_PROGRAM_BINARY_ARM        0x8F61
@@ -619,6 +758,23 @@
 #define GL_ARM_rgba8 1
 #endif /* GL_ARM_rgba8 */
 
+#ifndef GL_ARM_shader_framebuffer_fetch
+#define GL_ARM_shader_framebuffer_fetch 1
+#define GL_FETCH_PER_SAMPLE_ARM           0x8F65
+#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66
+#endif /* GL_ARM_shader_framebuffer_fetch */
+
+#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil
+#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1
+#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */
+
+#ifndef GL_DMP_program_binary
+#define GL_DMP_program_binary 1
+#define GL_SMAPHS30_PROGRAM_BINARY_DMP    0x9251
+#define GL_SMAPHS_PROGRAM_BINARY_DMP      0x9252
+#define GL_DMP_PROGRAM_BINARY_DMP         0x9253
+#endif /* GL_DMP_program_binary */
+
 #ifndef GL_DMP_shader_binary
 #define GL_DMP_shader_binary 1
 #define GL_SHADER_BINARY_DMP              0x9250
@@ -640,6 +796,14 @@
 #define GL_UNSIGNED_NORMALIZED_EXT        0x8C17
 #endif /* GL_EXT_color_buffer_half_float */
 
+#ifndef GL_EXT_copy_image
+#define GL_EXT_copy_image 1
+typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAEXTPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyImageSubDataEXT (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#endif
+#endif /* GL_EXT_copy_image */
+
 #ifndef GL_EXT_debug_label
 #define GL_EXT_debug_label 1
 #define GL_PROGRAM_PIPELINE_OBJECT_EXT    0x8A4F
@@ -757,6 +921,30 @@
 #endif
 #endif /* GL_EXT_draw_buffers */
 
+#ifndef GL_EXT_draw_buffers_indexed
+#define GL_EXT_draw_buffers_indexed 1
+#define GL_MIN                            0x8007
+#define GL_MAX                            0x8008
+typedef void (GL_APIENTRYP PFNGLENABLEIEXTPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIEXTPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCIEXTPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIEXTPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKIEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIEXTPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEnableiEXT (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiEXT (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glBlendEquationiEXT (GLuint buf, GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparateiEXT (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunciEXT (GLuint buf, GLenum src, GLenum dst);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparateiEXT (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glColorMaskiEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediEXT (GLenum target, GLuint index);
+#endif
+#endif /* GL_EXT_draw_buffers_indexed */
+
 #ifndef GL_EXT_draw_instanced
 #define GL_EXT_draw_instanced 1
 typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
@@ -767,6 +955,57 @@
 #endif
 #endif /* GL_EXT_draw_instanced */
 
+#ifndef GL_EXT_geometry_point_size
+#define GL_EXT_geometry_point_size 1
+#endif /* GL_EXT_geometry_point_size */
+
+#ifndef GL_EXT_geometry_shader
+#define GL_EXT_geometry_shader 1
+#define GL_GEOMETRY_SHADER_EXT            0x8DD9
+#define GL_GEOMETRY_SHADER_BIT_EXT        0x00000004
+#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916
+#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917
+#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918
+#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F
+#define GL_LAYER_PROVOKING_VERTEX_EXT     0x825E
+#ifndef GL_EXT_geometry_shader4
+#define GL_LINES_ADJACENCY_EXT            0x000A
+#define GL_LINE_STRIP_ADJACENCY_EXT       0x000B
+#define GL_TRIANGLES_ADJACENCY_EXT        0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT   0x000D
+#endif /* GL_EXT_geometry_shader4 */
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7
+#define GL_FIRST_VERTEX_CONVENTION_EXT    0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT     0x8E4E
+#define GL_UNDEFINED_VERTEX_EXT           0x8260
+#define GL_PRIMITIVES_GENERATED_EXT       0x8C87
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS_EXT     0x9317
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+#endif /* GL_EXT_geometry_shader */
+
+#ifndef GL_EXT_gpu_shader5
+#define GL_EXT_gpu_shader5 1
+#endif /* GL_EXT_gpu_shader5 */
+
 #ifndef GL_EXT_instanced_arrays
 #define GL_EXT_instanced_arrays 1
 #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE
@@ -839,12 +1078,23 @@
 #define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
 #endif /* GL_EXT_occlusion_query_boolean */
 
+#ifndef GL_EXT_primitive_bounding_box
+#define GL_EXT_primitive_bounding_box 1
+#define GL_PRIMITIVE_BOUNDING_BOX_EXT     0x92BE
+typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXEXTPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#endif
+#endif /* GL_EXT_primitive_bounding_box */
+
 #ifndef GL_EXT_pvrtc_sRGB
 #define GL_EXT_pvrtc_sRGB 1
 #define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54
 #define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
 #define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
 #define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG 0x93F0
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1
 #endif /* GL_EXT_pvrtc_sRGB */
 
 #ifndef GL_EXT_read_format_bgra
@@ -992,10 +1242,25 @@
 #define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
 #endif /* GL_EXT_shader_framebuffer_fetch */
 
+#ifndef GL_EXT_shader_implicit_conversions
+#define GL_EXT_shader_implicit_conversions 1
+#endif /* GL_EXT_shader_implicit_conversions */
+
 #ifndef GL_EXT_shader_integer_mix
 #define GL_EXT_shader_integer_mix 1
 #endif /* GL_EXT_shader_integer_mix */
 
+#ifndef GL_EXT_shader_io_blocks
+#define GL_EXT_shader_io_blocks 1
+#endif /* GL_EXT_shader_io_blocks */
+
+#ifndef GL_EXT_shader_pixel_local_storage
+#define GL_EXT_shader_pixel_local_storage 1
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67
+#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64
+#endif /* GL_EXT_shader_pixel_local_storage */
+
 #ifndef GL_EXT_shader_texture_lod
 #define GL_EXT_shader_texture_lod 1
 #endif /* GL_EXT_shader_texture_lod */
@@ -1008,6 +1273,109 @@
 #define GL_SAMPLER_2D_SHADOW_EXT          0x8B62
 #endif /* GL_EXT_shadow_samplers */
 
+#ifndef GL_EXT_tessellation_point_size
+#define GL_EXT_tessellation_point_size 1
+#endif /* GL_EXT_tessellation_point_size */
+
+#ifndef GL_EXT_tessellation_shader
+#define GL_EXT_tessellation_shader 1
+#define GL_PATCHES_EXT                    0x000E
+#define GL_PATCH_VERTICES_EXT             0x8E72
+#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75
+#define GL_TESS_GEN_MODE_EXT              0x8E76
+#define GL_TESS_GEN_SPACING_EXT           0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER_EXT      0x8E78
+#define GL_TESS_GEN_POINT_MODE_EXT        0x8E79
+#define GL_ISOLINES_EXT                   0x8E7A
+#define GL_QUADS_EXT                      0x0007
+#define GL_FRACTIONAL_ODD_EXT             0x8E7B
+#define GL_FRACTIONAL_EVEN_EXT            0x8E7C
+#define GL_MAX_PATCH_VERTICES_EXT         0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL_EXT         0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS_EXT  0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_IS_PER_PATCH_EXT               0x92E7
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308
+#define GL_TESS_CONTROL_SHADER_EXT        0x8E88
+#define GL_TESS_EVALUATION_SHADER_EXT     0x8E87
+#define GL_TESS_CONTROL_SHADER_BIT_EXT    0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010
+typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIEXTPROC) (GLenum pname, GLint value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPatchParameteriEXT (GLenum pname, GLint value);
+#endif
+#endif /* GL_EXT_tessellation_shader */
+
+#ifndef GL_EXT_texture_border_clamp
+#define GL_EXT_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_EXT       0x1004
+#define GL_CLAMP_TO_BORDER_EXT            0x812D
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIivEXT (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuivEXT (GLuint sampler, GLenum pname, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIivEXT (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivEXT (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+#endif /* GL_EXT_texture_border_clamp */
+
+#ifndef GL_EXT_texture_buffer
+#define GL_EXT_texture_buffer 1
+#define GL_TEXTURE_BUFFER_EXT             0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING_EXT     0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT    0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT     0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F
+#define GL_SAMPLER_BUFFER_EXT             0x8DC2
+#define GL_INT_SAMPLER_BUFFER_EXT         0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#define GL_IMAGE_BUFFER_EXT               0x9051
+#define GL_INT_IMAGE_BUFFER_EXT           0x905C
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT  0x9067
+#define GL_TEXTURE_BUFFER_OFFSET_EXT      0x919D
+#define GL_TEXTURE_BUFFER_SIZE_EXT        0x919E
+typedef void (GL_APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEEXTPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#endif
+#endif /* GL_EXT_texture_buffer */
+
 #ifndef GL_EXT_texture_compression_dxt1
 #define GL_EXT_texture_compression_dxt1 1
 #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT   0x83F0
@@ -1020,6 +1388,19 @@
 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  0x83F3
 #endif /* GL_EXT_texture_compression_s3tc */
 
+#ifndef GL_EXT_texture_cube_map_array
+#define GL_EXT_texture_cube_map_array 1
+#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT     0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A
+#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT     0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT       0x9054
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT   0x905F
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#endif /* GL_EXT_texture_cube_map_array */
+
 #ifndef GL_EXT_texture_filter_anisotropic
 #define GL_EXT_texture_filter_anisotropic 1
 #define GL_TEXTURE_MAX_ANISOTROPY_EXT     0x84FE
@@ -1082,6 +1463,19 @@
 #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
 #endif /* GL_EXT_texture_type_2_10_10_10_REV */
 
+#ifndef GL_EXT_texture_view
+#define GL_EXT_texture_view 1
+#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT     0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT    0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER_EXT     0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT    0x82DE
+#define GL_TEXTURE_IMMUTABLE_LEVELS       0x82DF
+typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTextureViewEXT (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#endif
+#endif /* GL_EXT_texture_view */
+
 #ifndef GL_EXT_unpack_subimage
 #define GL_EXT_unpack_subimage 1
 #define GL_UNPACK_ROW_LENGTH_EXT          0x0CF2
@@ -1138,6 +1532,52 @@
 #define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
 #endif /* GL_IMG_texture_compression_pvrtc2 */
 
+#ifndef GL_INTEL_performance_query
+#define GL_INTEL_performance_query 1
+#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000
+#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001
+#define GL_PERFQUERY_WAIT_INTEL           0x83FB
+#define GL_PERFQUERY_FLUSH_INTEL          0x83FA
+#define GL_PERFQUERY_DONOT_FLUSH_INTEL    0x83F9
+#define GL_PERFQUERY_COUNTER_EVENT_INTEL  0x94F0
+#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1
+#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2
+#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3
+#define GL_PERFQUERY_COUNTER_RAW_INTEL    0x94F4
+#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5
+#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8
+#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9
+#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA
+#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB
+#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC
+#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD
+#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE
+#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF
+#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500
+typedef void (GL_APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle);
+typedef void (GL_APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId);
+typedef void (GL_APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId);
+typedef void (GL_APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle);
+GL_APICALL void GL_APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glEndPerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId);
+GL_APICALL void GL_APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId);
+GL_APICALL void GL_APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
+GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten);
+GL_APICALL void GL_APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId);
+GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
+#endif
+#endif /* GL_INTEL_performance_query */
+
 #ifndef GL_NV_blend_equation_advanced
 #define GL_NV_blend_equation_advanced 1
 #define GL_BLEND_OVERLAP_NV               0x9281
diff --git a/third_party/khronos/README.chromium b/third_party/khronos/README.chromium
index e7b4d864..d803f145 100644
--- a/third_party/khronos/README.chromium
+++ b/third_party/khronos/README.chromium
@@ -2,7 +2,7 @@
 Short Name: khronos_headers
 URL: http://www.khronos.org/registry
 Version: unknown
-Date: 2013-12-13
+Date: 2014-10-20
 License: MIT/X11, SGI Free Software License B
 Security Critical: no
 
@@ -21,6 +21,13 @@
 
 GLES2/gl2.h
  - Added include of gl2chromium.h
+GLES2/gl2ext.h
+ - Chromium-specific define to account for issues in gles2_conform_test, 
+   see http://crbug.com/329708.
+ - Commented out GL_SAMPLER, conflicts with third_party/gles2_conform
+ - Drop const from last argument of GLDEBUGPROCKHR (win trybot fail)
+ - Added ifdef around GL_LINES_ADJACENCY_EXT to fix conflict with OSX
+   OpenGL framework headers.
 EGL/eglplatform.h
  - Added EGLNative*Type for Mac.
  - Added EGLNative*Type for native linux framebuffers.
diff --git a/third_party/libaddressinput/BUILD.gn b/third_party/libaddressinput/BUILD.gn
index 2f2bb03a..bb32d46 100644
--- a/third_party/libaddressinput/BUILD.gn
+++ b/third_party/libaddressinput/BUILD.gn
@@ -125,82 +125,95 @@
   ]
 }
 
-if (!is_android) {
+if (is_android) {
+  import("//build/config/android/rules.gni")
 
-# The list of files in libaddressinput.gypi.
-gypi_values = exec_script(
-    "//build/gypi_to_gn.py",
-    [ rebase_path("src/cpp/libaddressinput.gypi") ],
-    "scope",
-    [ "src/cpp/libaddressinput.gypi" ])
+  android_resources("android_addressinput_widget_resources") {
+    custom_package = "com.android.i18n.addressinput"
+    resource_dirs = [ "src/java/res" ]
+    v14_verify_only = true
+  }
+
+  # GYP: //third_party/libaddressinput/libaddressinput.gyp:android_addressinput_widget
+  android_library("android_addressinput_widget_java") {
+    DEPRECATED_java_in_dir = "src/java/src"
+    deps = [ ":android_addressinput_widget_resources" ]
+  }
+} else {
+  # The list of files in libaddressinput.gypi.
+  gypi_values = exec_script(
+      "//build/gypi_to_gn.py",
+      [ rebase_path("src/cpp/libaddressinput.gypi") ],
+      "scope",
+      [ "src/cpp/libaddressinput.gypi" ])
 
 
-# This target provides more complicated functionality like pinging servers
-# for validation rules.
-# GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput
-static_library("libaddressinput") {
-  sources = rebase_path(gypi_values.libaddressinput_files, ".", "src/cpp")
-  sources += [
-    "chromium/chrome_address_validator.cc",
-    "chromium/chrome_metadata_source.cc",
-    "chromium/chrome_storage_impl.cc",
-    "chromium/fallback_data_store.cc",
-    "chromium/input_suggester.cc",
-    "chromium/string_compare.cc",
-    "chromium/trie.cc",
-  ]
-  sources -= libaddressinput_util_files
-  sources -= [
-    "src/cpp/src/util/string_compare.cc",
-  ]
+  # This target provides more complicated functionality like pinging servers
+  # for validation rules.
+  # GYP version: third_party/libaddressinput/libaddressinput.gyp:libaddressinput
+  static_library("libaddressinput") {
+    sources = rebase_path(gypi_values.libaddressinput_files, ".", "src/cpp")
+    sources += [
+      "chromium/chrome_address_validator.cc",
+      "chromium/chrome_metadata_source.cc",
+      "chromium/chrome_storage_impl.cc",
+      "chromium/fallback_data_store.cc",
+      "chromium/input_suggester.cc",
+      "chromium/string_compare.cc",
+      "chromium/trie.cc",
+    ]
+    sources -= libaddressinput_util_files
+    sources -= [
+      "src/cpp/src/util/string_compare.cc",
+    ]
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
 
-  public_configs = [ ":libaddressinput_config" ]
+    public_configs = [ ":libaddressinput_config" ]
 
-  deps = [
-    ":strings",
-    ":util",
-    "//base",
-    "//base:i18n",
-    "//third_party/icu",
-    "//third_party/re2",
-  ]
+    deps = [
+      ":strings",
+      ":util",
+      "//base",
+      "//base:i18n",
+      "//third_party/icu",
+      "//third_party/re2",
+    ]
+  }
+
+  test("libaddressinput_unittests") {
+    sources = rebase_path(
+        gypi_values.libaddressinput_test_files, ".", "src/cpp")
+    sources += [
+      "chromium/addressinput_util_unittest.cc",
+      "chromium/chrome_address_validator_unittest.cc",
+      "chromium/chrome_metadata_source_unittest.cc",
+      "chromium/chrome_storage_impl_unittest.cc",
+      "chromium/fallback_data_store_unittest.cc",
+      "chromium/storage_test_runner.cc",
+      "chromium/string_compare_unittest.cc",
+      "chromium/trie_unittest.cc",
+    ]
+
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+
+    defines = [
+      "TEST_DATA_DIR=\"third_party/libaddressinput/src/testdata\"",
+    ]
+
+    include_dirs = [
+      "src/cpp/src",
+    ]
+
+    deps = [
+      ":libaddressinput",
+      ":strings",
+      "//base:prefs",
+      "//base/test:run_all_unittests",
+      "//net:test_support",
+      "//testing/gtest",
+    ]
+  }
 }
-
-test("libaddressinput_unittests") {
-  sources = rebase_path(gypi_values.libaddressinput_test_files, ".", "src/cpp")
-  sources += [
-    "chromium/addressinput_util_unittest.cc",
-    "chromium/chrome_address_validator_unittest.cc",
-    "chromium/chrome_metadata_source_unittest.cc",
-    "chromium/chrome_storage_impl_unittest.cc",
-    "chromium/fallback_data_store_unittest.cc",
-    "chromium/storage_test_runner.cc",
-    "chromium/string_compare_unittest.cc",
-    "chromium/trie_unittest.cc",
-  ]
-
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
-
-  defines = [
-    "TEST_DATA_DIR=\"third_party/libaddressinput/src/testdata\"",
-  ]
-
-  include_dirs = [
-    "src/cpp/src",
-  ]
-
-  deps = [
-    ":libaddressinput",
-    ":strings",
-    "//base:prefs",
-    "//base/test:run_all_unittests",
-    "//net:test_support",
-    "//testing/gtest",
-  ]
-}
-
-}  # !is_android
diff --git a/third_party/libaddressinput/libaddressinput.gyp b/third_party/libaddressinput/libaddressinput.gyp
index 698cbb5d..db2b466 100644
--- a/third_party/libaddressinput/libaddressinput.gyp
+++ b/third_party/libaddressinput/libaddressinput.gyp
@@ -165,6 +165,7 @@
     ['OS=="android"', {
       'targets': [
         {
+          # GN: //third_party/libaddressinput:android_addressinput_widget_java
           'target_name': 'android_addressinput_widget',
           'type': 'none',
           'variables': {
diff --git a/third_party/libevent/libevent_nacl_nonsfi.gyp b/third_party/libevent/libevent_nacl_nonsfi.gyp
index 8638c96..704de105 100644
--- a/third_party/libevent/libevent_nacl_nonsfi.gyp
+++ b/third_party/libevent/libevent_nacl_nonsfi.gyp
@@ -7,7 +7,7 @@
     '../../build/common_untrusted.gypi',
   ],
   'conditions': [
-    ['disable_nacl==0', {
+    ['disable_nacl==0 and disable_nacl_untrusted==0', {
       'targets': [
         {
           'target_name': 'event_nacl_nonsfi',
@@ -28,11 +28,10 @@
           'defines': [
             'HAVE_CONFIG_H',
           ],
+          'include_dirs': [
+            'nacl_nonsfi',
+          ],
           'variables': {
-            'include_dirs': [
-              'nacl_nonsfi',
-              '<(DEPTH)/native_client/src/public/linux_syscalls',
-            ],
             'nacl_untrusted_build': 1,
             'nlib_target': 'libevent_nacl_nonsfi.a',
             'build_glibc': 0,
@@ -42,7 +41,7 @@
             'build_nonsfi_helper': 1,
           },
           'dependencies': [
-            '<(DEPTH)/native_client/tools.gyp:prep_toolchain',
+            '../../native_client/tools.gyp:prep_toolchain',
           ],
         },
       ],
diff --git a/third_party/libjingle/BUILD.gn b/third_party/libjingle/BUILD.gn
index fb01a64..7d80631 100644
--- a/third_party/libjingle/BUILD.gn
+++ b/third_party/libjingle/BUILD.gn
@@ -548,6 +548,7 @@
     deps = [
       ":libjingle_webrtc_common",
       "//third_party/webrtc",
+      "//third_party/webrtc/modules/audio_processing",
       "//third_party/webrtc/system_wrappers",
       "//third_party/webrtc/voice_engine",
     ]
diff --git a/third_party/libjingle/libjingle.gyp b/third_party/libjingle/libjingle.gyp
index 9b26732..801d14346 100644
--- a/third_party/libjingle/libjingle.gyp
+++ b/third_party/libjingle/libjingle.gyp
@@ -589,6 +589,7 @@
             '<(libjingle_source)/talk/media/webrtc/webrtcvoiceengine.h',
           ],
           'dependencies': [
+            '<(DEPTH)/third_party/webrtc/modules/modules.gyp:audio_processing',
             '<(DEPTH)/third_party/webrtc/system_wrappers/source/system_wrappers.gyp:system_wrappers',
             '<(DEPTH)/third_party/webrtc/voice_engine/voice_engine.gyp:voice_engine',
             '<(DEPTH)/third_party/webrtc/webrtc.gyp:webrtc',
diff --git a/third_party/libjingle/overrides/init_webrtc.cc b/third_party/libjingle/overrides/init_webrtc.cc
index 041fb20..b160cbb 100644
--- a/third_party/libjingle/overrides/init_webrtc.cc
+++ b/third_party/libjingle/overrides/init_webrtc.cc
@@ -12,6 +12,8 @@
 #include "base/metrics/histogram.h"
 #include "base/native_library.h"
 #include "base/path_service.h"
+#include "third_party/webrtc/common.h"
+#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
 #include "webrtc/base/basictypes.h"
 #include "webrtc/base/logging.h"
 
@@ -80,6 +82,13 @@
   return true;
 }
 
+webrtc::AudioProcessing* CreateWebRtcAudioProcessing(
+    const webrtc::Config& config) {
+  // libpeerconnection is being compiled as a static lib, use
+  // webrtc::AudioProcessing directly.
+  return webrtc::AudioProcessing::Create(config);
+}
+
 #else  // !LIBPEERCONNECTION_LIB
 
 // When being compiled as a shared library, we need to bridge the gap between
@@ -89,6 +98,7 @@
 // Global function pointers to the factory functions in the shared library.
 CreateWebRtcMediaEngineFunction g_create_webrtc_media_engine = NULL;
 DestroyWebRtcMediaEngineFunction g_destroy_webrtc_media_engine = NULL;
+CreateWebRtcAudioProcessingFunction g_create_webrtc_audio_processing = NULL;
 
 // Returns the full or relative path to the libpeerconnection module depending
 // on what platform we're on.
@@ -165,8 +175,8 @@
       &AddTraceEvent,
       &g_create_webrtc_media_engine,
       &g_destroy_webrtc_media_engine,
-      &init_diagnostic_logging);
-
+      &init_diagnostic_logging,
+      &g_create_webrtc_audio_processing);
   if (init_ok)
     rtc::SetExtraLoggingInit(init_diagnostic_logging);
   return init_ok;
@@ -190,4 +200,12 @@
   g_destroy_webrtc_media_engine(media_engine);
 }
 
+webrtc::AudioProcessing* CreateWebRtcAudioProcessing(
+    const webrtc::Config& config) {
+  // The same as CreateWebRtcMediaEngine(), we call InitializeWebRtcModule here
+  // for convenience of tests.
+  InitializeWebRtcModule();
+  return g_create_webrtc_audio_processing(config);
+}
+
 #endif  // LIBPEERCONNECTION_LIB
diff --git a/third_party/libjingle/overrides/init_webrtc.h b/third_party/libjingle/overrides/init_webrtc.h
index 714f9c6..c29bd71b 100644
--- a/third_party/libjingle/overrides/init_webrtc.h
+++ b/third_party/libjingle/overrides/init_webrtc.h
@@ -23,6 +23,8 @@
 
 namespace webrtc {
 class AudioDeviceModule;
+class AudioProcessing;
+class Config;
 namespace metrics {
 class Histogram;
 }  // namespace metrics
@@ -51,6 +53,9 @@
 typedef void (*InitDiagnosticLoggingDelegateFunctionFunction)(
     void (*DelegateFunction)(const std::string&));
 
+typedef webrtc::AudioProcessing* (*CreateWebRtcAudioProcessingFunction)(
+    const webrtc::Config& config);
+
 // A typedef for the main initialize function in libpeerconnection.
 // This will initialize logging in the module with the proper arguments
 // as well as provide pointers back to a couple webrtc factory functions.
@@ -72,7 +77,8 @@
     webrtc::AddTraceEventPtr trace_add_trace_event,
     CreateWebRtcMediaEngineFunction* create_media_engine,
     DestroyWebRtcMediaEngineFunction* destroy_media_engine,
-    InitDiagnosticLoggingDelegateFunctionFunction* init_diagnostic_logging);
+    InitDiagnosticLoggingDelegateFunctionFunction* init_diagnostic_logging,
+    CreateWebRtcAudioProcessingFunction* create_audio_processing);
 
 #if !defined(LIBPEERCONNECTION_IMPLEMENTATION)
 // Load and initialize the shared WebRTC module (libpeerconnection).
@@ -81,6 +87,11 @@
 // If not called explicitly, this function will still be called from the main
 // CreateWebRtcMediaEngine factory function the first time it is called.
 bool InitializeWebRtcModule();
+
+// Return a webrtc::AudioProcessing object.
+webrtc::AudioProcessing* CreateWebRtcAudioProcessing(
+    const webrtc::Config& config);
+
 #endif
 
 #endif // THIRD_PARTY_LIBJINGLE_OVERRIDES_INIT_WEBRTC_H_
diff --git a/third_party/libjingle/overrides/initialize_module.cc b/third_party/libjingle/overrides/initialize_module.cc
index 09afbc2ae..1250cfb 100644
--- a/third_party/libjingle/overrides/initialize_module.cc
+++ b/third_party/libjingle/overrides/initialize_module.cc
@@ -8,6 +8,7 @@
 #include "base/logging.h"
 #include "init_webrtc.h"
 #include "talk/media/webrtc/webrtcmediaengine.h"
+#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
 #include "webrtc/base/basictypes.h"
 #include "webrtc/base/logging.h"
 
@@ -98,7 +99,9 @@
                       CreateWebRtcMediaEngineFunction* create_media_engine,
                       DestroyWebRtcMediaEngineFunction* destroy_media_engine,
                       InitDiagnosticLoggingDelegateFunctionFunction*
-                          init_diagnostic_logging) {
+                          init_diagnostic_logging,
+                      CreateWebRtcAudioProcessingFunction*
+                          create_audio_processing) {
 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
   g_alloc = alloc;
   g_dealloc = dealloc;
@@ -112,6 +115,7 @@
   *create_media_engine = &CreateWebRtcMediaEngine;
   *destroy_media_engine = &DestroyWebRtcMediaEngine;
   *init_diagnostic_logging = &rtc::InitDiagnosticLoggingDelegateFunction;
+  *create_audio_processing = &webrtc::AudioProcessing::Create;
 
   if (CommandLine::Init(0, NULL)) {
 #if !defined(OS_WIN)
diff --git a/third_party/libwebp/README.chromium b/third_party/libwebp/README.chromium
index 993bf47..cb4f035 100644
--- a/third_party/libwebp/README.chromium
+++ b/third_party/libwebp/README.chromium
@@ -1,14 +1,14 @@
 Name: WebP image encoder/decoder
 Short Name: libwebp
 URL: http://developers.google.com/speed/webp
-Version: v0.4.2-rc2
+Version: v0.4.2
 License: BSD
 License File: LICENSE
 Security Critical: Yes
 
 Description:
 Source archive:
-  http://downloads.webmproject.org/releases/webp/libwebp-0.4.2-rc2.tar.gz
+  http://downloads.webmproject.org/releases/webp/libwebp-0.4.2.tar.gz
 
 WebP is an image format that does both lossy and lossless compression of
 digital photographic images. WebP consists of a codec based on VP8, that Google
@@ -22,4 +22,3 @@
  * Merged COPYING/PATENTS to LICENSE
 Cherry-picks:
   Revert patch f7fc4bc: dec/webp.c: don't wait for data before reporting w/h
-  e2ecae6 enc_mips32: workaround gcc-4.9 bug
diff --git a/third_party/libwebp/utils/bit_reader.h b/third_party/libwebp/utils/bit_reader.h
index 89b5cc1c..f569734 100644
--- a/third_party/libwebp/utils/bit_reader.h
+++ b/third_party/libwebp/utils/bit_reader.h
@@ -156,7 +156,7 @@
 }
 
 // Advances the read buffer by 4 bytes to make room for reading next 32 bits.
-// Speed critical, but infrequent part of the code can be non-inligned.
+// Speed critical, but infrequent part of the code can be non-inlined.
 extern void VP8LDoFillBitWindow(VP8LBitReader* const br);
 static WEBP_INLINE void VP8LFillBitWindow(VP8LBitReader* const br) {
   if (br->bit_pos_ >= VP8L_WBITS) VP8LDoFillBitWindow(br);
diff --git a/third_party/libxml/libxml.gyp b/third_party/libxml/libxml.gyp
index 3e6f615..44b2e757 100644
--- a/third_party/libxml/libxml.gyp
+++ b/third_party/libxml/libxml.gyp
@@ -18,6 +18,7 @@
   'targets': [
     {
       'target_name': 'libxml',
+      'toolsets': ['host', 'target'],
       'conditions': [
         ['use_system_libxml', {
           'conditions': [
@@ -51,7 +52,14 @@
               },
             }],
             ['OS == "ios"', {
-              'type': 'none',
+              'type': 'static_library',
+              'sources': [
+                'chromium/libxml_utils.h',
+                'chromium/libxml_utils.cc',
+              ],
+              'include_dirs': [
+                '$(SDKROOT)/usr/include/libxml2',
+              ],
               'all_dependent_settings': {
                 'defines': [
                   'USE_SYSTEM_LIBXML',
diff --git a/third_party/mesa/mesa.gyp b/third_party/mesa/mesa.gyp
index bc115e1..6ccbb2ac 100644
--- a/third_party/mesa/mesa.gyp
+++ b/third_party/mesa/mesa.gyp
@@ -657,6 +657,14 @@
             '_GLAPI_NO_EXPORTS',
           ],
         }],
+        ['ubsan==1', {
+          # Due to a bug in LLVM (http://llvm.org/bugs/show_bug.cgi?id=21349),
+          # compilation hangs for some Mesa source files. Disable -O2
+          # temporarily until http://crbug.com/426271 is fixed.
+          'cflags!': [
+            '-O2',
+          ],
+        }],
       ],
     },
     # Building this target will hide the native OpenGL shared library and
diff --git a/third_party/opus/opus.gyp b/third_party/opus/opus.gyp
index e6c4bcf1..bc25921a 100644
--- a/third_party/opus/opus.gyp
+++ b/third_party/opus/opus.gyp
@@ -40,7 +40,12 @@
           'src/include',
         ],
       },
-      'includes': ['opus_srcs.gypi', ],
+      'includes': [
+        'opus_srcs.gypi',
+        # Disable LTO due to ELF section name out of range
+        # crbug.com/422251
+        '../../build/android/disable_lto.gypi',
+      ],
       'sources': ['<@(opus_common_sources)'],
       'conditions': [
         ['OS!="win"', {
diff --git a/third_party/sqlite/sqlite.gyp b/third_party/sqlite/sqlite.gyp
index 2f80fc6..26bc36d 100644
--- a/third_party/sqlite/sqlite.gyp
+++ b/third_party/sqlite/sqlite.gyp
@@ -177,6 +177,11 @@
           ],
         }],
       ],
+      'includes': [
+        # Disable LTO due to ELF section name out of range
+        # crbug.com/422251
+        '../../build/android/disable_lto.gypi',
+      ],
     },
   ],
   'conditions': [
diff --git a/third_party/typ/README.chromium b/third_party/typ/README.chromium
index a49eb393..360a646 100644
--- a/third_party/typ/README.chromium
+++ b/third_party/typ/README.chromium
@@ -1,7 +1,7 @@
 Name: typ
 URL: https://github.com/dpranke/typ.git
-Version: 0.8.5
-Revision: aba6b5defd08d74dc1e52d25838b04a38088072d
+Version: 0.8.6
+Revision: e25b780b0b147580ef248c212b238446264d9d78
 Security Critical: no
 License: Apache 2.0
 License File: NOT_SHIPPED
diff --git a/third_party/typ/run b/third_party/typ/run
index 9fb0bd2a..62558a6 100755
--- a/third_party/typ/run
+++ b/third_party/typ/run
@@ -13,6 +13,9 @@
 is_python3 = bool(sys.version_info.major == 3)
 has_python34 = False
 verbose = False
+repo_dir = os.path.abspath(os.path.dirname(__file__))
+path_to_cov = os.path.join(repo_dir, 'tools', 'cov.py')
+path_to_runner = os.path.join(repo_dir, 'typ', 'runner.py')
 
 
 def call(*args, **kwargs):
@@ -97,14 +100,12 @@
 
 
 def run_coverage(args):
-    repo_dir = os.path.abspath(os.path.dirname(__file__))
-    path_to_cov = os.path.join(repo_dir, 'tools', 'cov.py')
     if not args.path:
         args.path = [repo_dir]
     if not args.source:
         args.source = [os.path.join(repo_dir, 'typ')]
     argv = cov.argv_from_args(args)
-    cov_args = ['-m', 'typ', '-j', '1']
+    cov_args = [path_to_runner, '-j', '1']
     call(['python', path_to_cov] + argv + cov_args)
     if has_python34:
         call(['python3', path_to_cov] + argv + cov_args)
@@ -138,20 +139,18 @@
 
 
 def run_tests(args):
-    # Tests that we can run the command line directly if typ is in sys.path.
-    call(['python', os.path.join('typ', 'runner.py'),
-          'typ.tests.main_test.TestMain.test_basic'])
+    # Test that we can run the module directly if typ is in sys.path.
+    call(['python', '-m', 'typ', 'typ.tests.main_test.TestMain.test_basic'])
 
     # Test that we can run the command line directly if typ is not in sys.path.
-    repo_dir = os.path.abspath(os.path.dirname(__file__))
     home_dir = os.environ['HOME']
-    call(['python', os.path.join(repo_dir, 'typ', 'runner.py'),
-          'typ.tests.main_test.TestMain.test_basic'], cwd=home_dir)
+    call(['python', path_to_runner, 'typ.tests.main_test.TestMain.test_basic'],
+         cwd=home_dir)
 
     # Now run all the tests under Python2 and Python3.
-    call(['python', '-m', 'typ'])
+    call(['python', path_to_runner])
     if has_python34:
-        call(['python3', '-m', 'typ'])
+        call(['python3', path_to_runner])
 
 
 if __name__ == '__main__':
diff --git a/third_party/typ/typ/__main__.py b/third_party/typ/typ/__main__.py
index 375e3e2a..0e026e8 100644
--- a/third_party/typ/typ/__main__.py
+++ b/third_party/typ/typ/__main__.py
@@ -12,10 +12,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import sys
+import sys  # pragma: no cover
 
-from typ import main
+from typ import main  # pragma: no cover
 
 
-if __name__ == '__main__':
-    sys.exit(main(win_multiprocessing='spawn'))
+if __name__ == '__main__':  # pragma: no cover
+    sys.exit(main())
diff --git a/third_party/typ/typ/fakes/host_fake.py b/third_party/typ/typ/fakes/host_fake.py
index 3e8643ca..5b9e46d 100644
--- a/third_party/typ/typ/fakes/host_fake.py
+++ b/third_party/typ/typ/fakes/host_fake.py
@@ -166,6 +166,13 @@
         if path not in self.dirs:
             self.dirs.add(path)
 
+    def mktempfile(self, delete=True):
+        curno = self.current_tmpno
+        self.current_tmpno += 1
+        f = io.StringIO()
+        f.name = '__im_tmp/tmpfile_%u' % curno
+        return f
+
     def mkdtemp(self, suffix='', prefix='tmp', dir=None, **_kwargs):
         if dir is None:
             dir = self.sep + '__im_tmp'
diff --git a/third_party/typ/typ/host.py b/third_party/typ/typ/host.py
index c5f6ac8..fc9e1130 100644
--- a/third_party/typ/typ/host.py
+++ b/third_party/typ/typ/host.py
@@ -35,6 +35,7 @@
     python_interpreter = sys.executable
     is_python3 = bool(sys.version_info.major == 3)
 
+    pathsep = os.pathsep
     sep = os.sep
     env = os.environ
 
@@ -77,6 +78,11 @@
         return proc.returncode, stdout.decode('utf-8'), stderr.decode('utf-8')
 
     def call_inline(self, argv, env=None):
+        if isinstance(self.stdout, _TeedStream):  # pragma: no cover
+            ret, out, err = self.call(argv, env)
+            self.print_(out, end='')
+            self.print_(err, end='', stream=self.stderr)
+            return ret
         return subprocess.call(argv, stdin=self.stdin, stdout=self.stdout,
                                stderr=self.stderr, env=env)
 
@@ -126,6 +132,9 @@
         if not self.exists(path):
             os.makedirs(path)
 
+    def mktempfile(self, delete=True):
+        return tempfile.NamedTemporaryFile(delete=delete)
+
     def mkdtemp(self, **kwargs):
         return tempfile.mkdtemp(**kwargs)
 
diff --git a/third_party/typ/typ/runner.py b/third_party/typ/typ/runner.py
index 3a8dc82..61aeb9d9 100644
--- a/third_party/typ/typ/runner.py
+++ b/third_party/typ/typ/runner.py
@@ -29,6 +29,8 @@
 # that typ/runner.py works when invoked via subprocess on windows in
 # _spawn_main().
 path_to_file = os.path.realpath(__file__)
+if path_to_file.endswith('.pyc'):  # pragma: no cover
+    path_to_file = path_to_file[:-1]
 dir_above_typ = os.path.dirname(os.path.dirname(path_to_file))
 if dir_above_typ not in sys.path:  # pragma: no cover
     sys.path.append(dir_above_typ)
@@ -49,17 +51,12 @@
 ResultType = json_results.ResultType
 
 
-def main(argv=None, host=None, stdout=None, stderr=None,
-         win_multiprocessing=None, **defaults):
+def main(argv=None, host=None, win_multiprocessing=None, **defaults):
     host = host or Host()
-    if stdout:
-        host.stdout = stdout
-    if stderr:
-        host.stderr = stderr
     runner = Runner(host=host)
-
-    return runner.main(argv, win_multiprocessing=win_multiprocessing,
-                       **defaults)
+    if win_multiprocessing is not None:
+        runner.win_multiprocessing = win_multiprocessing
+    return runner.main(argv, **defaults)
 
 
 class TestInput(object):
@@ -74,8 +71,7 @@
 class TestSet(object):
 
     def __init__(self, parallel_tests=None, isolated_tests=None,
-                 tests_to_skip=None, context=None, setup_fn=None,
-                 teardown_fn=None):
+                 tests_to_skip=None):
 
         def promote(tests):
             tests = tests or []
@@ -85,18 +81,14 @@
         self.parallel_tests = promote(parallel_tests)
         self.isolated_tests = promote(isolated_tests)
         self.tests_to_skip = promote(tests_to_skip)
-        self.context = context
-        self.setup_fn = setup_fn
-        self.teardown_fn = teardown_fn
 
 
 class WinMultiprocessing(object):
-    force = 'force'
     ignore = 'ignore'
-    run_serially = 'run_serially'
+    importable = 'importable'
     spawn = 'spawn'
 
-    values = [force, ignore, run_serially, spawn]
+    values = [ignore, importable, spawn]
 
 
 class _AddTestsError(Exception):
@@ -106,29 +98,32 @@
 class Runner(object):
 
     def __init__(self, host=None):
+        self.args = None
+        self.classifier = None
+        self.cov = None
+        self.context = None
+        self.coverage_source = None
         self.host = host or Host()
         self.loader = unittest.loader.TestLoader()
         self.printer = None
+        self.setup_fn = None
         self.stats = None
-        self.cov = None
-        self.coverage_source = None
+        self.teardown_fn = None
         self.top_level_dir = None
-        self.args = None
+        self.win_multiprocessing = WinMultiprocessing.spawn
 
         # initialize self.args to the defaults.
         parser = ArgumentParser(self.host)
         self.parse_args(parser, [])
 
-    def main(self, argv=None, win_multiprocessing=None, **defaults):
+    def main(self, argv=None, **defaults):
         parser = ArgumentParser(self.host)
         self.parse_args(parser, argv, **defaults)
         if parser.exit_status is not None:
             return parser.exit_status
 
         try:
-            ret = self._handle_win_multiprocessing('main', win_multiprocessing)
-            if ret is None:
-                ret, _, _ = self.run(win_multiprocessing=win_multiprocessing)
+            ret, _, _ = self.run()
             return ret
         except KeyboardInterrupt:
             self.print_("interrupted, exiting", stream=self.host.stderr)
@@ -145,65 +140,10 @@
         if parser.exit_status is not None:
             return
 
-    def _handle_win_multiprocessing(self, entry_point, win_multiprocessing,
-                                    allow_spawn=True):
-        wmp = win_multiprocessing
-        force, ignore, run_serially, spawn = WinMultiprocessing.values
-
-        if (wmp is not None and wmp not in WinMultiprocessing.values):
-            raise ValueError('illegal value %s for win_multiprocessing' %
-                             wmp)
-
-        # First, check if __main__ is importable; if it is, we're fine.
-        if (self._main_is_importable() and wmp != force):
-            return None
-
-        if wmp is None and self.args.jobs == 1:
-            return None
-
-        if wmp is None:
-            raise ValueError(
-                'The __main__ module is not importable; The caller '
-                'must pass a valid WinMultiprocessing value (one of %s) '
-                'to %s to tell typ how to handle Windows.' %
-                (WinMultiprocessing.values, entry_point))
-
-        h = self.host
-
-        if (h.platform != 'win32' and wmp != force):
-            return
-
-        if wmp == ignore:  # pragma: win32
-            raise ValueError('Cannot use WinMultiprocessing.ignore for '
-                             'win_multiprocessing when actually running '
-                             'on Windows.')
-
-        if wmp == run_serially:  # pragma: win32
-            self.args.jobs = 1
-            return None
-
-        assert allow_spawn, ('Cannot use WinMultiprocessing.spawn '
-                             'in %s' % entry_point)
-        assert wmp in (force, spawn)
-        argv = ArgumentParser(h).argv_from_args(self.args)
-        return h.call_inline([h.python_interpreter, path_to_file] + argv)
-
-    def _main_is_importable(self):
-        path = self.host.realpath(sys.modules['__main__'].__file__)
-        if not path or not path.endswith('.py'):  # pragma: no cover
-            return False
-
-        for d in sys.path:
-            if path.startswith(self.host.realpath(d)):
-                return True
-        return False  # pragma: no cover
-
     def print_(self, msg='', end='\n', stream=None):
         self.host.print_(msg, end, stream=stream)
 
-    def run(self, test_set=None, classifier=None,
-            context=None, setup_fn=None, teardown_fn=None,
-            win_multiprocessing=None):
+    def run(self, test_set=None):
 
         ret = 0
         h = self.host
@@ -212,8 +152,9 @@
             self.print_(VERSION)
             return ret, None, None
 
-        self._handle_win_multiprocessing('Runner.run', win_multiprocessing,
-                                         allow_spawn=False)
+        should_spawn = self._check_win_multiprocessing()
+        if should_spawn:
+            return self._spawn(test_set)
 
         ret = self._set_up_runner()
         if ret:  # pragma: no cover
@@ -228,8 +169,7 @@
         result_set = ResultSet()
 
         if not test_set:
-            ret, test_set = self.find_tests(self.args, classifier, context,
-                                            setup_fn, teardown_fn)
+            ret, test_set = self.find_tests(self.args)
         find_end = h.time()
 
         if not ret:
@@ -243,8 +183,8 @@
         trace = self._trace_from_results(result_set)
         if full_results:
             self._summarize(full_results)
-            self.write_results(full_results)
-            upload_ret = self.upload_results(full_results)
+            self._write(self.args.write_full_results_to, full_results)
+            upload_ret = self._upload(full_results)
             if not ret:
                 ret = upload_ret
             reporting_end = h.time()
@@ -252,13 +192,93 @@
             self._add_trace_event(trace, 'discovery', find_start, find_end)
             self._add_trace_event(trace, 'testing', find_end, test_end)
             self._add_trace_event(trace, 'reporting', test_end, reporting_end)
-            self.write_trace(trace)
+            self._write(self.args.write_trace_to, trace)
             self.report_coverage()
         else:
             upload_ret = 0
 
         return ret, full_results, trace
 
+    def _check_win_multiprocessing(self):
+        wmp = self.win_multiprocessing
+
+        ignore, importable, spawn = WinMultiprocessing.values
+
+        if wmp not in WinMultiprocessing.values:
+            raise ValueError('illegal value %s for win_multiprocessing' %
+                             wmp)
+
+        h = self.host
+        if wmp == ignore and h.platform == 'win32':  # pragma: win32
+            raise ValueError('Cannot use WinMultiprocessing.ignore for '
+                             'win_multiprocessing when actually running '
+                             'on Windows.')
+
+        if wmp == ignore or self.args.jobs == 1:
+            return False
+
+        if wmp == importable:
+            if self._main_is_importable():
+                return False
+            raise ValueError('The __main__ module (%s) '  # pragma: no cover
+                             'may not be importable' %
+                             sys.modules['__main__'].__file__)
+
+        assert wmp == spawn
+        return True
+
+    def _main_is_importable(self):  # pragma: untested
+        path = sys.modules['__main__'].__file__
+        if not path:
+            return False
+        if path.endswith('.pyc'):
+            path = path[:-1]
+        if not path.endswith('.py'):
+            return False
+        if path.endswith('__main__.py'):
+            # main modules are not directly importable.
+            return False
+
+        path = self.host.realpath(path)
+        for d in sys.path:
+            if path.startswith(self.host.realpath(d)):
+                return True
+        return False  # pragma: no cover
+
+    def _spawn(self, test_set):
+        # TODO: Handle picklable hooks, rather than requiring them to be None.
+        assert self.classifier is None
+        assert self.context is None
+        assert self.setup_fn is None
+        assert self.teardown_fn is None
+        assert test_set is None
+        h = self.host
+
+        if self.args.write_trace_to:  # pragma: untested
+            should_delete_trace = False
+        else:
+            should_delete_trace = True
+            fp = h.mktempfile(delete=False)
+            fp.close()
+            self.args.write_trace_to = fp.name
+
+        if self.args.write_full_results_to:  # pragma: untested
+            should_delete_results = False
+        else:
+            should_delete_results = True
+            fp = h.mktempfile(delete=False)
+            fp.close()
+            self.args.write_full_results_to = fp.name
+
+        argv = ArgumentParser(h).argv_from_args(self.args)
+        ret = h.call_inline([h.python_interpreter, path_to_file] + argv)
+
+        trace = self._read_and_delete(self.args.write_trace_to,
+                                      should_delete_trace)
+        full_results = self._read_and_delete(self.args.write_full_results_to,
+                                             should_delete_results)
+        return ret, full_results, trace
+
     def _set_up_runner(self):
         h = self.host
         args = self.args
@@ -303,11 +323,8 @@
             self.cov.erase()
         return 0
 
-    def find_tests(self, args, classifier=None,
-                   context=None, setup_fn=None, teardown_fn=None):
-        test_set = self._make_test_set(context=context,
-                                       setup_fn=setup_fn,
-                                       teardown_fn=teardown_fn)
+    def find_tests(self, args):
+        test_set = TestSet()
 
         orig_skip = unittest.skip
         orig_skip_if = unittest.skipIf
@@ -317,7 +334,7 @@
 
         try:
             names = self._name_list_from_args(args)
-            classifier = classifier or _default_classifier(args)
+            classifier = self.classifier or _default_classifier(args)
 
             for name in names:
                 try:
@@ -396,7 +413,7 @@
 
         self._run_one_set(self.stats, result_set, test_set)
 
-        failed_tests = json_results.failed_test_names(result_set)
+        failed_tests = sorted(json_results.failed_test_names(result_set))
         retry_limit = self.args.retry_limit
 
         while retry_limit and failed_tests:
@@ -414,11 +431,7 @@
 
             stats = Stats(self.args.status_format, h.time, 1)
             stats.total = len(failed_tests)
-            tests_to_retry = self._make_test_set(
-                isolated_tests=[TestInput(name) for name in failed_tests],
-                context=test_set.context,
-                setup_fn=test_set.setup_fn,
-                teardown_fn=test_set.teardown_fn)
+            tests_to_retry = TestSet(isolated_tests=list(failed_tests))
             retry_set = ResultSet()
             self._run_one_set(stats, retry_set, tests_to_retry)
             result_set.results.extend(retry_set.results)
@@ -435,26 +448,14 @@
         return (json_results.exit_code_from_full_results(full_results),
                 full_results)
 
-    def _make_test_set(self, parallel_tests=None, isolated_tests=None,
-                       tests_to_skip=None, context=None, setup_fn=None,
-                       teardown_fn=None):
-        parallel_tests = parallel_tests or []
-        isolated_tests = isolated_tests or []
-        tests_to_skip = tests_to_skip or []
-        return TestSet(_sort_inputs(parallel_tests),
-                       _sort_inputs(isolated_tests),
-                       _sort_inputs(tests_to_skip),
-                       context, setup_fn, teardown_fn)
-
     def _run_one_set(self, stats, result_set, test_set):
         stats.total = (len(test_set.parallel_tests) +
                        len(test_set.isolated_tests) +
                        len(test_set.tests_to_skip))
         self._skip_tests(stats, result_set, test_set.tests_to_skip)
-        self._run_list(stats, result_set, test_set,
-                       test_set.parallel_tests, self.args.jobs)
-        self._run_list(stats, result_set, test_set,
-                       test_set.isolated_tests, 1)
+        self._run_list(stats, result_set, test_set.parallel_tests,
+                       self.args.jobs)
+        self._run_list(stats, result_set, test_set.isolated_tests, 1)
 
     def _skip_tests(self, stats, result_set, tests_to_skip):
         for test_input in tests_to_skip:
@@ -470,7 +471,7 @@
             stats.finished += 1
             self._print_test_finished(stats, result)
 
-    def _run_list(self, stats, result_set, test_set, test_inputs, jobs):
+    def _run_list(self, stats, result_set, test_inputs, jobs):
         h = self.host
         running_jobs = set()
 
@@ -478,7 +479,7 @@
         if not jobs:
             return
 
-        child = _Child(self, self.loader, test_set)
+        child = _Child(self)
         pool = make_pool(h, jobs, _run_one_test, child,
                          _setup_process, _teardown_process)
         try:
@@ -572,19 +573,22 @@
                      '' if num_failures == 1 else 's'), elide=False)
         self.print_()
 
-    def write_trace(self, trace):
-        if self.args.write_trace_to:
-            self.host.write_text_file(
-                self.args.write_trace_to,
-                json.dumps(trace, indent=2) + '\n')
+    def _read_and_delete(self, path, delete):
+        h = self.host
+        obj = None
+        if h.exists(path):
+            contents = h.read_text_file(path)
+            if contents:
+                obj = json.loads(contents)
+            if delete:
+                h.remove(path)
+        return obj
 
-    def write_results(self, full_results):
-        if self.args.write_full_results_to:
-            self.host.write_text_file(
-                self.args.write_full_results_to,
-                json.dumps(full_results, indent=2) + '\n')
+    def _write(self, path, obj):
+        if path:
+            self.host.write_text_file(path, json.dumps(obj, indent=2) + '\n')
 
-    def upload_results(self, full_results):
+    def _upload(self, full_results):
         h = self.host
         if not self.args.test_results_server:
             return 0
@@ -697,7 +701,7 @@
 
 class _Child(object):
 
-    def __init__(self, parent, loader, test_set):
+    def __init__(self, parent):
         self.host = None
         self.worker_num = None
         self.all = parent.args.all
@@ -705,11 +709,11 @@
         self.coverage = parent.args.coverage and parent.args.jobs > 1
         self.coverage_source = parent.coverage_source
         self.dry_run = parent.args.dry_run
-        self.loader = loader
+        self.loader = parent.loader
         self.passthrough = parent.args.passthrough
-        self.context = test_set.context
-        self.setup_fn = test_set.setup_fn
-        self.teardown_fn = test_set.teardown_fn
+        self.context = parent.context
+        self.setup_fn = parent.setup_fn
+        self.teardown_fn = parent.teardown_fn
         self.context_after_setup = None
         self.top_level_dir = parent.top_level_dir
         self.loaded_suites = {}
@@ -897,4 +901,5 @@
 
 
 if __name__ == '__main__':  # pragma: no cover
-    sys.exit(main(win_multiprocessing='spawn'))
+    sys.modules['__main__'].__file__ = path_to_file
+    sys.exit(main(win_multiprocessing=WinMultiprocessing.importable))
diff --git a/third_party/typ/typ/tests/host_test.py b/third_party/typ/typ/tests/host_test.py
index 50db37f..a06085ac 100644
--- a/third_party/typ/typ/tests/host_test.py
+++ b/third_party/typ/typ/tests/host_test.py
@@ -130,6 +130,12 @@
         self.assertEqual(h.basename('foo.txt'), 'foo.txt')
         self.assertEqual(h.basename('foo/bar.txt'), 'bar.txt')
 
+    def test_mktempfile(self, delete=False):
+        h = self.host()
+        f= h.mktempfile()
+        f.close()
+        self.assertNotEqual(f.name, None)
+
     def test_splitext(self):
         h = self.host()
         self.assertEqual(h.splitext('foo'), ('foo', ''))
diff --git a/third_party/typ/typ/tests/runner_test.py b/third_party/typ/typ/tests/runner_test.py
index 1d3b0cc5..1d8e5103 100644
--- a/third_party/typ/typ/tests/runner_test.py
+++ b/third_party/typ/typ/tests/runner_test.py
@@ -18,7 +18,7 @@
 
 
 from typ import Host, Runner, TestCase, TestSet, TestInput
-from typ import WinMultiprocessing, main
+from typ import WinMultiprocessing
 
 
 def _setup_process(child, context):  # pylint: disable=W0613
@@ -33,8 +33,11 @@
     def test_context(self):
         r = Runner()
         r.args.tests = ['typ.tests.runner_test.ContextTests']
-        ret, _, _ = r.run(context={'foo': 'bar'}, setup_fn=_setup_process,
-                          teardown_fn=_teardown_process)
+        r.context = {'foo': 'bar'}
+        r.setup_fn = _setup_process
+        r.teardown_fn = _teardown_process
+        r.win_multiprocessing = WinMultiprocessing.importable
+        ret, _, _ = r.run()
         self.assertEqual(ret, 0)
 
     def test_bad_default(self):
@@ -57,6 +60,7 @@
         test_set = TestSet()
         test_set.parallel_tests = [TestInput('nonexistent test')]
         r = Runner()
+        r.args.jobs = 1
         ret, _, _ = r.run(test_set)
         self.assertEqual(ret, 1)
 
@@ -75,6 +79,7 @@
             test_set = TestSet()
             test_set.parallel_tests = [TestInput('load_test.BaseTest.test_x')]
             r = Runner()
+            r.args.jobs = 1
             ret, _, _ = r.run(test_set)
             self.assertEqual(ret, 1)
         finally:
@@ -87,7 +92,7 @@
     def make_host(self):
         return Host()
 
-    def call(self, argv, platform=None, importable=None, **kwargs):
+    def call(self, argv, platform=None, win_multiprocessing=None, **kwargs):
         h = self.make_host()
         orig_wd = h.getcwd()
         tmpdir = None
@@ -98,8 +103,8 @@
             if platform is not None:
                 h.platform = platform
             r = Runner(h)
-            if importable is not None:
-                r._main_is_importable = lambda: importable
+            if win_multiprocessing is not None:
+                r.win_multiprocessing = win_multiprocessing
             ret = r.main(argv, **kwargs)
         finally:
             out, err = h.restore_output()
@@ -112,64 +117,19 @@
     def test_bad_value(self):
         self.assertRaises(ValueError, self.call, [], win_multiprocessing='foo')
 
-    def test_force(self):
-        h = self.make_host()
-        tmpdir = None
-        orig_wd = h.getcwd()
-        out = err = None
-        out_str = err_str = ''
-        try:
-            tmpdir = h.mkdtemp()
-            h.chdir(tmpdir)
-            out = tempfile.NamedTemporaryFile(delete=False)
-            err = tempfile.NamedTemporaryFile(delete=False)
-            ret = main([], stdout=out, stderr=err,
-                       win_multiprocessing=WinMultiprocessing.force)
-        finally:
-            h.chdir(orig_wd)
-            if tmpdir:
-                h.rmtree(tmpdir)
-            if out:
-                out.close()
-                out = open(out.name)
-                out_str = out.read()
-                out.close()
-                h.remove(out.name)
-            if err:
-                err.close()
-                err = open(err.name)
-                err_str = err.read()
-                err.close()
-                h.remove(err.name)
-
-        self.assertEqual(ret, 1)
-        self.assertEqual(out_str, 'No tests to run.\n')
-        self.assertEqual(err_str, '')
-
     def test_ignore(self):
         h = self.make_host()
         if h.platform == 'win32':  # pragma: win32
             self.assertRaises(ValueError, self.call, [],
                               win_multiprocessing=WinMultiprocessing.ignore)
         else:
-            result = self.call([], platform=None, importable=False,
+            result = self.call([],
                                win_multiprocessing=WinMultiprocessing.ignore)
             ret, out, err = result
             self.assertEqual(ret, 1)
             self.assertEqual(out, 'No tests to run.\n')
             self.assertEqual(err, '')
 
-    def test_multiple_jobs(self):
-        self.assertRaises(ValueError, self.call, ['-j', '2'],
-                          platform='win32', importable=False)
-
-    def test_normal(self):
-        # This tests that typ itself is importable ...
-        ret, out, err = self.call([])
-        self.assertEqual(ret, 1)
-        self.assertEqual(out, 'No tests to run.\n')
-        self.assertEqual(err, '')
-
     def test_real_unimportable_main(self):
         h = self.make_host()
         tmpdir = None
@@ -182,11 +142,19 @@
             out = tempfile.NamedTemporaryFile(delete=False)
             err = tempfile.NamedTemporaryFile(delete=False)
             path_above_typ = h.realpath(h.dirname(__file__), '..', '..')
-            env = {'PYTHONPATH': path_above_typ}
+            env = h.env.copy()
+            if 'PYTHONPATH' in env:  # pragma: untested
+                env['PYTHONPATH'] = '%s%s%s' % (env['PYTHONPATH'],
+                                                h.pathsep,
+                                                path_above_typ)
+            else:  # pragma: untested.
+                env['PYTHONPATH'] = path_above_typ
+
             h.write_text_file('test', d("""
                 import sys
                 import typ
-                sys.exit(typ.main())
+                importable = typ.WinMultiprocessing.importable
+                sys.exit(typ.main(win_multiprocessing=importable))
                 """))
             h.stdout = out
             h.stderr = err
@@ -211,28 +179,19 @@
 
         self.assertEqual(ret, 1)
         self.assertEqual(out_str, '')
-        self.assertIn('ValueError: The __main__ module is not importable',
+        self.assertIn('ValueError: The __main__ module ',
                       err_str)
 
-    def test_run_serially(self):
-        ret, out, err = self.call([], importable=False,
-                                  win_multiprocessing=WinMultiprocessing.spawn)
-        self.assertEqual(ret, 1)
-        self.assertEqual(out, 'No tests to run.\n')
-        self.assertEqual(err, '')
-
     def test_single_job(self):
-        ret, out, err = self.call(['-j', '1'], platform='win32',
-                                  importable=False)
+        ret, out, err = self.call(['-j', '1'], platform='win32')
         self.assertEqual(ret, 1)
-        self.assertEqual(out, 'No tests to run.\n')
+        self.assertIn('No tests to run.', out)
         self.assertEqual(err, '')
 
     def test_spawn(self):
-        ret, out, err = self.call([], importable=False,
-                                  win_multiprocessing=WinMultiprocessing.spawn)
+        ret, out, err = self.call([])
         self.assertEqual(ret, 1)
-        self.assertEqual(out, 'No tests to run.\n')
+        self.assertIn('No tests to run.', out)
         self.assertEqual(err, '')
 
 
diff --git a/third_party/typ/typ/version.py b/third_party/typ/typ/version.py
index 96ebc7a..3b66ba0 100644
--- a/third_party/typ/typ/version.py
+++ b/third_party/typ/typ/version.py
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-VERSION = '0.8.5'
+VERSION = '0.8.6'
diff --git a/tools/android/checkstyle/chromium-style-5.0.xml b/tools/android/checkstyle/chromium-style-5.0.xml
index 17b44b4..46b19e9a 100644
--- a/tools/android/checkstyle/chromium-style-5.0.xml
+++ b/tools/android/checkstyle/chromium-style-5.0.xml
@@ -164,6 +164,27 @@
       <property name="throwsIndent" value="8"/>
       <property name="lineWrappingIndentation" value="8"/>
     </module>
+    <!-- TODO(aurimas): make OperatorWrap into an error once all the warnings are fixed. -->
+    <module name="OperatorWrap">
+      <property name="severity" value="warning"/>
+      <property name="option" value="NL" />
+      <property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR " />
+    </module>
+    <module name="OperatorWrap">
+     <property name="severity" value="warning"/>
+     <property name="option" value="eol"/>
+     <property name="tokens" value="ASSIGN"/>
+    </module>
+    <module name="SeparatorWrap">
+      <property name="severity" value="warning"/>
+      <property name="tokens" value="DOT"/>
+      <property name="option" value="nl"/>
+    </module>
+    <module name="SeparatorWrap">
+      <property name="severity" value="warning"/>
+      <property name="tokens" value="COMMA"/>
+      <property name="option" value="EOL"/>
+    </module>
   </module>
   <module name="FileTabCharacter">
     <property name="severity" value="error"/>
diff --git a/tools/android/forwarder2/device_forwarder_main.cc b/tools/android/forwarder2/device_forwarder_main.cc
index cad46f4..aeb2853 100644
--- a/tools/android/forwarder2/device_forwarder_main.cc
+++ b/tools/android/forwarder2/device_forwarder_main.cc
@@ -68,7 +68,7 @@
   }
 
   // Daemon::ServerDelegate:
-  virtual void Init() OVERRIDE {
+  virtual void Init() override {
     DCHECK(!g_notifier);
     g_notifier = new forwarder2::PipeNotifier();
     signal(SIGTERM, KillHandler);
@@ -77,7 +77,7 @@
     controller_thread_->Start();
   }
 
-  virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE {
+  virtual void OnClientConnected(scoped_ptr<Socket> client_socket) override {
     if (initialized_) {
       client_socket->WriteString("OK");
       return;
@@ -119,7 +119,7 @@
   bool has_failed() const { return has_failed_; }
 
   // Daemon::ClientDelegate:
-  virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
+  virtual void OnDaemonReady(Socket* daemon_socket) override {
     char buf[kBufSize];
     const int bytes_read = daemon_socket->Read(
         buf, sizeof(buf) - 1 /* leave space for null terminator */);
diff --git a/tools/android/forwarder2/host_forwarder_main.cc b/tools/android/forwarder2/host_forwarder_main.cc
index 59571b66..514ad93 100644
--- a/tools/android/forwarder2/host_forwarder_main.cc
+++ b/tools/android/forwarder2/host_forwarder_main.cc
@@ -311,7 +311,7 @@
   }
 
   // Daemon::ServerDelegate:
-  virtual void Init() OVERRIDE {
+  virtual void Init() override {
     LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")";
     DCHECK(!g_notifier);
     g_notifier = new PipeNotifier();
@@ -319,7 +319,7 @@
     signal(SIGINT, KillHandler);
   }
 
-  virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE {
+  virtual void OnClientConnected(scoped_ptr<Socket> client_socket) override {
     char buf[kBufSize];
     const int bytes_read = client_socket->Read(buf, sizeof(buf));
     if (bytes_read <= 0) {
@@ -362,7 +362,7 @@
   bool has_failed() const { return has_failed_; }
 
   // Daemon::ClientDelegate:
-  virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
+  virtual void OnDaemonReady(Socket* daemon_socket) override {
     // Send the forward command to the daemon.
     CHECK_EQ(command_pickle_.size(),
              daemon_socket->WriteNumBytes(command_pickle_.data(),
diff --git a/tools/android/heap_profiler/heap_profiler_unittest.cc b/tools/android/heap_profiler/heap_profiler_unittest.cc
index 65c2700..d69af5f7 100644
--- a/tools/android/heap_profiler/heap_profiler_unittest.cc
+++ b/tools/android/heap_profiler/heap_profiler_unittest.cc
@@ -14,9 +14,9 @@
 
 class HeapProfilerTest : public testing::Test {
  public:
-  virtual void SetUp() OVERRIDE { heap_profiler_init(&stats_); }
+  virtual void SetUp() override { heap_profiler_init(&stats_); }
 
-  virtual void TearDown() OVERRIDE {
+  virtual void TearDown() override {
     CheckAllocVsStacktaceConsistency();
     heap_profiler_cleanup();
   }
diff --git a/tools/android/memconsumer/java/src/org/chromium/memconsumer/ResidentService.java b/tools/android/memconsumer/java/src/org/chromium/memconsumer/ResidentService.java
index 4d3d03f8..45e0eb81 100644
--- a/tools/android/memconsumer/java/src/org/chromium/memconsumer/ResidentService.java
+++ b/tools/android/memconsumer/java/src/org/chromium/memconsumer/ResidentService.java
@@ -40,12 +40,12 @@
             PendingIntent pendingIntent =
                     PendingIntent.getActivity(this, 0, notificationIntent, 0);
             Notification notification =
-                    new Notification.Builder(getApplicationContext()).
-                            setContentTitle("MC running (" + memory + "Mb)").
-                            setSmallIcon(R.drawable.notification_icon).
-                            setDeleteIntent(pendingIntent).
-                            setContentIntent(pendingIntent).
-                            build();
+                    new Notification.Builder(getApplicationContext())
+                            .setContentTitle("MC running (" + memory + "Mb)")
+                            .setSmallIcon(R.drawable.notification_icon)
+                            .setDeleteIntent(pendingIntent)
+                            .setContentIntent(pendingIntent)
+                            .build();
             startForeground(RESIDENT_NOTIFICATION_ID, notification);
             mIsInForeground = true;
         }
diff --git a/tools/auto_bisect/PRESUBMIT.py b/tools/auto_bisect/PRESUBMIT.py
index 0cfdd189..6fc3c6ec 100644
--- a/tools/auto_bisect/PRESUBMIT.py
+++ b/tools/auto_bisect/PRESUBMIT.py
@@ -12,13 +12,12 @@
 import subprocess
 import os
 
-# Paths to bisect config files relative to src/tools.
+# Paths to bisect config files relative to this script.
 CONFIG_FILES = [
-    'auto_bisect/config.cfg',
-    'run-perf-test.cfg'
+    'bisect.cfg',
+    os.path.join(os.path.pardir, 'run-perf-test.cfg'),
 ]
 
-
 def CheckChangeOnUpload(input_api, output_api):
   return _CommonChecks(input_api, output_api)
 
@@ -39,10 +38,10 @@
 def _CheckAllConfigFiles(input_api, output_api):
   """Checks all bisect config files and returns a list of presubmit results."""
   results = []
-  for f in input_api.AffectedFiles():
-    for config_file in CONFIG_FILES:
-      if f.LocalPath().endswith(config_file):
-        results.extend(_CheckConfigFile(config_file, output_api))
+  script_path = input_api.PresubmitLocalPath()
+  for config_file in CONFIG_FILES:
+    file_path = os.path.join(script_path, config_file)
+    results.extend(_CheckConfigFile(file_path, output_api))
   return results
 
 
@@ -54,7 +53,7 @@
     warning = 'Failed to read config file %s: %s' % (file_path, str(e))
     return [output_api.PresubmitError(warning, items=[file_path])]
 
-  if not hasattr(config_file.config):
+  if not hasattr(config_file, 'config'):
     warning = 'Config file has no "config" global variable: %s' % str(e)
     return [output_api.PresubmitError(warning, items=[file_path])]
 
diff --git a/tools/auto_bisect/bisect_perf_regression.py b/tools/auto_bisect/bisect_perf_regression.py
index e80fd43..52799962 100755
--- a/tools/auto_bisect/bisect_perf_regression.py
+++ b/tools/auto_bisect/bisect_perf_regression.py
@@ -33,7 +33,6 @@
 """
 
 import copy
-import datetime
 import errno
 import hashlib
 import optparse
@@ -49,7 +48,9 @@
 sys.path.append(os.path.join(
     os.path.dirname(__file__), os.path.pardir, 'telemetry'))
 
+from bisect_printer import BisectPrinter
 from bisect_results import BisectResults
+from bisect_state import BisectState
 import bisect_utils
 import builder
 import math_utils
@@ -57,99 +58,6 @@
 import source_control
 from telemetry.util import cloud_storage
 
-# Below is the map of "depot" names to information about each depot. Each depot
-# is a repository, and in the process of bisecting, revision ranges in these
-# repositories may also be bisected.
-#
-# Each depot information dictionary may contain:
-#   src: Path to the working directory.
-#   recurse: True if this repository will get bisected.
-#   depends: A list of other repositories that are actually part of the same
-#       repository in svn. If the repository has any dependent repositories
-#       (e.g. skia/src needs skia/include and skia/gyp to be updated), then
-#       they are specified here.
-#   svn: URL of SVN repository. Needed for git workflow to resolve hashes to
-#       SVN revisions.
-#   from: Parent depot that must be bisected before this is bisected.
-#   deps_var: Key name in vars variable in DEPS file that has revision
-#       information.
-DEPOT_DEPS_NAME = {
-    'chromium': {
-        'src': 'src',
-        'recurse': True,
-        'depends': None,
-        'from': ['cros', 'android-chrome'],
-        'viewvc':
-            'http://src.chromium.org/viewvc/chrome?view=revision&revision=',
-        'deps_var': 'chromium_rev'
-    },
-    'webkit': {
-        'src': 'src/third_party/WebKit',
-        'recurse': True,
-        'depends': None,
-        'from': ['chromium'],
-        'viewvc':
-            'http://src.chromium.org/viewvc/blink?view=revision&revision=',
-        'deps_var': 'webkit_revision'
-    },
-    'angle': {
-        'src': 'src/third_party/angle',
-        'src_old': 'src/third_party/angle_dx11',
-        'recurse': True,
-        'depends': None,
-        'from': ['chromium'],
-        'platform': 'nt',
-        'deps_var': 'angle_revision'
-    },
-    'v8': {
-        'src': 'src/v8',
-        'recurse': True,
-        'depends': None,
-        'from': ['chromium'],
-        'custom_deps': bisect_utils.GCLIENT_CUSTOM_DEPS_V8,
-        'viewvc': 'https://code.google.com/p/v8/source/detail?r=',
-        'deps_var': 'v8_revision'
-    },
-    'v8_bleeding_edge': {
-        'src': 'src/v8_bleeding_edge',
-        'recurse': True,
-        'depends': None,
-        'svn': 'https://v8.googlecode.com/svn/branches/bleeding_edge',
-        'from': ['v8'],
-        'viewvc': 'https://code.google.com/p/v8/source/detail?r=',
-        'deps_var': 'v8_revision'
-    },
-    'skia/src': {
-        'src': 'src/third_party/skia/src',
-        'recurse': True,
-        'svn': 'http://skia.googlecode.com/svn/trunk/src',
-        'depends': ['skia/include', 'skia/gyp'],
-        'from': ['chromium'],
-        'viewvc': 'https://code.google.com/p/skia/source/detail?r=',
-        'deps_var': 'skia_revision'
-    },
-    'skia/include': {
-        'src': 'src/third_party/skia/include',
-        'recurse': False,
-        'svn': 'http://skia.googlecode.com/svn/trunk/include',
-        'depends': None,
-        'from': ['chromium'],
-        'viewvc': 'https://code.google.com/p/skia/source/detail?r=',
-        'deps_var': 'None'
-    },
-    'skia/gyp': {
-        'src': 'src/third_party/skia/gyp',
-        'recurse': False,
-        'svn': 'http://skia.googlecode.com/svn/trunk/gyp',
-        'depends': None,
-        'from': ['chromium'],
-        'viewvc': 'https://code.google.com/p/skia/source/detail?r=',
-        'deps_var': 'None'
-    }
-}
-
-DEPOT_NAMES = DEPOT_DEPS_NAME.keys()
-
 # The script is in chromium/src/tools/auto_bisect. Throughout this script,
 # we use paths to other things in the chromium/src repository.
 
@@ -167,8 +75,9 @@
 MAX_WIN_BUILD_TIME = 14400
 MAX_LINUX_BUILD_TIME = 14400
 
-# The percentage at which confidence is considered high.
-HIGH_CONFIDENCE = 95
+# The confidence percentage we require to consider the initial range a
+# regression based on the test results of the inital good and bad revisions.
+REGRESSION_CONFIDENCE = 95
 
 # Patch template to add a new file, DEPS.sha under src folder.
 # This file contains SHA1 value of the DEPS changes made while bisecting
@@ -184,71 +93,22 @@
 +%(deps_sha)s
 """
 
-# The possible values of the --bisect_mode flag, which determines what to
-# use when classifying a revision as "good" or "bad".
-BISECT_MODE_MEAN = 'mean'
-BISECT_MODE_STD_DEV = 'std_dev'
-BISECT_MODE_RETURN_CODE = 'return_code'
+REGRESSION_CONFIDENCE_ERROR_TEMPLATE = """
+We could not reproduce the regression with this test/metric/platform combination
+with enough confidence.
 
-# The perf dashboard looks for a string like "Estimated Confidence: 95%"
-# to decide whether or not to cc the author(s). If you change this, please
-# update the perf dashboard as well.
-RESULTS_BANNER = """
-===== BISECT JOB RESULTS =====
-Status: %(status)s
+Here are the results for the initial revision range:
+'Good' revision: {good_rev}
+\tmean: {good_mean}
+\tstd.err.:{good_std_err}
+\tsample size:{good_sample_size}
+'Bad' revision: {bad_rev}
+\tmean: {bad_mean}
+\tstd.err.:{bad_std_err}
+\tsample size:{bad_sample_size}
 
-Test Command: %(command)s
-Test Metric: %(metrics)s
-Relative Change: %(change)s
-Estimated Confidence: %(confidence).02f%%"""
-
-# The perf dashboard specifically looks for the string
-# "Author  : " to parse out who to cc on a bug. If you change the
-# formatting here, please update the perf dashboard as well.
-RESULTS_REVISION_INFO = """
-===== SUSPECTED CL(s) =====
-Subject : %(subject)s
-Author  : %(author)s%(email_info)s%(commit_info)s
-Commit  : %(cl)s
-Date    : %(cl_date)s"""
-
-REPRO_STEPS_LOCAL = """
-==== INSTRUCTIONS TO REPRODUCE ====
-To run locally:
- - Use the test command given under 'BISECT JOB RESULTS' above.
- - Consider using a profiler. Pass --profiler=list to list available profilers.
-"""
-
-REPRO_STEPS_TRYJOB = """
-To reproduce on a performance try bot:
- 1. Edit run-perf-test.cfg
- 2. $ git try -b <bot> --svn_repo='svn://svn.chromium.org/chrome-try/try-perf'
-
-Notes:
- a) Follow the in-file instructions in run-perf-test.cfg.
- b) run-perf-test.cfg is under tools/ or under third_party/WebKit/Tools.
- c) Do your edits preferably under a new git branch.
- d) --browser=release and --browser=android-chromium-testshell are supported
-    depending on the platform (desktop|android).
- e) Strip any src/ directories from the head of relative path names.
- f) Make sure to use the appropriate bot on step 3.
-
-For more details please visit
-https://sites.google.com/a/chromium.org/dev/developers/performance-try-bots"""
-
-REPRO_STEPS_TRYJOB_TELEMETRY = """
-To reproduce on a performance try bot:
-%(command)s
-(Where <bot-name> comes from tools/perf/run_benchmark --browser=list)
-
-For more details please visit
-https://sites.google.com/a/chromium.org/dev/developers/performance-try-bots
-"""
-
-RESULTS_THANKYOU = """
-| O O | Visit http://www.chromium.org/developers/core-principles for Chrome's
-|  X  | policy on perf regressions. Contact chrome-perf-dashboard-team with any
-| / \ | questions or suggestions about bisecting. THANK YOU."""
+NOTE: There's still a chance that this is actually a regression, but you may
+      need to bisect a different platform."""
 
 # Git branch name used to run bisect try jobs.
 BISECT_TRYJOB_BRANCH = 'bisect-tryjob'
@@ -265,14 +125,6 @@
     return '%s\nError executing git command.' % self.args[0]
 
 
-def _AddAdditionalDepotInfo(depot_info):
-  """Adds additional depot info to the global depot variables."""
-  global DEPOT_DEPS_NAME
-  global DEPOT_NAMES
-  DEPOT_DEPS_NAME = dict(DEPOT_DEPS_NAME.items() + depot_info.items())
-  DEPOT_NAMES = DEPOT_DEPS_NAME.keys()
-
-
 def GetSHA1HexDigest(contents):
   """Returns SHA1 hex digest of the given string."""
   return hashlib.sha1(contents).hexdigest()
@@ -570,7 +422,7 @@
   in such cases check "deps" dictionary variable that matches
   angle.git@[a-fA-F0-9]{40}$ and replace git hash.
   """
-  deps_var = DEPOT_DEPS_NAME[depot]['deps_var']
+  deps_var = bisect_utils.DEPOT_DEPS_NAME[depot]['deps_var']
   try:
     deps_contents = ReadStringFromFile(deps_file)
     # Check whether the depot and revision pattern in DEPS file vars variable
@@ -758,85 +610,54 @@
   return True
 
 
-def _AddRevisionsIntoRevisionData(revisions, depot, sort, revision_data):
-  """Adds new revisions to the revision_data dictionary and initializes them.
+def _CheckRegressionConfidenceError(
+    good_revision,
+    bad_revision,
+    known_good_value,
+    known_bad_value):
+  """Checks whether we can be confident beyond a certain degree that the given
+  metrics represent a regression.
 
   Args:
-    revisions: List of revisions to add.
-    depot: Depot that's currently in use (src, webkit, etc...)
-    sort: Sorting key for displaying revisions.
-    revision_data: A dictionary to add the new revisions into.
-        Existing revisions will have their sort keys adjusted.
+    good_revision: string representing the commit considered 'good'
+    bad_revision: Same as above for 'bad'.
+    known_good_value: A dict with at least: 'values', 'mean' and 'std_err'
+    known_bad_value: Same as above.
+
+  Returns:
+    False if there is no error (i.e. we can be confident there's a regressioni),
+    a string containing the details of the lack of confidence otherwise.
   """
-  num_depot_revisions = len(revisions)
-
-  for _, v in revision_data.iteritems():
-    if v['sort'] > sort:
-      v['sort'] += num_depot_revisions
-
-  for i in xrange(num_depot_revisions):
-    r = revisions[i]
-    revision_data[r] = {
-        'revision' : r,
-        'depot' : depot,
-        'value' : None,
-        'perf_time' : 0,
-        'build_time' : 0,
-        'passed' : '?',
-        'sort' : i + sort + 1,
-    }
-
-
-def _PrintThankYou():
-  print RESULTS_THANKYOU
-
-
-def _PrintTableRow(column_widths, row_data):
-  """Prints out a row in a formatted table that has columns aligned.
-
-  Args:
-    column_widths: A list of column width numbers.
-    row_data: A list of items for each column in this row.
-  """
-  assert len(column_widths) == len(row_data)
-  text = ''
-  for i in xrange(len(column_widths)):
-    current_row_data = row_data[i].center(column_widths[i], ' ')
-    text += ('%%%ds' % column_widths[i]) % current_row_data
-  print text
-
-
-def _PrintStepTime(revision_data_sorted):
-  """Prints information about how long various steps took.
-
-  Args:
-    revision_data_sorted: The sorted list of revision data dictionaries."""
-  step_perf_time_avg = 0.0
-  step_build_time_avg = 0.0
-  step_count = 0.0
-  for _, current_data in revision_data_sorted:
-    if current_data['value']:
-      step_perf_time_avg += current_data['perf_time']
-      step_build_time_avg += current_data['build_time']
-      step_count += 1
-  if step_count:
-    step_perf_time_avg = step_perf_time_avg / step_count
-    step_build_time_avg = step_build_time_avg / step_count
-  print
-  print 'Average build time : %s' % datetime.timedelta(
-      seconds=int(step_build_time_avg))
-  print 'Average test time  : %s' % datetime.timedelta(
-      seconds=int(step_perf_time_avg))
-
+  error = False
+  # Adding good and bad values to a parameter list.
+  confidenceParams = []
+  for l in [known_bad_value['values'], known_good_value['values']]:
+    # Flatten if needed
+    if isinstance(l, list) and all([isinstance(x, list) for x in l]):
+      confidenceParams.append(sum(l, []))
+    else:
+      confidenceParams.append(l)
+  regression_confidence = BisectResults.ConfidenceScore(*confidenceParams)
+  if regression_confidence < REGRESSION_CONFIDENCE:
+    error = REGRESSION_CONFIDENCE_ERROR_TEMPLATE.format(
+        good_rev=good_revision,
+        good_mean=known_good_value['mean'],
+        good_std_err=known_good_value['std_err'],
+        good_sample_size=len(known_good_value['values']),
+        bad_rev=bad_revision,
+        bad_mean=known_bad_value['mean'],
+        bad_std_err=known_bad_value['std_err'],
+        bad_sample_size=len(known_bad_value['values']))
+  return error
 
 class DepotDirectoryRegistry(object):
 
   def __init__(self, src_cwd):
     self.depot_cwd = {}
-    for depot in DEPOT_NAMES:
+    for depot in bisect_utils.DEPOT_NAMES:
       # The working directory of each depot is just the path to the depot, but
       # since we're already in 'src', we can skip that part.
-      path_in_src = DEPOT_DEPS_NAME[depot]['src'][4:]
+      path_in_src = bisect_utils.DEPOT_DEPS_NAME[depot]['src'][4:]
       self.AddDepot(depot, os.path.join(src_cwd, path_in_src))
 
     self.AddDepot('chromium', src_cwd)
@@ -1051,8 +872,8 @@
                 'bleeding_edge revision r')[1]
             bleeding_edge_revision = int(bleeding_edge_revision.split(')')[0])
             git_revision = source_control.ResolveToRevision(
-                bleeding_edge_revision, 'v8_bleeding_edge', DEPOT_DEPS_NAME, 1,
-                cwd=v8_bleeding_edge_dir)
+                bleeding_edge_revision, 'v8_bleeding_edge',
+                bisect_utils.DEPOT_DEPS_NAME, 1, cwd=v8_bleeding_edge_dir)
             return git_revision
           except (IndexError, ValueError):
             pass
@@ -1060,8 +881,8 @@
         if not git_revision:
           # Wasn't successful, try the old way of looking for "Prepare push to"
           git_revision = source_control.ResolveToRevision(
-              int(commit_position) - 1, 'v8_bleeding_edge', DEPOT_DEPS_NAME, -1,
-              cwd=v8_bleeding_edge_dir)
+              int(commit_position) - 1, 'v8_bleeding_edge',
+              bisect_utils.DEPOT_DEPS_NAME, -1, cwd=v8_bleeding_edge_dir)
 
           if git_revision:
             revision_info = source_control.QueryRevisionInfo(git_revision,
@@ -1125,7 +946,7 @@
 
       rxp = re.compile(".git@(?P<revision>[a-fA-F0-9]+)")
       results = {}
-      for depot_name, depot_data in DEPOT_DEPS_NAME.iteritems():
+      for depot_name, depot_data in bisect_utils.DEPOT_DEPS_NAME.iteritems():
         if (depot_data.get('platform') and
             depot_data.get('platform') != os.name):
           continue
@@ -1154,10 +975,10 @@
       for depot_name, depot_revision in parse_results.iteritems():
         depot_revision = depot_revision.strip('@')
         print depot_name, depot_revision
-        for current_name, current_data in DEPOT_DEPS_NAME.iteritems():
-          if (current_data.has_key('deps_var') and
-              current_data['deps_var'] == depot_name):
-            src_name = current_name
+        for cur_name, cur_data in bisect_utils.DEPOT_DEPS_NAME.iteritems():
+          if (cur_data.has_key('deps_var') and
+              cur_data['deps_var'] == depot_name):
+            src_name = cur_name
             results[src_name] = depot_revision
             break
       return results
@@ -1252,18 +1073,19 @@
       return destination_dir
     return None
 
-  def GetBuildArchiveForRevision(self, revision, gs_bucket, target_arch,
-                                 patch_sha, out_dir):
+  def _GetBuildArchiveForRevision(self, revision, gs_bucket, target_arch,
+                                  patch_sha, out_dir):
     """Checks and downloads build archive for a given revision.
 
     Checks for build archive with Git hash or SVN revision. If either of the
     file exists, then downloads the archive file.
 
     Args:
-      revision: A Git hash revision.
-      gs_bucket: Cloud storage bucket name
-      target_arch: 32 or 64 bit build target
-      patch: A DEPS patch (used while bisecting 3rd party repositories).
+      revision: A git commit hash.
+      gs_bucket: Cloud storage bucket name.
+      target_arch: Architecture name string, e.g. "ia32" or "x64".
+      patch_sha: A SHA1 hex digest of a DEPS file patch, used while
+          bisecting 3rd party repositories.
       out_dir: Build output directory where downloaded file is stored.
 
     Returns:
@@ -1283,11 +1105,11 @@
         return FetchFromCloudStorage(gs_bucket, source_file, out_dir)
     return downloaded_archive
 
-  def DownloadCurrentBuild(self, revision, depot, build_type='Release'):
+  def _DownloadAndUnzipBuild(self, revision, depot, build_type='Release'):
     """Downloads the build archive for the given revision.
 
     Args:
-      revision: The git revision to download or build.
+      revision: The git revision to download.
       depot: The name of a dependency repository. Should be in DEPOT_NAMES.
       build_type: Target build type, e.g. Release', 'Debug', 'Release_x64' etc.
 
@@ -1308,30 +1130,138 @@
       # 'DEPS.sha' and add patch_sha evaluated above to it.
       patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha})
 
-    # Get build output directory.
     build_dir = builder.GetBuildOutputDirectory(self.opts, self.src_cwd)
-    abs_build_dir = os.path.abspath(build_dir)
+    downloaded_file = self._WaitForBuildDownload(
+        revision, build_dir, deps_patch=patch, deps_patch_sha=patch_sha)
+    if not downloaded_file:
+      return False
+    return self._UnzipAndMoveBuildProducts(downloaded_file, build_dir,
+                                           build_type=build_type)
 
-    fetch_build_func = lambda: self.GetBuildArchiveForRevision(
-      revision, self.opts.gs_bucket, self.opts.target_arch,
-      patch_sha, abs_build_dir)
+  def _WaitForBuildDownload(self, revision, build_dir, deps_patch=None,
+                            deps_patch_sha=None):
+    """Tries to download a zip archive for a build.
+
+    This involves seeing whether the archive is already available, and if not,
+    then requesting a build and waiting before downloading.
+
+    Args:
+      revision: A git commit hash.
+      build_dir: The directory to download the build into.
+      deps_patch: A patch which changes a dependency repository revision in
+          the DEPS, if applicable.
+      deps_patch_sha: The SHA1 hex digest of the above patch.
+
+    Returns:
+      File path of the downloaded file if successful, otherwise None.
+    """
+    abs_build_dir = os.path.abspath(build_dir)
+    fetch_build_func = lambda: self._GetBuildArchiveForRevision(
+        revision, self.opts.gs_bucket, self.opts.target_arch,
+        deps_patch_sha, abs_build_dir)
 
     # Downloaded archive file path, downloads build archive for given revision.
+    # This will be False if the build isn't yet available.
     downloaded_file = fetch_build_func()
 
-    # When build archive doesn't exists, post a build request to tryserver
+    # When build archive doesn't exist, post a build request to try server
     # and wait for the build to be produced.
     if not downloaded_file:
-      downloaded_file = self.PostBuildRequestAndWait(
-          revision, fetch_build=fetch_build_func, patch=patch)
+      downloaded_file = self._RequestBuildAndWait(
+          revision, fetch_build=fetch_build_func, patch=deps_patch)
       if not downloaded_file:
-        return False
+        return None
 
-    # Generic name for the archive, created when archive file is extracted.
+    return downloaded_file
+
+  def _RequestBuildAndWait(self, git_revision, fetch_build, patch=None):
+    """Triggers a try job for a build job.
+
+    This function prepares and starts a try job on the tryserver.chromium.perf
+    master, and waits for the binaries to be produced and archived in cloud
+    storage. Once the build is ready it's downloaded.
+
+    Args:
+      git_revision: A Git hash revision.
+      fetch_build: Function to check and download build from cloud storage.
+      patch: A DEPS patch (used while bisecting 3rd party repositories).
+
+    Returns:
+      Downloaded archive file path when requested build exists and download is
+      successful, otherwise None.
+    """
+    if not fetch_build:
+      return False
+
+    # Create a unique ID for each build request posted to try server builders.
+    # This ID is added to "Reason" property of the build.
+    build_request_id = GetSHA1HexDigest(
+        '%s-%s-%s' % (git_revision, patch, time.time()))
+
+    # Reverts any changes to DEPS file.
+    source_control.CheckoutFileAtRevision(
+      bisect_utils.FILE_DEPS, git_revision, cwd=self.src_cwd)
+
+    bot_name = self._GetBuilderName(self.opts.target_platform)
+    build_timeout = self._GetBuilderBuildTime()
+    target_file = None
+    try:
+      # Execute try job request to build revision with patch.
+      _BuilderTryjob(git_revision, bot_name, build_request_id, patch)
+      target_file, error_msg = _WaitUntilBuildIsReady(
+          fetch_build, bot_name, self.opts.builder_host,
+          self.opts.builder_port, build_request_id, build_timeout)
+      if not target_file:
+        print '%s [revision: %s]' % (error_msg, git_revision)
+    except RunGitError as e:
+      print ('Failed to post builder try job for revision: [%s].\n'
+             'Error: %s' % (git_revision, e))
+
+    return target_file
+
+  @staticmethod
+  def _GetBuilderName(target_platform):
+    """Gets builder bot name and build time in seconds based on platform."""
+    if bisect_utils.IsWindowsHost():
+      return 'win_perf_bisect_builder'
+    if bisect_utils.IsLinuxHost():
+      if target_platform == 'android':
+        return 'android_perf_bisect_builder'
+      return 'linux_perf_bisect_builder'
+    if bisect_utils.IsMacHost():
+      return 'mac_perf_bisect_builder'
+    raise NotImplementedError('Unsupported Platform "%s".' % sys.platform)
+
+  @staticmethod
+  def _GetBuilderBuildTime():
+    """Returns the time to wait for a build after requesting one."""
+    if bisect_utils.IsWindowsHost():
+      return MAX_WIN_BUILD_TIME
+    if bisect_utils.IsLinuxHost():
+      return MAX_LINUX_BUILD_TIME
+    if bisect_utils.IsMacHost():
+      return MAX_MAC_BUILD_TIME
+    raise NotImplementedError('Unsupported Platform "%s".' % sys.platform)
+
+  def _UnzipAndMoveBuildProducts(self, downloaded_file, build_dir,
+                                 build_type='Release'):
+    """Unzips the build archive and moves it to the build output directory.
+
+    The build output directory is whereever the binaries are expected to
+    be in order to start Chrome and run tests.
+
+    Args:
+      downloaded_file: File path of the downloaded zip file.
+      build_dir: Directory where the the zip file was downloaded to.
+      build_type: "Release" or "Debug".
+
+    Returns:
+      True if successful, False otherwise.
+    """
+    abs_build_dir = os.path.abspath(build_dir)
     output_dir = os.path.join(
         abs_build_dir, GetZipFileName(target_arch=self.opts.target_arch))
 
-    # Unzip build archive directory.
     try:
       RemoveDirectoryTree(output_dir)
       self.BackupOrRestoreOutputDirectory(restore=False)
@@ -1362,74 +1292,13 @@
         os.remove(downloaded_file)
     return False
 
-  def PostBuildRequestAndWait(self, git_revision, fetch_build, patch=None):
-    """POSTs the build request job to the try server instance.
-
-    A try job build request is posted to tryserver.chromium.perf master,
-    and waits for the binaries to be produced and archived on cloud storage.
-    Once the build is ready and stored onto cloud, build archive is downloaded
-    into the output folder.
-
-    Args:
-      git_revision: A Git hash revision.
-      fetch_build: Function to check and download build from cloud storage.
-      patch: A DEPS patch (used while bisecting 3rd party repositories).
-
-    Returns:
-      Downloaded archive file path when requested build exists and download is
-      successful, otherwise None.
-    """
-    def GetBuilderNameAndBuildTime(target_platform, target_arch='ia32'):
-      """Gets builder bot name and build time in seconds based on platform."""
-      # Bot names should match the one listed in tryserver.chromium's
-      # master.cfg which produces builds for bisect.
-      if bisect_utils.IsWindowsHost():
-        if bisect_utils.Is64BitWindows() and target_arch == 'x64':
-          return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME)
-        return ('win_perf_bisect_builder', MAX_WIN_BUILD_TIME)
-      if bisect_utils.IsLinuxHost():
-        if target_platform == 'android':
-          return ('android_perf_bisect_builder', MAX_LINUX_BUILD_TIME)
-        return ('linux_perf_bisect_builder', MAX_LINUX_BUILD_TIME)
-      if bisect_utils.IsMacHost():
-        return ('mac_perf_bisect_builder', MAX_MAC_BUILD_TIME)
-      raise NotImplementedError('Unsupported Platform "%s".' % sys.platform)
-    if not fetch_build:
-      return False
-
-    # Create a unique ID for each build request posted to try server builders.
-    # This ID is added to "Reason" property of the build.
-    build_request_id = GetSHA1HexDigest(
-        '%s-%s-%s' % (git_revision, patch, time.time()))
-
-    # Reverts any changes to DEPS file.
-    source_control.CheckoutFileAtRevision(
-      bisect_utils.FILE_DEPS, git_revision, cwd=self.src_cwd)
-
-    bot_name, build_timeout = GetBuilderNameAndBuildTime(
-       self.opts.target_platform, self.opts.target_arch)
-    target_file = None
-    try:
-      # Execute try job request to build revision with patch.
-      _BuilderTryjob(git_revision, bot_name, build_request_id, patch)
-      target_file, error_msg = _WaitUntilBuildIsReady(
-          fetch_build, bot_name, self.opts.builder_host,
-          self.opts.builder_port, build_request_id, build_timeout)
-      if not target_file:
-        print '%s [revision: %s]' % (error_msg, git_revision)
-    except RunGitError as e:
-      print ('Failed to post builder try job for revision: [%s].\n'
-             'Error: %s' % (git_revision, e))
-
-    return target_file
-
   def IsDownloadable(self, depot):
     """Checks if build can be downloaded based on target platform and depot."""
     if (self.opts.target_platform in ['chromium', 'android'] and
         self.opts.gs_bucket):
       return (depot == 'chromium' or
-              'chromium' in DEPOT_DEPS_NAME[depot]['from'] or
-              'v8' in DEPOT_DEPS_NAME[depot]['from'])
+              'chromium' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'] or
+              'v8' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'])
     return False
 
   def UpdateDepsContents(self, deps_contents, depot, git_revision, deps_key):
@@ -1492,7 +1361,7 @@
     if not os.path.exists(deps_file):
       return False
 
-    deps_var = DEPOT_DEPS_NAME[depot]['deps_var']
+    deps_var = bisect_utils.DEPOT_DEPS_NAME[depot]['deps_var']
     # Don't update DEPS file if deps_var is not set in DEPOT_DEPS_NAME.
     if not deps_var:
       print 'DEPS update not supported for Depot: %s', depot
@@ -1537,8 +1406,8 @@
     if not chromium_sha:
       raise RuntimeError('Failed to determine Chromium revision for %s' %
                          revision)
-    if ('chromium' in DEPOT_DEPS_NAME[depot]['from'] or
-        'v8' in DEPOT_DEPS_NAME[depot]['from']):
+    if ('chromium' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'] or
+        'v8' in bisect_utils.DEPOT_DEPS_NAME[depot]['from']):
       # Checkout DEPS file for the current chromium revision.
       if source_control.CheckoutFileAtRevision(
           bisect_utils.FILE_DEPS, chromium_sha, cwd=self.src_cwd):
@@ -1560,11 +1429,16 @@
             'DEPS checkout Failed for chromium revision : [%s]' % chromium_sha)
     return (None, None)
 
-  def BuildCurrentRevision(self, depot, revision=None):
-    """Builds chrome and performance_ui_tests on the current revision.
+  def _ObtainBuild(self, depot, revision=None):
+    """Obtains a build by either downloading or building directly.
+
+    Args:
+      depot: Dependency repository name.
+      revision: A git commit hash. If None is given, the currently checked-out
+          revision is built.
 
     Returns:
-      True if the build was successful.
+      True for success.
     """
     if self.opts.debug_ignore_build:
       return True
@@ -1575,7 +1449,7 @@
     # Fetch build archive for the given revision from the cloud storage when
     # the storage bucket is passed.
     if self.IsDownloadable(depot) and revision:
-      build_success = self.DownloadCurrentBuild(revision, depot)
+      build_success = self._DownloadAndUnzipBuild(revision, depot)
     else:
       # These codes are executed when bisect bots builds binaries locally.
       build_success = self.builder.Build(depot, self.opts)
@@ -1593,13 +1467,14 @@
     return not bisect_utils.RunGClient(['runhooks'], cwd=self.src_cwd)
 
   def _IsBisectModeUsingMetric(self):
-    return self.opts.bisect_mode in [BISECT_MODE_MEAN, BISECT_MODE_STD_DEV]
+    return self.opts.bisect_mode in [bisect_utils.BISECT_MODE_MEAN,
+                                     bisect_utils.BISECT_MODE_STD_DEV]
 
   def _IsBisectModeReturnCode(self):
-    return self.opts.bisect_mode in [BISECT_MODE_RETURN_CODE]
+    return self.opts.bisect_mode in [bisect_utils.BISECT_MODE_RETURN_CODE]
 
   def _IsBisectModeStandardDeviation(self):
-    return self.opts.bisect_mode in [BISECT_MODE_STD_DEV]
+    return self.opts.bisect_mode in [bisect_utils.BISECT_MODE_STD_DEV]
 
   def GetCompatibleCommand(self, command_to_run, revision, depot):
     """Return a possibly modified test command depending on the revision.
@@ -1808,20 +1683,20 @@
     # figure out for each mirror which git revision to grab. There's no
     # guarantee that the SVN revision will exist for each of the dependent
     # depots, so we have to grep the git logs and grab the next earlier one.
-    if not is_base and DEPOT_DEPS_NAME[depot]['depends']:
+    if not is_base and bisect_utils.DEPOT_DEPS_NAME[depot]['depends']:
       commit_position = source_control.GetCommitPosition(revision)
 
-      for d in DEPOT_DEPS_NAME[depot]['depends']:
+      for d in bisect_utils.DEPOT_DEPS_NAME[depot]['depends']:
         self.depot_registry.ChangeToDepotDir(d)
 
         dependant_rev = source_control.ResolveToRevision(
-            commit_position, d, DEPOT_DEPS_NAME, -1000)
+            commit_position, d, bisect_utils.DEPOT_DEPS_NAME, -1000)
 
         if dependant_rev:
           revisions_to_sync.append([d, dependant_rev])
 
       num_resolved = len(revisions_to_sync)
-      num_needed = len(DEPOT_DEPS_NAME[depot]['depends'])
+      num_needed = len(bisect_utils.DEPOT_DEPS_NAME[depot]['depends'])
 
       self.depot_registry.ChangeToDepotDir(depot)
 
@@ -1959,7 +1834,7 @@
       if not self._SyncAllRevisions(revisions_to_sync, sync_client):
         return ('Failed to sync: [%s]' % str(revision), BUILD_RESULT_FAIL)
 
-     # Try to do any post-sync steps. This may include "gclient runhooks".
+    # Try to do any post-sync steps. This may include "gclient runhooks".
     if not self._RunPostSync(depot):
       return ('Failed to run [gclient runhooks].', BUILD_RESULT_FAIL)
 
@@ -1971,7 +1846,7 @@
     # Obtain a build for this revision. This may be done by requesting a build
     # from another builder, waiting for it and downloading it.
     start_build_time = time.time()
-    build_success = self.BuildCurrentRevision(depot, revision)
+    build_success = self._ObtainBuild(depot, revision)
     if not build_success:
       return ('Failed to build revision: [%s]' % str(revision),
               BUILD_RESULT_FAIL)
@@ -2023,7 +1898,8 @@
       # want so that all the dependencies sync properly as well.
       # i.e. gclient sync src@<SHA1>
       if sync_client == 'gclient':
-        revision = '%s@%s' % (DEPOT_DEPS_NAME[depot]['src'], revision)
+        revision = '%s@%s' % (bisect_utils.DEPOT_DEPS_NAME[depot]['src'],
+                              revision)
 
       sync_success = source_control.SyncToRevision(revision, sync_client)
       if not sync_success:
@@ -2044,7 +1920,7 @@
       True if the current_value is closer to the known_good_value than the
       known_bad_value.
     """
-    if self.opts.bisect_mode == BISECT_MODE_STD_DEV:
+    if self.opts.bisect_mode == bisect_utils.BISECT_MODE_STD_DEV:
       dist_to_good_value = abs(current_value['std_dev'] -
           known_good_value['std_dev'])
       dist_to_bad_value = abs(current_value['std_dev'] -
@@ -2055,18 +1931,18 @@
 
     return dist_to_good_value < dist_to_bad_value
 
-  def _FillInV8BleedingEdgeInfo(self, min_revision_data, max_revision_data):
-    r1 = self._GetNearestV8BleedingEdgeFromTrunk(min_revision_data['revision'],
+  def _FillInV8BleedingEdgeInfo(self, min_revision_state, max_revision_state):
+    r1 = self._GetNearestV8BleedingEdgeFromTrunk(min_revision_state.revision,
         search_forward=True)
-    r2 = self._GetNearestV8BleedingEdgeFromTrunk(max_revision_data['revision'],
+    r2 = self._GetNearestV8BleedingEdgeFromTrunk(max_revision_state.revision,
         search_forward=False)
-    min_revision_data['external']['v8_bleeding_edge'] = r1
-    max_revision_data['external']['v8_bleeding_edge'] = r2
+    min_revision_state.external['v8_bleeding_edge'] = r1
+    max_revision_state.external['v8_bleeding_edge'] = r2
 
     if (not self._GetV8BleedingEdgeFromV8TrunkIfMappable(
-            min_revision_data['revision'])
+            min_revision_state.revision)
         or not self._GetV8BleedingEdgeFromV8TrunkIfMappable(
-            max_revision_data['revision'])):
+            max_revision_state.revision)):
       self.warnings.append(
           'Trunk revisions in V8 did not map directly to bleeding_edge. '
           'Attempted to expand the range to find V8 rolls which did map '
@@ -2074,54 +1950,54 @@
           'valid.')
 
   def _FindNextDepotToBisect(
-      self, current_depot, min_revision_data, max_revision_data):
+      self, current_depot, min_revision_state, max_revision_state):
     """Decides which depot the script should dive into next (if any).
 
     Args:
       current_depot: Current depot being bisected.
-      min_revision_data: Data about the earliest revision in the bisect range.
-      max_revision_data: Data about the latest revision in the bisect range.
+      min_revision_state: State of the earliest revision in the bisect range.
+      max_revision_state: State of the latest revision in the bisect range.
 
     Returns:
       Name of the depot to bisect next, or None.
     """
     external_depot = None
-    for next_depot in DEPOT_NAMES:
-      if DEPOT_DEPS_NAME[next_depot].has_key('platform'):
-        if DEPOT_DEPS_NAME[next_depot]['platform'] != os.name:
+    for next_depot in bisect_utils.DEPOT_NAMES:
+      if bisect_utils.DEPOT_DEPS_NAME[next_depot].has_key('platform'):
+        if bisect_utils.DEPOT_DEPS_NAME[next_depot]['platform'] != os.name:
           continue
 
-      if not (DEPOT_DEPS_NAME[next_depot]['recurse']
-              and min_revision_data['depot']
-              in DEPOT_DEPS_NAME[next_depot]['from']):
+      if not (bisect_utils.DEPOT_DEPS_NAME[next_depot]['recurse']
+              and min_revision_state.depot
+              in bisect_utils.DEPOT_DEPS_NAME[next_depot]['from']):
         continue
 
       if current_depot == 'v8':
         # We grab the bleeding_edge info here rather than earlier because we
         # finally have the revision range. From that we can search forwards and
         # backwards to try to match trunk revisions to bleeding_edge.
-        self._FillInV8BleedingEdgeInfo(min_revision_data, max_revision_data)
+        self._FillInV8BleedingEdgeInfo(min_revision_state, max_revision_state)
 
-      if (min_revision_data['external'].get(next_depot) ==
-          max_revision_data['external'].get(next_depot)):
+      if (min_revision_state.external.get(next_depot) ==
+          max_revision_state.external.get(next_depot)):
         continue
 
-      if (min_revision_data['external'].get(next_depot) and
-          max_revision_data['external'].get(next_depot)):
+      if (min_revision_state.external.get(next_depot) and
+          max_revision_state.external.get(next_depot)):
         external_depot = next_depot
         break
 
     return external_depot
 
   def PrepareToBisectOnDepot(
-      self, current_depot, end_revision, start_revision, previous_revision):
+      self, current_depot, start_revision, end_revision, previous_revision):
     """Changes to the appropriate directory and gathers a list of revisions
     to bisect between |start_revision| and |end_revision|.
 
     Args:
       current_depot: The depot we want to bisect.
-      end_revision: End of the revision range.
       start_revision: Start of the revision range.
+      end_revision: End of the revision range.
       previous_revision: The last revision we synced to on |previous_depot|.
 
     Returns:
@@ -2134,10 +2010,11 @@
 
     # V8 (and possibly others) is merged in periodically. Bisecting
     # this directory directly won't give much good info.
-    if DEPOT_DEPS_NAME[current_depot].has_key('custom_deps'):
+    if bisect_utils.DEPOT_DEPS_NAME[current_depot].has_key('custom_deps'):
       config_path = os.path.join(self.src_cwd, '..')
-      if bisect_utils.RunGClientAndCreateConfig(self.opts,
-          DEPOT_DEPS_NAME[current_depot]['custom_deps'], cwd=config_path):
+      if bisect_utils.RunGClientAndCreateConfig(
+          self.opts, bisect_utils.DEPOT_DEPS_NAME[current_depot]['custom_deps'],
+          cwd=config_path):
         return []
       if bisect_utils.RunGClient(
           ['sync', '--revision', previous_revision], cwd=self.src_cwd):
@@ -2191,8 +2068,8 @@
 
   def PrintRevisionsToBisectMessage(self, revision_list, depot):
     if self.opts.output_buildbot_annotations:
-      step_name = 'Bisection Range: [%s - %s]' % (
-          revision_list[len(revision_list)-1], revision_list[0])
+      step_name = 'Bisection Range: [%s:%s - %s]' % (depot, revision_list[-1],
+                                                     revision_list[0])
       bisect_utils.OutputAnnotationStepStart(step_name)
 
     print
@@ -2332,8 +2209,6 @@
     Returns:
       A BisectResults object.
     """
-    results = BisectResults(self.depot_registry)
-
     # Choose depot to bisect first
     target_depot = 'chromium'
     if self.opts.target_platform == 'cros':
@@ -2346,25 +2221,25 @@
 
     # If they passed SVN revisions, we can try match them to git SHA1 hashes.
     bad_revision = source_control.ResolveToRevision(
-        bad_revision_in, target_depot, DEPOT_DEPS_NAME, 100)
+        bad_revision_in, target_depot, bisect_utils.DEPOT_DEPS_NAME, 100)
     good_revision = source_control.ResolveToRevision(
-        good_revision_in, target_depot, DEPOT_DEPS_NAME, -100)
+        good_revision_in, target_depot, bisect_utils.DEPOT_DEPS_NAME, -100)
 
     os.chdir(cwd)
     if bad_revision is None:
-      results.error = 'Couldn\'t resolve [%s] to SHA1.' % bad_revision_in
-      return results
+      return BisectResults(
+          error='Couldn\'t resolve [%s] to SHA1.' % bad_revision_in)
 
     if good_revision is None:
-      results.error = 'Couldn\'t resolve [%s] to SHA1.' % good_revision_in
-      return results
+      return BisectResults(
+          error='Couldn\'t resolve [%s] to SHA1.' % good_revision_in)
 
     # Check that they didn't accidentally swap good and bad revisions.
     if not self.CheckIfRevisionsInProperOrder(
         target_depot, good_revision, bad_revision):
-      results.error = ('bad_revision < good_revision, did you swap these '
-                       'by mistake?')
-      return results
+      return BisectResults(error='bad_revision < good_revision, did you swap '
+                                 'these by mistake?')
+
     bad_revision, good_revision = self.NudgeRevisionsIfDEPSChange(
         bad_revision, good_revision, good_revision_in)
     if self.opts.output_buildbot_annotations:
@@ -2372,45 +2247,17 @@
 
     cannot_bisect = self.CanPerformBisect(good_revision, bad_revision)
     if cannot_bisect:
-      results.error = cannot_bisect.get('error')
-      return results
+      return BisectResults(error=cannot_bisect.get('error'))
 
     print 'Gathering revision range for bisection.'
     # Retrieve a list of revisions to do bisection on.
-    src_revision_list = self.GetRevisionList(
-        target_depot, bad_revision, good_revision)
+    revision_list = self.GetRevisionList(target_depot, bad_revision,
+                                         good_revision)
 
     if self.opts.output_buildbot_annotations:
       bisect_utils.OutputAnnotationStepClosed()
 
-    if src_revision_list:
-      # revision_data will store information about a revision such as the
-      # depot it came from, the webkit/V8 revision at that time,
-      # performance timing, build state, etc...
-      revision_data = results.revision_data
-
-      # revision_list is the list we're binary searching through at the moment.
-      revision_list = []
-
-      sort_key_ids = 0
-
-      for current_revision_id in src_revision_list:
-        sort_key_ids += 1
-
-        revision_data[current_revision_id] = {
-            'value' : None,
-            'passed' : '?',
-            'depot' : target_depot,
-            'external' : None,
-            'perf_time' : 0,
-            'build_time' : 0,
-            'sort' : sort_key_ids,
-        }
-        revision_list.append(current_revision_id)
-
-      min_revision = 0
-      max_revision = len(revision_list) - 1
-
+    if revision_list:
       self.PrintRevisionsToBisectMessage(revision_list, target_depot)
 
       if self.opts.output_buildbot_annotations:
@@ -2430,18 +2277,18 @@
         bisect_utils.OutputAnnotationStepClosed()
 
       if bad_results[1]:
-        results.error = ('An error occurred while building and running '
-            'the \'bad\' reference value. The bisect cannot continue without '
-            'a working \'bad\' revision to start from.\n\nError: %s' %
-            bad_results[0])
-        return results
+        error = ('An error occurred while building and running the \'bad\' '
+                 'reference value. The bisect cannot continue without '
+                 'a working \'bad\' revision to start from.\n\nError: %s' %
+                 bad_results[0])
+        return BisectResults(error=error)
 
       if good_results[1]:
-        results.error = ('An error occurred while building and running '
-            'the \'good\' reference value. The bisect cannot continue without '
-            'a working \'good\' revision to start from.\n\nError: %s' %
-            good_results[0])
-        return results
+        error = ('An error occurred while building and running the \'good\' '
+                 'reference value. The bisect cannot continue without '
+                 'a working \'good\' revision to start from.\n\nError: %s' %
+                 good_results[0])
+        return BisectResults(error=error)
 
       # We need these reference values to determine if later runs should be
       # classified as pass or fail.
@@ -2453,7 +2300,7 @@
       # lower is better).
       improvement_dir = self.opts.improvement_direction
       if improvement_dir:
-        higher_is_better  = improvement_dir > 0
+        higher_is_better = improvement_dir > 0
         if higher_is_better:
           message = "Expecting higher values to be better for this metric, "
         else:
@@ -2465,49 +2312,64 @@
           message += "and the metric appears to have decreased. "
         if ((higher_is_better and metric_increased) or
             (not higher_is_better and not metric_increased)):
-          results.error = (message + 'Then, the test results for the ends of '
-                           'the given \'good\' - \'bad\' range of revisions '
-                           'represent an improvement (and not a regression).')
-          return results
+          error = (message + 'Then, the test results for the ends of the given '
+                   '\'good\' - \'bad\' range of revisions represent an '
+                   'improvement (and not a regression).')
+          return BisectResults(error=error)
         print message, "Therefore we continue to bisect."
 
+      bisect_state = BisectState(target_depot, revision_list)
+      revision_states = bisect_state.GetRevisionStates()
+
+      min_revision = 0
+      max_revision = len(revision_states) - 1
+      # Check how likely it is that the good and bad results are different
+      # beyond chance-induced variation.
+      if not self.opts.debug_ignore_regression_confidence:
+        error = _CheckRegressionConfidenceError(good_revision,
+                                                bad_revision,
+                                                known_good_value,
+                                                known_bad_value)
+        if error:
+          return BisectResults(error=error)
+
       # Can just mark the good and bad revisions explicitly here since we
       # already know the results.
-      bad_revision_data = revision_data[revision_list[0]]
-      bad_revision_data['external'] = bad_results[2]
-      bad_revision_data['perf_time'] = bad_results[3]
-      bad_revision_data['build_time'] = bad_results[4]
-      bad_revision_data['passed'] = False
-      bad_revision_data['value'] = known_bad_value
+      bad_revision_state = revision_states[min_revision]
+      bad_revision_state.external = bad_results[2]
+      bad_revision_state.perf_time = bad_results[3]
+      bad_revision_state.build_time = bad_results[4]
+      bad_revision_state.passed = False
+      bad_revision_state.value = known_bad_value
 
-      good_revision_data = revision_data[revision_list[max_revision]]
-      good_revision_data['external'] = good_results[2]
-      good_revision_data['perf_time'] = good_results[3]
-      good_revision_data['build_time'] = good_results[4]
-      good_revision_data['passed'] = True
-      good_revision_data['value'] = known_good_value
+      good_revision_state = revision_states[max_revision]
+      good_revision_state.external = good_results[2]
+      good_revision_state.perf_time = good_results[3]
+      good_revision_state.build_time = good_results[4]
+      good_revision_state.passed = True
+      good_revision_state.value = known_good_value
 
-      next_revision_depot = target_depot
+      bisect_printer = BisectPrinter(self.opts, self.depot_registry)
 
       while True:
-        if not revision_list:
+        if not revision_states:
           break
 
-        min_revision_data = revision_data[revision_list[min_revision]]
-        max_revision_data = revision_data[revision_list[max_revision]]
-
         if max_revision - min_revision <= 1:
-          current_depot = min_revision_data['depot']
-          if min_revision_data['passed'] == '?':
+          min_revision_state = revision_states[min_revision]
+          max_revision_state = revision_states[max_revision]
+          current_depot = min_revision_state.depot
+          # TODO(sergiyb): Under which conditions can first two branches be hit?
+          if min_revision_state.passed == '?':
             next_revision_index = min_revision
-          elif max_revision_data['passed'] == '?':
+          elif max_revision_state.passed == '?':
             next_revision_index = max_revision
           elif current_depot in ['android-chrome', 'cros', 'chromium', 'v8']:
-            previous_revision = revision_list[min_revision]
+            previous_revision = revision_states[min_revision].revision
             # If there were changes to any of the external libraries we track,
             # should bisect the changes there as well.
             external_depot = self._FindNextDepotToBisect(
-                current_depot, min_revision_data, max_revision_data)
+                current_depot, min_revision_state, max_revision_state)
             # If there was no change in any of the external depots, the search
             # is over.
             if not external_depot:
@@ -2519,33 +2381,30 @@
                     'bleeding_edge.')
               break
 
-            earliest_revision = max_revision_data['external'][external_depot]
-            latest_revision = min_revision_data['external'][external_depot]
+            earliest_revision = max_revision_state.external[external_depot]
+            latest_revision = min_revision_state.external[external_depot]
 
             new_revision_list = self.PrepareToBisectOnDepot(
-                external_depot, latest_revision, earliest_revision,
+                external_depot, earliest_revision, latest_revision,
                 previous_revision)
 
             if not new_revision_list:
-              results.error = ('An error occurred attempting to retrieve '
-                               'revision range: [%s..%s]' %
-                               (earliest_revision, latest_revision))
-              return results
+              error = ('An error occurred attempting to retrieve revision '
+                       'range: [%s..%s]' % (earliest_revision, latest_revision))
+              return BisectResults(error=error)
 
-            _AddRevisionsIntoRevisionData(
-                new_revision_list, external_depot, min_revision_data['sort'],
-                revision_data)
+            revision_states = bisect_state.CreateRevisionStatesAfter(
+                external_depot, new_revision_list, current_depot,
+                previous_revision)
 
-            # Reset the bisection and perform it on the newly inserted
-            # changelists.
-            revision_list = new_revision_list
+            # Reset the bisection and perform it on the newly inserted states.
             min_revision = 0
-            max_revision = len(revision_list) - 1
-            sort_key_ids += len(revision_list)
+            max_revision = len(revision_states) - 1
 
             print ('Regression in metric %s appears to be the result of '
                    'changes in [%s].' % (metric, external_depot))
 
+            revision_list = [state.revision for state in revision_states]
             self.PrintRevisionsToBisectMessage(revision_list, external_depot)
 
             continue
@@ -2555,36 +2414,34 @@
           next_revision_index = (int((max_revision - min_revision) / 2) +
                                  min_revision)
 
-        next_revision_id = revision_list[next_revision_index]
-        next_revision_data = revision_data[next_revision_id]
-        next_revision_depot = next_revision_data['depot']
+        next_revision_state = revision_states[next_revision_index]
+        next_revision = next_revision_state.revision
+        next_depot = next_revision_state.depot
 
-        self.depot_registry.ChangeToDepotDir(next_revision_depot)
+        self.depot_registry.ChangeToDepotDir(next_depot)
 
+        message = 'Working on [%s:%s]' % (next_depot, next_revision)
+        print message
         if self.opts.output_buildbot_annotations:
-          step_name = 'Working on [%s]' % next_revision_id
-          bisect_utils.OutputAnnotationStepStart(step_name)
+          bisect_utils.OutputAnnotationStepStart(message)
 
-        print 'Working on revision: [%s]' % next_revision_id
-
-        run_results = self.RunTest(
-            next_revision_id, next_revision_depot, command_to_run, metric,
-            skippable=True)
+        run_results = self.RunTest(next_revision, next_depot, command_to_run,
+                                   metric, skippable=True)
 
         # If the build is successful, check whether or not the metric
         # had regressed.
         if not run_results[1]:
           if len(run_results) > 2:
-            next_revision_data['external'] = run_results[2]
-            next_revision_data['perf_time'] = run_results[3]
-            next_revision_data['build_time'] = run_results[4]
+            next_revision_state.external = run_results[2]
+            next_revision_state.perf_time = run_results[3]
+            next_revision_state.build_time = run_results[4]
 
           passed_regression = self._CheckIfRunPassed(run_results[0],
                                                      known_good_value,
                                                      known_bad_value)
 
-          next_revision_data['passed'] = passed_regression
-          next_revision_data['value'] = run_results[0]
+          next_revision_state.passed = passed_regression
+          next_revision_state.value = run_results[0]
 
           if passed_regression:
             max_revision = next_revision_index
@@ -2592,313 +2449,28 @@
             min_revision = next_revision_index
         else:
           if run_results[1] == BUILD_RESULT_SKIPPED:
-            next_revision_data['passed'] = 'Skipped'
+            next_revision_state.passed = 'Skipped'
           elif run_results[1] == BUILD_RESULT_FAIL:
-            next_revision_data['passed'] = 'Build Failed'
+            next_revision_state.passed = 'Build Failed'
 
           print run_results[0]
 
           # If the build is broken, remove it and redo search.
-          revision_list.pop(next_revision_index)
+          revision_states.pop(next_revision_index)
 
           max_revision -= 1
 
         if self.opts.output_buildbot_annotations:
-          self._PrintPartialResults(results)
+          bisect_printer.PrintPartialResults(bisect_state)
           bisect_utils.OutputAnnotationStepClosed()
+
+      return BisectResults(bisect_state, self.depot_registry, self.opts,
+                           self.warnings)
     else:
       # Weren't able to sync and retrieve the revision range.
-      results.error = ('An error occurred attempting to retrieve revision '
-                       'range: [%s..%s]' % (good_revision, bad_revision))
-
-    return results
-
-  def _PrintPartialResults(self, results):
-    results_dict = results.GetResultsDict()
-    self._PrintTestedCommitsTable(results_dict['revision_data_sorted'],
-                                  results_dict['first_working_revision'],
-                                  results_dict['last_broken_revision'],
-                                  100, final_step=False)
-
-  def _ConfidenceLevelStatus(self, results_dict):
-    if not results_dict['confidence']:
-      return None
-    confidence_status = 'Successful with %(level)s confidence%(warning)s.'
-    if results_dict['confidence'] >= HIGH_CONFIDENCE:
-      level = 'high'
-    else:
-      level = 'low'
-    warning = ' and warnings'
-    if not self.warnings:
-      warning = ''
-    return confidence_status % {'level': level, 'warning': warning}
-
-  def _GetViewVCLinkFromDepotAndHash(self, revision_id, depot):
-    """Gets link to the repository browser."""
-    info = source_control.QueryRevisionInfo(revision_id,
-        self.depot_registry.GetDepotDir(depot))
-    if depot and DEPOT_DEPS_NAME[depot].has_key('viewvc'):
-      try:
-        # Format is "git-svn-id: svn://....@123456 <other data>"
-        svn_line = [i for i in info['body'].splitlines() if 'git-svn-id:' in i]
-        svn_revision = svn_line[0].split('@')
-        svn_revision = svn_revision[1].split(' ')[0]
-        return DEPOT_DEPS_NAME[depot]['viewvc'] + svn_revision
-      except IndexError:
-        return ''
-    return ''
-
-  def _PrintRevisionInfo(self, cl, info, depot=None):
-    email_info = ''
-    if not info['email'].startswith(info['author']):
-      email_info = '\nEmail   : %s' % info['email']
-    commit_link = self._GetViewVCLinkFromDepotAndHash(cl, depot)
-    if commit_link:
-      commit_info = '\nLink    : %s' % commit_link
-    else:
-      commit_info = ('\nFailed to parse SVN revision from body:\n%s' %
-                     info['body'])
-    print RESULTS_REVISION_INFO % {
-        'subject': info['subject'],
-        'author': info['author'],
-        'email_info': email_info,
-        'commit_info': commit_info,
-        'cl': cl,
-        'cl_date': info['date']
-    }
-
-  def _PrintTestedCommitsHeader(self):
-    if self.opts.bisect_mode == BISECT_MODE_MEAN:
-      _PrintTableRow(
-          [20, 12, 70, 14, 12, 13],
-          ['Depot', 'Position', 'SHA', 'Mean', 'Std. Error', 'State'])
-    elif self.opts.bisect_mode == BISECT_MODE_STD_DEV:
-      _PrintTableRow(
-          [20, 12, 70, 14, 12, 13],
-          ['Depot', 'Position', 'SHA', 'Std. Error', 'Mean', 'State'])
-    elif self.opts.bisect_mode == BISECT_MODE_RETURN_CODE:
-      _PrintTableRow(
-          [20, 12, 70, 14, 13],
-          ['Depot', 'Position', 'SHA', 'Return Code', 'State'])
-    else:
-      assert False, 'Invalid bisect_mode specified.'
-
-  def _PrintTestedCommitsEntry(self, current_data, commit_position, cl_link,
-                               state_str):
-    if self.opts.bisect_mode == BISECT_MODE_MEAN:
-      std_error = '+-%.02f' % current_data['value']['std_err']
-      mean = '%.02f' % current_data['value']['mean']
-      _PrintTableRow(
-          [20, 12, 70, 12, 14, 13],
-          [current_data['depot'], commit_position, cl_link, mean, std_error,
-           state_str])
-    elif self.opts.bisect_mode == BISECT_MODE_STD_DEV:
-      std_error = '+-%.02f' % current_data['value']['std_err']
-      mean = '%.02f' % current_data['value']['mean']
-      _PrintTableRow(
-          [20, 12, 70, 12, 14, 13],
-          [current_data['depot'], commit_position, cl_link, std_error, mean,
-           state_str])
-    elif self.opts.bisect_mode == BISECT_MODE_RETURN_CODE:
-      mean = '%d' % current_data['value']['mean']
-      _PrintTableRow(
-          [20, 12, 70, 14, 13],
-          [current_data['depot'], commit_position, cl_link, mean,
-           state_str])
-
-  def _PrintTestedCommitsTable(
-      self, revision_data_sorted, first_working_revision, last_broken_revision,
-      confidence, final_step=True):
-    print
-    if final_step:
-      print '===== TESTED COMMITS ====='
-    else:
-      print '===== PARTIAL RESULTS ====='
-    self._PrintTestedCommitsHeader()
-    state = 0
-    for current_id, current_data in revision_data_sorted:
-      if current_data['value']:
-        if (current_id == last_broken_revision or
-            current_id == first_working_revision):
-          # If confidence is too low, don't add this empty line since it's
-          # used to put focus on a suspected CL.
-          if confidence and final_step:
-            print
-          state += 1
-          if state == 2 and not final_step:
-            # Just want a separation between "bad" and "good" cl's.
-            print
-
-        state_str = 'Bad'
-        if state == 1 and final_step:
-          state_str = 'Suspected CL'
-        elif state == 2:
-          state_str = 'Good'
-
-        # If confidence is too low, don't bother outputting good/bad.
-        if not confidence:
-          state_str = ''
-        state_str = state_str.center(13, ' ')
-
-        cl_link = self._GetViewVCLinkFromDepotAndHash(current_id,
-            current_data['depot'])
-        if not cl_link:
-          cl_link = current_id
-        commit_position = source_control.GetCommitPosition(
-            current_id, self.depot_registry.GetDepotDir(current_data['depot']))
-        commit_position = str(commit_position)
-        if not commit_position:
-          commit_position = ''
-        self._PrintTestedCommitsEntry(current_data, commit_position, cl_link,
-                                      state_str)
-
-  def _PrintReproSteps(self):
-    """Prints out a section of the results explaining how to run the test.
-
-    This message includes the command used to run the test.
-    """
-    command = '$ ' + self.opts.command
-    if bisect_utils.IsTelemetryCommand(self.opts.command):
-      command += ('\nAlso consider passing --profiler=list to see available '
-                  'profilers.')
-    print REPRO_STEPS_LOCAL
-    if bisect_utils.IsTelemetryCommand(self.opts.command):
-      telemetry_command = re.sub(r'--browser=[^\s]+',
-                                 '--browser=<bot-name>',
-                                 command)
-      print REPRO_STEPS_TRYJOB_TELEMETRY % {'command': telemetry_command}
-    else:
-      print REPRO_STEPS_TRYJOB
-
-  def _PrintOtherRegressions(self, other_regressions, revision_data):
-    """Prints a section of the results about other potential regressions."""
-    print
-    print 'Other regressions may have occurred:'
-    print '  %8s  %70s  %10s' % ('Depot'.center(8, ' '),
-        'Range'.center(70, ' '), 'Confidence'.center(10, ' '))
-    for regression in other_regressions:
-      current_id, previous_id, confidence = regression
-      current_data = revision_data[current_id]
-      previous_data = revision_data[previous_id]
-
-      current_link = self._GetViewVCLinkFromDepotAndHash(current_id,
-          current_data['depot'])
-      previous_link = self._GetViewVCLinkFromDepotAndHash(previous_id,
-          previous_data['depot'])
-
-      # If we can't map it to a viewable URL, at least show the original hash.
-      if not current_link:
-        current_link = current_id
-      if not previous_link:
-        previous_link = previous_id
-
-      print '  %8s  %70s %s' % (
-          current_data['depot'], current_link,
-          ('%d%%' % confidence).center(10, ' '))
-      print '  %8s  %70s' % (
-          previous_data['depot'], previous_link)
-      print
-
-  def _CheckForWarnings(self, results_dict):
-    if len(results_dict['culprit_revisions']) > 1:
-      self.warnings.append('Due to build errors, regression range could '
-                           'not be narrowed down to a single commit.')
-    if self.opts.repeat_test_count == 1:
-      self.warnings.append('Tests were only set to run once. This may '
-                           'be insufficient to get meaningful results.')
-    if 0 < results_dict['confidence'] < HIGH_CONFIDENCE:
-      self.warnings.append('Confidence is not high. Try bisecting again '
-                           'with increased repeat_count, larger range, or '
-                           'on another metric.')
-    if not results_dict['confidence']:
-      self.warnings.append('Confidence score is 0%. Try bisecting again on '
-                           'another platform or another metric.')
-
-  def FormatAndPrintResults(self, bisect_results):
-    """Prints the results from a bisection run in a readable format.
-
-    Args:
-      bisect_results: The results from a bisection test run.
-    """
-    results_dict = bisect_results.GetResultsDict()
-
-    self._CheckForWarnings(results_dict)
-
-    if self.opts.output_buildbot_annotations:
-      bisect_utils.OutputAnnotationStepStart('Build Status Per Revision')
-
-    print
-    print 'Full results of bisection:'
-    for current_id, current_data  in results_dict['revision_data_sorted']:
-      build_status = current_data['passed']
-
-      if type(build_status) is bool:
-        if build_status:
-          build_status = 'Good'
-        else:
-          build_status = 'Bad'
-
-      print '  %20s  %40s  %s' % (current_data['depot'],
-                                  current_id, build_status)
-    print
-
-    if self.opts.output_buildbot_annotations:
-      bisect_utils.OutputAnnotationStepClosed()
-      # The perf dashboard scrapes the "results" step in order to comment on
-      # bugs. If you change this, please update the perf dashboard as well.
-      bisect_utils.OutputAnnotationStepStart('Results')
-
-    self._PrintBanner(results_dict)
-    self._PrintWarnings()
-
-    if results_dict['culprit_revisions'] and results_dict['confidence']:
-      for culprit in results_dict['culprit_revisions']:
-        cl, info, depot = culprit
-        self._PrintRevisionInfo(cl, info, depot)
-      if results_dict['other_regressions']:
-        self._PrintOtherRegressions(results_dict['other_regressions'],
-                                    results_dict['revision_data'])
-    self._PrintTestedCommitsTable(results_dict['revision_data_sorted'],
-                                  results_dict['first_working_revision'],
-                                  results_dict['last_broken_revision'],
-                                  results_dict['confidence'])
-    _PrintStepTime(results_dict['revision_data_sorted'])
-    self._PrintReproSteps()
-    _PrintThankYou()
-    if self.opts.output_buildbot_annotations:
-      bisect_utils.OutputAnnotationStepClosed()
-
-  def _PrintBanner(self, results_dict):
-    if self._IsBisectModeReturnCode():
-      metrics = 'N/A'
-      change = 'Yes'
-    else:
-      metrics = '/'.join(self.opts.metric)
-      change = '%.02f%% (+/-%.02f%%)' % (
-          results_dict['regression_size'], results_dict['regression_std_err'])
-
-    if results_dict['culprit_revisions'] and results_dict['confidence']:
-      status = self._ConfidenceLevelStatus(results_dict)
-    else:
-      status = 'Failure, could not reproduce.'
-      change = 'Bisect could not reproduce a change.'
-
-    print RESULTS_BANNER % {
-        'status': status,
-        'command': self.opts.command,
-        'metrics': metrics,
-        'change': change,
-        'confidence': results_dict['confidence'],
-    }
-
-  def _PrintWarnings(self):
-    """Prints a list of warning strings if there are any."""
-    if not self.warnings:
-      return
-    print
-    print 'WARNINGS:'
-    for w in set(self.warnings):
-      print '  ! %s' % w
+      error = ('An error occurred attempting to retrieve revision range: '
+               '[%s..%s]' % (good_revision, bad_revision))
+      return BisectResults(error=error)
 
 
 def _IsPlatformSupported():
@@ -2968,13 +2540,14 @@
     self.debug_ignore_build = None
     self.debug_ignore_sync = None
     self.debug_ignore_perf_test = None
+    self.debug_ignore_regression_confidence = None
     self.debug_fake_first_test_mean = 0
     self.gs_bucket = None
     self.target_arch = 'ia32'
     self.target_build_type = 'Release'
     self.builder_host = None
     self.builder_port = None
-    self.bisect_mode = BISECT_MODE_MEAN
+    self.bisect_mode = bisect_utils.BISECT_MODE_MEAN
     self.improvement_direction = 0
 
   @staticmethod
@@ -3039,9 +2612,10 @@
                      'discarded).')
     group.add_option('--bisect_mode',
                      type='choice',
-                     choices=[BISECT_MODE_MEAN, BISECT_MODE_STD_DEV,
-                        BISECT_MODE_RETURN_CODE],
-                     default=BISECT_MODE_MEAN,
+                     choices=[bisect_utils.BISECT_MODE_MEAN,
+                              bisect_utils.BISECT_MODE_STD_DEV,
+                              bisect_utils.BISECT_MODE_RETURN_CODE],
+                     default=bisect_utils.BISECT_MODE_MEAN,
                      help='The bisect mode. Choices are to bisect on the '
                      'difference in mean, std_dev, or return_code.')
     parser.add_option_group(group)
@@ -3135,6 +2709,10 @@
     group.add_option('--debug_ignore_perf_test',
                      action='store_true',
                      help='DEBUG: Don\'t perform performance tests.')
+    group.add_option('--debug_ignore_regression_confidence',
+                     action='store_true',
+                     help='DEBUG: Don\'t score the confidence of the initial '
+                          'good and bad revisions\' test results.')
     group.add_option('--debug_fake_first_test_mean',
                      type='int',
                      default='0',
@@ -3159,7 +2737,8 @@
       if not opts.bad_revision:
         raise RuntimeError('missing required parameter: --bad_revision')
 
-      if not opts.metric and opts.bisect_mode != BISECT_MODE_RETURN_CODE:
+      if (not opts.metric and
+          opts.bisect_mode != bisect_utils.BISECT_MODE_RETURN_CODE):
         raise RuntimeError('missing required parameter: --metric')
 
       if opts.gs_bucket:
@@ -3186,7 +2765,7 @@
         if not opts.working_directory:
           raise RuntimeError('missing required parameter: --working_directory')
 
-      if opts.bisect_mode != BISECT_MODE_RETURN_CODE:
+      if opts.bisect_mode != bisect_utils.BISECT_MODE_RETURN_CODE:
         metric_values = opts.metric.split('/')
         if len(metric_values) != 2:
           raise RuntimeError('Invalid metric specified: [%s]' % opts.metric)
@@ -3222,7 +2801,7 @@
       assert hasattr(opts, k), 'Invalid %s attribute in BisectOptions.' % k
       setattr(opts, k, v)
 
-    if opts.metric and opts.bisect_mode != BISECT_MODE_RETURN_CODE:
+    if opts.metric and opts.bisect_mode != bisect_utils.BISECT_MODE_RETURN_CODE:
       metric_values = opts.metric.split('/')
       if len(metric_values) != 2:
         raise RuntimeError('Invalid metric specified: [%s]' % opts.metric)
@@ -3246,7 +2825,7 @@
       extra_src = bisect_utils.LoadExtraSrc(opts.extra_src)
       if not extra_src:
         raise RuntimeError('Invalid or missing --extra_src.')
-      _AddAdditionalDepotInfo(extra_src.GetAdditionalDepotInfo())
+      bisect_utils.AddAdditionalDepotInfo(extra_src.GetAdditionalDepotInfo())
 
     if opts.working_directory:
       custom_deps = bisect_utils.DEFAULT_GCLIENT_CUSTOM_DEPS
@@ -3272,14 +2851,13 @@
         not opts.working_directory):
       raise RuntimeError('You must switch to master branch to run bisection.')
     bisect_test = BisectPerformanceMetrics(opts)
+    bisect_printer = BisectPrinter(opts, bisect_test.depot_registry)
     try:
-      bisect_results = bisect_test.Run(opts.command,
-                                       opts.bad_revision,
-                                       opts.good_revision,
-                                       opts.metric)
-      if bisect_results.error:
-        raise RuntimeError(bisect_results.error)
-      bisect_test.FormatAndPrintResults(bisect_results)
+      results = bisect_test.Run(opts.command, opts.bad_revision,
+                                opts.good_revision, opts.metric)
+      if results.error:
+        raise RuntimeError(results.error)
+      bisect_printer.FormatAndPrintResults(results)
       return 0
     finally:
       bisect_test.PerformCleanup()
diff --git a/tools/auto_bisect/bisect_perf_regression_test.py b/tools/auto_bisect/bisect_perf_regression_test.py
index c7d98e0..8df897b1 100644
--- a/tools/auto_bisect/bisect_perf_regression_test.py
+++ b/tools/auto_bisect/bisect_perf_regression_test.py
@@ -12,37 +12,95 @@
 sys.path.append(os.path.join(SRC, 'third_party', 'pymock'))
 
 import bisect_perf_regression
-import bisect_results
+import bisect_printer
+import bisect_utils
 import mock
 import source_control
 
 
+# Regression confidence: 0%
+CLEAR_NON_REGRESSION = [
+    # Mean: 30.223 Std. Dev.: 11.383
+    [[16.886], [16.909], [16.99], [17.723], [17.952], [18.118], [19.028],
+     [19.552], [21.954], [38.573], [38.839], [38.965], [40.007], [40.572],
+     [41.491], [42.002], [42.33], [43.109], [43.238]],
+    # Mean: 34.76 Std. Dev.: 11.516
+    [[16.426], [17.347], [20.593], [21.177], [22.791], [27.843], [28.383],
+     [28.46], [29.143], [40.058], [40.303], [40.558], [41.918], [42.44],
+     [45.223], [46.494], [50.002], [50.625], [50.839]]
+]
+# Regression confidence: ~ 90%
+ALMOST_REGRESSION = [
+    # Mean: 30.042 Std. Dev.: 2.002
+    [[26.146], [28.04], [28.053], [28.074], [28.168], [28.209], [28.471],
+     [28.652], [28.664], [30.862], [30.973], [31.002], [31.897], [31.929],
+     [31.99], [32.214], [32.323], [32.452], [32.696]],
+    # Mean: 33.008 Std. Dev.: 4.265
+    [[34.963], [30.741], [39.677], [39.512], [34.314], [31.39], [34.361],
+     [25.2], [30.489], [29.434]]
+]
+# Regression confidence: ~ 98%
+BARELY_REGRESSION = [
+    # Mean: 28.828 Std. Dev.: 1.993
+    [[26.96], [27.605], [27.768], [27.829], [28.006], [28.206], [28.393],
+     [28.911], [28.933], [30.38], [30.462], [30.808], [31.74], [31.805],
+     [31.899], [32.077], [32.454], [32.597], [33.155]],
+    # Mean: 31.156 Std. Dev.: 1.980
+    [[28.729], [29.112], [29.258], [29.454], [29.789], [30.036], [30.098],
+     [30.174], [30.534], [32.285], [32.295], [32.552], [32.572], [32.967],
+     [33.165], [33.403], [33.588], [33.744], [34.147], [35.84]]
+]
+# Regression confidence: 99.5%
+CLEAR_REGRESSION = [
+    # Mean: 30.254 Std. Dev.: 2.987
+    [[26.494], [26.621], [26.701], [26.997], [26.997], [27.05], [27.37],
+     [27.488], [27.556], [31.846], [32.192], [32.21], [32.586], [32.596],
+     [32.618], [32.95], [32.979], [33.421], [33.457], [34.97]],
+    # Mean: 33.190 Std. Dev.: 2.972
+    [[29.547], [29.713], [29.835], [30.132], [30.132], [30.33], [30.406],
+     [30.592], [30.72], [34.486], [35.247], [35.253], [35.335], [35.378],
+     [35.934], [36.233], [36.41], [36.947], [37.982]]
+]
 # Default options for the dry run
 DEFAULT_OPTIONS = {
     'debug_ignore_build': True,
     'debug_ignore_sync': True,
     'debug_ignore_perf_test': True,
+    'debug_ignore_regression_confidence': True,
     'command': 'fake_command',
     'metric': 'fake/metric',
     'good_revision': 280000,
     'bad_revision': 280005,
-  }
+}
+
+# This global is a placeholder for a generator to be defined by the testcases
+# that use _MockRunTest
+_MockResultsGenerator = (x for x in [])
+
+def _FakeTestResult(values):
+  result_dict = {'mean': 0.0, 'std_err': 0.0, 'std_dev': 0.0, 'values': values}
+  success_code = 0
+  return (result_dict, success_code)
+
+
+def _MockRunTests(*args, **kwargs):
+  _, _ = args, kwargs
+  return _FakeTestResult(_MockResultsGenerator.next())
 
 
 def _GetBisectPerformanceMetricsInstance(options_dict):
   """Returns an instance of the BisectPerformanceMetrics class."""
-  bisect_options = bisect_perf_regression.BisectOptions.FromDict(options_dict)
-  bisect_instance = bisect_perf_regression.BisectPerformanceMetrics(
-      bisect_options)
-  return bisect_instance
+  opts = bisect_perf_regression.BisectOptions.FromDict(options_dict)
+  return bisect_perf_regression.BisectPerformanceMetrics(opts)
 
 
-def _GetExtendedOptions(d, f):
+def _GetExtendedOptions(improvement_dir, fake_first, ignore_confidence=True):
   """Returns the a copy of the default options dict plus some options."""
   result = dict(DEFAULT_OPTIONS)
   result.update({
-      'improvement_direction': d,
-      'debug_fake_first_test_mean': f})
+      'improvement_direction': improvement_dir,
+      'debug_fake_first_test_mean': fake_first,
+      'debug_ignore_regression_confidence': ignore_confidence})
   return result
 
 
@@ -61,13 +119,14 @@
   try:
     shutil.rmtree = lambda path, onerror: None
     bisect_instance = _GetBisectPerformanceMetricsInstance(options)
-    results = bisect_instance.Run(bisect_instance.opts.command,
-                                  bisect_instance.opts.bad_revision,
-                                  bisect_instance.opts.good_revision,
-                                  bisect_instance.opts.metric)
+    results = bisect_instance.Run(
+        bisect_instance.opts.command, bisect_instance.opts.bad_revision,
+        bisect_instance.opts.good_revision, bisect_instance.opts.metric)
 
     if print_results:
-      bisect_instance.FormatAndPrintResults(results)
+      printer = bisect_printer.BisectPrinter(bisect_instance.opts,
+                                             bisect_instance.depot_registry)
+      printer.FormatAndPrintResults(results)
 
     return results
   finally:
@@ -85,74 +144,6 @@
   def tearDown(self):
     os.chdir(self.cwd)
 
-  def _AssertConfidence(self, score, bad_values, good_values):
-    """Checks whether the given sets of values have a given confidence score.
-
-    The score represents our confidence that the two sets of values wouldn't
-    be as different as they are just by chance; that is, that some real change
-    occurred between the two sets of values.
-
-    Args:
-      score: Expected confidence score.
-      bad_values: First list of numbers.
-      good_values: Second list of numbers.
-    """
-    # ConfidenceScore takes a list of lists but these lists are flattened
-    # inside the function.
-    confidence = bisect_results.ConfidenceScore(
-        [[v] for v in bad_values],
-        [[v] for v in good_values])
-    self.assertEqual(score, confidence)
-
-  def testConfidenceScore_ZeroConfidence(self):
-    # The good and bad sets contain the same values, so the confidence that
-    # they're different should be zero.
-    self._AssertConfidence(0.0, [4, 5, 7, 6, 8, 7], [8, 7, 6, 7, 5, 4])
-
-  def testConfidenceScore_MediumConfidence(self):
-    self._AssertConfidence(80.0, [0, 1, 1, 1, 2, 2], [1, 1, 1, 3, 3, 4])
-
-  def testConfidenceScore_HighConfidence(self):
-    self._AssertConfidence(95.0, [0, 1, 1, 1, 2, 2], [1, 2, 2, 3, 3, 4])
-
-  def testConfidenceScore_VeryHighConfidence(self):
-    # Confidence is high if the two sets of values have no internal variance.
-    self._AssertConfidence(99.9, [1, 1, 1, 1], [1.2, 1.2, 1.2, 1.2])
-    self._AssertConfidence(99.9, [1, 1, 1, 1], [1.01, 1.01, 1.01, 1.01])
-
-  def testConfidenceScore_UnbalancedSampleSize(self):
-    # The second set of numbers only contains one number, so confidence is 0.
-    self._AssertConfidence(0.0, [1.1, 1.2, 1.1, 1.2, 1.0, 1.3, 1.2], [1.4])
-
-  def testConfidenceScore_EmptySample(self):
-    # Confidence is zero if either or both samples are empty.
-    self._AssertConfidence(0.0, [], [])
-    self._AssertConfidence(0.0, [], [1.1, 1.2, 1.1, 1.2, 1.0, 1.3, 1.2, 1.3])
-    self._AssertConfidence(0.0, [1.1, 1.2, 1.1, 1.2, 1.0, 1.3, 1.2, 1.3], [])
-
-  def testConfidenceScore_FunctionalTestResults(self):
-    self._AssertConfidence(80.0, [1, 1, 0, 1, 1, 1, 0, 1], [0, 0, 1, 0, 1, 0])
-    self._AssertConfidence(99.9, [1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0])
-
-  def testConfidenceScore_RealWorldCases(self):
-    """This method contains a set of data from actual bisect results.
-
-    The confidence scores asserted below were all copied from the actual
-    results, so the purpose of this test method is mainly to show what the
-    results for real cases are, and compare when we change the confidence
-    score function in the future.
-    """
-    self._AssertConfidence(80, [133, 130, 132, 132, 130, 129], [129, 129, 125])
-    self._AssertConfidence(99.5, [668, 667], [498, 498, 499])
-    self._AssertConfidence(80, [67, 68], [65, 65, 67])
-    self._AssertConfidence(0, [514], [514])
-    self._AssertConfidence(90, [616, 613, 607, 615], [617, 619, 619, 617])
-    self._AssertConfidence(0, [3.5, 5.8, 4.7, 3.5, 3.6], [2.8])
-    self._AssertConfidence(90, [3, 3, 3], [2, 2, 2, 3])
-    self._AssertConfidence(0, [1999004, 1999627], [223355])
-    self._AssertConfidence(90, [1040, 934, 961], [876, 875, 789])
-    self._AssertConfidence(90, [309, 305, 304], [302, 302, 299, 303, 298])
-
   def testParseDEPSStringManually(self):
     """Tests DEPS parsing."""
     deps_file_contents = """
@@ -249,7 +240,7 @@
         bisect_options)
     bisect_instance.opts.target_platform = target_platform
     git_revision = source_control.ResolveToRevision(
-        revision, 'chromium', bisect_perf_regression.DEPOT_DEPS_NAME, 100)
+        revision, 'chromium', bisect_utils.DEPOT_DEPS_NAME, 100)
     depot = 'chromium'
     command = bisect_instance.GetCompatibleCommand(
         original_command, git_revision, depot)
@@ -301,11 +292,11 @@
 
   def testBisectImprovementDirectionFails(self):
     """Dry run of a bisect with an improvement instead of regression."""
-
     # Test result goes from 0 to 100 where higher is better
     results = _GenericDryRun(_GetExtendedOptions(1, 100))
     self.assertIsNotNone(results.error)
     self.assertIn('not a regression', results.error)
+
     # Test result goes from 0 to -100 where lower is better
     results = _GenericDryRun(_GetExtendedOptions(-1, -100))
     self.assertIsNotNone(results.error)
@@ -320,6 +311,31 @@
     results = _GenericDryRun(_GetExtendedOptions(1, -100))
     self.assertIsNone(results.error)
 
+  @mock.patch('bisect_perf_regression.BisectPerformanceMetrics.'
+              'RunPerformanceTestAndParseResults', _MockRunTests)
+  def testBisectStopsOnDoubtfulRegression(self):
+    global _MockResultsGenerator
+    _MockResultsGenerator = (rs for rs in CLEAR_NON_REGRESSION)
+    results = _GenericDryRun(_GetExtendedOptions(0, 0, False))
+    self.assertIsNotNone(results.error)
+    self.assertIn('could not reproduce the regression', results.error)
+
+    _MockResultsGenerator = (rs for rs in ALMOST_REGRESSION)
+    results = _GenericDryRun(_GetExtendedOptions(0, 0, False))
+    self.assertIsNotNone(results.error)
+    self.assertIn('could not reproduce the regression', results.error)
+
+  @mock.patch('bisect_perf_regression.BisectPerformanceMetrics.'
+              'RunPerformanceTestAndParseResults', _MockRunTests)
+  def testBisectContinuesOnClearRegression(self):
+    global _MockResultsGenerator
+    _MockResultsGenerator = (rs for rs in CLEAR_REGRESSION)
+    with self.assertRaises(StopIteration):
+      _GenericDryRun(_GetExtendedOptions(0, 0, False))
+
+    _MockResultsGenerator = (rs for rs in BARELY_REGRESSION)
+    with self.assertRaises(StopIteration):
+      _GenericDryRun(_GetExtendedOptions(0, 0, False))
 
   def testGetCommitPosition(self):
     cp_git_rev = '7017a81991de983e12ab50dfc071c70e06979531'
@@ -366,18 +382,18 @@
   def setUp(self):
     self.old_chdir = os.chdir
     os.chdir = self.mockChdir
-    self.old_depot_names = bisect_perf_regression.DEPOT_NAMES
-    bisect_perf_regression.DEPOT_NAMES = ['mock_depot']
-    self.old_depot_deps_name = bisect_perf_regression.DEPOT_DEPS_NAME
-    bisect_perf_regression.DEPOT_DEPS_NAME = {'mock_depot': {'src': 'src/foo'}}
+    self.old_depot_names = bisect_utils.DEPOT_NAMES
+    bisect_utils.DEPOT_NAMES = ['mock_depot']
+    self.old_depot_deps_name = bisect_utils.DEPOT_DEPS_NAME
+    bisect_utils.DEPOT_DEPS_NAME = {'mock_depot': {'src': 'src/foo'}}
 
     self.registry = bisect_perf_regression.DepotDirectoryRegistry('/mock/src')
     self.cur_dir = None
 
   def tearDown(self):
     os.chdir = self.old_chdir
-    bisect_perf_regression.DEPOT_NAMES = self.old_depot_names
-    bisect_perf_regression.DEPOT_DEPS_NAME = self.old_depot_deps_name
+    bisect_utils.DEPOT_NAMES = self.old_depot_names
+    bisect_utils.DEPOT_DEPS_NAME = self.old_depot_deps_name
 
   def mockChdir(self, new_dir):
     self.cur_dir = new_dir
diff --git a/tools/auto_bisect/bisect_printer.py b/tools/auto_bisect/bisect_printer.py
new file mode 100644
index 0000000..df90fde8
--- /dev/null
+++ b/tools/auto_bisect/bisect_printer.py
@@ -0,0 +1,388 @@
+# 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.
+
+"""This file contains printing-related functionality of the bisect."""
+
+import datetime
+import re
+
+from bisect_results import BisectResults
+import bisect_utils
+import source_control
+
+
+# The perf dashboard looks for a string like "Estimated Confidence: 95%"
+# to decide whether or not to cc the author(s). If you change this, please
+# update the perf dashboard as well.
+RESULTS_BANNER = """
+===== BISECT JOB RESULTS =====
+Status: %(status)s
+
+Test Command: %(command)s
+Test Metric: %(metrics)s
+Relative Change: %(change)s
+Estimated Confidence: %(confidence).02f%%"""
+
+# The perf dashboard specifically looks for the string
+# "Author  : " to parse out who to cc on a bug. If you change the
+# formatting here, please update the perf dashboard as well.
+RESULTS_REVISION_INFO = """
+===== SUSPECTED CL(s) =====
+Subject : %(subject)s
+Author  : %(author)s%(commit_info)s
+Commit  : %(cl)s
+Date    : %(cl_date)s"""
+
+RESULTS_THANKYOU = """
+| O O | Visit http://www.chromium.org/developers/core-principles for Chrome's
+|  X  | policy on perf regressions. Contact chrome-perf-dashboard-team with any
+| / \ | questions or suggestions about bisecting. THANK YOU."""
+
+REPRO_STEPS_LOCAL = """
+==== INSTRUCTIONS TO REPRODUCE ====
+To run locally:
+ - Use the test command given under 'BISECT JOB RESULTS' above.
+ - Consider using a profiler. Pass --profiler=list to list available profilers.
+"""
+
+REPRO_STEPS_TRYJOB = """
+To reproduce on a performance try bot:
+ 1. Edit run-perf-test.cfg
+ 2. $ git try -b <bot> --svn_repo='svn://svn.chromium.org/chrome-try/try-perf'
+
+Notes:
+ a) Follow the in-file instructions in run-perf-test.cfg.
+ b) run-perf-test.cfg is under tools/ or under third_party/WebKit/Tools.
+ c) Do your edits preferably under a new git branch.
+ d) --browser=release and --browser=android-chromium-testshell are supported
+    depending on the platform (desktop|android).
+ e) Strip any src/ directories from the head of relative path names.
+ f) Make sure to use the appropriate bot on step 3.
+
+For more details please visit
+https://sites.google.com/a/chromium.org/dev/developers/performance-try-bots"""
+
+REPRO_STEPS_TRYJOB_TELEMETRY = """
+To reproduce on a performance try bot:
+%(command)s
+(Where <bot-name> comes from tools/perf/run_benchmark --browser=list)
+
+For more details please visit
+https://sites.google.com/a/chromium.org/dev/developers/performance-try-bots
+"""
+
+
+class BisectPrinter(object):
+
+  def __init__(self, opts, depot_registry):
+    self.opts = opts
+    self.depot_registry = depot_registry
+
+  def FormatAndPrintResults(self, bisect_results):
+    """Prints the results from a bisection run in a readable format.
+
+    Also prints annotations creating buildbot step "Results".
+
+    Args:
+      bisect_results: BisectResult object containing results to be printed.
+    """
+    if self.opts.output_buildbot_annotations:
+      bisect_utils.OutputAnnotationStepStart('Build Status Per Revision')
+
+    print
+    print 'Full results of bisection:'
+    for revision_state in bisect_results.state.GetRevisionStates():
+      build_status = revision_state.passed
+
+      if type(build_status) is bool:
+        if build_status:
+          build_status = 'Good'
+        else:
+          build_status = 'Bad'
+
+      print '  %20s  %40s  %s' % (revision_state.depot, revision_state.revision,
+                                  build_status)
+    print
+
+    if self.opts.output_buildbot_annotations:
+      bisect_utils.OutputAnnotationStepClosed()
+      # The perf dashboard scrapes the "results" step in order to comment on
+      # bugs. If you change this, please update the perf dashboard as well.
+      bisect_utils.OutputAnnotationStepStart('Results')
+
+    self._PrintBanner(bisect_results)
+    self._PrintWarnings(bisect_results.warnings)
+
+    if bisect_results.culprit_revisions and bisect_results.confidence:
+      for culprit in bisect_results.culprit_revisions:
+        cl, info, depot = culprit
+        self._PrintRevisionInfo(cl, info, depot)
+      if bisect_results.other_regressions:
+        self._PrintOtherRegressions(bisect_results.other_regressions)
+    self._PrintTestedCommitsTable(bisect_results.state.GetRevisionStates(),
+                                  bisect_results.first_working_revision,
+                                  bisect_results.last_broken_revision,
+                                  bisect_results.confidence)
+    self._PrintStepTime(bisect_results.state.GetRevisionStates())
+    self._PrintReproSteps()
+    self._PrintThankYou()
+    if self.opts.output_buildbot_annotations:
+      bisect_utils.OutputAnnotationStepClosed()
+
+  def PrintPartialResults(self, bisect_state):
+    revision_states = bisect_state.GetRevisionStates()
+    first_working_rev, last_broken_rev = BisectResults.FindBreakingRevRange(
+        revision_states)
+    self._PrintTestedCommitsTable(revision_states, first_working_rev,
+                                  last_broken_rev, 100, final_step=False)
+
+  @staticmethod
+  def _PrintThankYou():
+    print RESULTS_THANKYOU
+
+  @staticmethod
+  def _PrintStepTime(revision_states):
+    """Prints information about how long various steps took.
+
+    Args:
+      revision_states: Ordered list of revision states."""
+    step_perf_time_avg = 0.0
+    step_build_time_avg = 0.0
+    step_count = 0.0
+    for revision_state in revision_states:
+      if revision_state.value:
+        step_perf_time_avg += revision_state.perf_time
+        step_build_time_avg += revision_state.build_time
+        step_count += 1
+    if step_count:
+      step_perf_time_avg = step_perf_time_avg / step_count
+      step_build_time_avg = step_build_time_avg / step_count
+    print
+    print 'Average build time : %s' % datetime.timedelta(
+        seconds=int(step_build_time_avg))
+    print 'Average test time  : %s' % datetime.timedelta(
+        seconds=int(step_perf_time_avg))
+
+  def _GetViewVCLinkFromDepotAndHash(self, revision_id, depot):
+    """Gets link to the repository browser."""
+    info = source_control.QueryRevisionInfo(revision_id,
+        self.depot_registry.GetDepotDir(depot))
+    if depot and bisect_utils.DEPOT_DEPS_NAME[depot].has_key('viewvc'):
+      try:
+        # Format is "git-svn-id: svn://....@123456 <other data>"
+        svn_line = [i for i in info['body'].splitlines() if 'git-svn-id:' in i]
+        svn_revision = svn_line[0].split('@')
+        svn_revision = svn_revision[1].split(' ')[0]
+        return bisect_utils.DEPOT_DEPS_NAME[depot]['viewvc'] + svn_revision
+      except IndexError:
+        return ''
+    return ''
+
+  def _PrintRevisionInfo(self, cl, info, depot=None):
+    commit_link = self._GetViewVCLinkFromDepotAndHash(cl, depot)
+    if commit_link:
+      commit_info = '\nLink    : %s' % commit_link
+    else:
+      commit_info = ('\nFailed to parse SVN revision from body:\n%s' %
+                     info['body'])
+    print RESULTS_REVISION_INFO % {
+        'subject': info['subject'],
+        'author': info['email'],
+        'commit_info': commit_info,
+        'cl': cl,
+        'cl_date': info['date']
+    }
+
+  @staticmethod
+  def _PrintTableRow(column_widths, row_data):
+    """Prints out a row in a formatted table that has columns aligned.
+
+    Args:
+      column_widths: A list of column width numbers.
+      row_data: A list of items for each column in this row.
+    """
+    assert len(column_widths) == len(row_data)
+    text = ''
+    for i in xrange(len(column_widths)):
+      current_row_data = row_data[i].center(column_widths[i], ' ')
+      text += ('%%%ds' % column_widths[i]) % current_row_data
+    print text
+
+  def _PrintTestedCommitsHeader(self):
+    if self.opts.bisect_mode == bisect_utils.BISECT_MODE_MEAN:
+      self._PrintTableRow(
+          [20, 12, 70, 14, 12, 13],
+          ['Depot', 'Position', 'SHA', 'Mean', 'Std. Error', 'State'])
+    elif self.opts.bisect_mode == bisect_utils.BISECT_MODE_STD_DEV:
+      self._PrintTableRow(
+          [20, 12, 70, 14, 12, 13],
+          ['Depot', 'Position', 'SHA', 'Std. Error', 'Mean', 'State'])
+    elif self.opts.bisect_mode == bisect_utils.BISECT_MODE_RETURN_CODE:
+      self._PrintTableRow(
+          [20, 12, 70, 14, 13],
+          ['Depot', 'Position', 'SHA', 'Return Code', 'State'])
+    else:
+      assert False, 'Invalid bisect_mode specified.'
+
+  def _PrintTestedCommitsEntry(self, revision_state, commit_position, cl_link,
+                               state_str):
+    if self.opts.bisect_mode == bisect_utils.BISECT_MODE_MEAN:
+      std_error = '+-%.02f' % revision_state.value['std_err']
+      mean = '%.02f' % revision_state.value['mean']
+      self._PrintTableRow(
+          [20, 12, 70, 12, 14, 13],
+          [revision_state.depot, commit_position, cl_link, mean, std_error,
+           state_str])
+    elif self.opts.bisect_mode == bisect_utils.BISECT_MODE_STD_DEV:
+      std_error = '+-%.02f' % revision_state.value['std_err']
+      mean = '%.02f' % revision_state.value['mean']
+      self._PrintTableRow(
+          [20, 12, 70, 12, 14, 13],
+          [revision_state.depot, commit_position, cl_link, std_error, mean,
+           state_str])
+    elif self.opts.bisect_mode == bisect_utils.BISECT_MODE_RETURN_CODE:
+      mean = '%d' % revision_state.value['mean']
+      self._PrintTableRow(
+          [20, 12, 70, 14, 13],
+          [revision_state.depot, commit_position, cl_link, mean,
+           state_str])
+
+  def _PrintTestedCommitsTable(
+      self, revision_states, first_working_revision, last_broken_revision,
+      confidence, final_step=True):
+    print
+    if final_step:
+      print '===== TESTED COMMITS ====='
+    else:
+      print '===== PARTIAL RESULTS ====='
+    self._PrintTestedCommitsHeader()
+    state = 0
+    for revision_state in revision_states:
+      if revision_state.value:
+        if (revision_state == last_broken_revision or
+            revision_state == first_working_revision):
+          # If confidence is too low, don't add this empty line since it's
+          # used to put focus on a suspected CL.
+          if confidence and final_step:
+            print
+          state += 1
+          if state == 2 and not final_step:
+            # Just want a separation between "bad" and "good" cl's.
+            print
+
+        state_str = 'Bad'
+        if state == 1 and final_step:
+          state_str = 'Suspected CL'
+        elif state == 2:
+          state_str = 'Good'
+
+        # If confidence is too low, don't bother outputting good/bad.
+        if not confidence:
+          state_str = ''
+        state_str = state_str.center(13, ' ')
+
+        cl_link = self._GetViewVCLinkFromDepotAndHash(revision_state.revision,
+                                                      revision_state.depot)
+        if not cl_link:
+          cl_link = revision_state.revision
+        commit_position = source_control.GetCommitPosition(
+            revision_state.revision,
+            self.depot_registry.GetDepotDir(revision_state.depot))
+        commit_position = str(commit_position)
+        if not commit_position:
+          commit_position = ''
+        self._PrintTestedCommitsEntry(revision_state, commit_position, cl_link,
+                                      state_str)
+
+  def _PrintReproSteps(self):
+    """Prints out a section of the results explaining how to run the test.
+
+    This message includes the command used to run the test.
+    """
+    command = '$ ' + self.opts.command
+    if bisect_utils.IsTelemetryCommand(self.opts.command):
+      command += ('\nAlso consider passing --profiler=list to see available '
+                  'profilers.')
+    print REPRO_STEPS_LOCAL
+    if bisect_utils.IsTelemetryCommand(self.opts.command):
+      telemetry_command = re.sub(r'--browser=[^\s]+',
+                                 '--browser=<bot-name>',
+                                 command)
+      print REPRO_STEPS_TRYJOB_TELEMETRY % {'command': telemetry_command}
+    else:
+      print REPRO_STEPS_TRYJOB
+
+  def _PrintOtherRegressions(self, other_regressions):
+    """Prints a section of the results about other potential regressions."""
+    print
+    print 'Other regressions may have occurred:'
+    print '  %8s  %70s  %10s' % ('Depot'.center(8, ' '),
+        'Range'.center(70, ' '), 'Confidence'.center(10, ' '))
+    for regression in other_regressions:
+      current_rev_state, prev_rev_state, confidence = regression
+
+      current_link = self._GetViewVCLinkFromDepotAndHash(
+          current_rev_state.revision,
+          current_rev_state.depot)
+      previous_link = self._GetViewVCLinkFromDepotAndHash(
+          prev_rev_state.revision,
+          prev_rev_state.depot)
+
+      # If we can't map it to a viewable URL, at least show the original hash.
+      if not current_link:
+        current_link = current_rev_state.revision
+      if not previous_link:
+        previous_link = prev_rev_state.revision
+
+      print '  %8s  %70s %s' % (current_rev_state.depot, current_link,
+                                ('%d%%' % confidence).center(10, ' '))
+      print '  %8s  %70s' % (prev_rev_state.depot, previous_link)
+      print
+
+  @staticmethod
+  def _ConfidenceLevelStatus(bisect_results):
+    if not bisect_results.confidence:
+      return None
+    confidence_status = 'Successful with %(level)s confidence%(warning)s.'
+    if bisect_results.confidence >= bisect_utils.HIGH_CONFIDENCE:
+      level = 'high'
+    else:
+      level = 'low'
+    warning = ' and warnings'
+    if not bisect_results.warnings:
+      warning = ''
+    return confidence_status % {'level': level, 'warning': warning}
+
+  def _PrintBanner(self, bisect_results):
+    if self.opts.bisect_mode == bisect_utils.BISECT_MODE_RETURN_CODE:
+      metrics = 'N/A'
+      change = 'Yes'
+    else:
+      metrics = '/'.join(self.opts.metric)
+      change = '%.02f%% (+/-%.02f%%)' % (
+          bisect_results.regression_size, bisect_results.regression_std_err)
+
+    if bisect_results.culprit_revisions and bisect_results.confidence:
+      status = self._ConfidenceLevelStatus(bisect_results)
+    else:
+      status = 'Failure, could not reproduce.'
+      change = 'Bisect could not reproduce a change.'
+
+    print RESULTS_BANNER % {
+        'status': status,
+        'command': self.opts.command,
+        'metrics': metrics,
+        'change': change,
+        'confidence': bisect_results.confidence,
+    }
+
+  @staticmethod
+  def _PrintWarnings(warnings):
+    """Prints a list of warning strings if there are any."""
+    if not warnings:
+      return
+    print
+    print 'WARNINGS:'
+    for w in set(warnings):
+      print '  ! %s' % w
diff --git a/tools/auto_bisect/bisect_results.py b/tools/auto_bisect/bisect_results.py
index 59cb94d..281afe61 100644
--- a/tools/auto_bisect/bisect_results.py
+++ b/tools/auto_bisect/bisect_results.py
@@ -11,55 +11,148 @@
 import ttest
 
 
-def ConfidenceScore(good_results_lists, bad_results_lists):
-  """Calculates a confidence score.
-
-  This score is a percentage which represents our degree of confidence in the
-  proposition that the good results and bad results are distinct groups, and
-  their differences aren't due to chance alone.
-
-
-  Args:
-    good_results_lists: A list of lists of "good" result numbers.
-    bad_results_lists: A list of lists of "bad" result numbers.
-
-  Returns:
-    A number in the range [0, 100].
-  """
-  # If there's only one item in either list, this means only one revision was
-  # classified good or bad; this isn't good enough evidence to make a decision.
-  # If an empty list was passed, that also implies zero confidence.
-  if len(good_results_lists) <= 1 or len(bad_results_lists) <= 1:
-    return 0.0
-
-  # Flatten the lists of results lists.
-  sample1 = sum(good_results_lists, [])
-  sample2 = sum(bad_results_lists, [])
-
-  # If there were only empty lists in either of the lists (this is unexpected
-  # and normally shouldn't happen), then we also want to return 0.
-  if not sample1 or not sample2:
-    return 0.0
-
-  # The p-value is approximately the probability of obtaining the given set
-  # of good and bad values just by chance.
-  _, _, p_value = ttest.WelchsTTest(sample1, sample2)
-  return 100.0 * (1.0 - p_value)
-
-
 class BisectResults(object):
+  """Contains results of the completed bisect.
 
-  def __init__(self, depot_registry):
-    self._depot_registry = depot_registry
-    self.revision_data = {}
-    self.error = None
+  Properties:
+    error: Error message if the bisect failed.
+
+  If the error is None, the following properties are present:
+    warnings: List of warnings from the bisect run.
+    state: BisectState object from which these results were generated.
+    first_working_revision: First good revision.
+    last_broken_revision: Last bad revision.
+
+  If both of above revisions are not None, the follow properties are present:
+    culprit_revisions: A list of revisions, which contain the bad change
+        introducing the failure.
+    other_regressions: A list of tuples representing other regressions, which
+        may have occured.
+    regression_size: For performance bisects, this is a relative change of
+        the mean metric value. For other bisects this field always contains
+        'zero-to-nonzero'.
+    regression_std_err: For performance bisects, it is a pooled standard error
+        for groups of good and bad runs. Not used for other bisects.
+    confidence: For performance bisects, it is a confidence that the good and
+        bad runs are distinct groups. Not used for non-performance bisects.
+  """
+
+  def __init__(self, bisect_state=None, depot_registry=None, opts=None,
+               runtime_warnings=None, error=None):
+    """Computes final bisect results after a bisect run is complete.
+
+    This constructor should be called in one of the following ways:
+      BisectResults(state, depot_registry, opts, runtime_warnings)
+      BisectResults(error=error)
+
+    First option creates an object representing successful bisect results, while
+    second option creates an error result.
+
+    Args:
+      bisect_state: BisectState object representing latest bisect state.
+      depot_registry: DepotDirectoryRegistry object with information on each
+          repository in the bisect_state.
+      opts: Options passed to the bisect run.
+      runtime_warnings: A list of warnings from the bisect run.
+      error: Error message. When error is not None, other arguments are ignored.
+    """
+
+    self.error = error
+    if error is not None:
+      return
+
+    assert (bisect_state is not None and depot_registry is not None and
+            opts is not None and runtime_warnings is not None), (
+            'Incorrect use of the BisectResults constructor. When error is '
+            'None, all other arguments are required')
+
+    self.state = bisect_state
+
+    rev_states = bisect_state.GetRevisionStates()
+    first_working_rev, last_broken_rev = self.FindBreakingRevRange(rev_states)
+    self.first_working_revision = first_working_rev
+    self.last_broken_revision = last_broken_rev
+
+    if first_working_rev is not None and last_broken_rev is not None:
+      statistics = self._ComputeRegressionStatistics(
+          rev_states, first_working_rev, last_broken_rev)
+
+      self.regression_size = statistics['regression_size']
+      self.regression_std_err = statistics['regression_std_err']
+      self.confidence = statistics['confidence']
+
+      self.culprit_revisions = self._FindCulpritRevisions(
+          rev_states, depot_registry, first_working_rev, last_broken_rev)
+
+      self.other_regressions = self._FindOtherRegressions(
+          rev_states, statistics['bad_greater_than_good'])
+
+    self.warnings = runtime_warnings + self._GetResultBasedWarnings(
+        self.culprit_revisions, opts, self.confidence)
 
   @staticmethod
-  def _FindOtherRegressions(revision_data_sorted, bad_greater_than_good):
+  def _GetResultBasedWarnings(culprit_revisions, opts, confidence):
+    warnings = []
+    if len(culprit_revisions) > 1:
+      warnings.append('Due to build errors, regression range could '
+                      'not be narrowed down to a single commit.')
+    if opts.repeat_test_count == 1:
+      warnings.append('Tests were only set to run once. This may '
+                      'be insufficient to get meaningful results.')
+    if 0 < confidence < bisect_utils.HIGH_CONFIDENCE:
+      warnings.append('Confidence is not high. Try bisecting again '
+                      'with increased repeat_count, larger range, or '
+                      'on another metric.')
+    if not confidence:
+      warnings.append('Confidence score is 0%. Try bisecting again on '
+                      'another platform or another metric.')
+    return warnings
+
+  @staticmethod
+  def ConfidenceScore(sample1, sample2,
+                      accept_single_bad_or_good=False):
+    """Calculates a confidence score.
+
+    This score is a percentage which represents our degree of confidence in the
+    proposition that the good results and bad results are distinct groups, and
+    their differences aren't due to chance alone.
+
+
+    Args:
+      sample1: A flat list of "good" result numbers.
+      sample2: A flat list of "bad" result numbers.
+      accept_single_bad_or_good: If True, computes confidence even if there is
+          just one bad or good revision, otherwise single good or bad revision
+          always returns 0.0 confidence. This flag will probably get away when
+          we will implement expanding the bisect range by one more revision for
+          such case.
+
+    Returns:
+      A number in the range [0, 100].
+    """
+    # If there's only one item in either list, this means only one revision was
+    # classified good or bad; this isn't good enough evidence to make a
+    # decision. If an empty list was passed, that also implies zero confidence.
+    if not accept_single_bad_or_good:
+      if len(sample1) <= 1 or len(sample2) <= 1:
+        return 0.0
+
+    # If there were only empty lists in either of the lists (this is unexpected
+    # and normally shouldn't happen), then we also want to return 0.
+    if not sample1 or not sample2:
+      return 0.0
+
+    # The p-value is approximately the probability of obtaining the given set
+    # of good and bad values just by chance.
+    _, _, p_value = ttest.WelchsTTest(sample1, sample2)
+    return 100.0 * (1.0 - p_value)
+
+  @classmethod
+  def _FindOtherRegressions(cls, revision_states, bad_greater_than_good):
     """Compiles a list of other possible regressions from the revision data.
 
     Args:
-      revision_data_sorted: Sorted list of (revision, revision data) pairs.
+      revision_states: Sorted list of RevisionState objects.
       bad_greater_than_good: Whether the result value at the "bad" revision is
           numerically greater than the result value at the "good" revision.
 
@@ -69,13 +162,15 @@
     """
     other_regressions = []
     previous_values = []
-    previous_id = None
-    for current_id, current_data in revision_data_sorted:
-      current_values = current_data['value']
-      if current_values:
-        current_values = current_values['values']
+    prev_state = None
+    for revision_state in revision_states:
+      if revision_state.value:
+        current_values = revision_state.value['values']
         if previous_values:
-          confidence = ConfidenceScore(previous_values, [current_values])
+          confidence_params = (sum(previous_values, []),
+                               sum([current_values], []))
+          confidence = cls.ConfidenceScore(*confidence_params,
+                                           accept_single_bad_or_good=True)
           mean_of_prev_runs = math_utils.Mean(sum(previous_values, []))
           mean_of_current_runs = math_utils.Mean(current_values)
 
@@ -83,178 +178,85 @@
           # the overall regression. If the mean of the previous runs < the
           # mean of the current runs, this local regression is in same
           # direction.
-          prev_less_than_current = mean_of_prev_runs < mean_of_current_runs
-          is_same_direction = (prev_less_than_current if
-              bad_greater_than_good else not prev_less_than_current)
+          prev_greater_than_current = mean_of_prev_runs > mean_of_current_runs
+          is_same_direction = (prev_greater_than_current if
+              bad_greater_than_good else not prev_greater_than_current)
 
           # Only report potential regressions with high confidence.
           if is_same_direction and confidence > 50:
-            other_regressions.append([current_id, previous_id, confidence])
+            other_regressions.append([revision_state, prev_state, confidence])
         previous_values.append(current_values)
-        previous_id = current_id
+        prev_state = revision_state
     return other_regressions
 
-  def GetResultsDict(self):
-    """Prepares and returns information about the final resulsts as a dict.
-
-    Returns:
-      A dictionary with the following fields
-
-      'first_working_revision': First good revision.
-      'last_broken_revision': Last bad revision.
-      'culprit_revisions': A list of revisions, which contain the bad change
-          introducing the failure.
-      'other_regressions': A list of tuples representing other regressions,
-          which may have occured.
-      'regression_size': For performance bisects, this is a relative change of
-          the mean metric value. For other bisects this field always contains
-          'zero-to-nonzero'.
-      'regression_std_err': For performance bisects, it is a pooled standard
-          error for groups of good and bad runs. Not used for other bisects.
-      'confidence': For performance bisects, it is a confidence that the good
-          and bad runs are distinct groups. Not used for non-performance
-          bisects.
-      'revision_data_sorted': dict mapping revision ids to data about that
-          revision. Each piece of revision data consists of a dict with the
-          following keys:
-
-          'passed': Represents whether the performance test was successful at
-              that revision. Possible values include: 1 (passed), 0 (failed),
-              '?' (skipped), 'F' (build failed).
-          'depot': The depot that this revision is from (i.e. WebKit)
-          'external': If the revision is a 'src' revision, 'external' contains
-              the revisions of each of the external libraries.
-          'sort': A sort value for sorting the dict in order of commits.
-
-          For example:
-          {
-            'CL #1':
-            {
-              'passed': False,
-              'depot': 'chromium',
-              'external': None,
-              'sort': 0
-            }
-          }
-    """
-    revision_data_sorted = sorted(self.revision_data.iteritems(),
-                                  key = lambda x: x[1]['sort'])
-
-    # Find range where it possibly broke.
+  @staticmethod
+  def FindBreakingRevRange(revision_states):
     first_working_revision = None
-    first_working_revision_index = -1
     last_broken_revision = None
-    last_broken_revision_index = -1
+
+    for revision_state in revision_states:
+      if revision_state.passed == 1 and not first_working_revision:
+        first_working_revision = revision_state
+
+      if not revision_state.passed:
+        last_broken_revision = revision_state
+
+    return first_working_revision, last_broken_revision
+
+  @staticmethod
+  def _FindCulpritRevisions(revision_states, depot_registry, first_working_rev,
+                            last_broken_rev):
+    cwd = os.getcwd()
 
     culprit_revisions = []
-    other_regressions = []
-    regression_size = 0.0
-    regression_std_err = 0.0
-    confidence = 0.0
+    for i in xrange(last_broken_rev.index, first_working_rev.index):
+      depot_registry.ChangeToDepotDir(revision_states[i].depot)
+      info = source_control.QueryRevisionInfo(revision_states[i].revision)
+      culprit_revisions.append((revision_states[i].revision, info,
+                                revision_states[i].depot))
 
-    for i in xrange(len(revision_data_sorted)):
-      k, v = revision_data_sorted[i]
-      if v['passed'] == 1:
-        if not first_working_revision:
-          first_working_revision = k
-          first_working_revision_index = i
+    os.chdir(cwd)
+    return culprit_revisions
 
-      if not v['passed']:
-        last_broken_revision = k
-        last_broken_revision_index = i
+  @classmethod
+  def _ComputeRegressionStatistics(cls, rev_states, first_working_rev,
+                                   last_broken_rev):
+    # TODO(sergiyb): We assume that value has "values" key, which may not be
+    # the case for failure-bisects, where there is a single value only.
+    broken_means = [state.value['values']
+                    for state in rev_states[:last_broken_rev.index+1]
+                    if state.value]
 
-    if last_broken_revision != None and first_working_revision != None:
-      broken_means = []
-      for i in xrange(0, last_broken_revision_index + 1):
-        if revision_data_sorted[i][1]['value']:
-          broken_means.append(revision_data_sorted[i][1]['value']['values'])
+    working_means = [state.value['values']
+                     for state in rev_states[first_working_rev.index:]
+                     if state.value]
 
-      working_means = []
-      for i in xrange(first_working_revision_index, len(revision_data_sorted)):
-        if revision_data_sorted[i][1]['value']:
-          working_means.append(revision_data_sorted[i][1]['value']['values'])
+    # Flatten the lists to calculate mean of all values.
+    working_mean = sum(working_means, [])
+    broken_mean = sum(broken_means, [])
 
-      # Flatten the lists to calculate mean of all values.
-      working_mean = sum(working_means, [])
-      broken_mean = sum(broken_means, [])
+    # Calculate the approximate size of the regression
+    mean_of_bad_runs = math_utils.Mean(broken_mean)
+    mean_of_good_runs = math_utils.Mean(working_mean)
 
-      # Calculate the approximate size of the regression
-      mean_of_bad_runs = math_utils.Mean(broken_mean)
-      mean_of_good_runs = math_utils.Mean(working_mean)
-
-      regression_size = 100 * math_utils.RelativeChange(mean_of_good_runs,
+    regression_size = 100 * math_utils.RelativeChange(mean_of_good_runs,
                                                       mean_of_bad_runs)
-      if math.isnan(regression_size):
-        regression_size = 'zero-to-nonzero'
+    if math.isnan(regression_size):
+      regression_size = 'zero-to-nonzero'
 
-      regression_std_err = math.fabs(math_utils.PooledStandardError(
-          [working_mean, broken_mean]) /
-          max(0.0001, min(mean_of_good_runs, mean_of_bad_runs))) * 100.0
+    regression_std_err = math.fabs(math_utils.PooledStandardError(
+        [working_mean, broken_mean]) /
+        max(0.0001, min(mean_of_good_runs, mean_of_bad_runs))) * 100.0
 
-      # Give a "confidence" in the bisect. At the moment we use how distinct the
-      # values are before and after the last broken revision, and how noisy the
-      # overall graph is.
-      confidence = ConfidenceScore(working_means, broken_means)
+    # Give a "confidence" in the bisect. At the moment we use how distinct the
+    # values are before and after the last broken revision, and how noisy the
+    # overall graph is.
+    confidence_params = (sum(working_means, []), sum(broken_means, []))
+    confidence = cls.ConfidenceScore(*confidence_params)
 
-      culprit_revisions = []
+    bad_greater_than_good = mean_of_bad_runs > mean_of_good_runs
 
-      cwd = os.getcwd()
-      self._depot_registry.ChangeToDepotDir(
-          self.revision_data[last_broken_revision]['depot'])
-
-      if self.revision_data[last_broken_revision]['depot'] == 'cros':
-        # Want to get a list of all the commits and what depots they belong
-        # to so that we can grab info about each.
-        cmd = ['repo', 'forall', '-c',
-            'pwd ; git log --pretty=oneline --before=%d --after=%d' % (
-            last_broken_revision, first_working_revision + 1)]
-        output, return_code = bisect_utils.RunProcessAndRetrieveOutput(cmd)
-
-        changes = []
-        assert not return_code, ('An error occurred while running '
-                                 '"%s"' % ' '.join(cmd))
-        last_depot = None
-        cwd = os.getcwd()
-        for l in output.split('\n'):
-          if l:
-            # Output will be in form:
-            # /path_to_depot
-            # /path_to_other_depot
-            # <SHA1>
-            # /path_again
-            # <SHA1>
-            # etc.
-            if l[0] == '/':
-              last_depot = l
-            else:
-              contents = l.split(' ')
-              if len(contents) > 1:
-                changes.append([last_depot, contents[0]])
-        for c in changes:
-          os.chdir(c[0])
-          info = source_control.QueryRevisionInfo(c[1])
-          culprit_revisions.append((c[1], info, None))
-      else:
-        for i in xrange(last_broken_revision_index, len(revision_data_sorted)):
-          k, v = revision_data_sorted[i]
-          if k == first_working_revision:
-            break
-          self._depot_registry.ChangeToDepotDir(v['depot'])
-          info = source_control.QueryRevisionInfo(k)
-          culprit_revisions.append((k, info, v['depot']))
-      os.chdir(cwd)
-
-      # Check for any other possible regression ranges.
-      other_regressions = self._FindOtherRegressions(
-          revision_data_sorted, mean_of_bad_runs > mean_of_good_runs)
-
-    return {
-        'first_working_revision': first_working_revision,
-        'last_broken_revision': last_broken_revision,
-        'culprit_revisions': culprit_revisions,
-        'other_regressions': other_regressions,
-        'regression_size': regression_size,
-        'regression_std_err': regression_std_err,
-        'confidence': confidence,
-        'revision_data_sorted': revision_data_sorted
-    }
+    return {'regression_size': regression_size,
+            'regression_std_err': regression_std_err,
+            'confidence': confidence,
+            'bad_greater_than_good': bad_greater_than_good}
diff --git a/tools/auto_bisect/bisect_results_test.py b/tools/auto_bisect/bisect_results_test.py
index 361f5f10..25359c5 100644
--- a/tools/auto_bisect/bisect_results_test.py
+++ b/tools/auto_bisect/bisect_results_test.py
@@ -2,38 +2,248 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import os
 import unittest
 
-import bisect_results
-import ttest
+from bisect_results import BisectResults
+import source_control
 
 
-class ConfidenceScoreTest(unittest.TestCase):
+class MockDepotRegistry(object):
+  def ChangeToDepotDir(self, depot):
+    pass
+
+
+class MockRevisionState(object):
+  def __init__(self, revision, index, depot='chromium', value=None,
+               perf_time=0, build_time=0, passed='?', external=None):
+    self.depot = depot
+    self.revision = revision
+    self.index = index
+    self.value = value
+    self.perf_time = perf_time
+    self.build_time = build_time
+    self.passed = passed
+    self.external = external
+
+
+class MockBisectState(object):
+
+  def __init__(self):
+    self.mock_revision_states = []
+
+    mock_bad_val = {'values': [100, 105, 95]}
+    for i, rev in enumerate(['a', 'b']):
+      mock_rev_state = MockRevisionState(rev, i, value=mock_bad_val, passed=0)
+      self.mock_revision_states.append(mock_rev_state)
+
+    mock_good_val = {'values': [1, 2, 3]}
+    for i, rev in enumerate(['c', 'd', 'e'], start=2):
+      mock_rev_state = MockRevisionState(rev, i, value=mock_good_val, passed=1)
+      self.mock_revision_states.append(mock_rev_state)
+
+  def GetRevisionStates(self):
+    return self.mock_revision_states
+
+
+class MockBisectOptions(object):
+
+  def __init__(self):
+    self.repeat_test_count = 3
+
+
+class BisectResultsTest(unittest.TestCase):
+
+  def setUp(self):
+    self.mock_bisect_state = MockBisectState()
+    self.mock_depot_registry = MockDepotRegistry()
+    self.mock_opts = MockBisectOptions()
+    self.mock_warnings = []
+
+    self.original_getcwd = os.getcwd
+    self.original_chdir = os.chdir
+    self.original_query_revision_info = source_control.QueryRevisionInfo
+
+    os.getcwd = lambda: '/path'
+    os.chdir = lambda _: None
+
+    revision_infos = {'b': {'test': 'b'}, 'c': {'test': 'c'}}
+    source_control.QueryRevisionInfo = lambda rev: revision_infos[rev]
+
+  def tearDown(self):
+    os.getcwd = self.original_getcwd
+    os.chdir = self.original_chdir
+    source_control.QueryRevisionInfo = self.original_query_revision_info
+
+  def _AssertConfidence(self, score, bad_values, good_values):
+    """Checks whether the given sets of values have a given confidence score.
+
+    The score represents our confidence that the two sets of values wouldn't
+    be as different as they are just by chance; that is, that some real change
+    occurred between the two sets of values.
+
+    Args:
+      score: Expected confidence score.
+      bad_values: First list of numbers.
+      good_values: Second list of numbers.
+    """
+    confidence = BisectResults.ConfidenceScore(bad_values, good_values)
+    self.assertEqual(score, confidence)
 
   def testConfidenceScoreIsZeroOnTooFewLists(self):
-    self.assertEqual(bisect_results.ConfidenceScore([], [[1], [2]]), 0.0)
-    self.assertEqual(bisect_results.ConfidenceScore([[1], [2]], []), 0.0)
-    self.assertEqual(bisect_results.ConfidenceScore([[1]], [[1], [2]]), 0.0)
-    self.assertEqual(bisect_results.ConfidenceScore([[1], [2]], [[1]]), 0.0)
+    self._AssertConfidence(0.0, [], [1, 2])
+    self._AssertConfidence(0.0, [1, 2], [])
+    self._AssertConfidence(0.0, [1], [1, 2])
+    self._AssertConfidence(0.0, [1, 2], [1])
 
-  def testConfidenceScoreIsZeroOnEmptyLists(self):
-    self.assertEqual(bisect_results.ConfidenceScore([[], []], [[1], [2]]), 0.0)
-    self.assertEqual(bisect_results.ConfidenceScore([[1], [2]], [[], []]), 0.0)
+  def testConfidenceScore_ZeroConfidence(self):
+    # The good and bad sets contain the same values, so the confidence that
+    # they're different should be zero.
+    self._AssertConfidence(0.0, [4, 5, 7, 6, 8, 7], [8, 7, 6, 7, 5, 4])
 
-  def testConfidenceScoreIsUsingTTestWelchsTTest(self):
-    original_WelchsTTest = ttest.WelchsTTest
-    try:
-      ttest.WelchsTTest = lambda _sample1, _sample2: (0, 0, 0.42)
-      self.assertAlmostEqual(
-        bisect_results.ConfidenceScore([[1], [1]], [[2], [2]]), 58.0)
-    finally:
-      ttest.WelchsTTest = original_WelchsTTest
+  def testConfidenceScore_MediumConfidence(self):
+    self._AssertConfidence(80.0, [0, 1, 1, 1, 2, 2], [1, 1, 1, 3, 3, 4])
 
+  def testConfidenceScore_HighConfidence(self):
+    self._AssertConfidence(95.0, [0, 1, 1, 1, 2, 2], [1, 2, 2, 3, 3, 4])
 
-class BisectResulstsTest(unittest.TestCase):
-  # TODO(sergiyb): Write tests for GetResultDicts when it is broken into smaller
-  # pieces.
-  pass
+  def testConfidenceScore_VeryHighConfidence(self):
+    # Confidence is high if the two sets of values have no internal variance.
+    self._AssertConfidence(99.9, [1, 1, 1, 1], [1.2, 1.2, 1.2, 1.2])
+    self._AssertConfidence(99.9, [1, 1, 1, 1], [1.01, 1.01, 1.01, 1.01])
+
+  def testConfidenceScore_UnbalancedSampleSize(self):
+    # The second set of numbers only contains one number, so confidence is 0.
+    self._AssertConfidence(0.0, [1.1, 1.2, 1.1, 1.2, 1.0, 1.3, 1.2], [1.4])
+
+  def testConfidenceScore_EmptySample(self):
+    # Confidence is zero if either or both samples are empty.
+    self._AssertConfidence(0.0, [], [])
+    self._AssertConfidence(0.0, [], [1.1, 1.2, 1.1, 1.2, 1.0, 1.3, 1.2, 1.3])
+    self._AssertConfidence(0.0, [1.1, 1.2, 1.1, 1.2, 1.0, 1.3, 1.2, 1.3], [])
+
+  def testConfidenceScore_FunctionalTestResults(self):
+    self._AssertConfidence(80.0, [1, 1, 0, 1, 1, 1, 0, 1], [0, 0, 1, 0, 1, 0])
+    self._AssertConfidence(99.9, [1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0])
+
+  def testConfidenceScore_RealWorldCases(self):
+    """This method contains a set of data from actual bisect results.
+
+    The confidence scores asserted below were all copied from the actual
+    results, so the purpose of this test method is mainly to show what the
+    results for real cases are, and compare when we change the confidence
+    score function in the future.
+    """
+    self._AssertConfidence(80, [133, 130, 132, 132, 130, 129], [129, 129, 125])
+    self._AssertConfidence(99.5, [668, 667], [498, 498, 499])
+    self._AssertConfidence(80, [67, 68], [65, 65, 67])
+    self._AssertConfidence(0, [514], [514])
+    self._AssertConfidence(90, [616, 613, 607, 615], [617, 619, 619, 617])
+    self._AssertConfidence(0, [3.5, 5.8, 4.7, 3.5, 3.6], [2.8])
+    self._AssertConfidence(90, [3, 3, 3], [2, 2, 2, 3])
+    self._AssertConfidence(0, [1999004, 1999627], [223355])
+    self._AssertConfidence(90, [1040, 934, 961], [876, 875, 789])
+    self._AssertConfidence(90, [309, 305, 304], [302, 302, 299, 303, 298])
+
+  def testCorrectlyFindsBreakingRange(self):
+    revision_states = self.mock_bisect_state.mock_revision_states
+    revision_states[0].passed = 0
+    revision_states[1].passed = 0
+    revision_states[2].passed = 1
+    revision_states[3].passed = 1
+    revision_states[4].passed = 1
+
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                            self.mock_opts, self.mock_warnings)
+    self.assertEqual(revision_states[2], results.first_working_revision)
+    self.assertEqual(revision_states[1], results.last_broken_revision)
+
+  def testCorrectlyComputesRegressionStatistics(self):
+    revision_states = self.mock_bisect_state.mock_revision_states
+    revision_states[0].passed = 0
+    revision_states[0].value = {'values': [1000, 999, 998]}
+    revision_states[1].passed = 0
+    revision_states[1].value = {'values': [980, 1000, 999]}
+    revision_states[2].passed = 1
+    revision_states[2].value = {'values': [50, 45, 55]}
+    revision_states[3].passed = 1
+    revision_states[3].value = {'values': [45, 56, 45]}
+    revision_states[4].passed = 1
+    revision_states[4].value = {'values': [51, 41, 58]}
+
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                            self.mock_opts, self.mock_warnings)
+    self.assertAlmostEqual(99.9, results.confidence)
+    self.assertAlmostEqual(1909.86547085, results.regression_size)
+    self.assertAlmostEqual(7.16625904, results.regression_std_err)
+
+  def testFindsCulpritRevisions(self):
+    revision_states = self.mock_bisect_state.mock_revision_states
+    revision_states[1].depot = 'chromium'
+    revision_states[2].depot = 'webkit'
+
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                          self.mock_opts, self.mock_warnings)
+
+    self.assertEqual(1, len(results.culprit_revisions))
+    self.assertEqual(('b', {'test': 'b'}, 'chromium'),
+                     results.culprit_revisions[0])
+
+  def testFindsOtherRegressions(self):
+    revision_states = self.mock_bisect_state.mock_revision_states
+    revision_states[0].passed = 0
+    revision_states[0].value = {'values': [100, 100, 100]}
+    revision_states[1].passed = 0
+    revision_states[1].value = {'values': [100, 100, 100]}
+    revision_states[2].passed = 1
+    revision_states[2].value = {'values': [10, 10, 10]}
+    revision_states[3].passed = 1
+    revision_states[3].value = {'values': [100, 100, 100]}
+    revision_states[4].passed = 1
+    revision_states[4].value = {'values': [60, 60, 60]}
+
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                            self.mock_opts, self.mock_warnings)
+    expected_regressions = [[revision_states[2], revision_states[1], 99.9],
+                            [revision_states[4], revision_states[3], 80.0]]
+    self.assertEqual(expected_regressions, results.other_regressions)
+
+  def testNoResultBasedWarningsForNormalState(self):
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                            self.mock_opts, self.mock_warnings)
+    self.assertEqual(0, len(results.warnings))
+
+  def testWarningForMultipleCulpritRevisions(self):
+    self.mock_bisect_state.mock_revision_states[2].passed = 'Skipped'
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                            self.mock_opts, self.mock_warnings)
+    self.assertEqual(1, len(results.warnings))
+
+  def testWarningForTooLowRetryLimit(self):
+    self.mock_opts.repeat_test_count = 1
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                            self.mock_opts, self.mock_warnings)
+    self.assertEqual(1, len(results.warnings))
+
+  def testWarningForTooLowConfidence(self):
+    revision_states = self.mock_bisect_state.mock_revision_states
+    revision_states[2].value = {'values': [95, 100, 90]}
+    revision_states[3].value = {'values': [95, 100, 90]}
+    revision_states[4].value = {'values': [95, 100, 90]}
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                            self.mock_opts, self.mock_warnings)
+    self.assertGreater(results.confidence, 0)
+    self.assertEqual(1, len(results.warnings))
+
+  def testWarningForZeroConfidence(self):
+    revision_states = self.mock_bisect_state.mock_revision_states
+    revision_states[2].value = {'values': [100, 105, 95]}
+    revision_states[3].value = {'values': [100, 105, 95]}
+    revision_states[4].value = {'values': [100, 105, 95]}
+    results = BisectResults(self.mock_bisect_state, self.mock_depot_registry,
+                            self.mock_opts, self.mock_warnings)
+    self.assertEqual(0, results.confidence)
+    self.assertEqual(1, len(results.warnings))
 
 
 if __name__ == '__main__':
diff --git a/tools/auto_bisect/bisect_state.py b/tools/auto_bisect/bisect_state.py
new file mode 100644
index 0000000..f5d7451
--- /dev/null
+++ b/tools/auto_bisect/bisect_state.py
@@ -0,0 +1,99 @@
+# 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.
+
+
+class RevisionState(object):
+  """Contains bisect state for a given revision.
+
+  Properties:
+    depot: The depot that this revision is from (e.g. WebKit).
+    revision: Revision number (Git hash or SVN number).
+    index: Position of the state in the list of all revisions.
+    value: Value(s) returned from the test.
+    perf_time: Time that a test took.
+    build_time: Time that a build took.
+    passed: Represents whether the performance test was successful at that
+        revision. Possible values include: 1 (passed), 0 (failed),
+        '?' (skipped), 'F' (build failed).
+    external: If the revision is a 'src' revision, 'external' contains the
+        revisions of each of the external libraries.
+  """
+
+  def __init__(self, depot, revision, index):
+    self.depot = depot
+    self.revision = revision
+    self.index = index
+    self.value = None
+    self.perf_time = 0
+    self.build_time = 0
+    self.passed = '?'
+    self.external = None
+
+  # TODO(sergiyb): Update() to parse run_results from the RunTest.
+
+
+class BisectState(object):
+  """Represents a state of the bisect as a collection of revision states."""
+
+  def __init__(self, depot, revisions):
+    """Initializes a new BisectState object with a set of revision states.
+
+    Args:
+      depot: Name of the depot used for initial set of revision states.
+      revisions: List of revisions used for initial set of revision states.
+    """
+    self.revision_states = []
+    self.revision_index = {}
+
+    index = 0
+    for revision in revisions:
+      new_state = self._InitRevisionState(depot, revision, index)
+      self.revision_states.append(new_state)
+      index += 1
+
+  @staticmethod
+  def _RevisionKey(depot, revision):
+    return "%s:%s" % (depot, revision)
+
+  def _InitRevisionState(self, depot, revision, index):
+    key = self._RevisionKey(depot, revision)
+    self.revision_index[key] = index
+    return RevisionState(depot, revision, index)
+
+  def GetRevisionState(self, depot, revision):
+    """Returns a mutable revision state."""
+    key = self._RevisionKey(depot, revision)
+    index = self.revision_index.get(key)
+    return self.revision_states[index] if index else None
+
+  def CreateRevisionStatesAfter(self, depot, revisions, reference_depot,
+                                reference_revision):
+    """Creates a set of new revision states after a specified reference state.
+
+    Args:
+      depot: Name of the depot for the new revision states.
+      revisions: List of revisions for the new revision states.
+      reference_depot: Name of the depot for the reference revision state.
+      reference_revision: Revision for the reference revision state.
+
+    Returns:
+      A list containing all created revision states in order as they were added.
+    """
+    ref_key = self._RevisionKey(reference_depot, reference_revision)
+    ref_index = self.revision_index[ref_key]
+    num_new_revisions = len(revisions)
+    for entry in self.revision_states:
+      if entry.index > ref_index:
+        entry.index += num_new_revisions
+
+    first_index = ref_index + 1
+    for index, revision in enumerate(revisions, start=first_index):
+      new_state = self._InitRevisionState(depot, revision, index)
+      self.revision_states.insert(index, new_state)
+
+    return self.revision_states[first_index:first_index + num_new_revisions]
+
+  def GetRevisionStates(self):
+    """Returns a copy of the list of the revision states."""
+    return list(self.revision_states)
diff --git a/tools/auto_bisect/bisect_state_test.py b/tools/auto_bisect/bisect_state_test.py
new file mode 100644
index 0000000..0630fab5
--- /dev/null
+++ b/tools/auto_bisect/bisect_state_test.py
@@ -0,0 +1,31 @@
+# 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.
+
+import unittest
+
+from bisect_state import BisectState
+
+
+class BisectStateTest(unittest.TestCase):
+
+  def testCreatesRevisionsStateAfterAReferenceRevision(self):
+    bisect_state = BisectState('chromium', ['a', 'b', 'c', 'd'])
+    bisect_state.CreateRevisionStatesAfter('webkit', [1, 2, 3], 'chromium', 'b')
+    bisect_state.CreateRevisionStatesAfter('v8', [100, 200], 'webkit', 2)
+
+    actual_revisions = bisect_state.GetRevisionStates()
+    expected_revisions = [('chromium', 'a'), ('chromium', 'b'), ('webkit', 1),
+                          ('webkit', 2), ('v8', 100), ('v8', 200),
+                          ('webkit', 3), ('chromium', 'c'), ('chromium', 'd')]
+    self.assertEqual(len(expected_revisions), len(actual_revisions))
+    for i in xrange(len(actual_revisions)):
+      self.assertEqual(i, actual_revisions[i].index)
+      self.assertEqual(expected_revisions[i][0], actual_revisions[i].depot)
+      self.assertEqual(expected_revisions[i][1], actual_revisions[i].revision)
+
+  # TODO(sergiyb): More tests for the remaining functions.
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/tools/auto_bisect/bisect_utils.py b/tools/auto_bisect/bisect_utils.py
index da8b04b9..38f56f1 100644
--- a/tools/auto_bisect/bisect_utils.py
+++ b/tools/auto_bisect/bisect_utils.py
@@ -87,6 +87,116 @@
 # Bisect working directory.
 BISECT_DIR = 'bisect'
 
+# The percentage at which confidence is considered high.
+HIGH_CONFIDENCE = 95
+
+# Below is the map of "depot" names to information about each depot. Each depot
+# is a repository, and in the process of bisecting, revision ranges in these
+# repositories may also be bisected.
+#
+# Each depot information dictionary may contain:
+#   src: Path to the working directory.
+#   recurse: True if this repository will get bisected.
+#   depends: A list of other repositories that are actually part of the same
+#       repository in svn. If the repository has any dependent repositories
+#       (e.g. skia/src needs skia/include and skia/gyp to be updated), then
+#       they are specified here.
+#   svn: URL of SVN repository. Needed for git workflow to resolve hashes to
+#       SVN revisions.
+#   from: Parent depot that must be bisected before this is bisected.
+#   deps_var: Key name in vars variable in DEPS file that has revision
+#       information.
+DEPOT_DEPS_NAME = {
+    'chromium': {
+        'src': 'src',
+        'recurse': True,
+        'depends': None,
+        'from': ['cros', 'android-chrome'],
+        'viewvc':
+            'http://src.chromium.org/viewvc/chrome?view=revision&revision=',
+        'deps_var': 'chromium_rev'
+    },
+    'webkit': {
+        'src': 'src/third_party/WebKit',
+        'recurse': True,
+        'depends': None,
+        'from': ['chromium'],
+        'viewvc':
+            'http://src.chromium.org/viewvc/blink?view=revision&revision=',
+        'deps_var': 'webkit_revision'
+    },
+    'angle': {
+        'src': 'src/third_party/angle',
+        'src_old': 'src/third_party/angle_dx11',
+        'recurse': True,
+        'depends': None,
+        'from': ['chromium'],
+        'platform': 'nt',
+        'deps_var': 'angle_revision'
+    },
+    'v8': {
+        'src': 'src/v8',
+        'recurse': True,
+        'depends': None,
+        'from': ['chromium'],
+        'custom_deps': GCLIENT_CUSTOM_DEPS_V8,
+        'viewvc': 'https://code.google.com/p/v8/source/detail?r=',
+        'deps_var': 'v8_revision'
+    },
+    'v8_bleeding_edge': {
+        'src': 'src/v8_bleeding_edge',
+        'recurse': True,
+        'depends': None,
+        'svn': 'https://v8.googlecode.com/svn/branches/bleeding_edge',
+        'from': ['v8'],
+        'viewvc': 'https://code.google.com/p/v8/source/detail?r=',
+        'deps_var': 'v8_revision'
+    },
+    'skia/src': {
+        'src': 'src/third_party/skia/src',
+        'recurse': True,
+        'svn': 'http://skia.googlecode.com/svn/trunk/src',
+        'depends': ['skia/include', 'skia/gyp'],
+        'from': ['chromium'],
+        'viewvc': 'https://code.google.com/p/skia/source/detail?r=',
+        'deps_var': 'skia_revision'
+    },
+    'skia/include': {
+        'src': 'src/third_party/skia/include',
+        'recurse': False,
+        'svn': 'http://skia.googlecode.com/svn/trunk/include',
+        'depends': None,
+        'from': ['chromium'],
+        'viewvc': 'https://code.google.com/p/skia/source/detail?r=',
+        'deps_var': 'None'
+    },
+    'skia/gyp': {
+        'src': 'src/third_party/skia/gyp',
+        'recurse': False,
+        'svn': 'http://skia.googlecode.com/svn/trunk/gyp',
+        'depends': None,
+        'from': ['chromium'],
+        'viewvc': 'https://code.google.com/p/skia/source/detail?r=',
+        'deps_var': 'None'
+    }
+}
+
+DEPOT_NAMES = DEPOT_DEPS_NAME.keys()
+
+# The possible values of the --bisect_mode flag, which determines what to
+# use when classifying a revision as "good" or "bad".
+BISECT_MODE_MEAN = 'mean'
+BISECT_MODE_STD_DEV = 'std_dev'
+BISECT_MODE_RETURN_CODE = 'return_code'
+
+
+def AddAdditionalDepotInfo(depot_info):
+  """Adds additional depot info to the global depot variables."""
+  global DEPOT_DEPS_NAME
+  global DEPOT_NAMES
+  DEPOT_DEPS_NAME = dict(DEPOT_DEPS_NAME.items() + depot_info.items())
+  DEPOT_NAMES = DEPOT_DEPS_NAME.keys()
+
 
 def OutputAnnotationStepStart(name):
   """Outputs annotation to signal the start of a step to a try bot.
diff --git a/tools/checklicenses/checklicenses.py b/tools/checklicenses/checklicenses.py
index 1e34b08f..1fc824b 100755
--- a/tools/checklicenses/checklicenses.py
+++ b/tools/checklicenses/checklicenses.py
@@ -398,6 +398,11 @@
     'tools/symsrc/pefile.py': [
         'UNKNOWN',
     ],
+    # Not shipped, downloaded on trybots sometimes.
+    'tools/telemetry/third_party/gsutil': [
+        'BSD MIT/X11 (BSD like)',
+        'UNKNOWN',
+    ],
     'tools/telemetry/third_party/pyserial': [
         # https://sourceforge.net/p/pyserial/feature-requests/35/
         'UNKNOWN',
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp
index 3ff133db..a608cd2 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.cpp
+++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -66,6 +66,10 @@
   return type;
 }
 
+bool IsGtestTestFixture(const CXXRecordDecl* decl) {
+  return decl->getQualifiedNameAsString() == "testing::Test";
+}
+
 FixItHint FixItRemovalForVirtual(const SourceManager& manager,
                                  const CXXMethodDecl* method) {
   // Unfortunately, there doesn't seem to be a good way to determine the
@@ -294,7 +298,12 @@
        ++i) {
     const CXXMethodDecl* overridden = *i;
     if (IsMethodInBannedOrTestingNamespace(overridden) ||
-        InTestingNamespace(overridden)) {
+        // Provide an exception for ::testing::Test. gtest itself uses some
+        // magic to try to make sure SetUp()/TearDown() aren't capitalized
+        // incorrectly, but having the plugin enforce override is also nice.
+        (InTestingNamespace(overridden) &&
+         (!options_.strict_virtual_specifiers ||
+          !IsGtestTestFixture(overridden->getParent())))) {
       return true;
     }
   }
diff --git a/tools/clang/plugins/tests/virtual_specifiers.cpp b/tools/clang/plugins/tests/virtual_specifiers.cpp
index f4479a8..4d9acd3 100644
--- a/tools/clang/plugins/tests/virtual_specifiers.cpp
+++ b/tools/clang/plugins/tests/virtual_specifiers.cpp
@@ -61,3 +61,33 @@
   ~OverrideAndFinal() OVERRIDE FINAL {}
   void F() OVERRIDE FINAL {}
 };
+
+// Finally, some simple sanity tests that overrides in the testing namespace
+// don't trigger warnings, except for testing::Test.
+namespace testing {
+
+class Test {
+ public:
+  virtual ~Test();
+  virtual void SetUp();
+};
+
+class NotTest {
+ public:
+  virtual ~NotTest();
+  virtual void SetUp();
+};
+
+}  // namespace
+
+class MyTest : public testing::Test {
+ public:
+  virtual ~MyTest();
+  virtual void SetUp() override;
+};
+
+class MyNotTest : public testing::NotTest {
+ public:
+  virtual ~MyNotTest();
+  virtual void SetUp() override;
+};
diff --git a/tools/clang/plugins/tests/virtual_specifiers.txt b/tools/clang/plugins/tests/virtual_specifiers.txt
index 2ad1420..1f2e4755a 100644
--- a/tools/clang/plugins/tests/virtual_specifiers.txt
+++ b/tools/clang/plugins/tests/virtual_specifiers.txt
@@ -48,4 +48,11 @@
 virtual_specifiers.cpp:10:18: note: expanded from macro 'OVERRIDE'
 #define OVERRIDE override
                  ^
-12 warnings generated.
+virtual_specifiers.cpp:85:20: warning: [chromium-style] Overriding method must be marked with 'override' or 'final'.
+  virtual ~MyTest();
+                   ^
+                    override
+virtual_specifiers.cpp:86:3: warning: [chromium-style] 'virtual' is redundant; 'override' implies 'virtual'.
+  virtual void SetUp() override;
+  ^~~~~~~~
+14 warnings generated.
diff --git a/tools/cros/OWNERS b/tools/cros/OWNERS
new file mode 100644
index 0000000..4bb87663
--- /dev/null
+++ b/tools/cros/OWNERS
@@ -0,0 +1,10 @@
+# For more information about telemetry development, please see:
+# http://dev.chromium.org/developers/telemetry/telemetry-feature-guidelines
+
+# The set noparent is temporary until src/OWNERS isn't *.
+set noparent
+
+achuith@chromium.org
+tbarzic@chromium.org
+tengs@chromium.org
+zelidrag@chromium.org
diff --git a/tools/cros/bootstrap_deps b/tools/cros/bootstrap_deps
index 24f190f..f8e6310 100644
--- a/tools/cros/bootstrap_deps
+++ b/tools/cros/bootstrap_deps
@@ -18,4 +18,6 @@
         "https://src.chromium.org/chrome/trunk/src/content/test/gpu/bootstrap_deps",
     "src/tools/perf/bootstrap_deps":
         "https://src.chromium.org/chrome/trunk/src/tools/perf/bootstrap_deps",
+    "src/chrome/browser/policy/test/bootstrap_deps":
+        "https://src.chromium.org/chrome/trunk/src/chrome/browser/policy/test/bootstrap_deps",
 }
diff --git a/tools/find_depot_tools.py b/tools/find_depot_tools.py
index 469a283..1f918662 100644
--- a/tools/find_depot_tools.py
+++ b/tools/find_depot_tools.py
@@ -12,7 +12,7 @@
 
 
 def IsRealDepotTools(path):
-  return os.path.isfile(os.path.join(path, 'gclient'))
+  return os.path.isfile(os.path.join(path, 'gclient.py'))
 
 
 def add_depot_tools_to_path():
diff --git a/tools/gn/action_target_generator.h b/tools/gn/action_target_generator.h
index 9f3e224..3c8b5a8 100644
--- a/tools/gn/action_target_generator.h
+++ b/tools/gn/action_target_generator.h
@@ -5,7 +5,7 @@
 #ifndef TOOLS_GN_ACTION_TARGET_GENERATOR_H_
 #define TOOLS_GN_ACTION_TARGET_GENERATOR_H_
 
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "tools/gn/target_generator.h"
 
 // Populates a Target with the values from an action[_foreach] rule.
@@ -19,7 +19,7 @@
   virtual ~ActionTargetGenerator();
 
  protected:
-  virtual void DoRun() OVERRIDE;
+  void DoRun() override;
 
  private:
   bool FillScript();
diff --git a/tools/gn/binary_target_generator.h b/tools/gn/binary_target_generator.h
index f101dc2..0b8d521a 100644
--- a/tools/gn/binary_target_generator.h
+++ b/tools/gn/binary_target_generator.h
@@ -5,7 +5,7 @@
 #ifndef TOOLS_GN_BINARY_TARGET_GENERATOR_H_
 #define TOOLS_GN_BINARY_TARGET_GENERATOR_H_
 
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "tools/gn/target_generator.h"
 
 // Populates a Target with the values from a binary rule (executable, shared
@@ -20,7 +20,7 @@
   virtual ~BinaryTargetGenerator();
 
  protected:
-  virtual void DoRun() OVERRIDE;
+  void DoRun() override;
 
  private:
   bool FillCheckIncludes();
diff --git a/tools/gn/builder_unittest.cc b/tools/gn/builder_unittest.cc
index b9b7e5f..7a2f650 100644
--- a/tools/gn/builder_unittest.cc
+++ b/tools/gn/builder_unittest.cc
@@ -17,18 +17,14 @@
   }
 
   // Loader implementation:
-  virtual void Load(const SourceFile& file,
-                    const LocationRange& origin,
-                    const Label& toolchain_name) OVERRIDE {
+  void Load(const SourceFile& file,
+            const LocationRange& origin,
+            const Label& toolchain_name) override {
     files_.push_back(file);
   }
-  virtual void ToolchainLoaded(const Toolchain* toolchain) OVERRIDE {
-  }
-  virtual Label GetDefaultToolchain() const OVERRIDE {
-    return Label();
-  }
-  virtual const Settings* GetToolchainSettings(
-      const Label& label) const OVERRIDE {
+  void ToolchainLoaded(const Toolchain* toolchain) override {}
+  Label GetDefaultToolchain() const override { return Label(); }
+  const Settings* GetToolchainSettings(const Label& label) const override {
     return NULL;
   }
 
@@ -52,7 +48,7 @@
   }
 
  private:
-  virtual ~MockLoader() {}
+  ~MockLoader() override {}
 
   std::vector<SourceFile> files_;
 };
diff --git a/tools/gn/config.h b/tools/gn/config.h
index f08b859..543d660 100644
--- a/tools/gn/config.h
+++ b/tools/gn/config.h
@@ -5,7 +5,7 @@
 #ifndef TOOLS_GN_CONFIG_H_
 #define TOOLS_GN_CONFIG_H_
 
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "tools/gn/config_values.h"
 #include "tools/gn/item.h"
 
@@ -13,10 +13,10 @@
 class Config : public Item {
  public:
   Config(const Settings* settings, const Label& label);
-  virtual ~Config();
+  ~Config() override;
 
-  virtual Config* AsConfig() OVERRIDE;
-  virtual const Config* AsConfig() const OVERRIDE;
+  Config* AsConfig() override;
+  const Config* AsConfig() const override;
 
   ConfigValues& config_values() { return config_values_; }
   const ConfigValues& config_values() const { return config_values_; }
diff --git a/tools/gn/copy_target_generator.h b/tools/gn/copy_target_generator.h
index 2361bff..9d9b97ba 100644
--- a/tools/gn/copy_target_generator.h
+++ b/tools/gn/copy_target_generator.h
@@ -5,7 +5,7 @@
 #ifndef TOOLS_GN_COPY_TARGET_GENERATOR_H_
 #define TOOLS_GN_COPY_TARGET_GENERATOR_H_
 
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "tools/gn/target_generator.h"
 
 // Populates a Target with the values from a copy rule.
@@ -18,7 +18,7 @@
   virtual ~CopyTargetGenerator();
 
  protected:
-  virtual void DoRun() OVERRIDE;
+  void DoRun() override;
 
  private:
   void FillDestDir();
diff --git a/tools/gn/group_target_generator.h b/tools/gn/group_target_generator.h
index 47399496..141fdef 100644
--- a/tools/gn/group_target_generator.h
+++ b/tools/gn/group_target_generator.h
@@ -5,7 +5,7 @@
 #ifndef TOOLS_GN_GROUP_TARGET_GENERATOR_H_
 #define TOOLS_GN_GROUP_TARGET_GENERATOR_H_
 
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "tools/gn/target_generator.h"
 
 // Populates a Target with the values for a group rule.
@@ -18,7 +18,7 @@
   virtual ~GroupTargetGenerator();
 
  protected:
-  virtual void DoRun() OVERRIDE;
+  void DoRun() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(GroupTargetGenerator);
diff --git a/tools/gn/label_pattern.cc b/tools/gn/label_pattern.cc
index 752898f1..396a9b73 100644
--- a/tools/gn/label_pattern.cc
+++ b/tools/gn/label_pattern.cc
@@ -161,7 +161,7 @@
     // The non-wildcard stuff better not have a wildcard.
     if (path.find('*') != base::StringPiece::npos) {
       *err = Err(value, "Label patterns only support wildcard suffixes.",
-          "The pattern contained a '*' that wasn't at tne end.");
+          "The pattern contained a '*' that wasn't at the end.");
       return LabelPattern();
     }
 
diff --git a/tools/gn/loader.h b/tools/gn/loader.h
index 29204ae65..b5f0ad9 100644
--- a/tools/gn/loader.h
+++ b/tools/gn/loader.h
@@ -82,13 +82,12 @@
   LoaderImpl(const BuildSettings* build_settings);
 
   // Loader implementation.
-  virtual void Load(const SourceFile& file,
-                    const LocationRange& origin,
-                    const Label& toolchain_name) OVERRIDE;
-  virtual void ToolchainLoaded(const Toolchain* toolchain) OVERRIDE;
-  virtual Label GetDefaultToolchain() const OVERRIDE;
-  virtual const Settings* GetToolchainSettings(
-      const Label& label) const OVERRIDE;
+  void Load(const SourceFile& file,
+            const LocationRange& origin,
+            const Label& toolchain_name) override;
+  void ToolchainLoaded(const Toolchain* toolchain) override;
+  Label GetDefaultToolchain() const override;
+  const Settings* GetToolchainSettings(const Label& label) const override;
 
   // Sets the message loop corresponding to the main thread. By default this
   // class will use the thread active during construction, but there is not
@@ -115,7 +114,7 @@
   struct LoadID;
   struct ToolchainRecord;
 
-  virtual ~LoaderImpl();
+  ~LoaderImpl() override;
 
   // Schedules the input file manager to load the given file.
   void ScheduleLoadFile(const Settings* settings,
diff --git a/tools/gn/ninja_action_target_writer.h b/tools/gn/ninja_action_target_writer.h
index ac35b5b6..71c12397 100644
--- a/tools/gn/ninja_action_target_writer.h
+++ b/tools/gn/ninja_action_target_writer.h
@@ -7,8 +7,8 @@
 
 #include <vector>
 
-#include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
+#include "base/macros.h"
 #include "tools/gn/ninja_target_writer.h"
 
 class OutputFile;
@@ -17,9 +17,9 @@
 class NinjaActionTargetWriter : public NinjaTargetWriter {
  public:
   NinjaActionTargetWriter(const Target* target, std::ostream& out);
-  virtual ~NinjaActionTargetWriter();
+  ~NinjaActionTargetWriter() override;
 
-  virtual void Run() OVERRIDE;
+  void Run() override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(NinjaActionTargetWriter,
diff --git a/tools/gn/ninja_binary_target_writer.h b/tools/gn/ninja_binary_target_writer.h
index e3236ce..22d2332 100644
--- a/tools/gn/ninja_binary_target_writer.h
+++ b/tools/gn/ninja_binary_target_writer.h
@@ -5,7 +5,7 @@
 #ifndef TOOLS_GN_NINJA_BINARY_TARGET_WRITER_H_
 #define TOOLS_GN_NINJA_BINARY_TARGET_WRITER_H_
 
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "tools/gn/config_values.h"
 #include "tools/gn/ninja_target_writer.h"
 #include "tools/gn/toolchain.h"
@@ -18,9 +18,9 @@
 class NinjaBinaryTargetWriter : public NinjaTargetWriter {
  public:
   NinjaBinaryTargetWriter(const Target* target, std::ostream& out);
-  virtual ~NinjaBinaryTargetWriter();
+  ~NinjaBinaryTargetWriter() override;
 
-  virtual void Run() OVERRIDE;
+  void Run() override;
 
  private:
   typedef std::set<OutputFile> OutputFileSet;
diff --git a/tools/gn/ninja_copy_target_writer.h b/tools/gn/ninja_copy_target_writer.h
index 58003dc..9e1746e 100644
--- a/tools/gn/ninja_copy_target_writer.h
+++ b/tools/gn/ninja_copy_target_writer.h
@@ -5,7 +5,7 @@
 #ifndef TOOLS_GN_NINJA_COPY_TARGET_WRITER_H_
 #define TOOLS_GN_NINJA_COPY_TARGET_WRITER_H_
 
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "tools/gn/ninja_target_writer.h"
 
 class Tool;
@@ -14,9 +14,9 @@
 class NinjaCopyTargetWriter : public NinjaTargetWriter {
  public:
   NinjaCopyTargetWriter(const Target* target, std::ostream& out);
-  virtual ~NinjaCopyTargetWriter();
+  ~NinjaCopyTargetWriter() override;
 
-  virtual void Run() OVERRIDE;
+  void Run() override;
 
  private:
   // Writes the rules top copy the file(s), putting the computed output file
diff --git a/tools/gn/ninja_group_target_writer.h b/tools/gn/ninja_group_target_writer.h
index 31625f8..66e5f043 100644
--- a/tools/gn/ninja_group_target_writer.h
+++ b/tools/gn/ninja_group_target_writer.h
@@ -5,16 +5,16 @@
 #ifndef TOOLS_GN_NINJA_GROUP_TARGET_WRITER_H_
 #define TOOLS_GN_NINJA_GROUP_TARGET_WRITER_H_
 
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "tools/gn/ninja_target_writer.h"
 
 // Writes a .ninja file for a group target type.
 class NinjaGroupTargetWriter : public NinjaTargetWriter {
  public:
   NinjaGroupTargetWriter(const Target* target, std::ostream& out);
-  virtual ~NinjaGroupTargetWriter();
+  ~NinjaGroupTargetWriter() override;
 
-  virtual void Run() OVERRIDE;
+  void Run() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(NinjaGroupTargetWriter);
diff --git a/tools/gn/ninja_target_writer_unittest.cc b/tools/gn/ninja_target_writer_unittest.cc
index 31c58dc5..e46471a 100644
--- a/tools/gn/ninja_target_writer_unittest.cc
+++ b/tools/gn/ninja_target_writer_unittest.cc
@@ -19,7 +19,7 @@
       : NinjaTargetWriter(target, out) {
   }
 
-  virtual void Run() OVERRIDE {}
+  void Run() override {}
 
   // Make this public so the test can call it.
   OutputFile WriteInputDepsStampAndGetDep(
diff --git a/tools/gn/parse_tree.h b/tools/gn/parse_tree.h
index 0630058..60d15700 100644
--- a/tools/gn/parse_tree.h
+++ b/tools/gn/parse_tree.h
@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "base/basictypes.h"
-#include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "tools/gn/err.h"
 #include "tools/gn/token.h"
@@ -137,15 +136,15 @@
 class AccessorNode : public ParseNode {
  public:
   AccessorNode();
-  virtual ~AccessorNode();
+  ~AccessorNode() override;
 
-  virtual const AccessorNode* AsAccessor() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const AccessorNode* AsAccessor() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   // Base is the thing on the left of the [] or dot, currently always required
   // to be an identifier token.
@@ -180,15 +179,15 @@
 class BinaryOpNode : public ParseNode {
  public:
   BinaryOpNode();
-  virtual ~BinaryOpNode();
+  ~BinaryOpNode() override;
 
-  virtual const BinaryOpNode* AsBinaryOp() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const BinaryOpNode* AsBinaryOp() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   const Token& op() const { return op_; }
   void set_op(const Token& t) { op_ = t; }
@@ -217,15 +216,15 @@
  public:
   // Set has_scope if this block introduces a nested scope.
   explicit BlockNode(bool has_scope);
-  virtual ~BlockNode();
+  ~BlockNode() override;
 
-  virtual const BlockNode* AsBlock() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const BlockNode* AsBlock() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   void set_begin_token(const Token& t) { begin_token_ = t; }
   void set_end(scoped_ptr<EndNode> e) { end_ = e.Pass(); }
@@ -258,15 +257,15 @@
 class ConditionNode : public ParseNode {
  public:
   ConditionNode();
-  virtual ~ConditionNode();
+  ~ConditionNode() override;
 
-  virtual const ConditionNode* AsConditionNode() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const ConditionNode* AsConditionNode() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   void set_if_token(const Token& token) { if_token_ = token; }
 
@@ -303,15 +302,15 @@
 class FunctionCallNode : public ParseNode {
  public:
   FunctionCallNode();
-  virtual ~FunctionCallNode();
+  ~FunctionCallNode() override;
 
-  virtual const FunctionCallNode* AsFunctionCall() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const FunctionCallNode* AsFunctionCall() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   const Token& function() const { return function_; }
   void set_function(Token t) { function_ = t; }
@@ -336,15 +335,15 @@
  public:
   IdentifierNode();
   IdentifierNode(const Token& token);
-  virtual ~IdentifierNode();
+  ~IdentifierNode() override;
 
-  virtual const IdentifierNode* AsIdentifier() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const IdentifierNode* AsIdentifier() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   const Token& value() const { return value_; }
   void set_value(const Token& t) { value_ = t; }
@@ -360,15 +359,15 @@
 class ListNode : public ParseNode {
  public:
   ListNode();
-  virtual ~ListNode();
+  ~ListNode() override;
 
-  virtual const ListNode* AsList() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const ListNode* AsList() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   void set_begin_token(const Token& t) { begin_token_ = t; }
   void set_end(scoped_ptr<EndNode> e) { end_ = e.Pass(); }
@@ -397,15 +396,15 @@
  public:
   LiteralNode();
   LiteralNode(const Token& token);
-  virtual ~LiteralNode();
+  ~LiteralNode() override;
 
-  virtual const LiteralNode* AsLiteral() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const LiteralNode* AsLiteral() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   const Token& value() const { return value_; }
   void set_value(const Token& t) { value_ = t; }
@@ -421,15 +420,15 @@
 class UnaryOpNode : public ParseNode {
  public:
   UnaryOpNode();
-  virtual ~UnaryOpNode();
+  ~UnaryOpNode() override;
 
-  virtual const UnaryOpNode* AsUnaryOp() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const UnaryOpNode* AsUnaryOp() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   const Token& op() const { return op_; }
   void set_op(const Token& t) { op_ = t; }
@@ -456,15 +455,15 @@
 class BlockCommentNode : public ParseNode {
  public:
   BlockCommentNode();
-  virtual ~BlockCommentNode();
+  ~BlockCommentNode() override;
 
-  virtual const BlockCommentNode* AsBlockComment() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const BlockCommentNode* AsBlockComment() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   const Token& comment() const { return comment_; }
   void set_comment(const Token& t) { comment_ = t; }
@@ -484,15 +483,15 @@
 class EndNode : public ParseNode {
  public:
   EndNode(const Token& token);
-  virtual ~EndNode();
+  ~EndNode() override;
 
-  virtual const EndNode* AsEnd() const OVERRIDE;
-  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
-  virtual LocationRange GetRange() const OVERRIDE;
-  virtual Err MakeErrorDescribing(
+  const EndNode* AsEnd() const override;
+  Value Execute(Scope* scope, Err* err) const override;
+  LocationRange GetRange() const override;
+  Err MakeErrorDescribing(
       const std::string& msg,
-      const std::string& help = std::string()) const OVERRIDE;
-  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
+      const std::string& help = std::string()) const override;
+  void Print(std::ostream& out, int indent) const override;
 
   const Token& value() const { return value_; }
   void set_value(const Token& t) { value_ = t; }
diff --git a/tools/gn/scope_per_file_provider.h b/tools/gn/scope_per_file_provider.h
index 2ef84cc..8f9c5539 100644
--- a/tools/gn/scope_per_file_provider.h
+++ b/tools/gn/scope_per_file_provider.h
@@ -21,8 +21,7 @@
   virtual ~ScopePerFileProvider();
 
   // ProgrammaticProvider implementation.
-  virtual const Value* GetProgrammaticValue(
-      const base::StringPiece& ident) OVERRIDE;
+  const Value* GetProgrammaticValue(const base::StringPiece& ident) override;
 
  private:
   const Value* GetCurrentToolchain();
diff --git a/tools/gn/setup.h b/tools/gn/setup.h
index 558c54d..3658892 100644
--- a/tools/gn/setup.h
+++ b/tools/gn/setup.h
@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "base/basictypes.h"
-#include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/memory/scoped_ptr.h"
 #include "tools/gn/build_settings.h"
@@ -90,7 +89,7 @@
 class Setup : public CommonSetup {
  public:
   Setup();
-  virtual ~Setup();
+  ~Setup() override;
 
   // Configures the build for the current command line. On success returns
   // true. On failure, prints the error and returns false.
@@ -114,7 +113,7 @@
 
   Scheduler& scheduler() { return scheduler_; }
 
-  virtual Scheduler* GetScheduler() OVERRIDE;
+  Scheduler* GetScheduler() override;
 
   // Returns the file used to store the build arguments. Note that the path
   // might not exist.
@@ -202,14 +201,14 @@
   // default copy constructor.
   DependentSetup(Setup* derive_from);
   DependentSetup(DependentSetup* derive_from);
-  virtual ~DependentSetup();
+  ~DependentSetup() override;
 
   // These are the two parts of Run() in the regular setup, not including the
   // call to actually run the message loop.
   void RunPreMessageLoop();
   bool RunPostMessageLoop();
 
-  virtual Scheduler* GetScheduler() OVERRIDE;
+  Scheduler* GetScheduler() override;
 
  private:
   Scheduler* scheduler_;
diff --git a/tools/gn/target.h b/tools/gn/target.h
index 5b19aad6..8e5a3e2 100644
--- a/tools/gn/target.h
+++ b/tools/gn/target.h
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/basictypes.h"
-#include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/strings/string_piece.h"
 #include "base/synchronization/lock.h"
@@ -52,15 +51,15 @@
   typedef std::vector<std::string> StringVector;
 
   Target(const Settings* settings, const Label& label);
-  virtual ~Target();
+  ~Target() override;
 
   // Returns a string naming the output type.
   static const char* GetStringForOutputType(OutputType type);
 
   // Item overrides.
-  virtual Target* AsTarget() OVERRIDE;
-  virtual const Target* AsTarget() const OVERRIDE;
-  virtual bool OnResolved(Err* err) OVERRIDE;
+  Target* AsTarget() override;
+  const Target* AsTarget() const override;
+  bool OnResolved(Err* err) override;
 
   OutputType output_type() const { return output_type_; }
   void set_output_type(OutputType t) { output_type_ = t; }
diff --git a/tools/gn/toolchain.h b/tools/gn/toolchain.h
index 393596cb..c94d8ed 100644
--- a/tools/gn/toolchain.h
+++ b/tools/gn/toolchain.h
@@ -5,7 +5,6 @@
 #ifndef TOOLS_GN_TOOLCHAIN_H_
 #define TOOLS_GN_TOOLCHAIN_H_
 
-#include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_piece.h"
@@ -61,11 +60,11 @@
   static const char* kToolCopy;
 
   Toolchain(const Settings* settings, const Label& label);
-  virtual ~Toolchain();
+  ~Toolchain() override;
 
   // Item overrides.
-  virtual Toolchain* AsToolchain() OVERRIDE;
-  virtual const Toolchain* AsToolchain() const OVERRIDE;
+  Toolchain* AsToolchain() override;
+  const Toolchain* AsToolchain() const override;
 
   // Returns TYPE_NONE on failure.
   static ToolType ToolNameToType(const base::StringPiece& str);
diff --git a/tools/ipc_fuzzer/mutate/generate.cc b/tools/ipc_fuzzer/mutate/generate.cc
index acc169f6..8d11280 100644
--- a/tools/ipc_fuzzer/mutate/generate.cc
+++ b/tools/ipc_fuzzer/mutate/generate.cc
@@ -104,65 +104,65 @@
   GeneratorImpl() {}
   virtual ~GeneratorImpl() {}
 
-  virtual void GenerateBool(bool* value) OVERRIDE {
+  virtual void GenerateBool(bool* value) override {
     *value = RandInRange(2);
   }
 
-  virtual void GenerateInt(int* value) OVERRIDE {
+  virtual void GenerateInt(int* value) override {
     GenerateIntegralType<int>(value);
   }
 
-  virtual void GenerateLong(long* value) OVERRIDE {
+  virtual void GenerateLong(long* value) override {
     GenerateIntegralType<long>(value);
   }
 
-  virtual void GenerateSize(size_t* value) OVERRIDE {
+  virtual void GenerateSize(size_t* value) override {
     GenerateIntegralType<size_t>(value);
   }
 
-  virtual void GenerateUChar(unsigned char* value) OVERRIDE {
+  virtual void GenerateUChar(unsigned char* value) override {
     GenerateIntegralType<unsigned char>(value);
   }
 
-  virtual void GenerateUInt16(uint16* value) OVERRIDE {
+  virtual void GenerateUInt16(uint16* value) override {
     GenerateIntegralType<uint16>(value);
   }
 
-  virtual void GenerateUInt32(uint32* value) OVERRIDE {
+  virtual void GenerateUInt32(uint32* value) override {
     GenerateIntegralType<uint32>(value);
   }
 
-  virtual void GenerateInt64(int64* value) OVERRIDE {
+  virtual void GenerateInt64(int64* value) override {
     GenerateIntegralType<int64>(value);
   }
 
-  virtual void GenerateUInt64(uint64* value) OVERRIDE {
+  virtual void GenerateUInt64(uint64* value) override {
     GenerateIntegralType<uint64>(value);
   }
 
-  virtual void GenerateFloat(float* value) OVERRIDE {
+  virtual void GenerateFloat(float* value) override {
     GenerateFloatingType<float>(value);
   }
 
-  virtual void GenerateDouble(double* value) OVERRIDE {
+  virtual void GenerateDouble(double* value) override {
     GenerateFloatingType<double>(value);
   }
 
-  virtual void GenerateString(std::string* value) OVERRIDE {
+  virtual void GenerateString(std::string* value) override {
     GenerateStringType<std::string>(value);
   }
 
-  virtual void GenerateString16(base::string16* value) OVERRIDE {
+  virtual void GenerateString16(base::string16* value) override {
     GenerateStringType<base::string16>(value);
   }
 
-  virtual void GenerateData(char* data, int length) OVERRIDE {
+  virtual void GenerateData(char* data, int length) override {
     for (int i = 0; i < length; ++i) {
       GenerateIntegralType<char>(&data[i]);
     }
   }
 
-  virtual void GenerateBytes(void* data, int data_len) OVERRIDE {
+  virtual void GenerateBytes(void* data, int data_len) override {
     GenerateData(static_cast<char*>(data), data_len);
   }
 };
diff --git a/tools/ipc_fuzzer/mutate/mutate.cc b/tools/ipc_fuzzer/mutate/mutate.cc
index 512944f..3a42f4e 100644
--- a/tools/ipc_fuzzer/mutate/mutate.cc
+++ b/tools/ipc_fuzzer/mutate/mutate.cc
@@ -94,64 +94,64 @@
 
   virtual ~DefaultFuzzer() {}
 
-  virtual void FuzzBool(bool* value) OVERRIDE {
+  virtual void FuzzBool(bool* value) override {
     if (RandEvent(frequency_))
       (*value) = !(*value);
   }
 
-  virtual void FuzzInt(int* value) OVERRIDE {
+  virtual void FuzzInt(int* value) override {
     FuzzIntegralType<int>(value, frequency_);
   }
 
-  virtual void FuzzLong(long* value) OVERRIDE {
+  virtual void FuzzLong(long* value) override {
     FuzzIntegralType<long>(value, frequency_);
   }
 
-  virtual void FuzzSize(size_t* value) OVERRIDE {
+  virtual void FuzzSize(size_t* value) override {
     FuzzIntegralType<size_t>(value, frequency_);
   }
 
-  virtual void FuzzUChar(unsigned char* value) OVERRIDE {
+  virtual void FuzzUChar(unsigned char* value) override {
     FuzzIntegralType<unsigned char>(value, frequency_);
   }
 
-  virtual void FuzzUInt16(uint16* value) OVERRIDE {
+  virtual void FuzzUInt16(uint16* value) override {
     FuzzIntegralType<uint16>(value, frequency_);
   }
 
-  virtual void FuzzUInt32(uint32* value) OVERRIDE {
+  virtual void FuzzUInt32(uint32* value) override {
     FuzzIntegralType<uint32>(value, frequency_);
   }
 
-  virtual void FuzzInt64(int64* value) OVERRIDE {
+  virtual void FuzzInt64(int64* value) override {
     FuzzIntegralType<int64>(value, frequency_);
   }
 
-  virtual void FuzzUInt64(uint64* value) OVERRIDE {
+  virtual void FuzzUInt64(uint64* value) override {
     FuzzIntegralType<uint64>(value, frequency_);
   }
 
-  virtual void FuzzFloat(float* value) OVERRIDE {
+  virtual void FuzzFloat(float* value) override {
     if (RandEvent(frequency_))
       *value = RandDouble();
   }
 
-  virtual void FuzzDouble(double* value) OVERRIDE {
+  virtual void FuzzDouble(double* value) override {
     if (RandEvent(frequency_))
       *value = RandDouble();
   }
 
-  virtual void FuzzString(std::string* value) OVERRIDE {
+  virtual void FuzzString(std::string* value) override {
     FuzzStringType<std::string>(value, frequency_, "BORKED", std::string());
   }
 
-  virtual void FuzzString16(base::string16* value) OVERRIDE {
+  virtual void FuzzString16(base::string16* value) override {
     FuzzStringType<base::string16>(value, frequency_,
                                    base::WideToUTF16(L"BORKED"),
                                    base::WideToUTF16(L""));
   }
 
-  virtual void FuzzData(char* data, int length) OVERRIDE {
+  virtual void FuzzData(char* data, int length) override {
     if (RandEvent(frequency_)) {
       for (int i = 0; i < length; ++i) {
         FuzzIntegralType<char>(&data[i], frequency_);
@@ -159,7 +159,7 @@
     }
   }
 
-  virtual void FuzzBytes(void* data, int data_len) OVERRIDE {
+  virtual void FuzzBytes(void* data, int data_len) override {
     FuzzData(static_cast<char*>(data), data_len);
   }
 
@@ -175,21 +175,21 @@
   NoOpFuzzer() {}
   virtual ~NoOpFuzzer() {}
 
-  virtual void FuzzBool(bool* value) OVERRIDE {}
-  virtual void FuzzInt(int* value) OVERRIDE {}
-  virtual void FuzzLong(long* value) OVERRIDE {}
-  virtual void FuzzSize(size_t* value) OVERRIDE {}
-  virtual void FuzzUChar(unsigned char* value) OVERRIDE {}
-  virtual void FuzzUInt16(uint16* value) OVERRIDE {}
-  virtual void FuzzUInt32(uint32* value) OVERRIDE {}
-  virtual void FuzzInt64(int64* value) OVERRIDE {}
-  virtual void FuzzUInt64(uint64* value) OVERRIDE {}
-  virtual void FuzzFloat(float* value) OVERRIDE {}
-  virtual void FuzzDouble(double* value) OVERRIDE {}
-  virtual void FuzzString(std::string* value) OVERRIDE {}
-  virtual void FuzzString16(base::string16* value) OVERRIDE {}
-  virtual void FuzzData(char* data, int length) OVERRIDE {}
-  virtual void FuzzBytes(void* data, int data_len) OVERRIDE {}
+  virtual void FuzzBool(bool* value) override {}
+  virtual void FuzzInt(int* value) override {}
+  virtual void FuzzLong(long* value) override {}
+  virtual void FuzzSize(size_t* value) override {}
+  virtual void FuzzUChar(unsigned char* value) override {}
+  virtual void FuzzUInt16(uint16* value) override {}
+  virtual void FuzzUInt32(uint32* value) override {}
+  virtual void FuzzInt64(int64* value) override {}
+  virtual void FuzzUInt64(uint64* value) override {}
+  virtual void FuzzFloat(float* value) override {}
+  virtual void FuzzDouble(double* value) override {}
+  virtual void FuzzString(std::string* value) override {}
+  virtual void FuzzString16(base::string16* value) override {}
+  virtual void FuzzData(char* data, int length) override {}
+  virtual void FuzzBytes(void* data, int data_len) override {}
 };
 
 class FuzzerFactory {
diff --git a/tools/ipc_fuzzer/replay/replay_process.h b/tools/ipc_fuzzer/replay/replay_process.h
index 8a396a8..6af6c3b 100644
--- a/tools/ipc_fuzzer/replay/replay_process.h
+++ b/tools/ipc_fuzzer/replay/replay_process.h
@@ -37,8 +37,8 @@
   void Run();
 
   // IPC::Listener implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-  virtual void OnChannelError() OVERRIDE;
+  virtual bool OnMessageReceived(const IPC::Message& message) override;
+  virtual void OnChannelError() override;
 
  private:
   void SendNextMessage();
diff --git a/tools/memory/asan/blacklist.txt b/tools/memory/asan/blacklist.txt
new file mode 100644
index 0000000..99a1472
--- /dev/null
+++ b/tools/memory/asan/blacklist.txt
@@ -0,0 +1,5 @@
+# The rules in this file are only applied at compile time.
+# Because the Chrome buildsystem does not automatically touch the files
+# mentioned here, changing this file requires clobbering all ASan bots.
+#
+# Please think twice before you add or remove these rules.
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 4f104a7..c70a46d 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -3130,6 +3130,13 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Hotword.HotwordTrigger">
+  <owner>amistry@chromium.org</owner>
+  <owner>rlp@chromium.org</owner>
+  <owner>somast@chromium.org</owner>
+  <description>User triggered the hotword by saying 'Ok Google'.</description>
+</action>
+
 <action name="ImportLockDialogCocoa_Shown">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
diff --git a/tools/metrics/actions/extract_actions.py b/tools/metrics/actions/extract_actions.py
index d30c8a89..9bcfb2c9 100755
--- a/tools/metrics/actions/extract_actions.py
+++ b/tools/metrics/actions/extract_actions.py
@@ -407,6 +407,9 @@
   actions.add('ConnectivityDiagnostics.UA.TestResultExpanded')
   actions.add('ConnectivityDiagnostics.UA.TestSuiteRun')
 
+  # Actions sent by 'Ok Google' Hotwording.
+  actions.add('Hotword.HotwordTrigger')
+
 def GrepForActions(path, actions):
   """Grep a source file for calls to UserMetrics functions.
 
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index a5e39a9..57b34a8e 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -6134,6 +6134,17 @@
   </summary>
 </histogram>
 
+<histogram name="EasyUnlock.SignIn.LoginEvent" enum="EasyUnlockLoginEvent">
+  <owner>xiaowenx@google.com</owner>
+  <owner>xiyuan@google.com</owner>
+  <summary>
+    Measures the use of Easy sign-in: records whether an Easy sign-in login
+    succeeded or  failed; or if a password fallback was used, the reason why.
+    Recorded upon a login attempt for users who have the Easy sign-in feature
+    enabled.
+  </summary>
+</histogram>
+
 <histogram name="EasyUnlock.StartupTimeFromSuspend" units="milliseconds">
   <owner>joshwoodward@google.com</owner>
   <owner>tengs@chromium.org</owner>
@@ -9635,6 +9646,8 @@
   <owner>kmadhusu@chromium.org</owner>
   <summary>
     Counts number of Google searches from various access points in the browser.
+    WARNING: Do not use this histogram as it currently fails to classify a large
+    percentage of Omnibox searches correctly - http://crbug.com/421631.
   </summary>
 </histogram>
 
@@ -10026,6 +10039,39 @@
   </summary>
 </histogram>
 
+<histogram name="Hotword.HotwordMediaStreamResult"
+    enum="HotwordMediaStreamResult">
+  <owner>amistry@chromium.org</owner>
+  <owner>rlp@chromium.org</owner>
+  <owner>somast@chromium.org</owner>
+  <summary>
+    Success or error when attempting to open a MediaStream for the microphone.
+    At most one success or error will be logged for an attempt to open a stream.
+  </summary>
+</histogram>
+
+<histogram name="Hotword.HotwordNaClMessageTimeout"
+    enum="HotwordNaClMessageTimeout">
+  <owner>amistry@chromium.org</owner>
+  <owner>rlp@chromium.org</owner>
+  <owner>somast@chromium.org</owner>
+  <summary>
+    Timeout occured while waiting for a message from the NaCl hotword detector
+    plugin. This value is the message that was expected to be received from the
+    plugin.
+  </summary>
+</histogram>
+
+<histogram name="Hotword.HotwordNaClPluginLoadResult"
+    enum="HotwordNaClPluginLoadResult">
+  <owner>amistry@chromium.org</owner>
+  <owner>rlp@chromium.org</owner>
+  <owner>somast@chromium.org</owner>
+  <summary>
+    Success or error when attempting to load the NaCl hotword detector plugin.
+  </summary>
+</histogram>
+
 <histogram name="HttpCache.AsyncValidationDuration" units="milliseconds">
   <owner>ricea@chromium.org</owner>
   <summary>
@@ -14042,6 +14088,16 @@
   <summary>The scheme of the URL for each main-frame navigation.</summary>
 </histogram>
 
+<histogram name="Navigation.OnBeforeUnloadOverheadTime" units="milliseconds">
+  <owner>carlosk@chromium.org</owner>
+  <summary>
+    Overhead time spent handling the OnBeforeUnload event from the browser
+    standpoint. More precisely, it is the total time between dispatch and
+    acknowledgment of the BeforeUnload event on the browser side, minus the
+    actual time spent executing the BeforeUnload handlers on the renderer side.
+  </summary>
+</histogram>
+
 <histogram name="Navigation.RedirectChainSize" units="characters">
   <owner>haitaol@chromium.org</owner>
   <owner>donnd@chromium.org</owner>
@@ -14724,6 +14780,9 @@
 
 <histogram name="Net.AlternateProtocolUsage.1000Truncated"
     enum="AlternateProtocolUsage">
+  <obsolete>
+    Deprecated 10/2014.
+  </obsolete>
   <owner>rch@chromium.org</owner>
   <summary>
     Breakdown of how requests which could potentially make use of an alternate
@@ -14734,6 +14793,9 @@
 
 <histogram name="Net.AlternateProtocolUsage.200Truncated"
     enum="AlternateProtocolUsage">
+  <obsolete>
+    Deprecated 10/2014.
+  </obsolete>
   <owner>rch@chromium.org</owner>
   <summary>
     Breakdown of how requests which could potentially make use of an alternate
@@ -17204,11 +17266,27 @@
   </summary>
 </histogram>
 
+<histogram name="Net.QuicServerInfo.DiskCacheLoadTime" units="milliseconds">
+  <owner>rtenneti@chromium.org</owner>
+  <summary>Time spent to load QUIC server information from disk cache.</summary>
+</histogram>
+
 <histogram name="Net.QuicServerInfo.DiskCacheReadTime" units="milliseconds">
+  <obsolete>
+    Deprecated as of 10/2014. Replaced by DiskCacheWaitForDataReadyTime.
+  </obsolete>
   <owner>rch@chromium.org</owner>
   <summary>Time spent to load QUIC server information from disk cache.</summary>
 </histogram>
 
+<histogram name="Net.QuicServerInfo.DiskCacheWaitForDataReadyTime"
+    units="milliseconds">
+  <owner>rtenneti@chromium.org</owner>
+  <summary>
+    Time spent waiting to load QUIC server information from disk cache.
+  </summary>
+</histogram>
+
 <histogram name="Net.QuicSession.21CumulativePacketsReceived"
     units="Received in Ranges">
   <owner>rch@chromium.org</owner>
@@ -17240,6 +17318,22 @@
   </summary>
 </histogram>
 
+<histogram name="Net.QuicSession.BlockedFrames.Received">
+  <owner>rtenneti@chromium.org</owner>
+  <summary>
+    The number of BLOCKED frames recevied by a QuicSession when the session is
+    closed.
+  </summary>
+</histogram>
+
+<histogram name="Net.QuicSession.BlockedFrames.Sent">
+  <owner>rtenneti@chromium.org</owner>
+  <summary>
+    The number of BLOCKED frames sent by a QuicSession when the session is
+    closed.
+  </summary>
+</histogram>
+
 <histogram name="Net.QuicSession.ClosedDuringInitializeSession">
   <owner>rch@chromium.org</owner>
   <summary>
@@ -17923,6 +18017,14 @@
 </histogram>
 
 <histogram name="Net.SpdyConnectionLatency" units="milliseconds">
+  <obsolete>
+    Replaced by Net.SpdyConnectionLatency_2 on 2014-10-21.
+  </obsolete>
+  <owner>rch@chromium.org</owner>
+  <summary>Time from when the Connect() starts until it completes.</summary>
+</histogram>
+
+<histogram name="Net.SpdyConnectionLatency_2" units="milliseconds">
   <owner>rch@chromium.org</owner>
   <summary>Time from when the Connect() starts until it completes.</summary>
 </histogram>
@@ -18234,6 +18336,14 @@
 </histogram>
 
 <histogram name="Net.SSL_Connection_Latency" units="milliseconds">
+  <obsolete>
+    Replaced by Net.SSL_Connection_Latency_2 on 2014-10-21.
+  </obsolete>
+  <owner>agl@chromium.org</owner>
+  <summary>Time from when the Connect() starts until it completes.</summary>
+</histogram>
+
+<histogram name="Net.SSL_Connection_Latency_2" units="milliseconds">
   <owner>agl@chromium.org</owner>
   <summary>Time from when the Connect() starts until it completes.</summary>
 </histogram>
@@ -18252,6 +18362,17 @@
 </histogram>
 
 <histogram name="Net.SSL_Connection_Latency_Google" units="milliseconds">
+  <obsolete>
+    Replaced by Net.SSL_Connection_Latency_Google2 on 2014-10-21.
+  </obsolete>
+  <owner>agl@chromium.org</owner>
+  <summary>
+    Time from when the Connect() starts until it completes for google.com and
+    any subdomain of it.
+  </summary>
+</histogram>
+
+<histogram name="Net.SSL_Connection_Latency_Google2" units="milliseconds">
   <owner>agl@chromium.org</owner>
   <summary>
     Time from when the Connect() starts until it completes for google.com and
@@ -20772,6 +20893,30 @@
   </summary>
 </histogram>
 
+<histogram name="Networks.RememberedShared">
+  <owner>stevenjb@chromium.org</owner>
+  <summary>
+    Number of shared remembered (preferred) networks on Chrome OS. Updated any
+    time the network list changes.
+  </summary>
+</histogram>
+
+<histogram name="Networks.RememberedUnshared">
+  <owner>stevenjb@chromium.org</owner>
+  <summary>
+    Number of private remembered (preferred) networks on Chrome OS. Updated any
+    time the network list changes.
+  </summary>
+</histogram>
+
+<histogram name="Networks.Visible">
+  <owner>stevenjb@chromium.org</owner>
+  <summary>
+    Number of visible (in-range) networks on Chrome OS. Updated any time the
+    network list changes.
+  </summary>
+</histogram>
+
 <histogram name="NewTabPage.ActionAndroid" enum="NewTabPageActionAndroid">
   <owner>newt@chromium.org</owner>
   <summary>
@@ -21625,6 +21770,55 @@
   <summary>Time from boot to sign-in completed.</summary>
 </histogram>
 
+<histogram name="OOBE.ErrorScreensTime.Enrollment" units="milliseconds">
+  <owner>rsorokin@chromium.org</owner>
+  <summary>
+    Time spent on error screens during enrollment or autoenrollment.
+  </summary>
+</histogram>
+
+<histogram name="OOBE.ErrorScreensTime.Signin" units="milliseconds">
+  <owner>rsorokin@chromium.org</owner>
+  <summary>Time spent on error screens during signin.</summary>
+</histogram>
+
+<histogram name="OOBE.ErrorScreensTime.Supervised" units="milliseconds">
+  <owner>rsorokin@chromium.org</owner>
+  <summary>
+    Time spent on error screens during supervised user creation.
+  </summary>
+</histogram>
+
+<histogram name="OOBE.ErrorScreensTime.Update" units="milliseconds">
+  <owner>rsorokin@chromium.org</owner>
+  <summary>Time spent on error screens during update.</summary>
+</histogram>
+
+<histogram name="OOBE.NetworkErrorShown.Enrollment" enum="NetworkErrorType">
+  <owner>rsorokin@google.com</owner>
+  <summary>
+    Number of times error screen has appeared during enrollment or
+    autoenrollment.
+  </summary>
+</histogram>
+
+<histogram name="OOBE.NetworkErrorShown.Signin" enum="NetworkErrorType">
+  <owner>rsorokin@google.com</owner>
+  <summary>Number of times error screen has appeared during signin.</summary>
+</histogram>
+
+<histogram name="OOBE.NetworkErrorShown.Supervised" enum="NetworkErrorType">
+  <owner>rsorokin@google.com</owner>
+  <summary>
+    Number of times error screen has appeared during supervised user creation.
+  </summary>
+</histogram>
+
+<histogram name="OOBE.NetworkErrorShown.Update" enum="NetworkErrorType">
+  <owner>rsorokin@google.com</owner>
+  <summary>Number of times error screen has appeared during update.</summary>
+</histogram>
+
 <histogram name="OOBE.StepCompletionTime" units="milliseconds">
   <owner>merkulova@chromium.org</owner>
   <summary>Time spent on specific OOBE screen.</summary>
@@ -26723,6 +26917,16 @@
   </summary>
 </histogram>
 
+<histogram name="PushMessaging.RegistrationStatus"
+    enum="PushRegistrationStatus">
+  <owner>johnme@google.com</owner>
+  <owner>mvanouwerkerk@google.com</owner>
+  <summary>
+    When a webpage registers for push messaging, this records whether the
+    request is successful, or otherwise the type of error encountered.
+  </summary>
+</histogram>
+
 <histogram name="Quickoffice.csvFormattedCellCount">
   <owner>dskelton@google.com</owner>
   <summary>
@@ -33933,6 +34137,9 @@
 
 <histogram name="StartupTimeBomb.Alarm" units="milliseconds">
   <owner>rtenneti@chromium.org</owner>
+  <obsolete>
+    Deprecated as of 10/2014.
+  </obsolete>
   <summary>
     Time duration measured from the time the startup timebomb was started and
     when it went off.
@@ -41203,6 +41410,24 @@
   <int value="5" label="Disable"/>
 </enum>
 
+<enum name="EasyUnlockLoginEvent" type="int">
+  <int value="0" label="Easy sign-in success"/>
+  <int value="1" label="Easy sign-in failure"/>
+  <int value="2" label="Password sign-in: No pairing"/>
+  <int value="3" label="Password sign-in: Pairing changed"/>
+  <int value="4" label="Password sign-in: User hardlock"/>
+  <int value="5" label="Password sign-in: Service not active"/>
+  <int value="6" label="Password sign-in: No Bluetooth"/>
+  <int value="7" label="Password sign-in: Bluetooth connecting"/>
+  <int value="8" label="Password sign-in: No phone"/>
+  <int value="9" label="Password sign-in: Phone not authenticated"/>
+  <int value="10" label="Password sign-in: Phone locked"/>
+  <int value="11" label="Password sign-in: Phone not lockable"/>
+  <int value="12" label="Password sign-in: Phone not nearby"/>
+  <int value="13" label="Password sign-in: Phone not supported"/>
+  <int value="14" label="Password sign-in: Phone authenticated"/>
+</enum>
+
 <enum name="EasyUnlockNotificationEvent" type="int">
   <int value="0" label="Set up notification shown"/>
   <int value="1" label="Set up notification clicked"/>
@@ -43035,6 +43260,7 @@
   <int value="905" label="BOOKMARKMANAGERPRIVATE_SETVERSION"/>
   <int value="906" label="FILESYSTEMPROVIDER_NOTIFY"/>
   <int value="907" label="USB_GETUSERSELECTEDDEVICES"/>
+  <int value="908" label="INPUTMETHODPRIVATE_GETINPUTMETHODCONFIG"/>
 </enum>
 
 <enum name="ExtensionInstallCause" type="int">
@@ -43911,6 +44137,9 @@
   <int value="568" label="SVGPathSegDOM"/>
   <int value="569" label="SVGTransformListConsolidate"/>
   <int value="570" label="SVGAnimatedTransformListBaseVal"/>
+  <int value="571" label="QuotedAnimationName"/>
+  <int value="572" label="QuotedKeyframesRule"/>
+  <int value="573" label="SrcsetDroppedCandidate"/>
 </enum>
 
 <enum name="FFmpegCodecs" type="int">
@@ -44835,6 +45064,38 @@
   <int value="3" label="Microphone error"/>
 </enum>
 
+<enum name="HotwordMediaStreamResult" type="int">
+  <int value="0" label="Success"/>
+  <int value="1" label="Unknown error"/>
+  <int value="2" label="NotSupportedError"/>
+  <int value="3" label="PermissionDeniedError"/>
+  <int value="4" label="ConstraintNotSatisfiedError"/>
+  <int value="5" label="OverconstrainedError"/>
+  <int value="6" label="NotFoundError"/>
+  <int value="7" label="AbortError"/>
+  <int value="8" label="SourceUnavailableError"/>
+  <int value="9" label="PermissionDismissedError"/>
+  <int value="10" label="InvalidStateError"/>
+  <int value="11" label="DevicesNotFoundError"/>
+  <int value="12" label="InvalidSecurityOriginError"/>
+</enum>
+
+<enum name="HotwordNaClMessageTimeout" type="int">
+  <int value="0" label="REQUEST_MODEL"/>
+  <int value="1" label="MODEL_LOADED"/>
+  <int value="2" label="READY_FOR_AUDIO"/>
+  <int value="3" label="STOPPED"/>
+  <int value="4" label="HOTWORD_DETECTED"/>
+  <int value="5" label="MS_CONFIGURED"/>
+</enum>
+
+<enum name="HotwordNaClPluginLoadResult" type="int">
+  <int value="0" label="Success"/>
+  <int value="1" label="Unknown error"/>
+  <int value="2" label="Module crash"/>
+  <int value="3" label="Module not found"/>
+</enum>
+
 <enum name="HotwordPrefState" type="int">
   <int value="0" label="Preference not set"/>
   <int value="1" label="Hotwording enabled"/>
@@ -46166,6 +46427,7 @@
   <int value="18" label="Ratpoison"/>
   <int value="19" label="StumpWM"/>
   <int value="20" label="wmii"/>
+  <int value="21" label="Fluxbox"/>
 </enum>
 
 <enum name="LoadType" type="int">
@@ -46229,6 +46491,7 @@
   <int value="-1876881908"
       label="disable-infobar-for-protected-media-identifier"/>
   <int value="-1874908826" label="enable-instant-search-clicks"/>
+  <int value="-1872989945" label="enable-webview-based-signin"/>
   <int value="-1870961970" label="enable-filemanager-mtp"/>
   <int value="-1847835522" label="disable-touch-adjustment"/>
   <int value="-1838482444" label="disable-settings-window"/>
@@ -46245,6 +46508,7 @@
   <int value="-1703308540" label="disable-webaudio"/>
   <int value="-1696366449" label="disable-permissions-bubbles"/>
   <int value="-1662447331" label="wake-on-packets"/>
+  <int value="-1654344175" label="disable-extension-info-dialog"/>
   <int value="-1619757314" label="touch-scrolling-mode"/>
   <int value="-1605567628" label="disable-overlay-scrollbar"/>
   <int value="-1596559650" label="max-tiles-for-interest-area"/>
@@ -46277,6 +46541,7 @@
   <int value="-1201183153" label="enable-centered-app-list"/>
   <int value="-1172204005" label="enable-offline-auto-reload-visible-only"/>
   <int value="-1159563774" label="enable-accessibility-script-injection"/>
+  <int value="-1136627751" label="ignore-autocomplete-off-autofill"/>
   <int value="-1136509631" label="ssl-interstitial-v1"/>
   <int value="-1125133283" label="disable-threaded-scrolling"/>
   <int value="-1102212525" label="enable-tcp-fastopen"/>
@@ -46373,6 +46638,7 @@
   <int value="370486304" label="enable-origin-chip-on-srp"/>
   <int value="401983950" label="enable-spdy4"/>
   <int value="402143634" label="enable-search-button-in-omnibox-always"/>
+  <int value="415154056" label="enable-physical-keyboard-autocorrect"/>
   <int value="423615350" label="enable-tab-audio-muting"/>
   <int value="446316019" label="enable-threaded-compositing"/>
   <int value="451196246" label="disable-impl-side-painting"/>
@@ -46406,6 +46672,7 @@
   <int value="887011602" label="enable-spelling-auto-correct"/>
   <int value="909439558" label="disable-device-discovery"/>
   <int value="952558794" label="enable-remote-assistance"/>
+  <int value="980396200" label="enable-new-korean-ime"/>
   <int value="1022992701" label="enable-origin-chip-always"/>
   <int value="1033597574" label="disable-layer-squashing"/>
   <int value="1050321458" label="new-profile-management"/>
@@ -46426,6 +46693,7 @@
   <int value="1142515376" label="enable-nacl"/>
   <int value="1150622273" label="enable-apps-file-associations"/>
   <int value="1163255347" label="ash-enable-touch-view-touch-feedback"/>
+  <int value="1181056275" label="enable-cloud-backup"/>
   <int value="1196644408" label="performance-monitor-gathering"/>
   <int value="1205849612" label="enable-sync-synced-notifications"/>
   <int value="1210343926" label="enable-drop-sync-credential"/>
@@ -48142,6 +48410,15 @@
   <int value="1" label="User Disconnect"/>
 </enum>
 
+<enum name="NetworkErrorType" type="int">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="Portal"/>
+  <int value="2" label="Offline"/>
+  <int value="3" label="Proxy"/>
+  <int value="4" label="AuthExtTimeout"/>
+  <int value="5" label="None"/>
+</enum>
+
 <enum name="NetworkLocationRequestEvent" type="int">
   <int value="0" label="REQUEST_START"/>
   <int value="1" label="REQUEST_CANCEL"/>
@@ -50559,6 +50836,15 @@
   <int value="22" label="DOMAIN_NUM_EVENTS"/>
 </enum>
 
+<enum name="PushRegistrationStatus" type="int">
+  <int value="0" label="Successful"/>
+  <int value="1" label="Page has no active Service Worker"/>
+  <int value="2" label="Push service not available"/>
+  <int value="3" label="Registration limit reached"/>
+  <int value="4" label="Permission denied"/>
+  <int value="5" label="Push service error"/>
+</enum>
+
 <enum name="QuicAddressMismatch" type="int">
   <int value="0" label="Address mismatch: IPv4 IPv4"/>
   <int value="1" label="Address mismatch: IPv6 IPv6"/>
@@ -53086,6 +53372,7 @@
   <int value="2" label="Closing"/>
   <int value="3" label="Writing"/>
   <int value="4" label="Renaming"/>
+  <int value="5" label="Flushing"/>
 </enum>
 
 <enum name="TileMemoryBudget" type="int">
@@ -56396,6 +56683,17 @@
   <affected-histogram name="Net.ProxyResolver.ExecutionTime"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="NetworkErrors" separator=".">
+  <suffix name="AuthExtTimeout" label="with the last error AuthExtTimeout"/>
+  <suffix name="Offline" label="with the last error Offline"/>
+  <suffix name="Portal" label="with the last error Portal"/>
+  <suffix name="Proxy" label="with the last error Proxy"/>
+  <affected-histogram name="OOBE.ErrorScreensTime.Enrollment"/>
+  <affected-histogram name="OOBE.ErrorScreensTime.Signin"/>
+  <affected-histogram name="OOBE.ErrorScreensTime.Supervised"/>
+  <affected-histogram name="OOBE.ErrorScreensTime.Update"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="NewTabPageProviders" separator=".">
   <suffix name="client" label="Suggestions coming from the client."/>
   <suffix name="client0" label="Suggestions coming from the client source 0."/>
@@ -57368,6 +57666,7 @@
   <suffix name="FalseStart_enabled"/>
   <suffix name="FalseStart_disabled"/>
   <affected-histogram name="Net.SSL_Connection_Latency"/>
+  <affected-histogram name="Net.SSL_Connection_Latency_2"/>
   <affected-histogram name="PLT.BeginToFinish_LinkLoadNormal"/>
   <affected-histogram name="PLT.BeginToFinish_NormalLoad"/>
 </histogram_suffixes>
@@ -57376,10 +57675,15 @@
   <suffix name="Resume_Handshake" label="Session Resumption"/>
   <suffix name="Full_Handshake" label="Full"/>
   <affected-histogram name="Net.SSL_Connection_Latency"/>
+  <affected-histogram name="Net.SSL_Connection_Latency_2"/>
   <affected-histogram name="Net.SSL_Connection_Latency_Google"/>
+  <affected-histogram name="Net.SSL_Connection_Latency_Google2"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="StartupTimeBombAlarm" separator=".">
+  <obsolete>
+    Deprecated as of 10/2014.
+  </obsolete>
   <suffix name="ThreadNowDuration" label="Duration is in thread CPU time."/>
   <suffix name="TimeDuration" label="Duration is in clock time."/>
   <suffix name="TimeTicksDuration" label="Duration is in TimeTicks time."/>
diff --git a/tools/perf/benchmarks/benchmark_smoke_unittest.py b/tools/perf/benchmarks/benchmark_smoke_unittest.py
index fa35328..2239a38 100644
--- a/tools/perf/benchmarks/benchmark_smoke_unittest.py
+++ b/tools/perf/benchmarks/benchmark_smoke_unittest.py
@@ -84,7 +84,8 @@
       continue
 
     # TODO(tonyg): Smoke doesn't work with session_restore yet.
-    if benchmark.Name().startswith('session_restore'):
+    if (benchmark.Name().startswith('session_restore') or
+        benchmark.Name().startswith('skpicture_printer')):
       continue
 
     if hasattr(benchmark, 'generated_profile_archive'):
diff --git a/tools/perf/benchmarks/power.py b/tools/perf/benchmarks/power.py
index c8aeac23..ab96a59 100644
--- a/tools/perf/benchmarks/power.py
+++ b/tools/perf/benchmarks/power.py
@@ -14,3 +14,12 @@
 
   test = power.Power
   page_set = page_sets.AndroidAcceptancePageSet
+
+
+@benchmark.Enabled('android')
+class PowerTypical10Mobile(benchmark.Benchmark):
+
+  """Android typical 10 mobile power test."""
+
+  test = power.Power
+  page_set = page_sets.Typical10MobilePageSet
diff --git a/tools/perf/benchmarks/skpicture_printer.py b/tools/perf/benchmarks/skpicture_printer.py
new file mode 100644
index 0000000..89559ac
--- /dev/null
+++ b/tools/perf/benchmarks/skpicture_printer.py
@@ -0,0 +1,42 @@
+# 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.
+
+from measurements import skpicture_printer
+from telemetry import benchmark
+from telemetry.core import discover
+from telemetry.page import page_set
+
+
+def _MatchPageSetName(page_set_name, page_set_base_dir):
+  page_sets = []
+  page_sets += discover.DiscoverClasses(page_set_base_dir, page_set_base_dir,
+                                        page_set.PageSet,
+                                        index_by_class_name=True).values()
+  for p in page_sets:
+    if page_set_name == p.Name():
+      return p
+  return None
+
+
+@benchmark.Disabled
+class SkpicturePrinter(benchmark.Benchmark):
+  test = skpicture_printer.SkpicturePrinter
+
+  @classmethod
+  def AddTestCommandLineArgs(cls, parser):
+    parser.add_option('--page-set-name',  action='store', type='string')
+    parser.add_option('--page-set-base-dir', action='store', type='string')
+
+  @classmethod
+  def ProcessCommandLineArgs(cls, parser, args):
+    cls.PageTestClass().ProcessCommandLineArgs(parser, args)
+    if not args.page_set_name:
+      parser.error('Please specify --page-set-name')
+    if not args.page_set_base_dir:
+      parser.error('Please specify --page-set-base-dir')
+
+  def CreatePageSet(self, options):
+    page_set_class = _MatchPageSetName(options.page_set_name,
+                                       options.page_set_base_dir)
+    return page_set_class()
diff --git a/tools/perf/benchmarks/tab_switching.py b/tools/perf/benchmarks/tab_switching.py
index a1cb74c..e5b0436 100644
--- a/tools/perf/benchmarks/tab_switching.py
+++ b/tools/perf/benchmarks/tab_switching.py
@@ -32,3 +32,10 @@
   test = tab_switching.TabSwitching
   page_set = page_sets.ToughEnergyCasesPageSet
   options = {'pageset_repeat': 10}
+
+
+@benchmark.Disabled  # Just for local testing, not on waterfall.
+class TabSwitchingFlashEnergyCases(benchmark.Benchmark):
+  test = tab_switching.TabSwitching
+  page_set = page_sets.FlashEnergyCasesPageSet
+  options = {'pageset_repeat': 10}
diff --git a/tools/perf/metrics/webrtc_stats.py b/tools/perf/metrics/webrtc_stats.py
index e96bfcc..c199577 100644
--- a/tools/perf/metrics/webrtc_stats.py
+++ b/tools/perf/metrics/webrtc_stats.py
@@ -3,6 +3,8 @@
 # found in the LICENSE file.
 
 import json
+import logging
+import re
 
 from metrics import Metric
 from telemetry.core import camel_case
@@ -28,6 +30,25 @@
     # TODO(phoglund): Add much more interesting metrics.
 }
 
+
+def GetReportKind(report):
+  if 'audioInputLevel' in report or 'audioOutputLevel' in report:
+    return 'audio'
+  if 'googFrameRateSent' in report or 'googFrameRateReceived' in report:
+    return 'video'
+
+  logging.error('Did not recognize report batch: %s.', report.keys())
+  return 'unknown'
+
+
+def DistinguishAudioAndVideo(report, stat_name):
+  return GetReportKind(report) + '_' + stat_name
+
+
+def StripAudioVideoDistinction(stat_name):
+  return re.sub('^(audio|video)_', '', stat_name)
+
+
 def SortStatsIntoTimeSeries(report_batches):
   time_series = {}
   for report_batch in report_batches:
@@ -35,7 +56,8 @@
       for stat_name, value in report.iteritems():
         if stat_name not in INTERESTING_METRICS:
           continue
-        time_series.setdefault(stat_name, []).append(float(value))
+        full_stat_name = DistinguishAudioAndVideo(report, stat_name)
+        time_series.setdefault(full_stat_name, []).append(float(value))
 
   return time_series
 
@@ -66,8 +88,9 @@
       for stat_name, values in time_series.iteritems():
         stat_name_underscored = camel_case.ToUnderscore(stat_name)
         trace_name = 'peer_connection_%d_%s' % (i, stat_name_underscored)
+        general_name = StripAudioVideoDistinction(stat_name)
         results.AddValue(list_of_scalar_values.ListOfScalarValues(
             results.current_page, trace_name,
-            INTERESTING_METRICS[stat_name]['units'], values,
-            description=INTERESTING_METRICS[stat_name]['description'],
+            INTERESTING_METRICS[general_name]['units'], values,
+            description=INTERESTING_METRICS[general_name]['description'],
             important=False))
diff --git a/tools/perf/metrics/webrtc_stats_unittest.py b/tools/perf/metrics/webrtc_stats_unittest.py
index 8f1fd1fa..9b5c2bb 100644
--- a/tools/perf/metrics/webrtc_stats_unittest.py
+++ b/tools/perf/metrics/webrtc_stats_unittest.py
@@ -14,9 +14,10 @@
       {
          "googFrameHeightInput":"480",
          "googFrameWidthInput":"640",
+         "googFrameRateSent": "23",
          "packetsLost":"-1",
          "googRtt":"-1",
-         "packetsSent":"0",
+         "packetsSent":"1",
          "bytesSent":"0"
       },
       {
@@ -31,6 +32,7 @@
       {
          "googFrameHeightInput":"480",
          "googFrameWidthInput":"640",
+         "googFrameRateSent": "21",
          "packetsLost":"-1",
          "googRtt":"-1",
          "packetsSent":"8",
@@ -48,6 +50,7 @@
 [
    [
       {
+         "googFrameRateReceived": "23",
          "googDecodeMs":"0",
          "packetsReceived":"8",
          "googRenderDelayMs":"10",
@@ -56,6 +59,7 @@
    ],
    [
       {
+         "googFrameRateReceived": "23",
          "googDecodeMs":"14",
          "packetsReceived":"1234",
          "googRenderDelayMs":"102",
@@ -108,27 +112,29 @@
     self.assertTrue(results.received_values,
                     'Expected values for googDecodeMs and others, got none.')
 
-    # TODO(phoglund): this is actually a bug; make the metric clever enough to
-    # distinguish packetsSent on audio from packetsSent on video, etc.
+    # This also ensures we're clever enough to tell video packetsSent from audio
+    # packetsSent.
     self.assertEqual(results.received_values[0].values,
-                     [0.0, 4.0, 8.0, 16.0])
+                     [4.0, 16.0])
     self.assertEqual(results.received_values[1].values,
-                     [8.0, 1234.0])
+                     [1.0, 8.0])
 
   def testExtractsInterestingMetricsOnly(self):
     results = self._RunMetricOnJson(SAMPLE_JSON)
 
-    self.assertEqual(len(results.received_values), 4)
+    self.assertEqual(len(results.received_values), 5)
     self.assertEqual(results.received_values[0].name,
-                     'peer_connection_0_packets_sent',
+                     'peer_connection_0_audio_packets_sent',
                      'The result should be a ListOfScalarValues instance with '
                      'a name <peer connection id>_<statistic>.')
     self.assertEqual(results.received_values[1].name,
-                     'peer_connection_1_packets_received')
+                     'peer_connection_0_video_packets_sent')
     self.assertEqual(results.received_values[2].name,
-                     'peer_connection_1_goog_decode_ms')
+                     'peer_connection_1_video_goog_max_decode_ms')
     self.assertEqual(results.received_values[3].name,
-                     'peer_connection_1_goog_max_decode_ms')
+                     'peer_connection_1_video_packets_received')
+    self.assertEqual(results.received_values[4].name,
+                     'peer_connection_1_video_goog_decode_ms')
 
   def testReturnsIfJsonIsEmpty(self):
     results = self._RunMetricOnJson('[]')
diff --git a/tools/perf/page_sets/data/flash_energy_cases.json b/tools/perf/page_sets/data/flash_energy_cases.json
new file mode 100644
index 0000000..cb8f10e
--- /dev/null
+++ b/tools/perf/page_sets/data/flash_energy_cases.json
@@ -0,0 +1,13 @@
+{
+    "description": "Describes the Web Page Replay archives for a page set. Don't edit by hand! Use record_wpr for updating.", 
+    "archives": {
+        "flash_energy_cases_000.wpr": [
+            "http://nos.nl/video/712855-eerste-beelden-na-de-aanslag-in-canada.html", 
+            "http://forum.gazeta.pl/forum/f,17007,Polityka_i_Gospodarka.html", 
+            "http://tinypic.com/", 
+            "https://www.facebook.com/video.php?v=524346051035153&set=vb.134474600022302&type=2&theater", 
+            "http://v.qq.com/cover/d/dm9vn9cnsn2v2gx.html?ptag=v.newplaybutton.program.dpjd", 
+            "http://videos.huffingtonpost.com/politics/protesters-march-to-hong-kong-leaders-home-518476075"
+        ]
+    }
+}
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/flash_energy_cases_000.wpr.sha1 b/tools/perf/page_sets/data/flash_energy_cases_000.wpr.sha1
new file mode 100644
index 0000000..ee693cf
--- /dev/null
+++ b/tools/perf/page_sets/data/flash_energy_cases_000.wpr.sha1
@@ -0,0 +1 @@
+7d928f2c2f95999e26f00c72f8c9dd9a55932643
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/typical_10_mobile.json b/tools/perf/page_sets/data/typical_10_mobile.json
new file mode 100644
index 0000000..b8e1501
--- /dev/null
+++ b/tools/perf/page_sets/data/typical_10_mobile.json
@@ -0,0 +1,17 @@
+{
+    "description": "Describes the Web Page Replay archives for a page set. Don't edit by hand! Use record_wpr for updating.", 
+    "archives": {
+        "typical_10_mobile_000.wpr": [
+            "http://m.ynet.co.il", 
+            "http://m.facebook.com/barackobama", 
+            "http://m.chiebukuro.yahoo.co.jp/detail/q10136829180", 
+            "http://m.ebay.com/itm/351157205404", 
+            "http://siriuslymeg.tumblr.com/", 
+            "http://www.rg.ru/2014/10/21/cska-site.html", 
+            "http://wapbaike.baidu.com/", 
+            "http://m.huffpost.com/us/entry/6004486", 
+            "http://www.cnn.com/2014/03/31/showbiz/tv/himym-finale/index.html", 
+            "http://de.m.wikipedia.org/wiki/K%C3%B6lner_Dom"
+        ]
+    }
+}
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/typical_10_mobile_000.wpr.sha1 b/tools/perf/page_sets/data/typical_10_mobile_000.wpr.sha1
new file mode 100644
index 0000000..4fc7168
--- /dev/null
+++ b/tools/perf/page_sets/data/typical_10_mobile_000.wpr.sha1
@@ -0,0 +1 @@
+88abc57bafa161d3536f7daf5b792a4a9b7ef1fc
\ No newline at end of file
diff --git a/tools/perf/page_sets/flash_energy_cases.py b/tools/perf/page_sets/flash_energy_cases.py
new file mode 100644
index 0000000..1c52f68b
--- /dev/null
+++ b/tools/perf/page_sets/flash_energy_cases.py
@@ -0,0 +1,39 @@
+# 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.
+from telemetry.page import page as page_module
+from telemetry.page import page_set as page_set_module
+
+
+class FlashEnergyCasesPage(page_module.Page):
+
+  def __init__(self, url, page_set):
+    super(FlashEnergyCasesPage, self).__init__(url=url, page_set=page_set)
+    self.user_agent_type = 'desktop'
+    self.archive_data_file = 'data/flash_energy_cases.json'
+
+
+class FlashEnergyCasesPageSet(page_set_module.PageSet):
+
+  """ Pages with flash heavy content. """
+
+  def __init__(self):
+    super(FlashEnergyCasesPageSet, self).__init__(
+      user_agent_type='desktop',
+      archive_data_file='data/flash_energy_cases.json',
+      bucket=page_set_module.PARTNER_BUCKET)
+
+    urls_list = [
+        # pylint: disable=C0301
+        'http://v.qq.com/cover/d/dm9vn9cnsn2v2gx.html?ptag=v.newplaybutton.program.dpjd',
+        'http://videos.huffingtonpost.com/politics/protesters-march-to-hong-kong-leaders-home-518476075',
+        'http://nos.nl/video/712855-eerste-beelden-na-de-aanslag-in-canada.html',
+        # Why: Large flash ad
+        'http://forum.gazeta.pl/forum/f,17007,Polityka_i_Gospodarka.html',
+        # Why: Multiple flash ads
+        'http://tinypic.com/',
+        'https://www.facebook.com/video.php?v=524346051035153&set=vb.134474600022302&type=2&theater'
+    ]
+
+    for url in urls_list:
+      self.AddPage(FlashEnergyCasesPage(url, self))
diff --git a/tools/perf/page_sets/typical_10_mobile.py b/tools/perf/page_sets/typical_10_mobile.py
new file mode 100644
index 0000000..5b3dbc4
--- /dev/null
+++ b/tools/perf/page_sets/typical_10_mobile.py
@@ -0,0 +1,56 @@
+# 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.
+from telemetry.page import page as page_module
+from telemetry.page import page_set as page_set_module
+
+
+class Typical10MobilePage(page_module.Page):
+
+  def __init__(self, url, page_set, name=''):
+    super(Typical10MobilePage, self).__init__(
+        url=url, page_set=page_set, name=name,
+        credentials_path = 'data/credentials.json')
+    self.user_agent_type = 'mobile'
+    self.archive_data_file = 'data/typical_10_mobile.json'
+
+  def RunPowerPageInteractions(self, action_runner):
+    action_runner.Wait(20)
+    action_runner.ScrollPage()
+    action_runner.Wait(20)
+
+
+class Typical10MobilePageSet(page_set_module.PageSet):
+  """10 typical mobile pages, used for power testing."""
+
+  def __init__(self):
+    super(Typical10MobilePageSet, self).__init__(
+        user_agent_type='mobile',
+        archive_data_file='data/typical_10_mobile.json',
+        bucket=page_set_module.PARTNER_BUCKET)
+
+    urls_list = [
+        # Why: Top site
+        'http://m.facebook.com/barackobama',
+        # Why: Wikipedia article with lots of pictures, German language
+        'http://de.m.wikipedia.org/wiki/K%C3%B6lner_Dom',
+        # Why: current top Q&A on popular Japanese site
+        'http://m.chiebukuro.yahoo.co.jp/detail/q10136829180',
+        # Why: news article on popular site
+        'http://m.huffpost.com/us/entry/6004486',
+        # Why: news article on popular site
+        'http://www.cnn.com/2014/03/31/showbiz/tv/himym-finale/index.html',
+        # Why: Popular RTL language site
+        'http://m.ynet.co.il',
+        # Why: Popular Russian language site
+        'http://www.rg.ru/2014/10/21/cska-site.html',
+        # Why: Popular shopping site
+        'http://m.ebay.com/itm/351157205404',
+        # Why: Popular viral site, lots of images
+        'http://siriuslymeg.tumblr.com/',
+        # Why: Popular Chinese language site.
+        'http://wapbaike.baidu.com/',
+    ]
+
+    for url in urls_list:
+      self.AddPage(Typical10MobilePage(url, self))
diff --git a/tools/perf/test-info.json b/tools/perf/test-info.json
index 4276042..571e020 100644
--- a/tools/perf/test-info.json
+++ b/tools/perf/test-info.json
@@ -213,5 +213,11 @@
   },
   "tab_switching.top_10":{
     "description":"This test records the MPArch.RWH_TabSwitchPaintDuration histogram, which is a measure of the time between when a tab was requested to be shown, and when first paint occurred. The script opens 10 pages in different tabs, waits for them to load, and then switches to each tab and records the metric. The pages were chosen from Alexa top ranking sites."
+  },
+  "task_execution_time.key_mobile_sites":{
+    "description":"This benchmark measures the runtimes of various tasks on the renderer main thread while scrolling on key mobile sites. It is used for tracking and guiding optimizations in the Blink scheduler project."
+  },
+  "task_execution_time.tough_scheduling_cases":{
+    "description":"This benchmark measures the runtimes of various tasks on the renderer main thread while scrolling on synthetic pages with challenging scheduling properties. It is used for tracking and guiding optimizations in the Blink scheduler project."
   }
 }
diff --git a/tools/relocation_packer/BUILD.gn b/tools/relocation_packer/BUILD.gn
new file mode 100644
index 0000000..d841277e
--- /dev/null
+++ b/tools/relocation_packer/BUILD.gn
@@ -0,0 +1,135 @@
+# 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.
+
+import("config.gni")
+
+assert(relocation_packing_supported)
+
+if (target_arch == "arm") {
+  target_define = "TARGET_ARM"
+} else if (target_arch == "arm64") {
+  target_define = "TARGET_ARM64"
+}
+
+if (current_toolchain == host_toolchain) {
+  # GYP: //tools/relocation_packer/relocation_packer.gyp:lib_relocation_packer
+  source_set("lib_relocation_packer") {
+    defines = [ target_define ]
+    deps = [ "//third_party/elfutils:libelf" ]
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+    sources = [
+      "src/debug.cc",
+      "src/delta_encoder.cc",
+      "src/elf_file.cc",
+      "src/leb128.cc",
+      "src/packer.cc",
+      "src/sleb128.cc",
+      "src/run_length_encoder.cc",
+    ]
+  }
+
+  # GYP: //tools/relocation_packer/relocation_packer.gyp:relocation_packer
+  executable("relocation_packer") {
+    defines = [ target_define ]
+    deps = [
+      ":lib_relocation_packer",
+      "//third_party/elfutils:libelf",
+    ]
+    sources = [ "src/main.cc" ]
+  }
+
+  # GYP: //tools/relocation_packer/relocation_packer.gyp:relocation_packer_unittests
+  test("relocation_packer_unittests") {
+    sources = [
+      "src/debug_unittest.cc",
+      "src/delta_encoder_unittest.cc",
+      "src/elf_file_unittest.cc",
+      "src/leb128_unittest.cc",
+      "src/packer_unittest.cc",
+      "src/sleb128_unittest.cc",
+      "src/run_length_encoder_unittest.cc",
+      "src/run_all_unittests.cc",
+    ]
+    rebased_test_data = rebase_path("test_data", root_build_dir)
+    data = [
+      "test_data/elf_file_unittest_relocs_arm32.so",
+      "test_data/elf_file_unittest_relocs_arm32_packed.so",
+      "test_data/elf_file_unittest_relocs_arm64.so",
+      "test_data/elf_file_unittest_relocs_arm64_packed.so",
+    ]
+    defines = [
+      target_define,
+      "INTERMEDIATE_DIR=\"$rebased_test_data\""
+    ]
+    include_dirs = [ "//" ]
+    deps = [
+      ":lib_relocation_packer",
+      ":relocation_packer_test_data",
+      "//testing:gtest",
+    ]
+  }
+}
+
+if (current_toolchain == default_toolchain &&
+    (target_arch == "arm" || target_arch == "arm64")) {
+  # Targets to build test data.  These participate only in building test
+  # data for use with elf_file_unittest.cc, and are not part of the main
+  # relocation packer build.  Unit test data files are checked in to the
+  # source tree as 'golden' data, and are not generated 'on the fly' by
+  # the build.
+  #
+  # See test_data/generate_elf_file_unittest_relocs.sh for instructions.
+
+  # GYP: //tools/relocation_packer/relocation_packer.gyp:relocation_packer_test_data
+  shared_library("relocation_packer_test_data") {
+    cflags = [ "-O0", "-g0" ]
+    sources = [
+      "test_data/elf_file_unittest_relocs.cc"
+    ]
+  }
+
+  # GYP: //tools/relocation_packer/relocation_packer.gyp:relocation_packer_unittests_test_data
+  action("relocation_packer_unittests_test_data") {
+    script = "test_data/generate_elf_file_unittest_relocs.py"
+    test_file = "$root_build_dir/librelocation_packer_test_data.so"
+    if (target_arch == "arm") {
+      added_section = ".android.rel.dyn"
+      packed_output = "elf_file_unittest_relocs_arm32_packed.so"
+      unpacked_output = "elf_file_unittest_relocs_arm32.so"
+    } else if (target_arch == "arm64") {
+      added_section = ".android.rela.dyn"
+      packed_output = "elf_file_unittest_relocs_arm64_packed.so"
+      unpacked_output = "elf_file_unittest_relocs_arm64.so"
+    } else {
+      assert(false, "Unsupported target arch for relocation packer")
+    }
+
+    packed_output = "$root_build_dir/$packed_output"
+    unpacked_output = "$root_build_dir/$unpacked_output"
+
+    inputs = [
+      test_file,
+    ]
+
+    deps = [
+      ":relocation_packer_test_data",
+      ":relocation_packer($host_toolchain)",
+    ]
+
+    outputs = [
+      packed_output,
+      unpacked_output,
+    ]
+
+    args = [
+      "--android-pack-relocations", rebase_path(relocation_packer_exe, root_build_dir),
+      "--android-objcopy", rebase_path(android_objcopy, root_build_dir),
+      "--added-section=$added_section",
+      "--test-file", rebase_path(test_file, root_build_dir),
+      "--packed-output", rebase_path(packed_output, root_build_dir),
+      "--unpacked-output", rebase_path(unpacked_output, root_build_dir),
+    ]
+  }
+}
diff --git a/tools/relocation_packer/config.gni b/tools/relocation_packer/config.gni
new file mode 100644
index 0000000..fec27522
--- /dev/null
+++ b/tools/relocation_packer/config.gni
@@ -0,0 +1,22 @@
+# 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.
+
+relocation_packing_supported = (
+    (target_arch == "arm") || (target_arch == "arm64"))
+
+if (relocation_packing_supported) {
+  relocation_packer_target = "//tools/relocation_packer($host_toolchain)"
+  relocation_packer_dir = get_label_info(
+      "$relocation_packer_target", "root_out_dir")
+  relocation_packer_exe = "${relocation_packer_dir}/relocation_packer"
+
+  if (target_arch == "arm") {
+    relocations_have_addends = 0
+  } else if (target_arch == "arm64") {
+    relocations_have_addends = 1
+  }
+} else {
+  relocations_have_addends = 0
+  relocation_packer_exe = ""
+}
diff --git a/tools/relocation_packer/relocation_packer.gyp b/tools/relocation_packer/relocation_packer.gyp
index 5d1574fd..1e9c1b95 100644
--- a/tools/relocation_packer/relocation_packer.gyp
+++ b/tools/relocation_packer/relocation_packer.gyp
@@ -16,6 +16,7 @@
   },
   'targets': [
     {
+      # GN: //tools/relocation_packer:lib_relocation_packer
       'target_name': 'lib_relocation_packer',
       'toolsets': ['host'],
       'type': 'static_library',
@@ -36,6 +37,7 @@
       ],
     },
     {
+      # GN: //tools/relocation_packer:relocation_packer
       'target_name': 'relocation_packer',
       'toolsets': ['host'],
       'type': 'executable',
@@ -51,6 +53,7 @@
       ],
     },
     {
+      # GN: //tools/relocation_packer:relocation_packer_unittests
       'target_name': 'relocation_packer_unittests',
       'toolsets': ['host'],
       'type': 'executable',
@@ -98,6 +101,7 @@
     #
     # See test_data/generate_elf_file_unittest_relocs.sh for instructions.
     {
+      # GN: //tools/relocation_packer:relocation_packer_test_data
       'target_name': 'relocation_packer_test_data',
       'toolsets': ['target'],
       'type': 'shared_library',
@@ -110,6 +114,7 @@
       ],
     },
     {
+      # GN: //tools/relocation_packer:relocation_packer_unittests_test_data
       'target_name': 'relocation_packer_unittests_test_data',
       'toolsets': ['target'],
       'type': 'none',
diff --git a/tools/telemetry/support/html_output/results-template.html b/tools/telemetry/support/html_output/results-template.html
index 69ad6b80..f66698d 100644
--- a/tools/telemetry/support/html_output/results-template.html
+++ b/tools/telemetry/support/html_output/results-template.html
@@ -598,8 +598,9 @@
 
     testNames.sort().map(function (testName) {
         var test = tests[testName];
-        if (test.isMemoryTest() != shouldIgnoreMemory)
-            createTableRow(runs, test, referenceIndex, useLargeLinePlots);
+        if (test.isMemoryTest() != shouldIgnoreMemory) {
+            new TableRow(runs, test, referenceIndex, useLargeLinePlots);
+        }
     });
 
     $('.closeButton').click(function(event) {
@@ -682,111 +683,115 @@
     + '<circle cx="50" cy="73" r="6" fill="white" />'
     + '</svg>';
 
-function createTableRow(runs, test, referenceIndex, useLargeLinePlots) {
-    var tableRow = $('<tr><td class="test collapsed"' + (test.isImportant ? ' style="font-weight:bold"' : '') + '>' + test.name() + '</td><td class="unit">' + test.unit() + '</td></tr>');
+function TableRow(runs, test, referenceIndex, useLargeLinePlots) {
+    this.runs = runs;
+    this.test = test;
+    this.referenceIndex = referenceIndex;
+    this.useLargeLinePlots = useLargeLinePlots;
 
-    function markupForRun(result, referenceResult) {
-        var comparisonCell = '';
-        var hiddenValue = '';
-        var shouldCompare = result !== referenceResult;
-        if (shouldCompare && referenceResult) {
-            var percentDifference = referenceResult.percentDifference(result);
-            var better = test.biggerIsBetter() ? percentDifference > 0 : percentDifference < 0;
-            var comparison = '';
-            var className = 'comparison';
-            if (referenceResult.isStatisticallySignificant(result)) {
-                comparison = formatPercentage(Math.abs(percentDifference)) + (better ? ' Better' : ' Worse&nbsp;');
-                className += better ? ' better' : ' worse';
-            }
-            hiddenValue = '<span style="display: none">|' + comparison + '</span>';
-            comparisonCell = '<td class="' + className + '">' + comparison + '</td>';
-        } else if (shouldCompare)
-            comparisonCell = '<td class="comparison"></td>';
-
-        var values = result.values();
-        var warning = '';
-        var regressionAnalysis = '';
-        if (result.histogramValues) {
-            // Don't calculate regression result for histograms.
-        }
-        else if (values && values.length > 3) {
-            regressionResult = linearRegression(values);
-            regressionAnalysis = 'slope=' + toFixedWidthPrecision(regressionResult.slope)
-                + ', R^2=' + toFixedWidthPrecision(regressionResult.rSquared);
-            if (regressionResult.rSquared > 0.6 && Math.abs(regressionResult.slope) > 0.01) {
-                warning = ' <span class="regression-warning" title="Detected a time dependency with ' + regressionAnalysis + '">' + warningSign + ' </span>';
-            }
-        }
-
-        var statistics = '&sigma;=' + toFixedWidthPrecision(result.confidenceIntervalDelta()) + ', min=' + toFixedWidthPrecision(result.min())
-            + ', max=' + toFixedWidthPrecision(result.max()) + '\n' + regressionAnalysis;
-
-        // Tablesorter doesn't know about the second cell so put the comparison in the invisible element.
-        return '<td class="result" title="' + statistics + '">' + toFixedWidthPrecision(result.mean()) + hiddenValue
-            + '</td><td class="confidenceIntervalDelta" title="' + statistics + '">&plusmn; '
-            + formatPercentage(result.confidenceIntervalDeltaRatio()) + warning + '</td>' + comparisonCell;
-    }
-
-    function markupForMissingRun(isReference) {
-        return '<td colspan="' + (isReference ? 2 : 3) + '" class="missing">Missing</td>';
-    }
+    this.tableRow = $('<tr><td class="test collapsed"' + (this.test.isImportant ? ' style="font-weight:bold"' : '') + '>' + this.test.name() + '</td><td class="unit">' + this.test.unit() + '</td></tr>');
 
     var runIndex = 0;
-    var results = test.results();
+    var results = this.test.results();
     var referenceResult = undefined;
     var resultIndexMap = {};
     for (var i = 0; i < results.length; i++) {
-        while (runs[runIndex] !== results[i].run())
+        while (this.runs[runIndex] !== results[i].run())
             runIndex++;
-        if (runIndex == referenceIndex)
+        if (runIndex == this.referenceIndex)
             referenceResult = results[i];
         resultIndexMap[runIndex] = i;
     }
-    for (var i = 0; i < runs.length; i++) {
+    for (var i = 0; i < this.runs.length; i++) {
         var resultIndex = resultIndexMap[i];
         if (resultIndex == undefined)
-            tableRow.append(markupForMissingRun(i == referenceIndex));
+            this.tableRow.append(this.markupForMissingRun(i == this.referenceIndex));
         else
-            tableRow.append(markupForRun(results[resultIndex], referenceResult));
+            this.tableRow.append(this.markupForRun(results[resultIndex], this.referenceResult));
     }
 
-    $('#container').children('tbody').last().append(tableRow);
+    $('#container').children('tbody').last().append(this.tableRow);
 
-    function toggle() {
-        var firstCell = tableRow.children('td').first();
-        if (firstCell.children('section').length) {
-            firstCell.children('section').remove();
-            tableRow.children('td').css({'padding-bottom': ''});
-            tableRow.children('td').first().addClass('collapsed');
-            tableRow.children('td').first().removeClass('expanded');
-        } else {
-            var plot = createPlot(firstCell, test, useLargeLinePlots);
-            plot.css({'position': 'absolute', 'z-index': 2});
-            var offset = tableRow.offset();
-            offset.left += 1;
-            offset.top += tableRow.outerHeight();
-            plot.offset(offset);
-            tableRow.children('td').css({'padding-bottom': plot.outerHeight() + 5});
-            tableRow.children('td').first().removeClass('collapsed');
-            tableRow.children('td').first().addClass('expanded');
-        }
-
-        return false;
-    };
-
-    tableRow.click(function(event) {
-        if (event.target != tableRow[0] && event.target.parentNode != tableRow[0])
-            return;
-
-        event.preventDefault();
-
-        toggle();
-    });
-
-    if (test.isImportant && window.isFirstImportantRow) {
+    if (this.test.isImportant && window.isFirstImportantRow) {
         window.isFirstImportantRow = false;
-        toggle();
+        this.toggle();
     }
+
+    var owningObject = this;
+    this.tableRow.click(function(event) {
+        if (event.target != owningObject.tableRow[0] && event.target.parentNode != owningObject.tableRow[0]) {
+            return;
+        }
+        event.preventDefault();
+        owningObject.toggle();
+    });
+}
+
+TableRow.prototype.markupForRun = function(result, referenceResult) {
+    var comparisonCell = '';
+    var hiddenValue = '';
+    var shouldCompare = result !== referenceResult;
+    if (shouldCompare && referenceResult) {
+        var percentDifference = referenceResult.percentDifference(result);
+        var better = this.test.biggerIsBetter() ? percentDifference > 0 : percentDifference < 0;
+        var comparison = '';
+        var className = 'comparison';
+        if (referenceResult.isStatisticallySignificant(result)) {
+            comparison = formatPercentage(Math.abs(percentDifference)) + (better ? ' Better' : ' Worse&nbsp;');
+            className += better ? ' better' : ' worse';
+        }
+        hiddenValue = '<span style="display: none">|' + comparison + '</span>';
+        comparisonCell = '<td class="' + className + '">' + comparison + '</td>';
+    } else if (shouldCompare)
+        comparisonCell = '<td class="comparison"></td>';
+
+    var values = result.values();
+    var warning = '';
+    var regressionAnalysis = '';
+    if (result.histogramValues) {
+        // Don't calculate regression result for histograms.
+    } else if (values && values.length > 3) {
+        regressionResult = linearRegression(values);
+        regressionAnalysis = 'slope=' + toFixedWidthPrecision(regressionResult.slope)
+            + ', R^2=' + toFixedWidthPrecision(regressionResult.rSquared);
+        if (regressionResult.rSquared > 0.6 && Math.abs(regressionResult.slope) > 0.01) {
+            warning = ' <span class="regression-warning" title="Detected a time dependency with ' + regressionAnalysis + '">' + warningSign + ' </span>';
+        }
+    }
+
+    var statistics = '&sigma;=' + toFixedWidthPrecision(result.confidenceIntervalDelta()) + ', min=' + toFixedWidthPrecision(result.min())
+        + ', max=' + toFixedWidthPrecision(result.max()) + '\n' + regressionAnalysis;
+
+    // Tablesorter doesn't know about the second cell so put the comparison in the invisible element.
+    return '<td class="result" title="' + statistics + '">' + toFixedWidthPrecision(result.mean()) + hiddenValue
+        + '</td><td class="confidenceIntervalDelta" title="' + statistics + '">&plusmn; '
+        + formatPercentage(result.confidenceIntervalDeltaRatio()) + warning + '</td>' + comparisonCell;
+}
+
+TableRow.prototype.markupForMissingRun = function(isReference) {
+    return '<td colspan="' + (isReference ? 2 : 3) + '" class="missing">Missing</td>';
+}
+
+TableRow.prototype.toggle = function() {
+    var firstCell = this.tableRow.children('td').first();
+    if (firstCell.children('section').length) {
+        firstCell.children('section').remove();
+        this.tableRow.children('td').css({'padding-bottom': ''});
+        this.tableRow.children('td').first().addClass('collapsed');
+        this.tableRow.children('td').first().removeClass('expanded');
+    } else {
+        var plot = createPlot(firstCell, this.test, this.useLargeLinePlots);
+        plot.css({'position': 'absolute', 'z-index': 2});
+        var offset = this.tableRow.offset();
+        offset.left += 1;
+        offset.top += this.tableRow.outerHeight();
+        plot.offset(offset);
+        this.tableRow.children('td').css({'padding-bottom': plot.outerHeight() + 5});
+        this.tableRow.children('td').first().removeClass('collapsed');
+        this.tableRow.children('td').first().addClass('expanded');
+    }
+
+    return false;
 }
 
 function init() {
diff --git a/tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js b/tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js
index 7ec6a6c..7d21eb3 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js
+++ b/tools/telemetry/telemetry/core/backends/chrome/chromeos_login_ext/main.js
@@ -12,6 +12,7 @@
 var msg = {
   'method': 'completeLogin',
   'email': 'test@test.test',
+  'gaiaId': '12345',
   'password': ''
 };
 window.parent.postMessage(msg, PARENT_PAGE);
diff --git a/tools/telemetry/telemetry/core/backends/chrome/inspector_memory_unittest.py b/tools/telemetry/telemetry/core/backends/chrome/inspector_memory_unittest.py
index 59d1ce89..e9361529 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/inspector_memory_unittest.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/inspector_memory_unittest.py
@@ -9,6 +9,7 @@
 class InspectorMemoryTest(tab_test_case.TabTestCase):
 
   @benchmark.Enabled('has tabs')
+  @benchmark.Disabled  # http://crbug.com/422244
   def testGetDOMStats(self):
     # Due to an issue with CrOS, we create a new tab here rather than
     # using the existing tab to get a consistent starting page on all platforms.
diff --git a/tools/telemetry/telemetry/core/backends/chrome/inspector_network_unittest.py b/tools/telemetry/telemetry/core/backends/chrome/inspector_network_unittest.py
index 7e8a4920..b7165b50 100644
--- a/tools/telemetry/telemetry/core/backends/chrome/inspector_network_unittest.py
+++ b/tools/telemetry/telemetry/core/backends/chrome/inspector_network_unittest.py
@@ -1,6 +1,8 @@
 # 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.
+
+from telemetry import benchmark
 from telemetry.core.backends.chrome import inspector_network
 from telemetry.timeline import recording_options
 from telemetry.unittest import tab_test_case
@@ -67,6 +69,9 @@
           self.assertFalse('<!DOCTYPE HTML>' in body)
           self.assertTrue(base64_encoded)
 
+  # Flaky on many platforms (at least Win, Linux, and Mac).
+  # http://crbug.com/424706
+  @benchmark.Disabled
   def testCacheableHTTPResponse(self):
     # We know this page has one PNG image and its cacheable.
     events = self._NavigateAndGetHTTPResponseEvents('image_decoding.html')
diff --git a/tools/telemetry/telemetry/core/user_agent.py b/tools/telemetry/telemetry/core/user_agent.py
index 885c221..0592c91 100644
--- a/tools/telemetry/telemetry/core/user_agent.py
+++ b/tools/telemetry/telemetry/core/user_agent.py
@@ -5,20 +5,20 @@
 UA_TYPE_MAPPING = {
   'desktop':
       'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) '
-      'AppleWebKit/537.22 (KHTML, like Gecko) '
-      'Chrome/27.0.1453.111 Safari/537.22',
+      'AppleWebKit/537.36 (KHTML, like Gecko) '
+      'Chrome/40.0.2194.2 Safari/537.36',
   'mobile':
       'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) '
-      'AppleWebKit/535.19 (KHTML, like Gecko) Chrome/27.0.1453.111 Mobile '
-      'Safari/535.19',
+      'AppleWebKit/535.36 (KHTML, like Gecko) Chrome/40.0.2194.2 Mobile '
+      'Safari/535.36',
   'tablet':
       'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus 7 Build/IMM76B) '
-      'AppleWebKit/535.19 (KHTML, like Gecko) Chrome/27.0.1453.111 '
-      'Safari/535.19',
+      'AppleWebKit/535.36 (KHTML, like Gecko) Chrome/40.0.2194.2 '
+      'Safari/535.36',
   'tablet_10_inch':
       'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus 10 Build/IMM76B) '
-      'AppleWebKit/535.19 (KHTML, like Gecko) Chrome/27.0.1453.111 '
-      'Safari/535.19',
+      'AppleWebKit/535.36 (KHTML, like Gecko) Chrome/40.0.2194.2 '
+      'Safari/535.36',
 }
 
 
diff --git a/tools/telemetry/telemetry/page/profile_generator.py b/tools/telemetry/telemetry/page/profile_generator.py
index 8a253f7..d308e61 100644
--- a/tools/telemetry/telemetry/page/profile_generator.py
+++ b/tools/telemetry/telemetry/page/profile_generator.py
@@ -81,7 +81,7 @@
   if results.failures:
     logging.warning('Some pages failed.')
     logging.warning('Failed pages:\n%s',
-                    '\n'.join(results.pages_that_failed))
+                    '\n'.join(map(str, results.pages_that_failed)))
     return 1
 
   # Everything is a-ok, move results to final destination.
diff --git a/tools/telemetry/telemetry/page/record_wpr.py b/tools/telemetry/telemetry/page/record_wpr.py
index 97919e01..f1f811b 100644
--- a/tools/telemetry/telemetry/page/record_wpr.py
+++ b/tools/telemetry/telemetry/page/record_wpr.py
@@ -123,7 +123,12 @@
     self._AddCommandLineArgs()
     self._ParseArgs(args)
     self._ProcessCommandLineArgs()
-    self._page_set = self._GetPageSet(base_dir, target)
+
+    if self._options.page_set_base_dir:
+      page_set_base_dir = self._options.page_set_base_dir
+    else:
+      page_set_base_dir = base_dir
+    self._page_set = self._GetPageSet(page_set_base_dir, target)
 
   @property
   def options(self):
@@ -144,6 +149,8 @@
     return results_options.CreateResults(benchmark_metadata, self._options)
 
   def _AddCommandLineArgs(self):
+    self._parser.add_option('--page-set-base-dir', action='store',
+                            type='string')
     page_runner.AddCommandLineArgs(self._parser)
     if self._benchmark is not None:
       self._benchmark.AddCommandLineArgs(self._parser)
diff --git a/tools/telemetry/telemetry/page/record_wpr_unittest.py b/tools/telemetry/telemetry/page/record_wpr_unittest.py
index 1370962..0197451b 100644
--- a/tools/telemetry/telemetry/page/record_wpr_unittest.py
+++ b/tools/telemetry/telemetry/page/record_wpr_unittest.py
@@ -164,6 +164,20 @@
     self.assertEqual(set(mock_benchmark.mock_page_set.pages),
                      results.pages_that_succeeded)
 
+  def testPageSetBaseDirFlag(self):
+    flags = [
+       '--page-set-base-dir', self._test_data_dir,
+       '--mock-benchmark-url', self._url,
+       '--browser', self._browser.browser_type,
+    ]
+    mock_benchmark = MockBenchmark()
+    wpr_recorder = record_wpr.WprRecorder(
+        'non-existent-dummy-dir', mock_benchmark, flags)
+    results = wpr_recorder.CreateResults()
+    wpr_recorder.Record(results)
+    self.assertEqual(set(mock_benchmark.mock_page_set.pages),
+                     results.pages_that_succeeded)
+
   def testCommandLineFlags(self):
     flags = [
         '--page-repeat', '2',
diff --git a/tools/telemetry/telemetry/web_components/results_viewer.html b/tools/telemetry/telemetry/web_components/results_viewer.html
index 04807bd5..62ce2d9c 100644
--- a/tools/telemetry/telemetry/web_components/results_viewer.html
+++ b/tools/telemetry/telemetry/web_components/results_viewer.html
@@ -4,15 +4,15 @@
 Use of this source code is governed by a BSD-style license that can be
 found in the LICENSE file.
 -->
-<link rel="import" href="/tvcm/ui.html">
+<link rel="import" href="/base/ui.html">
 <script>
 'use strict';
 
-tvcm.exportTo('telemetry.web_components', function() {
+tv.exportTo('telemetry.web_components', function() {
   /**
    * @constructor
    */
-  var ResultsViewer = tvcm.ui.define('x-results-viewer');
+  var ResultsViewer = tv.ui.define('x-results-viewer');
 
   ResultsViewer.prototype = {
     __proto__: HTMLUnknownElement.prototype,
diff --git a/tools/telemetry/telemetry/web_components/results_viewer_unittest.html b/tools/telemetry/telemetry/web_components/results_viewer_unittest.html
index 40e718a..82d7a5d 100644
--- a/tools/telemetry/telemetry/web_components/results_viewer_unittest.html
+++ b/tools/telemetry/telemetry/web_components/results_viewer_unittest.html
@@ -8,7 +8,7 @@
 <script>
 'use strict';
 
-tvcm.unittest.testSuite(function() {
+tv.unittest.testSuite(function() {
   test('testBasic', function() {
     var resultsViewer = new telemetry.web_components.ResultsViewer();
     resultsViewer.dataToView = {hello: 'world', nice: ['to', 'see', 'you']};
diff --git a/tools/telemetry/telemetry/web_components/tvcm_stub.py b/tools/telemetry/telemetry/web_components/tvcm_stub.py
index 214d0f1..089cf92 100644
--- a/tools/telemetry/telemetry/web_components/tvcm_stub.py
+++ b/tools/telemetry/telemetry/web_components/tvcm_stub.py
@@ -4,7 +4,10 @@
 
 from telemetry.core import util
 
-# Bring in tvcm module for basic JS components capabilities.
+# Bring in tv module for basic JS components capabilities.
+util.AddDirToPythonPath(
+    util.GetChromiumSrcDir(), 'third_party', 'trace-viewer', 'trace_viewer')
+
 util.AddDirToPythonPath(
     util.GetChromiumSrcDir(),
     'third_party', 'trace-viewer', 'third_party', 'tvcm')
diff --git a/tools/telemetry/telemetry/web_components/viewer_unittest_data.html b/tools/telemetry/telemetry/web_components/viewer_unittest_data.html
index 69c860594c..ac0b3c9 100644
--- a/tools/telemetry/telemetry/web_components/viewer_unittest_data.html
+++ b/tools/telemetry/telemetry/web_components/viewer_unittest_data.html
@@ -4,15 +4,15 @@
 Use of this source code is governed by a BSD-style license that can be
 found in the LICENSE file.
 -->
-<link rel="import" href="/tvcm/ui.html">
+<link rel="import" href="/base/ui.html">
 <script>
 'use strict';
 
-tvcm.exportTo('telemetry.web_components', function() {
+tv.exportTo('telemetry.web_components', function() {
   /**
    * @constructor
    */
-  var SimpleViewer = tvcm.ui.define('x-results-viewer');
+  var SimpleViewer = tv.ui.define('x-results-viewer');
 
   SimpleViewer.prototype = {
     __proto__: HTMLUnknownElement.prototype,
diff --git a/tools/telemetry/telemetry/web_components/web_component_bootstrap.js b/tools/telemetry/telemetry/web_components/web_component_bootstrap.js
index eaee1094..a28ec69 100644
--- a/tools/telemetry/telemetry/web_components/web_component_bootstrap.js
+++ b/tools/telemetry/telemetry/web_components/web_component_bootstrap.js
@@ -11,7 +11,7 @@
   try {
     data = JSON.parse(componentDataScript.textContent);
   } catch (e) {
-    tvcm.showPanic('Could not load data', e.stack || e);
+    tv.showPanic('Could not load data', e.stack || e);
   }
   g_results = new $js_class_name;
   g_results.$data_binding_property = data;
diff --git a/tools/valgrind/chrome_tests.py b/tools/valgrind/chrome_tests.py
index d5f3d185..9b0b52fa 100755
--- a/tools/valgrind/chrome_tests.py
+++ b/tools/valgrind/chrome_tests.py
@@ -475,6 +475,9 @@
       return 0;
     return self.SimpleTest("chrome", "unit_tests")
 
+  def TestUIBaseUnit(self):
+    return self.SimpleTest("chrome", "ui_base_unittests")
+
   def TestUIUnit(self):
     return self.SimpleTest("chrome", "ui_unittests")
 
@@ -723,6 +726,7 @@
     "sync": TestSync,            "sync_unit_tests": TestSync,
     "sync_integration_tests": TestSyncIntegration,
     "sync_integration": TestSyncIntegration,
+    "ui_base_unit": TestUIBaseUnit,       "ui_base_unittests": TestUIBaseUnit,
     "ui_unit": TestUIUnit,       "ui_unittests": TestUIUnit,
     "unit": TestUnit,            "unit_tests": TestUnit,
     "url": TestURL,              "url_unittests": TestURL,
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index 70e0b8f..dd5ee292 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -4,25 +4,17 @@
 
 java_cpp_enum("java_enums_srcjar") {
   sources = [
+    "../base/page_transition_types.h",
     "../base/window_open_disposition.h",
     "../gfx/android/java_bitmap.h",
   ]
   outputs = [
     "org/chromium/ui/WindowOpenDisposition.java",
+    "org/chromium/ui/base/PageTransition.java",
     "org/chromium/ui/gfx/BitmapFormat.java",
   ]
 }
 
-java_cpp_template("page_transition_types_srcjar") {
-  package_name = "org/chromium/ui/base"
-  sources = [
-    "java/PageTransitionTypes.template",
-  ]
-  inputs = [
-    "../base/page_transition_types_list.h",
-  ]
-}
-
 java_strings_grd("ui_strings_grd") {
   grd_file = "java/strings/android_ui_strings.grd"
   outputs = [
@@ -91,6 +83,5 @@
   ]
   srcjar_deps = [
     ":java_enums_srcjar",
-    ":page_transition_types_srcjar",
   ]
 }
diff --git a/ui/android/java/PageTransitionTypes.template b/ui/android/java/PageTransitionTypes.template
deleted file mode 100644
index d2f12f8..0000000
--- a/ui/android/java/PageTransitionTypes.template
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2012 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.ui.base;
-
-public class PageTransitionTypes {
-#define PAGE_TRANSITION(label, value) public static final int \
-  PAGE_TRANSITION_ ## label = value;
-#include "ui/base/page_transition_types_list.h"
-#undef PAGE_TRANSITION
-}
diff --git a/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java b/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java
index 78f86c9..ca087dd 100644
--- a/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java
+++ b/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java
@@ -27,8 +27,8 @@
     @CalledByNative
     public static boolean isTablet(Context context) {
         if (sIsTablet == null) {
-            int minimumScreenWidthDp = context.getResources().getConfiguration().
-                    smallestScreenWidthDp;
+            int minimumScreenWidthDp = context.getResources().getConfiguration()
+                    .smallestScreenWidthDp;
             sIsTablet = minimumScreenWidthDp >= MINIMUM_TABLET_WIDTH_DP;
         }
         return sIsTablet;
diff --git a/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java b/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java
new file mode 100644
index 0000000..64488043
--- /dev/null
+++ b/ui/android/java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java
@@ -0,0 +1,98 @@
+// 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.
+
+package org.chromium.ui.widget;
+
+import android.content.Context;
+import android.text.SpannableString;
+import android.text.style.ClickableSpan;
+import android.util.AttributeSet;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.PopupMenu;
+import android.widget.TextView;
+
+/**
+ * ClickableSpan isn't accessible by default, so we create a simple subclass
+ * of TextView that addresses this by adding click and longpress handlers.
+ * If there's only one ClickableSpan, we activate it. If there's more than
+ * one, we pop up a Spinner to disambiguate.
+ */
+public class TextViewWithClickableSpans extends TextView {
+    public TextViewWithClickableSpans(Context context) {
+        super(context);
+        init();
+    }
+
+    public TextViewWithClickableSpans(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public TextViewWithClickableSpans(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    private void init() {
+        setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                handleClick();
+            }
+        });
+        setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                openDisambiguationMenu();
+                return true;
+            }
+        });
+    }
+
+    private ClickableSpan[] getClickableSpans() {
+        CharSequence text = getText();
+        if (!(text instanceof SpannableString)) return null;
+
+        SpannableString spannable = (SpannableString) text;
+        return spannable.getSpans(0, spannable.length(), ClickableSpan.class);
+    }
+
+    private void handleClick() {
+        ClickableSpan[] clickableSpans = getClickableSpans();
+        if (clickableSpans == null || clickableSpans.length == 0) {
+            return;
+        } else if (clickableSpans.length == 1) {
+            clickableSpans[0].onClick(this);
+        } else {
+            openDisambiguationMenu();
+        }
+    }
+
+    private void openDisambiguationMenu() {
+        ClickableSpan[] clickableSpans = getClickableSpans();
+        if (clickableSpans == null || clickableSpans.length == 0)
+            return;
+
+        SpannableString spannable = (SpannableString) getText();
+        PopupMenu popup = new PopupMenu(getContext(), this);
+        Menu menu = popup.getMenu();
+        for (final ClickableSpan clickableSpan : clickableSpans) {
+            CharSequence itemText = spannable.subSequence(
+                    spannable.getSpanStart(clickableSpan),
+                    spannable.getSpanEnd(clickableSpan));
+            MenuItem menuItem = menu.add(itemText);
+            menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+                @Override
+                public boolean onMenuItemClick(MenuItem menuItem) {
+                    clickableSpan.onClick(TextViewWithClickableSpans.this);
+                    return true;
+                }
+            });
+        }
+
+        popup.show();
+    }
+}
diff --git a/ui/android/ui_android.gyp b/ui/android/ui_android.gyp
index bb0d0f5..f26e51c6 100644
--- a/ui/android/ui_android.gyp
+++ b/ui/android/ui_android.gyp
@@ -18,14 +18,10 @@
     {
       'target_name': 'page_transition_types_java',
       'type': 'none',
-      'sources': [
-        'java/PageTransitionTypes.template',
-      ],
       'variables': {
-        'package_name': 'org/chromium/ui/base',
-        'template_deps': ['../base/page_transition_types_list.h'],
+        'source_file': '../base/page_transition_types.h',
       },
-      'includes': [ '../../build/android/java_cpp_template.gypi' ],
+      'includes': [ '../../build/android/java_cpp_enum.gypi' ],
     },
     {
       'target_name': 'window_open_disposition_java',
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn
index a5055e0e..6ebb5da 100644
--- a/ui/app_list/BUILD.gn
+++ b/ui/app_list/BUILD.gn
@@ -26,6 +26,8 @@
     "app_list_switches.h",
     "app_list_view_delegate.cc",
     "app_list_view_delegate.h",
+    "folder_image_source.cc",
+    "folder_image_source.h",
     "pagination_controller.cc",
     "pagination_controller.h",
     "pagination_model.cc",
diff --git a/ui/app_list/app_list.gyp b/ui/app_list/app_list.gyp
index 919a3f86..01c878c8 100644
--- a/ui/app_list/app_list.gyp
+++ b/ui/app_list/app_list.gyp
@@ -74,6 +74,8 @@
         'cocoa/item_drag_controller.mm',
         'cocoa/scroll_view_with_no_scrollbars.h',
         'cocoa/scroll_view_with_no_scrollbars.mm',
+        'folder_image_source.cc',
+        'folder_image_source.h',
         'pagination_controller.cc',
         'pagination_controller.h',
         'pagination_model.cc',
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc
index 0ce093a..dcd1c881 100644
--- a/ui/app_list/app_list_constants.cc
+++ b/ui/app_list/app_list_constants.cc
@@ -80,7 +80,7 @@
 const int kReorderDroppingCircleRadius = 35;
 
 // The padding around the outside of the experimental app list (top and sides).
-const int kExperimentalWindowPadding = 23;
+const int kExperimentalWindowPadding = 24;
 
 // Max items allowed in a folder.
 size_t kMaxFolderItems = 16;
diff --git a/ui/app_list/app_list_folder_item.cc b/ui/app_list/app_list_folder_item.cc
index 120d48e..a844be6 100644
--- a/ui/app_list/app_list_folder_item.cc
+++ b/ui/app_list/app_list_folder_item.cc
@@ -7,78 +7,11 @@
 #include "base/guid.h"
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/app_list_item_list.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/image/canvas_image_source.h"
-#include "ui/gfx/image/image_skia_operations.h"
+#include "ui/app_list/folder_image_source.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace app_list {
 
-namespace {
-
-const int kItemIconDimension = 16;
-
-// Generates the folder icon with the top 4 child item icons laid in 2x2 tile.
-class FolderImageSource : public gfx::CanvasImageSource {
- public:
-  typedef std::vector<gfx::ImageSkia> Icons;
-
-  FolderImageSource(const Icons& icons, const gfx::Size& size)
-      : gfx::CanvasImageSource(size, false),
-        icons_(icons),
-        size_(size) {
-    DCHECK(icons.size() <= kNumFolderTopItems);
-  }
-
-  ~FolderImageSource() override {}
-
- private:
-  void DrawIcon(gfx::Canvas* canvas,
-                const gfx::ImageSkia& icon,
-                const gfx::Size icon_size,
-                int x, int y) {
-    if (icon.isNull())
-      return;
-
-    gfx::ImageSkia resized(
-        gfx::ImageSkiaOperations::CreateResizedImage(
-            icon, skia::ImageOperations::RESIZE_BEST, icon_size));
-    canvas->DrawImageInt(resized, 0, 0, resized.width(), resized.height(),
-        x, y, resized.width(), resized.height(), true);
-  }
-
-  // gfx::CanvasImageSource overrides:
-  void Draw(gfx::Canvas* canvas) override {
-    // Draw folder circle.
-    gfx::Point center = gfx::Point(size().width() / 2 , size().height() / 2);
-    SkPaint paint;
-    paint.setStyle(SkPaint::kFill_Style);
-    paint.setAntiAlias(true);
-    paint.setColor(kFolderBubbleColor);
-    canvas->DrawCircle(center, size().width() / 2, paint);
-
-    if (icons_.size() == 0)
-      return;
-
-    // Draw top items' icons.
-    const gfx::Size item_icon_size =
-        gfx::Size(kItemIconDimension, kItemIconDimension);
-    Rects top_icon_bounds =
-        AppListFolderItem::GetTopIconsBounds(gfx::Rect(size()));
-
-    for (size_t i= 0; i < kNumFolderTopItems && i < icons_.size(); ++i) {
-      DrawIcon(canvas, icons_[i], item_icon_size,
-               top_icon_bounds[i].x(), top_icon_bounds[i].y());
-    }
-  }
-
-  Icons icons_;
-  gfx::Size size_;
-
-  DISALLOW_COPY_AND_ASSIGN(FolderImageSource);
-};
-
-}  // namespace
-
 AppListFolderItem::AppListFolderItem(const std::string& id,
                                      FolderType folder_type)
     : AppListItem(id),
@@ -115,14 +48,14 @@
     const gfx::Rect& folder_icon_bounds) {
   for (size_t i = 0; i < top_items_.size(); ++i) {
     if (item->id() == top_items_[i]->id()) {
-      Rects rects = AppListFolderItem::GetTopIconsBounds(folder_icon_bounds);
+      std::vector<gfx::Rect> rects =
+          FolderImageSource::GetTopIconsBounds(folder_icon_bounds);
       return rects[i];
     }
   }
 
   gfx::Rect target_rect(folder_icon_bounds);
-  target_rect.ClampToCenteredSize(
-      gfx::Size(kItemIconDimension, kItemIconDimension));
+  target_rect.ClampToCenteredSize(FolderImageSource::ItemIconSize());
   return target_rect;
 }
 
@@ -133,38 +66,6 @@
 // static
 const char AppListFolderItem::kItemType[] = "FolderItem";
 
-// static
-Rects AppListFolderItem::GetTopIconsBounds(
-    const gfx::Rect& folder_icon_bounds) {
-  const int delta_to_center = 1;
-  gfx::Point icon_center = folder_icon_bounds.CenterPoint();
-  Rects top_icon_bounds;
-
-  // Get the top left icon bounds.
-  int left_x = icon_center.x() - kItemIconDimension - delta_to_center;
-  int top_y = icon_center.y() - kItemIconDimension - delta_to_center;
-  gfx::Rect top_left(left_x, top_y, kItemIconDimension, kItemIconDimension);
-  top_icon_bounds.push_back(top_left);
-
-  // Get the top right icon bounds.
-  int right_x = icon_center.x() + delta_to_center;
-  gfx::Rect top_right(right_x, top_y, kItemIconDimension, kItemIconDimension);
-  top_icon_bounds.push_back(top_right);
-
-  // Get the bottom left icon bounds.
-  int bottom_y = icon_center.y() + delta_to_center;
-  gfx::Rect bottom_left(
-      left_x, bottom_y, kItemIconDimension, kItemIconDimension);
-  top_icon_bounds.push_back(bottom_left);
-
-  // Get the bottom right icon bounds.
-  gfx::Rect bottom_right(
-      right_x, bottom_y, kItemIconDimension, kItemIconDimension);
-  top_icon_bounds.push_back(bottom_right);
-
-  return top_icon_bounds;
-}
-
 const char* AppListFolderItem::GetItemType() const {
   return AppListFolderItem::kItemType;
 }
diff --git a/ui/app_list/app_list_folder_item.h b/ui/app_list/app_list_folder_item.h
index 9b51d4b78..cd572e7 100644
--- a/ui/app_list/app_list_folder_item.h
+++ b/ui/app_list/app_list_folder_item.h
@@ -12,14 +12,15 @@
 #include "ui/app_list/app_list_item.h"
 #include "ui/app_list/app_list_item_list_observer.h"
 #include "ui/app_list/app_list_item_observer.h"
-#include "ui/gfx/geometry/rect.h"
+
+namespace gfx {
+class Rect;
+}
 
 namespace app_list {
 
 class AppListItemList;
 
-typedef std::vector<gfx::Rect> Rects;
-
 // AppListFolderItem implements the model/controller for folders.
 class APP_LIST_EXPORT AppListFolderItem : public AppListItem,
                                           public AppListItemListObserver,
@@ -67,11 +68,6 @@
   void OnExtensionPreferenceChanged() override;
   bool CompareForTest(const AppListItem* other) const override;
 
-  // Calculates the top item icons' bounds inside |folder_icon_bounds|.
-  // Returns the bounds of top item icons in sequence of top left, top right,
-  // bottom left, bottom right.
-  static Rects GetTopIconsBounds(const gfx::Rect& folder_icon_bounds);
-
   // Returns an id for a new folder.
   static std::string GenerateId();
 
diff --git a/ui/app_list/folder_image_source.cc b/ui/app_list/folder_image_source.cc
new file mode 100644
index 0000000..ac3f108
--- /dev/null
+++ b/ui/app_list/folder_image_source.cc
@@ -0,0 +1,115 @@
+// 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 "ui/app_list/folder_image_source.h"
+
+#include "ui/app_list/app_list_constants.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/image/image_skia_operations.h"
+
+namespace {
+
+const int kItemIconDimension = 16;
+
+}  // namespace
+
+namespace app_list {
+
+FolderImageSource::FolderImageSource(const Icons& icons, const gfx::Size& size)
+    : gfx::CanvasImageSource(size, false), icons_(icons), size_(size) {
+  DCHECK(icons.size() <= kNumFolderTopItems);
+}
+
+FolderImageSource::~FolderImageSource() {
+}
+
+// static
+gfx::Size FolderImageSource::ItemIconSize() {
+  return gfx::Size(kItemIconDimension, kItemIconDimension);
+}
+
+// static
+std::vector<gfx::Rect> FolderImageSource::GetTopIconsBounds(
+    const gfx::Rect& folder_icon_bounds) {
+  const int delta_to_center = 1;
+  gfx::Point icon_center = folder_icon_bounds.CenterPoint();
+  std::vector<gfx::Rect> top_icon_bounds;
+
+  // Get the top left icon bounds.
+  int left_x = icon_center.x() - kItemIconDimension - delta_to_center;
+  int top_y = icon_center.y() - kItemIconDimension - delta_to_center;
+  gfx::Rect top_left(left_x, top_y, kItemIconDimension, kItemIconDimension);
+  top_icon_bounds.push_back(top_left);
+
+  // Get the top right icon bounds.
+  int right_x = icon_center.x() + delta_to_center;
+  gfx::Rect top_right(right_x, top_y, kItemIconDimension, kItemIconDimension);
+  top_icon_bounds.push_back(top_right);
+
+  // Get the bottom left icon bounds.
+  int bottom_y = icon_center.y() + delta_to_center;
+  gfx::Rect bottom_left(
+      left_x, bottom_y, kItemIconDimension, kItemIconDimension);
+  top_icon_bounds.push_back(bottom_left);
+
+  // Get the bottom right icon bounds.
+  gfx::Rect bottom_right(
+      right_x, bottom_y, kItemIconDimension, kItemIconDimension);
+  top_icon_bounds.push_back(bottom_right);
+
+  return top_icon_bounds;
+}
+
+void FolderImageSource::DrawIcon(gfx::Canvas* canvas,
+                                 const gfx::ImageSkia& icon,
+                                 const gfx::Size icon_size,
+                                 int x,
+                                 int y) {
+  if (icon.isNull())
+    return;
+
+  gfx::ImageSkia resized(gfx::ImageSkiaOperations::CreateResizedImage(
+      icon, skia::ImageOperations::RESIZE_BEST, icon_size));
+  canvas->DrawImageInt(resized,
+                       0,
+                       0,
+                       resized.width(),
+                       resized.height(),
+                       x,
+                       y,
+                       resized.width(),
+                       resized.height(),
+                       true);
+}
+
+void FolderImageSource::Draw(gfx::Canvas* canvas) {
+  // Draw folder circle.
+  gfx::Point center = gfx::Point(size().width() / 2, size().height() / 2);
+  SkPaint paint;
+  paint.setStyle(SkPaint::kFill_Style);
+  paint.setAntiAlias(true);
+  paint.setColor(kFolderBubbleColor);
+  canvas->DrawCircle(center, size().width() / 2, paint);
+
+  if (icons_.size() == 0)
+    return;
+
+  // Draw top items' icons.
+  const gfx::Size item_icon_size(ItemIconSize());
+  std::vector<gfx::Rect> top_icon_bounds = GetTopIconsBounds(gfx::Rect(size()));
+
+  for (size_t i = 0; i < kNumFolderTopItems && i < icons_.size(); ++i) {
+    DrawIcon(canvas,
+             icons_[i],
+             item_icon_size,
+             top_icon_bounds[i].x(),
+             top_icon_bounds[i].y());
+  }
+}
+
+}  // namespace app_list
diff --git a/ui/app_list/folder_image_source.h b/ui/app_list/folder_image_source.h
new file mode 100644
index 0000000..6bfba4c2
--- /dev/null
+++ b/ui/app_list/folder_image_source.h
@@ -0,0 +1,56 @@
+// 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 UI_APP_LIST_APP_LIST_FOLDER_IMAGE_SOURCE_H_
+#define UI_APP_LIST_APP_LIST_FOLDER_IMAGE_SOURCE_H_
+
+#include <vector>
+
+#include "ui/gfx/image/canvas_image_source.h"
+
+namespace gfx {
+class Canvas;
+class ImageSkia;
+class Rect;
+class Size;
+}
+
+namespace app_list {
+
+// Generates the folder icon with the top 4 child item icons laid in 2x2 tile.
+class FolderImageSource : public gfx::CanvasImageSource {
+ public:
+  typedef std::vector<gfx::ImageSkia> Icons;
+
+  FolderImageSource(const Icons& icons, const gfx::Size& size);
+  ~FolderImageSource() override;
+
+  // Gets the size of a small app icon inside the folder icon.
+  static gfx::Size ItemIconSize();
+
+  // Calculates the top item icons' bounds inside |folder_icon_bounds|.
+  // Returns the bounds of top item icons in sequence of top left, top right,
+  // bottom left, bottom right.
+  static std::vector<gfx::Rect> GetTopIconsBounds(
+      const gfx::Rect& folder_icon_bounds);
+
+ private:
+  void DrawIcon(gfx::Canvas* canvas,
+                const gfx::ImageSkia& icon,
+                const gfx::Size icon_size,
+                int x,
+                int y);
+
+  // gfx::CanvasImageSource overrides:
+  void Draw(gfx::Canvas* canvas) override;
+
+  Icons icons_;
+  gfx::Size size_;
+
+  DISALLOW_COPY_AND_ASSIGN(FolderImageSource);
+};
+
+}  // namespace app_list
+
+#endif  // UI_APP_LIST_APP_LIST_FOLDER_ITEM_H_
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index b7e08b1c..dbe6a3d7 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -36,9 +36,6 @@
 
 namespace {
 
-// Border padding space around the bubble contents.
-const int kPadding = 1;
-
 // The maximum allowed time to wait for icon loading in milliseconds.
 const int kMaxIconLoadingWaitTimeInMs = 50;
 
@@ -106,18 +103,18 @@
 ////////////////////////////////////////////////////////////////////////////////
 // AppListMainView:
 
-AppListMainView::AppListMainView(AppListViewDelegate* delegate,
-                                 int initial_apps_page,
-                                 gfx::NativeView parent)
+AppListMainView::AppListMainView(AppListViewDelegate* delegate)
     : delegate_(delegate),
       model_(delegate->GetModel()),
       search_box_view_(NULL),
       contents_view_(NULL),
       contents_switcher_view_(NULL),
       weak_ptr_factory_(this) {
-  SetBorder(
-      views::Border::CreateEmptyBorder(kPadding, kPadding, kPadding, kPadding));
-  SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
+  SetLayoutManager(
+      new views::BoxLayout(views::BoxLayout::kVertical,
+                           0,
+                           0,
+                           switches::IsExperimentalAppListEnabled() ? 0 : 1));
 
   search_box_view_ = new SearchBoxView(this, delegate);
   views::View* container = new SearchBoxContainerView(this, search_box_view_);
@@ -129,6 +126,13 @@
                                          kExperimentalWindowPadding));
   }
   AddChildView(container);
+}
+
+AppListMainView::~AppListMainView() {
+  pending_icon_loaders_.clear();
+}
+
+void AppListMainView::Init(gfx::NativeView parent, int initial_apps_page) {
   AddContentsViews();
 
   // Switch the apps grid view to the specified page.
@@ -160,10 +164,6 @@
   delegate_->StartSearch();
 }
 
-AppListMainView::~AppListMainView() {
-  pending_icon_loaders_.clear();
-}
-
 void AppListMainView::ShowAppListWhenReady() {
   if (pending_icon_loaders_.empty()) {
     icon_loading_wait_timer_.Stop();
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h
index 2abe961..09df64c 100644
--- a/ui/app_list/views/app_list_main_view.h
+++ b/ui/app_list/views/app_list_main_view.h
@@ -39,11 +39,11 @@
                                         public SearchResultListViewDelegate {
  public:
   // Takes ownership of |delegate|.
-  explicit AppListMainView(AppListViewDelegate* delegate,
-                           int initial_apps_page,
-                           gfx::NativeView parent);
+  explicit AppListMainView(AppListViewDelegate* delegate);
   virtual ~AppListMainView();
 
+  void Init(gfx::NativeView parent, int initial_apps_page);
+
   void ShowAppListWhenReady();
 
   void ResetForShow();
diff --git a/ui/app_list/views/app_list_main_view_unittest.cc b/ui/app_list/views/app_list_main_view_unittest.cc
index 08cd351..8f744d10 100644
--- a/ui/app_list/views/app_list_main_view_unittest.cc
+++ b/ui/app_list/views/app_list_main_view_unittest.cc
@@ -76,9 +76,10 @@
     // In Ash, the third argument is a container aura::Window, but it is always
     // NULL on Windows, and not needed for tests. It is only used to determine
     // the scale factor for preloading icons.
-    main_view_ = new AppListMainView(delegate_.get(), 0, NULL);
+    main_view_ = new AppListMainView(delegate_.get());
     main_view_->SetPaintToLayer(true);
     main_view_->model()->SetFoldersEnabled(true);
+    main_view_->Init(NULL, 0);
 
     widget_ = new views::Widget;
     views::Widget::InitParams params =
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index c6b88965..112338f6 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -327,12 +327,12 @@
                                        const gfx::Vector2d& anchor_offset) {
   base::Time start_time = base::Time::Now();
 
-  app_list_main_view_ =
-      new AppListMainView(delegate_, initial_apps_page, parent);
+  app_list_main_view_ = new AppListMainView(delegate_);
   AddChildView(app_list_main_view_);
   app_list_main_view_->SetPaintToLayer(true);
   app_list_main_view_->SetFillsBoundsOpaquely(false);
   app_list_main_view_->layer()->SetMasksToBounds(true);
+  app_list_main_view_->Init(parent, initial_apps_page);
 
   // Speech recognition is available only when the start page exists.
   if (delegate_ && delegate_->IsSpeechRecognitionEnabled()) {
diff --git a/ui/app_list/views/apps_container_view.cc b/ui/app_list/views/apps_container_view.cc
index b026a3e..52c1051c 100644
--- a/ui/app_list/views/apps_container_view.cc
+++ b/ui/app_list/views/apps_container_view.cc
@@ -11,6 +11,7 @@
 #include "ui/app_list/app_list_constants.h"
 #include "ui/app_list/app_list_folder_item.h"
 #include "ui/app_list/app_list_switches.h"
+#include "ui/app_list/folder_image_source.h"
 #include "ui/app_list/views/app_list_folder_view.h"
 #include "ui/app_list/views/app_list_item_view.h"
 #include "ui/app_list/views/app_list_main_view.h"
@@ -194,7 +195,7 @@
   Layout();
 }
 
-Rects AppsContainerView::GetTopItemIconBoundsInActiveFolder() {
+std::vector<gfx::Rect> AppsContainerView::GetTopItemIconBoundsInActiveFolder() {
   // Get the active folder's icon bounds relative to AppsContainerView.
   AppListItemView* folder_item_view =
       apps_grid_view_->activated_folder_item_view();
@@ -202,7 +203,7 @@
       folder_item_view->GetIconBounds());
   gfx::Rect to_container = apps_grid_view_->ConvertRectToParent(to_grid_view);
 
-  return AppListFolderItem::GetTopIconsBounds(to_container);
+  return FolderImageSource::GetTopIconsBounds(to_container);
 }
 
 void AppsContainerView::CreateViewsForFolderTopItemsAnimation(
diff --git a/ui/app_list/views/apps_container_view.h b/ui/app_list/views/apps_container_view.h
index 895d2e4..1f4c28d3 100644
--- a/ui/app_list/views/apps_container_view.h
+++ b/ui/app_list/views/apps_container_view.h
@@ -11,6 +11,10 @@
 #include "ui/app_list/views/top_icon_animation_view.h"
 #include "ui/views/view.h"
 
+namespace gfx {
+class Rect;
+}
+
 namespace app_list {
 
 class AppsGridView;
@@ -85,7 +89,7 @@
   // is relative to AppsContainerView.
   // Returns the bounds of top items' icon in sequence of top left, top right,
   // bottom left, bottom right.
-  Rects GetTopItemIconBoundsInActiveFolder();
+  std::vector<gfx::Rect> GetTopItemIconBoundsInActiveFolder();
 
   // Creates the transitional views for animating the top items in the folder
   // when opening or closing a folder.
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc
index 2c277a5e..6c2e4f1 100644
--- a/ui/app_list/views/apps_grid_view.cc
+++ b/ui/app_list/views/apps_grid_view.cc
@@ -60,8 +60,9 @@
 const int kDragBufferPx = 20;
 
 // Padding space in pixels for fixed layout.
-const int kLeftRightPadding = 23;
 const int kTopPadding = 1;
+const int kBottomPadding = 1;
+const int kLeftRightPadding = 24;
 
 // Padding space in pixels between pages.
 const int kPagePadding = 40;
@@ -71,7 +72,7 @@
 const int kPreferredTileHeight = 98;
 
 const int kExperimentalPreferredTileWidth = 90;
-const int kExperimentalPrefferedTileHeight = 90;
+const int kExperimentalPreferredTileHeight = 90;
 
 // Padding on each side of a tile.
 const int kExperimentalTileLeftRightPadding = 15;
@@ -106,7 +107,7 @@
 gfx::Size GetTileViewSize() {
   return switches::IsExperimentalAppListEnabled()
              ? gfx::Size(kExperimentalPreferredTileWidth,
-                         kExperimentalPrefferedTileHeight)
+                         kExperimentalPreferredTileHeight)
              : gfx::Size(kPreferredTileWidth, kPreferredTileHeight);
 }
 
@@ -424,11 +425,15 @@
   cols_ = cols;
   rows_per_page_ = rows_per_page;
 
-  SetBorder(views::Border::CreateEmptyBorder(
-      switches::IsExperimentalAppListEnabled() ? 0 : kTopPadding,
-      kLeftRightPadding,
-      0,
-      kLeftRightPadding));
+  if (switches::IsExperimentalAppListEnabled()) {
+    SetBorder(views::Border::CreateEmptyBorder(0,
+                                               kExperimentalWindowPadding,
+                                               kBottomPadding,
+                                               kExperimentalWindowPadding));
+  } else {
+    SetBorder(views::Border::CreateEmptyBorder(
+        kTopPadding, kLeftRightPadding, kBottomPadding, kLeftRightPadding));
+  }
 }
 
 void AppsGridView::ResetForShowApps() {
diff --git a/ui/aura/test/test_screen.cc b/ui/aura/test/test_screen.cc
index 63e44b9..1b0f9ff 100644
--- a/ui/aura/test/test_screen.cc
+++ b/ui/aura/test/test_screen.cc
@@ -109,10 +109,6 @@
   return ui_scale;
 }
 
-bool TestScreen::IsDIPEnabled() {
-  return true;
-}
-
 void TestScreen::OnWindowBoundsChanged(
     Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) {
   DCHECK_EQ(host_->window(), window);
diff --git a/ui/aura/test/test_screen.h b/ui/aura/test/test_screen.h
index 7b1f98b..c7a01a6b 100644
--- a/ui/aura/test/test_screen.h
+++ b/ui/aura/test/test_screen.h
@@ -49,7 +49,6 @@
   virtual void OnWindowDestroying(Window* window) override;
 
   // gfx::Screen overrides:
-  virtual bool IsDIPEnabled() override;
   virtual gfx::Point GetCursorScreenPoint() override;
   virtual gfx::NativeWindow GetWindowUnderCursor() override;
   virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point)
diff --git a/ui/aura/test/window_test_api.cc b/ui/aura/test/window_test_api.cc
index 0ea3e18a..86b3370b 100644
--- a/ui/aura/test/window_test_api.cc
+++ b/ui/aura/test/window_test_api.cc
@@ -5,6 +5,8 @@
 #include "ui/aura/test/window_test_api.h"
 
 #include "ui/aura/window.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/aura/window_tree_host.h"
 
 namespace aura {
 namespace test {
@@ -17,7 +19,12 @@
 }
 
 bool WindowTestApi::ContainsMouse() const {
-  return window_->ContainsMouse();
+  if (!window_->IsVisible())
+    return false;
+  WindowTreeHost* host = window_->GetHost();
+  return host &&
+         window_->ContainsPointInRoot(
+             host->dispatcher()->GetLastMouseLocationInRoot());
 }
 
 }  // namespace test
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index a6c3226f45..4d9cec70 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -1445,16 +1445,6 @@
 #endif
 }
 
-bool Window::ContainsMouse() {
-  bool contains_mouse = false;
-  if (IsVisible()) {
-    WindowTreeHost* host = GetHost();
-    contains_mouse = host &&
-        ContainsPointInRoot(host->dispatcher()->GetLastMouseLocationInRoot());
-  }
-  return contains_mouse;
-}
-
 const Window* Window::GetAncestorWithLayer(gfx::Vector2d* offset) const {
   for (const aura::Window* window = this; window; window = window->parent()) {
     if (window->layer())
diff --git a/ui/aura/window.h b/ui/aura/window.h
index 95f6e7d..4f597eb8 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -470,9 +470,6 @@
   // Updates the layer name based on the window's name and id.
   void UpdateLayerName();
 
-  // Returns true if the mouse is currently within our bounds.
-  bool ContainsMouse();
-
   // Returns the first ancestor (starting at |this|) with a layer. |offset| is
   // set to the offset from |this| to the first ancestor with a layer. |offset|
   // may be NULL.
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc
index 0b1103d..eadda03 100644
--- a/ui/aura/window_event_dispatcher.cc
+++ b/ui/aura/window_event_dispatcher.cc
@@ -381,7 +381,8 @@
     if (details.dispatcher_destroyed)
       return;
 
-    old_capture->delegate()->OnCaptureLost();
+    if (!details.target_destroyed)
+      old_capture->delegate()->OnCaptureLost();
   }
 
   if (new_capture) {
diff --git a/ui/aura/window_event_dispatcher_unittest.cc b/ui/aura/window_event_dispatcher_unittest.cc
index 6822101..e5db027 100644
--- a/ui/aura/window_event_dispatcher_unittest.cc
+++ b/ui/aura/window_event_dispatcher_unittest.cc
@@ -2079,6 +2079,28 @@
             Env::GetInstance()->last_mouse_location().ToString());
 }
 
+// Tests that the window which has capture can get destroyed as a result of
+// ui::ET_MOUSE_CAPTURE_CHANGED event dispatched in
+// WindowEventDispatcher::UpdateCapture without causing a "use after free".
+TEST_F(WindowEventDispatcherTest, DestroyWindowOnCaptureChanged) {
+  SelfDestructDelegate delegate;
+  scoped_ptr<aura::Window> window_first(CreateTestWindowWithDelegate(
+      &delegate, 1, gfx::Rect(20, 10, 10, 20), root_window()));
+  Window* window_first_raw = window_first.get();
+  window_first->Show();
+  window_first->SetCapture();
+  delegate.set_window(window_first.Pass());
+  EXPECT_TRUE(delegate.has_window());
+
+  scoped_ptr<aura::Window> window_second(
+      test::CreateTestWindowWithId(2, root_window()));
+  window_second->Show();
+
+  client::CaptureDelegate* capture_delegate = host()->dispatcher();
+  capture_delegate->UpdateCapture(window_first_raw, window_second.get());
+  EXPECT_FALSE(delegate.has_window());
+}
+
 class StaticFocusClient : public client::FocusClient {
  public:
   explicit StaticFocusClient(Window* focused)
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 45da06f4..4e9515a 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -238,8 +238,6 @@
     "win/accessibility_misc_utils.cc",
     "win/accessibility_misc_utils.h",
     "win/atl_module.h",
-    "win/dpi_setup.cc",
-    "win/dpi_setup.h",
     "win/foreground_helper.cc",
     "win/foreground_helper.h",
     "win/hidden_window.cc",
diff --git a/ui/base/ime/OWNERS b/ui/base/ime/OWNERS
index bc96702..6cde11e 100644
--- a/ui/base/ime/OWNERS
+++ b/ui/base/ime/OWNERS
@@ -1,5 +1,6 @@
 # primary reviewer.
 yukishiino@chromium.org
+shuchen@chromium.org
 
 # backup reviewers.
 komatsu@chromium.org
diff --git a/ui/base/ime/chromeos/ime_bridge.h b/ui/base/ime/chromeos/ime_bridge.h
index a4b5fefd..ff7d4fa 100644
--- a/ui/base/ime/chromeos/ime_bridge.h
+++ b/ui/base/ime/chromeos/ime_bridge.h
@@ -50,8 +50,8 @@
   // A type of each member is based on the html spec, but InputContext can be
   // used to specify about a non html text field like Omnibox.
   struct InputContext {
-    InputContext(ui::TextInputType type_, ui::TextInputMode mode_) :
-      type(type_), mode(mode_) {}
+    InputContext(ui::TextInputType type_, ui::TextInputMode mode_, int flags_) :
+      type(type_), mode(mode_), flags(flags_) {}
 
     // An attribute of the field defined at
     // http://www.w3.org/TR/html401/interact/forms.html#input-control-types.
@@ -61,6 +61,9 @@
     //  association-of-controls-and-forms.html#input-modalities
     //  :-the-inputmode-attribute.
     ui::TextInputMode mode;
+    // An antribute to indicate the flags for web input fields. Please refer to
+    // WebTextInputType.
+    int flags;
   };
 
   virtual ~IMEEngineHandlerInterface() {}
diff --git a/ui/base/ime/chromeos/ime_keymap.cc b/ui/base/ime/chromeos/ime_keymap.cc
index ec3513ab..d214321 100644
--- a/ui/base/ime/chromeos/ime_keymap.cc
+++ b/ui/base/ime/chromeos/ime_keymap.cc
@@ -121,8 +121,8 @@
   {VKEY_SCROLL, "ScrollLock"},
   {VKEY_LSHIFT, "ShiftLeft"},
   {VKEY_RSHIFT, "ShiftRight"},
-  {VKEY_LCONTROL, "CtrlLeft"},
-  {VKEY_RCONTROL, "CtrlRight"},
+  {VKEY_LCONTROL, "ControlLeft"},
+  {VKEY_RCONTROL, "ControlRight"},
   {VKEY_LMENU, "AltLeft"},
   {VKEY_RMENU, "AltRight"},
   {VKEY_BROWSER_BACK, "BrowserBack"},
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.cc b/ui/base/ime/chromeos/mock_ime_engine_handler.cc
index ca855a0..bc0ff599 100644
--- a/ui/base/ime/chromeos/mock_ime_engine_handler.cc
+++ b/ui/base/ime/chromeos/mock_ime_engine_handler.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "ui/base/ime/chromeos/mock_ime_engine_handler.h"
+#include "ui/base/ime/text_input_flags.h"
 
 namespace chromeos {
 
@@ -13,7 +14,8 @@
       process_key_event_call_count_(0),
       reset_call_count_(0),
       last_text_input_context_(ui::TEXT_INPUT_TYPE_NONE,
-                               ui::TEXT_INPUT_MODE_DEFAULT),
+                               ui::TEXT_INPUT_MODE_DEFAULT,
+                               ui::TEXT_INPUT_FLAG_NONE),
       last_set_surrounding_cursor_pos_(0),
       last_set_surrounding_anchor_pos_(0) {
 }
diff --git a/ui/base/ime/dummy_input_method.cc b/ui/base/ime/dummy_input_method.cc
index a12bbfc..700e793 100644
--- a/ui/base/ime/dummy_input_method.cc
+++ b/ui/base/ime/dummy_input_method.cc
@@ -71,6 +71,10 @@
   return TEXT_INPUT_MODE_DEFAULT;
 }
 
+int DummyInputMethod::GetTextInputFlags() const {
+  return 0;
+}
+
 bool DummyInputMethod::CanComposeInline() const {
   return true;
 }
diff --git a/ui/base/ime/dummy_input_method.h b/ui/base/ime/dummy_input_method.h
index 20a019b..edad7b8 100644
--- a/ui/base/ime/dummy_input_method.h
+++ b/ui/base/ime/dummy_input_method.h
@@ -35,6 +35,7 @@
   bool IsActive() override;
   TextInputType GetTextInputType() const override;
   TextInputMode GetTextInputMode() const override;
+  int GetTextInputFlags() const override;
   bool CanComposeInline() const override;
   bool IsCandidatePopupOpen() const override;
   void ShowImeIfNeeded() override;
diff --git a/ui/base/ime/dummy_text_input_client.cc b/ui/base/ime/dummy_text_input_client.cc
index cea49c6..3adb420 100644
--- a/ui/base/ime/dummy_text_input_client.cc
+++ b/ui/base/ime/dummy_text_input_client.cc
@@ -44,6 +44,10 @@
   return TEXT_INPUT_MODE_DEFAULT;
 }
 
+int DummyTextInputClient::GetTextInputFlags() const {
+  return 0;
+}
+
 bool DummyTextInputClient::CanComposeInline() const {
   return false;
 }
diff --git a/ui/base/ime/dummy_text_input_client.h b/ui/base/ime/dummy_text_input_client.h
index 898ffa2..32dd857 100644
--- a/ui/base/ime/dummy_text_input_client.h
+++ b/ui/base/ime/dummy_text_input_client.h
@@ -25,6 +25,7 @@
   gfx::NativeWindow GetAttachedWindow() const override;
   TextInputType GetTextInputType() const override;
   TextInputMode GetTextInputMode() const override;
+  int GetTextInputFlags() const override;
   bool CanComposeInline() const override;
   gfx::Rect GetCaretBounds() const override;
   bool GetCompositionCharacterBounds(uint32 index,
diff --git a/ui/base/ime/input_method.h b/ui/base/ime/input_method.h
index 462e0b0..164b1f1 100644
--- a/ui/base/ime/input_method.h
+++ b/ui/base/ime/input_method.h
@@ -146,6 +146,10 @@
   // ui::TEXT_INPUT_TYPE_DEFAULT if there is no focused client.
   virtual TextInputMode GetTextInputMode() const = 0;
 
+  // Gets the text input flags of the focused text input client. Returns
+  // 0 if there is no focused client.
+  virtual int GetTextInputFlags() const = 0;
+
   // Checks if the focused text input client supports inline composition.
   virtual bool CanComposeInline() const = 0;
 
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc
index ed34767..0dca378 100644
--- a/ui/base/ime/input_method_base.cc
+++ b/ui/base/ime/input_method_base.cc
@@ -80,6 +80,11 @@
   return client ? client->GetTextInputMode() : TEXT_INPUT_MODE_DEFAULT;
 }
 
+int InputMethodBase::GetTextInputFlags() const {
+  TextInputClient* client = GetTextInputClient();
+  return client ? client->GetTextInputFlags() : 0;
+}
+
 bool InputMethodBase::CanComposeInline() const {
   TextInputClient* client = GetTextInputClient();
   return client ? client->CanComposeInline() : true;
@@ -126,6 +131,12 @@
                     OnTextInputStateChanged(client));
 }
 
+void InputMethodBase::NotifyTextInputCaretBoundsChanged(
+    const TextInputClient* client) {
+  FOR_EACH_OBSERVER(
+      InputMethodObserver, observer_list_, OnCaretBoundsChanged(client));
+}
+
 void InputMethodBase::SetFocusedTextInputClientInternal(
     TextInputClient* client) {
   if (switches::IsTextInputFocusManagerEnabled())
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h
index 8c6dd258..4d732cdd 100644
--- a/ui/base/ime/input_method_base.h
+++ b/ui/base/ime/input_method_base.h
@@ -49,6 +49,7 @@
 
   TextInputType GetTextInputType() const override;
   TextInputMode GetTextInputMode() const override;
+  int GetTextInputFlags() const override;
   bool CanComposeInline() const override;
   void ShowImeIfNeeded() override;
 
@@ -81,6 +82,10 @@
   // Convenience method to notify all observers of TextInputClient changes.
   void NotifyTextInputStateChanged(const TextInputClient* client);
 
+  // Convenience method to notify all observers of CaretBounds changes on
+  // |client| which is the text input client with focus.
+  void NotifyTextInputCaretBoundsChanged(const TextInputClient* client);
+
   // Interface for for signalling candidate window events.
   // See also *Callback functions below. To avoid reentrancy issue that
   // TextInputClient manipulates IME state during even handling, these methods
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc
index 6930968f..37a9c3c 100644
--- a/ui/base/ime/input_method_chromeos.cc
+++ b/ui/base/ime/input_method_chromeos.cc
@@ -123,7 +123,7 @@
   // normal input field (not a password field).
   // Note: We need to send the key event to ibus even if the |context_| is not
   // enabled, so that ibus can have a chance to enable the |context_|.
-  if (!IsInputFieldFocused() || !GetEngine()) {
+  if (!IsNonPasswordInputFieldFocused() || !GetEngine()) {
     if (event.type() == ET_KEY_PRESSED) {
       if (ExecuteCharacterComposer(event)) {
         // Treating as PostIME event if character composer handles key event and
@@ -167,7 +167,7 @@
     // The focus in to or out from password field should also notify engine.
     engine->FocusOut();
     chromeos::IMEEngineHandlerInterface::InputContext context(
-        GetTextInputType(), GetTextInputMode());
+        GetTextInputType(), GetTextInputMode(), GetTextInputFlags());
     engine->FocusIn(context);
   }
 
@@ -178,6 +178,11 @@
   if (!IsInputFieldFocused() || !IsTextInputClientFocused(client))
     return;
 
+  NotifyTextInputCaretBoundsChanged(client);
+
+  if (!IsNonPasswordInputFieldFocused())
+    return;
+
   // The current text input type should not be NONE if |context_| is focused.
   DCHECK(!IsTextInputTypeNone());
   const gfx::Rect rect = GetTextInputClient()->GetCaretBounds();
@@ -230,7 +235,7 @@
 }
 
 void InputMethodChromeOS::CancelComposition(const TextInputClient* client) {
-  if (IsInputFieldFocused() && IsTextInputClientFocused(client))
+  if (IsNonPasswordInputFieldFocused() && IsTextInputClientFocused(client))
     ResetContext();
 }
 
@@ -271,7 +276,7 @@
 
   if (GetEngine()) {
     chromeos::IMEEngineHandlerInterface::InputContext context(
-        GetTextInputType(), GetTextInputMode());
+        GetTextInputType(), GetTextInputMode(), GetTextInputFlags());
     GetEngine()->FocusIn(context);
   }
 }
@@ -285,7 +290,7 @@
 }
 
 void InputMethodChromeOS::ResetContext() {
-  if (!IsInputFieldFocused() || !GetTextInputClient())
+  if (!IsNonPasswordInputFieldFocused() || !GetTextInputClient())
     return;
 
   DCHECK(system_toplevel_window_focused());
@@ -319,7 +324,7 @@
   chromeos::IMECandidateWindowHandlerInterface* candidate_window =
       chromeos::IMEBridge::Get()->GetCandidateWindowHandler();
   if (candidate_window)
-    candidate_window->FocusStateChanged(IsInputFieldFocused());
+    candidate_window->FocusStateChanged(IsNonPasswordInputFieldFocused());
 
   chromeos::IMEBridge::Get()->SetCurrentTextInputType(GetTextInputType());
 
@@ -654,9 +659,13 @@
   }
 }
 
-bool InputMethodChromeOS::IsInputFieldFocused() {
+bool InputMethodChromeOS::IsNonPasswordInputFieldFocused() {
   TextInputType type = GetTextInputType();
   return (type != TEXT_INPUT_TYPE_NONE) && (type != TEXT_INPUT_TYPE_PASSWORD);
 }
 
+bool InputMethodChromeOS::IsInputFieldFocused() {
+  return GetTextInputType() != TEXT_INPUT_TYPE_NONE;
+}
+
 }  // namespace ui
diff --git a/ui/base/ime/input_method_chromeos.h b/ui/base/ime/input_method_chromeos.h
index a09cd3d..1022b04e 100644
--- a/ui/base/ime/input_method_chromeos.h
+++ b/ui/base/ime/input_method_chromeos.h
@@ -112,8 +112,10 @@
   // Callback function for IMEEngineHandlerInterface::ProcessKeyEvent.
   void ProcessKeyEventDone(uint32 id, ui::KeyEvent* event, bool is_handled);
 
-  // Returns whether an input field is focused. Note that password field is not
-  // considered as an input field.
+  // Returns whether an non-password input field is focused.
+  bool IsNonPasswordInputFieldFocused();
+
+  // Returns true if an text input field is focused.
   bool IsInputFieldFocused();
 
   // All pending key events. Note: we do not own these object, we just save
diff --git a/ui/base/ime/input_method_chromeos_unittest.cc b/ui/base/ime/input_method_chromeos_unittest.cc
index 5071872..3e7f20b 100644
--- a/ui/base/ime/input_method_chromeos_unittest.cc
+++ b/ui/base/ime/input_method_chromeos_unittest.cc
@@ -279,6 +279,9 @@
   virtual TextInputMode GetTextInputMode() const override {
     return input_mode_;
   }
+  virtual int GetTextInputFlags() const override {
+    return 0;
+  }
   virtual bool CanComposeInline() const override {
     return can_compose_inline_;
   }
diff --git a/ui/base/ime/mock_input_method.cc b/ui/base/ime/mock_input_method.cc
index 5ffc76f..fb1e6ba 100644
--- a/ui/base/ime/mock_input_method.cc
+++ b/ui/base/ime/mock_input_method.cc
@@ -102,6 +102,10 @@
   return TEXT_INPUT_MODE_DEFAULT;
 }
 
+int MockInputMethod::GetTextInputFlags() const {
+  return 0;
+}
+
 bool MockInputMethod::CanComposeInline() const {
   return true;
 }
diff --git a/ui/base/ime/mock_input_method.h b/ui/base/ime/mock_input_method.h
index 67a2029..b88787c7 100644
--- a/ui/base/ime/mock_input_method.h
+++ b/ui/base/ime/mock_input_method.h
@@ -47,6 +47,7 @@
   bool IsActive() override;
   TextInputType GetTextInputType() const override;
   TextInputMode GetTextInputMode() const override;
+  int GetTextInputFlags() const override;
   bool CanComposeInline() const override;
   bool IsCandidatePopupOpen() const override;
   void ShowImeIfNeeded() override;
diff --git a/ui/base/ime/remote_input_method_win.cc b/ui/base/ime/remote_input_method_win.cc
index f74dcde6..f3ed001 100644
--- a/ui/base/ime/remote_input_method_win.cc
+++ b/ui/base/ime/remote_input_method_win.cc
@@ -270,6 +270,11 @@
                               : TEXT_INPUT_MODE_DEFAULT;
   }
 
+  virtual int GetTextInputFlags() const override {
+    return text_input_client_ ? text_input_client_->GetTextInputFlags()
+                              : 0;
+  }
+
   virtual bool CanComposeInline() const override {
     return text_input_client_ ? text_input_client_->CanComposeInline() : true;
   }
diff --git a/ui/base/ime/text_input_client.h b/ui/base/ime/text_input_client.h
index ff1242f..582a0d3 100644
--- a/ui/base/ime/text_input_client.h
+++ b/ui/base/ime/text_input_client.h
@@ -68,6 +68,11 @@
   // TEXT_INPUT_MODE_DEFAULT at runtime.
   virtual ui::TextInputMode GetTextInputMode() const = 0;
 
+  // Returns the current text input flags, which is a bit map of
+  // WebTextInputType defined in blink. This is valid only for web input fileds;
+  // it will return TEXT_INPUT_FLAG_NONE for native input fields.
+  virtual int GetTextInputFlags() const = 0;
+
   // Returns if the client supports inline composition currently.
   virtual bool CanComposeInline() const = 0;
 
diff --git a/ui/base/ime/text_input_flags.h b/ui/base/ime/text_input_flags.h
new file mode 100644
index 0000000..3e83a70
--- /dev/null
+++ b/ui/base/ime/text_input_flags.h
@@ -0,0 +1,24 @@
+// 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 UI_BASE_IME_TEXT_INPUT_FLAGS_H_
+#define UI_BASE_IME_TEXT_INPUT_FLAGS_H_
+
+namespace ui {
+
+// Intentionally keep in sync with blink::WebTextInputFlags defined in:
+// third_party/WebKit/public/web/WebTextInputType.h
+enum TextInputFlags {
+  TEXT_INPUT_FLAG_NONE = 0,
+  TEXT_INPUT_FLAG_AUTOCOMPLETE_ON = 1 << 0,
+  TEXT_INPUT_FLAG_AUTOCOMPLETE_OFF = 1 << 1,
+  TEXT_INPUT_FLAG_AUTOCORRECT_ON = 1 << 2,
+  TEXT_INPUT_FLAG_AUTOCORRECT_OFF = 1 << 3,
+  TEXT_INPUT_FLAG_SPELLCHECK_ON = 1 << 4,
+  TEXT_INPUT_FLAG_SPELLCHECK_OFF = 1 << 5
+};
+
+}  // namespace ui
+
+#endif  // UI_BASE_IME_TEXT_INPUT_FLAGS_H_
diff --git a/ui/base/l10n/l10n_util.cc b/ui/base/l10n/l10n_util.cc
index bcc070a..6768adbec 100644
--- a/ui/base/l10n/l10n_util.cc
+++ b/ui/base/l10n/l10n_util.cc
@@ -189,6 +189,7 @@
 bool IsDuplicateName(const std::string& locale_name) {
   static const char* const kDuplicateNames[] = {
     "en",
+    "en_001",
     "pt",
     "zh",
     "zh_hans_cn",
diff --git a/ui/base/layout.cc b/ui/base/layout.cc
index aa3aecf..0c3802b 100644
--- a/ui/base/layout.cc
+++ b/ui/base/layout.cc
@@ -84,10 +84,10 @@
 
 float GetImageScale(ScaleFactor scale_factor) {
 #if defined(OS_WIN)
-  if (gfx::IsHighDPIEnabled())
-    return gfx::win::GetDeviceScaleFactor();
-#endif
+  return gfx::GetDPIScale();
+#else
   return GetScaleForScaleFactor(scale_factor);
+#endif
 }
 
 float GetScaleForScaleFactor(ScaleFactor scale_factor) {
@@ -122,11 +122,8 @@
 #if !defined(OS_MACOSX)
 float GetScaleFactorForNativeView(gfx::NativeView view) {
   gfx::Screen* screen = gfx::Screen::GetScreenFor(view);
-  if (screen->IsDIPEnabled()) {
-    gfx::Display display = screen->GetDisplayNearestWindow(view);
-    return display.device_scale_factor();
-  }
-  return 1.0f;
+  gfx::Display display = screen->GetDisplayNearestWindow(view);
+  return display.device_scale_factor();
 }
 #endif  // !defined(OS_MACOSX)
 
diff --git a/ui/base/page_transition_types.h b/ui/base/page_transition_types.h
index 3ca67c5..4e54f92 100644
--- a/ui/base/page_transition_types.h
+++ b/ui/base/page_transition_types.h
@@ -10,12 +10,139 @@
 
 namespace ui {
 
+// Types of transitions between pages. These are stored in the history
+// database to separate visits, and are reported by the renderer for page
+// navigations.
+//
+// WARNING: don't change these numbers. They are written directly into the
+// history database, so future versions will need the same values to match
+// the enums.
+//
+// A type is made of a core value and a set of qualifiers. A type has one
+// core value and 0 or or more qualifiers.
+//
+// A Java counterpart will be generated for this enum.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.ui.base
 enum PageTransition {
+  // User got to this page by clicking a link on another page.
+  PAGE_TRANSITION_LINK = 0,
 
-#define PAGE_TRANSITION(label, value) PAGE_TRANSITION_ ## label = value,
-#include "ui/base/page_transition_types_list.h"
-#undef PAGE_TRANSITION
+  // User got this page by typing the URL in the URL bar.  This should not be
+  // used for cases where the user selected a choice that didn't look at all
+  // like a URL; see GENERATED below.
+  //
+  // We also use this for other "explicit" navigation actions.
+  PAGE_TRANSITION_TYPED = 1,
 
+  // User got to this page through a suggestion in the UI, for example)
+  // through the destinations page.
+  PAGE_TRANSITION_AUTO_BOOKMARK = 2,
+
+  // This is a subframe navigation. This is any content that is automatically
+  // loaded in a non-toplevel frame. For example, if a page consists of
+  // several frames containing ads, those ad URLs will have this transition
+  // type. The user may not even realize the content in these pages is a
+  // separate frame, so may not care about the URL (see MANUAL below).
+  PAGE_TRANSITION_AUTO_SUBFRAME = 3,
+
+  // For subframe navigations that are explicitly requested by the user and
+  // generate new navigation entries in the back/forward list. These are
+  // probably more important than frames that were automatically loaded in
+  // the background because the user probably cares about the fact that this
+  // link was loaded.
+  PAGE_TRANSITION_MANUAL_SUBFRAME = 4,
+
+  // User got to this page by typing in the URL bar and selecting an entry
+  // that did not look like a URL.  For example, a match might have the URL
+  // of a Google search result page, but appear like "Search Google for ...".
+  // These are not quite the same as TYPED navigations because the user
+  // didn't type or see the destination URL.
+  // See also KEYWORD.
+  PAGE_TRANSITION_GENERATED = 5,
+
+  // This is a toplevel navigation. This is any content that is automatically
+  // loaded in a toplevel frame.  For example, opening a tab to show the ASH
+  // screen saver, opening the devtools window, opening the NTP after the safe
+  // browsing warning, opening web-based dialog boxes are examples of
+  // AUTO_TOPLEVEL navigations.
+  PAGE_TRANSITION_AUTO_TOPLEVEL = 6,
+
+  // The user filled out values in a form and submitted it. NOTE that in
+  // some situations submitting a form does not result in this transition
+  // type. This can happen if the form uses script to submit the contents.
+  PAGE_TRANSITION_FORM_SUBMIT = 7,
+
+  // The user "reloaded" the page, either by hitting the reload button or by
+  // hitting enter in the address bar.  NOTE: This is distinct from the
+  // concept of whether a particular load uses "reload semantics" (i.e.
+  // bypasses cached data).  For this reason, lots of code needs to pass
+  // around the concept of whether a load should be treated as a "reload"
+  // separately from their tracking of this transition type, which is mainly
+  // used for proper scoring for consumers who care about how frequently a
+  // user typed/visited a particular URL.
+  //
+  // SessionRestore and undo tab close use this transition type too.
+  PAGE_TRANSITION_RELOAD = 8,
+
+  // The url was generated from a replaceable keyword other than the default
+  // search provider. If the user types a keyword (which also applies to
+  // tab-to-search) in the omnibox this qualifier is applied to the transition
+  // type of the generated url. TemplateURLModel then may generate an
+  // additional visit with a transition type of KEYWORD_GENERATED against the
+  // url 'http://' + keyword. For example, if you do a tab-to-search against
+  // wikipedia the generated url has a transition qualifer of KEYWORD, and
+  // TemplateURLModel generates a visit for 'wikipedia.org' with a transition
+  // type of KEYWORD_GENERATED.
+  PAGE_TRANSITION_KEYWORD = 9,
+
+  // Corresponds to a visit generated for a keyword. See description of
+  // KEYWORD for more details.
+  PAGE_TRANSITION_KEYWORD_GENERATED = 10,
+
+  // ADDING NEW CORE VALUE? Be sure to update the LAST_CORE and CORE_MASK
+  // values below.  Also update CoreTransitionString().
+  PAGE_TRANSITION_LAST_CORE = PAGE_TRANSITION_KEYWORD_GENERATED,
+  PAGE_TRANSITION_CORE_MASK = 0xFF,
+
+  // Qualifiers
+  // Any of the core values above can be augmented by one or more qualifiers.
+  // These qualifiers further define the transition.
+
+  // A managed user attempted to visit a URL but was blocked.
+  PAGE_TRANSITION_BLOCKED = 0x00800000,
+
+  // User used the Forward or Back button to navigate among browsing history.
+  PAGE_TRANSITION_FORWARD_BACK = 0x01000000,
+
+  // User used the address bar to trigger this navigation.
+  PAGE_TRANSITION_FROM_ADDRESS_BAR = 0x02000000,
+
+  // User is navigating to the home page.
+  PAGE_TRANSITION_HOME_PAGE = 0x04000000,
+
+  // The transition originated from an external application; the exact
+  // definition of this is embedder dependent.
+  PAGE_TRANSITION_FROM_API = 0x08000000,
+
+  // The beginning of a navigation chain.
+  PAGE_TRANSITION_CHAIN_START = 0x10000000,
+
+  // The last transition in a redirect chain.
+  PAGE_TRANSITION_CHAIN_END = 0x20000000,
+
+  // Redirects caused by JavaScript or a meta refresh tag on the page.
+  PAGE_TRANSITION_CLIENT_REDIRECT = 0x40000000,
+
+  // Redirects sent from the server by HTTP headers. It might be nice to
+  // break this out into 2 types in the future, permanent or temporary, if we
+  // can get that information from WebKit.
+  PAGE_TRANSITION_SERVER_REDIRECT = 0x80000000,
+
+  // Used to test whether a transition involves a redirect.
+  PAGE_TRANSITION_IS_REDIRECT_MASK = 0xC0000000,
+
+  // General mask defining the bits used for the qualifiers.
+  PAGE_TRANSITION_QUALIFIER_MASK = 0xFFFFFF00,
 };
 
 // Compares two PageTransition types ignoring qualifiers. |rhs| is taken to
diff --git a/ui/base/page_transition_types_list.h b/ui/base/page_transition_types_list.h
deleted file mode 100644
index be673343..0000000
--- a/ui/base/page_transition_types_list.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Intentionally no include guards because this file is meant to be included
-// inside a macro to generate enum values.
-
-// Types of transitions between pages. These are stored in the history
-// database to separate visits, and are reported by the renderer for page
-// navigations.
-//
-// WARNING: don't change these numbers. They are written directly into the
-// history database, so future versions will need the same values to match
-// the enums.
-//
-// A type is made of a core value and a set of qualifiers. A type has one
-// core value and 0 or or more qualifiers.
-
-// User got to this page by clicking a link on another page.
-PAGE_TRANSITION(LINK, 0)
-
-// User got this page by typing the URL in the URL bar.  This should not be
-// used for cases where the user selected a choice that didn't look at all
-// like a URL; see GENERATED below.
-//
-// We also use this for other "explicit" navigation actions.
-PAGE_TRANSITION(TYPED, 1)
-
-// User got to this page through a suggestion in the UI, for example)
-// through the destinations page.
-PAGE_TRANSITION(AUTO_BOOKMARK, 2)
-
-// This is a subframe navigation. This is any content that is automatically
-// loaded in a non-toplevel frame. For example, if a page consists of
-// several frames containing ads, those ad URLs will have this transition
-// type. The user may not even realize the content in these pages is a
-// separate frame, so may not care about the URL (see MANUAL below).
-PAGE_TRANSITION(AUTO_SUBFRAME, 3)
-
-// For subframe navigations that are explicitly requested by the user and
-// generate new navigation entries in the back/forward list. These are
-// probably more important than frames that were automatically loaded in
-// the background because the user probably cares about the fact that this
-// link was loaded.
-PAGE_TRANSITION(MANUAL_SUBFRAME, 4)
-
-// User got to this page by typing in the URL bar and selecting an entry
-// that did not look like a URL.  For example, a match might have the URL
-// of a Google search result page, but appear like "Search Google for ...".
-// These are not quite the same as TYPED navigations because the user
-// didn't type or see the destination URL.
-// See also KEYWORD.
-PAGE_TRANSITION(GENERATED, 5)
-
-// This is a toplevel navigation. This is any content that is automatically
-// loaded in a toplevel frame.  For example, opening a tab to show the ASH
-// screen saver, opening the devtools window, opening the NTP after the safe
-// browsing warning, opening web-based dialog boxes are examples of
-// AUTO_TOPLEVEL navigations.
-PAGE_TRANSITION(AUTO_TOPLEVEL, 6)
-
-// The user filled out values in a form and submitted it. NOTE that in
-// some situations submitting a form does not result in this transition
-// type. This can happen if the form uses script to submit the contents.
-PAGE_TRANSITION(FORM_SUBMIT, 7)
-
-// The user "reloaded" the page, either by hitting the reload button or by
-// hitting enter in the address bar.  NOTE: This is distinct from the
-// concept of whether a particular load uses "reload semantics" (i.e.
-// bypasses cached data).  For this reason, lots of code needs to pass
-// around the concept of whether a load should be treated as a "reload"
-// separately from their tracking of this transition type, which is mainly
-// used for proper scoring for consumers who care about how frequently a
-// user typed/visited a particular URL.
-//
-// SessionRestore and undo tab close use this transition type too.
-PAGE_TRANSITION(RELOAD, 8)
-
-// The url was generated from a replaceable keyword other than the default
-// search provider. If the user types a keyword (which also applies to
-// tab-to-search) in the omnibox this qualifier is applied to the transition
-// type of the generated url. TemplateURLModel then may generate an
-// additional visit with a transition type of KEYWORD_GENERATED against the
-// url 'http://' + keyword. For example, if you do a tab-to-search against
-// wikipedia the generated url has a transition qualifer of KEYWORD, and
-// TemplateURLModel generates a visit for 'wikipedia.org' with a transition
-// type of KEYWORD_GENERATED.
-PAGE_TRANSITION(KEYWORD, 9)
-
-// Corresponds to a visit generated for a keyword. See description of
-// KEYWORD for more details.
-PAGE_TRANSITION(KEYWORD_GENERATED, 10)
-
-// ADDING NEW CORE VALUE? Be sure to update the LAST_CORE and CORE_MASK
-// values below.  Also update CoreTransitionString().
-PAGE_TRANSITION(LAST_CORE,   PAGE_TRANSITION_KEYWORD_GENERATED)
-PAGE_TRANSITION(CORE_MASK, 0xFF)
-
-// Qualifiers
-// Any of the core values above can be augmented by one or more qualifiers.
-// These qualifiers further define the transition.
-
-// A managed user attempted to visit a URL but was blocked.
-PAGE_TRANSITION(BLOCKED, 0x00800000)
-
-// User used the Forward or Back button to navigate among browsing history.
-PAGE_TRANSITION(FORWARD_BACK, 0x01000000)
-
-// User used the address bar to trigger this navigation.
-PAGE_TRANSITION(FROM_ADDRESS_BAR, 0x02000000)
-
-// User is navigating to the home page.
-PAGE_TRANSITION(HOME_PAGE, 0x04000000)
-
-// The transition originated from an external application; the exact definition
-// of this is embedder dependent.
-PAGE_TRANSITION(FROM_API, 0x08000000)
-
-// The beginning of a navigation chain.
-PAGE_TRANSITION(CHAIN_START, 0x10000000)
-
-// The last transition in a redirect chain.
-PAGE_TRANSITION(CHAIN_END, 0x20000000)
-
-// Redirects caused by JavaScript or a meta refresh tag on the page.
-PAGE_TRANSITION(CLIENT_REDIRECT, 0x40000000)
-
-// Redirects sent from the server by HTTP headers. It might be nice to
-// break this out into 2 types in the future, permanent or temporary, if we
-// can get that information from WebKit.
-PAGE_TRANSITION(SERVER_REDIRECT, 0x80000000)
-
-// Used to test whether a transition involves a redirect.
-PAGE_TRANSITION(IS_REDIRECT_MASK, 0xC0000000)
-
-// General mask defining the bits used for the qualifiers.
-PAGE_TRANSITION(QUALIFIER_MASK, 0xFFFFFF00)
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc
index c4d70b2..e6d08e7 100644
--- a/ui/base/resource/resource_bundle.cc
+++ b/ui/base/resource/resource_bundle.cc
@@ -46,7 +46,6 @@
 #endif
 
 #if defined(OS_WIN)
-#include "ui/base/win/dpi_setup.h"
 #include "ui/gfx/win/dpi.h"
 #endif
 
@@ -470,6 +469,7 @@
   for (size_t i = 0; i < data_packs_.size(); i++) {
     if ((data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_100P ||
          data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_200P ||
+         data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_300P ||
          data_packs_[i]->GetScaleFactor() == ui::SCALE_FACTOR_NONE) &&
         data_packs_[i]->GetStringPiece(static_cast<uint16>(resource_id),
                                        &data))
@@ -630,14 +630,12 @@
   supported_scale_factors.push_back(SCALE_FACTOR_200P);
 #elif defined(OS_WIN)
   bool default_to_100P = true;
-  if (gfx::IsHighDPIEnabled()) {
-    // On Windows if the dpi scale is greater than 1.25 on high dpi machines
-    // downscaling from 200 percent looks better than scaling up from 100
-    // percent.
-    if (gfx::GetDPIScale() > 1.25) {
-      supported_scale_factors.push_back(SCALE_FACTOR_200P);
-      default_to_100P = false;
-    }
+  // On Windows if the dpi scale is greater than 1.25 on high dpi machines
+  // downscaling from 200 percent looks better than scaling up from 100
+  // percent.
+  if (gfx::GetDPIScale() > 1.25) {
+    supported_scale_factors.push_back(SCALE_FACTOR_200P);
+    default_to_100P = false;
   }
   if (default_to_100P)
     supported_scale_factors.push_back(SCALE_FACTOR_100P);
@@ -646,10 +644,7 @@
 #if defined(OS_WIN)
   // Must be called _after_ supported scale factors are set since it
   // uses them.
-  // Don't initialize the device scale factor if it has already been
-  // initialized.
-  if (!gfx::win::IsDeviceScaleFactorSet())
-    ui::win::InitDeviceScaleFactor();
+  gfx::InitDeviceScaleFactor(gfx::GetDPIScale());
 #endif
 }
 
diff --git a/ui/base/resource/resource_bundle_ios.mm b/ui/base/resource/resource_bundle_ios.mm
index 80cc74a8..b84f8fe6 100644
--- a/ui/base/resource/resource_bundle_ios.mm
+++ b/ui/base/resource/resource_bundle_ios.mm
@@ -54,11 +54,9 @@
                         SCALE_FACTOR_200P);
   }
 
-  // TODO(rohitrao): Add a chrome_300_percent file and load it here.  For now,
-  // we are simply falling back to the 200P resources. http://crbug.com/413300.
   if (IsScaleFactorSupported(SCALE_FACTOR_300P)) {
-    AddDataPackFromPath(GetResourcesPakFilePath(@"chrome_200_percent", nil),
-                        SCALE_FACTOR_200P);
+    AddDataPackFromPath(GetResourcesPakFilePath(@"chrome_300_percent", nil),
+                        SCALE_FACTOR_300P);
   }
 }
 
diff --git a/ui/base/resource/resource_bundle_unittest.cc b/ui/base/resource/resource_bundle_unittest.cc
index 488947d..565bf59 100644
--- a/ui/base/resource/resource_bundle_unittest.cc
+++ b/ui/base/resource/resource_bundle_unittest.cc
@@ -473,7 +473,7 @@
 // via ResourceBundle::GetImageNamed().
 TEST_F(ResourceBundleImageTest, GetImageNamed) {
 #if defined(OS_WIN)
-  gfx::ForceHighDPISupportForTesting(2.0);
+  gfx::InitDeviceScaleFactor(2.0);
 #endif
   std::vector<ScaleFactor> supported_factors;
   supported_factors.push_back(SCALE_FACTOR_100P);
diff --git a/ui/base/resource/resource_bundle_win.cc b/ui/base/resource/resource_bundle_win.cc
index fa17eee..045f8ae 100644
--- a/ui/base/resource/resource_bundle_win.cc
+++ b/ui/base/resource/resource_bundle_win.cc
@@ -49,7 +49,6 @@
         SCALE_FACTOR_100P);
   }
   if (IsScaleFactorSupported(SCALE_FACTOR_200P)) {
-    DCHECK(gfx::IsHighDPIEnabled());
     AddDataPackFromPath(
         GetResourcesPakFilePath("chrome_200_percent.pak"),
         SCALE_FACTOR_200P);
diff --git a/ui/base/test/run_all_unittests.cc b/ui/base/test/run_all_unittests.cc
index cb2067a..4215631 100644
--- a/ui/base/test/run_all_unittests.cc
+++ b/ui/base/test/run_all_unittests.cc
@@ -48,7 +48,7 @@
   base::TestSuite::Initialize();
 
 #if defined(OS_WIN)
-  gfx::ForceHighDPISupportForTesting(1.0);
+  gfx::InitDeviceScaleFactor(1.0);
 #endif
 
 #if defined(OS_ANDROID)
diff --git a/ui/base/ui_base.gyp b/ui/base/ui_base.gyp
index 46557122..053360e 100644
--- a/ui/base/ui_base.gyp
+++ b/ui/base/ui_base.gyp
@@ -348,8 +348,6 @@
         'win/accessibility_misc_utils.cc',
         'win/accessibility_misc_utils.h',
         'win/atl_module.h',
-        'win/dpi_setup.cc',
-        'win/dpi_setup.h',
         'win/foreground_helper.cc',
         'win/foreground_helper.h',
         'win/hidden_window.cc',
diff --git a/ui/base/win/dpi_setup.cc b/ui/base/win/dpi_setup.cc
deleted file mode 100644
index 423b7881..0000000
--- a/ui/base/win/dpi_setup.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 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 "ui/base/win/dpi_setup.h"
-
-#include "base/command_line.h"
-#include "ui/base/layout.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/win/dpi.h"
-
-namespace ui {
-namespace win {
-
-void InitDeviceScaleFactor() {
-  gfx::InitDeviceScaleFactor(gfx::GetDPIScale());
-}
-
-}  // namespace win
-}  // namespace ui
diff --git a/ui/base/win/dpi_setup.h b/ui/base/win/dpi_setup.h
deleted file mode 100644
index 5837153d..0000000
--- a/ui/base/win/dpi_setup.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 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 UI_BASE_WIN_DPI_SETUP_H_
-#define UI_BASE_WIN_DPI_SETUP_H_
-
-#include "ui/base/ui_base_export.h"
-
-namespace ui {
-namespace win {
-
-// Initializes the device scale factor. If support is enabled, this will set
-// the best available scale based on the screen's pixel density. This can be
-// affected (overridden) by --force-device-scale-factor=x
-// This function can be called only once for the lifetime of a process.
-UI_BASE_EXPORT void InitDeviceScaleFactor();
-
-}  // namespace win
-}  // namespace ui
-
-#endif  // UI_BASE_WIN_DPI_SETUP_H_
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index c595e9d..6526e6e4 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -1253,6 +1253,8 @@
       return WM_COMPIZ;
     if (name == "e16" || name == "Enlightenment")
       return WM_ENLIGHTENMENT;
+    if (name == "Fluxbox")
+      return WM_FLUXBOX;
     if (name == "i3")
       return WM_I3;
     if (StartsWithASCII(name, "IceWM", true))
diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h
index 1346f74..cb468a8 100644
--- a/ui/base/x/x11_util.h
+++ b/ui/base/x/x11_util.h
@@ -260,6 +260,7 @@
   WM_BLACKBOX,
   WM_COMPIZ,
   WM_ENLIGHTENMENT,
+  WM_FLUXBOX,
   WM_I3,
   WM_ICE_WM,
   WM_ION3,
diff --git a/ui/chromeos/touch_exploration_controller_unittest.cc b/ui/chromeos/touch_exploration_controller_unittest.cc
index 3fabbe7..201aefd 100644
--- a/ui/chromeos/touch_exploration_controller_unittest.cc
+++ b/ui/chromeos/touch_exploration_controller_unittest.cc
@@ -94,10 +94,10 @@
   }
 
   const std::vector<float> VolumeChanges() { return volume_changes_; }
-  const size_t NumAdjustSounds() { return num_times_adjust_sound_played_; }
-  const size_t NumPassthroughSounds() { return num_times_passthrough_played_; }
-  const size_t NumExitScreenSounds() { return num_times_exit_screen_played_; }
-  const size_t NumEnterScreenSounds() {
+  size_t NumAdjustSounds() { return num_times_adjust_sound_played_; }
+  size_t NumPassthroughSounds() { return num_times_passthrough_played_; }
+  size_t NumExitScreenSounds() { return num_times_exit_screen_played_; }
+  size_t NumEnterScreenSounds() {
     return num_times_enter_screen_played_;
   }
 
diff --git a/ui/compositor/PRESUBMIT.py b/ui/compositor/PRESUBMIT.py
index 405f8ce..6bc103c 100644
--- a/ui/compositor/PRESUBMIT.py
+++ b/ui/compositor/PRESUBMIT.py
@@ -11,6 +11,6 @@
 def GetPreferredTryMasters(project, change):
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_chromeos_rel_swarming': set(['defaulttests']),
+      'linux_chromium_chromeos_rel': set(['defaulttests']),
     }
   }
diff --git a/ui/display/chromeos/display_configurator.cc b/ui/display/chromeos/display_configurator.cc
index 3194636..8d0a2410 100644
--- a/ui/display/chromeos/display_configurator.cc
+++ b/ui/display/chromeos/display_configurator.cc
@@ -129,6 +129,11 @@
     if (mode->size() != size)
       continue;
 
+    if (mode == display.native_mode()) {
+      best_mode = mode;
+      break;
+    }
+
     if (!best_mode) {
       best_mode = mode;
       continue;
@@ -579,15 +584,14 @@
   // Set |selected_mode| fields.
   for (size_t i = 0; i < cached_displays_.size(); ++i) {
     DisplayState* display_state = &cached_displays_[i];
-    if (display_state->display->has_proper_display_id()) {
-      gfx::Size size;
-      if (state_controller_ &&
-          state_controller_->GetResolutionForDisplayId(
-              display_state->display->display_id(), &size)) {
-        display_state->selected_mode =
-            FindDisplayModeMatchingSize(*display_state->display, size);
-      }
+    gfx::Size size;
+    if (state_controller_ &&
+        state_controller_->GetResolutionForDisplayId(
+            display_state->display->display_id(), &size)) {
+      display_state->selected_mode =
+          FindDisplayModeMatchingSize(*display_state->display, size);
     }
+
     // Fall back to native mode.
     if (!display_state->selected_mode)
       display_state->selected_mode = display_state->display->native_mode();
@@ -960,12 +964,9 @@
         // With either both displays on or both displays off, use one of the
         // dual modes.
         std::vector<int64_t> display_ids;
-        for (size_t i = 0; i < cached_displays_.size(); ++i) {
-          // If display id isn't available, switch to extended mode.
-          if (!cached_displays_[i].display->has_proper_display_id())
-            return MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED;
+        for (size_t i = 0; i < cached_displays_.size(); ++i)
           display_ids.push_back(cached_displays_[i].display->display_id());
-        }
+
         return state_controller_->GetStateForDisplayIds(display_ids);
       }
     }
diff --git a/ui/display/chromeos/display_configurator_unittest.cc b/ui/display/chromeos/display_configurator_unittest.cc
index aecaddd..0c4c1025 100644
--- a/ui/display/chromeos/display_configurator_unittest.cc
+++ b/ui/display/chromeos/display_configurator_unittest.cc
@@ -359,7 +359,6 @@
     o->set_type(DISPLAY_CONNECTION_TYPE_INTERNAL);
     o->set_is_aspect_preserving_scaling(true);
     o->set_display_id(123);
-    o->set_has_proper_display_id(true);
 
     o = &outputs_[1];
     o->set_current_mode(&big_mode_);
@@ -369,7 +368,6 @@
     o->set_type(DISPLAY_CONNECTION_TYPE_HDMI);
     o->set_is_aspect_preserving_scaling(true);
     o->set_display_id(456);
-    o->set_has_proper_display_id(true);
 
     UpdateOutputs(2, false);
   }
@@ -439,6 +437,9 @@
 
   // Fields are width, height, interlaced, refresh rate.
   modes.push_back(new DisplayMode(gfx::Size(1920, 1200), false, 60.0));
+  DisplayMode* native_mode =
+      new DisplayMode(gfx::Size(1920, 1200), false, 50.0);
+  modes.push_back(native_mode);
   // Different rates.
   modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 30.0));
   modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 50.0));
@@ -462,40 +463,42 @@
 
   TestDisplaySnapshot output;
   output.set_modes(modes.get());
+  output.set_native_mode(native_mode);
 
-  EXPECT_EQ(modes[0],
+  // Should pick native over highest refresh rate.
+  EXPECT_EQ(modes[1],
             DisplayConfigurator::FindDisplayModeMatchingSize(
                 output, gfx::Size(1920, 1200)));
 
   // Should pick highest refresh rate.
-  EXPECT_EQ(modes[2],
+  EXPECT_EQ(modes[3],
             DisplayConfigurator::FindDisplayModeMatchingSize(
                 output, gfx::Size(1920, 1080)));
 
   // Should pick non-interlaced mode.
-  EXPECT_EQ(modes[6],
+  EXPECT_EQ(modes[7],
             DisplayConfigurator::FindDisplayModeMatchingSize(
                 output, gfx::Size(1280, 720)));
 
   // Interlaced only. Should pick one with the highest refresh rate in
   // interlaced mode.
-  EXPECT_EQ(modes[9],
+  EXPECT_EQ(modes[10],
             DisplayConfigurator::FindDisplayModeMatchingSize(
                 output, gfx::Size(1024, 768)));
 
   // Mixed: Should pick one with the highest refresh rate in
   // interlaced mode.
-  EXPECT_EQ(modes[12],
+  EXPECT_EQ(modes[13],
             DisplayConfigurator::FindDisplayModeMatchingSize(
                 output, gfx::Size(1024, 600)));
 
   // Just one interlaced mode.
-  EXPECT_EQ(modes[13],
+  EXPECT_EQ(modes[14],
             DisplayConfigurator::FindDisplayModeMatchingSize(
                 output, gfx::Size(640, 480)));
 
   // Refresh rate not available.
-  EXPECT_EQ(modes[14],
+  EXPECT_EQ(modes[15],
             DisplayConfigurator::FindDisplayModeMatchingSize(
                 output, gfx::Size(320, 200)));
 
@@ -1004,18 +1007,7 @@
   EXPECT_EQ(2, observer_.num_failures());
 }
 
-TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForDisplaysWithoutId) {
-  outputs_[0].set_has_proper_display_id(false);
-  UpdateOutputs(2, false);
-  configurator_.Init(false);
-  state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
-  configurator_.ForceInitialConfigure(0);
-  EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
-            configurator_.display_state());
-}
-
-TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForDisplaysWithId) {
-  outputs_[0].set_has_proper_display_id(true);
+TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForMirroredDisplays) {
   UpdateOutputs(2, false);
   configurator_.Init(false);
   state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
diff --git a/ui/display/chromeos/test/test_display_snapshot.cc b/ui/display/chromeos/test/test_display_snapshot.cc
index b7eba9a..227e6f4 100644
--- a/ui/display/chromeos/test/test_display_snapshot.cc
+++ b/ui/display/chromeos/test/test_display_snapshot.cc
@@ -7,7 +7,6 @@
 namespace ui {
 TestDisplaySnapshot::TestDisplaySnapshot()
     : DisplaySnapshot(0,
-                      false,
                       gfx::Point(0, 0),
                       gfx::Size(0, 0),
                       DISPLAY_CONNECTION_TYPE_UNKNOWN,
@@ -20,7 +19,6 @@
 
 TestDisplaySnapshot::TestDisplaySnapshot(
     int64_t display_id,
-    bool has_proper_display_id,
     const gfx::Point& origin,
     const gfx::Size& physical_size,
     DisplayConnectionType type,
@@ -29,7 +27,6 @@
     const DisplayMode* current_mode,
     const DisplayMode* native_mode)
     : DisplaySnapshot(display_id,
-                      has_proper_display_id,
                       origin,
                       physical_size,
                       type,
diff --git a/ui/display/chromeos/test/test_display_snapshot.h b/ui/display/chromeos/test/test_display_snapshot.h
index 95653ca..5691c897 100644
--- a/ui/display/chromeos/test/test_display_snapshot.h
+++ b/ui/display/chromeos/test/test_display_snapshot.h
@@ -14,7 +14,6 @@
  public:
   TestDisplaySnapshot();
   TestDisplaySnapshot(int64_t display_id,
-                      bool has_proper_display_id,
                       const gfx::Point& origin,
                       const gfx::Size& physical_size,
                       DisplayConnectionType type,
@@ -34,9 +33,6 @@
     is_aspect_preserving_scaling_ = state;
   }
   void set_display_id(int64_t id) { display_id_ = id; }
-  void set_has_proper_display_id(bool has_display_id) {
-    has_proper_display_id_ = has_display_id;
-  }
 
   // DisplaySnapshot overrides:
   virtual std::string ToString() const override;
diff --git a/ui/display/chromeos/x11/display_snapshot_x11.cc b/ui/display/chromeos/x11/display_snapshot_x11.cc
index 52c4ba7..bb3e6105 100644
--- a/ui/display/chromeos/x11/display_snapshot_x11.cc
+++ b/ui/display/chromeos/x11/display_snapshot_x11.cc
@@ -11,7 +11,6 @@
 
 DisplaySnapshotX11::DisplaySnapshotX11(
     int64_t display_id,
-    bool has_proper_display_id,
     const gfx::Point& origin,
     const gfx::Size& physical_size,
     DisplayConnectionType type,
@@ -25,7 +24,6 @@
     RRCrtc crtc,
     int index)
     : DisplaySnapshot(display_id,
-                      has_proper_display_id,
                       origin,
                       physical_size,
                       type,
diff --git a/ui/display/chromeos/x11/display_snapshot_x11.h b/ui/display/chromeos/x11/display_snapshot_x11.h
index 50128b4a..35b5f68e 100644
--- a/ui/display/chromeos/x11/display_snapshot_x11.h
+++ b/ui/display/chromeos/x11/display_snapshot_x11.h
@@ -18,7 +18,6 @@
 class DISPLAY_EXPORT DisplaySnapshotX11 : public DisplaySnapshot {
  public:
   DisplaySnapshotX11(int64_t display_id,
-                     bool has_proper_display_id,
                      const gfx::Point& origin,
                      const gfx::Size& physical_size,
                      DisplayConnectionType type,
diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.cc b/ui/display/chromeos/x11/native_display_delegate_x11.cc
index 50dc3225..42d4961 100644
--- a/ui/display/chromeos/x11/native_display_delegate_x11.cc
+++ b/ui/display/chromeos/x11/native_display_delegate_x11.cc
@@ -308,8 +308,8 @@
     RRCrtc* last_used_crtc,
     int index) {
   int64_t display_id = 0;
-  bool has_display_id = GetDisplayId(
-      output, static_cast<uint8_t>(index), &display_id);
+  if (!GetDisplayId(output, static_cast<uint8_t>(index), &display_id))
+    display_id = index;
 
   bool has_overscan = false;
   GetOutputOverscanFlag(output, &has_overscan);
@@ -318,17 +318,6 @@
   if (type == DISPLAY_CONNECTION_TYPE_UNKNOWN)
     LOG(ERROR) << "Unknown link type: " << info->name;
 
-  // Use the index as a valid display ID even if the internal
-  // display doesn't have valid EDID because the index
-  // will never change.
-  if (!has_display_id) {
-    if (type == DISPLAY_CONNECTION_TYPE_INTERNAL)
-      has_display_id = true;
-
-    // Fallback to output index.
-    display_id = index;
-  }
-
   RRMode native_mode_id = GetOutputNativeMode(info);
   RRMode current_mode_id = None;
   gfx::Point origin;
@@ -369,7 +358,6 @@
 
   DisplaySnapshotX11* display_snapshot =
       new DisplaySnapshotX11(display_id,
-                             has_display_id,
                              origin,
                              gfx::Size(info->mm_width, info->mm_height),
                              type,
diff --git a/ui/display/chromeos/x11/native_display_event_dispatcher_x11_unittest.cc b/ui/display/chromeos/x11/native_display_event_dispatcher_x11_unittest.cc
index 45bca9f..de877962 100644
--- a/ui/display/chromeos/x11/native_display_event_dispatcher_x11_unittest.cc
+++ b/ui/display/chromeos/x11/native_display_event_dispatcher_x11_unittest.cc
@@ -24,7 +24,6 @@
 
   DisplaySnapshotX11* snapshot = new DisplaySnapshotX11(
       0,
-      false,
       gfx::Point(0, 0),
       gfx::Size(0, 0),
       DISPLAY_CONNECTION_TYPE_UNKNOWN,
diff --git a/ui/display/types/display_snapshot.cc b/ui/display/types/display_snapshot.cc
index efe401b..38e42b2 100644
--- a/ui/display/types/display_snapshot.cc
+++ b/ui/display/types/display_snapshot.cc
@@ -7,7 +7,6 @@
 namespace ui {
 
 DisplaySnapshot::DisplaySnapshot(int64_t display_id,
-                                 bool has_proper_display_id,
                                  const gfx::Point& origin,
                                  const gfx::Size& physical_size,
                                  DisplayConnectionType type,
@@ -18,7 +17,6 @@
                                  const DisplayMode* current_mode,
                                  const DisplayMode* native_mode)
     : display_id_(display_id),
-      has_proper_display_id_(has_proper_display_id),
       origin_(origin),
       physical_size_(physical_size),
       type_(type),
diff --git a/ui/display/types/display_snapshot.h b/ui/display/types/display_snapshot.h
index 7019208..e0dcc7b 100644
--- a/ui/display/types/display_snapshot.h
+++ b/ui/display/types/display_snapshot.h
@@ -20,7 +20,6 @@
 class DISPLAY_TYPES_EXPORT DisplaySnapshot {
  public:
   DisplaySnapshot(int64_t display_id,
-                  bool has_proper_display_id,
                   const gfx::Point& origin,
                   const gfx::Size& physical_size,
                   DisplayConnectionType type,
@@ -42,7 +41,6 @@
   std::string display_name() const { return display_name_; }
 
   int64_t display_id() const { return display_id_; }
-  bool has_proper_display_id() const { return has_proper_display_id_; }
 
   const DisplayMode* current_mode() const { return current_mode_; }
   const DisplayMode* native_mode() const { return native_mode_; }
@@ -59,7 +57,6 @@
  protected:
   // Display id for this output.
   int64_t display_id_;
-  bool has_proper_display_id_;
 
   // Display's origin on the framebuffer.
   gfx::Point origin_;
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn
index c697e54..c00d2e6 100644
--- a/ui/events/BUILD.gn
+++ b/ui/events/BUILD.gn
@@ -32,6 +32,10 @@
     "gestures/fling_curve.h",
     "gestures/gesture_configuration.cc",
     "gestures/gesture_configuration.h",
+    "input_device.cc",
+    "input_device.h",
+    "keyboard_device.cc",
+    "keyboard_device.h",
     "keycodes/keyboard_code_conversion.cc",
     "keycodes/keyboard_code_conversion.h",
     "keycodes/keyboard_code_conversion_android.cc",
@@ -234,8 +238,8 @@
     "test/event_generator.h",
     "test/events_test_utils.cc",
     "test/events_test_utils.h",
-    "test/mock_motion_event.cc",
-    "test/mock_motion_event.h",
+    "test/motion_event_test_utils.cc",
+    "test/motion_event_test_utils.h",
     "test/platform_event_waiter.cc",
     "test/platform_event_waiter.h",
     "test/test_event_handler.cc",
@@ -293,6 +297,7 @@
     "keycodes/dom4/keycode_converter_unittest.cc",
     "latency_info_unittest.cc",
     "platform/platform_event_source_unittest.cc",
+    "x/device_data_manager_x11_unittest.cc",
     "x/events_x_unittest.cc",
   ]
 
@@ -315,6 +320,7 @@
     deps += [ "//ui/gfx/x" ]
   } else {
     sources -= [
+      "x/device_data_manager_x11_unittest.cc",
       "x/events_x_unittest.cc",
     ]
   }
diff --git a/ui/events/OWNERS b/ui/events/OWNERS
index aeec937..d9d3b1f 100644
--- a/ui/events/OWNERS
+++ b/ui/events/OWNERS
@@ -4,3 +4,4 @@
 
 # If you're doing structural changes get a review from one of the OWNERS.
 per-file *.gyp*=*
+per-file BUILD.gn=*
diff --git a/ui/events/PRESUBMIT.py b/ui/events/PRESUBMIT.py
index bc905a3..1065f3c 100644
--- a/ui/events/PRESUBMIT.py
+++ b/ui/events/PRESUBMIT.py
@@ -17,12 +17,12 @@
 
   return {
     'tryserver.chromium.linux': {
-      'linux_chromium_rel_swarming': tests,
-      'linux_chromium_chromeos_rel_swarming': tests,
+      'linux_chromium_rel': tests,
+      'linux_chromium_chromeos_rel': tests,
       'linux_chromeos_asan': tests,
     },
     'tryserver.chromium.win': {
       'win_chromium_compile_dbg': tests,
-      'win_chromium_rel_swarming': tests,
+      'win_chromium_rel': tests,
     }
   }
diff --git a/ui/events/device_data_manager.cc b/ui/events/device_data_manager.cc
index d255b871..a9e8578dd 100644
--- a/ui/events/device_data_manager.cc
+++ b/ui/events/device_data_manager.cc
@@ -13,6 +13,14 @@
 
 namespace ui {
 
+namespace {
+
+bool InputDeviceEquals(const ui::InputDevice& a, const ui::InputDevice& b) {
+  return a.id == b.id;
+}
+
+}  // namespace
+
 // static
 DeviceDataManager* DeviceDataManager::instance_ = NULL;
 
@@ -64,13 +72,14 @@
   }
 }
 
-bool DeviceDataManager::IsTouchDeviceIdValid(int touch_device_id) const {
+bool DeviceDataManager::IsTouchDeviceIdValid(
+    unsigned int touch_device_id) const {
   return (touch_device_id > 0 && touch_device_id < kMaxDeviceNum);
 }
 
 void DeviceDataManager::UpdateTouchInfoForDisplay(
     int64_t display_id,
-    int touch_device_id,
+    unsigned int touch_device_id,
     const gfx::Transform& touch_transformer) {
   if (IsTouchDeviceIdValid(touch_device_id)) {
     touch_device_to_display_map_[touch_device_id] = display_id;
@@ -78,19 +87,19 @@
   }
 }
 
-void DeviceDataManager::UpdateTouchRadiusScale(int touch_device_id,
+void DeviceDataManager::UpdateTouchRadiusScale(unsigned int touch_device_id,
                                                double scale) {
   if (IsTouchDeviceIdValid(touch_device_id))
     touch_radius_scale_map_[touch_device_id] = scale;
 }
 
-void DeviceDataManager::ApplyTouchRadiusScale(int touch_device_id,
+void DeviceDataManager::ApplyTouchRadiusScale(unsigned int touch_device_id,
                                               double* radius) {
   if (IsTouchDeviceIdValid(touch_device_id))
     *radius = (*radius) * touch_radius_scale_map_[touch_device_id];
 }
 
-void DeviceDataManager::ApplyTouchTransformer(int touch_device_id,
+void DeviceDataManager::ApplyTouchTransformer(unsigned int touch_device_id,
                                               float* x,
                                               float* y) {
   if (IsTouchDeviceIdValid(touch_device_id)) {
@@ -103,7 +112,8 @@
   }
 }
 
-int64_t DeviceDataManager::GetDisplayForTouchDevice(int touch_device_id) const {
+int64_t DeviceDataManager::GetDisplayForTouchDevice(
+    unsigned int touch_device_id) const {
   if (IsTouchDeviceIdValid(touch_device_id))
     return touch_device_to_display_map_[touch_device_id];
   return gfx::Display::kInvalidDisplayID;
@@ -111,11 +121,32 @@
 
 void DeviceDataManager::OnTouchscreenDevicesUpdated(
     const std::vector<TouchscreenDevice>& devices) {
+  if (devices.size() == touchscreen_devices_.size() &&
+      std::equal(devices.begin(),
+                 devices.end(),
+                 touchscreen_devices_.begin(),
+                 InputDeviceEquals)) {
+    return;
+  }
   touchscreen_devices_ = devices;
-
   FOR_EACH_OBSERVER(InputDeviceEventObserver,
                     observers_,
-                    OnInputDeviceConfigurationChanged());
+                    OnTouchscreenDeviceConfigurationChanged());
+}
+
+void DeviceDataManager::OnKeyboardDevicesUpdated(
+    const std::vector<KeyboardDevice>& devices) {
+  if (devices.size() == keyboard_devices_.size() &&
+      std::equal(devices.begin(),
+                 devices.end(),
+                 keyboard_devices_.begin(),
+                 InputDeviceEquals)) {
+    return;
+  }
+  keyboard_devices_ = devices;
+  FOR_EACH_OBSERVER(InputDeviceEventObserver,
+                    observers_,
+                    OnKeyboardDeviceConfigurationChanged());
 }
 
 void DeviceDataManager::AddObserver(InputDeviceEventObserver* observer) {
diff --git a/ui/events/device_data_manager.h b/ui/events/device_data_manager.h
index 87e3bd46..f19daed 100644
--- a/ui/events/device_data_manager.h
+++ b/ui/events/device_data_manager.h
@@ -14,6 +14,7 @@
 #include "base/observer_list.h"
 #include "ui/events/device_hotplug_event_observer.h"
 #include "ui/events/events_base_export.h"
+#include "ui/events/keyboard_device.h"
 #include "ui/events/touchscreen_device.h"
 #include "ui/gfx/transform.h"
 
@@ -24,6 +25,7 @@
 // Keeps track of device mappings and event transformations.
 class EVENTS_BASE_EXPORT DeviceDataManager : public DeviceHotplugEventObserver {
  public:
+  static const int kMaxDeviceNum = 128;
   ~DeviceDataManager() override;
 
   static void CreateInstance();
@@ -32,18 +34,22 @@
 
   void ClearTouchTransformerRecord();
   void UpdateTouchInfoForDisplay(int64_t display_id,
-                                 int touch_device_id,
+                                 unsigned int touch_device_id,
                                  const gfx::Transform& touch_transformer);
-  void ApplyTouchTransformer(int touch_device_id, float* x, float* y);
-  int64_t GetDisplayForTouchDevice(int touch_device_id) const;
+  void ApplyTouchTransformer(unsigned int touch_device_id, float* x, float* y);
+  int64_t GetDisplayForTouchDevice(unsigned int touch_device_id) const;
 
-  void UpdateTouchRadiusScale(int touch_device_id, double scale);
-  void ApplyTouchRadiusScale(int touch_device_id, double* radius);
+  void UpdateTouchRadiusScale(unsigned int touch_device_id, double scale);
+  void ApplyTouchRadiusScale(unsigned int touch_device_id, double* radius);
 
   const std::vector<TouchscreenDevice>& touchscreen_devices() const {
     return touchscreen_devices_;
   }
 
+  const std::vector<KeyboardDevice>& keyboard_devices() const {
+    return keyboard_devices_;
+  }
+
   void AddObserver(InputDeviceEventObserver* observer);
   void RemoveObserver(InputDeviceEventObserver* observer);
 
@@ -52,16 +58,16 @@
 
   static DeviceDataManager* instance();
 
-  static const int kMaxDeviceNum = 128;
+  // DeviceHotplugEventObserver:
+  void OnTouchscreenDevicesUpdated(
+      const std::vector<TouchscreenDevice>& devices) override;
+  virtual void OnKeyboardDevicesUpdated(
+      const std::vector<KeyboardDevice>& devices) override;
 
  private:
   static DeviceDataManager* instance_;
 
-  bool IsTouchDeviceIdValid(int touch_device_id) const;
-
-  // DeviceHotplugEventObserver:
-  void OnTouchscreenDevicesUpdated(
-      const std::vector<TouchscreenDevice>& devices) override;
+  bool IsTouchDeviceIdValid(unsigned int touch_device_id) const;
 
   double touch_radius_scale_map_[kMaxDeviceNum];
 
@@ -71,6 +77,7 @@
   gfx::Transform touch_device_transformer_map_[kMaxDeviceNum];
 
   std::vector<TouchscreenDevice> touchscreen_devices_;
+  std::vector<KeyboardDevice> keyboard_devices_;
 
   ObserverList<InputDeviceEventObserver> observers_;
 
diff --git a/ui/events/device_hotplug_event_observer.h b/ui/events/device_hotplug_event_observer.h
index 8a763a6..1e709902 100644
--- a/ui/events/device_hotplug_event_observer.h
+++ b/ui/events/device_hotplug_event_observer.h
@@ -5,19 +5,29 @@
 #ifndef UI_EVENTS_DEVICE_HOTPLUG_EVENT_OBSERVER_H_
 #define UI_EVENTS_DEVICE_HOTPLUG_EVENT_OBSERVER_H_
 
+#include <vector>
+
 #include "ui/events/events_base_export.h"
-#include "ui/events/touchscreen_device.h"
 
 namespace ui {
 
+struct KeyboardDevice;
+struct TouchscreenDevice;
+
 // Listener for specific input device hotplug events.
 class EVENTS_BASE_EXPORT DeviceHotplugEventObserver {
  public:
   virtual ~DeviceHotplugEventObserver() {}
 
-  // On a hotplug event this is called with the list of available devices.
+  // On a hotplug event this is called with the list of available touchscreen
+  // devices. The set of touchscreen devices may not necessarily have changed.
   virtual void OnTouchscreenDevicesUpdated(
       const std::vector<TouchscreenDevice>& devices) = 0;
+
+  // On a hotplug event this is called with the list of available keyboard
+  // devices. The set of keyboard devices may not necessarily have changed.
+  virtual void OnKeyboardDevicesUpdated(
+      const std::vector<KeyboardDevice>& devices) = 0;
 };
 
 }  // namespace ui
diff --git a/ui/events/event.cc b/ui/events/event.cc
index fa6dbac..894d5b0 100644
--- a/ui/events/event.cc
+++ b/ui/events/event.cc
@@ -612,6 +612,7 @@
       event.flags() == last_key_event_->flags() &&
       (event.time_stamp() - last_key_event_->time_stamp()).InMilliseconds() <
       kMaxAutoRepeatTimeMs) {
+    last_key_event_->set_time_stamp(event.time_stamp());
     return true;
   }
   delete last_key_event_;
diff --git a/ui/events/event_unittest.cc b/ui/events/event_unittest.cc
index d2a6a69..4912b03 100644
--- a/ui/events/event_unittest.cc
+++ b/ui/events/event_unittest.cc
@@ -389,6 +389,19 @@
 #endif  // OS_WIN
 }
 
+namespace {
+#if defined(USE_X11)
+void SetKeyEventTimestamp(XEvent* event, long time) {
+  event->xkey.time = time;
+}
+
+#elif defined(OS_WIN)
+void SetKeyEventTimestamp(MSG& msg, long time) {
+  msg.time = time;
+}
+#endif
+}  // namespace
+
 #if defined(USE_X11) || defined(OS_WIN)
 TEST(EventTest, AutoRepeat) {
   const uint16 kNativeCodeA = ui::KeycodeConverter::CodeToNativeKeycode("KeyA");
@@ -396,6 +409,13 @@
 #if defined(USE_X11)
   ScopedXI2Event native_event_a_pressed;
   native_event_a_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
+  ScopedXI2Event native_event_a_pressed_1500;
+  native_event_a_pressed_1500.InitKeyEvent(
+      ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
+  ScopedXI2Event native_event_a_pressed_3000;
+  native_event_a_pressed_3000.InitKeyEvent(
+      ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
+
   ScopedXI2Event native_event_a_released;
   native_event_a_released.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, kNativeCodeA);
   ScopedXI2Event native_event_b_pressed;
@@ -410,41 +430,64 @@
   const LPARAM lParam_a = GetLParamFromScanCode(kNativeCodeA);
   const LPARAM lParam_b = GetLParamFromScanCode(kNativeCodeB);
   MSG native_event_a_pressed = { NULL, WM_KEYDOWN, VKEY_A, lParam_a };
+  MSG native_event_a_pressed_1500 = { NULL, WM_KEYDOWN, VKEY_A, lParam_a };
+  MSG native_event_a_pressed_3000 = { NULL, WM_KEYDOWN, VKEY_A, lParam_a };
   MSG native_event_a_released = { NULL, WM_KEYUP, VKEY_A, lParam_a };
   MSG native_event_b_pressed = { NULL, WM_KEYUP, VKEY_B, lParam_b };
 #endif
-  KeyEvent key_a1(native_event_a_pressed);
-  EXPECT_FALSE(key_a1.IsRepeat());
-  KeyEvent key_a1_released(native_event_a_released);
-  EXPECT_FALSE(key_a1_released.IsRepeat());
+  SetKeyEventTimestamp(native_event_a_pressed_1500, 1500);
+  SetKeyEventTimestamp(native_event_a_pressed_3000, 3000);
 
-  KeyEvent key_a2(native_event_a_pressed);
-  EXPECT_FALSE(key_a2.IsRepeat());
-  KeyEvent key_a2_repeated(native_event_a_pressed);
-  EXPECT_TRUE(key_a2_repeated.IsRepeat());
-  KeyEvent key_a2_released(native_event_a_released);
-  EXPECT_FALSE(key_a2_released.IsRepeat());
+  {
+    KeyEvent key_a1(native_event_a_pressed);
+    EXPECT_FALSE(key_a1.IsRepeat());
+    KeyEvent key_a1_released(native_event_a_released);
+    EXPECT_FALSE(key_a1_released.IsRepeat());
 
-  KeyEvent key_a3(native_event_a_pressed);
-  EXPECT_FALSE(key_a3.IsRepeat());
-  KeyEvent key_b(native_event_b_pressed);
-  EXPECT_FALSE(key_b.IsRepeat());
-  KeyEvent key_a3_again(native_event_a_pressed);
-  EXPECT_FALSE(key_a3_again.IsRepeat());
-  KeyEvent key_a3_repeated(native_event_a_pressed);
-  EXPECT_TRUE(key_a3_repeated.IsRepeat());
-  KeyEvent key_a3_repeated2(native_event_a_pressed);
-  EXPECT_TRUE(key_a3_repeated2.IsRepeat());
-  KeyEvent key_a3_released(native_event_a_released);
-  EXPECT_FALSE(key_a3_released.IsRepeat());
+    KeyEvent key_a2(native_event_a_pressed);
+    EXPECT_FALSE(key_a2.IsRepeat());
+    KeyEvent key_a2_repeated(native_event_a_pressed);
+    EXPECT_TRUE(key_a2_repeated.IsRepeat());
+    KeyEvent key_a2_released(native_event_a_released);
+    EXPECT_FALSE(key_a2_released.IsRepeat());
+  }
+
+  {
+    KeyEvent key_a3(native_event_a_pressed);
+    EXPECT_FALSE(key_a3.IsRepeat());
+    KeyEvent key_b(native_event_b_pressed);
+    EXPECT_FALSE(key_b.IsRepeat());
+    KeyEvent key_a3_again(native_event_a_pressed);
+    EXPECT_FALSE(key_a3_again.IsRepeat());
+    KeyEvent key_a3_repeated(native_event_a_pressed);
+    EXPECT_TRUE(key_a3_repeated.IsRepeat());
+    KeyEvent key_a3_repeated2(native_event_a_pressed);
+    EXPECT_TRUE(key_a3_repeated2.IsRepeat());
+    KeyEvent key_a3_released(native_event_a_released);
+    EXPECT_FALSE(key_a3_released.IsRepeat());
+  }
+
+  // Hold the key longer than max auto repeat timeout.
+  {
+    KeyEvent key_a4_0(native_event_a_pressed);
+    EXPECT_FALSE(key_a4_0.IsRepeat());
+    KeyEvent key_a4_1500(native_event_a_pressed_1500);
+    EXPECT_TRUE(key_a4_1500.IsRepeat());
+    KeyEvent key_a4_3000(native_event_a_pressed_3000);
+    EXPECT_TRUE(key_a4_3000.IsRepeat());
+    KeyEvent key_a4_released(native_event_a_released);
+    EXPECT_FALSE(key_a4_released.IsRepeat());
+  }
 
 #if defined(USE_X11)
-  KeyEvent key_a4_pressed(native_event_a_pressed);
-  EXPECT_FALSE(key_a4_pressed.IsRepeat());
+  {
+    KeyEvent key_a4_pressed(native_event_a_pressed);
+    EXPECT_FALSE(key_a4_pressed.IsRepeat());
 
-  KeyEvent key_a4_pressed_nonstandard_state(
-      native_event_a_pressed_nonstandard_state);
-  EXPECT_FALSE(key_a4_pressed_nonstandard_state.IsRepeat());
+    KeyEvent key_a4_pressed_nonstandard_state(
+        native_event_a_pressed_nonstandard_state);
+    EXPECT_FALSE(key_a4_pressed_nonstandard_state.IsRepeat());
+  }
 #endif
 }
 #endif  // USE_X11 || OS_WIN
diff --git a/ui/events/events.gyp b/ui/events/events.gyp
index 8af08c5..833b30f 100644
--- a/ui/events/events.gyp
+++ b/ui/events/events.gyp
@@ -54,6 +54,10 @@
         'gestures/fling_curve.h',
         'gestures/gesture_configuration.cc',
         'gestures/gesture_configuration.h',
+        'input_device.cc',
+        'input_device.h',
+        'keyboard_device.cc',
+        'keyboard_device.h',
         'keycodes/keyboard_code_conversion.cc',
         'keycodes/keyboard_code_conversion.h',
         'keycodes/keyboard_code_conversion_android.cc',
@@ -270,8 +274,8 @@
         'test/events_test_utils.h',
         'test/events_test_utils_x11.cc',
         'test/events_test_utils_x11.h',
-        'test/mock_motion_event.cc',
-        'test/mock_motion_event.h',
+        'test/motion_event_test_utils.cc',
+        'test/motion_event_test_utils.h',
         'test/platform_event_waiter.cc',
         'test/platform_event_waiter.h',
         'test/test_event_handler.cc',
@@ -329,6 +333,7 @@
         'keycodes/dom4/keycode_converter_unittest.cc',
         'latency_info_unittest.cc',
         'platform/platform_event_source_unittest.cc',
+        'x/device_data_manager_x11_unittest.cc',
         'x/events_x_unittest.cc',
       ],
       'conditions': [
diff --git a/ui/events/gesture_detection/bitset_32.h b/ui/events/gesture_detection/bitset_32.h
index 1cc2dad..7b347f16 100644
--- a/ui/events/gesture_detection/bitset_32.h
+++ b/ui/events/gesture_detection/bitset_32.h
@@ -87,7 +87,7 @@
     return n;
   }
 
-  // Gets the inde of the specified bit in the set, which is the number of
+  // Gets the index of the specified bit in the set, which is the number of
   // marked bits that appear before the specified bit.
   inline uint32_t get_index_of_bit(uint32_t n) const {
     DCHECK_LE(n, 31U);
diff --git a/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc b/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc
index f8af11e..5ea3dc2 100644
--- a/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc
+++ b/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc
@@ -5,7 +5,7 @@
 #include "base/basictypes.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/gesture_detection/gesture_event_data_packet.h"
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
 
 using ui::test::MockMotionEvent;
 
diff --git a/ui/events/gesture_detection/gesture_provider_unittest.cc b/ui/events/gesture_detection/gesture_provider_unittest.cc
index da305ff..e933b7fd 100644
--- a/ui/events/gesture_detection/gesture_provider_unittest.cc
+++ b/ui/events/gesture_detection/gesture_provider_unittest.cc
@@ -12,7 +12,7 @@
 #include "ui/events/gesture_detection/gesture_event_data.h"
 #include "ui/events/gesture_detection/gesture_provider.h"
 #include "ui/events/gesture_detection/motion_event.h"
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
 #include "ui/gfx/geometry/point_f.h"
 
 using base::TimeDelta;
diff --git a/ui/events/gesture_detection/motion_event.cc b/ui/events/gesture_detection/motion_event.cc
index 71a6912..3c25a7af 100644
--- a/ui/events/gesture_detection/motion_event.cc
+++ b/ui/events/gesture_detection/motion_event.cc
@@ -5,6 +5,7 @@
 #include "ui/events/gesture_detection/motion_event.h"
 
 #include "base/logging.h"
+#include "ui/events/gesture_detection/motion_event_generic.h"
 
 namespace ui {
 
@@ -45,49 +46,12 @@
   return -1;
 }
 
-bool operator==(const MotionEvent& lhs, const MotionEvent& rhs) {
-  if (lhs.GetId() != rhs.GetId() || lhs.GetAction() != rhs.GetAction() ||
-      lhs.GetActionIndex() != rhs.GetActionIndex() ||
-      lhs.GetPointerCount() != rhs.GetPointerCount() ||
-      lhs.GetButtonState() != rhs.GetButtonState() ||
-      lhs.GetEventTime() != rhs.GetEventTime() ||
-      lhs.GetHistorySize() != rhs.GetHistorySize())
-    return false;
-
-  for (size_t i = 0; i < lhs.GetPointerCount(); ++i) {
-    int rhsi = rhs.FindPointerIndexOfId(lhs.GetPointerId(i));
-    if (rhsi == -1)
-      return false;
-
-    if (lhs.GetX(i) != rhs.GetX(rhsi) || lhs.GetY(i) != rhs.GetY(rhsi) ||
-        lhs.GetRawX(i) != rhs.GetRawX(rhsi) ||
-        lhs.GetRawY(i) != rhs.GetRawY(rhsi) ||
-        lhs.GetTouchMajor(i) != rhs.GetTouchMajor(rhsi) ||
-        lhs.GetTouchMinor(i) != rhs.GetTouchMinor(rhsi) ||
-        lhs.GetOrientation(i) != rhs.GetOrientation(rhsi) ||
-        lhs.GetPressure(i) != rhs.GetPressure(rhsi) ||
-        lhs.GetToolType(i) != rhs.GetToolType(rhsi))
-      return false;
-
-    for (size_t h = 0; h < lhs.GetHistorySize(); ++h) {
-      if (lhs.GetHistoricalX(i, h) != rhs.GetHistoricalX(rhsi, h) ||
-          lhs.GetHistoricalY(i, h) != rhs.GetHistoricalY(rhsi, h) ||
-          lhs.GetHistoricalTouchMajor(i, h) !=
-              rhs.GetHistoricalTouchMajor(rhsi, h))
-        return false;
-    }
-  }
-
-  for (size_t h = 0; h < lhs.GetHistorySize(); ++h) {
-    if (lhs.GetHistoricalEventTime(h) != rhs.GetHistoricalEventTime(h))
-      return false;
-  }
-
-  return true;
+scoped_ptr<MotionEvent> MotionEvent::Clone() const {
+  return MotionEventGeneric::CloneEvent(*this);
 }
 
-bool operator!=(const MotionEvent& lhs, const MotionEvent& rhs) {
-  return !(lhs == rhs);
+scoped_ptr<MotionEvent> MotionEvent::Cancel() const {
+  return MotionEventGeneric::CancelEvent(*this);
 }
 
 }  // namespace ui
diff --git a/ui/events/gesture_detection/motion_event.h b/ui/events/gesture_detection/motion_event.h
index 2277277a..469b656 100644
--- a/ui/events/gesture_detection/motion_event.h
+++ b/ui/events/gesture_detection/motion_event.h
@@ -76,9 +76,7 @@
   virtual float GetHistoricalY(size_t pointer_index,
                                size_t historical_index) const;
 
-  virtual scoped_ptr<MotionEvent> Clone() const = 0;
-  virtual scoped_ptr<MotionEvent> Cancel() const = 0;
-
+  // Utility accessor methods for convenience.
   float GetX() const { return GetX(0); }
   float GetY() const { return GetY(0); }
   float GetRawX() const { return GetRawX(0); }
@@ -98,12 +96,14 @@
 
   // O(N) search of pointers (use sparingly!). Returns -1 if |id| nonexistent.
   int FindPointerIndexOfId(int id) const;
-};
 
-GESTURE_DETECTION_EXPORT bool operator==(const MotionEvent& lhs,
-                                         const MotionEvent& rhs);
-GESTURE_DETECTION_EXPORT bool operator!=(const MotionEvent& lhs,
-                                         const MotionEvent& rhs);
+  // Note that these methods perform shallow copies of the originating events.
+  // They guarantee only that the returned type will reflect the same
+  // data exposed by the MotionEvent interface; no guarantees are made that the
+  // underlying implementation is identical to the source implementation.
+  scoped_ptr<MotionEvent> Clone() const;
+  scoped_ptr<MotionEvent> Cancel() const;
+};
 
 }  // namespace ui
 
diff --git a/ui/events/gesture_detection/motion_event_buffer.cc b/ui/events/gesture_detection/motion_event_buffer.cc
index 89690d650..d1dec70 100644
--- a/ui/events/gesture_detection/motion_event_buffer.cc
+++ b/ui/events/gesture_detection/motion_event_buffer.cc
@@ -5,7 +5,6 @@
 #include "ui/events/gesture_detection/motion_event_buffer.h"
 
 #include "base/debug/trace_event.h"
-#include "ui/events/gesture_detection/motion_event.h"
 #include "ui/events/gesture_detection/motion_event_generic.h"
 
 namespace ui {
@@ -24,7 +23,7 @@
 // the last time delta.
 const int kResampleMaxPredictionMs = 8;
 
-typedef ScopedVector<MotionEvent> MotionEventVector;
+typedef ScopedVector<MotionEventGeneric> MotionEventVector;
 
 float Lerp(float a, float b, float alpha) {
   return a + alpha * (b - a);
@@ -86,22 +85,8 @@
   return unconsumed_batch.Pass();
 }
 
-PointerProperties PointerFromMotionEvent(const MotionEvent& event,
-                                         size_t pointer_index) {
-  PointerProperties result;
-  result.id = event.GetPointerId(pointer_index);
-  result.tool_type = event.GetToolType(pointer_index);
-  result.x = event.GetX(pointer_index);
-  result.y = event.GetY(pointer_index);
-  result.raw_x = event.GetRawX(pointer_index);
-  result.raw_y = event.GetRawY(pointer_index);
-  result.pressure = event.GetPressure(pointer_index);
-  result.touch_major = event.GetTouchMajor(pointer_index);
-  result.touch_minor = event.GetTouchMinor(pointer_index);
-  result.orientation = event.GetOrientation(pointer_index);
-  return result;
-}
-
+// Linearly interpolate the pointer position between two MotionEvent samples.
+// Only pointers of finger or unknown type will be resampled.
 PointerProperties ResamplePointer(const MotionEvent& event0,
                                   const MotionEvent& event1,
                                   size_t event0_pointer_index,
@@ -113,12 +98,12 @@
   // horizon (i.e., the event no later than the time interpolated by alpha).
   if (!ShouldResampleTool(event0.GetToolType(event0_pointer_index))) {
     if (alpha > 1)
-      return PointerFromMotionEvent(event1, event1_pointer_index);
+      return PointerProperties(event1, event1_pointer_index);
     else
-      return PointerFromMotionEvent(event0, event0_pointer_index);
+      return PointerProperties(event0, event0_pointer_index);
   }
 
-  PointerProperties p(PointerFromMotionEvent(event0, event0_pointer_index));
+  PointerProperties p(event0, event0_pointer_index);
   p.x = Lerp(p.x, event1.GetX(event1_pointer_index), alpha);
   p.y = Lerp(p.y, event1.GetY(event1_pointer_index), alpha);
   p.raw_x = Lerp(p.raw_x, event1.GetRawX(event1_pointer_index), alpha);
@@ -126,9 +111,12 @@
   return p;
 }
 
-scoped_ptr<MotionEvent> ResampleMotionEvent(const MotionEvent& event0,
-                                            const MotionEvent& event1,
-                                            base::TimeTicks resample_time) {
+// Linearly interpolate the pointers between two event samples using the
+// provided |resample_time|.
+scoped_ptr<MotionEventGeneric> ResampleMotionEvent(
+    const MotionEvent& event0,
+    const MotionEvent& event1,
+    base::TimeTicks resample_time) {
   DCHECK_EQ(MotionEvent::ACTION_MOVE, event0.GetAction());
   DCHECK_EQ(event0.GetPointerCount(), event1.GetPointerCount());
 
@@ -161,184 +149,88 @@
   event->set_id(event0.GetId());
   event->set_action_index(event0.GetActionIndex());
   event->set_button_state(event0.GetButtonState());
-
   return event.Pass();
 }
 
-// MotionEvent implementation for storing multiple events, with the most
-// recent event used as the base event, and prior events used as the history.
-class CompoundMotionEvent : public ui::MotionEvent {
- public:
-  explicit CompoundMotionEvent(MotionEventVector events)
-      : events_(events.Pass()) {
-    DCHECK_GE(events_.size(), 1U);
-  }
-  ~CompoundMotionEvent() override {}
+// Synthesize a compound MotionEventGeneric event from a sequence of events.
+// Events must be in non-decreasing (time) order.
+scoped_ptr<MotionEventGeneric> ConsumeSamples(MotionEventVector events) {
+  DCHECK(!events.empty());
+  scoped_ptr<MotionEventGeneric> event(events.back());
+  for (size_t i = 0; i + 1 < events.size(); ++i)
+    event->PushHistoricalEvent(scoped_ptr<MotionEvent>(events[i]));
+  events.weak_clear();
+  return event.Pass();
+}
 
-  int GetId() const override { return latest().GetId(); }
+// Consume a series of event samples, attempting to synthesize a new, synthetic
+// event if the samples and sample time meet certain interpolation/extrapolation
+// conditions. If such conditions are met, the provided samples will be added
+// to the synthetic event's history, otherwise, the samples will be used to
+// generate a basic, compound event.
+// TODO(jdduke): Revisit resampling to handle cases where alternating frames
+// are resampled or resampling is otherwise inconsistent, e.g., a 90hz input
+// and 60hz frame signal could phase-align such that even frames yield an
+// extrapolated event and odd frames are not resampled, crbug.com/399381.
+scoped_ptr<MotionEventGeneric> ConsumeSamplesAndTryResampling(
+    base::TimeTicks resample_time,
+    MotionEventVector events,
+    const MotionEvent* next) {
+  const ui::MotionEvent* event0 = nullptr;
+  const ui::MotionEvent* event1 = nullptr;
+  if (next) {
+    DCHECK(resample_time < next->GetEventTime());
+    // Interpolate between current sample and future sample.
+    event0 = events.back();
+    event1 = next;
+  } else if (events.size() >= 2) {
+    // Extrapolate future sample using current sample and past sample.
+    event0 = events[events.size() - 2];
+    event1 = events[events.size() - 1];
 
-  Action GetAction() const override { return latest().GetAction(); }
-
-  int GetActionIndex() const override { return latest().GetActionIndex(); }
-
-  size_t GetPointerCount() const override { return latest().GetPointerCount(); }
-
-  int GetPointerId(size_t pointer_index) const override {
-    return latest().GetPointerId(pointer_index);
-  }
-
-  float GetX(size_t pointer_index) const override {
-    return latest().GetX(pointer_index);
-  }
-
-  float GetY(size_t pointer_index) const override {
-    return latest().GetY(pointer_index);
-  }
-
-  float GetRawX(size_t pointer_index) const override {
-    return latest().GetRawX(pointer_index);
-  }
-
-  float GetRawY(size_t pointer_index) const override {
-    return latest().GetRawY(pointer_index);
-  }
-
-  float GetTouchMajor(size_t pointer_index) const override {
-    return latest().GetTouchMajor(pointer_index);
-  }
-
-  float GetTouchMinor(size_t pointer_index) const override {
-    return latest().GetTouchMinor(pointer_index);
-  }
-
-  float GetOrientation(size_t pointer_index) const override {
-    return latest().GetOrientation(pointer_index);
-  }
-
-  float GetPressure(size_t pointer_index) const override {
-    return latest().GetPressure(pointer_index);
-  }
-
-  ToolType GetToolType(size_t pointer_index) const override {
-    return latest().GetToolType(pointer_index);
-  }
-
-  int GetButtonState() const override { return latest().GetButtonState(); }
-
-  int GetFlags() const override { return latest().GetFlags(); }
-
-  base::TimeTicks GetEventTime() const override {
-    return latest().GetEventTime();
-  }
-
-  size_t GetHistorySize() const override { return events_.size() - 1; }
-
-  base::TimeTicks GetHistoricalEventTime(
-      size_t historical_index) const override {
-    DCHECK_LT(historical_index, GetHistorySize());
-    return events_[historical_index]->GetEventTime();
-  }
-
-  float GetHistoricalTouchMajor(size_t pointer_index,
-                                size_t historical_index) const override {
-    DCHECK_LT(historical_index, GetHistorySize());
-    return events_[historical_index]->GetTouchMajor();
-  }
-
-  float GetHistoricalX(size_t pointer_index,
-                       size_t historical_index) const override {
-    DCHECK_LT(historical_index, GetHistorySize());
-    return events_[historical_index]->GetX(pointer_index);
-  }
-
-  float GetHistoricalY(size_t pointer_index,
-                       size_t historical_index) const override {
-    DCHECK_LT(historical_index, GetHistorySize());
-    return events_[historical_index]->GetY(pointer_index);
-  }
-
-  scoped_ptr<MotionEvent> Clone() const override {
-    MotionEventVector cloned_events;
-    cloned_events.reserve(events_.size());
-    for (size_t i = 0; i < events_.size(); ++i)
-      cloned_events.push_back(events_[i]->Clone().release());
-    return scoped_ptr<MotionEvent>(
-        new CompoundMotionEvent(cloned_events.Pass()));
-  }
-
-  scoped_ptr<MotionEvent> Cancel() const override { return latest().Cancel(); }
-
-  // Returns the new, resampled event, or NULL if none was created.
-  // TODO(jdduke): Revisit resampling to handle cases where alternating frames
-  // are resampled or resampling is otherwise inconsistent, e.g., a 90hz input
-  // and 60hz frame signal could phase-align such that even frames yield an
-  // extrapolated event and odd frames are not resampled, crbug.com/399381.
-  const MotionEvent* TryResample(base::TimeTicks resample_time,
-                                 const ui::MotionEvent* next) {
-    DCHECK_EQ(GetAction(), ACTION_MOVE);
-    const ui::MotionEvent* event0 = NULL;
-    const ui::MotionEvent* event1 = NULL;
-    if (next) {
-      DCHECK(resample_time < next->GetEventTime());
-      // Interpolate between current sample and future sample.
-      event0 = events_.back();
-      event1 = next;
-    } else if (events_.size() >= 2) {
-      // Extrapolate future sample using current sample and past sample.
-      event0 = events_[events_.size() - 2];
-      event1 = events_[events_.size() - 1];
-
-      const base::TimeTicks time1 = event1->GetEventTime();
-      base::TimeTicks max_predict =
-          time1 +
-          std::min((event1->GetEventTime() - event0->GetEventTime()) / 2,
-                   base::TimeDelta::FromMilliseconds(kResampleMaxPredictionMs));
-      if (resample_time > max_predict) {
-        TRACE_EVENT_INSTANT2("input",
-                             "MotionEventBuffer::TryResample prediction adjust",
-                             TRACE_EVENT_SCOPE_THREAD,
-                             "original(ms)",
-                             (resample_time - time1).InMilliseconds(),
-                             "adjusted(ms)",
-                             (max_predict - time1).InMilliseconds());
-        resample_time = max_predict;
-      }
-    } else {
-      TRACE_EVENT_INSTANT0("input",
-                           "MotionEventBuffer::TryResample insufficient data",
-                           TRACE_EVENT_SCOPE_THREAD);
-      return NULL;
-    }
-
-    DCHECK(event0);
-    DCHECK(event1);
-    const base::TimeTicks time0 = event0->GetEventTime();
     const base::TimeTicks time1 = event1->GetEventTime();
-    base::TimeDelta delta = time1 - time0;
-    if (delta < base::TimeDelta::FromMilliseconds(kResampleMinDeltaMs)) {
-      TRACE_EVENT_INSTANT1("input",
-                           "MotionEventBuffer::TryResample failure",
+    base::TimeTicks max_predict =
+        time1 +
+        std::min((event1->GetEventTime() - event0->GetEventTime()) / 2,
+                 base::TimeDelta::FromMilliseconds(kResampleMaxPredictionMs));
+    if (resample_time > max_predict) {
+      TRACE_EVENT_INSTANT2("input",
+                           "MotionEventBuffer::TryResample prediction adjust",
                            TRACE_EVENT_SCOPE_THREAD,
-                           "event_delta_too_small(ms)",
-                           delta.InMilliseconds());
-      return NULL;
+                           "original(ms)",
+                           (resample_time - time1).InMilliseconds(),
+                           "adjusted(ms)",
+                           (max_predict - time1).InMilliseconds());
+      resample_time = max_predict;
     }
-
-    events_.push_back(
-        ResampleMotionEvent(*event0, *event1, resample_time).release());
-    return events_.back();
+  } else {
+    TRACE_EVENT_INSTANT0("input",
+                         "MotionEventBuffer::TryResample insufficient data",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return ConsumeSamples(events.Pass());
   }
 
-  size_t samples() const { return events_.size(); }
+  DCHECK(event0);
+  DCHECK(event1);
+  const base::TimeTicks time0 = event0->GetEventTime();
+  const base::TimeTicks time1 = event1->GetEventTime();
+  base::TimeDelta delta = time1 - time0;
+  if (delta < base::TimeDelta::FromMilliseconds(kResampleMinDeltaMs)) {
+    TRACE_EVENT_INSTANT1("input",
+                         "MotionEventBuffer::TryResample failure",
+                         TRACE_EVENT_SCOPE_THREAD,
+                         "event_delta_too_small(ms)",
+                         delta.InMilliseconds());
+    return ConsumeSamples(events.Pass());
+  }
 
- private:
-  const MotionEvent& latest() const { return *events_.back(); }
-
-  // Events are in order from oldest to newest.
-  MotionEventVector events_;
-
-  DISALLOW_COPY_AND_ASSIGN(CompoundMotionEvent);
-};
+  scoped_ptr<MotionEventGeneric> resampled_event =
+      ResampleMotionEvent(*event0, *event1, resample_time);
+  for (size_t i = 0; i < events.size(); ++i)
+    resampled_event->PushHistoricalEvent(scoped_ptr<MotionEvent>(events[i]));
+  events.weak_clear();
+  return resampled_event.Pass();
+}
 
 }  // namespace
 
@@ -351,6 +243,7 @@
 }
 
 void MotionEventBuffer::OnMotionEvent(const MotionEvent& event) {
+  DCHECK_EQ(0U, event.GetHistorySize());
   if (event.GetAction() != MotionEvent::ACTION_MOVE) {
     last_extrapolated_event_time_ = base::TimeTicks();
     if (!buffered_events_.empty())
@@ -368,7 +261,7 @@
     last_extrapolated_event_time_ = base::TimeTicks();
   }
 
-  scoped_ptr<MotionEvent> clone = event.Clone();
+  scoped_ptr<MotionEventGeneric> clone = MotionEventGeneric::CloneEvent(event);
   if (buffered_events_.empty()) {
     buffered_events_.push_back(clone.release());
     client_->SetNeedsFlush();
@@ -411,26 +304,29 @@
     return;
   }
 
-  CompoundMotionEvent resampled_event(events.Pass());
-  base::TimeTicks original_event_time = resampled_event.GetEventTime();
-  const MotionEvent* next_event =
-      !buffered_events_.empty() ? buffered_events_.front() : NULL;
+  FlushWithResampling(events.Pass(), frame_time);
+}
 
-  // Try to interpolate/extrapolate a new event at |frame_time|. Note that
-  // |new_event|, if non-NULL, is owned by |resampled_event_|.
-  const MotionEvent* new_event =
-      resampled_event.TryResample(frame_time, next_event);
+void MotionEventBuffer::FlushWithResampling(MotionEventVector events,
+                                            base::TimeTicks resample_time) {
+  DCHECK(!events.empty());
+  base::TimeTicks original_event_time = events.back()->GetEventTime();
+  const MotionEvent* next_event =
+      !buffered_events_.empty() ? buffered_events_.front() : nullptr;
+
+  scoped_ptr<MotionEventGeneric> resampled_event =
+      ConsumeSamplesAndTryResampling(resample_time, events.Pass(), next_event);
+  DCHECK(resampled_event);
 
   // Log the extrapolated event time, guarding against subsequently queued
   // events that might have an earlier timestamp.
-  if (!next_event && new_event &&
-      new_event->GetEventTime() > original_event_time) {
-    last_extrapolated_event_time_ = new_event->GetEventTime();
+  if (!next_event && resampled_event->GetEventTime() > original_event_time) {
+    last_extrapolated_event_time_ = resampled_event->GetEventTime();
   } else {
     last_extrapolated_event_time_ = base::TimeTicks();
   }
 
-  client_->ForwardMotionEvent(resampled_event);
+  client_->ForwardMotionEvent(*resampled_event);
   if (!buffered_events_.empty())
     client_->SetNeedsFlush();
 }
@@ -440,16 +336,7 @@
   if (events.empty())
     return;
 
-  if (events.size() == 1) {
-    // Avoid CompoundEvent creation to prevent unnecessary allocations.
-    scoped_ptr<MotionEvent> event(events.front());
-    events.weak_clear();
-    client_->ForwardMotionEvent(*event);
-    return;
-  }
-
-  CompoundMotionEvent compound_event(events.Pass());
-  client_->ForwardMotionEvent(compound_event);
+  client_->ForwardMotionEvent(*ConsumeSamples(events.Pass()));
 }
 
 }  // namespace ui
diff --git a/ui/events/gesture_detection/motion_event_buffer.h b/ui/events/gesture_detection/motion_event_buffer.h
index 498d5535..7a5e597 100644
--- a/ui/events/gesture_detection/motion_event_buffer.h
+++ b/ui/events/gesture_detection/motion_event_buffer.h
@@ -13,6 +13,7 @@
 namespace ui {
 
 class MotionEvent;
+class MotionEventGeneric;
 
 // Allows event forwarding and flush requests from a |MotionEventBuffer|.
 class MotionEventBufferClient {
@@ -52,8 +53,10 @@
   void Flush(base::TimeTicks frame_time);
 
  private:
-  typedef ScopedVector<MotionEvent> MotionEventVector;
+  typedef ScopedVector<MotionEventGeneric> MotionEventVector;
 
+  void FlushWithResampling(MotionEventVector events,
+                           base::TimeTicks resample_time);
   void FlushWithoutResampling(MotionEventVector events);
 
   MotionEventBufferClient* const client_;
@@ -61,7 +64,7 @@
 
   // Time of the most recently extrapolated event. This will be 0 if the
   // last sent event was not extrapolated. Used internally to guard against
-  // conflicts between events received from the platfrom that may have an
+  // conflicts between events received from the platform that may have an
   // earlier timestamp than that synthesized at the latest resample.
   base::TimeTicks last_extrapolated_event_time_;
 
diff --git a/ui/events/gesture_detection/motion_event_buffer_unittest.cc b/ui/events/gesture_detection/motion_event_buffer_unittest.cc
index badbd98..ba018b2 100644
--- a/ui/events/gesture_detection/motion_event_buffer_unittest.cc
+++ b/ui/events/gesture_detection/motion_event_buffer_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/gesture_detection/motion_event_buffer.h"
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
 
 using base::TimeDelta;
 using base::TimeTicks;
@@ -41,14 +41,14 @@
                               public MotionEventBufferClient {
  public:
   MotionEventBufferTest() : needs_flush_(false) {}
-  virtual ~MotionEventBufferTest() {}
+  ~MotionEventBufferTest() override {}
 
   // MotionEventBufferClient implementation.
-  virtual void ForwardMotionEvent(const MotionEvent& event) override {
+  void ForwardMotionEvent(const MotionEvent& event) override {
     forwarded_events_.push_back(event.Clone().release());
   }
 
-  virtual void SetNeedsFlush() override { needs_flush_ = true; }
+  void SetNeedsFlush() override { needs_flush_ = true; }
 
   bool GetAndResetNeedsFlush() {
     bool needs_flush = needs_flush_;
@@ -344,9 +344,9 @@
   event_time += base::TimeDelta::FromMilliseconds(5);
 
   // Events with different pointer ids should not combine.
-  PointerProperties pointer0(5.f, 5.f);
+  PointerProperties pointer0(5.f, 5.f, 1.f);
   pointer0.id = 1;
-  PointerProperties pointer1(10.f, 10.f);
+  PointerProperties pointer1(10.f, 10.f, 2.f);
   pointer1.id = 2;
   MotionEventGeneric move3(MotionEvent::ACTION_MOVE, event_time, pointer0);
   move3.PushPointer(pointer1);
@@ -407,9 +407,9 @@
   base::TimeTicks event_time = base::TimeTicks::Now();
   MotionEventBuffer buffer(this, true);
 
-  PointerProperties p0(1.f, 2.f);
+  PointerProperties p0(1.f, 2.f, 3.f);
   p0.id = 1;
-  PointerProperties p1(2.f, 1.f);
+  PointerProperties p1(2.f, 1.f, 0.5f);
   p1.id = 2;
 
   MotionEventGeneric move0(MotionEvent::ACTION_MOVE, event_time, p0);
diff --git a/ui/events/gesture_detection/motion_event_generic.cc b/ui/events/gesture_detection/motion_event_generic.cc
index ad853f5..6b4b61d7 100644
--- a/ui/events/gesture_detection/motion_event_generic.cc
+++ b/ui/events/gesture_detection/motion_event_generic.cc
@@ -21,7 +21,7 @@
       orientation(0) {
 }
 
-PointerProperties::PointerProperties(float x, float y)
+PointerProperties::PointerProperties(float x, float y, float touch_major)
     : id(0),
       tool_type(MotionEvent::TOOL_TYPE_UNKNOWN),
       x(x),
@@ -29,17 +29,23 @@
       raw_x(x),
       raw_y(y),
       pressure(0),
-      touch_major(0),
+      touch_major(touch_major),
       touch_minor(0),
       orientation(0) {
 }
 
-MotionEventGeneric::MotionEventGeneric()
-    : action_(ACTION_CANCEL),
-      id_(0),
-      action_index_(0),
-      button_state_(0),
-      flags_(0) {
+PointerProperties::PointerProperties(const MotionEvent& event,
+                                     size_t pointer_index)
+    : id(event.GetPointerId(pointer_index)),
+      tool_type(event.GetToolType(pointer_index)),
+      x(event.GetX(pointer_index)),
+      y(event.GetY(pointer_index)),
+      raw_x(event.GetRawX(pointer_index)),
+      raw_y(event.GetRawY(pointer_index)),
+      pressure(event.GetPressure(pointer_index)),
+      touch_major(event.GetTouchMajor(pointer_index)),
+      touch_minor(event.GetTouchMinor(pointer_index)),
+      orientation(event.GetOrientation(pointer_index)) {
 }
 
 MotionEventGeneric::MotionEventGeneric(Action action,
@@ -62,6 +68,9 @@
       button_state_(other.button_state_),
       flags_(other.flags_),
       pointers_(other.pointers_) {
+  const size_t history_size = other.GetHistorySize();
+  for (size_t h = 0; h < history_size; ++h)
+    PushHistoricalEvent(other.historical_events_[h]->Clone());
 }
 
 MotionEventGeneric::~MotionEventGeneric() {
@@ -146,20 +155,119 @@
   return event_time_;
 }
 
-scoped_ptr<MotionEvent> MotionEventGeneric::Clone() const {
-  return scoped_ptr<MotionEvent>(new MotionEventGeneric(*this));
+size_t MotionEventGeneric::GetHistorySize() const {
+  return historical_events_.size();
 }
 
-scoped_ptr<MotionEvent> MotionEventGeneric::Cancel() const {
-  scoped_ptr<MotionEventGeneric> event(new MotionEventGeneric(*this));
-  event->set_action(ACTION_CANCEL);
-  return event.Pass();
+base::TimeTicks MotionEventGeneric::GetHistoricalEventTime(
+    size_t historical_index) const {
+  DCHECK_LT(historical_index, historical_events_.size());
+  return historical_events_[historical_index]->GetEventTime();
+}
+
+float MotionEventGeneric::GetHistoricalTouchMajor(
+    size_t pointer_index,
+    size_t historical_index) const {
+  DCHECK_LT(historical_index, historical_events_.size());
+  return historical_events_[historical_index]->GetTouchMajor(pointer_index);
+}
+
+float MotionEventGeneric::GetHistoricalX(size_t pointer_index,
+                                         size_t historical_index) const {
+  DCHECK_LT(historical_index, historical_events_.size());
+  return historical_events_[historical_index]->GetX(pointer_index);
+}
+
+float MotionEventGeneric::GetHistoricalY(size_t pointer_index,
+                                         size_t historical_index) const {
+  DCHECK_LT(historical_index, historical_events_.size());
+  return historical_events_[historical_index]->GetY(pointer_index);
+}
+
+// static
+scoped_ptr<MotionEventGeneric> MotionEventGeneric::CloneEvent(
+    const MotionEvent& event) {
+  bool with_history = true;
+  return make_scoped_ptr(new MotionEventGeneric(event, with_history));
+}
+
+// static
+scoped_ptr<MotionEventGeneric> MotionEventGeneric::CancelEvent(
+    const MotionEvent& event) {
+  bool with_history = false;
+  scoped_ptr<MotionEventGeneric> cancel_event(
+      new MotionEventGeneric(event, with_history));
+  cancel_event->set_action(ACTION_CANCEL);
+  return cancel_event.Pass();
 }
 
 void MotionEventGeneric::PushPointer(const PointerProperties& pointer) {
+  DCHECK_EQ(0U, GetHistorySize());
   pointers_->push_back(pointer);
 }
 
+void MotionEventGeneric::PushHistoricalEvent(scoped_ptr<MotionEvent> event) {
+  DCHECK(event);
+  DCHECK_EQ(event->GetAction(), ACTION_MOVE);
+  DCHECK_EQ(event->GetPointerCount(), GetPointerCount());
+  DCHECK_EQ(event->GetAction(), GetAction());
+  DCHECK_LE(event->GetEventTime().ToInternalValue(),
+            GetEventTime().ToInternalValue());
+  historical_events_.push_back(event.release());
+}
+
+MotionEventGeneric::MotionEventGeneric()
+    : action_(ACTION_CANCEL), id_(0), action_index_(0), button_state_(0) {
+}
+
+MotionEventGeneric::MotionEventGeneric(const MotionEvent& event,
+                                       bool with_history)
+    : action_(event.GetAction()),
+      event_time_(event.GetEventTime()),
+      id_(event.GetId()),
+      action_index_(
+          (action_ == ACTION_POINTER_UP || action_ == ACTION_POINTER_DOWN)
+              ? event.GetActionIndex()
+              : 0),
+      button_state_(event.GetButtonState()),
+      flags_(event.GetFlags()) {
+  const size_t pointer_count = event.GetPointerCount();
+  for (size_t i = 0; i < pointer_count; ++i)
+    PushPointer(PointerProperties(event, i));
+
+  if (!with_history)
+    return;
+
+  const size_t history_size = event.GetHistorySize();
+  for (size_t h = 0; h < history_size; ++h) {
+    scoped_ptr<MotionEventGeneric> historical_event(new MotionEventGeneric());
+    historical_event->set_action(ACTION_MOVE);
+    historical_event->set_event_time(event.GetHistoricalEventTime(h));
+    for (size_t i = 0; i < pointer_count; ++i) {
+      historical_event->PushPointer(
+          PointerProperties(event.GetHistoricalX(i, h),
+                            event.GetHistoricalY(i, h),
+                            event.GetHistoricalTouchMajor(i, h)));
+    }
+    PushHistoricalEvent(historical_event.Pass());
+  }
+}
+
+MotionEventGeneric& MotionEventGeneric::operator=(
+    const MotionEventGeneric& other) {
+  action_ = other.action_;
+  event_time_ = other.event_time_;
+  id_ = other.id_;
+  action_index_ = other.action_index_;
+  button_state_ = other.button_state_;
+  flags_ = other.flags_;
+  pointers_ = other.pointers_;
+  const size_t history_size = other.GetHistorySize();
+  for (size_t h = 0; h < history_size; ++h)
+    PushHistoricalEvent(other.historical_events_[h]->Clone());
+  return *this;
+}
+
 void MotionEventGeneric::PopPointer() {
   DCHECK_GT(pointers_->size(), 0U);
   pointers_->pop_back();
diff --git a/ui/events/gesture_detection/motion_event_generic.h b/ui/events/gesture_detection/motion_event_generic.h
index 17109cb..359a651 100644
--- a/ui/events/gesture_detection/motion_event_generic.h
+++ b/ui/events/gesture_detection/motion_event_generic.h
@@ -7,6 +7,7 @@
 
 #include "base/basictypes.h"
 #include "base/containers/stack_container.h"
+#include "base/memory/scoped_vector.h"
 #include "ui/events/gesture_detection/gesture_detection_export.h"
 #include "ui/events/gesture_detection/motion_event.h"
 
@@ -14,7 +15,8 @@
 
 struct GESTURE_DETECTION_EXPORT PointerProperties {
   PointerProperties();
-  PointerProperties(float x, float y);
+  PointerProperties(float x, float y, float touch_major);
+  PointerProperties(const MotionEvent& event, size_t pointer_index);
 
   int id;
   MotionEvent::ToolType tool_type;
@@ -56,11 +58,22 @@
   int GetButtonState() const override;
   int GetFlags() const override;
   base::TimeTicks GetEventTime() const override;
-  scoped_ptr<MotionEvent> Clone() const override;
-  scoped_ptr<MotionEvent> Cancel() const override;
+  size_t GetHistorySize() const override;
+  base::TimeTicks GetHistoricalEventTime(
+      size_t historical_index) const override;
+  float GetHistoricalTouchMajor(size_t pointer_index,
+                                size_t historical_index) const override;
+  float GetHistoricalX(size_t pointer_index,
+                       size_t historical_index) const override;
+  float GetHistoricalY(size_t pointer_index,
+                       size_t historical_index) const override;
 
   void PushPointer(const PointerProperties& pointer);
 
+  // Add an event to the history. |this| and |event| must have the same pointer
+  // count and must both have an action of ACTION_MOVE.
+  void PushHistoricalEvent(scoped_ptr<MotionEvent> event);
+
   void set_action(Action action) { action_ = action; }
   void set_event_time(base::TimeTicks event_time) { event_time_ = event_time; }
   void set_id(int id) { id_ = id; }
@@ -68,8 +81,13 @@
   void set_button_state(int button_state) { button_state_ = button_state; }
   void set_flags(int flags) { flags_ = flags; }
 
+  static scoped_ptr<MotionEventGeneric> CloneEvent(const MotionEvent& event);
+  static scoped_ptr<MotionEventGeneric> CancelEvent(const MotionEvent& event);
+
  protected:
   MotionEventGeneric();
+  MotionEventGeneric(const MotionEvent& event, bool with_history);
+  MotionEventGeneric& operator=(const MotionEventGeneric& other);
 
   void PopPointer();
 
@@ -88,6 +106,7 @@
   int button_state_;
   int flags_;
   base::StackVector<PointerProperties, kTypicalMaxPointerCount> pointers_;
+  ScopedVector<MotionEvent> historical_events_;
 };
 
 }  // namespace ui
diff --git a/ui/events/gesture_detection/motion_event_generic_unittest.cc b/ui/events/gesture_detection/motion_event_generic_unittest.cc
index f1aa2937..23762e3f 100644
--- a/ui/events/gesture_detection/motion_event_generic_unittest.cc
+++ b/ui/events/gesture_detection/motion_event_generic_unittest.cc
@@ -5,6 +5,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/gesture_detection/motion_event_generic.h"
+#include "ui/events/test/motion_event_test_utils.h"
 
 namespace ui {
 
@@ -16,12 +17,12 @@
   EXPECT_EQ(0U, event.GetHistorySize());
   EXPECT_EQ(event_time, event.GetEventTime());
 
-  event.PushPointer(PointerProperties(8.3f, 4.7f));
+  event.PushPointer(PointerProperties(8.3f, 4.7f, 0.9f));
   ASSERT_EQ(2U, event.GetPointerCount());
   EXPECT_EQ(8.3f, event.GetX(1));
   EXPECT_EQ(4.7f, event.GetY(1));
 
-  event.PushPointer(PointerProperties(2.3f, -3.7f));
+  event.PushPointer(PointerProperties(2.3f, -3.7f, 5.8f));
   ASSERT_EQ(3U, event.GetPointerCount());
   EXPECT_EQ(2.3f, event.GetX(2));
   EXPECT_EQ(-3.7f, event.GetY(2));
@@ -44,31 +45,78 @@
 
   event.set_action_index(1);
   EXPECT_EQ(1, event.GetActionIndex());
+
+  event.set_action(MotionEvent::ACTION_MOVE);
+  EXPECT_EQ(MotionEvent::ACTION_MOVE, event.GetAction());
+
+  PointerProperties historical_pointer0(1.2f, 2.4f, 1.f);
+  PointerProperties historical_pointer1(2.4f, 4.8f, 2.f);
+  PointerProperties historical_pointer2(4.8f, 9.6f, 3.f);
+  MotionEventGeneric historical_event(
+      MotionEvent::ACTION_MOVE,
+      event_time - base::TimeDelta::FromMilliseconds(5),
+      historical_pointer0);
+  historical_event.PushPointer(historical_pointer1);
+  historical_event.PushPointer(historical_pointer2);
+
+  event.PushHistoricalEvent(historical_event.Clone());
+  EXPECT_EQ(1U, event.GetHistorySize());
+  EXPECT_EQ(event_time - base::TimeDelta::FromMilliseconds(5),
+            event.GetHistoricalEventTime(0));
+  EXPECT_EQ(1.2f, event.GetHistoricalX(0, 0));
+  EXPECT_EQ(2.4f, event.GetHistoricalY(0, 0));
+  EXPECT_EQ(1.f, event.GetHistoricalTouchMajor(0, 0));
+  EXPECT_EQ(2.4f, event.GetHistoricalX(1, 0));
+  EXPECT_EQ(4.8f, event.GetHistoricalY(1, 0));
+  EXPECT_EQ(2.f, event.GetHistoricalTouchMajor(1, 0));
+  EXPECT_EQ(4.8f, event.GetHistoricalX(2, 0));
+  EXPECT_EQ(9.6f, event.GetHistoricalY(2, 0));
+  EXPECT_EQ(3.f, event.GetHistoricalTouchMajor(2, 0));
 }
 
 TEST(MotionEventGenericTest, Clone) {
   MotionEventGeneric event(MotionEvent::ACTION_DOWN,
                            base::TimeTicks::Now(),
-                           PointerProperties(8.3f, 4.7f));
+                           PointerProperties(8.3f, 4.7f, 2.f));
   event.set_id(1);
   event.set_button_state(MotionEvent::BUTTON_PRIMARY);
 
   scoped_ptr<MotionEvent> clone = event.Clone();
   ASSERT_TRUE(clone);
-  EXPECT_EQ(event, *clone);
+  EXPECT_EQ(test::ToString(event), test::ToString(*clone));
+}
+
+TEST(MotionEventGenericTest, CloneWithHistory) {
+  base::TimeTicks event_time = base::TimeTicks::Now();
+  base::TimeTicks historical_event_time =
+      event_time - base::TimeDelta::FromMilliseconds(5);
+
+  PointerProperties pointer(8.3f, 4.7f, 10.1f);
+  MotionEventGeneric event(MotionEvent::ACTION_MOVE, event_time, pointer);
+
+  PointerProperties historical_pointer(3.4f, -4.3f, 11.5);
+  scoped_ptr<MotionEvent> historical_event(new MotionEventGeneric(
+      MotionEvent::ACTION_MOVE, historical_event_time, historical_pointer));
+
+  event.PushHistoricalEvent(historical_event.Pass());
+  EXPECT_EQ(1U, event.GetHistorySize());
+
+  scoped_ptr<MotionEvent> clone = event.Clone();
+  ASSERT_TRUE(clone);
+  EXPECT_EQ(test::ToString(event), test::ToString(*clone));
 }
 
 TEST(MotionEventGenericTest, Cancel) {
   MotionEventGeneric event(MotionEvent::ACTION_UP,
                            base::TimeTicks::Now(),
-                           PointerProperties(8.7f, 4.3f));
+                           PointerProperties(8.7f, 4.3f, 1.f));
   event.set_id(2);
   event.set_button_state(MotionEvent::BUTTON_SECONDARY);
 
   scoped_ptr<MotionEvent> cancel = event.Cancel();
   event.set_action(MotionEvent::ACTION_CANCEL);
   ASSERT_TRUE(cancel);
-  EXPECT_EQ(event, *cancel);
+  EXPECT_EQ(test::ToString(event), test::ToString(*cancel));
 }
 
 TEST(MotionEventGenericTest, FindPointerIndexOfId) {
@@ -98,4 +146,51 @@
   EXPECT_EQ(-1, event2.FindPointerIndexOfId(2));
 }
 
+TEST(MotionEventGenericTest, ToString) {
+  base::TimeTicks event_time = base::TimeTicks::Now();
+  base::TimeTicks historical_event_time0 =
+      event_time - base::TimeDelta::FromMilliseconds(10);
+  base::TimeTicks historical_event_time1 =
+      event_time - base::TimeDelta::FromMilliseconds(5);
+
+  PointerProperties pointer0(1, 2, 3);
+  pointer0.id = 7;
+  pointer0.pressure = 10;
+  pointer0.touch_minor = 15;
+  pointer0.touch_major = 20;
+  pointer0.orientation = 1;
+
+  PointerProperties pointer1(4, 5, 6);
+  pointer1.id = 3;
+  pointer0.pressure = 25;
+  pointer0.touch_minor = 30;
+  pointer0.touch_major = 35;
+  pointer0.orientation = -1;
+
+  MotionEventGeneric event(MotionEvent::ACTION_MOVE, event_time, pointer0);
+  event.PushPointer(pointer1);
+
+  pointer0.x += 50;
+  pointer1.x -= 50;
+  scoped_ptr<MotionEventGeneric> historical_event0(new MotionEventGeneric(
+      MotionEvent::ACTION_MOVE, historical_event_time0, pointer0));
+  historical_event0->PushPointer(pointer1);
+
+  pointer0.x += 100;
+  pointer1.x -= 100;
+  scoped_ptr<MotionEventGeneric> historical_event1(new MotionEventGeneric(
+      MotionEvent::ACTION_MOVE, historical_event_time1, pointer0));
+  historical_event1->PushPointer(pointer1);
+
+  event.PushHistoricalEvent(historical_event0.Pass());
+  event.PushHistoricalEvent(historical_event1.Pass());
+  ASSERT_EQ(2U, event.GetHistorySize());
+  ASSERT_EQ(2U, event.GetPointerCount());
+
+  // Do a basic smoke exercise of event stringification to ensure things don't
+  // explode in the process.
+  std::string event_string = test::ToString(event);
+  EXPECT_FALSE(event_string.empty());
+}
+
 }  // namespace ui
diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc b/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
index d8a2551..6b980f9 100644
--- a/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
+++ b/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
@@ -6,7 +6,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/gesture_detection/touch_disposition_gesture_filter.h"
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
 
 using ui::test::MockMotionEvent;
 
diff --git a/ui/events/gesture_detection/velocity_tracker_unittest.cc b/ui/events/gesture_detection/velocity_tracker_unittest.cc
index 9b45053..9b350b5 100644
--- a/ui/events/gesture_detection/velocity_tracker_unittest.cc
+++ b/ui/events/gesture_detection/velocity_tracker_unittest.cc
@@ -8,7 +8,7 @@
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/gesture_detection/velocity_tracker_state.h"
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 
diff --git a/ui/events/gestures/motion_event_aura.cc b/ui/events/gestures/motion_event_aura.cc
index 1b7b825..867d47a 100644
--- a/ui/events/gestures/motion_event_aura.cc
+++ b/ui/events/gestures/motion_event_aura.cc
@@ -173,7 +173,6 @@
 }
 
 int MotionEventAura::GetButtonState() const {
-  NOTIMPLEMENTED();
   return 0;
 }
 
@@ -185,26 +184,15 @@
   return last_touch_time_;
 }
 
-scoped_ptr<MotionEvent> MotionEventAura::Clone() const {
-  return scoped_ptr<MotionEvent>(new MotionEventAura(pointer_count_,
-                                                     last_touch_time_,
-                                                     cached_action_,
-                                                     cached_action_index_,
-                                                     flags_,
-                                                     active_touches_));
-}
-scoped_ptr<MotionEvent> MotionEventAura::Cancel() const {
-  return scoped_ptr<MotionEvent>(new MotionEventAura(
-      pointer_count_, last_touch_time_, ACTION_CANCEL, -1, 0, active_touches_));
-}
-
 void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent& event) {
   if (event.type() != ET_TOUCH_RELEASED &&
       event.type() != ET_TOUCH_CANCELLED) {
     return;
   }
 
-  int index_to_delete = static_cast<int>(GetIndexFromId(event.touch_id()));
+  DCHECK(pointer_count_);
+  int index_to_delete = GetIndexFromId(event.touch_id());
+  cached_action_index_ = 0;
   pointer_count_--;
   active_touches_[index_to_delete] = active_touches_[pointer_count_];
 }
@@ -249,8 +237,7 @@
         cached_action_ = ACTION_DOWN;
       } else {
         cached_action_ = ACTION_POINTER_DOWN;
-        cached_action_index_ =
-            static_cast<int>(GetIndexFromId(touch.touch_id()));
+        cached_action_index_ = GetIndexFromId(touch.touch_id());
       }
       break;
     case ET_TOUCH_RELEASED:
@@ -258,9 +245,7 @@
         cached_action_ = ACTION_UP;
       } else {
         cached_action_ = ACTION_POINTER_UP;
-        cached_action_index_ =
-            static_cast<int>(GetIndexFromId(touch.touch_id()));
-        DCHECK_LT(cached_action_index_, static_cast<int>(pointer_count_));
+        cached_action_index_ = GetIndexFromId(touch.touch_id());
       }
       break;
     case ET_TOUCH_CANCELLED:
@@ -275,13 +260,11 @@
   }
 }
 
-size_t MotionEventAura::GetIndexFromId(int id) const {
-  for (size_t i = 0; i < pointer_count_; ++i) {
-    if (active_touches_[i].touch_id == id)
-      return i;
-  }
-  NOTREACHED();
-  return 0;
+int MotionEventAura::GetIndexFromId(int id) const {
+  int index = FindPointerIndexOfId(id);
+  DCHECK_GE(index, 0);
+  DCHECK_LT(index, static_cast<int>(pointer_count_));
+  return index;
 }
 
 }  // namespace ui
diff --git a/ui/events/gestures/motion_event_aura.h b/ui/events/gestures/motion_event_aura.h
index 7ba2726..4087b82 100644
--- a/ui/events/gestures/motion_event_aura.h
+++ b/ui/events/gestures/motion_event_aura.h
@@ -42,9 +42,6 @@
   virtual int GetFlags() const override;
   virtual base::TimeTicks GetEventTime() const override;
 
-  virtual scoped_ptr<MotionEvent> Clone() const override;
-  virtual scoped_ptr<MotionEvent> Cancel() const override;
-
   int GetSourceDeviceId(size_t pointer_index) const;
 
   // We can't cleanup removed touch points immediately upon receipt of a
@@ -81,7 +78,7 @@
   void AddTouch(const TouchEvent& touch);
   void UpdateTouch(const TouchEvent& touch);
   void UpdateCachedAction(const TouchEvent& touch);
-  size_t GetIndexFromId(int id) const;
+  int GetIndexFromId(int id) const;
 
   size_t pointer_count_;
   base::TimeTicks last_touch_time_;
diff --git a/ui/events/gestures/motion_event_aura_unittest.cc b/ui/events/gestures/motion_event_aura_unittest.cc
index 6e645dc..d1fdadf 100644
--- a/ui/events/gestures/motion_event_aura_unittest.cc
+++ b/ui/events/gestures/motion_event_aura_unittest.cc
@@ -10,6 +10,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event.h"
 #include "ui/events/gestures/motion_event_aura.h"
+#include "ui/events/test/motion_event_test_utils.h"
 
 namespace {
 
@@ -112,6 +113,7 @@
   EXPECT_EQ(2U, clone->GetPointerCount());
   EXPECT_EQ(ids[0], clone->GetPointerId(0));
   EXPECT_EQ(ids[2], clone->GetPointerId(1));
+  EXPECT_EQ(test::ToString(event), test::ToString(*clone));
 
   TouchEvent release0 = TouchWithType(ET_TOUCH_RELEASED, ids[0]);
   event.OnTouch(release0);
@@ -138,20 +140,22 @@
   event.OnTouch(press0);
   TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, ids[1]);
   event.OnTouch(press1);
+  EXPECT_EQ(1, event.GetActionIndex());
   TouchEvent press2 = TouchWithType(ET_TOUCH_PRESSED, ids[2]);
   event.OnTouch(press2);
+  EXPECT_EQ(2, event.GetActionIndex());
   EXPECT_EQ(3U, event.GetPointerCount());
 
   TouchEvent release1 = TouchWithType(ET_TOUCH_RELEASED, ids[1]);
   event.OnTouch(release1);
-  event.CleanupRemovedTouchPoints(release1);
   EXPECT_EQ(1, event.GetActionIndex());
+  event.CleanupRemovedTouchPoints(release1);
   EXPECT_EQ(2U, event.GetPointerCount());
 
   TouchEvent release2 = TouchWithType(ET_TOUCH_RELEASED, ids[0]);
   event.OnTouch(release2);
-  event.CleanupRemovedTouchPoints(release2);
   EXPECT_EQ(0, event.GetActionIndex());
+  event.CleanupRemovedTouchPoints(release2);
   EXPECT_EQ(1U, event.GetPointerCount());
 
   TouchEvent release0 = TouchWithType(ET_TOUCH_RELEASED, ids[2]);
@@ -204,13 +208,12 @@
   // Test cloning of pointer location information.
   scoped_ptr<MotionEvent> clone = event.Clone();
   {
-    const MotionEventAura* raw_clone_aura =
-        static_cast<MotionEventAura*>(clone.get());
-    EXPECT_EQ(2U, raw_clone_aura->GetPointerCount());
-    EXPECT_FLOAT_EQ(x, raw_clone_aura->GetX(1));
-    EXPECT_FLOAT_EQ(y, raw_clone_aura->GetY(1));
-    EXPECT_FLOAT_EQ(raw_x, raw_clone_aura->GetRawX(1));
-    EXPECT_FLOAT_EQ(raw_y, raw_clone_aura->GetRawY(1));
+    EXPECT_EQ(test::ToString(event), test::ToString(*clone));
+    EXPECT_EQ(2U, clone->GetPointerCount());
+    EXPECT_FLOAT_EQ(x, clone->GetX(1));
+    EXPECT_FLOAT_EQ(y, clone->GetY(1));
+    EXPECT_FLOAT_EQ(raw_x, clone->GetRawX(1));
+    EXPECT_FLOAT_EQ(raw_y, clone->GetRawY(1));
   }
 
   x = 27.9f;
@@ -282,14 +285,12 @@
   // Test cloning of tap params
   scoped_ptr<MotionEvent> clone = event.Clone();
   {
-    const MotionEventAura* raw_clone_aura =
-        static_cast<MotionEventAura*>(clone.get());
-    EXPECT_EQ(2U, raw_clone_aura->GetPointerCount());
-    EXPECT_FLOAT_EQ(radius_y, raw_clone_aura->GetTouchMajor(1) / 2);
-    EXPECT_FLOAT_EQ(radius_x, raw_clone_aura->GetTouchMinor(1) / 2);
-    EXPECT_FLOAT_EQ(
-        rotation_angle, raw_clone_aura->GetOrientation(1) * 180 / M_PI);
-    EXPECT_FLOAT_EQ(pressure, raw_clone_aura->GetPressure(1));
+    EXPECT_EQ(test::ToString(event), test::ToString(*clone));
+    EXPECT_EQ(2U, clone->GetPointerCount());
+    EXPECT_FLOAT_EQ(radius_y, clone->GetTouchMajor(1) / 2);
+    EXPECT_FLOAT_EQ(radius_x, clone->GetTouchMinor(1) / 2);
+    EXPECT_FLOAT_EQ(rotation_angle, clone->GetOrientation(1) * 180 / M_PI);
+    EXPECT_FLOAT_EQ(pressure, clone->GetPressure(1));
   }
 
   radius_x = 76.98f;
@@ -391,7 +392,7 @@
 
   scoped_ptr<MotionEvent> cancel = event.Cancel();
   EXPECT_EQ(MotionEvent::ACTION_CANCEL, cancel->GetAction());
-  EXPECT_EQ(2U, static_cast<MotionEventAura*>(cancel.get())->GetPointerCount());
+  EXPECT_EQ(2U, cancel->GetPointerCount());
 }
 
 TEST(MotionEventAuraTest, ToolType) {
diff --git a/ui/events/input_device.cc b/ui/events/input_device.cc
new file mode 100644
index 0000000..4c356248
--- /dev/null
+++ b/ui/events/input_device.cc
@@ -0,0 +1,23 @@
+// 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 "ui/events/input_device.h"
+
+#include <string>
+
+namespace ui {
+
+// static
+const unsigned int InputDevice::kInvalidId = 0;
+
+InputDevice::InputDevice(unsigned int id,
+                         InputDeviceType type,
+                         const std::string& name)
+    : id(id), type(type), name(name) {
+}
+
+InputDevice::~InputDevice() {
+}
+
+}  // namespace ui
diff --git a/ui/events/input_device.h b/ui/events/input_device.h
new file mode 100644
index 0000000..526b005
--- /dev/null
+++ b/ui/events/input_device.h
@@ -0,0 +1,39 @@
+// 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 UI_EVENTS_INPUT_DEVICE_H_
+#define UI_EVENTS_INPUT_DEVICE_H_
+
+#include <string>
+
+#include "ui/events/events_base_export.h"
+
+namespace ui {
+
+enum InputDeviceType {
+  INPUT_DEVICE_INTERNAL,  // Internally connected input device.
+  INPUT_DEVICE_EXTERNAL,  // Known externally connected input device.
+  INPUT_DEVICE_UNKNOWN,   // Device that may or may not be an external device.
+};
+
+// Represents an input device state.
+struct EVENTS_BASE_EXPORT InputDevice {
+  static const unsigned int kInvalidId;
+
+  InputDevice(unsigned int id, InputDeviceType type, const std::string& name);
+  virtual ~InputDevice();
+
+  // ID of the device. This ID is unique between all input devices.
+  unsigned int id;
+
+  // The type of the input device.
+  InputDeviceType type;
+
+  // Name of the device.
+  std::string name;
+};
+
+}  // namespace ui
+
+#endif  // UI_EVENTS_INPUT_DEVICE_H_
diff --git a/ui/events/input_device_event_observer.h b/ui/events/input_device_event_observer.h
index 679f1f4..c23fe9a6 100644
--- a/ui/events/input_device_event_observer.h
+++ b/ui/events/input_device_event_observer.h
@@ -12,7 +12,8 @@
  public:
   virtual ~InputDeviceEventObserver() {}
 
-  virtual void OnInputDeviceConfigurationChanged() = 0;
+  virtual void OnKeyboardDeviceConfigurationChanged() = 0;
+  virtual void OnTouchscreenDeviceConfigurationChanged() = 0;
 };
 
 }  // namespace ui
diff --git a/ui/events/keyboard_device.cc b/ui/events/keyboard_device.cc
new file mode 100644
index 0000000..0950d19
--- /dev/null
+++ b/ui/events/keyboard_device.cc
@@ -0,0 +1,19 @@
+// 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 "ui/events/keyboard_device.h"
+
+#include <string>
+
+#include "ui/events/input_device.h"
+
+namespace ui {
+
+KeyboardDevice::KeyboardDevice(int id,
+                               InputDeviceType type,
+                               const std::string& name)
+    : InputDevice(id, type, name) {
+}
+
+}  // namespace ui
diff --git a/ui/events/keyboard_device.h b/ui/events/keyboard_device.h
new file mode 100644
index 0000000..ab145ff
--- /dev/null
+++ b/ui/events/keyboard_device.h
@@ -0,0 +1,22 @@
+// 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 UI_EVENTS_KEYBOARD_DEVICE_H_
+#define UI_EVENTS_KEYBOARD_DEVICE_H_
+
+#include <string>
+
+#include "ui/events/events_base_export.h"
+#include "ui/events/input_device.h"
+
+namespace ui {
+
+// Represents a Keyboard device state.
+struct EVENTS_BASE_EXPORT KeyboardDevice : public InputDevice {
+  KeyboardDevice(int id, InputDeviceType type, const std::string& name);
+};
+
+}  // namespace ui
+
+#endif  // UI_EVENTS_KEYBOARD_DEVICE_H_
diff --git a/ui/events/ozone/device/udev/device_manager_udev.h b/ui/events/ozone/device/udev/device_manager_udev.h
index 13c76b94..2d01ed8c 100644
--- a/ui/events/ozone/device/udev/device_manager_udev.h
+++ b/ui/events/ozone/device/udev/device_manager_udev.h
@@ -7,7 +7,7 @@
 
 #include "base/message_loop/message_pump_libevent.h"
 #include "base/observer_list.h"
-#include "device/udev_linux/udev.h"
+#include "device/udev_linux/scoped_udev.h"
 #include "ui/events/ozone/device/device_manager.h"
 
 namespace ui {
diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc
index 6d75ea9..a59d472 100644
--- a/ui/events/ozone/evdev/event_device_info.cc
+++ b/ui/events/ozone/evdev/event_device_info.cc
@@ -9,6 +9,10 @@
 #include "base/logging.h"
 #include "base/threading/thread_restrictions.h"
 
+#if !defined(EVIOCGMTSLOTS)
+#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
+#endif
+
 namespace ui {
 
 namespace {
@@ -40,6 +44,24 @@
   return true;
 }
 
+// |request| needs to be the equivalent to:
+// struct input_mt_request_layout {
+//   uint32_t code;
+//   int32_t values[num_slots];
+// };
+//
+// |size| is num_slots + 1 (for code).
+bool GetSlotValues(int fd, int32_t* request, unsigned int size) {
+  if (ioctl(fd,
+            EVIOCGMTSLOTS(sizeof(int32_t) * size),
+            request) < 0) {
+    DLOG(ERROR) << "failed EVIOCGMTSLOTS(" << request[0] << ") on fd " << fd;
+    return false;
+  }
+
+  return true;
+}
+
 }  // namespace
 
 EventDeviceInfo::EventDeviceInfo() {
@@ -86,6 +108,20 @@
       if (!GetAbsInfo(fd, i, &abs_info_[i]))
         return false;
 
+  int max_num_slots = abs_info_[ABS_MT_SLOT].maximum + 1;
+  // |request| is MT code + slots.
+  int32_t request[max_num_slots + 1];
+  for (unsigned int i = ABS_MT_SLOT + 1; i < ABS_MAX; ++i) {
+    memset(request, 0, sizeof(request));
+    request[0] = i;
+    if (HasAbsEvent(i))
+      if (!GetSlotValues(fd, request, max_num_slots + 1))
+        LOG(WARNING) << "Failed to get multitouch values for code " << i;
+
+    slot_values_[i - ABS_MT_SLOT - 1].assign(
+        request + 1, request + max_num_slots + 1);
+  }
+
   return true;
 }
 
@@ -145,6 +181,14 @@
   return abs_info_[code].maximum;
 }
 
+int32 EventDeviceInfo::GetSlotValue(unsigned int code,
+                                    unsigned int slot) const {
+  const std::vector<int32_t>& slots = GetMtSlotsForCode(code);
+  DCHECK_LE(0u, slot) << slot << " is an invalid slot";
+  DCHECK_LT(slot, slots.size()) << slot << " is an invalid slot";
+  return slots[slot];
+}
+
 bool EventDeviceInfo::HasAbsXY() const {
   if (HasAbsEvent(ABS_X) && HasAbsEvent(ABS_Y))
     return true;
@@ -182,4 +226,12 @@
   return true;
 }
 
+const std::vector<int32_t>& EventDeviceInfo::GetMtSlotsForCode(int code) const {
+  int index = code - ABS_MT_SLOT - 1;
+  DCHECK_LE(0, index) << code << " is not a valid multi-touch code";
+  DCHECK_LT(index, EVDEV_ABS_MT_COUNT)
+      << code << " is not a valid multi-touch code";
+  return slot_values_[index];
+}
+
 }  // namespace ui
diff --git a/ui/events/ozone/evdev/event_device_info.h b/ui/events/ozone/evdev/event_device_info.h
index 3217114..adca89e0 100644
--- a/ui/events/ozone/evdev/event_device_info.h
+++ b/ui/events/ozone/evdev/event_device_info.h
@@ -8,10 +8,15 @@
 #include <limits.h>
 #include <linux/input.h>
 
+#include <vector>
+
 #include "base/basictypes.h"
 #include "ui/events/ozone/evdev/event_device_util.h"
 #include "ui/events/ozone/evdev/events_ozone_evdev_export.h"
 
+// ABS_MT_SLOT isn't valid options for EVIOCGMTSLOTS ioctl.
+#define EVDEV_ABS_MT_COUNT (ABS_MAX - ABS_MT_SLOT - 1)
+
 namespace ui {
 
 // Device information for Linux input devices
@@ -38,6 +43,7 @@
   // Properties of absolute axes.
   int32 GetAbsMinimum(unsigned int code) const;
   int32 GetAbsMaximum(unsigned int code) const;
+  int32 GetSlotValue(unsigned int code, unsigned int slot) const;
 
   // Check input device properties.
   bool HasProp(unsigned int code) const;
@@ -53,6 +59,9 @@
   bool IsMappedToScreen() const;
 
  private:
+  // Return the slot vector in |slot_values_| for |code|.
+  const std::vector<int32_t>& GetMtSlotsForCode(int code) const;
+
   unsigned long ev_bits_[EVDEV_BITS_TO_LONGS(EV_CNT)];
   unsigned long key_bits_[EVDEV_BITS_TO_LONGS(KEY_CNT)];
   unsigned long rel_bits_[EVDEV_BITS_TO_LONGS(REL_CNT)];
@@ -64,6 +73,9 @@
 
   struct input_absinfo abs_info_[ABS_CNT];
 
+  // Store the values for the multi-touch properties for each slot.
+  std::vector<int32_t> slot_values_[EVDEV_ABS_MT_COUNT];
+
   DISALLOW_COPY_AND_ASSIGN(EventDeviceInfo);
 };
 
diff --git a/ui/events/ozone/evdev/event_dispatch_callback.h b/ui/events/ozone/evdev/event_dispatch_callback.h
index 1974d51f..ae07817 100644
--- a/ui/events/ozone/evdev/event_dispatch_callback.h
+++ b/ui/events/ozone/evdev/event_dispatch_callback.h
@@ -11,7 +11,7 @@
 
 class Event;
 
-typedef base::Callback<void(Event*)> EventDispatchCallback;
+typedef base::Callback<void(scoped_ptr<Event>)> EventDispatchCallback;
 
 }  // namspace ui
 
diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc
index 703e95d3..0a0d674 100644
--- a/ui/events/ozone/evdev/event_factory_evdev.cc
+++ b/ui/events/ozone/evdev/event_factory_evdev.cc
@@ -156,8 +156,7 @@
     : last_device_id_(0),
       device_manager_(device_manager),
       dispatch_callback_(
-          base::Bind(base::IgnoreResult(&EventFactoryEvdev::DispatchUiEvent),
-                     base::Unretained(this))),
+          base::Bind(&EventFactoryEvdev::PostUiEvent, base::Unretained(this))),
       keyboard_(&modifiers_, dispatch_callback_),
       cursor_(cursor),
 #if defined(USE_EVDEV_GESTURES)
@@ -169,8 +168,16 @@
 
 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); }
 
-void EventFactoryEvdev::DispatchUiEvent(Event* event) {
-  DispatchEvent(event);
+void EventFactoryEvdev::PostUiEvent(scoped_ptr<Event> event) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::Bind(&EventFactoryEvdev::DispatchUiEventTask,
+                 weak_ptr_factory_.GetWeakPtr(),
+                 base::Passed(&event)));
+}
+
+void EventFactoryEvdev::DispatchUiEventTask(scoped_ptr<Event> event) {
+  DispatchEvent(event.get());
 }
 
 void EventFactoryEvdev::AttachInputDevice(
@@ -269,12 +276,11 @@
                                      const gfx::PointF& location) {
   if (cursor_) {
     cursor_->MoveCursorTo(widget, location);
-    MouseEvent mouse_event(ET_MOUSE_MOVED,
-                           cursor_->location(),
-                           cursor_->location(),
-                           modifiers_.GetModifierFlags(),
-                           /* changed_button_flags */ 0);
-    DispatchEvent(&mouse_event);
+    PostUiEvent(make_scoped_ptr(new MouseEvent(ET_MOUSE_MOVED,
+                                               cursor_->location(),
+                                               cursor_->location(),
+                                               modifiers_.GetModifierFlags(),
+                                               /* changed_button_flags */ 0)));
   }
 }
 
@@ -289,9 +295,11 @@
   std::vector<TouchscreenDevice> touchscreens;
   for (auto it = converters_.begin(); it != converters_.end(); ++it) {
     if (it->second->HasTouchscreen()) {
-      touchscreens.push_back(TouchscreenDevice(it->second->id(),
-                                               it->second->GetTouchscreenSize(),
-                                               false /* is_internal */));
+      touchscreens.push_back(
+          TouchscreenDevice(it->second->id(),
+                            InputDeviceType::INPUT_DEVICE_EXTERNAL,
+                            std::string(), /* Device name */
+                            it->second->GetTouchscreenSize()));
     }
   }
 
diff --git a/ui/events/ozone/evdev/event_factory_evdev.h b/ui/events/ozone/evdev/event_factory_evdev.h
index 1812f19..74585fc6 100644
--- a/ui/events/ozone/evdev/event_factory_evdev.h
+++ b/ui/events/ozone/evdev/event_factory_evdev.h
@@ -39,12 +39,16 @@
                     DeviceManager* device_manager);
   virtual ~EventFactoryEvdev();
 
-  void DispatchUiEvent(Event* event);
-
   void WarpCursorTo(gfx::AcceleratedWidget widget,
                     const gfx::PointF& location);
 
  private:
+  // Post a task to dispatch an event.
+  void PostUiEvent(scoped_ptr<Event> event);
+
+  // Dispatch event via PlatformEventSource.
+  void DispatchUiEventTask(scoped_ptr<Event> event);
+
   // Open device at path & starting processing events (on UI thread).
   void AttachInputDevice(scoped_ptr<EventConverterEvdev> converter);
 
diff --git a/ui/events/ozone/evdev/key_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/key_event_converter_evdev_unittest.cc
index fb5a90ae..aa7d4a5 100644
--- a/ui/events/ozone/evdev/key_event_converter_evdev_unittest.cc
+++ b/ui/events/ozone/evdev/key_event_converter_evdev_unittest.cc
@@ -72,13 +72,14 @@
   unsigned size() { return dispatched_events_.size(); }
   ui::KeyEvent* dispatched_event(unsigned index) {
     DCHECK_GT(dispatched_events_.size(), index);
-    return dispatched_events_[index];
+    ui::Event* ev = dispatched_events_[index];
+    DCHECK(ev->IsKeyEvent());
+    return static_cast<ui::KeyEvent*>(ev);
   }
 
  private:
-  void DispatchEventForTest(ui::Event* event) {
-    dispatched_events_.push_back(
-        new ui::KeyEvent(*static_cast<ui::KeyEvent*>(event)));
+  void DispatchEventForTest(scoped_ptr<ui::Event> event) {
+    dispatched_events_.push_back(event.release());
   }
 
   base::MessageLoopForUI ui_loop_;
@@ -87,7 +88,7 @@
   scoped_ptr<ui::KeyboardEvdev> keyboard_;
   scoped_ptr<ui::MockKeyEventConverterEvdev> device_;
 
-  ScopedVector<ui::KeyEvent> dispatched_events_;
+  ScopedVector<ui::Event> dispatched_events_;
 
   int events_out_;
   int events_in_;
@@ -353,3 +354,18 @@
   EXPECT_EQ(ui::VKEY_CAPITAL, event->key_code());
   EXPECT_EQ(0, event->flags());
 }
+
+TEST_F(KeyEventConverterEvdevTest, UnmappedKeyPress) {
+  ui::MockKeyEventConverterEvdev* dev = device();
+
+  struct input_event mock_kernel_queue[] = {
+      {{0, 0}, EV_KEY, BTN_TOUCH, 1},
+      {{0, 0}, EV_SYN, SYN_REPORT, 0},
+
+      {{0, 0}, EV_KEY, BTN_TOUCH, 0},
+      {{0, 0}, EV_SYN, SYN_REPORT, 0},
+  };
+
+  dev->ProcessEvents(mock_kernel_queue, arraysize(mock_kernel_queue));
+  EXPECT_EQ(0u, size());
+}
diff --git a/ui/events/ozone/evdev/keyboard_evdev.cc b/ui/events/ozone/evdev/keyboard_evdev.cc
index 6e5266f..b5a0849 100644
--- a/ui/events/ozone/evdev/keyboard_evdev.cc
+++ b/ui/events/ozone/evdev/keyboard_evdev.cc
@@ -228,12 +228,14 @@
   ui::KeyboardCode code = KeyboardCodeFromEvdevKey(key);
   int flags = modifiers_->GetModifierFlags();
 
-  KeyEvent key_event(
+  if (code == VKEY_UNKNOWN)
+    return;
+
+  callback_.Run(make_scoped_ptr(new KeyEvent(
       down ? ET_KEY_PRESSED : ET_KEY_RELEASED,
       code,
       KeycodeConverter::NativeKeycodeToCode(key + kXkbKeycodeOffset),
-      flags);
-  callback_.Run(&key_event);
+      flags)));
 }
 
 }  // namespace ui
diff --git a/ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.cc b/ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.cc
index a6d424d..9bc7c8e 100644
--- a/ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.cc
+++ b/ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.cc
@@ -250,12 +250,11 @@
   cursor_->MoveCursor(gfx::Vector2dF(move->dx, move->dy));
   // TODO(spang): Use move->ordinal_dx, move->ordinal_dy
   // TODO(spang): Use move->start_time, move->end_time
-  MouseEvent event(ET_MOUSE_MOVED,
-                   cursor_->location(),
-                   cursor_->location(),
-                   modifiers_->GetModifierFlags(),
-                   /* changed_button_flags */ 0);
-  Dispatch(&event);
+  Dispatch(make_scoped_ptr(new MouseEvent(ET_MOUSE_MOVED,
+                                          cursor_->location(),
+                                          cursor_->location(),
+                                          modifiers_->GetModifierFlags(),
+                                          /* changed_button_flags */ 0)));
 }
 
 void GestureInterpreterLibevdevCros::OnGestureScroll(
@@ -271,16 +270,15 @@
 
   // TODO(spang): Support SetNaturalScroll
   // TODO(spang): Use scroll->start_time
-  ScrollEvent event(ET_SCROLL,
-                    cursor_->location(),
-                    StimeToTimedelta(gesture->end_time),
-                    modifiers_->GetModifierFlags(),
-                    scroll->dx,
-                    scroll->dy,
-                    scroll->ordinal_dx,
-                    scroll->ordinal_dy,
-                    kGestureScrollFingerCount);
-  Dispatch(&event);
+  Dispatch(make_scoped_ptr(new ScrollEvent(ET_SCROLL,
+                                           cursor_->location(),
+                                           StimeToTimedelta(gesture->end_time),
+                                           modifiers_->GetModifierFlags(),
+                                           scroll->dx,
+                                           scroll->dy,
+                                           scroll->ordinal_dx,
+                                           scroll->ordinal_dy,
+                                           kGestureScrollFingerCount)));
 }
 
 void GestureInterpreterLibevdevCros::OnGestureButtonsChange(
@@ -339,16 +337,15 @@
                                                   : ET_SCROLL_FLING_CANCEL);
 
   // Fling is like 2-finger scrolling but with velocity instead of displacement.
-  ScrollEvent event(type,
-                    cursor_->location(),
-                    StimeToTimedelta(gesture->end_time),
-                    modifiers_->GetModifierFlags(),
-                    fling->vx,
-                    fling->vy,
-                    fling->ordinal_vx,
-                    fling->ordinal_vy,
-                    kGestureScrollFingerCount);
-  Dispatch(&event);
+  Dispatch(make_scoped_ptr(new ScrollEvent(type,
+                                           cursor_->location(),
+                                           StimeToTimedelta(gesture->end_time),
+                                           modifiers_->GetModifierFlags(),
+                                           fling->vx,
+                                           fling->vy,
+                                           fling->ordinal_vx,
+                                           fling->ordinal_vy,
+                                           kGestureScrollFingerCount)));
 }
 
 void GestureInterpreterLibevdevCros::OnGestureSwipe(const Gesture* gesture,
@@ -363,16 +360,15 @@
     return;  // No cursor!
 
   // Swipe is 3-finger scrolling.
-  ScrollEvent event(ET_SCROLL,
-                    cursor_->location(),
-                    StimeToTimedelta(gesture->end_time),
-                    modifiers_->GetModifierFlags(),
-                    swipe->dx,
-                    swipe->dy,
-                    swipe->ordinal_dx,
-                    swipe->ordinal_dy,
-                    kGestureSwipeFingerCount);
-  Dispatch(&event);
+  Dispatch(make_scoped_ptr(new ScrollEvent(ET_SCROLL,
+                                           cursor_->location(),
+                                           StimeToTimedelta(gesture->end_time),
+                                           modifiers_->GetModifierFlags(),
+                                           swipe->dx,
+                                           swipe->dy,
+                                           swipe->ordinal_dx,
+                                           swipe->ordinal_dy,
+                                           kGestureSwipeFingerCount)));
 }
 
 void GestureInterpreterLibevdevCros::OnGestureSwipeLift(
@@ -386,17 +382,15 @@
   // Turn a swipe lift into a fling start.
   // TODO(spang): Figure out why and put it in this comment.
 
-  ScrollEvent event(ET_SCROLL_FLING_START,
-                    cursor_->location(),
-                    StimeToTimedelta(gesture->end_time),
-                    modifiers_->GetModifierFlags(),
-                    /* x_offset */ 0,
-                    /* y_offset */ 0,
-                    /* x_offset_ordinal */ 0,
-                    /* y_offset_ordinal */ 0,
-                    kGestureScrollFingerCount);
-  Dispatch(&event);
-
+  Dispatch(make_scoped_ptr(new ScrollEvent(ET_SCROLL_FLING_START,
+                                           cursor_->location(),
+                                           StimeToTimedelta(gesture->end_time),
+                                           modifiers_->GetModifierFlags(),
+                                           /* x_offset */ 0,
+                                           /* y_offset */ 0,
+                                           /* x_offset_ordinal */ 0,
+                                           /* y_offset_ordinal */ 0,
+                                           kGestureScrollFingerCount)));
 }
 
 void GestureInterpreterLibevdevCros::OnGesturePinch(const Gesture* gesture,
@@ -420,8 +414,8 @@
   NOTIMPLEMENTED();
 }
 
-void GestureInterpreterLibevdevCros::Dispatch(Event* event) {
-  dispatch_callback_.Run(event);
+void GestureInterpreterLibevdevCros::Dispatch(scoped_ptr<Event> event) {
+  dispatch_callback_.Run(event.Pass());
 }
 
 void GestureInterpreterLibevdevCros::DispatchMouseButton(unsigned int modifier,
@@ -430,8 +424,8 @@
   int flag = modifiers_->GetEventFlagFromModifier(modifier);
   EventType type = (down ? ET_MOUSE_PRESSED : ET_MOUSE_RELEASED);
   modifiers_->UpdateModifier(modifier, down);
-  MouseEvent event(type, loc, loc, modifiers_->GetModifierFlags() | flag, flag);
-  Dispatch(&event);
+  Dispatch(make_scoped_ptr(new MouseEvent(
+      type, loc, loc, modifiers_->GetModifierFlags() | flag, flag)));
 }
 
 void GestureInterpreterLibevdevCros::DispatchChangedKeys(Evdev* evdev,
diff --git a/ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.h b/ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.h
index 0499c579..9d89d0a 100644
--- a/ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.h
+++ b/ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.h
@@ -77,7 +77,7 @@
   void OnGesturePinch(const Gesture* gesture, const GesturePinch* pinch);
   void OnGestureMetrics(const Gesture* gesture, const GestureMetrics* metrics);
 
-  void Dispatch(Event* event);
+  void Dispatch(scoped_ptr<Event> event);
   void DispatchMouseButton(unsigned int modifier, bool down);
   void DispatchChangedKeys(Evdev* evdev, const timeval& time);
 
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
index 7b666e0..ef087a1 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
@@ -72,6 +72,17 @@
 
 namespace ui {
 
+TouchEventConverterEvdev::InProgressEvents::InProgressEvents()
+    : x_(0),
+      y_(0),
+      id_(-1),
+      finger_(-1),
+      type_(ET_UNKNOWN),
+      radius_x_(0),
+      radius_y_(0),
+      pressure_(0) {
+}
+
 TouchEventConverterEvdev::TouchEventConverterEvdev(
     int fd,
     base::FilePath path,
@@ -129,6 +140,19 @@
                                 cal.bezel_right,
                                 cal.bezel_top,
                                 cal.bezel_bottom);
+
+  for (int i = 0;
+       i < std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, MAX_FINGERS);
+       ++i) {
+    events_[i].finger_ = info.GetSlotValue(ABS_MT_TRACKING_ID, i);
+    events_[i].type_ =
+        events_[i].finger_ < 0 ? ET_TOUCH_RELEASED : ET_TOUCH_PRESSED;
+    events_[i].x_ = info.GetSlotValue(ABS_MT_POSITION_X, i);
+    events_[i].y_ = info.GetSlotValue(ABS_MT_POSITION_Y, i);
+    events_[i].radius_x_ = info.GetSlotValue(ABS_MT_TOUCH_MAJOR, i);
+    events_[i].radius_y_ = info.GetSlotValue(ABS_MT_TOUCH_MINOR, i);
+    events_[i].pressure_ = info.GetSlotValue(ABS_MT_PRESSURE, i);
+  }
 }
 
 bool TouchEventConverterEvdev::Reinitialize() {
@@ -280,16 +304,16 @@
   for (int i = 0; i < MAX_FINGERS; i++) {
     if (altered_slots_[i]) {
       // TODO(rikroege): Support elliptical finger regions.
-      TouchEvent evt(events_[i].type_,
-                     gfx::PointF(events_[i].x_, events_[i].y_),
-                     /* flags */ 0,
-                     /* touch_id */ i,
-                     delta,
-                     /* radius_x */ events_[i].radius_x_,
-                     /* radius_y */ events_[i].radius_y_,
-                     /* angle */ 0.,
-                     events_[i].pressure_);
-      callback_.Run(&evt);
+      callback_.Run(make_scoped_ptr(
+          new TouchEvent(events_[i].type_,
+                         gfx::PointF(events_[i].x_, events_[i].y_),
+                         /* flags */ 0,
+                         /* touch_id */ i,
+                         delta,
+                         /* radius_x */ events_[i].radius_x_,
+                         /* radius_y */ events_[i].radius_y_,
+                         /* angle */ 0.,
+                         events_[i].pressure_)));
 
       // Subsequent events for this finger will be touch-move until it
       // is released.
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h
index 83aa13ac..d36f901 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev.h
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -93,6 +93,8 @@
   std::bitset<MAX_FINGERS> altered_slots_;
 
   struct InProgressEvents {
+    InProgressEvents();
+
     float x_;
     float y_;
     int id_;  // Device reported "unique" touch point id; -1 means not active
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
index 3e76476..6a8494b1 100644
--- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
+++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -46,7 +46,12 @@
                          long queue_index);
 
   unsigned size() { return dispatched_events_.size(); }
-  TouchEvent* event(unsigned index) { return dispatched_events_[index]; }
+  TouchEvent* event(unsigned index) {
+    DCHECK_GT(dispatched_events_.size(), index);
+    Event* ev = dispatched_events_[index];
+    DCHECK(ev->IsTouchEvent());
+    return static_cast<TouchEvent*>(ev);
+  }
 
   // Actually dispatch the event reader code.
   void ReadNow() {
@@ -54,9 +59,8 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  void DispatchCallback(Event* event) {
-    dispatched_events_.push_back(
-        new TouchEvent(*static_cast<TouchEvent*>(event)));
+  void DispatchCallback(scoped_ptr<Event> event) {
+    dispatched_events_.push_back(event.release());
   }
 
   virtual bool Reinitialize() override { return true; }
@@ -65,7 +69,7 @@
   int read_pipe_;
   int write_pipe_;
 
-  ScopedVector<TouchEvent> dispatched_events_;
+  ScopedVector<Event> dispatched_events_;
 
   DISALLOW_COPY_AND_ASSIGN(MockTouchEventConverterEvdev);
 };
diff --git a/ui/events/test/event_generator.cc b/ui/events/test/event_generator.cc
index 8fae713..24b4387 100644
--- a/ui/events/test/event_generator.cc
+++ b/ui/events/test/event_generator.cc
@@ -14,7 +14,7 @@
 #include "ui/events/event_source.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/test/events_test_utils.h"
-#include "ui/gfx/vector2d_conversions.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
 
 #if defined(USE_X11)
 #include <X11/Xlib.h>
diff --git a/ui/events/test/mock_motion_event.cc b/ui/events/test/motion_event_test_utils.cc
similarity index 68%
rename from ui/events/test/mock_motion_event.cc
rename to ui/events/test/motion_event_test_utils.cc
index f3de1dd..45350fc 100644
--- a/ui/events/test/mock_motion_event.cc
+++ b/ui/events/test/motion_event_test_utils.cc
@@ -2,9 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/events/test/mock_motion_event.h"
+#include "ui/events/test/motion_event_test_utils.h"
+
+#include <sstream>
 
 #include "base/logging.h"
+#include "ui/events/gesture_detection/bitset_32.h"
+#include "ui/events/gesture_detection/motion_event.h"
 
 using base::TimeTicks;
 
@@ -19,13 +23,11 @@
 }
 
 PointerProperties CreatePointer(float x, float y, int id) {
-  PointerProperties pointer(x, y);
-  pointer.touch_major = MockMotionEvent::TOUCH_MAJOR;
+  PointerProperties pointer(x, y, MockMotionEvent::TOUCH_MAJOR);
   pointer.id = id;
   return pointer;
 }
 
-
 }  // namespace
 
 MockMotionEvent::MockMotionEvent()
@@ -85,16 +87,7 @@
     : MotionEventGeneric(other) {
 }
 
-MockMotionEvent::~MockMotionEvent() {}
-
-scoped_ptr<MotionEvent> MockMotionEvent::Clone() const {
-  return scoped_ptr<MotionEvent>(new MockMotionEvent(*this));
-}
-
-scoped_ptr<MotionEvent> MockMotionEvent::Cancel() const {
-  scoped_ptr<MockMotionEvent> event(new MockMotionEvent(*this));
-  event->set_action(MotionEvent::ACTION_CANCEL);
-  return event.Pass();
+MockMotionEvent::~MockMotionEvent() {
 }
 
 void MockMotionEvent::PressPoint(float x, float y) {
@@ -173,5 +166,54 @@
   }
 }
 
+std::string ToString(const MotionEvent& event) {
+  std::stringstream ss;
+  ss << "MotionEvent {"
+     << "\n ID: " << event.GetId() << "\n Action: " << event.GetAction()
+     << "\n ActionIndex: " << event.GetActionIndex()
+     << "\n Flags: " << event.GetFlags()
+     << "\n ButtonState: " << event.GetButtonState() << "\n Pointers: [";
+  const size_t pointer_count = event.GetPointerCount();
+  const size_t history_size = event.GetHistorySize();
+
+  BitSet32 pointer_ids;
+  for (size_t i = 0; i < pointer_count; ++i) {
+    pointer_ids.mark_bit(event.GetPointerId(i));
+
+    // Print the pointers sorted by id.
+    while (!pointer_ids.is_empty()) {
+      int pi = event.FindPointerIndexOfId(pointer_ids.first_marked_bit());
+      DCHECK_GE(pi, 0);
+      pointer_ids.clear_first_marked_bit();
+      ss << "{"
+         << "\n  Pos: (" << event.GetX(pi) << ", " << event.GetY(pi) << ")"
+         << "\n  RawPos: (" << event.GetX(pi) << ", " << event.GetY(pi) << ")"
+         << "\n  Size: (" << event.GetTouchMajor(pi) << ", "
+         << event.GetTouchMinor(pi) << ")"
+         << "\n  Orientation: " << event.GetOrientation(pi)
+         << "\n  Pressure: " << event.GetOrientation(pi)
+         << "\n  Tool: " << event.GetToolType(pi);
+      if (history_size) {
+        ss << "\n  History: [";
+        for (size_t h = 0; h < history_size; ++h) {
+          ss << "\n   { " << event.GetHistoricalX(pi, h) << ", "
+             << event.GetHistoricalY(pi, h) << ", "
+             << event.GetHistoricalTouchMajor(pi, h) << ", "
+             << event.GetHistoricalEventTime(pi).ToInternalValue() << " }";
+          if (h + 1 < history_size)
+            ss << ",";
+        }
+        ss << "\n  ]";
+      }
+      ss << "\n }";
+      if (i + 1 < pointer_count)
+        ss << ", ";
+    }
+    ss << "]\n}";
+  }
+
+  return ss.str();
+}
+
 }  // namespace test
 }  // namespace ui
diff --git a/ui/events/test/mock_motion_event.h b/ui/events/test/motion_event_test_utils.h
similarity index 87%
rename from ui/events/test/mock_motion_event.h
rename to ui/events/test/motion_event_test_utils.h
index d04d715..4010bc4 100644
--- a/ui/events/test/mock_motion_event.h
+++ b/ui/events/test/motion_event_test_utils.h
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef UI_EVENTS_TEST_MOTION_EVENT_TEST_UTILS_H_
+#define UI_EVENTS_TEST_MOTION_EVENT_TEST_UTILS_H_
+
+#include <string>
 #include <vector>
 
 #include "base/basictypes.h"
@@ -39,10 +43,6 @@
 
   ~MockMotionEvent() override;
 
-  // MotionEvent methods.
-  scoped_ptr<MotionEvent> Clone() const override;
-  scoped_ptr<MotionEvent> Cancel() const override;
-
   // Utility methods.
   void PressPoint(float x, float y);
   void MovePoint(size_t index, float x, float y);
@@ -57,5 +57,9 @@
   void ResolvePointers();
 };
 
+std::string ToString(const MotionEvent& event);
+
 }  // namespace test
 }  // namespace ui
+
+#endif  // UI_EVENTS_TEST_MOTION_EVENT_TEST_UTILS_H_
diff --git a/ui/events/touchscreen_device.cc b/ui/events/touchscreen_device.cc
index 07844a15..58c2370d 100644
--- a/ui/events/touchscreen_device.cc
+++ b/ui/events/touchscreen_device.cc
@@ -4,15 +4,17 @@
 
 #include "ui/events/touchscreen_device.h"
 
+#include <string>
+
+#include "ui/events/input_device.h"
+
 namespace ui {
 
-// static
-const int TouchscreenDevice::kInvalidId = 0;
-
 TouchscreenDevice::TouchscreenDevice(int id,
-                                     const gfx::Size& size,
-                                     bool is_internal)
-    : id(id), size(size), is_internal(is_internal) {
+                                     InputDeviceType type,
+                                     const std::string& name,
+                                     const gfx::Size& size)
+    : InputDevice(id, type, name), size(size) {
 }
 
 }  // namespace ui
diff --git a/ui/events/touchscreen_device.h b/ui/events/touchscreen_device.h
index 669f306..d281a0b 100644
--- a/ui/events/touchscreen_device.h
+++ b/ui/events/touchscreen_device.h
@@ -5,25 +5,23 @@
 #ifndef UI_EVENTS_TOUCHSCREEN_DEVICE_H_
 #define UI_EVENTS_TOUCHSCREEN_DEVICE_H_
 
+#include <string>
+
 #include "ui/events/events_base_export.h"
+#include "ui/events/input_device.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace ui {
 
 // Represents a Touchscreen device state.
-struct EVENTS_BASE_EXPORT TouchscreenDevice {
-  static const int kInvalidId;
-
-  TouchscreenDevice(int id, const gfx::Size& size, bool is_internal);
-
-  // ID of the touch screen. This ID must uniquely identify the touch screen.
-  int id;
+struct EVENTS_BASE_EXPORT TouchscreenDevice : public InputDevice {
+  TouchscreenDevice(int id,
+                    InputDeviceType type,
+                    const std::string& name,
+                    const gfx::Size& size);
 
   // Size of the touch screen area.
   gfx::Size size;
-
-  // True if this is an internal touchscreen.
-  bool is_internal;
 };
 
 }  // namespace ui
diff --git a/ui/events/x/device_data_manager_x11.cc b/ui/events/x/device_data_manager_x11.cc
index 795cc44..4b29631 100644
--- a/ui/events/x/device_data_manager_x11.cc
+++ b/ui/events/x/device_data_manager_x11.cc
@@ -8,11 +8,14 @@
 #include <X11/extensions/XInput2.h>
 #include <X11/Xlib.h>
 
+#include <utility>
+
 #include "base/logging.h"
 #include "base/memory/singleton.h"
 #include "base/sys_info.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/event_switches.h"
+#include "ui/events/keyboard_device.h"
 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
 #include "ui/events/x/device_list_cache_x.h"
 #include "ui/events/x/touch_factory_x11.h"
@@ -106,6 +109,14 @@
 
 namespace ui {
 
+namespace {
+
+bool KeyboardDeviceHasId(const ui::KeyboardDevice keyboard, unsigned int id) {
+  return keyboard.id == id;
+}
+
+}  // namespace
+
 bool DeviceDataManagerX11::IsCMTDataType(const int type) {
   return (type >= kCMTDataTypeStart) && (type <= kCMTDataTypeEnd);
 }
@@ -661,7 +672,8 @@
   }
 }
 
-bool DeviceDataManagerX11::TouchEventNeedsCalibrate(int touch_device_id) const {
+bool DeviceDataManagerX11::TouchEventNeedsCalibrate(
+    unsigned int touch_device_id) const {
 #if defined(OS_CHROMEOS) && defined(USE_XI2_MT)
   int64 touch_display_id = GetDisplayForTouchDevice(touch_device_id);
   if (base::SysInfo::IsRunningOnChromeOS() &&
@@ -681,10 +693,31 @@
 
 void DeviceDataManagerX11::DisableDevice(unsigned int deviceid) {
   blocked_devices_.set(deviceid, true);
+  // TODO(rsadam@): Support blocking touchscreen devices.
+  std::vector<KeyboardDevice> keyboards = keyboard_devices();
+  std::vector<KeyboardDevice>::iterator it =
+      std::find_if(keyboards.begin(),
+                   keyboards.end(),
+                   std::bind2nd(std::ptr_fun(&KeyboardDeviceHasId), deviceid));
+  if (it != std::end(keyboards)) {
+    blocked_keyboards_.insert(
+        std::pair<unsigned int, KeyboardDevice>(deviceid, *it));
+    keyboards.erase(it);
+    DeviceDataManager::OnKeyboardDevicesUpdated(keyboards);
+  }
 }
 
 void DeviceDataManagerX11::EnableDevice(unsigned int deviceid) {
   blocked_devices_.set(deviceid, false);
+  std::map<unsigned int, KeyboardDevice>::iterator it =
+      blocked_keyboards_.find(deviceid);
+  if (it != blocked_keyboards_.end()) {
+    std::vector<KeyboardDevice> devices = keyboard_devices();
+    // Add device to current list of active devices.
+    devices.push_back((*it).second);
+    blocked_keyboards_.erase(it);
+    DeviceDataManager::OnKeyboardDevicesUpdated(devices);
+  }
 }
 
 bool DeviceDataManagerX11::IsEventBlocked(
@@ -707,4 +740,30 @@
   return blocked_devices_.test(xievent->sourceid);
 }
 
+void DeviceDataManagerX11::OnKeyboardDevicesUpdated(
+    const std::vector<KeyboardDevice>& devices) {
+  std::vector<KeyboardDevice> keyboards(devices);
+  for (std::map<unsigned int, KeyboardDevice>::iterator blocked_iter =
+           blocked_keyboards_.begin();
+       blocked_iter != blocked_keyboards_.end();) {
+    // Check if the blocked device still exists in list of devices.
+    std::vector<KeyboardDevice>::iterator it =
+        std::find_if(keyboards.begin(),
+                     keyboards.end(),
+                     std::bind2nd(std::ptr_fun(&KeyboardDeviceHasId),
+                                  (*blocked_iter).first));
+    // If the device no longer exists, unblock it, else filter it out from our
+    // active list.
+    if (it == keyboards.end()) {
+      blocked_devices_.set((*blocked_iter).first, false);
+      blocked_keyboards_.erase(blocked_iter++);
+    } else {
+      keyboards.erase(it);
+      ++blocked_iter;
+    }
+  }
+  // Notify base class of updated list.
+  DeviceDataManager::OnKeyboardDevicesUpdated(keyboards);
+}
+
 }  // namespace ui
diff --git a/ui/events/x/device_data_manager_x11.h b/ui/events/x/device_data_manager_x11.h
index 6ceff06..33a1d0c 100644
--- a/ui/events/x/device_data_manager_x11.h
+++ b/ui/events/x/device_data_manager_x11.h
@@ -15,6 +15,7 @@
 #include <X11/extensions/XInput2.h>
 
 #include <bitset>
+#include <functional>
 #include <map>
 #include <set>
 #include <vector>
@@ -51,37 +52,37 @@
   enum DataType {
     // Define the valuators used the CrOS CMT driver. Used by mice and CrOS
     // touchpads.
-    DT_CMT_SCROLL_X = 0,  // Scroll amount on the X (horizontal) direction.
-    DT_CMT_SCROLL_Y,      // Scroll amount on the Y (vertical) direction.
-    DT_CMT_ORDINAL_X,     // Original (unaccelerated) value on the X direction.
-                          // Can be used both for scrolls and flings.
-    DT_CMT_ORDINAL_Y,     // Original (unaccelerated) value on the Y direction.
-                          // Can be used both for scrolls and flings.
-    DT_CMT_START_TIME,    // Gesture start time.
-    DT_CMT_END_TIME,      // Gesture end time.
-    DT_CMT_FLING_X,       // Fling amount on the X (horizontal) direction.
-    DT_CMT_FLING_Y,       // Fling amount on the Y (vertical) direction.
-    DT_CMT_FLING_STATE,   // The state of fling gesture (whether the user just
-                          // start flinging or that he/she taps down).
-    DT_CMT_METRICS_TYPE,  // Metrics type of the metrics gesture, which are
-                          // used to wrap interesting patterns that we would
-                          // like to track via the UMA system.
-    DT_CMT_METRICS_DATA1, // Complementary data 1 of the metrics gesture.
-    DT_CMT_METRICS_DATA2, // Complementary data 2 of the metrics gesture.
-    DT_CMT_FINGER_COUNT,  // Finger counts in the current gesture. A same type
-                          // of gesture can have very different meanings based
-                          // on that (e.g. 2f scroll v.s. 3f swipe).
+    DT_CMT_SCROLL_X = 0,   // Scroll amount on the X (horizontal) direction.
+    DT_CMT_SCROLL_Y,       // Scroll amount on the Y (vertical) direction.
+    DT_CMT_ORDINAL_X,      // Original (unaccelerated) value on the X direction.
+                           // Can be used both for scrolls and flings.
+    DT_CMT_ORDINAL_Y,      // Original (unaccelerated) value on the Y direction.
+                           // Can be used both for scrolls and flings.
+    DT_CMT_START_TIME,     // Gesture start time.
+    DT_CMT_END_TIME,       // Gesture end time.
+    DT_CMT_FLING_X,        // Fling amount on the X (horizontal) direction.
+    DT_CMT_FLING_Y,        // Fling amount on the Y (vertical) direction.
+    DT_CMT_FLING_STATE,    // The state of fling gesture (whether the user just
+                           // start flinging or that he/she taps down).
+    DT_CMT_METRICS_TYPE,   // Metrics type of the metrics gesture, which are
+                           // used to wrap interesting patterns that we would
+                           // like to track via the UMA system.
+    DT_CMT_METRICS_DATA1,  // Complementary data 1 of the metrics gesture.
+    DT_CMT_METRICS_DATA2,  // Complementary data 2 of the metrics gesture.
+    DT_CMT_FINGER_COUNT,   // Finger counts in the current gesture. A same type
+                           // of gesture can have very different meanings based
+                           // on that (e.g. 2f scroll v.s. 3f swipe).
 
     // End of CMT data types.
     // Beginning of touch data types.
 
     // Define the valuators following the Multi-touch Protocol. Used by
     // touchscreen devices.
-    DT_TOUCH_MAJOR,       // Length of the touch area.
-    DT_TOUCH_MINOR,       // Width of the touch area.
-    DT_TOUCH_ORIENTATION, // Angle between the X-axis and the major axis of the
-                          // touch area.
-    DT_TOUCH_PRESSURE,    // Pressure of the touch contact.
+    DT_TOUCH_MAJOR,        // Length of the touch area.
+    DT_TOUCH_MINOR,        // Width of the touch area.
+    DT_TOUCH_ORIENTATION,  // Angle between the X-axis and the major axis of the
+                           // touch area.
+    DT_TOUCH_PRESSURE,     // Pressure of the touch contact.
 
     DT_TOUCH_POSITION_X,  // Touch X position.
     DT_TOUCH_POSITION_Y,  // Touch Y position.
@@ -90,14 +91,14 @@
     // track individual touch. 'Tracking ID' is an unsigned 32-bit value and
     // is increased for each new touch. It will wrap back to 0 when reaching
     // the numerical limit.
-    DT_TOUCH_TRACKING_ID, // ID of the touch point.
+    DT_TOUCH_TRACKING_ID,  // ID of the touch point.
 
     // Kernel timestamp from touch screen (if available).
     DT_TOUCH_RAW_TIMESTAMP,
 
     // End of touch data types.
 
-    DT_LAST_ENTRY         // This must come last.
+    DT_LAST_ENTRY  // This must come last.
   };
 
   // Data struct to store extracted data from an input event.
@@ -225,7 +226,7 @@
                               DataType type,
                               double value);
 
-  bool TouchEventNeedsCalibrate(int touch_device_id) const;
+  bool TouchEventNeedsCalibrate(unsigned int touch_device_id) const;
 
   // Sets the keys which are still allowed on a disabled keyboard device.
   void SetDisabledKeyboardAllowedKeys(
@@ -238,6 +239,11 @@
   // Returns true if |native_event| should be blocked.
   bool IsEventBlocked(const base::NativeEvent& native_event);
 
+ protected:
+  // DeviceHotplugEventObserver:
+  virtual void OnKeyboardDevicesUpdated(
+      const std::vector<KeyboardDevice>& devices) override;
+
  private:
   DeviceDataManagerX11();
   virtual ~DeviceDataManagerX11();
@@ -300,6 +306,10 @@
   // use this only on touchscreen devices.
   std::vector<double> last_seen_valuator_[kMaxDeviceNum][kMaxSlotNum];
 
+  // Map that stores meta-data for blocked keyboards. This is needed to restore
+  // devices when they are re-enabled.
+  std::map<unsigned int, ui::KeyboardDevice> blocked_keyboards_;
+
   // X11 atoms cache.
   X11AtomCache atom_cache_;
 
diff --git a/ui/events/x/device_data_manager_x11_unittest.cc b/ui/events/x/device_data_manager_x11_unittest.cc
new file mode 100644
index 0000000..08254ea
--- /dev/null
+++ b/ui/events/x/device_data_manager_x11_unittest.cc
@@ -0,0 +1,182 @@
+// 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 "ui/events/x/device_data_manager_x11.h"
+
+#include <vector>
+
+// Generically-named #defines from Xlib that conflict with symbols in GTest.
+#undef Bool
+#undef None
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/device_hotplug_event_observer.h"
+#include "ui/events/input_device.h"
+#include "ui/events/input_device_event_observer.h"
+#include "ui/events/keyboard_device.h"
+#include "ui/events/touchscreen_device.h"
+
+namespace ui {
+namespace test {
+namespace {
+
+class TestInputDeviceObserver : public InputDeviceEventObserver {
+ public:
+  explicit TestInputDeviceObserver(DeviceDataManagerX11* manager)
+      : manager_(manager), change_notified_(false) {
+    if (manager_)
+      manager_->AddObserver(this);
+  }
+
+  virtual ~TestInputDeviceObserver() {
+    if (manager_)
+      manager_->RemoveObserver(this);
+  }
+
+  // InputDeviceEventObserver implementation.
+  virtual void OnTouchscreenDeviceConfigurationChanged() override {}
+  virtual void OnKeyboardDeviceConfigurationChanged() override {
+    change_notified_ = true;
+  }
+
+  int change_notified() const { return change_notified_; }
+  void Reset() { change_notified_ = false; }
+
+ private:
+  DeviceDataManager* manager_;
+  bool change_notified_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestInputDeviceObserver);
+};
+
+}  //  namespace
+
+class DeviceDataManagerX11Test : public testing::Test {
+ public:
+  DeviceDataManagerX11Test() {}
+  virtual ~DeviceDataManagerX11Test() {}
+
+  virtual void SetUp() override { DeviceDataManagerX11::CreateInstance(); }
+
+  virtual void TearDown() override {
+    SetKeyboardDevices(std::vector<KeyboardDevice>());
+  }
+
+  virtual void SetKeyboardDevices(const std::vector<KeyboardDevice>& devices) {
+    DeviceHotplugEventObserver* manager = DeviceDataManagerX11::GetInstance();
+    manager->OnKeyboardDevicesUpdated(devices);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DeviceDataManagerX11Test);
+};
+
+// Tests that the the device data manager notifies observers when a device is
+// disabled and re-enabled.
+TEST_F(DeviceDataManagerX11Test, NotifyOnDisable) {
+  DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
+  TestInputDeviceObserver observer(manager);
+  std::vector<ui::KeyboardDevice> keyboards;
+  keyboards.push_back(ui::KeyboardDevice(
+      1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
+  keyboards.push_back(ui::KeyboardDevice(
+      2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
+  SetKeyboardDevices(keyboards);
+  EXPECT_TRUE(observer.change_notified());
+  std::vector<KeyboardDevice> devices = manager->keyboard_devices();
+  EXPECT_EQ(keyboards.size(), devices.size());
+  observer.Reset();
+  // Disable the device, should be notified that the device list contains one
+  // less device.
+  manager->DisableDevice(2u);
+  EXPECT_TRUE(observer.change_notified());
+  devices = manager->keyboard_devices();
+  EXPECT_EQ(1u, devices.size());
+  KeyboardDevice device = devices.front();
+  EXPECT_EQ(1u, device.id);
+  observer.Reset();
+  // Reenable the device, should be notified that the device list contains one
+  // more device.
+  manager->EnableDevice(2u);
+  EXPECT_TRUE(observer.change_notified());
+  devices = manager->keyboard_devices();
+  EXPECT_EQ(keyboards.size(), devices.size());
+}
+
+// Tests blocking multiple devices.
+TEST_F(DeviceDataManagerX11Test, TestMultipleDisable) {
+  DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
+  TestInputDeviceObserver observer(manager);
+  std::vector<ui::KeyboardDevice> keyboards;
+  keyboards.push_back(ui::KeyboardDevice(
+      1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
+  keyboards.push_back(ui::KeyboardDevice(
+      2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
+  SetKeyboardDevices(keyboards);
+  EXPECT_TRUE(observer.change_notified());
+  std::vector<KeyboardDevice> devices = manager->keyboard_devices();
+  EXPECT_EQ(keyboards.size(), devices.size());
+  observer.Reset();
+  // Disable the device, should be notified that the device list contains one
+  // less device.
+  manager->DisableDevice(1u);
+  EXPECT_TRUE(observer.change_notified());
+  devices = manager->keyboard_devices();
+  EXPECT_EQ(1u, devices.size());
+  observer.Reset();
+  // Disable the second device, should be notified that the device list empty.
+  manager->DisableDevice(2u);
+  EXPECT_TRUE(observer.change_notified());
+  devices = manager->keyboard_devices();
+  EXPECT_EQ(0u, devices.size());
+  observer.Reset();
+  // Enable the first device, should be notified that one device present.
+  manager->EnableDevice(1u);
+  EXPECT_TRUE(observer.change_notified());
+  devices = manager->keyboard_devices();
+  EXPECT_EQ(1u, devices.size());
+  observer.Reset();
+  // Enable the second device, should be notified that both devices present.
+  manager->EnableDevice(2u);
+  EXPECT_TRUE(observer.change_notified());
+  devices = manager->keyboard_devices();
+  EXPECT_EQ(2u, devices.size());
+}
+
+TEST_F(DeviceDataManagerX11Test, UnblockOnDeviceUnplugged) {
+  DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
+  TestInputDeviceObserver observer(manager);
+  std::vector<ui::KeyboardDevice> all_keyboards;
+  all_keyboards.push_back(ui::KeyboardDevice(
+      1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
+  all_keyboards.push_back(ui::KeyboardDevice(
+      2u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
+  SetKeyboardDevices(all_keyboards);
+  EXPECT_TRUE(observer.change_notified());
+  std::vector<KeyboardDevice> devices = manager->keyboard_devices();
+  EXPECT_EQ(all_keyboards.size(), devices.size());
+  observer.Reset();
+  // Expect to be notified that the device is no longer available.
+  manager->DisableDevice(2u);
+  EXPECT_TRUE(observer.change_notified());
+  devices = manager->keyboard_devices();
+  EXPECT_EQ(1u, devices.size());
+  observer.Reset();
+  // Unplug the disabled device. Should not be notified, since the active list
+  // did not change.
+  std::vector<ui::KeyboardDevice> subset_keyboards;
+  subset_keyboards.push_back(ui::KeyboardDevice(
+      1u, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
+  SetKeyboardDevices(subset_keyboards);
+  EXPECT_FALSE(observer.change_notified());
+  // Replug in the first device. Should be notified of the new device.
+  SetKeyboardDevices(all_keyboards);
+  EXPECT_TRUE(observer.change_notified());
+  devices = manager->keyboard_devices();
+  // Both devices now present.
+  EXPECT_EQ(2u, devices.size());
+}
+
+}  // namespace test
+}  // namespace ui
diff --git a/ui/events/x/hotplug_event_handler_x11.cc b/ui/events/x/hotplug_event_handler_x11.cc
index 16f42f7..ae685f87 100644
--- a/ui/events/x/hotplug_event_handler_x11.cc
+++ b/ui/events/x/hotplug_event_handler_x11.cc
@@ -7,6 +7,7 @@
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/XInput2.h>
 
+#include <algorithm>
 #include <cmath>
 #include <set>
 #include <string>
@@ -19,6 +20,8 @@
 #include "base/strings/string_util.h"
 #include "base/sys_info.h"
 #include "ui/events/device_hotplug_event_observer.h"
+#include "ui/events/input_device.h"
+#include "ui/events/keyboard_device.h"
 #include "ui/events/touchscreen_device.h"
 #include "ui/gfx/x/x11_types.h"
 
@@ -26,6 +29,36 @@
 
 namespace {
 
+// The name of the xinput device corresponding to the AT internal keyboard.
+const char kATKeyboardName[] = "AT Translated Set 2 keyboard";
+
+// The prefix of xinput devices corresponding to CrOS EC internal keyboards.
+const char kCrosEcKeyboardPrefix[] = "cros-ec";
+
+// Returns true if |name| is the name of a known keyboard device. Note, this may
+// return false negatives.
+bool IsKnownKeyboard(const std::string& name) {
+  std::string lower = base::StringToLowerASCII(name);
+  return lower.find("keyboard") != std::string::npos;
+}
+
+// Returns true if |name| is the name of a known internal keyboard device. Note,
+// this may return false negatives.
+bool IsInternalKeyboard(const std::string& name) {
+  // TODO(rsadam@): Come up with a more generic way of identifying internal
+  // keyboards. See crbug.com/420728.
+  if (name == kATKeyboardName)
+    return true;
+  return name.compare(
+             0u, strlen(kCrosEcKeyboardPrefix), kCrosEcKeyboardPrefix) == 0;
+}
+
+// Returns true if |name| is the name of a known XTEST device. Note, this may
+// return false negatives.
+bool IsTestKeyboard(const std::string& name) {
+  return name.find("XTEST") != std::string::npos;
+}
+
 // We consider the touchscreen to be internal if it is an I2c device.
 // With the device id, we can query X to get the device's dev input
 // node eventXXX. Then we search all the dev input nodes registered
@@ -116,6 +149,32 @@
   const XIDeviceList& device_list =
       DeviceListCacheX::GetInstance()->GetXI2DeviceList(gfx::GetXDisplay());
   HandleTouchscreenDevices(device_list);
+  HandleKeyboardDevices(device_list);
+}
+
+void HotplugEventHandlerX11::HandleKeyboardDevices(
+    const XIDeviceList& x11_devices) {
+  std::vector<KeyboardDevice> devices;
+
+  for (int i = 0; i < x11_devices.count; i++) {
+    if (!x11_devices[i].enabled || x11_devices[i].use != XISlaveKeyboard)
+      continue;  // Assume all keyboards are keyboard slaves
+    std::string device_name(x11_devices[i].name);
+    base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name);
+    if (IsTestKeyboard(device_name))
+      continue;  // Skip test devices.
+    InputDeviceType type;
+    if (IsInternalKeyboard(device_name)) {
+      type = InputDeviceType::INPUT_DEVICE_INTERNAL;
+    } else if (IsKnownKeyboard(device_name)) {
+      type = InputDeviceType::INPUT_DEVICE_EXTERNAL;
+    } else {
+      type = InputDeviceType::INPUT_DEVICE_UNKNOWN;
+    }
+    devices.push_back(
+        KeyboardDevice(x11_devices[i].deviceid, type, device_name));
+  }
+  delegate_->OnKeyboardDevicesUpdated(devices);
 }
 
 void HotplugEventHandlerX11::HandleTouchscreenDevices(
@@ -169,10 +228,13 @@
     // Touchscreens should have absolute X and Y axes, and be direct touch
     // devices.
     if (width > 0.0 && height > 0.0 && is_direct_touch) {
-      bool is_internal =
-          IsTouchscreenInternal(display, x11_devices[i].deviceid);
+      InputDeviceType type =
+          IsTouchscreenInternal(display, x11_devices[i].deviceid)
+              ? InputDeviceType::INPUT_DEVICE_INTERNAL
+              : InputDeviceType::INPUT_DEVICE_EXTERNAL;
+      std::string name(x11_devices[i].name);
       devices.push_back(TouchscreenDevice(
-          x11_devices[i].deviceid, gfx::Size(width, height), is_internal));
+          x11_devices[i].deviceid, type, name, gfx::Size(width, height)));
     }
   }
 
diff --git a/ui/events/x/hotplug_event_handler_x11.h b/ui/events/x/hotplug_event_handler_x11.h
index c99fbf2..fd735de 100644
--- a/ui/events/x/hotplug_event_handler_x11.h
+++ b/ui/events/x/hotplug_event_handler_x11.h
@@ -23,6 +23,7 @@
 
  private:
   void HandleTouchscreenDevices(const XIDeviceList& device_list);
+  void HandleKeyboardDevices(const XIDeviceList& device_list);
 
   DeviceHotplugEventObserver* delegate_;  // Not owned.
 
diff --git a/ui/file_manager/audio_player/elements/audio_player.js b/ui/file_manager/audio_player/elements/audio_player.js
index ee71220..4b5c282 100644
--- a/ui/file_manager/audio_player/elements/audio_player.js
+++ b/ui/file_manager/audio_player/elements/audio_player.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 Polymer('audio-player', {
   /**
    * Child Elements
diff --git a/ui/file_manager/audio_player/js/audio_player.js b/ui/file_manager/audio_player/js/audio_player.js
index 932dee3..a10c93b5 100644
--- a/ui/file_manager/audio_player/js/audio_player.js
+++ b/ui/file_manager/audio_player/js/audio_player.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Overrided metadata worker's path.
  * @type {string}
diff --git a/ui/file_manager/audio_player/js/background.js b/ui/file_manager/audio_player/js/background.js
index 23cf74c2..22e14643 100644
--- a/ui/file_manager/audio_player/js/background.js
+++ b/ui/file_manager/audio_player/js/background.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Icon of the audio player.
  * TODO(yoshiki): Consider providing an exact size icon, instead of relying
diff --git a/ui/file_manager/audio_player/js/metadata_worker.js b/ui/file_manager/audio_player/js/metadata_worker.js
index 56ea36c7e..26af2a1 100644
--- a/ui/file_manager/audio_player/js/metadata_worker.js
+++ b/ui/file_manager/audio_player/js/metadata_worker.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 // Load the worker script of Files.app.
 importScripts(
     'chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/' +
diff --git a/ui/file_manager/externs/html_menu_item_element.js b/ui/file_manager/externs/html_menu_item_element.js
new file mode 100644
index 0000000..b9e40a4e
--- /dev/null
+++ b/ui/file_manager/externs/html_menu_item_element.js
@@ -0,0 +1,58 @@
+// 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.
+
+/**
+ * @constructor
+ * @extends {HTMLElement}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#the-menuitem-element
+ */
+function HTMLMenuItemElement() {}
+
+/**
+ * @type {string}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#dom-menuitem-type
+ */
+HTMLMenuItemElement.prototype.type;
+
+/**
+ * @type {string}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#dom-menuitem-label
+ */
+HTMLMenuItemElement.prototype.label;
+
+/**
+ * @type {string}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#dom-menuitem-icon
+ */
+HTMLMenuItemElement.prototype.icon;
+
+/**
+ * @type {boolean}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#dom-menuitem-disabled
+ */
+HTMLMenuItemElement.prototype.disabled;
+
+/**
+ * @type {boolean}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#dom-menuitem-checked
+ */
+HTMLMenuItemElement.prototype.checked;
+
+/**
+ * @type {string}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#dom-menuitem-radiogroup
+ */
+HTMLMenuItemElement.prototype.radiogroup;
+
+/**
+ * @type {boolean}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#dom-menuitem-default
+ */
+HTMLMenuItemElement.prototype.default;
+
+/**
+ * @type {HTMLElement|undefined}
+ * @see http://www.w3.org/html/wg/drafts/html/master/interactive-elements.html#dom-menuitem-command
+ */
+HTMLMenuItemElement.prototype.command;
diff --git a/ui/file_manager/file_manager/background/js/app_window_wrapper.js b/ui/file_manager/file_manager/background/js/app_window_wrapper.js
index 6a0cf2b..9fccfce 100644
--- a/ui/file_manager/file_manager/background/js/app_window_wrapper.js
+++ b/ui/file_manager/file_manager/background/js/app_window_wrapper.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Wrapper for an app window.
  *
diff --git a/ui/file_manager/file_manager/background/js/background.js b/ui/file_manager/file_manager/background/js/background.js
index e21cf51..7ae1896 100644
--- a/ui/file_manager/file_manager/background/js/background.js
+++ b/ui/file_manager/file_manager/background/js/background.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Type of a Files.app's instance launch.
  * @enum {number}
diff --git a/ui/file_manager/file_manager/background/js/background_base.js b/ui/file_manager/file_manager/background/js/background_base.js
index bb65302..f0a86a0 100644
--- a/ui/file_manager/file_manager/background/js/background_base.js
+++ b/ui/file_manager/file_manager/background/js/background_base.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Root class of the background page.
  * @constructor
diff --git a/ui/file_manager/file_manager/background/js/device_handler.js b/ui/file_manager/file_manager/background/js/device_handler.js
index ede5409..7c42ce7 100644
--- a/ui/file_manager/file_manager/background/js/device_handler.js
+++ b/ui/file_manager/file_manager/background/js/device_handler.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Handler of device event.
  * @constructor
diff --git a/ui/file_manager/file_manager/background/js/drive_sync_handler.js b/ui/file_manager/file_manager/background/js/drive_sync_handler.js
index 505f926..066972b 100644
--- a/ui/file_manager/file_manager/background/js/drive_sync_handler.js
+++ b/ui/file_manager/file_manager/background/js/drive_sync_handler.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Handler of the background page for the drive sync events.
  * @param {ProgressCenter} progressCenter Progress center to submit the
diff --git a/ui/file_manager/file_manager/background/js/file_operation_handler.js b/ui/file_manager/file_manager/background/js/file_operation_handler.js
index c3dd81b..5ea0d918 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_handler.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_handler.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * An event handler of the background page for file operations.
  * @param {FileBrowserBackground} background Background page.
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager.js b/ui/file_manager/file_manager/background/js/file_operation_manager.js
index 67b81be1..10d6026 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_manager.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_manager.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Utilities for FileOperationManager.
  */
diff --git a/ui/file_manager/file_manager/background/js/progress_center.js b/ui/file_manager/file_manager/background/js/progress_center.js
index a8b1fe2b..1fb83b5 100644
--- a/ui/file_manager/file_manager/background/js/progress_center.js
+++ b/ui/file_manager/file_manager/background/js/progress_center.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Progress center at the background page.
  * @constructor
diff --git a/ui/file_manager/file_manager/background/js/volume_manager.js b/ui/file_manager/file_manager/background/js/volume_manager.js
index 1f0704a..41a0c52 100644
--- a/ui/file_manager/file_manager/background/js/volume_manager.js
+++ b/ui/file_manager/file_manager/background/js/volume_manager.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Represents each volume, such as "drive", "download directory", each "USB
  * flush storage", or "mounted zip archive" etc.
diff --git a/ui/file_manager/file_manager/common/js/async_util.js b/ui/file_manager/file_manager/common/js/async_util.js
index dcd03e3..16a1ca28 100644
--- a/ui/file_manager/file_manager/common/js/async_util.js
+++ b/ui/file_manager/file_manager/common/js/async_util.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Namespace for async utility functions.
  */
diff --git a/ui/file_manager/file_manager/common/js/error_util.js b/ui/file_manager/file_manager/common/js/error_util.js
index 15cbc6ff..9fd8f11 100644
--- a/ui/file_manager/file_manager/common/js/error_util.js
+++ b/ui/file_manager/file_manager/common/js/error_util.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * This variable is checked in SelectFileDialogExtensionBrowserTest.
  * @type {number}
diff --git a/ui/file_manager/file_manager/common/js/progress_center_common.js b/ui/file_manager/file_manager/common/js/progress_center_common.js
index 56ff028..dd73d8eb 100644
--- a/ui/file_manager/file_manager/common/js/progress_center_common.js
+++ b/ui/file_manager/file_manager/common/js/progress_center_common.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Event of the ProgressCenter class.
  * @enum {string}
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js
index 02620223..6e73c087 100644
--- a/ui/file_manager/file_manager/common/js/util.js
+++ b/ui/file_manager/file_manager/common/js/util.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Namespace for utility functions.
  */
diff --git a/ui/file_manager/file_manager/common/js/volume_manager_common.js b/ui/file_manager/file_manager/common/js/volume_manager_common.js
index 2d0f7295..249969c 100644
--- a/ui/file_manager/file_manager/common/js/volume_manager_common.js
+++ b/ui/file_manager/file_manager/common/js/volume_manager_common.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Namespace for common types shared between VolumeManager and
  * VolumeManagerWrapper.
diff --git a/ui/file_manager/file_manager/foreground/css/list.css b/ui/file_manager/file_manager/foreground/css/list.css
index d102d69..7e4ae21f 100644
--- a/ui/file_manager/file_manager/foreground/css/list.css
+++ b/ui/file_manager/file_manager/foreground/css/list.css
@@ -62,7 +62,7 @@
     button,
     input[type='button'],
     input[type='submit'],
-    select):not(.custom-appearance):not(.link-button) {
+    select):not(.custom-appearance) {
   line-height: normal;
   vertical-align: middle;
 }
diff --git a/ui/file_manager/file_manager/foreground/js/app_installer.js b/ui/file_manager/file_manager/foreground/js/app_installer.js
index 4b75bea..7cd74712 100644
--- a/ui/file_manager/file_manager/foreground/js/app_installer.js
+++ b/ui/file_manager/file_manager/foreground/js/app_installer.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Manage the installation of apps.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
index 0a389d83..7d54aa26 100644
--- a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
+++ b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
@@ -78,6 +78,7 @@
           './thumbnail_loader.js',
           './ui/conflict_dialog.js',
           './ui/default_action_dialog.js',
+          './ui/dialog_footer.js',
           './ui/directory_tree.js',
           './ui/drag_selector.js',
           './ui/drive_banners.js',
@@ -103,6 +104,7 @@
           '<(CLOSURE_DIR)/externs/file_manager_private.js',
           '<(CLOSURE_DIR)/externs/metrics_private.js',
           '../../common/js/externs.js',
+          '../../../externs/html_menu_item_element.js',
         ],
       },
       'includes': [
diff --git a/ui/file_manager/file_manager/foreground/js/cws_container_client.js b/ui/file_manager/file_manager/foreground/js/cws_container_client.js
index 612bbe5..d177630e 100644
--- a/ui/file_manager/file_manager/foreground/js/cws_container_client.js
+++ b/ui/file_manager/file_manager/foreground/js/cws_container_client.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {WebView} webView Web View tag.
  * @param {?string} ext File extension.
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js
index aec6b15..5aa0678 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_contents.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Scanner of the entries.
  * @constructor
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js
index 1f943531..ac27ae8 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 // If directory files changes too often, don't rescan directory more than once
 // per specified interval
 var SIMULTANEOUS_RESCAN_INTERVAL = 500;
@@ -274,7 +272,8 @@
  */
 DirectoryModel.prototype.getLeadEntry_ = function() {
   var index = this.fileListSelection_.leadIndex;
-  return index >= 0 && this.getFileList().item(index);
+  return index >= 0 ?
+      /** @type {Entry} */ (this.getFileList().item(index)) : null;
 };
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index 4344c58c..40db19e 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * FileManager constructor.
  *
@@ -111,14 +109,14 @@
 
   /**
    * List of acceptable file types for open dialog.
-   * @type {Array.<Object>}
+   * @type {!Array.<Object>}
    * @private
    */
   this.fileTypes_ = [];
 
   /**
    * Startup parameters for this application.
-   * @type {Object}
+   * @type {?{includeAllFiles:boolean, action:string}}
    * @private
    */
   this.params_ = null;
@@ -232,29 +230,8 @@
   // Menus.
 
   /**
-   * Context menu for files.
-   * @type {HTMLMenuElement}
-   * @private
-   */
-  this.fileContextMenu_ = null;
-
-  /**
-   * Context menu for volumes or shortcuts displayed on left pane.
-   * @type {HTMLMenuElement}
-   * @private
-   */
-  this.rootsContextMenu_ = null;
-
-  /**
-   * Context menu for directory tree items.
-   * @type {HTMLMenuElement}
-   * @private
-   */
-  this.directoryTreeContextMenu_ = null;
-
-  /**
    * Context menu for texts.
-   * @type {HTMLMenuElement}
+   * @type {cr.ui.Menu}
    * @private
    */
   this.textContextMenu_ = null;
@@ -304,26 +281,12 @@
 
   /**
    * The button to open gear menu.
-   * @type {HTMLButtonElement}
+   * @type {cr.ui.MenuButton}
    * @private
    */
   this.gearButton_ = null;
 
   /**
-   * The OK button.
-   * @type {HTMLButtonElement}
-   * @private
-   */
-  this.okButton_ = null;
-
-  /**
-   * The cancel button.
-   * @type {HTMLButtonElement}
-   * @private
-   */
-  this.cancelButton_ = null;
-
-  /**
    * The combo button to specify the task.
    * @type {HTMLButtonElement}
    * @private
@@ -338,13 +301,6 @@
   this.renameInput_ = null;
 
   /**
-   * The input element to specify file name.
-   * @type {HTMLInputElement}
-   * @private
-   */
-  this.filenameInput_ = null;
-
-  /**
    * The file table.
    * @type {FileTable}
    * @private
@@ -387,13 +343,6 @@
   this.listContainer_ = null;
 
   /**
-   * The file type selector.
-   * @type {HTMLSelectElement}
-   * @private
-   */
-  this.fileTypeSelector_ = null;
-
-  /**
    * Open-with command in the context menu.
    * @type {cr.ui.Command}
    * @private
@@ -604,27 +553,51 @@
 
 FileManager.prototype = {
   __proto__: cr.EventTarget.prototype,
+  /**
+   * @return {DirectoryModel}
+   */
   get directoryModel() {
     return this.directoryModel_;
   },
+  /**
+   * @return {DirectoryTree}
+   */
   get directoryTree() {
     return this.directoryTree_;
   },
+  /**
+   * @return {HTMLDocument}
+   */
   get document() {
     return this.document_;
   },
+  /**
+   * @return {FileTransferController}
+   */
   get fileTransferController() {
     return this.fileTransferController_;
   },
+  /**
+   * @return {FileOperationManager}
+   */
   get fileOperationManager() {
     return this.fileOperationManager_;
   },
+  /**
+   * @return {BackgroundWindow}
+   */
   get backgroundPage() {
     return this.backgroundPage_;
   },
+  /**
+   * @return {VolumeManagerWrapper}
+   */
   get volumeManager() {
     return this.volumeManager_;
   },
+  /**
+   * @return {FileManagerUI}
+   */
   get ui() {
     return this.ui_;
   }
@@ -997,37 +970,53 @@
    * @private
    */
   FileManager.prototype.initContextMenus_ = function() {
-    this.fileContextMenu_ = this.dialogDom_.querySelector('#file-context-menu');
-    cr.ui.Menu.decorate(this.fileContextMenu_);
+    assert(this.grid_);
+    assert(this.table_);
+    assert(this.document_);
+    assert(this.dialogDom_);
 
-    cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_);
-    cr.ui.contextMenuHandler.setContextMenu(this.table_.querySelector('.list'),
-        this.fileContextMenu_);
+    // Set up the context menu for the file list.
+    var fileContextMenu = queryRequiredElement(
+        this.dialogDom_, '#file-context-menu');
+    cr.ui.Menu.decorate(fileContextMenu);
+    fileContextMenu = /** @type {!cr.ui.Menu} */ (fileContextMenu);
+
+    cr.ui.contextMenuHandler.setContextMenu(this.grid_, fileContextMenu);
     cr.ui.contextMenuHandler.setContextMenu(
-        this.document_.querySelector('.drive-welcome.page'),
-        this.fileContextMenu_);
+        queryRequiredElement(this.table_, '.list'), fileContextMenu);
+    cr.ui.contextMenuHandler.setContextMenu(
+        queryRequiredElement(this.document_, '.drive-welcome.page'),
+        fileContextMenu);
 
-    this.rootsContextMenu_ =
-        this.dialogDom_.querySelector('#roots-context-menu');
-    cr.ui.Menu.decorate(this.rootsContextMenu_);
-    this.directoryTree_.contextMenuForRootItems = this.rootsContextMenu_;
+    // Set up the context menu for the volume/shortcut items in directory tree.
+    var rootsContextMenu = queryRequiredElement(
+        this.dialogDom_, '#roots-context-menu');
+    cr.ui.Menu.decorate(rootsContextMenu);
+    rootsContextMenu = /** @type {!cr.ui.Menu} */ (rootsContextMenu);
 
-    this.directoryTreeContextMenu_ =
-        this.dialogDom_.querySelector('#directory-tree-context-menu');
-    cr.ui.Menu.decorate(this.directoryTreeContextMenu_);
-    this.directoryTree_.contextMenuForSubitems = this.directoryTreeContextMenu_;
+    this.directoryTree_.contextMenuForRootItems = rootsContextMenu;
 
-    this.textContextMenu_ =
-        this.dialogDom_.querySelector('#text-context-menu');
-    cr.ui.Menu.decorate(this.textContextMenu_);
+    // Set up the context menu for the folder items in directory tree.
+    var directoryTreeContextMenu = queryRequiredElement(
+        this.dialogDom_, '#directory-tree-context-menu');
+    cr.ui.Menu.decorate(directoryTreeContextMenu);
+    directoryTreeContextMenu =
+        /** @type {!cr.ui.Menu} */ (directoryTreeContextMenu);
 
-    this.gearButton_ = this.dialogDom_.querySelector('#gear-button');
-    this.gearButton_.addEventListener('menushow',
-        this.onShowGearMenu_.bind(this));
+    this.directoryTree_.contextMenuForSubitems = directoryTreeContextMenu;
 
+    // Set up the context menu for the text editing.
+    var textContextMenu = queryRequiredElement(
+        this.dialogDom_, '#text-context-menu');
+    cr.ui.Menu.decorate(textContextMenu);
+    this.textContextMenu_ = /** @type {!cr.ui.Menu} */ (textContextMenu);
+
+    var gearButton = queryRequiredElement(this.dialogDom_, '#gear-button');
+    gearButton.addEventListener('menushow', this.onShowGearMenu_.bind(this));
     this.dialogDom_.querySelector('#gear-menu').menuItemSelector =
         'menuitem, hr';
-    cr.ui.decorate(this.gearButton_, cr.ui.MenuButton);
+    cr.ui.decorate(gearButton, cr.ui.MenuButton);
+    this.gearButton_ = /** @type {!cr.ui.MenuButton} */ (gearButton);
 
     this.syncButton.checkable = true;
     this.hostedButton.checkable = true;
@@ -1068,6 +1057,9 @@
    * @private
    */
   FileManager.prototype.initCommands_ = function() {
+    assert(this.textContextMenu_);
+    assert(this.renameInput_);
+
     this.commandHandler = new CommandHandler(this);
 
     // TODO(hirono): Move the following block to the UI part.
@@ -1248,9 +1240,6 @@
 
     // Create the root view of FileManager.
     this.ui_ = new FileManagerUI(this.dialogDom_, this.dialogType);
-    this.fileTypeSelector_ = this.ui_.fileTypeSelector;
-    this.okButton_ = this.ui_.okButton;
-    this.cancelButton_ = this.ui_.cancelButton;
 
     // Show the window as soon as the UI pre-initialization is done.
     if (this.dialogType == DialogType.FULL_PAGE && !util.runningInBrowser()) {
@@ -1303,22 +1292,25 @@
     // Cache nodes we'll be manipulating.
     var dom = this.dialogDom_;
 
-    this.filenameInput_ = dom.querySelector('#filename-input-box input');
-    this.taskItems_ = dom.querySelector('#tasks');
+    var taskItems = queryRequiredElement(dom, '#tasks');
+    this.taskItems_ = /** @type {HTMLButtonElement} */ (taskItems);
 
-    this.table_ = dom.querySelector('.detail-table');
-    this.grid_ = dom.querySelector('.thumbnail-grid');
-    this.spinner_ = dom.querySelector('#list-container > .spinner-layer');
+    var spinner = queryRequiredElement(dom, '#list-container > .spinner-layer');
+    this.spinner_ = /** @type {HTMLDivElement} */ (spinner);
     this.showSpinner_(true);
 
     var fullPage = this.dialogType == DialogType.FULL_PAGE;
+    var table = queryRequiredElement(dom, '.detail-table');
+    var grid = queryRequiredElement(dom, '.thumbnail-grid');
     FileTable.decorate(
-        this.table_, this.metadataCache_, this.volumeManager_, fullPage);
-    FileGrid.decorate(this.grid_, this.metadataCache_, this.volumeManager_);
+        table, this.metadataCache_, this.volumeManager_, fullPage);
+    FileGrid.decorate(grid, this.metadataCache_, this.volumeManager_);
+    this.table_ = /** @type {!FileTable} */ (table);
+    this.grid_ = /** @type {!FileGrid} */ (grid);
 
     this.ui_.locationLine = new LocationLine(
-        dom.querySelector('#location-breadcrumbs'),
-        dom.querySelector('#location-volume-icon'),
+        queryRequiredElement(dom, '#location-breadcrumbs'),
+        queryRequiredElement(dom, '#location-volume-icon'),
         this.metadataCache_,
         this.volumeManager_);
     this.ui_.locationLine.addEventListener(
@@ -1338,7 +1330,7 @@
 
     // Initialize progress center panel.
     this.progressCenterPanel_ = new ProgressCenterPanel(
-        dom.querySelector('#progress-center'));
+        queryRequiredElement(dom, '#progress-center'));
     this.backgroundPage_.background.progressCenter.addPanel(
         this.progressCenterPanel_);
 
@@ -1355,11 +1347,11 @@
         'blur', this.onRenameInputBlur_.bind(this));
 
     // TODO(hirono): Rename the handler after creating the DialogFooter class.
-    this.filenameInput_.addEventListener(
+    this.ui_.dialogFooter.filenameInput.addEventListener(
         'input', this.onFilenameInputInput_.bind(this));
-    this.filenameInput_.addEventListener(
+    this.ui_.dialogFooter.filenameInput.addEventListener(
         'keydown', this.onFilenameInputKeyDown_.bind(this));
-    this.filenameInput_.addEventListener(
+    this.ui_.dialogFooter.filenameInput.addEventListener(
         'focus', this.onFilenameInputFocus_.bind(this));
 
     this.listContainer_ = /** @type {!HTMLDivElement} */
@@ -1371,9 +1363,11 @@
     this.listContainer_.addEventListener(
         'mousemove', this.onListMouseMove_.bind(this));
 
-    this.okButton_.addEventListener('click', this.onOk_.bind(this));
+    this.ui_.dialogFooter.okButton.addEventListener(
+        'click', this.onOk_.bind(this));
     this.onCancelBound_ = this.onCancel_.bind(this);
-    this.cancelButton_.addEventListener('click', this.onCancelBound_);
+    this.ui_.dialogFooter.cancelButton.addEventListener(
+        'click', this.onCancelBound_);
 
     this.decorateSplitter(
         this.dialogDom_.querySelector('#navigation-list-splitter'));
@@ -1381,10 +1375,12 @@
     this.dialogContainer_ = /** @type {!HTMLDivElement} */
         (this.dialogDom_.querySelector('.dialog-container'));
 
-    this.syncButton = /** @type {!HTMLElement} */
-        (this.dialogDom_.querySelector('#gear-menu-drive-sync-settings'));
-    this.hostedButton = /** @type {!HTMLElement} */
-        (this.dialogDom_.querySelector('#gear-menu-drive-hosted-settings'));
+    this.syncButton = /** @type {!HTMLMenuItemElement} */
+        (queryRequiredElement(this.dialogDom_,
+                              '#gear-menu-drive-sync-settings'));
+    this.hostedButton = /** @type {!HTMLMenuItemElement} */
+        (queryRequiredElement(this.dialogDom_,
+                             '#gear-menu-drive-hosted-settings'));
 
     this.ui_.toggleViewButton.addEventListener('click',
         this.onToggleViewButtonClick_.bind(this));
@@ -1402,8 +1398,8 @@
     this.dialogDom_.ownerDocument.defaultView.addEventListener(
         'resize', this.onResize_.bind(this));
 
-    this.defaultActionMenuItem_ = /** @type {HTMLElement} */
-        (this.dialogDom_.querySelector('#default-action'));
+    this.defaultActionMenuItem_ = /** @type {!HTMLMenuItemElement} */
+        (queryRequiredElement(this.dialogDom_, '#default-action'));
 
     this.openWithCommand_ = /** @type {cr.ui.Command} */
         (this.dialogDom_.querySelector('#open-with'));
@@ -1411,7 +1407,10 @@
     this.defaultActionMenuItem_.addEventListener('activate',
         this.dispatchSelectionAction_.bind(this));
 
-    this.initFileTypeFilter_();
+    this.ui_.dialogFooter.initFileTypeFilter(
+        this.fileTypes_, this.params_.includeAllFiles);
+    this.ui_.dialogFooter.fileTypeSelector.addEventListener(
+        'change', this.updateFileTypeFilter_.bind(this));
 
     util.addIsFocusedMethod();
 
@@ -1622,7 +1621,7 @@
   FileManager.prototype.refocus = function() {
     var targetElement;
     if (this.dialogType == DialogType.SELECT_SAVEAS_FILE)
-      targetElement = this.filenameInput_;
+      targetElement = this.ui_.dialogFooter.filenameInput;
     else
       targetElement = this.currentList_;
 
@@ -1650,21 +1649,6 @@
     }
   };
 
-  /**
-   * Index of selected item in the typeList of the dialog params.
-   *
-   * @return {number} 1-based index of selected type or 0 if no type selected.
-   * @private
-   */
-  FileManager.prototype.getSelectedFilterIndex_ = function() {
-    var index = Number(this.fileTypeSelector_.selectedIndex);
-    if (index < 0)  // Nothing selected.
-      return 0;
-    if (this.params_.includeAllFiles)  // Already 1-based.
-      return index;
-    return index + 1;  // Convert to 1-based;
-  };
-
   FileManager.prototype.setListType = function(type) {
     if (type && type == this.listType_)
       return;
@@ -1790,68 +1774,12 @@
   };
 
   /**
-   * Fills the file type list or hides it.
-   * @private
-   */
-  FileManager.prototype.initFileTypeFilter_ = function() {
-    if (this.params_.includeAllFiles) {
-      var option = this.document_.createElement('option');
-      option.innerText = str('ALL_FILES_FILTER');
-      this.fileTypeSelector_.appendChild(option);
-      option.value = 0;
-    }
-
-    for (var i = 0; i !== this.fileTypes_.length; i++) {
-      var fileType = this.fileTypes_[i];
-      var option = this.document_.createElement('option');
-      var description = fileType.description;
-      if (!description) {
-        // See if all the extensions in the group have the same description.
-        for (var j = 0; j !== fileType.extensions.length; j++) {
-          var currentDescription = FileType.typeToString(
-              FileType.getTypeForName('.' + fileType.extensions[j]));
-          if (!description)  // Set the first time.
-            description = currentDescription;
-          else if (description != currentDescription) {
-            // No single description, fall through to the extension list.
-            description = null;
-            break;
-          }
-        }
-
-        if (!description)
-          // Convert ['jpg', 'png'] to '*.jpg, *.png'.
-          description = fileType.extensions.map(function(s) {
-            return '*.' + s;
-          }).join(', ');
-      }
-      option.innerText = description;
-
-      option.value = i + 1;
-
-      if (fileType.selected)
-        option.selected = true;
-
-      this.fileTypeSelector_.appendChild(option);
-    }
-
-    var options = this.fileTypeSelector_.querySelectorAll('option');
-    if (options.length >= 2) {
-      // There is in fact no choice, show the selector.
-      this.fileTypeSelector_.hidden = false;
-
-      this.fileTypeSelector_.addEventListener('change',
-          this.updateFileTypeFilter_.bind(this));
-    }
-  };
-
-  /**
    * Filters file according to the selected file type.
    * @private
    */
   FileManager.prototype.updateFileTypeFilter_ = function() {
     this.fileFilter_.removeFilter('fileType');
-    var selectedIndex = this.getSelectedFilterIndex_();
+    var selectedIndex = this.ui_.dialogFooter.selectedFilterIndex;
     if (selectedIndex > 0) { // Specific filter selected.
       var regexp = new RegExp('\\.(' +
           this.fileTypes_[selectedIndex - 1].extensions.join('|') + ')$', 'i');
@@ -1862,12 +1790,13 @@
 
       // In save dialog, update the destination name extension.
       if (this.dialogType === DialogType.SELECT_SAVEAS_FILE) {
-        var current = this.filenameInput_.value;
+        var current = this.ui_.dialogFooter.filenameInput.value;
         var newExt = this.fileTypes_[selectedIndex - 1].extensions[0];
         if (newExt && !regexp.test(current)) {
           var i = current.lastIndexOf('.');
           if (i >= 0) {
-            this.filenameInput_.value = current.substr(0, i) + '.' + newExt;
+            this.ui_.dialogFooter.filenameInput.value =
+                current.substr(0, i) + '.' + newExt;
             this.selectTargetNameInFilenameInput_();
           }
         }
@@ -2177,7 +2106,7 @@
         this.directoryModel_.addEventListener('scan-completed', listener);
       }
     } else if (this.dialogType === DialogType.SELECT_SAVEAS_FILE) {
-      this.filenameInput_.value = opt_suggestedName || '';
+      this.ui_.dialogFooter.filenameInput.value = opt_suggestedName || '';
       this.selectTargetNameInFilenameInput_();
     }
   };
@@ -2542,7 +2471,7 @@
    * @private
    */
   FileManager.prototype.selectTargetNameInFilenameInput_ = function() {
-    var input = this.filenameInput_;
+    var input = this.ui_.dialogFooter.filenameInput;
     input.focus();
     var selectionEnd = input.value.lastIndexOf('.');
     if (selectionEnd == -1) {
@@ -2600,7 +2529,7 @@
         tasks.executeDefault();
       return true;
     }
-    if (!this.okButton_.disabled) {
+    if (!this.ui_.dialogFooter.okButton.disabled) {
       this.onOk_();
       return true;
     }
@@ -3068,7 +2997,7 @@
    */
   FileManager.prototype.onFilenameInputKeyDown_ = function(event) {
     if ((util.getKeyModifiers(event) + event.keyCode) === '13' /* Enter */)
-      this.okButton_.click();
+      this.ui_.dialogFooter.okButton.click();
   };
 
   /**
@@ -3076,7 +3005,7 @@
    * @private
    */
   FileManager.prototype.onFilenameInputFocus_ = function(event) {
-    var input = this.filenameInput_;
+    var input = this.ui_.dialogFooter.filenameInput;
 
     // On focus we want to select everything but the extension, but
     // Chrome will select-all after the focus event completes.  We
@@ -3372,7 +3301,7 @@
         if (this.dialogType != DialogType.FULL_PAGE) {
           // If there is nothing else for ESC to do, then cancel the dialog.
           event.preventDefault();
-          this.cancelButton_.click();
+          this.ui_.dialogFooter.cancelButton.click();
         }
         break;
     }
@@ -3607,8 +3536,9 @@
       this.document_.querySelector('.dialog-container').appendChild(shade);
       setTimeout(function() { shade.setAttribute('fadein', 'fadein'); }, 100);
       footer.setAttribute('progress', 'progress');
-      this.cancelButton_.removeEventListener('click', this.onCancelBound_);
-      this.cancelButton_.addEventListener('click', onCancel);
+      this.ui_.dialogFooter.cancelButton.removeEventListener(
+          'click', this.onCancelBound_);
+      this.ui_.dialogFooter.cancelButton.addEventListener('click', onCancel);
       chrome.fileManagerPrivate.onFileTransfersUpdated.addListener(
           onFileTransfersUpdated);
     }.bind(this);
@@ -3616,8 +3546,9 @@
     var cleanup = function() {
       shade.parentNode.removeChild(shade);
       footer.removeAttribute('progress');
-      this.cancelButton_.removeEventListener('click', onCancel);
-      this.cancelButton_.addEventListener('click', this.onCancelBound_);
+      this.ui_.dialogFooter.cancelButton.removeEventListener('click', onCancel);
+      this.ui_.dialogFooter.cancelButton.addEventListener(
+          'click', this.onCancelBound_);
       chrome.fileManagerPrivate.onFileTransfersUpdated.removeListener(
           onFileTransfersUpdated);
     }.bind(this);
@@ -3659,7 +3590,7 @@
     if (this.dialogType == DialogType.SELECT_SAVEAS_FILE) {
       // Save-as doesn't require a valid selection from the list, since
       // we're going to take the filename from the text input.
-      var filename = this.filenameInput_.value;
+      var filename = this.ui_.dialogFooter.filenameInput.value;
       if (!filename)
         throw new Error('Missing filename!');
 
@@ -3682,7 +3613,7 @@
           this.selectFilesAndClose_({
             urls: [currentDirUrl + encodeURIComponent(filename)],
             multiple: false,
-            filterIndex: this.getSelectedFilterIndex_(filename)
+            filterIndex: this.ui_.dialogFooter.selectedFilterIndex
           });
         }.bind(this);
 
@@ -3724,7 +3655,7 @@
       var singleSelection = {
         urls: [url],
         multiple: false,
-        filterIndex: this.getSelectedFilterIndex_()
+        filterIndex: this.ui_.dialogFooter.selectedFilterIndex
       };
       this.selectFilesAndClose_(singleSelection);
       return;
@@ -3774,7 +3705,7 @@
     var singleSelection = {
       urls: [files[0]],
       multiple: false,
-      filterIndex: this.getSelectedFilterIndex_()
+      filterIndex: this.ui_.dialogFooter.selectedFilterIndex
     };
     this.selectFilesAndClose_(singleSelection);
   };
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index a1ee73c..f45c70b 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * TODO(dzvorygin): Here we use this hack, since 'hidden' is standard
  * attribute and we can't use it's setter as usual.
diff --git a/ui/file_manager/file_manager/foreground/js/file_selection.js b/ui/file_manager/file_manager/foreground/js/file_selection.js
index ef3ff25..86df259 100644
--- a/ui/file_manager/file_manager/foreground/js/file_selection.js
+++ b/ui/file_manager/file_manager/foreground/js/file_selection.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * The current selection object.
  *
@@ -159,8 +157,8 @@
 function FileSelectionHandler(fileManager) {
   this.fileManager_ = fileManager;
   // TODO(dgozman): create a shared object with most of UI elements.
-  this.okButton_ = fileManager.okButton_;
-  this.filenameInput_ = fileManager.filenameInput_;
+  this.okButton_ = fileManager.ui.dialogFooter.okButton;
+  this.filenameInput_ = fileManager.ui.dialogFooter.filenameInput;
   this.previewPanel_ = fileManager.previewPanel_;
   this.taskItems_ = fileManager.taskItems_;
 }
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js
index fcf383a..d8a4537 100644
--- a/ui/file_manager/file_manager/foreground/js/file_tasks.js
+++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * This object encapsulates everything related to tasks execution.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
index f37baeb..fc43cc1c 100644
--- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Global (placed in the window object) variable name to hold internal
  * file dragging information. Needed to show visual feedback while dragging
diff --git a/ui/file_manager/file_manager/foreground/js/file_type.js b/ui/file_manager/file_manager/foreground/js/file_type.js
index 046a716..f82a3d1 100644
--- a/ui/file_manager/file_manager/foreground/js/file_type.js
+++ b/ui/file_manager/file_manager/foreground/js/file_type.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Namespace object for file type utility functions.
  */
diff --git a/ui/file_manager/file_manager/foreground/js/file_watcher.js b/ui/file_manager/file_manager/foreground/js/file_watcher.js
index dc59e70..ed43e41d 100644
--- a/ui/file_manager/file_manager/foreground/js/file_watcher.js
+++ b/ui/file_manager/file_manager/foreground/js/file_watcher.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Watches for changes in the tracked directory, including local metadata
  * changes.
diff --git a/ui/file_manager/file_manager/foreground/js/main.js b/ui/file_manager/file_manager/foreground/js/main.js
index 140b2e0..f624b50 100644
--- a/ui/file_manager/file_manager/foreground/js/main.js
+++ b/ui/file_manager/file_manager/foreground/js/main.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @type {FileManager}
  */
diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js
index 8fd4a36..4fe9dec7 100644
--- a/ui/file_manager/file_manager/foreground/js/main_scripts.js
+++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js
@@ -65,6 +65,7 @@
 
 (function() {
 // 'strict mode' is invoked for this scope.
+'use strict';
 
 // error_util.js must be loaded before all other Files.app's scripts.
 //<include src="../../common/js/error_util.js">
@@ -98,6 +99,7 @@
 //<include src="thumbnail_loader.js">
 //<include src="ui/conflict_dialog.js">
 //<include src="ui/default_action_dialog.js">
+//<include src="ui/dialog_footer.js">
 //<include src="ui/directory_tree.js">
 //<include src="ui/drag_selector.js">
 //<include src="ui/drive_banners.js" >
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/byte_reader.js b/ui/file_manager/file_manager/foreground/js/metadata/byte_reader.js
index e422bf5..5bf28a3 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/byte_reader.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/byte_reader.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @constructor
  * @param {ArrayBuffer} arrayBuffer An array of buffers to be read from.
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/exif_parser.js b/ui/file_manager/file_manager/foreground/js/metadata/exif_parser.js
index 9d9e3ecf..fafcc79 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/exif_parser.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/exif_parser.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 var EXIF_MARK_SOI = 0xffd8;  // Start of image data.
 var EXIF_MARK_SOS = 0xffda;  // Start of "stream" (the actual image data).
 var EXIF_MARK_SOF = 0xffc0;  // Start of "frame"
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.js b/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.js
index 719343b..531ee4f 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/function_parallel.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @class FunctionSequence to invoke steps in sequence
  *
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.js b/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.js
index 6a1bf08..85ffe95 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/function_sequence.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @class FunctionSequence to invoke steps in sequence
  *
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.js b/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.js
index 05a541da..98ff5e6 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/id3_parser.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Protocol + host parts of extension URL.
  * @type {string}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.js b/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.js
index 8a3ba07..bb60457 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/image_parsers.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /* Base class for image metadata parsers that only need to look at a short
   fragment at the start of the file */
 function SimpleImageParser(parent, type, urlFilter, headerSize) {
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache.js
index 8de5921e..092d9ce 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_cache.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * MetadataCache is a map from Entry to an object containing properties.
  * Properties are divided by types, and all properties of one type are accessed
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_dispatcher.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_dispatcher.js
index 9f886680..07ee39c 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_dispatcher.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_dispatcher.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Protocol + host parts of extension URL.
  * @type {string}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.js
index 087eb42..adc0ea7 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {MetadataDispatcher} parent Parent object.
  * @param {string} type Parser type.
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/mpeg_parser.js b/ui/file_manager/file_manager/foreground/js/metadata/mpeg_parser.js
index 36ede26c..63cacedd 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/mpeg_parser.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/mpeg_parser.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {MetadataDispatcher} parent Parent object.
  * @constructor
diff --git a/ui/file_manager/file_manager/foreground/js/mouse_inactivity_watcher.js b/ui/file_manager/file_manager/foreground/js/mouse_inactivity_watcher.js
index 7f0da335..e19b82a 100644
--- a/ui/file_manager/file_manager/foreground/js/mouse_inactivity_watcher.js
+++ b/ui/file_manager/file_manager/foreground/js/mouse_inactivity_watcher.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * A controller class detects mouse inactivity and hides "tool" elements.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
index 62b031d9..5195f86 100644
--- a/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
+++ b/ui/file_manager/file_manager/foreground/js/navigation_list_model.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Base item of NavigationListModel. Should not be created directly.
  * @param {string} label Label.
diff --git a/ui/file_manager/file_manager/foreground/js/progress_center_item_group.js b/ui/file_manager/file_manager/foreground/js/progress_center_item_group.js
index d556a81..4958190 100644
--- a/ui/file_manager/file_manager/foreground/js/progress_center_item_group.js
+++ b/ui/file_manager/file_manager/foreground/js/progress_center_item_group.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Group of progress item in the progress center panels.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/search_controller.js b/ui/file_manager/file_manager/foreground/js/search_controller.js
index 23c9bd21..1340c6dd 100644
--- a/ui/file_manager/file_manager/foreground/js/search_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/search_controller.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Controller for searching.
  * @param {SearchBox} searchBox Search box UI element.
diff --git a/ui/file_manager/file_manager/foreground/js/share_client.js b/ui/file_manager/file_manager/foreground/js/share_client.js
index 36033cc..f332dd6b 100644
--- a/ui/file_manager/file_manager/foreground/js/share_client.js
+++ b/ui/file_manager/file_manager/foreground/js/share_client.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {WebView} webView Web View tag.
  * @param {string} url Share Url for an entry.
diff --git a/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js b/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
index 0102947..51d1115 100644
--- a/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
+++ b/ui/file_manager/file_manager/foreground/js/thumbnail_loader.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Loads a thumbnail using provided url. In CANVAS mode, loaded images
  * are attached as <canvas> element, while in IMAGE mode as <img>.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/combobutton.js b/ui/file_manager/file_manager/foreground/js/ui/combobutton.js
index 85f962dd..e6a84b4 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/combobutton.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/combobutton.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @fileoverview This implements a combobutton control.
  */
diff --git a/ui/file_manager/file_manager/foreground/js/ui/commandbutton.js b/ui/file_manager/file_manager/foreground/js/ui/commandbutton.js
index 88543c1..570dc57 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/commandbutton.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/commandbutton.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @fileoverview This implements a common button control, bound to command.
  */
@@ -60,7 +58,8 @@
                                       /** @type {EventListener} */ (this));
   }
 
-  if (typeof command == 'string' && command[0] == '#') {
+  if (typeof command == 'string') {
+    assert(command[0] == '#');
     command = /** @type {!cr.ui.Command} */
         (this.ownerDocument.getElementById(command.slice(1)));
     cr.ui.decorate(command, cr.ui.Command);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/conflict_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/conflict_dialog.js
index 3c80530..44af485d 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/conflict_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/conflict_dialog.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Dialog to confirm the operation for conflicted file operations.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/ui/default_action_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/default_action_dialog.js
index cba4e6a..47bab22 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/default_action_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/default_action_dialog.js
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
-
 /**
  * DefaultActionDialog contains a message, a list box, an ok button, and a
  * cancel button.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js
new file mode 100644
index 0000000..758ce92a
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/ui/dialog_footer.js
@@ -0,0 +1,163 @@
+// 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.
+
+/**
+ * Footer shown when the Files.app is opened as a file/folder selecting dialog.
+ * @param {DialogType} dialogType Dialog type.
+ * @param {!Element} container Container of the dialog footer.
+ * @param {!Element} filenameInput Filename input element.
+ * @constructor
+ */
+function DialogFooter(dialogType, container, filenameInput) {
+  /**
+   * Dialog type.
+   * @type {DialogType}
+   * @const
+   * @private
+   */
+  this.dialogType_ = dialogType;
+
+  /**
+   * OK button in the footer.
+   * @const
+   * @type {!HTMLButtonElement}
+   */
+  this.okButton = /** @type {!HTMLButtonElement} */
+      (container.querySelector('.ok'));
+
+  /**
+   * Cancel button in the footer.
+   * @const
+   * @type {!HTMLButtonElement}
+   */
+  this.cancelButton = /** @type {!HTMLButtonElement} */
+      (container.querySelector('.cancel'));
+
+  /**
+   * File type selector in the footer.
+   * @const
+   * @type {!HTMLSelectElement}
+   */
+  this.fileTypeSelector = /** @type {!HTMLSelectElement} */
+      (container.querySelector('.file-type'));
+
+  /**
+   * @const
+   * @type {!Element}
+   */
+  this.filenameInput = filenameInput;
+
+  // Initialize the element styles.
+  container.classList.add('button-panel');
+  this.okButton.textContent = DialogFooter.getOKButtonLabel_(dialogType);
+}
+
+DialogFooter.prototype = {
+  /**
+   * @return {number} Selected filter index.
+   */
+  get selectedFilterIndex() {
+    return ~~this.fileTypeSelector.value;
+  }
+};
+
+/**
+ * Finds the dialog footer element for the dialog type.
+ * @param {DialogType} dialogType Dialog type.
+ * @param {!Document} document Document.
+ * @return {!DialogFooter} Dialog footer created with the found element.
+ */
+DialogFooter.findDialogFooter = function(dialogType, document) {
+  // If the footer panel exists, the buttons are placed there. Otherwise,
+  // the buttons are on the preview panel.
+  var hasFooterPanel = dialogType == DialogType.SELECT_SAVEAS_FILE;
+  return new DialogFooter(
+      dialogType,
+      queryRequiredElement(
+          document, hasFooterPanel ? '.dialog-footer' : '.preview-panel'),
+      queryRequiredElement(document, '#filename-input-box input'));
+};
+
+/**
+ * Obtains the label of OK button for the dialog type.
+ * @param {DialogType} dialogType Dialog type.
+ * @return {string} OK button label.
+ * @private
+ */
+DialogFooter.getOKButtonLabel_ = function(dialogType) {
+  switch (dialogType) {
+    case DialogType.SELECT_UPLOAD_FOLDER:
+      return str('UPLOAD_LABEL');
+
+    case DialogType.SELECT_SAVEAS_FILE:
+      return str('SAVE_LABEL');
+
+    case DialogType.SELECT_FOLDER:
+    case DialogType.SELECT_OPEN_FILE:
+    case DialogType.SELECT_OPEN_MULTI_FILE:
+    case DialogType.FULL_PAGE:
+      return str('OPEN_LABEL');
+
+    default:
+      throw new Error('Unknown dialog type: ' + dialogType);
+  }
+};
+
+/**
+ * Fills the file type list or hides it.
+ * @param {!Array.<{extensions: Array.<string>, description: string}>} fileTypes
+ *     List of file type.
+ * @param {boolean} includeAllFiles Whether the filter includes the 'all files'
+ *     item or not.
+ */
+DialogFooter.prototype.initFileTypeFilter = function(
+    fileTypes, includeAllFiles) {
+  if (includeAllFiles) {
+    var option = document.createElement('option');
+    option.innerText = str('ALL_FILES_FILTER');
+    option.value = 0;
+    this.fileTypeSelector.appendChild(option);
+  }
+
+  for (var i = 0; i < fileTypes.length; i++) {
+    var fileType = fileTypes[i];
+    var option = document.createElement('option');
+    var description = fileType.description;
+    if (!description) {
+      // See if all the extensions in the group have the same description.
+      for (var j = 0; j !== fileType.extensions.length; j++) {
+        var currentDescription = FileType.typeToString(
+            FileType.getTypeForName('.' + fileType.extensions[j]));
+        if (!description)  {
+          // Set the first time.
+          description = currentDescription;
+        } else if (description != currentDescription) {
+          // No single description, fall through to the extension list.
+          description = null;
+          break;
+        }
+      }
+
+      if (!description) {
+        // Convert ['jpg', 'png'] to '*.jpg, *.png'.
+        description = fileType.extensions.map(function(s) {
+          return '*.' + s;
+        }).join(', ');
+      }
+    }
+    option.innerText = description;
+    option.value = i + 1;
+
+    if (fileType.selected)
+      option.selected = true;
+
+    this.fileTypeSelector.appendChild(option);
+  }
+
+  var options = this.fileTypeSelector.querySelectorAll('option');
+  if (options.length >= 2) {
+    // There is in fact no choice, show the selector.
+    this.fileTypeSelector.hidden = false;
+  }
+};
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
index 49b10352..b7c094d 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 ////////////////////////////////////////////////////////////////////////////////
 // DirectoryTreeBase
 
@@ -30,7 +28,7 @@
   while (this.entries_[index]) {
     var currentEntry = this.entries_[index];
     var currentElement = this.items[index];
-    var label = util.getEntryLabel(tree.volumeManager_, currentEntry);
+    var label = util.getEntryLabel(tree.volumeManager_, currentEntry) || '';
 
     if (index >= this.items.length) {
       var item = new DirectoryItem(label, currentEntry, this, tree);
@@ -532,7 +530,7 @@
 
     for (var i = 0; i < entries.length; i++) {
       var item = new DirectoryItem(
-          util.getEntryLabel(this.parentTree_.volumeManager_, entries[i]),
+          util.getEntryLabel(this.parentTree_.volumeManager_, entries[i]) || '',
           entries[i], this, this.parentTree_);
       this.add(item);
       item.updateSubDirectories(false);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
index ba145bf..9ab27c8 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/drag_selector.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Drag selector used on the file list or the grid table.
  * TODO(hirono): Support drag selection for grid view. crbug.com/224832
diff --git a/ui/file_manager/file_manager/foreground/js/ui/drive_banners.js b/ui/file_manager/file_manager/foreground/js/ui/drive_banners.js
index 4776e40..4f85191 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/drive_banners.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/drive_banners.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Responsible for showing following banners in the file list.
  *  - WelcomeBanner
diff --git a/ui/file_manager/file_manager/foreground/js/ui/error_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/error_dialog.js
index 96bb4e1..63515a6f 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/error_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/error_dialog.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {HTMLElement} parentNode Node to be parent for this dialog.
  * @constructor
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
index 005a54b..123d5ad 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_grid.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * FileGrid constructor.
  *
@@ -32,7 +30,7 @@
 
 /**
  * Decorates an HTML element to be a FileGrid.
- * @param {HTMLElement} self The grid to decorate.
+ * @param {!Element} self The grid to decorate.
  * @param {MetadataCache} metadataCache Metadata cache to find entries
  *                                      metadata.
  * @param {VolumeManagerWrapper} volumeManager Volume manager instance.
@@ -227,6 +225,7 @@
  */
 FileGrid.Item.decorate = function(li, entry, grid) {
   li.__proto__ = FileGrid.Item.prototype;
+  li = /** @type {!FileGrid.Item} */ (li);
   // TODO(mtomasz): Pass the metadata cache and the volume manager directly
   // instead of accessing private members of grid.
   FileGrid.decorateThumbnail(
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js
index 5d56a74d..bb7c83a 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_dialog_base.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * This class is an extended class, to manage the status of the dialogs.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
index b06b473e..48c1938a 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * The root of the file manager's view managing the DOM of Files.app.
  *
@@ -105,22 +103,10 @@
   this.toggleViewButton = null;
 
   /**
-   * File type selector in the footer.
-   * @type {HTMLSelectElement}
+   * Dialog footer.
+   * @type {DialogFooter}
    */
-  this.fileTypeSelector = null;
-
-  /**
-   * OK button in the footer.
-   * @type {HTMLButtonElement}
-   */
-  this.okButton = null;
-
-  /**
-   * Cancel button in the footer.
-   * @type {HTMLButtonElement}
-   */
-  this.cancelButton = null;
+  this.dialogFooter = null;
 
   Object.seal(this);
 
@@ -143,44 +129,10 @@
  */
 FileManagerUI.prototype.initDialogType_ = function() {
   // Obtain elements.
-  var hasFooterPanel =
-      this.dialogType_ == DialogType.SELECT_SAVEAS_FILE;
-
-  // If the footer panel exists, the buttons are placed there. Otherwise,
-  // the buttons are on the preview panel.
-  var parentPanelOfButtons = this.element_.ownerDocument.querySelector(
-      !hasFooterPanel ? '.preview-panel' : '.dialog-footer');
-  parentPanelOfButtons.classList.add('button-panel');
-  this.fileTypeSelector = /** @type {!HTMLSelectElement} */
-      (parentPanelOfButtons.querySelector('.file-type'));
-  this.okButton = /** @type {!HTMLButtonElement} */
-      (parentPanelOfButtons.querySelector('.ok'));
-  this.cancelButton = /** @type {!HTMLButtonElement} */
-      (parentPanelOfButtons.querySelector('.cancel'));
+  this.dialogFooter = DialogFooter.findDialogFooter(
+      this.dialogType_, /** @type {!Document} */(this.element_.ownerDocument));
 
   // Set attributes.
-  var okLabel = str('OPEN_LABEL');
-
-  switch (this.dialogType_) {
-    case DialogType.SELECT_UPLOAD_FOLDER:
-      okLabel = str('UPLOAD_LABEL');
-      break;
-
-    case DialogType.SELECT_SAVEAS_FILE:
-      okLabel = str('SAVE_LABEL');
-      break;
-
-    case DialogType.SELECT_FOLDER:
-    case DialogType.SELECT_OPEN_FILE:
-    case DialogType.SELECT_OPEN_MULTI_FILE:
-    case DialogType.FULL_PAGE:
-      break;
-
-    default:
-      throw new Error('Unknown dialog type: ' + this.dialogType_);
-  }
-
-  this.okButton.textContent = okLabel;
   this.element_.setAttribute('type', this.dialogType_);
 };
 
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.js b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
index 13491d52..3064618 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Namespace for utility functions.
  */
@@ -225,7 +223,7 @@
 
 /**
  * Decorates the element.
- * @param {HTMLElement} self Table to decorate.
+ * @param {!Element} self Table to decorate.
  * @param {MetadataCache} metadataCache To retrieve metadata.
  * @param {VolumeManagerWrapper} volumeManager To retrieve volume info.
  * @param {boolean} fullPage True if it's full page File Manager,
@@ -590,7 +588,8 @@
  * @private
  */
 FileTable.prototype.renderDate_ = function(entry, columnId, table) {
-  var div = this.ownerDocument.createElement('div');
+  var div = /** @type {!HTMLDivElement} */
+      (this.ownerDocument.createElement('div'));
   div.className = 'date';
 
   this.updateDate_(div, entry);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/location_line.js b/ui/file_manager/file_manager/foreground/js/ui/location_line.js
index 9d50a36..25fbdcf 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/location_line.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/location_line.js
@@ -2,14 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * TODO(hirono): Remove metadataCache and volumeManager dependencies from the UI
  * class.
  * @extends {cr.EventTarget}
- * @param {HTMLElement} breadcrumbs Container element for breadcrumbs.
- * @param {HTMLElement} volumeIcon Volume icon.
+ * @param {!Element} breadcrumbs Container element for breadcrumbs.
+ * @param {!Element} volumeIcon Volume icon.
  * @param {MetadataCache} metadataCache To retrieve metadata.
  * @param {VolumeManagerWrapper} volumeManager Volume manager.
  * @constructor
diff --git a/ui/file_manager/file_manager/foreground/js/ui/multi_profile_share_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/multi_profile_share_dialog.js
index 19362b0..a1cb232f 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/multi_profile_share_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/multi_profile_share_dialog.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Dialog to confirm the share between profiles.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js b/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js
index 8def6fb..47cd2c72 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/preview_panel.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * PreviewPanel UI class.
  * @param {Element} element DOM Element of preview panel.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js b/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js
index 2047e31f..94de1f41 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/progress_center_panel.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Item element of the progress center.
  * @param {Document} document Document which the new item belongs to.
@@ -49,14 +47,14 @@
  * @private
  */
 ProgressCenterItemElement.safelySetAnimation_ = function(callback) {
-  var requestId = requestAnimationFrame(function() {
+  var requestId = window.requestAnimationFrame(function() {
     // The transition start properties currently set are rendered at this frame.
     // And the transition end properties set by the callback is rendered at the
     // next frame.
-    requestId = requestAnimationFrame(callback);
+    requestId = window.requestAnimationFrame(callback);
   });
   return function() {
-    cancelAnimationFrame(requestId);
+    window.cancelAnimationFrame(requestId);
   };
 };
 
@@ -168,13 +166,13 @@
 /**
  * Progress center panel.
  *
- * @param {HTMLElement} element DOM Element of the process center panel.
+ * @param {!Element} element DOM Element of the process center panel.
  * @constructor
  */
 function ProgressCenterPanel(element) {
   /**
    * Root element of the progress center.
-   * @type {Element}
+   * @type {!Element}
    * @private
    */
   this.element_ = element;
@@ -310,7 +308,9 @@
   if (newItem) {
     if (!itemElement) {
       itemElement = new ProgressCenterItemElement(this.element_.ownerDocument);
-      this.openView_.insertBefore(itemElement, this.openView_.firstNode);
+      // Find quiet node and insert the item before the quiet node.
+      this.openView_.insertBefore(
+          itemElement, this.openView_.querySelector('.quiet'));
     }
     itemElement.update(newItem, targetGroup.isAnimated(item.id));
   } else {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/scrollbar.js b/ui/file_manager/file_manager/foreground/js/ui/scrollbar.js
index 755fbec..14304736 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/scrollbar.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/scrollbar.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Creates a new scroll bar element.
  * @extends {HTMLDivElement}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/search_box.js b/ui/file_manager/file_manager/foreground/js/ui/search_box.js
index a066bfa..32b0bb3 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/search_box.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/search_box.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Search box.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/ui/share_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/share_dialog.js
index cd5831d29..15feb5a 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/share_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/share_dialog.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {HTMLElement} parentNode Node to be parent for this dialog.
  * @constructor
diff --git a/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js
index fc42c1c8..fd4f5b8 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/suggest_apps_dialog.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * SuggestAppsDialog contains a list box to select an app to be opened the file
  * with. This dialog should be used as action picker for file operations.
diff --git a/ui/file_manager/file_manager/foreground/js/ui/tree.css.js b/ui/file_manager/file_manager/foreground/js/ui/tree.css.js
index 6b89acbd..08c6c5c 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/tree.css.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/tree.css.js
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Custom version of chrome://resources/css/tree.css.js, adding support for
  * inverted arrow icons.
  */
 (function() {
+  'use strict';
+
   /**
    * @type {number}
    * @const
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index fa6d025c..01977de 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -112,6 +112,7 @@
       <script src="foreground/js/thumbnail_loader.js"></script>
       <script src="foreground/js/ui/conflict_dialog.js"></script>
       <script src="foreground/js/ui/default_action_dialog.js"></script>
+      <script src="foreground/js/ui/dialog_footer.js"></script>
       <script src="foreground/js/ui/directory_tree.js"></script>
       <script src="foreground/js/ui/drag_selector.js"></script>
       <script src="foreground/js/ui/drive_banners.js"></script>
diff --git a/ui/file_manager/gallery/js/background.js b/ui/file_manager/gallery/js/background.js
index 0b51c04..591d466 100644
--- a/ui/file_manager/gallery/js/background.js
+++ b/ui/file_manager/gallery/js/background.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {Object.<string, string>} stringData String data.
  * @param {VolumeManager} volumeManager Volume manager.
diff --git a/ui/file_manager/gallery/js/error_banner.js b/ui/file_manager/gallery/js/error_banner.js
index ec63c98..3a23a4f7 100644
--- a/ui/file_manager/gallery/js/error_banner.js
+++ b/ui/file_manager/gallery/js/error_banner.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {Element} container Content container.
  * @constructor
diff --git a/ui/file_manager/gallery/js/gallery.js b/ui/file_manager/gallery/js/gallery.js
index 04e539f..3a20e4d07 100644
--- a/ui/file_manager/gallery/js/gallery.js
+++ b/ui/file_manager/gallery/js/gallery.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Called from the main frame when unloading.
  * @param {boolean=} opt_exiting True if the app is exiting.
diff --git a/ui/file_manager/gallery/js/gallery_item.js b/ui/file_manager/gallery/js/gallery_item.js
index f5c2b6f..994d5a24 100644
--- a/ui/file_manager/gallery/js/gallery_item.js
+++ b/ui/file_manager/gallery/js/gallery_item.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Object representing an image item (a photo).
  *
diff --git a/ui/file_manager/gallery/js/image_editor/commands.js b/ui/file_manager/gallery/js/image_editor/commands.js
index 8635505..fdde44f 100644
--- a/ui/file_manager/gallery/js/image_editor/commands.js
+++ b/ui/file_manager/gallery/js/image_editor/commands.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Command queue is the only way to modify images.
  * Supports undo/redo.
diff --git a/ui/file_manager/gallery/js/image_editor/exif_encoder.js b/ui/file_manager/gallery/js/image_editor/exif_encoder.js
index cc9c06b..80fdef8 100644
--- a/ui/file_manager/gallery/js/image_editor/exif_encoder.js
+++ b/ui/file_manager/gallery/js/image_editor/exif_encoder.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 // TODO:(kaznacheev) Share the EXIF constants with exif_parser.js
 var EXIF_MARK_SOS = 0xffda;  // Start of "stream" (the actual image data).
 var EXIF_MARK_SOI = 0xffd8;  // Start of image data.
diff --git a/ui/file_manager/gallery/js/image_editor/filter.js b/ui/file_manager/gallery/js/image_editor/filter.js
index d61b895c..87c0467 100644
--- a/ui/file_manager/gallery/js/image_editor/filter.js
+++ b/ui/file_manager/gallery/js/image_editor/filter.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * A namespace for image filter utilities.
  */
diff --git a/ui/file_manager/gallery/js/image_editor/image_adjust.js b/ui/file_manager/gallery/js/image_editor/image_adjust.js
index 1794b97b..0a7e306 100644
--- a/ui/file_manager/gallery/js/image_editor/image_adjust.js
+++ b/ui/file_manager/gallery/js/image_editor/image_adjust.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * The base class for simple filters that only modify the image content
  * but do not modify the image dimensions.
diff --git a/ui/file_manager/gallery/js/image_editor/image_buffer.js b/ui/file_manager/gallery/js/image_editor/image_buffer.js
index 0526bca..6d28f62 100644
--- a/ui/file_manager/gallery/js/image_editor/image_buffer.js
+++ b/ui/file_manager/gallery/js/image_editor/image_buffer.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * A stack of overlays that display itself and handle mouse events.
  * TODO(kaznacheev) Consider disbanding this class and moving
diff --git a/ui/file_manager/gallery/js/image_editor/image_editor.js b/ui/file_manager/gallery/js/image_editor/image_editor.js
index 37a3bb7..38361889 100644
--- a/ui/file_manager/gallery/js/image_editor/image_editor.js
+++ b/ui/file_manager/gallery/js/image_editor/image_editor.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * ImageEditor is the top level object that holds together and connects
  * everything needed for image editing.
diff --git a/ui/file_manager/gallery/js/image_editor/image_encoder.js b/ui/file_manager/gallery/js/image_editor/image_encoder.js
index c043c50..0cc5e654 100644
--- a/ui/file_manager/gallery/js/image_editor/image_encoder.js
+++ b/ui/file_manager/gallery/js/image_editor/image_encoder.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * A namespace class for image encoding functions. All methods are static.
  */
diff --git a/ui/file_manager/gallery/js/image_editor/image_transform.js b/ui/file_manager/gallery/js/image_editor/image_transform.js
index d73e409..da2ec750 100644
--- a/ui/file_manager/gallery/js/image_editor/image_transform.js
+++ b/ui/file_manager/gallery/js/image_editor/image_transform.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Crop mode.
  *
diff --git a/ui/file_manager/gallery/js/image_editor/image_util.js b/ui/file_manager/gallery/js/image_editor/image_util.js
index eaa1608..7191ee4 100644
--- a/ui/file_manager/gallery/js/image_editor/image_util.js
+++ b/ui/file_manager/gallery/js/image_editor/image_util.js
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
-
 // Namespace object for the utilities.
 function ImageUtil() {}
 
diff --git a/ui/file_manager/gallery/js/image_editor/image_view.js b/ui/file_manager/gallery/js/image_editor/image_view.js
index 2f1f6b6..0b84fe0 100644
--- a/ui/file_manager/gallery/js/image_editor/image_view.js
+++ b/ui/file_manager/gallery/js/image_editor/image_view.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * The overlay displaying the image.
  *
diff --git a/ui/file_manager/gallery/js/image_editor/viewport.js b/ui/file_manager/gallery/js/image_editor/viewport.js
index f9dea70..54ea128 100644
--- a/ui/file_manager/gallery/js/image_editor/viewport.js
+++ b/ui/file_manager/gallery/js/image_editor/viewport.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Viewport class controls the way the image is displayed (scale, offset etc).
  * @constructor
diff --git a/ui/file_manager/gallery/js/metadata_worker.js b/ui/file_manager/gallery/js/metadata_worker.js
index 56ea36c7e..26af2a1 100644
--- a/ui/file_manager/gallery/js/metadata_worker.js
+++ b/ui/file_manager/gallery/js/metadata_worker.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 // Load the worker script of Files.app.
 importScripts(
     'chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/' +
diff --git a/ui/file_manager/gallery/js/mosaic_mode.js b/ui/file_manager/gallery/js/mosaic_mode.js
index a19b50a..900c6f3 100644
--- a/ui/file_manager/gallery/js/mosaic_mode.js
+++ b/ui/file_manager/gallery/js/mosaic_mode.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {Element} container Content container.
  * @param {ErrorBanner} errorBanner Error banner.
diff --git a/ui/file_manager/gallery/js/ribbon.js b/ui/file_manager/gallery/js/ribbon.js
index 4fc44b6..acbc4f9 100644
--- a/ui/file_manager/gallery/js/ribbon.js
+++ b/ui/file_manager/gallery/js/ribbon.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Scrollable thumbnail ribbon at the bottom of the Gallery in the Slide mode.
  *
diff --git a/ui/file_manager/gallery/js/slide_mode.js b/ui/file_manager/gallery/js/slide_mode.js
index 1f0edc23..974fb97 100644
--- a/ui/file_manager/gallery/js/slide_mode.js
+++ b/ui/file_manager/gallery/js/slide_mode.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Slide mode displays a single image and has a set of controls to navigate
  * between the images and to edit an image.
diff --git a/ui/file_manager/image_loader/background.js b/ui/file_manager/image_loader/background.js
index 028a082..bdfac1cc 100644
--- a/ui/file_manager/image_loader/background.js
+++ b/ui/file_manager/image_loader/background.js
@@ -2,7 +2,5 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 // Load the extension.
 ImageLoader.getInstance();
diff --git a/ui/file_manager/image_loader/cache.js b/ui/file_manager/image_loader/cache.js
index 5bdb2beb..478bccd 100644
--- a/ui/file_manager/image_loader/cache.js
+++ b/ui/file_manager/image_loader/cache.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Persistent cache storing images in an indexed database on the hard disk.
  * @constructor
diff --git a/ui/file_manager/image_loader/image_loader.js b/ui/file_manager/image_loader/image_loader.js
index e45c084..abd183d 100644
--- a/ui/file_manager/image_loader/image_loader.js
+++ b/ui/file_manager/image_loader/image_loader.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Loads and resizes an image.
  * @constructor
diff --git a/ui/file_manager/image_loader/image_loader_client.js b/ui/file_manager/image_loader/image_loader_client.js
index 6dfef8e9..88bdaaf8 100644
--- a/ui/file_manager/image_loader/image_loader_client.js
+++ b/ui/file_manager/image_loader/image_loader_client.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Client used to connect to the remote ImageLoader extension. Client class runs
  * in the extension, where the client.js is included (eg. Files.app).
diff --git a/ui/file_manager/image_loader/request.js b/ui/file_manager/image_loader/request.js
index 1b1f0df..767b878f 100644
--- a/ui/file_manager/image_loader/request.js
+++ b/ui/file_manager/image_loader/request.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @typedef {{
  *   cache: (boolean|undefined),
diff --git a/ui/file_manager/image_loader/scheduler.js b/ui/file_manager/image_loader/scheduler.js
index 844a122..b0f841b 100644
--- a/ui/file_manager/image_loader/scheduler.js
+++ b/ui/file_manager/image_loader/scheduler.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Scheduler for requests. Fetches requests from a queue and processes them
  * synchronously, taking into account priorities. The highest priority is 0.
diff --git a/ui/file_manager/video_player/js/background.js b/ui/file_manager/video_player/js/background.js
index 3e97266..03e58012 100644
--- a/ui/file_manager/video_player/js/background.js
+++ b/ui/file_manager/video_player/js/background.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 // Stores the app windows OLNY for test purpose.
 // We SHOULD NOT use it as it is except for test, since the files which have
 // the same name will be overridden each other.
diff --git a/ui/file_manager/video_player/js/cast/cast_extension_discoverer.js b/ui/file_manager/video_player/js/cast/cast_extension_discoverer.js
index b2ff50d..fe23cb94 100644
--- a/ui/file_manager/video_player/js/cast/cast_extension_discoverer.js
+++ b/ui/file_manager/video_player/js/cast/cast_extension_discoverer.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Discover the ID of installed cast extension.
  * @constructor
diff --git a/ui/file_manager/video_player/js/cast/cast_video_element.js b/ui/file_manager/video_player/js/cast/cast_video_element.js
index 53abbd0..a2ffb39 100644
--- a/ui/file_manager/video_player/js/cast/cast_video_element.js
+++ b/ui/file_manager/video_player/js/cast/cast_video_element.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Interval for updating media info (in ms).
  * @type {number}
diff --git a/ui/file_manager/video_player/js/cast/caster.js b/ui/file_manager/video_player/js/cast/caster.js
index e7dfaff..cf718e2 100644
--- a/ui/file_manager/video_player/js/cast/caster.js
+++ b/ui/file_manager/video_player/js/cast/caster.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 // This hack prevents a bug on the cast extension.
 // TODO(yoshiki): Remove this once the cast extension supports Chrome apps.
 // Although localStorage in Chrome app is not supported, but it's used in the
diff --git a/ui/file_manager/video_player/js/cast/media_manager.js b/ui/file_manager/video_player/js/cast/media_manager.js
index dbf8b8d..28e729d 100644
--- a/ui/file_manager/video_player/js/cast/media_manager.js
+++ b/ui/file_manager/video_player/js/cast/media_manager.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * Media manager class.
  * This class supports the information for the media file.
diff --git a/ui/file_manager/video_player/js/error_util.js b/ui/file_manager/video_player/js/error_util.js
index d3270e8c..597a2393 100644
--- a/ui/file_manager/video_player/js/error_util.js
+++ b/ui/file_manager/video_player/js/error_util.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * This variable is checked in SelectFileDialogExtensionBrowserTest.
  * @type {number}
diff --git a/ui/file_manager/video_player/js/media_controls.js b/ui/file_manager/video_player/js/media_controls.js
index a565cc4..efe0231 100644
--- a/ui/file_manager/video_player/js/media_controls.js
+++ b/ui/file_manager/video_player/js/media_controls.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @fileoverview MediaControls class implements media playback controls
  * that exist outside of the audio/video HTML element.
diff --git a/ui/file_manager/video_player/js/video_player.js b/ui/file_manager/video_player/js/video_player.js
index cd5dc02..1c6e04a 100644
--- a/ui/file_manager/video_player/js/video_player.js
+++ b/ui/file_manager/video_player/js/video_player.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
-
 /**
  * @param {Element} playerContainer Main container.
  * @param {Element} videoContainer Container for the video element.
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index ed3cc568..080c7d57 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -290,7 +290,6 @@
     #  deps += [ "//base:base_java" ]
     #}
 
-    # TODO(jdduke): Revisit optimization after gauging benefit, crbug/419051.
     if (!is_debug) {
       configs -= [ "//build/config/compiler:optimize" ]
       configs += [ "//build/config/compiler:optimize_max" ]
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc
index 7ce7c472..7508e68 100644
--- a/ui/gfx/canvas.cc
+++ b/ui/gfx/canvas.cc
@@ -92,12 +92,12 @@
                            int* height,
                            int line_height,
                            int flags) {
-  float fractional_width = *width;
-  float factional_height = *height;
+  float fractional_width = static_cast<float>(*width);
+  float factional_height = static_cast<float>(*height);
   SizeStringFloat(text, font_list, &fractional_width,
                   &factional_height, line_height, flags);
-  *width = std::ceil(fractional_width);
-  *height = std::ceil(factional_height);
+  *width = ToCeiledInt(fractional_width);
+  *height = ToCeiledInt(factional_height);
 }
 
 // static
diff --git a/ui/gfx/canvas_paint_win.cc b/ui/gfx/canvas_paint_win.cc
index 7d20fbc..f377b8d 100644
--- a/ui/gfx/canvas_paint_win.cc
+++ b/ui/gfx/canvas_paint_win.cc
@@ -55,9 +55,7 @@
   const int width = ps_.rcPaint.right - ps_.rcPaint.left;
   const int height = ps_.rcPaint.bottom - ps_.rcPaint.top;
 
-  RecreateBackingCanvas(gfx::Size(width, height),
-      gfx::win::GetDeviceScaleFactor(),
-      opaque);
+  RecreateBackingCanvas(gfx::Size(width, height), gfx::GetDPIScale(), opaque);
   skia::PlatformCanvas* canvas = platform_canvas();
 
   canvas->clear(SkColorSetARGB(0, 0, 0, 0));
@@ -65,8 +63,8 @@
   // This will bring the canvas into the screen coordinate system for the
   // dirty rect
   canvas->translate(
-      -ps_.rcPaint.left / gfx::win::GetDeviceScaleFactor(),
-      -ps_.rcPaint.top / gfx::win::GetDeviceScaleFactor());
+      -ps_.rcPaint.left / gfx::GetDPIScale(),
+      -ps_.rcPaint.top / gfx::GetDPIScale());
 }
 
 }  // namespace gfx
diff --git a/ui/gfx/canvas_skia.cc b/ui/gfx/canvas_skia.cc
index 2f9bd605..dc35eeda 100644
--- a/ui/gfx/canvas_skia.cc
+++ b/ui/gfx/canvas_skia.cc
@@ -8,6 +8,7 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "ui/gfx/font_list.h"
+#include "ui/gfx/geometry/safe_integer_conversions.h"
 #include "ui/gfx/insets.h"
 #include "ui/gfx/range/range.h"
 #include "ui/gfx/rect.h"
@@ -100,7 +101,7 @@
 // Elides |text| and adjusts |range| appropriately. If eliding causes |range|
 // to no longer point to the same character in |text|, |range| is made invalid.
 void ElideTextAndAdjustRange(const FontList& font_list,
-                             int width,
+                             float width,
                              base::string16* text,
                              Range* range) {
   const base::char16 start_char =
@@ -174,10 +175,11 @@
     else if (!(flags & NO_ELLIPSIS))
       wrap_behavior = ELIDE_LONG_WORDS;
 
-    Rect rect(*width, INT_MAX);
     std::vector<base::string16> strings;
-    ElideRectangleText(adjusted_text, font_list, rect.width(), rect.height(),
+    ElideRectangleText(adjusted_text, font_list,
+                       *width, INT_MAX,
                        wrap_behavior, &strings);
+    Rect rect(ClampToInt(*width), INT_MAX);
     scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
     UpdateRenderText(rect, base::string16(), font_list, flags, 0,
                      render_text.get());
@@ -198,11 +200,12 @@
     // will inexplicably fail with result E_INVALIDARG. Guard against this.
     const size_t kMaxRenderTextLength = 5000;
     if (adjusted_text.length() >= kMaxRenderTextLength) {
-      *width = font_list.GetExpectedTextWidth(adjusted_text.length());
-      *height = font_list.GetHeight();
+      *width = static_cast<float>(
+          font_list.GetExpectedTextWidth(adjusted_text.length()));
+      *height = static_cast<float>(font_list.GetHeight());
     } else {
       scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
-      Rect rect(*width, *height);
+      Rect rect(ClampToInt(*width), ClampToInt(*height));
       StripAcceleratorChars(flags, &adjusted_text);
       UpdateRenderText(rect, adjusted_text, font_list, flags, 0,
                        render_text.get());
@@ -247,7 +250,8 @@
       wrap_behavior = ELIDE_LONG_WORDS;
 
     std::vector<base::string16> strings;
-    ElideRectangleText(adjusted_text, font_list, text_bounds.width(),
+    ElideRectangleText(adjusted_text, font_list,
+                       static_cast<float>(text_bounds.width()),
                        text_bounds.height(), wrap_behavior, &strings);
 
     for (size_t i = 0; i < strings.size(); i++) {
@@ -294,8 +298,9 @@
 #endif
 
     if (elide_text) {
-      ElideTextAndAdjustRange(font_list, text_bounds.width(), &adjusted_text,
-                              &range);
+      ElideTextAndAdjustRange(font_list,
+                              static_cast<float>(text_bounds.width()),
+                              &adjusted_text, &range);
     }
 
     UpdateRenderText(rect, adjusted_text, font_list, flags, color,
diff --git a/ui/gfx/color_analysis.h b/ui/gfx/color_analysis.h
index b7ad314d..e6d1d96 100644
--- a/ui/gfx/color_analysis.h
+++ b/ui/gfx/color_analysis.h
@@ -10,8 +10,8 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/ref_counted_memory.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/geometry/matrix3_f.h"
 #include "ui/gfx/gfx_export.h"
-#include "ui/gfx/matrix3_f.h"
 
 class SkBitmap;
 
diff --git a/ui/gfx/geometry/BUILD.gn b/ui/gfx/geometry/BUILD.gn
index 08633303..eee571fc 100644
--- a/ui/gfx/geometry/BUILD.gn
+++ b/ui/gfx/geometry/BUILD.gn
@@ -61,7 +61,6 @@
     "//ui/gfx:gfx_export",
   ]
 
-  # TODO(jdduke): Revisit optimization after gauging benefit, crbug/419051.
   if (is_android && !is_debug) {
     configs -= [ "//build/config/compiler:optimize" ]
     configs += [ "//build/config/compiler:optimize_max" ]
diff --git a/ui/gfx/gfx.gyp b/ui/gfx/gfx.gyp
index c0ff2d3..080ce32b3 100644
--- a/ui/gfx/gfx.gyp
+++ b/ui/gfx/gfx.gyp
@@ -65,7 +65,6 @@
         'geometry/vector3d_f.cc',
         'geometry/vector3d_f.h',
       ],
-      # TODO(jdduke): Revisit optimization after gauging benefit, crbug/419051.
       'includes': [
         '../../build/android/increase_size_for_speed.gypi',
       ],
diff --git a/ui/gfx/interpolated_transform.h b/ui/gfx/interpolated_transform.h
index dea52b459..8194080 100644
--- a/ui/gfx/interpolated_transform.h
+++ b/ui/gfx/interpolated_transform.h
@@ -7,11 +7,11 @@
 
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/point.h"
 #include "ui/gfx/point3_f.h"
 #include "ui/gfx/transform.h"
 #include "ui/gfx/transform_util.h"
-#include "ui/gfx/vector3d_f.h"
 
 namespace ui {
 
diff --git a/ui/gfx/matrix3_f.h b/ui/gfx/matrix3_f.h
deleted file mode 100644
index 936c312..0000000
--- a/ui/gfx/matrix3_f.h
+++ /dev/null
@@ -1,7 +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.
-
-// TODO(beng): remove once callsites are patched.
-#include "ui/gfx/geometry/matrix3_f.h"
-
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index d7a6a55..1ca874a0 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -18,6 +18,7 @@
 #include "third_party/skia/include/core/SkTypeface.h"
 #include "third_party/skia/include/effects/SkGradientShader.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/safe_integer_conversions.h"
 #include "ui/gfx/insets.h"
 #include "ui/gfx/render_text_harfbuzz.h"
 #include "ui/gfx/scoped_canvas.h"
@@ -269,8 +270,10 @@
 }
 
 void SkiaTextRenderer::DrawUnderline(int x, int y, int width) {
-  SkRect r = SkRect::MakeLTRB(x, y + underline_position_, x + width,
-                              y + underline_position_ + underline_thickness_);
+  SkScalar x_scalar = SkIntToScalar(x);
+  SkRect r = SkRect::MakeLTRB(
+      x_scalar, y + underline_position_, x_scalar + width,
+      y + underline_position_ + underline_thickness_);
   if (underline_thickness_ == kUnderlineMetricsNotSet) {
     const SkScalar text_size = paint_.getTextSize();
     r.fTop = SkScalarMulAdd(text_size, kUnderlineOffset, y);
@@ -283,7 +286,9 @@
   const SkScalar text_size = paint_.getTextSize();
   const SkScalar height = SkScalarMul(text_size, kLineThickness);
   const SkScalar offset = SkScalarMulAdd(text_size, kStrikeThroughOffset, y);
-  const SkRect r = SkRect::MakeLTRB(x, offset, x + width, offset + height);
+  SkScalar x_scalar = SkIntToScalar(x);
+  const SkRect r =
+      SkRect::MakeLTRB(x_scalar, offset, x_scalar + width, offset + height);
   canvas_skia_->drawRect(r, paint_);
 }
 
@@ -314,7 +319,7 @@
   const int clip_height = height + 2 * thickness;
 
   paint_.setAntiAlias(true);
-  paint_.setStrokeWidth(thickness);
+  paint_.setStrokeWidth(SkIntToScalar(thickness));
 
   const bool clipped = pieces_.size() > 1;
   SkCanvas* sk_canvas = canvas_->sk_canvas();
@@ -708,8 +713,7 @@
 }
 
 SizeF RenderText::GetStringSizeF() {
-  const Size size = GetStringSize();
-  return SizeF(size.width(), size.height());
+  return GetStringSize();
 }
 
 float RenderText::GetContentWidth() {
@@ -845,7 +849,8 @@
 }
 
 void RenderText::SetDisplayOffset(int horizontal_offset) {
-  const int extra_content = GetContentWidth() - display_rect_.width();
+  const int extra_content =
+      ToFlooredInt(GetContentWidth()) - display_rect_.width();
   const int cursor_width = cursor_enabled_ ? 1 : 0;
 
   int min_offset = 0;
@@ -1198,8 +1203,9 @@
       static_cast<int>(GetContentWidth()) > display_rect_.width()) {
     // This doesn't trim styles so ellipsis may get rendered as a different
     // style than the preceding text. See crbug.com/327850.
-    layout_text_.assign(
-        Elide(layout_text_, display_rect_.width(), elide_behavior_));
+    layout_text_.assign(Elide(layout_text_,
+                              static_cast<float>(display_rect_.width()),
+                              elide_behavior_));
   }
 
   // Replace the newline character with a newline symbol in single line mode.
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 442199a..3ee5332 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -71,12 +71,12 @@
                              hb_codepoint_t codepoint,
                              hb_position_t* width,
                              hb_glyph_extents_t* extents) {
-  DCHECK_LE(codepoint, 0xFFFFU);
+  DCHECK_LE(codepoint, std::numeric_limits<uint16>::max());
   paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
 
   SkScalar sk_width;
   SkRect sk_bounds;
-  uint16_t glyph = codepoint;
+  uint16_t glyph = static_cast<uint16_t>(codepoint);
 
   paint->getTextWidths(&glyph, sizeof(glyph), &sk_width, &sk_bounds);
   if (width)
@@ -273,7 +273,7 @@
 
 // Creates a HarfBuzz font from the given Skia face and text size.
 hb_font_t* CreateHarfBuzzFont(SkTypeface* skia_face,
-                              int text_size,
+                              SkScalar text_size,
                               const FontRenderParams& params,
                               bool background_is_transparent) {
   typedef std::pair<HarfBuzzFace, GlyphCache> FaceCache;
@@ -882,7 +882,7 @@
       lines[0].segments.push_back(segment);
 
       paint.setTypeface(run.skia_face.get());
-      paint.setTextSize(run.font_size);
+      paint.setTextSize(SkIntToScalar(run.font_size));
       SkPaint::FontMetrics metrics;
       paint.getFontMetrics(&metrics);
 
@@ -909,7 +909,7 @@
   for (size_t i = 0; i < runs_.size(); ++i) {
     const internal::TextRunHarfBuzz& run = *runs_[visual_to_logical_[i]];
     renderer.SetTypeface(run.skia_face.get());
-    renderer.SetTextSize(run.font_size);
+    renderer.SetTextSize(SkIntToScalar(run.font_size));
     renderer.SetFontRenderParams(run.render_params,
                                  background_is_transparent());
 
@@ -937,11 +937,12 @@
       renderer.DrawPosText(&positions[colored_glyphs.start()],
                            &run.glyphs[colored_glyphs.start()],
                            colored_glyphs.length());
-      int width = (colored_glyphs.end() == run.glyph_count ? run.width :
-              run.positions[colored_glyphs.end()].x()) -
-          run.positions[colored_glyphs.start()].x();
-      renderer.DrawDecorations(origin.x(), origin.y(), width, run.underline,
-                               run.strike, run.diagonal_strike);
+      int start_x = SkScalarRoundToInt(positions[colored_glyphs.start()].x());
+      int end_x = SkScalarRoundToInt((colored_glyphs.end() == run.glyph_count) ?
+          (run.width + SkIntToScalar(origin.x())) :
+          positions[colored_glyphs.end()].x());
+      renderer.DrawDecorations(start_x, origin.y(), end_x - start_x,
+                               run.underline, run.strike, run.diagonal_strike);
     }
 
     current_x += run.width;
@@ -1069,84 +1070,86 @@
   ubidi_reorderLogical(&levels[0], num_runs, &logical_to_visual_[0]);
 }
 
+bool RenderTextHarfBuzz::CompareFamily(
+    internal::TextRunHarfBuzz* run,
+    const std::string& family,
+    const gfx::FontRenderParams& render_params,
+    std::string* best_family,
+    gfx::FontRenderParams* best_render_params,
+    size_t* best_missing_glyphs) {
+  if (!ShapeRunWithFont(run, family, render_params))
+    return false;
+
+  const size_t missing_glyphs = run->CountMissingGlyphs();
+  if (missing_glyphs < *best_missing_glyphs) {
+    *best_family = family;
+    *best_render_params = render_params;
+    *best_missing_glyphs = missing_glyphs;
+  }
+  return missing_glyphs == 0;
+}
+
 void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) {
   const Font& primary_font = font_list().GetPrimaryFont();
-  const std::string primary_font_name = primary_font.GetFontName();
   run->font_size = primary_font.GetFontSize();
 
-  size_t best_font_missing = std::numeric_limits<size_t>::max();
-  std::string best_font;
-  std::string current_font;
+  std::string best_family;
+  FontRenderParams best_render_params;
+  size_t best_missing_glyphs = std::numeric_limits<size_t>::max();
 
-  // Try shaping with |primary_font|.
-  if (ShapeRunWithFont(run, primary_font_name)) {
-    current_font = primary_font_name;
-    size_t current_missing = run->CountMissingGlyphs();
-    if (current_missing == 0)
-      return;
-    if (current_missing < best_font_missing) {
-      best_font_missing = current_missing;
-      best_font = current_font;
-    }
-  }
+  if (CompareFamily(run, primary_font.GetFontName(),
+                    primary_font.GetFontRenderParams(),
+                    &best_family, &best_render_params, &best_missing_glyphs))
+    return;
 
 #if defined(OS_WIN)
   Font uniscribe_font;
   const base::char16* run_text = &(GetLayoutText()[run->range.start()]);
   if (GetUniscribeFallbackFont(primary_font, run_text, run->range.length(),
                                &uniscribe_font) &&
-      ShapeRunWithFont(run, uniscribe_font.GetFontName())) {
-    current_font = uniscribe_font.GetFontName();
-    size_t current_missing = run->CountMissingGlyphs();
-    if (current_missing == 0)
-      return;
-    if (current_missing < best_font_missing) {
-      best_font_missing = current_missing;
-      best_font = current_font;
-    }
-  }
+      CompareFamily(run, uniscribe_font.GetFontName(),
+                    uniscribe_font.GetFontRenderParams(),
+                    &best_family, &best_render_params, &best_missing_glyphs))
+    return;
 #endif
 
-  // Try shaping with the fonts in the fallback list except the first, which is
-  // |primary_font|.
-  std::vector<std::string> fonts = GetFallbackFontFamilies(primary_font_name);
-  for (size_t i = 1; i < fonts.size(); ++i) {
-    if (!ShapeRunWithFont(run, fonts[i]))
-      continue;
-    current_font = fonts[i];
-    size_t current_missing = run->CountMissingGlyphs();
-    if (current_missing == 0)
+  // Skip the first fallback font, which is |primary_font|.
+  std::vector<std::string> fallback_families =
+      GetFallbackFontFamilies(primary_font.GetFontName());
+  for (size_t i = 1; i < fallback_families.size(); ++i) {
+    FontRenderParamsQuery query(false);
+    query.families.push_back(fallback_families[i]);
+    query.pixel_size = run->font_size;
+    query.style = run->font_style;
+    FontRenderParams fallback_render_params = GetFontRenderParams(query, NULL);
+    if (CompareFamily(run, fallback_families[i], fallback_render_params,
+                      &best_family, &best_render_params, &best_missing_glyphs))
       return;
-    if (current_missing < best_font_missing) {
-      best_font_missing = current_missing;
-      best_font = current_font;
-    }
   }
 
-  if (!best_font.empty() &&
-      (best_font == current_font || ShapeRunWithFont(run, best_font))) {
+  if (!best_family.empty() &&
+      (best_family == run->family ||
+       ShapeRunWithFont(run, best_family, best_render_params)))
     return;
-  }
 
   run->glyph_count = 0;
   run->width = 0.0f;
 }
 
 bool RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run,
-                                          const std::string& font_family) {
+                                          const std::string& font_family,
+                                          const FontRenderParams& params) {
   const base::string16& text = GetLayoutText();
   skia::RefPtr<SkTypeface> skia_face =
       internal::CreateSkiaTypeface(font_family, run->font_style);
   if (skia_face == NULL)
     return false;
   run->skia_face = skia_face;
-  FontRenderParamsQuery query(false);
-  query.families.push_back(font_family);
-  query.pixel_size = run->font_size;
-  query.style = run->font_style;
-  run->render_params = GetFontRenderParams(query, NULL);
-  hb_font_t* harfbuzz_font = CreateHarfBuzzFont(run->skia_face.get(),
-      run->font_size, run->render_params, background_is_transparent());
+  run->family = font_family;
+  run->render_params = params;
+  hb_font_t* harfbuzz_font = CreateHarfBuzzFont(
+      run->skia_face.get(), SkIntToScalar(run->font_size), run->render_params,
+      background_is_transparent());
 
   // Create a HarfBuzz buffer and add the string to be shaped. The HarfBuzz
   // buffer holds our text, run information to be used by the shaping engine,
@@ -1174,10 +1177,11 @@
   run->positions.reset(new SkPoint[run->glyph_count]);
   run->width = 0.0f;
   for (size_t i = 0; i < run->glyph_count; ++i) {
-    run->glyphs[i] = infos[i].codepoint;
+    DCHECK_LE(infos[i].codepoint, std::numeric_limits<uint16>::max());
+    run->glyphs[i] = static_cast<uint16>(infos[i].codepoint);
     run->glyph_to_char[i] = infos[i].cluster;
-    const int x_offset = SkFixedToScalar(hb_positions[i].x_offset);
-    const int y_offset = SkFixedToScalar(hb_positions[i].y_offset);
+    const SkScalar x_offset = SkFixedToScalar(hb_positions[i].x_offset);
+    const SkScalar y_offset = SkFixedToScalar(hb_positions[i].y_offset);
     run->positions[i].set(run->width + x_offset, -y_offset);
     run->width += SkFixedToScalar(hb_positions[i].x_advance);
 #if defined(OS_LINUX)
diff --git a/ui/gfx/render_text_harfbuzz.h b/ui/gfx/render_text_harfbuzz.h
index c3508ff2..68da3e83 100644
--- a/ui/gfx/render_text_harfbuzz.h
+++ b/ui/gfx/render_text_harfbuzz.h
@@ -60,6 +60,7 @@
   std::vector<uint32> glyph_to_char;
   size_t glyph_count;
 
+  std::string family;
   skia::RefPtr<SkTypeface> skia_face;
   FontRenderParams render_params;
   int font_size;
@@ -127,10 +128,23 @@
   // Break the text into logical runs and populate the visual <-> logical maps.
   void ItemizeText();
 
+  // Helper method for ShapeRun() that calls ShapeRunWithFont() with |run|,
+  // |family|, and |render_params|, returning true if the family provides all
+  // needed glyphs and false otherwise. Additionally updates |best_family|,
+  // |best_render_params|, and |best_missing_glyphs| if |family| has fewer than
+  // |best_missing_glyphs| missing glyphs.
+  bool CompareFamily(internal::TextRunHarfBuzz* run,
+                     const std::string& family,
+                     const gfx::FontRenderParams& render_params,
+                     std::string* best_family,
+                     gfx::FontRenderParams* best_render_params,
+                     size_t* best_missing_glyphs);
+
   // Shape the glyphs needed for the text |run|.
   void ShapeRun(internal::TextRunHarfBuzz* run);
   bool ShapeRunWithFont(internal::TextRunHarfBuzz* run,
-                        const std::string& font);
+                        const std::string& font_family,
+                        const FontRenderParams& params);
 
   // Text runs in logical order.
   ScopedVector<internal::TextRunHarfBuzz> runs_;
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index 10a0a90b..1c6f902 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -15,6 +15,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/break_list.h"
 #include "ui/gfx/canvas.h"
+#include "ui/gfx/font.h"
 #include "ui/gfx/render_text_harfbuzz.h"
 
 #if defined(OS_WIN)
@@ -2287,7 +2288,8 @@
   render_text.EnsureLayout();
   ASSERT_EQ(1U, render_text.runs_.size());
   internal::TextRunHarfBuzz* run = render_text.runs_[0];
-  render_text.ShapeRunWithFont(run, "TheFontThatDoesntExist");
+  render_text.ShapeRunWithFont(
+      run, "TheFontThatDoesntExist", FontRenderParams());
 }
 
 // Ensure an empty run returns sane values to queries.
diff --git a/ui/gfx/render_text_win.cc b/ui/gfx/render_text_win.cc
index 4a9848ea..f68224b 100644
--- a/ui/gfx/render_text_win.cc
+++ b/ui/gfx/render_text_win.cc
@@ -802,7 +802,7 @@
       pos.back().set(SkIntToScalar(text_offset.x() + segment_x),
                      SkIntToScalar(text_offset.y()));
 
-      renderer.SetTextSize(run->font.GetFontSize());
+      renderer.SetTextSize(SkIntToScalar(run->font.GetFontSize()));
       renderer.SetFontFamilyWithStyle(run->font.GetFontName(), run->font_style);
 
       for (BreakList<SkColor>::const_iterator it =
@@ -828,10 +828,10 @@
         renderer.SetForegroundColor(it->second);
         renderer.DrawPosText(&start_pos, &run->glyphs[colored_glyphs.start()],
                              colored_glyphs.length());
-        renderer.DrawDecorations(start_pos.x(), text_offset.y(),
-                                 SkScalarCeilToInt(end_pos.x() - start_pos.x()),
-                                 run->underline, run->strike,
-                                 run->diagonal_strike);
+        int start_x = SkScalarRoundToInt(start_pos.x());
+        renderer.DrawDecorations(
+            start_x, text_offset.y(), SkScalarRoundToInt(end_pos.x()) - start_x,
+            run->underline, run->strike, run->diagonal_strike);
       }
 
       preceding_segment_widths += segment_width;
@@ -1122,8 +1122,8 @@
   for (int i = 0; i < run->glyph_count; ++i)
     run->glyphs[i] = IsWhitespace(run_text[i]) ? space_glyph : missing_glyph;
   for (size_t i = 0; i < run_length; ++i) {
-    run->logical_clusters[i] = run->script_analysis.fRTL ?
-        run_length - 1 - i : i;
+    run->logical_clusters[i] =
+        static_cast<WORD>(run->script_analysis.fRTL ? run_length - 1 - i : i);
   }
 
   // TODO(msw): Don't use SCRIPT_UNDEFINED. Apparently Uniscribe can
diff --git a/ui/gfx/screen.h b/ui/gfx/screen.h
index e6a38a6..a05866ab 100644
--- a/ui/gfx/screen.h
+++ b/ui/gfx/screen.h
@@ -50,9 +50,6 @@
   Screen();
   virtual ~Screen();
 
-  // Returns true if DIP is enabled.
-  virtual bool IsDIPEnabled() = 0;
-
   // Returns the current absolute position of the mouse pointer.
   virtual gfx::Point GetCursorScreenPoint() = 0;
 
diff --git a/ui/gfx/screen_android.cc b/ui/gfx/screen_android.cc
index 4f043539..d48b0b1 100644
--- a/ui/gfx/screen_android.cc
+++ b/ui/gfx/screen_android.cc
@@ -15,8 +15,6 @@
  public:
   ScreenAndroid() {}
 
-  virtual bool IsDIPEnabled() override { return true; }
-
   virtual gfx::Point GetCursorScreenPoint() override { return gfx::Point(); }
 
   virtual gfx::NativeWindow GetWindowUnderCursor() override {
diff --git a/ui/gfx/screen_ios.mm b/ui/gfx/screen_ios.mm
index ac5ccc48..e05568e 100644
--- a/ui/gfx/screen_ios.mm
+++ b/ui/gfx/screen_ios.mm
@@ -12,10 +12,6 @@
 namespace {
 
 class ScreenIos : public gfx::Screen {
-  virtual bool IsDIPEnabled() override {
-    return true;
-  }
-
   virtual gfx::Point GetCursorScreenPoint() override {
     NOTIMPLEMENTED();
     return gfx::Point(0, 0);
diff --git a/ui/gfx/screen_mac.mm b/ui/gfx/screen_mac.mm
index 45f3f45..2bb90e6 100644
--- a/ui/gfx/screen_mac.mm
+++ b/ui/gfx/screen_mac.mm
@@ -91,8 +91,6 @@
         ScreenMac::DisplayReconfigurationCallBack, this);
   }
 
-  bool IsDIPEnabled() override { return true; }
-
   gfx::Point GetCursorScreenPoint() override {
     NSPoint mouseLocation  = [NSEvent mouseLocation];
     // Flip coordinates to gfx (0,0 in top-left corner) using primary screen.
diff --git a/ui/gfx/screen_win.cc b/ui/gfx/screen_win.cc
index a115a104..d5ad22b 100644
--- a/ui/gfx/screen_win.cc
+++ b/ui/gfx/screen_win.cc
@@ -29,7 +29,7 @@
   gfx::Rect bounds = gfx::Rect(monitor_info.rcMonitor);
   gfx::Display display(id, bounds);
   display.set_work_area(gfx::Rect(monitor_info.rcWork));
-  display.SetScaleAndBounds(gfx::win::GetDeviceScaleFactor(), bounds);
+  display.SetScaleAndBounds(gfx::GetDPIScale(), bounds);
 
   DEVMODE mode;
   memset(&mode, 0, sizeof(DEVMODE));
@@ -93,10 +93,6 @@
   SingletonHwnd::GetInstance()->RemoveObserver(this);
 }
 
-bool ScreenWin::IsDIPEnabled() {
-  return IsInHighDPIMode();
-}
-
 gfx::Point ScreenWin::GetCursorScreenPoint() {
   POINT pt;
   GetCursorPos(&pt);
@@ -164,7 +160,7 @@
   gfx::Display display = GetDisplay(mi);
   // TODO(kevers|girard): Test if these checks can be reintroduced for high-DIP
   // once more of the app is DIP-aware.
-  if (!(IsInHighDPIMode() || IsHighDPIEnabled())) {
+  if (GetDPIScale() == 1.0) {
     DCHECK_EQ(GetSystemMetrics(SM_CXSCREEN), display.size().width());
     DCHECK_EQ(GetSystemMetrics(SM_CYSCREEN), display.size().height());
   }
diff --git a/ui/gfx/screen_win.h b/ui/gfx/screen_win.h
index 7d7d2b00..1c82f22 100644
--- a/ui/gfx/screen_win.h
+++ b/ui/gfx/screen_win.h
@@ -21,7 +21,6 @@
 
  protected:
   // Overridden from gfx::Screen:
-  virtual bool IsDIPEnabled() override;
   virtual gfx::Point GetCursorScreenPoint() override;
   virtual gfx::NativeWindow GetWindowUnderCursor() override;
   virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point)
diff --git a/ui/gfx/text_elider.cc b/ui/gfx/text_elider.cc
index 279e5cb..1bf85d49 100644
--- a/ui/gfx/text_elider.cc
+++ b/ui/gfx/text_elider.cc
@@ -24,6 +24,7 @@
 #include "third_party/icu/source/common/unicode/rbbi.h"
 #include "third_party/icu/source/common/unicode/uloc.h"
 #include "ui/gfx/font_list.h"
+#include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/render_text.h"
 #include "ui/gfx/text_utils.h"
 
@@ -211,7 +212,8 @@
   render_text->set_truncate_length(5000);
   render_text->SetFontList(font_list);
   available_pixel_width = std::ceil(available_pixel_width);
-  render_text->SetDisplayRect(gfx::Rect(gfx::Size(available_pixel_width, 1)));
+  render_text->SetDisplayRect(
+      gfx::ToEnclosingRect(gfx::RectF(gfx::SizeF(available_pixel_width, 1))));
   render_text->SetElideBehavior(behavior);
   render_text->SetText(text);
   return render_text->layout_text();
diff --git a/ui/gfx/transform.cc b/ui/gfx/transform.cc
index 7fe5174e..6a6fe794 100644
--- a/ui/gfx/transform.cc
+++ b/ui/gfx/transform.cc
@@ -12,13 +12,13 @@
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/point.h"
 #include "ui/gfx/point3_f.h"
 #include "ui/gfx/rect.h"
 #include "ui/gfx/safe_integer_conversions.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/gfx/transform_util.h"
-#include "ui/gfx/vector3d_f.h"
 
 namespace gfx {
 
diff --git a/ui/gfx/transform_unittest.cc b/ui/gfx/transform_unittest.cc
index ef801ac..94b3b61 100644
--- a/ui/gfx/transform_unittest.cc
+++ b/ui/gfx/transform_unittest.cc
@@ -15,11 +15,11 @@
 #include "base/logging.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/box_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/point.h"
 #include "ui/gfx/point3_f.h"
 #include "ui/gfx/quad_f.h"
 #include "ui/gfx/transform_util.h"
-#include "ui/gfx/vector3d_f.h"
 
 namespace gfx {
 
diff --git a/ui/gfx/vector2d_conversions.h b/ui/gfx/vector2d_conversions.h
deleted file mode 100644
index 5417e1c3..0000000
--- a/ui/gfx/vector2d_conversions.h
+++ /dev/null
@@ -1,7 +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.
-
-// TODO(beng): remove once callsites are patched.
-#include "ui/gfx/geometry/vector2d_conversions.h"
-
diff --git a/ui/gfx/vector3d_f.h b/ui/gfx/vector3d_f.h
deleted file mode 100644
index ad0445f..0000000
--- a/ui/gfx/vector3d_f.h
+++ /dev/null
@@ -1,7 +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.
-
-// TODO(beng): remove once callsites are patched.
-#include "ui/gfx/geometry/vector3d_f.h"
-
diff --git a/ui/gfx/win/dpi.cc b/ui/gfx/win/dpi.cc
index 2777f7cb..6ea9ba8 100644
--- a/ui/gfx/win/dpi.cc
+++ b/ui/gfx/win/dpi.cc
@@ -6,8 +6,6 @@
 
 #include <windows.h>
 #include "base/win/scoped_hdc.h"
-#include "base/win/windows_version.h"
-#include "base/win/registry.h"
 #include "ui/gfx/display.h"
 #include "ui/gfx/point_conversions.h"
 #include "ui/gfx/rect_conversions.h"
@@ -20,90 +18,17 @@
 
 bool force_highdpi_for_testing = false;
 
-BOOL IsProcessDPIAwareWrapper() {
-  typedef BOOL(WINAPI *IsProcessDPIAwarePtr)(VOID);
-  IsProcessDPIAwarePtr is_process_dpi_aware_func =
-      reinterpret_cast<IsProcessDPIAwarePtr>(
-          GetProcAddress(GetModuleHandleA("user32.dll"), "IsProcessDPIAware"));
-  if (is_process_dpi_aware_func)
-    return is_process_dpi_aware_func();
-  return FALSE;
-}
-
 float g_device_scale_factor = 0.0f;
 
 float GetUnforcedDeviceScaleFactor() {
   // If the global device scale factor is initialized use it. This is to ensure
-  // we use the same scale factor across all callsites. We don't use the
-  // GetDeviceScaleFactor function here because it fires a DCHECK if the
-  // g_device_scale_factor global is 0.
+  // we use the same scale factor across all callsites.
   if (g_device_scale_factor)
     return g_device_scale_factor;
   return static_cast<float>(gfx::GetDPI().width()) /
       static_cast<float>(kDefaultDPIX);
 }
 
-// Duplicated from Win8.1 SDK ShellScalingApi.h
-typedef enum PROCESS_DPI_AWARENESS {
-    PROCESS_DPI_UNAWARE = 0,
-    PROCESS_SYSTEM_DPI_AWARE = 1,
-    PROCESS_PER_MONITOR_DPI_AWARE = 2
-} PROCESS_DPI_AWARENESS;
-
-typedef enum MONITOR_DPI_TYPE {
-    MDT_EFFECTIVE_DPI = 0,
-    MDT_ANGULAR_DPI = 1,
-    MDT_RAW_DPI = 2,
-    MDT_DEFAULT = MDT_EFFECTIVE_DPI
-} MONITOR_DPI_TYPE;
-
-// Win8.1 supports monitor-specific DPI scaling.
-bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
-  typedef BOOL(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
-  SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
-      reinterpret_cast<SetProcessDpiAwarenessPtr>(
-          GetProcAddress(GetModuleHandleA("user32.dll"),
-                          "SetProcessDpiAwarenessInternal"));
-  if (set_process_dpi_awareness_func) {
-    HRESULT hr = set_process_dpi_awareness_func(value);
-    if (SUCCEEDED(hr)) {
-      VLOG(1) << "SetProcessDpiAwareness succeeded.";
-      return true;
-    } else if (hr == E_ACCESSDENIED) {
-      LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
-          "Function called twice, or manifest was used.";
-    }
-  }
-  return false;
-}
-
-// This function works for Windows Vista through Win8. Win8.1 must use
-// SetProcessDpiAwareness[Wrapper]
-BOOL SetProcessDPIAwareWrapper() {
-  typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
-  SetProcessDPIAwarePtr set_process_dpi_aware_func =
-      reinterpret_cast<SetProcessDPIAwarePtr>(
-      GetProcAddress(GetModuleHandleA("user32.dll"),
-                      "SetProcessDPIAware"));
-  return set_process_dpi_aware_func &&
-    set_process_dpi_aware_func();
-}
-
-DWORD ReadRegistryValue(HKEY root,
-                        const wchar_t* base_key,
-                        const wchar_t* value_name,
-                        DWORD default_value) {
-  base::win::RegKey reg_key(HKEY_CURRENT_USER,
-                            base_key,
-                            KEY_QUERY_VALUE);
-  DWORD value;
-  if (reg_key.Valid() &&
-      reg_key.ReadValueDW(value_name, &value) == ERROR_SUCCESS) {
-    return value;
-  }
-  return default_value;
-}
-
 }  // namespace
 
 namespace gfx {
@@ -131,63 +56,25 @@
 }
 
 float GetDPIScale() {
-  if (IsHighDPIEnabled()) {
-    if (gfx::Display::HasForceDeviceScaleFactor())
-      return gfx::Display::GetForcedDeviceScaleFactor();
-    float dpi_scale = GetUnforcedDeviceScaleFactor();
-    if (dpi_scale <= 1.25) {
-      // Force 125% and below to 100% scale. We do this to maintain previous
-      // (non-DPI-aware) behavior where only the font size was boosted.
-      dpi_scale = 1.0;
-    }
-    return dpi_scale;
+  if (gfx::Display::HasForceDeviceScaleFactor())
+    return gfx::Display::GetForcedDeviceScaleFactor();
+  float dpi_scale = GetUnforcedDeviceScaleFactor();
+  if (dpi_scale <= 1.25) {
+    // Force 125% and below to 100% scale. We do this to maintain previous
+    // (non-DPI-aware) behavior where only the font size was boosted.
+    dpi_scale = 1.0;
   }
-  return 1.0;
-}
-
-void ForceHighDPISupportForTesting(float scale) {
-  g_device_scale_factor = scale;
-}
-
-bool IsHighDPIEnabled() {
-  // Flag stored in HKEY_CURRENT_USER\SOFTWARE\\Google\\Chrome\\Profile,
-  // under the DWORD value high-dpi-support.
-  // Default is disabled.
-  static DWORD value = ReadRegistryValue(
-      HKEY_CURRENT_USER, gfx::win::kRegistryProfilePath,
-      gfx::win::kHighDPISupportW, TRUE);
-  return value != 0;
-}
-
-bool IsInHighDPIMode() {
-  return GetDPIScale() > 1.0;
-}
-
-void EnableHighDPISupport() {
-  if (IsHighDPIEnabled() &&
-      !SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
-    SetProcessDPIAwareWrapper();
-  }
+  return dpi_scale;
 }
 
 namespace win {
 
-GFX_EXPORT const wchar_t kRegistryProfilePath[] =
-    L"Software\\Google\\Chrome\\Profile";
-GFX_EXPORT const wchar_t kHighDPISupportW[] = L"high-dpi-support";
-
-float GetDeviceScaleFactor() {
-  DCHECK_NE(0.0f, g_device_scale_factor);
-  return g_device_scale_factor;
-}
-
 Point ScreenToDIPPoint(const Point& pixel_point) {
-  return ToFlooredPoint(ScalePoint(pixel_point,
-                                   1.0f / GetDeviceScaleFactor()));
+  return ToFlooredPoint(ScalePoint(pixel_point, 1.0f / GetDPIScale()));
 }
 
 Point DIPToScreenPoint(const Point& dip_point) {
-  return ToFlooredPoint(ScalePoint(dip_point, GetDeviceScaleFactor()));
+  return ToFlooredPoint(ScalePoint(dip_point, GetDPIScale()));
 }
 
 Rect ScreenToDIPRect(const Rect& pixel_bounds) {
@@ -208,22 +95,16 @@
 
 Size ScreenToDIPSize(const Size& size_in_pixels) {
   // Always ceil sizes. Otherwise we may be leaving off part of the bounds.
-  return ToCeiledSize(
-      ScaleSize(size_in_pixels, 1.0f / GetDeviceScaleFactor()));
+  return ToCeiledSize(ScaleSize(size_in_pixels, 1.0f / GetDPIScale()));
 }
 
 Size DIPToScreenSize(const Size& dip_size) {
   // Always ceil sizes. Otherwise we may be leaving off part of the bounds.
-  return ToCeiledSize(ScaleSize(dip_size, GetDeviceScaleFactor()));
+  return ToCeiledSize(ScaleSize(dip_size, GetDPIScale()));
 }
 
 int GetSystemMetricsInDIP(int metric) {
-  return static_cast<int>(GetSystemMetrics(metric) /
-      GetDeviceScaleFactor() + 0.5);
-}
-
-bool IsDeviceScaleFactorSet() {
-  return g_device_scale_factor != 0.0f;
+  return static_cast<int>(GetSystemMetrics(metric) / GetDPIScale() + 0.5);
 }
 
 }  // namespace win
diff --git a/ui/gfx/win/dpi.h b/ui/gfx/win/dpi.h
index 19f6a57..02c798ca1 100644
--- a/ui/gfx/win/dpi.h
+++ b/ui/gfx/win/dpi.h
@@ -25,21 +25,8 @@
 // 96 then the scale factor is 1.0.
 GFX_EXPORT float GetDPIScale();
 
-// Tests to see if the command line flag "--high-dpi-support" is set.
-GFX_EXPORT bool IsHighDPIEnabled();
-
-GFX_EXPORT bool IsInHighDPIMode();
-
-GFX_EXPORT void EnableHighDPISupport();
-
-GFX_EXPORT void ForceHighDPISupportForTesting(float scale);
-
-// TODO(kevers|girard):  Move above methods into win namespace.
-
 namespace win {
 
-GFX_EXPORT float GetDeviceScaleFactor();
-
 GFX_EXPORT Point ScreenToDIPPoint(const Point& pixel_point);
 
 GFX_EXPORT Point DIPToScreenPoint(const Point& dip_point);
@@ -58,13 +45,6 @@
 // GetSystemMetrics for the given |metric|, then converts the result to DIP.
 GFX_EXPORT int GetSystemMetricsInDIP(int metric);
 
-// Returns true if the global device scale factor has been explicitly set for
-// the process.
-GFX_EXPORT bool IsDeviceScaleFactorSet();
-
-GFX_EXPORT extern const wchar_t kRegistryProfilePath[];
-GFX_EXPORT extern const wchar_t kHighDPISupportW[];
-
 }  // namespace win
 }  // namespace gfx
 
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index b135cac..790b38b6 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -868,6 +868,13 @@
                  'gl_versions': ['es3'],
                  'extensions': ['GL_NV_path_rendering'] }],
   'arguments': 'GLenum matrixMode' },
+  { 'return_type': 'void',
+    'known_as': 'glBlendBarrierKHR',
+    'versions': [{ 'name': 'glBlendBarrierNV',
+                   'extensions': ['GL_NV_blend_equation_advanced'] },
+                 { 'name': 'glBlendBarrierKHR',
+                   'extensions': ['GL_KHR_blend_equation_advanced'] }],
+    'arguments': 'void' },
 ]
 
 OSMESA_FUNCTIONS = [
@@ -1079,7 +1086,7 @@
       'EGLuint64CHROMIUM* sbc', },
 { 'return_type': 'EGLint',
   'versions': [{ 'name': 'eglWaitSyncKHR',
-                 'extensions': ['EGL_KHR_fence_sync'] }],
+                 'extensions': ['EGL_KHR_fence_sync', 'EGL_KHR_wait_sync'] }],
   'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags' }
 ]
 
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp
index f3be5b26..fdd227a 100644
--- a/ui/gl/gl.gyp
+++ b/ui/gl/gl.gyp
@@ -311,6 +311,14 @@
             '../android/ui_android.gyp:ui_java',
           ],
         }],
+        ['ubsan==1', {
+          # Due to a bug in LLVM (http://llvm.org/bugs/show_bug.cgi?id=21349),
+          # compilation hangs for some GL source files. Disable -O2 temporarily
+          # until http://crbug.com/426271 is fixed.
+          'cflags!': [
+            '-O2',
+          ],
+        }],
       ],
     },
     {
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h
index 22774f50..aef80f07 100644
--- a/ui/gl/gl_bindings.h
+++ b/ui/gl/gl_bindings.h
@@ -224,6 +224,30 @@
 #define GL_PATH_PROJECTION_CHROMIUM 0x1701
 #endif
 
+#ifndef GL_KHR_blend_equation_advanced
+#define GL_KHR_blend_equation_advanced 1
+#define GL_COLORBURN_KHR                  0x929A
+#define GL_COLORDODGE_KHR                 0x9299
+#define GL_DARKEN_KHR                     0x9297
+#define GL_DIFFERENCE_KHR                 0x929E
+#define GL_EXCLUSION_KHR                  0x92A0
+#define GL_HARDLIGHT_KHR                  0x929B
+#define GL_HSL_COLOR_KHR                  0x92AF
+#define GL_HSL_HUE_KHR                    0x92AD
+#define GL_HSL_LUMINOSITY_KHR             0x92B0
+#define GL_HSL_SATURATION_KHR             0x92AE
+#define GL_LIGHTEN_KHR                    0x9298
+#define GL_MULTIPLY_KHR                   0x9294
+#define GL_OVERLAY_KHR                    0x9296
+#define GL_SCREEN_KHR                     0x9295
+#define GL_SOFTLIGHT_KHR                  0x929C
+#endif /* GL_KHR_blend_equation_advanced */
+
+#ifndef GL_KHR_blend_equation_advanced_coherent
+#define GL_KHR_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_KHR    0x9285
+#endif /* GL_KHR_blend_equation_advanced_coherent */
+
 #ifndef GL_EXT_disjoint_timer_query
 #define GL_EXT_disjoint_timer_query 1
 #define GL_QUERY_COUNTER_BITS_EXT         0x8864
diff --git a/ui/gl/gl_fence_egl.cc b/ui/gl/gl_fence_egl.cc
index ebc33bf..2ff18fc 100644
--- a/ui/gl/gl_fence_egl.cc
+++ b/ui/gl/gl_fence_egl.cc
@@ -42,6 +42,10 @@
 }
 
 void GLFenceEGL::ServerWait() {
+  if (!gfx::g_driver_egl.ext.b_EGL_KHR_wait_sync) {
+    ClientWait();
+    return;
+  }
   if (!flush_event_.get() || flush_event_->IsSignaled()) {
     EGLint flags = 0;
     eglWaitSyncKHR(display_, sync_, flags);
diff --git a/ui/login/account_picker/user_pod_row.js b/ui/login/account_picker/user_pod_row.js
index 96d678f..dbac7f3de 100644
--- a/ui/login/account_picker/user_pod_row.js
+++ b/ui/login/account_picker/user_pod_row.js
@@ -292,6 +292,14 @@
     },
 
     /**
+     * Sets the ARIA label for the icon.
+     * @param {!string} ariaLabel
+     */
+    setAriaLabel: function(ariaLabel) {
+      this.iconElement.setAttribute('aria-label', ariaLabel);
+    },
+
+    /**
      * Shows the icon.
      */
     show: function() {
@@ -352,9 +360,6 @@
       }
 
       this.hideTooltip_(true);
-
-      if (this.tooltip_)
-        this.iconElement.setAttribute('aria-lablel', this.tooltip_);
     },
 
     /**
@@ -496,7 +501,6 @@
         return;
       $('bubble').hideForElement(this);
       this.tooltipAutoshown_ = false;
-      this.iconElement.removeAttribute('aria-label');
     },
 
     /**
@@ -2246,6 +2250,7 @@
      * @param {string} username Username of pod to add button
      * @param {!{id: !string,
      *           hardlockOnClick: boolean,
+     *           ariaLabel: string | undefined,
      *           tooltip: ({text: string, autoshow: boolean} | undefined)}} icon
      *     The icon parameters.
      */
@@ -2269,6 +2274,12 @@
         pod.customIconElement.setInteractive(null);
       }
 
+      var ariaLabel = icon.ariaLabel || (icon.tooltip && icon.tooltip.text);
+      if (ariaLabel)
+        pod.customIconElement.setAriaLabel(ariaLabel);
+      else
+        console.warn('No ARIA label for user pod custom icon.');
+
       pod.customIconElement.show();
 
       // This has to be called after |show| in case the tooltip should be shown
diff --git a/ui/ozone/common/display_snapshot_proxy.cc b/ui/ozone/common/display_snapshot_proxy.cc
index 0e9db0b..4bc9e24 100644
--- a/ui/ozone/common/display_snapshot_proxy.cc
+++ b/ui/ozone/common/display_snapshot_proxy.cc
@@ -20,7 +20,6 @@
 
 DisplaySnapshotProxy::DisplaySnapshotProxy(const DisplaySnapshot_Params& params)
     : DisplaySnapshot(params.display_id,
-                      params.has_proper_display_id,
                       params.origin,
                       params.physical_size,
                       params.type,
diff --git a/ui/ozone/common/display_util.cc b/ui/ozone/common/display_util.cc
index 784656e..8db7c3a6 100644
--- a/ui/ozone/common/display_util.cc
+++ b/ui/ozone/common/display_util.cc
@@ -22,7 +22,6 @@
     const DisplaySnapshot& display) {
   DisplaySnapshot_Params params;
   params.display_id = display.display_id();
-  params.has_proper_display_id = display.has_proper_display_id();
   params.origin = display.origin();
   params.physical_size = display.physical_size();
   params.type = display.type();
diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.cc b/ui/ozone/common/gpu/ozone_gpu_message_params.cc
index 7b69136..aae2e14 100644
--- a/ui/ozone/common/gpu/ozone_gpu_message_params.cc
+++ b/ui/ozone/common/gpu/ozone_gpu_message_params.cc
@@ -13,7 +13,6 @@
 
 DisplaySnapshot_Params::DisplaySnapshot_Params()
     : display_id(0),
-      has_proper_display_id(false),
       origin(),
       physical_size(),
       type(ui::DISPLAY_CONNECTION_TYPE_NONE),
diff --git a/ui/ozone/common/gpu/ozone_gpu_message_params.h b/ui/ozone/common/gpu/ozone_gpu_message_params.h
index fcce42fe..fe35df9 100644
--- a/ui/ozone/common/gpu/ozone_gpu_message_params.h
+++ b/ui/ozone/common/gpu/ozone_gpu_message_params.h
@@ -28,7 +28,6 @@
   ~DisplaySnapshot_Params();
 
   int64_t display_id;
-  bool has_proper_display_id;
   gfx::Point origin;
   gfx::Size physical_size;
   DisplayConnectionType type;
diff --git a/ui/ozone/common/gpu/ozone_gpu_messages.h b/ui/ozone/common/gpu/ozone_gpu_messages.h
index 86cd286..3d9556e 100644
--- a/ui/ozone/common/gpu/ozone_gpu_messages.h
+++ b/ui/ozone/common/gpu/ozone_gpu_messages.h
@@ -32,7 +32,6 @@
 
 IPC_STRUCT_TRAITS_BEGIN(ui::DisplaySnapshot_Params)
   IPC_STRUCT_TRAITS_MEMBER(display_id)
-  IPC_STRUCT_TRAITS_MEMBER(has_proper_display_id)
   IPC_STRUCT_TRAITS_MEMBER(origin)
   IPC_STRUCT_TRAITS_MEMBER(physical_size)
   IPC_STRUCT_TRAITS_MEMBER(type)
diff --git a/ui/ozone/platform/dri/display_snapshot_dri.cc b/ui/ozone/platform/dri/display_snapshot_dri.cc
index 0d0c5591..383f949 100644
--- a/ui/ozone/platform/dri/display_snapshot_dri.cc
+++ b/ui/ozone/platform/dri/display_snapshot_dri.cc
@@ -67,7 +67,6 @@
                                        drmModeCrtc* crtc,
                                        uint32_t index)
     : DisplaySnapshot(index,
-                      false,
                       gfx::Point(crtc->x, crtc->y),
                       gfx::Size(connector->mmWidth, connector->mmHeight),
                       GetDisplayType(connector),
@@ -91,7 +90,9 @@
         static_cast<uint8_t*>(edid_blob->data),
         static_cast<uint8_t*>(edid_blob->data) + edid_blob->length);
 
-    has_proper_display_id_ = GetDisplayIdFromEDID(edid, index, &display_id_);
+    if (!GetDisplayIdFromEDID(edid, index, &display_id_))
+      display_id_ = index;
+
     ParseOutputDeviceData(edid, NULL, &display_name_);
     ParseOutputOverscanFlag(edid, &overscan_flag_);
   } else {
diff --git a/ui/ozone/platform/dri/gbm_buffer.cc b/ui/ozone/platform/dri/gbm_buffer.cc
index 030dc3b3..8eaccbf 100644
--- a/ui/ozone/platform/dri/gbm_buffer.cc
+++ b/ui/ozone/platform/dri/gbm_buffer.cc
@@ -4,9 +4,13 @@
 
 #include "ui/ozone/platform/dri/gbm_buffer.h"
 
+#include <drm.h>
+#include <fcntl.h>
 #include <gbm.h>
+#include <xf86drm.h>
 
 #include "base/logging.h"
+#include "ui/ozone/platform/dri/dri_wrapper.h"
 
 namespace ui {
 
@@ -60,22 +64,37 @@
   return buffer;
 }
 
-GbmPixmap::GbmPixmap(scoped_refptr<GbmBuffer> buffer) : buffer_(buffer) {
+GbmPixmap::GbmPixmap(scoped_refptr<GbmBuffer> buffer)
+    : buffer_(buffer), dma_buf_(-1) {
+}
+
+bool GbmPixmap::Initialize(DriWrapper* dri) {
+  if (drmPrimeHandleToFD(dri->get_fd(),
+                         buffer_->GetHandle(),
+                         DRM_CLOEXEC,
+                         &dma_buf_)) {
+    LOG(ERROR) << "Failed to export buffer to dma_buf";
+    return false;
+  }
+
+  return true;
 }
 
 GbmPixmap::~GbmPixmap() {
+  if (dma_buf_ > 0)
+    close(dma_buf_);
 }
 
 void* GbmPixmap::GetEGLClientBuffer() {
-  return buffer_->bo();
+  return NULL;
 }
 
 int GbmPixmap::GetDmaBufFd() {
-  return -1;
+  return dma_buf_;
 }
 
 int GbmPixmap::GetDmaBufPitch() {
-  return -1;
+  return gbm_bo_get_stride(buffer_->bo());
 }
 
 }  // namespace ui
diff --git a/ui/ozone/platform/dri/gbm_buffer.h b/ui/ozone/platform/dri/gbm_buffer.h
index 3fad2c5..06c2d58 100644
--- a/ui/ozone/platform/dri/gbm_buffer.h
+++ b/ui/ozone/platform/dri/gbm_buffer.h
@@ -38,6 +38,7 @@
 class GbmPixmap : public NativePixmap {
  public:
   GbmPixmap(scoped_refptr<GbmBuffer> buffer);
+  bool Initialize(DriWrapper* dri);
 
   // NativePixmap:
   virtual void* GetEGLClientBuffer() override;
@@ -50,6 +51,7 @@
   virtual ~GbmPixmap();
 
   scoped_refptr<GbmBuffer> buffer_;
+  int dma_buf_;
 
   DISALLOW_COPY_AND_ASSIGN(GbmPixmap);
 };
diff --git a/ui/ozone/platform/dri/gbm_surface_factory.cc b/ui/ozone/platform/dri/gbm_surface_factory.cc
index e04ae8e..bbb2c4074 100644
--- a/ui/ozone/platform/dri/gbm_surface_factory.cc
+++ b/ui/ozone/platform/dri/gbm_surface_factory.cc
@@ -176,7 +176,11 @@
   if (!buffer.get())
     return NULL;
 
-  return scoped_refptr<GbmPixmap>(new GbmPixmap(buffer));
+  scoped_refptr<GbmPixmap> pixmap(new GbmPixmap(buffer));
+  if (!pixmap->Initialize(drm_))
+    return NULL;
+
+  return pixmap;
 }
 
 OverlayCandidatesOzone* GbmSurfaceFactory::GetOverlayCandidates(
diff --git a/ui/platform_window/win/win_window.cc b/ui/platform_window/win/win_window.cc
index ae1e3eac..b6a0b03 100644
--- a/ui/platform_window/win/win_window.cc
+++ b/ui/platform_window/win/win_window.cc
@@ -107,7 +107,7 @@
 void WinWindow::MoveCursorTo(const gfx::Point& location) {}
 
 LRESULT WinWindow::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) {
-  MSG msg = { hwnd(), message, w_param, l_param, 0,
+  MSG msg = { hwnd(), message, w_param, l_param, GetMessageTime(),
               { CR_GET_X_LPARAM(l_param), CR_GET_Y_LPARAM(l_param) } };
   MouseEvent event(msg);
   if (IsMouseEventFromTouch(message))
diff --git a/ui/resources/default_100_percent/disable.png b/ui/resources/default_100_percent/disable.png
new file mode 100644
index 0000000..f5ba52b
--- /dev/null
+++ b/ui/resources/default_100_percent/disable.png
Binary files differ
diff --git a/ui/resources/default_100_percent/disable_hover.png b/ui/resources/default_100_percent/disable_hover.png
new file mode 100644
index 0000000..c9bec3cd
--- /dev/null
+++ b/ui/resources/default_100_percent/disable_hover.png
Binary files differ
diff --git a/ui/resources/default_100_percent/disable_pressed.png b/ui/resources/default_100_percent/disable_pressed.png
new file mode 100644
index 0000000..417a432
--- /dev/null
+++ b/ui/resources/default_100_percent/disable_pressed.png
Binary files differ
diff --git a/ui/resources/default_200_percent/disable.png b/ui/resources/default_200_percent/disable.png
new file mode 100644
index 0000000..2652320
--- /dev/null
+++ b/ui/resources/default_200_percent/disable.png
Binary files differ
diff --git a/ui/resources/default_200_percent/disable_hover.png b/ui/resources/default_200_percent/disable_hover.png
new file mode 100644
index 0000000..67d1261
--- /dev/null
+++ b/ui/resources/default_200_percent/disable_hover.png
Binary files differ
diff --git a/ui/resources/default_200_percent/disable_pressed.png b/ui/resources/default_200_percent/disable_pressed.png
new file mode 100644
index 0000000..dcdfc842
--- /dev/null
+++ b/ui/resources/default_200_percent/disable_pressed.png
Binary files differ
diff --git a/mojo/examples/wm_flow/app/DEPS b/ui/resources/default_300_percent/DELETE_ME
similarity index 100%
copy from mojo/examples/wm_flow/app/DEPS
copy to ui/resources/default_300_percent/DELETE_ME
diff --git a/ui/resources/ui_resources.grd b/ui/resources/ui_resources.grd
index 1bae8be1..d294424 100644
--- a/ui/resources/ui_resources.grd
+++ b/ui/resources/ui_resources.grd
@@ -8,6 +8,7 @@
     <output filename="grit/ui_resources_map.h" type="resource_map_header" context="default_100_percent" />
     <output filename="ui_resources_100_percent.pak" type="data_package" context="default_100_percent" />
     <output filename="ui_resources_200_percent.pak" type="data_package" context="default_200_percent" />
+    <output filename="ui_resources_300_percent.pak" type="data_package" context="default_300_percent" />
   </outputs>
   <release seq="1">
     <structures fallback_to_low_resolution="true">
@@ -167,6 +168,10 @@
       <structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG" file="close_dialog.png" />
       <structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG_H" file="close_dialog_hover.png" />
       <structure type="chrome_scaled_image" name="IDR_CLOSE_DIALOG_P" file="close_dialog_pressed.png" />
+      <structure type="chrome_scaled_image" name="IDR_DISABLE" file="disable.png" />
+      <structure type="chrome_scaled_image" name="IDR_DISABLE_H" file="disable_hover.png" />
+      <structure type="chrome_scaled_image" name="IDR_DISABLE_P" file="disable_pressed.png" />
+
       <if expr="desktop_linux">
         <structure type="chrome_scaled_image" name="IDR_CLOSE_H" file="linux/linux_close_hover.png" />
         <structure type="chrome_scaled_image" name="IDR_CLOSE_P" file="linux/linux_close_pressed.png" />
diff --git a/ui/shell_dialogs/select_file_dialog.cc b/ui/shell_dialogs/select_file_dialog.cc
index e5abd07..d26fc36d 100644
--- a/ui/shell_dialogs/select_file_dialog.cc
+++ b/ui/shell_dialogs/select_file_dialog.cc
@@ -46,7 +46,10 @@
     int index,
     void* params) {
   // Most of the dialogs need actual local path, so default to it.
-  FileSelected(file.local_path, index, params);
+  // If local path is empty, use file_path instead.
+  FileSelected(file.local_path.empty() ? file.file_path : file.local_path,
+               index,
+               params);
 }
 
 void SelectFileDialog::Listener::MultiFilesSelectedWithExtraInfo(
@@ -54,7 +57,8 @@
     void* params) {
   std::vector<base::FilePath> file_paths;
   for (size_t i = 0; i < files.size(); ++i)
-    file_paths.push_back(files[i].local_path);
+    file_paths.push_back(files[i].local_path.empty() ? files[i].file_path
+                                                     : files[i].local_path);
 
   MultiFilesSelected(file_paths, params);
 }
diff --git a/ui/shell_dialogs/selected_file_info.cc b/ui/shell_dialogs/selected_file_info.cc
index 8bc68ab..054c511 100644
--- a/ui/shell_dialogs/selected_file_info.cc
+++ b/ui/shell_dialogs/selected_file_info.cc
@@ -12,8 +12,6 @@
                                    const base::FilePath& in_local_path)
     : file_path(in_file_path),
       local_path(in_local_path) {
-  if (local_path.empty())
-    local_path = file_path;
   display_name = in_file_path.BaseName().value();
 }
 
diff --git a/ui/shell_dialogs/selected_file_info.h b/ui/shell_dialogs/selected_file_info.h
index a2e9134..a1789c97 100644
--- a/ui/shell_dialogs/selected_file_info.h
+++ b/ui/shell_dialogs/selected_file_info.h
@@ -20,10 +20,9 @@
 
   // The actual local path to the selected file. This can be a snapshot file
   // with a human unreadable name like /blah/.d41d8cd98f00b204e9800998ecf8427e.
-  // |real_path| can differ from |file_path| for drive files (e.g.
+  // |local_path| can differ from |file_path| for drive files (e.g.
   // /drive_cache/temporary/d41d8cd98f00b204e9800998ecf8427e vs.
   // /special/drive/foo.txt).
-  // If not set, defaults to |file_path|.
   base::FilePath local_path;
 
   // This field is optional. The display name contains only the base name
@@ -41,4 +40,3 @@
 }  // namespace ui
 
 #endif  // UI_SHELL_DIALOGS_SELECTED_FILE_INFO_H_
-
diff --git a/ui/views/accessibility/native_view_accessibility_win.cc b/ui/views/accessibility/native_view_accessibility_win.cc
index 023e311..c27a1cec 100644
--- a/ui/views/accessibility/native_view_accessibility_win.cc
+++ b/ui/views/accessibility/native_view_accessibility_win.cc
@@ -1491,13 +1491,11 @@
     return;
 
   std::set<Widget*> child_widgets;
-  Widget::GetAllChildWidgets(widget->GetNativeView(), &child_widgets);
   Widget::GetAllOwnedWidgets(widget->GetNativeView(), &child_widgets);
   for (std::set<Widget*>::const_iterator iter = child_widgets.begin();
            iter != child_widgets.end(); ++iter) {
     Widget* child_widget = *iter;
-    if (child_widget == widget)
-      continue;
+    DCHECK_NE(widget, child_widget);
 
     if (!child_widget->IsVisible())
       continue;
diff --git a/ui/views/controls/button/menu_button.cc b/ui/views/controls/button/menu_button.cc
index debd227..f2b3852 100644
--- a/ui/views/controls/button/menu_button.cc
+++ b/ui/views/controls/button/menu_button.cc
@@ -171,28 +171,18 @@
 
 bool MenuButton::OnMousePressed(const ui::MouseEvent& event) {
   RequestFocus();
-  if (state() != STATE_DISABLED) {
-    // If we're draggable (GetDragOperations returns a non-zero value), then
-    // don't pop on press, instead wait for release.
-    if (event.IsOnlyLeftMouseButton() &&
-        HitTestPoint(event.location()) &&
-        GetDragOperations(event.location()) == ui::DragDropTypes::DRAG_NONE) {
-      TimeDelta delta = TimeTicks::Now() - menu_closed_time_;
-      if (delta.InMilliseconds() > kMinimumMsBetweenButtonClicks)
-        return Activate();
-    }
+  if (state() != STATE_DISABLED && ShouldEnterPushedState(event) &&
+      HitTestPoint(event.location())) {
+    TimeDelta delta = TimeTicks::Now() - menu_closed_time_;
+    if (delta.InMilliseconds() > kMinimumMsBetweenButtonClicks)
+      return Activate();
   }
   return true;
 }
 
 void MenuButton::OnMouseReleased(const ui::MouseEvent& event) {
-  // Explicitly test for left mouse button to show the menu. If we tested for
-  // !IsTriggerableEvent it could lead to a situation where we end up showing
-  // the menu and context menu (this would happen if the right button is not
-  // triggerable and there's a context menu).
-  if (GetDragOperations(event.location()) != ui::DragDropTypes::DRAG_NONE &&
-      state() != STATE_DISABLED && !InDrag() && event.IsOnlyLeftMouseButton() &&
-      HitTestPoint(event.location())) {
+  if (state() != STATE_DISABLED && ShouldEnterPushedState(event) &&
+      HitTestPoint(event.location()) && !InDrag()) {
     Activate();
   } else {
     LabelButton::OnMouseReleased(event);
@@ -201,21 +191,21 @@
 
 void MenuButton::OnMouseEntered(const ui::MouseEvent& event) {
   if (pressed_lock_count_ == 0)  // Ignore mouse movement if state is locked.
-    CustomButton::OnMouseEntered(event);
+    LabelButton::OnMouseEntered(event);
 }
 
 void MenuButton::OnMouseExited(const ui::MouseEvent& event) {
   if (pressed_lock_count_ == 0)  // Ignore mouse movement if state is locked.
-    CustomButton::OnMouseExited(event);
+    LabelButton::OnMouseExited(event);
 }
 
 void MenuButton::OnMouseMoved(const ui::MouseEvent& event) {
   if (pressed_lock_count_ == 0)  // Ignore mouse movement if state is locked.
-    CustomButton::OnMouseMoved(event);
+    LabelButton::OnMouseMoved(event);
 }
 
 void MenuButton::OnGestureEvent(ui::GestureEvent* event) {
-  if (state() != STATE_DISABLED && event->type() == ui::ET_GESTURE_TAP &&
+  if (state() != STATE_DISABLED && ShouldEnterPushedState(*event) &&
       !Activate()) {
     // When |Activate()| returns |false|, it means that a menu is shown and
     // has handled the gesture event. So, there is no need to further process
@@ -287,6 +277,25 @@
   return gfx::Rect(s);
 }
 
+bool MenuButton::ShouldEnterPushedState(const ui::Event& event) {
+  if (event.IsMouseEvent()) {
+    const ui::MouseEvent& mouseev = static_cast<const ui::MouseEvent&>(event);
+    // Active on left mouse button only, to prevent a menu from being activated
+    // when a right-click would also activate a context menu.
+    if (!mouseev.IsOnlyLeftMouseButton())
+      return false;
+    // If dragging is supported activate on release, otherwise activate on
+    // pressed.
+    ui::EventType active_on =
+        GetDragOperations(mouseev.location()) == ui::DragDropTypes::DRAG_NONE
+            ? ui::ET_MOUSE_PRESSED
+            : ui::ET_MOUSE_RELEASED;
+    return event.type() == active_on;
+  }
+
+  return event.type() == ui::ET_GESTURE_TAP;
+}
+
 void MenuButton::IncrementPressedLocked() {
   ++pressed_lock_count_;
   SetState(STATE_PRESSED);
diff --git a/ui/views/controls/button/menu_button.h b/ui/views/controls/button/menu_button.h
index a1baf05c..5f7dc68 100644
--- a/ui/views/controls/button/menu_button.h
+++ b/ui/views/controls/button/menu_button.h
@@ -65,25 +65,28 @@
   virtual bool Activate();
 
   // Overridden from View:
-  virtual gfx::Size GetPreferredSize() const override;
-  virtual const char* GetClassName() const override;
-  virtual void OnPaint(gfx::Canvas* canvas) override;
-  virtual bool OnMousePressed(const ui::MouseEvent& event) override;
-  virtual void OnMouseReleased(const ui::MouseEvent& event) override;
-  virtual void OnMouseEntered(const ui::MouseEvent& event) override;
-  virtual void OnMouseExited(const ui::MouseEvent& event) override;
-  virtual void OnMouseMoved(const ui::MouseEvent& event) override;
-  virtual void OnGestureEvent(ui::GestureEvent* event) override;
-  virtual bool OnKeyPressed(const ui::KeyEvent& event) override;
-  virtual bool OnKeyReleased(const ui::KeyEvent& event) override;
-  virtual void GetAccessibleState(ui::AXViewState* state) override;
+  gfx::Size GetPreferredSize() const override;
+  const char* GetClassName() const override;
+  void OnPaint(gfx::Canvas* canvas) override;
+  bool OnMousePressed(const ui::MouseEvent& event) override;
+  void OnMouseReleased(const ui::MouseEvent& event) override;
+  void OnMouseEntered(const ui::MouseEvent& event) override;
+  void OnMouseExited(const ui::MouseEvent& event) override;
+  void OnMouseMoved(const ui::MouseEvent& event) override;
+  void OnGestureEvent(ui::GestureEvent* event) override;
+  bool OnKeyPressed(const ui::KeyEvent& event) override;
+  bool OnKeyReleased(const ui::KeyEvent& event) override;
+  void GetAccessibleState(ui::AXViewState* state) override;
 
  protected:
   // Paint the menu marker image.
   void PaintMenuMarker(gfx::Canvas* canvas);
 
   // Overridden from LabelButton:
-  virtual gfx::Rect GetChildAreaBounds() override;
+  gfx::Rect GetChildAreaBounds() override;
+
+  // Overridden from CustomButton:
+  bool ShouldEnterPushedState(const ui::Event& event) override;
 
   // Offset of the associated menu position.
   gfx::Point menu_offset_;
diff --git a/ui/views/controls/button/menu_button_unittest.cc b/ui/views/controls/button/menu_button_unittest.cc
index 3b153ad..b75a55a 100644
--- a/ui/views/controls/button/menu_button_unittest.cc
+++ b/ui/views/controls/button/menu_button_unittest.cc
@@ -6,20 +6,28 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/utf_string_conversions.h"
+#include "ui/base/dragdrop/drag_drop_types.h"
 #include "ui/events/test/event_generator.h"
 #include "ui/views/controls/button/menu_button_listener.h"
+#include "ui/views/drag_controller.h"
 #include "ui/views/test/views_test_base.h"
 
+#if defined(USE_AURA)
+#include "ui/events/event.h"
+#include "ui/events/event_handler.h"
+#include "ui/wm/public/drag_drop_client.h"
+#endif
+
 using base::ASCIIToUTF16;
 
 namespace views {
 
 class MenuButtonTest : public ViewsTestBase {
  public:
-  MenuButtonTest() : widget_(NULL), button_(NULL) {}
+  MenuButtonTest() : widget_(nullptr), button_(nullptr) {}
   virtual ~MenuButtonTest() {}
 
-  virtual void TearDown() override {
+  void TearDown() override {
     if (widget_ && !widget_->IsClosed())
       widget_->Close();
 
@@ -31,14 +39,12 @@
 
  protected:
   // Creates a MenuButton with no button listener.
-  void CreateMenuButtonWithNoListener() {
-    CreateMenuButton(NULL, NULL);
-  }
+  void CreateMenuButtonWithNoListener() { CreateMenuButton(nullptr, nullptr); }
 
   // Creates a MenuButton with a ButtonListener. In this case, the MenuButton
   // acts like a regular button.
   void CreateMenuButtonWithButtonListener(ButtonListener* button_listener) {
-    CreateMenuButton(button_listener, NULL);
+    CreateMenuButton(button_listener, nullptr);
   }
 
   // Creates a MenuButton with a MenuButtonListener. In this case, when the
@@ -46,7 +52,7 @@
   // drop-down menu.
   void CreateMenuButtonWithMenuButtonListener(
       MenuButtonListener* menu_button_listener) {
-    CreateMenuButton(NULL, menu_button_listener);
+    CreateMenuButton(nullptr, menu_button_listener);
   }
 
  private:
@@ -80,12 +86,12 @@
 class TestButtonListener : public ButtonListener {
  public:
   TestButtonListener()
-      : last_sender_(NULL),
+      : last_sender_(nullptr),
         last_sender_state_(Button::STATE_NORMAL),
         last_event_type_(ui::ET_UNKNOWN) {}
   virtual ~TestButtonListener() {}
 
-  virtual void ButtonPressed(Button* sender, const ui::Event& event) override {
+  void ButtonPressed(Button* sender, const ui::Event& event) override {
     last_sender_ = sender;
     CustomButton* custom_button = CustomButton::AsCustomButton(sender);
     DCHECK(custom_button);
@@ -107,11 +113,11 @@
 
 class TestMenuButtonListener : public MenuButtonListener {
  public:
-  TestMenuButtonListener() {}
+  TestMenuButtonListener()
+      : last_source_(nullptr), last_source_state_(Button::STATE_NORMAL) {}
   virtual ~TestMenuButtonListener() {}
 
-  virtual void OnMenuButtonClicked(View* source,
-                                   const gfx::Point& /*point*/) override {
+  void OnMenuButtonClicked(View* source, const gfx::Point& /*point*/) override {
     last_source_ = source;
     CustomButton* custom_button = CustomButton::AsCustomButton(source);
     DCHECK(custom_button);
@@ -126,11 +132,127 @@
   Button::ButtonState last_source_state_;
 };
 
+// Basic implementation of a DragController, to test input behaviour for
+// MenuButtons that can be dragged.
+class TestDragController : public DragController {
+ public:
+  TestDragController() {}
+  virtual ~TestDragController() {}
+
+  void WriteDragDataForView(View* sender,
+                            const gfx::Point& press_pt,
+                            ui::OSExchangeData* data) override {}
+
+  int GetDragOperationsForView(View* sender, const gfx::Point& p) override {
+    return ui::DragDropTypes::DRAG_MOVE;
+  }
+
+  bool CanStartDragForView(View* sender,
+                           const gfx::Point& press_pt,
+                           const gfx::Point& p) override {
+    return true;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestDragController);
+};
+
+#if defined(USE_AURA)
+// Basic implementation of a DragDropClient, tracking the state of the drag
+// operation. While dragging addition mouse events are consumed, preventing the
+// target view from receiving them.
+class TestDragDropClient : public aura::client::DragDropClient,
+                           public ui::EventHandler {
+ public:
+  TestDragDropClient();
+  virtual ~TestDragDropClient();
+
+  // aura::client::DragDropClient:
+  int StartDragAndDrop(const ui::OSExchangeData& data,
+                       aura::Window* root_window,
+                       aura::Window* source_window,
+                       const gfx::Point& root_location,
+                       int operation,
+                       ui::DragDropTypes::DragEventSource source) override;
+  void DragUpdate(aura::Window* target, const ui::LocatedEvent& event) override;
+  void Drop(aura::Window* target, const ui::LocatedEvent& event) override;
+  void DragCancel() override;
+  bool IsDragDropInProgress() override;
+
+  // ui::EventHandler:
+  void OnMouseEvent(ui::MouseEvent* event) override;
+
+ private:
+  // True while receiving ui::LocatedEvents for drag operations.
+  bool drag_in_progress_;
+
+  // Target window where drag operations are occuring.
+  aura::Window* target_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestDragDropClient);
+};
+
+TestDragDropClient::TestDragDropClient()
+    : drag_in_progress_(false), target_(nullptr) {
+}
+
+TestDragDropClient::~TestDragDropClient() {
+}
+
+int TestDragDropClient::StartDragAndDrop(
+    const ui::OSExchangeData& data,
+    aura::Window* root_window,
+    aura::Window* source_window,
+    const gfx::Point& root_location,
+    int operation,
+    ui::DragDropTypes::DragEventSource source) {
+  if (IsDragDropInProgress())
+    return ui::DragDropTypes::DRAG_NONE;
+  drag_in_progress_ = true;
+  target_ = root_window;
+  return operation;
+}
+
+void TestDragDropClient::DragUpdate(aura::Window* target,
+                                    const ui::LocatedEvent& event) {
+}
+
+void TestDragDropClient::Drop(aura::Window* target,
+                              const ui::LocatedEvent& event) {
+  drag_in_progress_ = false;
+}
+
+void TestDragDropClient::DragCancel() {
+  drag_in_progress_ = false;
+}
+
+bool TestDragDropClient::IsDragDropInProgress() {
+  return drag_in_progress_;
+}
+
+void TestDragDropClient::OnMouseEvent(ui::MouseEvent* event) {
+  if (!IsDragDropInProgress())
+    return;
+  switch (event->type()) {
+    case ui::ET_MOUSE_DRAGGED:
+      DragUpdate(target_, *event);
+      event->StopPropagation();
+      break;
+    case ui::ET_MOUSE_RELEASED:
+      Drop(target_, *event);
+      event->StopPropagation();
+      break;
+    default:
+      break;
+  }
+}
+#endif  // defined(USE_AURA)
+
 // Tests if the listener is notified correctly, when a mouse click happens on a
 // MenuButton that has a regular ButtonListener.
 TEST_F(MenuButtonTest, ActivateNonDropDownOnMouseClick) {
-  scoped_ptr<TestButtonListener> button_listener(new TestButtonListener);
-  CreateMenuButtonWithButtonListener(button_listener.get());
+  TestButtonListener button_listener;
+  CreateMenuButtonWithButtonListener(&button_listener);
 
   ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
 
@@ -139,33 +261,32 @@
 
   // Check that MenuButton has notified the listener on mouse-released event,
   // while it was in hovered state.
-  EXPECT_EQ(button(), button_listener->last_sender());
-  EXPECT_EQ(ui::ET_MOUSE_RELEASED, button_listener->last_event_type());
-  EXPECT_EQ(Button::STATE_HOVERED, button_listener->last_sender_state());
+  EXPECT_EQ(button(), button_listener.last_sender());
+  EXPECT_EQ(ui::ET_MOUSE_RELEASED, button_listener.last_event_type());
+  EXPECT_EQ(Button::STATE_HOVERED, button_listener.last_sender_state());
 }
 
 // Tests if the listener is notified correctly when a gesture tap happens on a
 // MenuButton that has a regular ButtonListener.
 TEST_F(MenuButtonTest, ActivateNonDropDownOnGestureTap) {
-  scoped_ptr<TestButtonListener> button_listener(new TestButtonListener);
-  CreateMenuButtonWithButtonListener(button_listener.get());
+  TestButtonListener button_listener;
+  CreateMenuButtonWithButtonListener(&button_listener);
 
   ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
   generator.GestureTapAt(gfx::Point(10, 10));
 
   // Check that MenuButton has notified the listener on gesture tap event, while
   // it was in hovered state.
-  EXPECT_EQ(button(), button_listener->last_sender());
-  EXPECT_EQ(ui::ET_GESTURE_TAP, button_listener->last_event_type());
-  EXPECT_EQ(Button::STATE_HOVERED, button_listener->last_sender_state());
+  EXPECT_EQ(button(), button_listener.last_sender());
+  EXPECT_EQ(ui::ET_GESTURE_TAP, button_listener.last_event_type());
+  EXPECT_EQ(Button::STATE_HOVERED, button_listener.last_sender_state());
 }
 
 // Tests if the listener is notified correctly when a mouse click happens on a
 // MenuButton that has a MenuButtonListener.
 TEST_F(MenuButtonTest, ActivateDropDownOnMouseClick) {
-  scoped_ptr<TestMenuButtonListener> menu_button_listener(
-      new TestMenuButtonListener);
-  CreateMenuButtonWithMenuButtonListener(menu_button_listener.get());
+  TestMenuButtonListener menu_button_listener;
+  CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
 
   ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
 
@@ -174,24 +295,23 @@
 
   // Check that MenuButton has notified the listener, while it was in pressed
   // state.
-  EXPECT_EQ(button(), menu_button_listener->last_source());
-  EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener->last_source_state());
+  EXPECT_EQ(button(), menu_button_listener.last_source());
+  EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener.last_source_state());
 }
 
 // Tests if the listener is notified correctly when a gesture tap happens on a
 // MenuButton that has a MenuButtonListener.
 TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) {
-  scoped_ptr<TestMenuButtonListener> menu_button_listener(
-      new TestMenuButtonListener);
-  CreateMenuButtonWithMenuButtonListener(menu_button_listener.get());
+  TestMenuButtonListener menu_button_listener;
+  CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
 
   ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
   generator.GestureTapAt(gfx::Point(10, 10));
 
   // Check that MenuButton has notified the listener, while it was in pressed
   // state.
-  EXPECT_EQ(button(), menu_button_listener->last_source());
-  EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener->last_source_state());
+  EXPECT_EQ(button(), menu_button_listener.last_source());
+  EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener.last_source_state());
 }
 
 // Test that the MenuButton stays pressed while there are any PressedLocks.
@@ -230,4 +350,44 @@
   EXPECT_EQ(Button::STATE_HOVERED, button()->state());
 }
 
+// Test that the MenuButton does not become pressed if it can be dragged, until
+// a release occurs.
+TEST_F(MenuButtonTest, DraggableMenuButtonActivatesOnRelease) {
+  TestMenuButtonListener menu_button_listener;
+  CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
+  TestDragController drag_controller;
+  button()->set_drag_controller(&drag_controller);
+
+  ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
+
+  generator.set_current_location(gfx::Point(10, 10));
+  generator.PressLeftButton();
+  EXPECT_EQ(nullptr, menu_button_listener.last_source());
+
+  generator.ReleaseLeftButton();
+  EXPECT_EQ(button(), menu_button_listener.last_source());
+  EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener.last_source_state());
+}
+
+#if defined(USE_AURA)
+// Tests that the MenuButton does not become pressed if it can be dragged, and a
+// DragDropClient is processing the events.
+TEST_F(MenuButtonTest, DraggableMenuButtonDoesNotActivateOnDrag) {
+  TestMenuButtonListener menu_button_listener;
+  CreateMenuButtonWithMenuButtonListener(&menu_button_listener);
+  TestDragController drag_controller;
+  button()->set_drag_controller(&drag_controller);
+
+  TestDragDropClient drag_client;
+  SetDragDropClient(GetContext(), &drag_client);
+  button()->PrependPreTargetHandler(&drag_client);
+
+  ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
+  generator.set_current_location(gfx::Point(10, 10));
+  generator.DragMouseBy(10, 0);
+  EXPECT_EQ(nullptr, menu_button_listener.last_source());
+  EXPECT_EQ(Button::STATE_NORMAL, menu_button_listener.last_source_state());
+}
+#endif
+
 }  // namespace views
diff --git a/ui/views/controls/menu/menu_separator_win.cc b/ui/views/controls/menu/menu_separator_win.cc
index 98a70baa..f674968 100644
--- a/ui/views/controls/menu/menu_separator_win.cc
+++ b/ui/views/controls/menu/menu_separator_win.cc
@@ -46,7 +46,7 @@
   // Hack to get the separator to display correctly on Windows where we may
   // have fractional scales. We move the separator 1 pixel down to ensure that
   // it falls within the clipping rect which is scaled up.
-  float device_scale = gfx::win::GetDeviceScaleFactor();
+  float device_scale = gfx::GetDPIScale();
   bool is_fractional_scale =
       (device_scale - static_cast<int>(device_scale) != 0);
   if (is_fractional_scale && separator_bounds.y() == 0)
diff --git a/ui/views/controls/prefix_selector.cc b/ui/views/controls/prefix_selector.cc
index c901edd2..7e23aa9 100644
--- a/ui/views/controls/prefix_selector.cc
+++ b/ui/views/controls/prefix_selector.cc
@@ -67,6 +67,10 @@
   return ui::TEXT_INPUT_MODE_DEFAULT;
 }
 
+int PrefixSelector::GetTextInputFlags() const {
+  return 0;
+}
+
 bool PrefixSelector::CanComposeInline() const {
   return false;
 }
diff --git a/ui/views/controls/prefix_selector.h b/ui/views/controls/prefix_selector.h
index 615f239..8c40eda 100644
--- a/ui/views/controls/prefix_selector.h
+++ b/ui/views/controls/prefix_selector.h
@@ -34,6 +34,7 @@
   virtual gfx::NativeWindow GetAttachedWindow() const override;
   virtual ui::TextInputType GetTextInputType() const override;
   virtual ui::TextInputMode GetTextInputMode() const override;
+  virtual int GetTextInputFlags() const override;
   virtual bool CanComposeInline() const override;
   virtual gfx::Rect GetCaretBounds() const override;
   virtual bool GetCompositionCharacterBounds(uint32 index,
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index cd4c7e4..5a0cad8 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -1416,6 +1416,10 @@
   return ui::TEXT_INPUT_MODE_DEFAULT;
 }
 
+int Textfield::GetTextInputFlags() const {
+  return 0;
+}
+
 bool Textfield::CanComposeInline() const {
   return true;
 }
diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h
index 53f0ee6..f84b07e 100644
--- a/ui/views/controls/textfield/textfield.h
+++ b/ui/views/controls/textfield/textfield.h
@@ -287,6 +287,7 @@
   virtual gfx::NativeWindow GetAttachedWindow() const override;
   virtual ui::TextInputType GetTextInputType() const override;
   virtual ui::TextInputMode GetTextInputMode() const override;
+  virtual int GetTextInputFlags() const override;
   virtual bool CanComposeInline() const override;
   virtual gfx::Rect GetCaretBounds() const override;
   virtual bool GetCompositionCharacterBounds(uint32 index,
diff --git a/ui/views/ime/OWNERS b/ui/views/ime/OWNERS
index 9f6409af..b53970a 100644
--- a/ui/views/ime/OWNERS
+++ b/ui/views/ime/OWNERS
@@ -1,5 +1,6 @@
 # primary reviewer
 yukishiino@chromium.org
+shuchen@chromium.org
 
 # backup reviewers.
 mukai@chromium.org
diff --git a/ui/views/ime/input_method_bridge.cc b/ui/views/ime/input_method_bridge.cc
index 8e321f0..92f886ea 100644
--- a/ui/views/ime/input_method_bridge.cc
+++ b/ui/views/ime/input_method_bridge.cc
@@ -226,6 +226,11 @@
   return client ? client->GetTextInputMode() : ui::TEXT_INPUT_MODE_DEFAULT;
 }
 
+int InputMethodBridge::GetTextInputFlags() const {
+  TextInputClient* client = GetTextInputClient();
+  return client ? client->GetTextInputFlags() : 0;
+}
+
 bool InputMethodBridge::CanComposeInline() const {
   TextInputClient* client = GetTextInputClient();
   return client ? client->CanComposeInline() : true;
diff --git a/ui/views/ime/input_method_bridge.h b/ui/views/ime/input_method_bridge.h
index 43fb9479..8813e87 100644
--- a/ui/views/ime/input_method_bridge.h
+++ b/ui/views/ime/input_method_bridge.h
@@ -59,6 +59,7 @@
   virtual gfx::NativeWindow GetAttachedWindow() const override;
   virtual ui::TextInputType GetTextInputType() const override;
   virtual ui::TextInputMode GetTextInputMode() const override;
+  virtual int GetTextInputFlags() const override;
   virtual bool CanComposeInline() const override;
   virtual gfx::Rect GetCaretBounds() const override;
   virtual bool GetCompositionCharacterBounds(uint32 index,
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 8c5fd8b..601e5a2 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -971,13 +971,10 @@
       return;
 
     case ui::ET_MOUSE_MOVED:
-      if ((event->flags() & (ui::EF_LEFT_MOUSE_BUTTON |
-                             ui::EF_RIGHT_MOUSE_BUTTON |
-                             ui::EF_MIDDLE_MOUSE_BUTTON)) == 0) {
-        OnMouseMoved(*event);
-        return;
-      }
-      // FALL-THROUGH
+      CHECK(!event->IsAnyButton());
+      OnMouseMoved(*event);
+      return;
+
     case ui::ET_MOUSE_DRAGGED:
       if (ProcessMouseDragged(*event))
         event->SetHandled();
@@ -2264,6 +2261,8 @@
 }
 
 bool View::ProcessMouseDragged(const ui::MouseEvent& event) {
+  CHECK_EQ(ui::ET_MOUSE_DRAGGED, event.type());
+
   // Copy the field, that way if we're deleted after drag and drop no harm is
   // done.
   ContextMenuController* context_menu_controller = context_menu_controller_;
diff --git a/ui/views/widget/desktop_aura/desktop_screen_win.cc b/ui/views/widget/desktop_aura/desktop_screen_win.cc
index aede1795..a8e088c 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_screen_win.cc
@@ -26,10 +26,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopScreenWin, gfx::ScreenWin implementation:
 
-bool DesktopScreenWin::IsDIPEnabled() {
-  return true;
-}
-
 gfx::Display DesktopScreenWin::GetDisplayMatching(
     const gfx::Rect& match_rect) const {
   return GetDisplayNearestPoint(match_rect.CenterPoint());
diff --git a/ui/views/widget/desktop_aura/desktop_screen_win.h b/ui/views/widget/desktop_aura/desktop_screen_win.h
index 0ba1f5d..59776a6 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_win.h
+++ b/ui/views/widget/desktop_aura/desktop_screen_win.h
@@ -17,7 +17,6 @@
 
  private:
   // Overridden from gfx::ScreenWin:
-  virtual bool IsDIPEnabled() override;
   virtual gfx::Display GetDisplayMatching(
       const gfx::Rect& match_rect) const override;
   virtual HWND GetHWNDFromNativeView(gfx::NativeView window) const override;
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index bb253cf..083e900f 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -112,10 +112,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopScreenX11, gfx::Screen implementation:
 
-bool DesktopScreenX11::IsDIPEnabled() {
-  return true;
-}
-
 gfx::Point DesktopScreenX11::GetCursorScreenPoint() {
   TRACE_EVENT0("views", "DesktopScreenX11::GetCursorScreenPoint()");
 
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.h b/ui/views/widget/desktop_aura/desktop_screen_x11.h
index 1fc32d1..c97c9d9 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_x11.h
+++ b/ui/views/widget/desktop_aura/desktop_screen_x11.h
@@ -31,7 +31,6 @@
   virtual ~DesktopScreenX11();
 
   // Overridden from gfx::Screen:
-  virtual bool IsDIPEnabled() override;
   virtual gfx::Point GetCursorScreenPoint() override;
   virtual gfx::NativeWindow GetWindowUnderCursor() override;
   virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point)
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index d184ae4..ac57a18 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -286,7 +286,7 @@
     // See crbug.com/410593.
     gfx::NativeRegion shape = native_region;
     SkRegion device_region;
-    if (gfx::IsInHighDPIMode()) {
+    if (gfx::GetDPIScale() > 1.0) {
       shape = &device_region;
       const float& scale = gfx::GetDPIScale();
       std::vector<SkIRect> rects;
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index 2889355..a37ad73 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -1107,16 +1107,18 @@
 // static
 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view,
                                              Widget::Widgets* owned) {
-  const aura::Window::Windows& transient_children =
-      wm::GetTransientChildren(native_view);
-  for (aura::Window::Windows::const_iterator i = transient_children.begin();
-       i != transient_children.end(); ++i) {
+  // Add all owned widgets.
+  for (aura::Window* transient_child : wm::GetTransientChildren(native_view)) {
     NativeWidgetPrivate* native_widget = static_cast<NativeWidgetPrivate*>(
-        GetNativeWidgetForNativeView(*i));
+        GetNativeWidgetForNativeView(transient_child));
     if (native_widget && native_widget->GetWidget())
       owned->insert(native_widget->GetWidget());
-    GetAllOwnedWidgets((*i), owned);
+    GetAllOwnedWidgets(transient_child, owned);
   }
+
+  // Add all child windows.
+  for (aura::Window* child : native_view->children())
+    GetAllChildWidgets(child, owned);
 }
 
 // static
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 08ab9398..8dcd73e 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -318,7 +318,8 @@
   static void GetAllChildWidgets(gfx::NativeView native_view,
                                  Widgets* children);
 
-  // Returns all non-child Widgets owned by |native_view|.
+  // Returns all Widgets owned by |native_view| (including child widgets, but
+  // not including itself).
   static void GetAllOwnedWidgets(gfx::NativeView native_view,
                                  Widgets* owned);
 
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 1544507e..43398be 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -1219,7 +1219,7 @@
 
   // We need to clip to the dirty rect ourselves.
   layered_window_contents_->sk_canvas()->save();
-  double scale = gfx::win::GetDeviceScaleFactor();
+  double scale = gfx::GetDPIScale();
   layered_window_contents_->sk_canvas()->scale(
       SkScalar(scale),SkScalar(scale));
   layered_window_contents_->ClipRect(invalid_rect_);
diff --git a/ui/webui/resources/css/list.css b/ui/webui/resources/css/list.css
index 8ecb918..e4d756a9 100644
--- a/ui/webui/resources/css/list.css
+++ b/ui/webui/resources/css/list.css
@@ -101,7 +101,7 @@
     button,
     input[type='button'],
     input[type='submit'],
-    select):not(.custom-appearance):not(.link-button) {
+    select):not(.custom-appearance) {
   line-height: normal;
   margin: 0;
   vertical-align: middle;
diff --git a/ui/webui/resources/css/widgets.css b/ui/webui/resources/css/widgets.css
index 571f9c4..9d12cfe7 100644
--- a/ui/webui/resources/css/widgets.css
+++ b/ui/webui/resources/css/widgets.css
@@ -10,7 +10,7 @@
 
 :-webkit-any(button,
              input[type='button'],
-             input[type='submit']):not(.custom-appearance):not(.link-button),
+             input[type='submit']):not(.custom-appearance),
 select,
 input[type='checkbox'],
 input[type='radio'] {
@@ -30,7 +30,7 @@
 
 :-webkit-any(button,
              input[type='button'],
-             input[type='submit']):not(.custom-appearance):not(.link-button),
+             input[type='submit']):not(.custom-appearance),
 select {
   min-height: 2em;
   min-width: 4em;
@@ -44,7 +44,7 @@
 
 :-webkit-any(button,
              input[type='button'],
-             input[type='submit']):not(.custom-appearance):not(.link-button) {
+             input[type='submit']):not(.custom-appearance) {
   -webkit-padding-end: 10px;
   -webkit-padding-start: 10px;
 }
@@ -157,7 +157,7 @@
     :-webkit-any(
         button,
         input[type='button'],
-        input[type='submit']):not(.custom-appearance):not(.link-button)) {
+        input[type='submit']):not(.custom-appearance)) {
   background-image: -webkit-linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0);
   border-color: rgba(0, 0, 0, 0.3);
   box-shadow: 0 1px 0 rgba(0, 0, 0, 0.12),
@@ -180,7 +180,7 @@
     :-webkit-any(
         button,
         input[type='button'],
-        input[type='submit']):not(.custom-appearance):not(.link-button)) {
+        input[type='submit']):not(.custom-appearance)) {
   background-image: -webkit-linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);
   box-shadow: none;
   text-shadow: none;
@@ -197,7 +197,7 @@
 :disabled:-webkit-any(
     button,
     input[type='button'],
-    input[type='submit']):not(.custom-appearance):not(.link-button),
+    input[type='submit']):not(.custom-appearance),
 select:disabled {
   background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
   border-color: rgba(80, 80, 80, 0.2);
@@ -240,7 +240,7 @@
     :-webkit-any(
          button,
          input[type='button'],
-         input[type='submit']):not(.custom-appearance):not(.link-button)) {
+         input[type='submit']):not(.custom-appearance)) {
   /* OVERRIDE */
   -webkit-transition: border-color 200ms;
   /* We use border color because it follows the border radius (unlike outline).
@@ -249,31 +249,26 @@
   outline: none;
 }
 
-/* Link buttons ***************************************************************/
+/* Action links ***************************************************************/
 
-.link-button {
-  -webkit-box-shadow: none;
-  background: transparent none;
-  border: none;
-  color: rgb(17, 85, 204);
+[is='action-link'] {
   cursor: pointer;
-  /* Input elements have -webkit-small-control which can override the body font.
-   * Resolve this by using 'inherit'. */
-  font: inherit;
-  margin: 0;
-  padding: 0;
 }
 
-.link-button:hover {
+[is='action-link'] {
+  text-decoration: none;
+}
+
+[is='action-link']:hover {
   text-decoration: underline;
 }
 
-.link-button:active {
+[is='action-link']:active {
   color: rgb(5, 37, 119);
   text-decoration: underline;
 }
 
-.link-button[disabled] {
+[is='action-link'][disabled] {
   color: #999;
   cursor: default;
   text-decoration: none;
diff --git a/ui/webui/resources/js/action_link.js b/ui/webui/resources/js/action_link.js
new file mode 100644
index 0000000..88afd53
--- /dev/null
+++ b/ui/webui/resources/js/action_link.js
@@ -0,0 +1,57 @@
+// 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.
+
+// Action links are elements that are used to perform an in-page navigation or
+// action (e.g. showing a dialog).
+//
+// They look like normal anchor (<a>) tags as their text color is blue. However,
+// they're subtly different as they're not initially underlined (giving users a
+// clue that underlined links navigate while action links don't).
+//
+// Action links look very similar to normal links when hovered (hand cursor,
+// underlined). This gives the user an idea that clicking this link will do
+// something similar to navigation but in the same page.
+//
+// They can be created in JavaScript like this:
+//
+//   var link = document.createElement('a', 'action-link');  // Note second arg.
+//
+// or with a constructor like this:
+//
+//   var link = new ActionLink();
+//
+// They can be used easily from HTML as well, like so:
+//
+//   <a is="action-link">Click me!</a>
+//
+// NOTE: <action-link> and document.createElement('action-link') don't work.
+
+/**
+ * @constructor
+ * @extends {HTMLAnchorElement}
+ */
+var ActionLink = document.registerElement('action-link', {
+  prototype: {
+    __proto__: HTMLAnchorElement.prototype,
+
+    createdCallback: function() {
+      // Links aren't tabble unless there's an [href] attribute set. Setting
+      // this adds undesirable "Open link in new tab..." context menu handlers
+      // so just manually add to tab order instead.
+      this.tabIndex = 0;
+
+      this.addEventListener('keydown', function(e) {
+        if (e.keyIdentifier == 'Enter') {
+          // Schedule a click asynchronously because other 'keydown' handlers
+          // may still run later (e.g. document.addEventListener('keydown')).
+          // Specifically options dialogs break when this timeout isn't here.
+          // NOTE: this affects the "trusted" state of the ensuing click. I
+          // haven't found anything that breaks because of this (yet).
+          window.setTimeout(this.click.bind(this), 0);
+        }
+      });
+    },
+  },
+  extends: 'a',
+});
diff --git a/ui/webui/resources/js/util.js b/ui/webui/resources/js/util.js
index 9f97351..03db2a29 100644
--- a/ui/webui/resources/js/util.js
+++ b/ui/webui/resources/js/util.js
@@ -227,6 +227,7 @@
 }
 
 /**
+ * TODO(dbeam): DO NOT USE. THIS IS DEPRECATED. Use an action-link instead.
  * Call this to stop clicks on <a href="#"> links from scrolling to the top of
  * the page (and possibly showing a # in the link).
  */
@@ -261,6 +262,21 @@
                           'Missing required element: ' + id);
 }
 
+/**
+ * Query an element that's known to exist by a selector. We use this instead of
+ * just calling querySelector and not checking the result because this lets us
+ * satisfy the JSCompiler type system.
+ * @param {(!Document|!DocumentFragment|!Element)} context The context object
+ *     for querySelector.
+ * @param {string} selectors CSS selectors to query the element.
+ * @return {!HTMLElement} the Element.
+ */
+function queryRequiredElement(context, selectors) {
+  var element = context.querySelector(selectors);
+  return assertInstanceof(element, HTMLElement,
+                          'Missing required element: ' + selectors);
+}
+
 // Handle click on a link. If the link points to a chrome: or file: url, then
 // call into the browser to do the navigation.
 document.addEventListener('click', function(e) {
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd
index 9cc6726..a532d8c 100644
--- a/ui/webui/resources/webui_resources.grd
+++ b/ui/webui/resources/webui_resources.grd
@@ -353,6 +353,8 @@
       <structure name="IDR_WEBUI_JS_I18N_TEMPLATE_NO_PROCESS"
                  file="js/i18n_template_no_process.js"
                  type="chrome_html" />
+      <structure name="IDR_WEBUI_JS_ACTION_LINK"
+                 file="js/action_link.js" type="chrome_html" />
       <structure name="IDR_WEBUI_JS_LOAD_TIME_DATA"
                  file="js/load_time_data.js" type="chrome_html" />
       <structure name="IDR_WEBUI_JS_MEDIA_COMMON"
diff --git a/ui/wm/core/nested_accelerator_dispatcher_linux.cc b/ui/wm/core/nested_accelerator_dispatcher_linux.cc
index ee5b5872..16a4efb8 100644
--- a/ui/wm/core/nested_accelerator_dispatcher_linux.cc
+++ b/ui/wm/core/nested_accelerator_dispatcher_linux.cc
@@ -85,8 +85,8 @@
     }
     ui::PlatformEventDispatcher* prev = *restore_dispatcher_;
 
-    return prev ? prev->DispatchEvent(event)
-                : ui::POST_DISPATCH_PERFORM_DEFAULT;
+    uint32_t perform_default = ui::POST_DISPATCH_PERFORM_DEFAULT;
+    return prev ? prev->DispatchEvent(event) : perform_default;
   }
 
   scoped_ptr<ui::ScopedEventDispatcher> restore_dispatcher_;
diff --git a/ui/wm/core/window_animations.cc b/ui/wm/core/window_animations.cc
index 746ea48a..c523c98 100644
--- a/ui/wm/core/window_animations.cc
+++ b/ui/wm/core/window_animations.cc
@@ -29,11 +29,11 @@
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/animation/animation.h"
+#include "ui/gfx/geometry/vector3d_f.h"
 #include "ui/gfx/interpolated_transform.h"
 #include "ui/gfx/rect_conversions.h"
 #include "ui/gfx/screen.h"
 #include "ui/gfx/vector2d.h"
-#include "ui/gfx/vector3d_f.h"
 #include "ui/wm/core/window_util.h"
 #include "ui/wm/core/wm_core_switches.h"
 #include "ui/wm/public/animation_host.h"
diff --git a/url/url_canon_icu.h b/url/url_canon_icu.h
index 18b1f09..80d79539 100644
--- a/url/url_canon_icu.h
+++ b/url/url_canon_icu.h
@@ -24,11 +24,11 @@
   // be managed by the creator such that it is alive as long as this is.
   ICUCharsetConverter(UConverter* converter);
 
-  virtual ~ICUCharsetConverter();
+  ~ICUCharsetConverter() override;
 
-  virtual void ConvertFromUTF16(const base::char16* input,
-                                int input_len,
-                                CanonOutput* output) override;
+  void ConvertFromUTF16(const base::char16* input,
+                        int input_len,
+                        CanonOutput* output) override;
 
  private:
   // The ICU converter, not owned by this class.
diff --git a/url/url_canon_stdstring.h b/url/url_canon_stdstring.h
index 62622b4..c3d8ba14 100644
--- a/url/url_canon_stdstring.h
+++ b/url/url_canon_stdstring.h
@@ -36,12 +36,12 @@
 class URL_EXPORT StdStringCanonOutput : public CanonOutput {
  public:
   StdStringCanonOutput(std::string* str);
-  virtual ~StdStringCanonOutput();
+  ~StdStringCanonOutput() override;
 
   // Must be called after writing has completed but before the string is used.
   void Complete();
 
-  virtual void Resize(int sz) override;
+  void Resize(int sz) override;
 
  protected:
   std::string* str_;